예제 #1
0
    def create_version(cls,
                       community_id,
                       community_schema,
                       root_schema_version=None):
        """Create a new schema draft for the given community.

        Args:
            community_id (UUID): ID of the community whose schema is create.
            community_schema (dict): loaded JSON Schema validating the
                community specific metadata.
            root_schema_version (int): version of the root schema used by this
                community schema. If set to None, the root_schema of the last
                version is used, if there is no previous version
                (new community), the last root_schema is used.

        Returns:
            :class:`b2share.modules.schemas.api.CommunitySchema`: the
                new Community schema.
        """
        from .models import CommunitySchemaVersion
        from b2share.modules.schemas.helpers import validate_json_schema

        previous_community_schemas = _fetch_all_query_pages(
            CommunitySchemaVersion.query.filter(
                CommunitySchemaVersion.community == community_id).order_by(
                    CommunitySchemaVersion.version.asc()))

        prev_schemas = map(lambda x: x.community_schema,
                           previous_community_schemas)
        validate_json_schema(community_schema, prev_schemas)

        with db.session.begin_nested():
            if len(previous_community_schemas) > 0:
                last_schema = previous_community_schemas[-1]

                new_version = last_schema.version + 1
                if root_schema_version is None:
                    root_schema_version = last_schema.root_schema
            else:
                if root_schema_version is None:
                    # there is no schema yet, the community is new.
                    # Use the last RootSchema.
                    from .models import RootSchemaVersion
                    try:
                        root_schema_version = RootSchemaVersion.query.order_by(
                            RootSchemaVersion.version).limit(1).one().version
                    except NoResultFound as e:
                        raise RootSchemaDoesNotExistError from e
                new_version = 0

            model = CommunitySchemaVersion(
                community=community_id,
                root_schema=root_schema_version,
                community_schema=json.dumps(
                    community_schema,
                    # avoid default whitespaces
                    separators=(',', ':')),
                version=new_version)
            db.session.add(model)
        return cls(model)
예제 #2
0
    def create_version(cls, community_id, community_schema,
                       root_schema_version=None):
        """Create a new schema draft for the given community.

        Args:
            community_id (UUID): ID of the community whose schema is create.
            community_schema (dict): loaded JSON Schema validating the
                community specific metadata.
            root_schema_version (int): version of the root schema used by this
                community schema. If set to None, the root_schema of the last
                version is used, if there is no previous version
                (new community), the last root_schema is used.

        Returns:
            :class:`b2share.modules.schemas.api.CommunitySchema`: the
                new Community schema.
        """
        from .models import CommunitySchemaVersion

        previous_community_schemas = _fetch_all_query_pages(
            CommunitySchemaVersion.query.filter(
                CommunitySchemaVersion.community == community_id
            ).order_by(CommunitySchemaVersion.version.asc())
        )

        prev_schemas = map(lambda x: x.community_schema,
                           previous_community_schemas)
        validate_json_schema(community_schema, prev_schemas)

        with db.session.begin_nested():
            if len(previous_community_schemas) > 0:
                last_schema = previous_community_schemas[-1]

                new_version = last_schema.version + 1
                if root_schema_version is None:
                    root_schema_version = last_schema.root_schema
            else:
                if root_schema_version is None:
                    # there is no schema yet, the community is new.
                    # Use the last RootSchema.
                    from .models import RootSchemaVersion
                    try:
                        root_schema_version = RootSchemaVersion.query.order_by(
                            RootSchemaVersion.version).limit(1).one().version
                    except NoResultFound as e:
                        raise RootSchemaDoesNotExistError from e
                new_version = 0

            model = CommunitySchemaVersion(
                community=community_id,
                root_schema=root_schema_version,
                community_schema=json.dumps(community_schema,
                                            # avoid default whitespaces
                                            separators=(',', ':')),
                version=new_version)
            db.session.add(model)
        return cls(model)
