Ejemplo n.º 1
0
    def merge(self, source):
        """Merge a resource to collection.

        Merge content into existing resource or create new content. Returns
        the message digest after merging the content.

        If content source does not exist in the collection it causes migrage
        operation.

        This method cannot merge a collection because so far there has been
        no need for it.

        Args:
            source (Resource): Resource to be merged to collection.

        Returns:
            str: None or message digest after merging the source.
        """

        digest = None
        if not source or not isinstance(source, Resource):
            self._logger.debug(
                'source was not merged to collection: {}'.format(
                    Logger.remove_ansi(str(source))))

            return digest

        if source.digest in self.keys():
            if self[source.digest].merge(source):
                digest = self[source.digest].digest
            else:
                self._logger.debug(
                    'merging content to existing resource failed: {}'.format(
                        Logger.remove_ansi(str(source))))
                try:
                    del self[source.digest]
                except KeyError:
                    self._logger.info(
                        'unexpected failure to delete existing content: {}'.
                        format(Logger.remove_ansi(str(source))))
        else:
            if self.migrate(source):
                digest = source.digest
            else:
                self._logger.debug(
                    'migrating new content to collection failed: {}'.format(
                        Logger.remove_ansi(str(source))))
                try:
                    del self[
                        source.
                        digest]  # This should never be executed. But just in case of an error in above migrate method.
                except KeyError:
                    pass

        return digest
Ejemplo n.º 2
0
    def _set_integrity_error(self, error, resource):
        """Set integrity error.

        Args:
            error (Exception): Exception string from integrity error.
            resource (Resource): Resource which SQL operation caused exception.
        """

        digest = self._get_digest(resource)
        match = self._catch_violating_column.search(str(error))
        if match:
            if match.group('column') == 'uuid' and not Config.defaults:
                cause = Cause.HTTP_500
            else:
                cause = Cause.HTTP_CONFLICT
            Cause.push(
                cause, 'content: {} :already exist with digest: {:.16}'.format(
                    match.group('column'), digest))
        else:
            self._logger.info(
                'database integrity error parse failure: {}'.format(error))
            Cause.push(
                Cause.HTTP_CONFLICT,
                'content already exist with digest: {:.16}'.format(digest))
        if not Config.defaults:
            self._logger.info(
                'database integrity error from database: {}'.format(
                    traceback.format_exc()))
            self._logger.info(
                'database integrity error from resource: {}'.format(
                    Logger.remove_ansi(str(resource))))
            self._logger.info(
                'database integrity error stack trace: {}'.format(
                    traceback.format_stack(limit=20)))
Ejemplo n.º 3
0
    def migrate(self, source):
        """Migrate resource or collection to collection.

        Add new resources or override originals if they exist.

        Args:
           source (content): Resource or Collection that is migrated.
        """

        migrated = False
        if isinstance(source, Collection):
            for resource in source.resources():
                self.migrate(resource)
        elif isinstance(source, Resource):
            if source.category in Const.CATEGORIES:
                if source.seal():
                    if source.digest not in self.keys():
                        self._data['meta'][
                            'total'] = self._data['meta']['total'] + 1
                    self._data['data'][source.digest] = {}
                    self._data['data'][source.digest]['data'] = source
                    migrated = True
                else:
                    self._logger.debug(
                        'resource: {} :not migrated to collection'.format(
                            source.digest))
            else:
                self._logger.debug(
                    'migrate to collection failed due to unknown category: {}'.
                    format(Logger.remove_ansi(str(source))))

        return migrated
Ejemplo n.º 4
0
    def _get_digest(self, resource):
        """Return digest of given content from database."""

        digest = 'not found'
        category = resource.category
        collection = self._select_data(resource.data)
        if not collection:
            collection = self._select_uuid(resource.uuid)

        if len(collection) == 1:
            digest = next(collection.resources()).digest
        else:
            Cause.push(
                Cause.HTTP_500,
                'internal error when searching content possibly violating database unique constraints'
            )
            self._logger.debug(
                'internal server error searching resource from database: {}'.
                format(Logger.remove_ansi(str(resource))))
            self._logger.debug(
                'internal server error searching unique digest hits: %d :from category: %s',
                len(collection), category)

        return digest