use sea_orm::*; use crate::db::*; #[derive(Clone, Debug)] pub struct PackageQuery { conn: DatabaseConnection, } impl PackageQuery { pub fn new(conn: DatabaseConnection) -> Self { Self { conn } } pub async fn page( &self, per_page: u64, page: u64, ) -> super::Result<(u64, Vec)> { let paginator = Package::find() .order_by_asc(package::Column::Id) .paginate(&self.conn, per_page); let packages = paginator.fetch_page(page).await?; let total_pages = paginator.num_pages().await?; Ok((total_pages, packages)) } pub async fn by_id(&self, id: i32) -> Result> { package::Entity::find_by_id(id).one(&self.conn).await } pub async fn by_fields( &self, repo_id: i32, name: &str, version: Option<&str>, arch: &str, ) -> Result> { let mut query = Package::find() .filter(package::Column::RepoId.eq(repo_id)) .filter(package::Column::Name.eq(name)) .filter(package::Column::Arch.eq(arch)); if let Some(version) = version { query = query.filter(package::Column::Version.eq(version)); } query.one(&self.conn).await } pub async fn delete_with_arch(&self, repo_id: i32, arch: &str) -> Result { Package::delete_many() .filter(package::Column::RepoId.eq(repo_id)) .filter(package::Column::Arch.eq(arch)) .exec(&self.conn) .await } pub async fn insert(&self, repo_id: i32, pkg: crate::repo::package::Package) -> Result<()> { let info = pkg.info; let model = package::ActiveModel { id: NotSet, repo_id: Set(repo_id), base: Set(info.base), name: Set(info.name), version: Set(info.version), arch: Set(info.arch), size: Set(info.size), c_size: Set(info.csize), description: Set(info.description), url: Set(info.url), build_date: Set(info.build_date.to_string()), packager: Set(info.packager), pgp_sig: Set(info.pgpsig), pgp_sig_size: Set(info.pgpsigsize), sha256_sum: Set(info.sha256sum), }; let pkg_entry = model.insert(&self.conn).await?; // Insert all the related tables PackageLicense::insert_many(info.licenses.iter().map(|s| package_license::ActiveModel { package_id: Set(pkg_entry.id), name: Set(s.to_string()), })) .on_empty_do_nothing() .exec(&self.conn) .await?; PackageGroup::insert_many(info.groups.iter().map(|s| package_group::ActiveModel { package_id: Set(pkg_entry.id), name: Set(s.to_string()), })) .on_empty_do_nothing() .exec(&self.conn) .await?; let related = info .conflicts .iter() .map(|s| (PackageRelatedEnum::Conflicts, s)) .chain( info.replaces .iter() .map(|s| (PackageRelatedEnum::Replaces, s)), ) .chain( info.provides .iter() .map(|s| (PackageRelatedEnum::Provides, s)), ) .chain(info.depends.iter().map(|s| (PackageRelatedEnum::Depend, s))) .chain( info.makedepends .iter() .map(|s| (PackageRelatedEnum::Depend, s)), ) .chain( info.checkdepends .iter() .map(|s| (PackageRelatedEnum::Checkdepend, s)), ) .chain( info.optdepends .iter() .map(|s| (PackageRelatedEnum::Optdepend, s)), ); PackageRelated::insert_many(related.map(|(t, s)| package_related::ActiveModel { package_id: Set(pkg_entry.id), r#type: Set(t), name: Set(s.to_string()), })); PackageFile::insert_many(pkg.files.iter().map(|s| package_file::ActiveModel { package_id: Set(pkg_entry.id), path: Set(s.display().to_string()), })) .on_empty_do_nothing() .exec(&self.conn) .await?; Ok(()) } pub async fn full(&self, id: i32) -> Result> { if let Some(entry) = self.by_id(id).await? { let licenses = entry .find_related(PackageLicense) .all(&self.conn) .await? .into_iter() .map(|e| e.name) .collect(); let groups = entry .find_related(PackageGroup) .all(&self.conn) .await? .into_iter() .map(|e| e.name) .collect(); let related = entry .find_related(PackageRelated) .all(&self.conn) .await? .into_iter() .map(|e| (e.r#type, e.name)) .collect(); let files = entry .find_related(PackageFile) .all(&self.conn) .await? .into_iter() .map(|e| e.path) .collect(); Ok(Some(FullPackage { entry, licenses, groups, related, files, })) } else { Ok(None) } } }