예제 #3
0
    def create_version(self, json_schema, version_number=None):
        """Create a new version of this schema and release it.

        Args:
            json_schema (dict): the json_schema to use for this new version.

        Returns:
            :class:`b2share.modules.schemas.models.BlockSchemaVersion`:
                The new block schema version.

        Raises:
            :class:`b2share.modules.schemas.errors.InvalidJSONSchemaError`:
                The given JSON Schema is not valid.

        """
        from .models import BlockSchemaVersion as BlockSchemaVersionModel

        if self.deprecated:
            raise BlockSchemaIsDeprecated()
        if not isinstance(json_schema, dict):
            raise InvalidJSONSchemaError('json_schema must be a dict')

        previous_block_schema_versions = _fetch_all_query_pages(
            BlockSchemaVersionModel.query.filter(
                BlockSchemaVersionModel.block_schema == self.model.id,
                # BlockSchemaVersionModel.version < version_number
            ).order_by(BlockSchemaVersionModel.version.asc())
        )
        prev_schemas = map(lambda x: x.json_schema,
                           previous_block_schema_versions)

        validate_json_schema(json_schema, prev_schemas)
        # FIXME: validate the json-schema
        with db.session.begin_nested():
            last_version = db.session.query(
                sqlalchemy.func.max(BlockSchemaVersionModel.version)
                .label('last_version')
            ).filter(
                BlockSchemaVersionModel.block_schema == self.model.id
            ).one().last_version

            new_version = (last_version + 1 if last_version is not None
                           else 0)
            if version_number and new_version < version_number:
                raise InvalidSchemaVersionError(last_version)
            elif version_number and new_version > version_number:
                raise SchemaVersionExistsError(last_version)

            model = BlockSchemaVersionModel(
                block_schema=self.model.id,
                # we specify the separators in order to avoir whitespaces
                json_schema=json.dumps(json_schema, separators=(',', ':')),
                version=new_version)
            db.session.add(model)
        return BlockSchemaVersion(model, self)
예제 #4
0
    def create_version(self, json_schema, version_number=None):
        """Create a new version of this schema and release it.

        Args:
            json_schema (dict): the json_schema to use for this new version.

        Returns:
            :class:`b2share.modules.schemas.models.BlockSchemaVersion`:
                The new block schema version.

        Raises:
            :class:`b2share.modules.schemas.errors.InvalidJSONSchemaError`:
                The given JSON Schema is not valid.

        """
        from .models import BlockSchemaVersion as BlockSchemaVersionModel

        if self.deprecated:
            raise BlockSchemaIsDeprecated()
        if not isinstance(json_schema, dict):
            raise InvalidJSONSchemaError('json_schema must be a dict')

        previous_block_schema_versions = _fetch_all_query_pages(
            BlockSchemaVersionModel.query.filter(
                BlockSchemaVersionModel.block_schema == self.model.id,
                # BlockSchemaVersionModel.version < version_number
            ).order_by(BlockSchemaVersionModel.version.asc())
        )
        prev_schemas = map(lambda x: x.json_schema,
                           previous_block_schema_versions)

        validate_json_schema(json_schema, prev_schemas)
        # FIXME: validate the json-schema
        with db.session.begin_nested():
            last_version = db.session.query(
                sqlalchemy.func.max(BlockSchemaVersionModel.version)
                .label('last_version')
            ).filter(
                BlockSchemaVersionModel.block_schema == self.model.id
            ).one().last_version

            new_version = (last_version + 1 if last_version is not None
                           else 0)
            if version_number and new_version < version_number:
                raise InvalidSchemaVersionError(last_version)
            elif version_number and new_version > version_number:
                raise SchemaVersionExistsError(last_version)

            model = BlockSchemaVersionModel(
                block_schema=self.model.id,
                # we specify the separators in order to avoir whitespaces
                json_schema=json.dumps(json_schema, separators=(',', ':')),
                version=new_version)
            db.session.add(model)
        return BlockSchemaVersion(model, self)
예제 #5
0
    def create_new_version(cls, version, json_schema, options={}):
        """Load a new root schema version.

        Args:
            version (int): version number of this schema. Versions are known
                in advance and are the same for all B2Share instances. This is
                more of a security check as the version MUST follow the last
                loaded one.
            json_schema (dict): the JSON Schema corresponding to this version.

        Raises:
            :class:`b2share.modules.schemas.errors.InvalidRootSchemaError`:
                If the root schema version is invalid.
            :class:`b2share.modules.schemas.errors.InvalidJSONSchemaError`:
                The given JSON Schema is not valid.
        """
        from .models import RootSchemaVersion
        if not isinstance(json_schema, dict):
            raise InvalidJSONSchemaError('json_schema must be a dict')

        previous_root_schemas = _fetch_all_query_pages(
            RootSchemaVersion.query.filter(
                RootSchemaVersion.version < version).order_by(
                    RootSchemaVersion.version.asc()))
        prev_schemas = map(lambda x: x.json_schema, previous_root_schemas)

        if 'definitions' in json_schema:
            json_schema = Schema._resolveLocalReferences(
                json_schema, json_schema['definitions'])
            del json_schema['definitions']

        validate_json_schema(json_schema, prev_schemas, options)

        with db.session.begin_nested():
            # Force the given version to follow the previous one.
            # Root schema versions are not random and should be hard-coded.
            # This is just to make sure that a version was not skipped.
            last_version = db.session.query(
                sqlalchemy.func.max(RootSchemaVersion.version).label(
                    'last_version')).one().last_version
            if last_version is None:
                if version != 0:
                    raise InvalidRootSchemaError('First version should '
                                                 'be 0.')
            elif last_version + 1 != version:
                raise InvalidRootSchemaError('Given version does not '
                                             'follow the previous one.')
            # Create the root schema.
            model = RootSchemaVersion(json_schema=json.dumps(json_schema),
                                      version=version)
            root_schema = cls(model)
            db.session.add(model)
            return root_schema
