Esempio n. 1
0
    def create_version(
        self,
        channel_name,
        package_name,
        package_format,
        platform,
        version,
        build_number,
        build_string,
        filename,
        info,
        uploader_id,
        size,
        upsert: bool = False,
    ):
        # hold a lock on the package
        package = (  # noqa
            self.db.query(Package).with_for_update().filter(
                Package.channel_name ==
                channel_name).filter(Package.name == package_name).filter(
                    PackageVersion.package_format == package_format).filter(
                        PackageVersion.platform == platform)).first()

        existing_versions = (self.db.query(PackageVersion).filter(
            PackageVersion.channel_name == channel_name
        ).filter(PackageVersion.package_name == package_name).filter(
            PackageVersion.package_format == package_format).filter(
                PackageVersion.platform == platform).filter(
                    PackageVersion.version == version).filter(
                        PackageVersion.build_number == build_number).filter(
                            PackageVersion.build_string == build_string))
        package_version = existing_versions.one_or_none()

        if not package_version:

            all_existing_versions = (self.db.query(PackageVersion).filter(
                PackageVersion.channel_name == channel_name).filter(
                    PackageVersion.package_name == package_name).order_by(
                        PackageVersion.version_order.asc())).all()

            version_order = 0

            if all_existing_versions:
                new_version = versionorder.VersionOrder(version)
                for v in all_existing_versions:
                    # type checker justly complains that v.version could be None
                    # ignoring it before attempting true fix
                    other = versionorder.VersionOrder(
                        v.version)  # type: ignore
                    is_newer = other < new_version or (
                        other == new_version and v.build_number < build_number)
                    if is_newer:
                        break
                version_order = v.version_order if is_newer else v.version_order + 1

                (self.db.query(PackageVersion).filter(
                    PackageVersion.channel_name == channel_name).filter(
                        PackageVersion.package_name == package_name).filter(
                            PackageVersion.package_format == package_format).
                 filter(PackageVersion.platform == platform).filter(
                     PackageVersion.version_order >= version_order).update(
                         {"version_order": PackageVersion.version_order + 1
                          }, ))

            package_version = PackageVersion(
                id=uuid.uuid4().bytes,
                channel_name=channel_name,
                package_name=package_name,
                package_format=package_format,
                platform=platform,
                version=version,
                build_number=build_number,
                build_string=build_string,
                filename=filename,
                info=info,
                version_order=version_order,
                uploader_id=uploader_id,
                size=size,
            )

            self.db.add(package_version)
            logger.debug(
                f"adding package {package_name} version {version} to " +
                f"channel {channel_name}", )

        elif upsert:
            existing_versions.update(
                {
                    "filename": filename,
                    "info": info,
                    "uploader_id": uploader_id,
                    "time_modified": datetime.utcnow(),
                    "size": size,
                },
                synchronize_session="evaluate",
            )
        else:
            raise IntegrityError("duplicate package version", "", "")

        self.db.commit()

        return package_version
Esempio n. 2
0
    def cleanup_channel_db(self, channel_name: str, dry_run: bool = False):
        # remove all Packages without PackageVersions
        package_without_package_versions = []
        all_packages = self.db.query(Package).filter(
            Package.channel_name == channel_name)
        for each_package in all_packages:
            all_package_versions = (self.db.query(PackageVersion).filter(
                PackageVersion.channel_name == channel_name).filter(
                    PackageVersion.package_name == each_package.name))
            if all_package_versions.count() == 0:
                package_without_package_versions.append(each_package.name)

        for each_package_name in package_without_package_versions:
            if not dry_run:
                self.db.query(PackageMember).filter(
                    PackageMember.channel_name == channel_name).filter(
                        PackageMember.package_name ==
                        each_package_name).delete()

                self.db.query(Package).filter(
                    Package.channel_name == channel_name).filter(
                        Package.name == each_package_name).delete()

            logger.info(
                f"removing Package {channel_name}/{each_package_name} from db as "
                "it has no PackageVersions")

        if not dry_run:
            self.db.commit()

        # clean platforms / channeldata for Packages
        all_packages = self.db.query(Package).filter(
            Package.channel_name == channel_name)
        for each_package in all_packages:
            if each_package.channeldata is not None:
                each_package_channeldata = json.loads(each_package.channeldata)
                subdirs = each_package_channeldata["subdirs"]
                if subdirs:
                    if not dry_run:
                        subdirs = sorted(list(set(subdirs)))
                        each_package_channeldata["subdirs"] = subdirs
                        each_package.channeldata = json.dumps(
                            each_package_channeldata)
                        each_package.url = each_package_channeldata.get(
                            "home", "")
                        each_package.platforms = ":".join(
                            each_package_channeldata.get("subdirs", []))
                    logger.info(
                        "cleaning platforms and "
                        f"channeldata for {channel_name}/{each_package.name}")

        if not dry_run:
            self.db.commit()
        logger.info(f"Done cleaning up db for {channel_name}")

        # Re-sort all PackageVersions
        all_packages = self.db.query(Package).filter(
            Package.channel_name == channel_name)
        for x, each_package in enumerate(all_packages):
            all_versions_for_each_package = (
                self.db.query(PackageVersion).
                filter(PackageVersion.channel_name == channel_name).filter(
                    PackageVersion.package_name == each_package.name).order_by(
                        PackageVersion.version_order.asc())).all()

            if not dry_run:
                v_dict = {}
                for each_package_version in all_versions_for_each_package:
                    if each_package_version.version is not None:
                        v_dict[
                            each_package_version] = versionorder.VersionOrder(
                                each_package_version.version)
                sorted_v = sorted(v_dict.items(),
                                  key=lambda item: item[1],
                                  reverse=True)

                for i, (each_package_version, version) in enumerate(sorted_v):
                    each_package_version.version_order = i
            logger.info(
                f"Re-sorted PackageVersions for {channel_name}/{each_package.name}"
            )

        if not dry_run:
            self.db.commit()
        logger.info(f"Done sorting package versions for {channel_name}")