iota_graphql_rpc/data/
package_resolver.rs1use std::{
6 collections::{BTreeSet, HashMap},
7 sync::Arc,
8};
9
10use async_graphql::dataloader::Loader;
11use async_trait::async_trait;
12use diesel::{ExpressionMethods, QueryDsl};
13use iota_indexer::{models::packages::StoredPackage, schema::packages};
14use iota_package_resolver::{
15 Package, PackageStore, PackageStoreWithLruCache, Resolver, Result,
16 error::Error as PackageResolverError,
17};
18use move_core_types::account_address::AccountAddress;
19
20use crate::data::{DataLoader, Db, DbConnection, QueryExecutor};
21
22const STORE: &str = "PostgresDB";
23
24pub(crate) type PackageCache = PackageStoreWithLruCache<DbPackageStore>;
25pub(crate) type PackageResolver = Arc<Resolver<PackageCache>>;
26
27pub struct DbPackageStore(DataLoader);
30
31#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)]
33struct PackageKey(AccountAddress);
34
35impl DbPackageStore {
36 pub fn new(loader: DataLoader) -> Self {
37 Self(loader)
38 }
39}
40
41#[async_trait]
42impl PackageStore for DbPackageStore {
43 async fn fetch(&self, id: AccountAddress) -> Result<Arc<Package>> {
44 let Self(DataLoader(loader)) = self;
45 let Some(package) = loader.load_one(PackageKey(id)).await? else {
46 return Err(PackageResolverError::PackageNotFound(id));
47 };
48
49 Ok(package)
50 }
51}
52
53impl Loader<PackageKey> for Db {
54 type Value = Arc<Package>;
55 type Error = PackageResolverError;
56
57 async fn load(&self, keys: &[PackageKey]) -> Result<HashMap<PackageKey, Arc<Package>>> {
58 use packages::dsl;
59
60 let ids: BTreeSet<_> = keys.iter().map(|PackageKey(id)| id.to_vec()).collect();
61 let stored_packages: Vec<StoredPackage> = self
62 .execute(move |conn| {
63 conn.results(move || {
64 dsl::packages.filter(dsl::package_id.eq_any(ids.iter().cloned()))
65 })
66 })
67 .await
68 .map_err(|e| PackageResolverError::Store {
69 store: STORE,
70 source: Arc::new(e),
71 })?;
72
73 let mut id_to_package = HashMap::new();
74 for stored_package in stored_packages {
75 let move_package = bcs::from_bytes(&stored_package.move_package)?;
76 let package = Package::read_from_package(&move_package)?;
77 id_to_package.insert(PackageKey(*move_package.id()), Arc::new(package));
78 }
79
80 Ok(id_to_package)
81 }
82}