예제 #6
0
    def create_new_version(cls, version, json_schema):
        """Load a new root schema version.

        Args:
            version (int): version number of this schema. Versions are known
                in advance and are the same for all B2Share instances. This is
                more of a security check as the version MUST follow the last
                loaded one.
            json_schema (dict): the JSON Schema corresponding to this version.

        Raises:
            :class:`b2share.modules.schemas.errors.InvalidRootSchemaError`:
                If the root schema version is invalid.
            :class:`b2share.modules.schemas.errors.InvalidJSONSchemaError`:
                The given JSON Schema is not valid.
        """
        from .models import RootSchemaVersion
        if not isinstance(json_schema, dict):
            raise InvalidJSONSchemaError('json_schema must be a dict')

        previous_root_schemas = _fetch_all_query_pages(
            RootSchemaVersion.query.filter(
                RootSchemaVersion.version < version
            ).order_by(RootSchemaVersion.version.asc())
        )
        prev_schemas = map(lambda x: x.json_schema, previous_root_schemas)
        validate_json_schema(json_schema, prev_schemas)

        with db.session.begin_nested():
            # Force the given version to follow the previous one.
            # Root schema versions are not random and should be hard-coded.
            # This is just to make sure that a version was not skipped.
            last_version = db.session.query(
                sqlalchemy.func.max(
                    RootSchemaVersion.version).label('last_version')
            ).one().last_version
            if last_version is None:
                if version != 0:
                    raise InvalidRootSchemaError('First version should '
                                                 'be 0.')
            elif last_version + 1 != version:
                raise InvalidRootSchemaError('Given version does not '
                                             'follow the previous one.')
            # Create the root schema.
            model = RootSchemaVersion(
                json_schema=json.dumps(json_schema),
                version=version)
            root_schema = cls(model)
            db.session.add(model)
            return root_schema
예제 #7
0
    def update_existing_version(cls, version, json_schema, options={}):
        """Update an existing root schema version.

        Args:
            version (int): version number of this schema. Versions are known
                in advance and are the same for all B2Share instances. This is
                more of a security check as the version MUST follow the last
                loaded one.
            json_schema (dict): the JSON Schema corresponding to this version.

        Raises:
            :class:`b2share.modules.schemas.errors.InvalidRootSchemaError`:
                If the root schema version is invalid.
            :class:`b2share.modules.schemas.errors.RootSchemaDoesNotExistError`:
                If the root schema version does not exist.
            :class:`b2share.modules.schemas.errors.InvalidJSONSchemaError`:
                The given JSON Schema is not valid.
        """
        from .models import RootSchemaVersion
        if not isinstance(json_schema, dict):
            raise InvalidJSONSchemaError('json_schema must be a dict')

        existing_schema = RootSchemaVersion.query.filter(
            RootSchemaVersion.version == version).one()

        if existing_schema is None:
            raise RootSchemaDoesNotExistError(
                "Root schema version {0} intended for update does not exist.".
                format(version))

        # resolve references if definitions present
        if 'definitions' in json_schema:
            json_schema = Schema._resolveLocalReferences(
                json_schema, json_schema['definitions'])
            del json_schema['definitions']

        validate_json_schema(json_schema, [existing_schema.json_schema],
                             options)

        with db.session.begin_nested():
            # Update the root schema.
            model = RootSchemaVersion(json_schema=json.dumps(json_schema),
                                      version=version)
            root_schema = cls(model)
            db.session.merge(model)
            return root_schema