class ReleasePackage(Model): __bind_key__ = 'packages' __tablename__ = "releases_packages" package_id = reference_col('packages', nullable=True) release_id = reference_col('releases', nullable=False) package_version_id = reference_col('package_versions', nullable=False) release = relationship('Release', backref='release_packages', uselist=False) package = relationship('Package', backref='release_packages', uselist=False) package_version = relationship('PackageVersion', backref='release_packages', uselist=False) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) if self.package_id is None: version = kwargs.get('package_version') or PackageVersion.get(self.package_version_id) self.package_id = version.package_id __table_args__ = ( db.UniqueConstraint('package_id', 'release_id'), db.PrimaryKeyConstraint('package_version_id', 'release_id'), ) def __repr__(self): return self.repr(['package_version_id', 'release_id'])
class SuitePackage(Model): __bind_key__ = 'packages' __tablename__ = "suite_packages" package_id = reference_col('packages', nullable=False) suite_id = reference_col('suites', nullable=False, pk_name="slug") suite = relationship('Suite', uselist=False) package = relationship('Package', uselist=False) __table_args__ = (db.PrimaryKeyConstraint('package_id', 'suite_id'), ) def __repr__(self): return self.repr(['package_id', 'suite_id'])
class PackageVersion(Model, UuidPrimaryKey, StorageCubbyMixinFactory(nullable=False)): __bind_key__ = 'packages' __tablename__ = "package_versions" version = Column(VersionType, nullable=False) local = Column(PathType, nullable=True) run = Column(db.String, nullable=True) test = Column(db.String, nullable=True) url = Column(URLType, nullable=True) package_id = reference_col("packages", nullable=False) package = relationship(Package, backref=db.backref('versions', cascade='delete', lazy='dynamic')) package_eager = relationship(Package, backref=db.backref('versions_eager', cascade='delete', lazy='joined')) @validates('version') def version_readonly(self, key, value): existing = getattr(self, key) if existing is not None: raise ValueError("'version' can only be written once.") return value def __init__(self, *args, cubby=None, **kwargs): if cubby is not None: self.set_cubby(cubby) else: kwargs['service'] = current_app.storage.default_service kwargs['location'] = current_app.storage.default_location kwargs['bucket'] = current_app.storage.default_bucket package = kwargs.get('package') or Package.get( kwargs.get('package_id')) version = kwargs.get('version') kwargs['key'] = f'{package.slug}/{package.slug}-{version}.zip' kwargs['content_type'] = 'application/zip' Model.__init__(self, *args, **kwargs) @property def remote(self): if not self.url and self.cubby(): self.update(url=self.cubby().url(), commit=True) return self.url __table_args__ = (UniqueConstraint( 'package_id', 'version', name='package_version_tuple_is_unique'), )
class ScheduledRelease(Model, UuidPrimaryKey): __bind_key__ = 'packages' __tablename__ = "scheduled_releases" datetime = Column(TimezoneAwareDatetime, nullable=False) release_id = reference_col('releases', nullable=False) release = relationship('Release', uselist=False, backref=db.backref('scheduled_releases', lazy='dynamic')) def __repr__(self): return self.repr(['datetime', 'release'])
class Package(Model, UuidPrimaryKey, SlugMixinFactory('name', nullable=False)): __bind_key__ = 'packages' __tablename__ = "packages" name = Column(db.Unicode(255), nullable=False) namespace_slug = reference_col('namespaces', pk_name='slug', nullable=False) namespace = relationship(Namespace, backref=db.backref("packages", cascade='delete', lazy='dynamic')) def __init__(self, **kwargs): Model.__init__(self, **kwargs) if 'namespace' in kwargs: self.namespace_slug = kwargs['namespace'].slug __table_args__ = (UniqueConstraint( 'namespace_slug', 'slug', name='package_slug_is_unique_in_namespace'), ) @classmethod def lookup(cls, namespace, package): return (cls.query.filter_by(slug=slugify(package)).filter( Namespace.slug == slugify(namespace)).first()) @hybrid_property def path(self): return self.namespace_slug + "/" + self.slug @classmethod def lookup_path(cls, path): return (cls.query.filter_by(path=path).first()) @classmethod def lookup_paths(cls, paths): if len(paths) == 0: return [] return cls.query.filter(Package.path.in_(paths)).all()
class Release(Model, UuidPrimaryKey): __bind_key__ = 'packages' __tablename__ = "releases" title = Column(db.Unicode) packages = relationship('Package', secondary="releases_packages", backref='releases', viewonly=True) package_versions = relationship('PackageVersion', secondary="releases_packages", backref='releases', viewonly=True) suite_id = reference_col('suites', nullable=True, pk_name='slug') suite = relationship('Suite', backref=db.backref('releases', lazy='dynamic'), uselist=False) def set_versions(self, versions=[], commit=False): self.release_packages = [ReleasePackage(release=self, package_version=v) for v in versions] self.save(commit=commit)