sui_indexer_alt_schema/
objects.rs

1// Copyright (c) Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use anyhow::Context;
5use diesel::{
6    FromSqlRow, backend::Backend, deserialize, expression::AsExpression, prelude::*, serialize,
7    sql_types::SmallInt,
8};
9
10use sui_field_count::FieldCount;
11use sui_types::object::{Object, Owner};
12
13use crate::schema::{
14    coin_balance_buckets, coin_balance_buckets_deletion_reference, kv_objects, obj_info,
15    obj_info_deletion_reference, obj_versions,
16};
17
18#[derive(Insertable, Debug, Clone, FieldCount, Queryable)]
19#[diesel(table_name = kv_objects, primary_key(object_id, object_version))]
20#[diesel(treat_none_as_default_value = false)]
21pub struct StoredObject {
22    pub object_id: Vec<u8>,
23    pub object_version: i64,
24    pub serialized_object: Option<Vec<u8>>,
25}
26
27#[derive(
28    Insertable, Selectable, Debug, Clone, PartialEq, Eq, FieldCount, Queryable, QueryableByName,
29)]
30#[diesel(table_name = obj_versions, primary_key(object_id, object_version))]
31pub struct StoredObjVersion {
32    pub object_id: Vec<u8>,
33    pub object_version: i64,
34    pub object_digest: Option<Vec<u8>>,
35    pub cp_sequence_number: i64,
36}
37
38#[derive(AsExpression, FromSqlRow, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
39#[diesel(sql_type = SmallInt)]
40#[repr(i16)]
41pub enum StoredOwnerKind {
42    Immutable = 0,
43    Address = 1,
44    Object = 2,
45    Shared = 3,
46}
47
48#[derive(AsExpression, FromSqlRow, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
49#[diesel(sql_type = SmallInt)]
50#[repr(i16)]
51pub enum StoredCoinOwnerKind {
52    Fastpath = 0,
53    Consensus = 1,
54}
55
56#[derive(Insertable, Debug, Clone, FieldCount, Queryable)]
57#[diesel(table_name = obj_info, primary_key(object_id, cp_sequence_number))]
58#[diesel(treat_none_as_default_value = false)]
59pub struct StoredObjInfo {
60    pub object_id: Vec<u8>,
61    pub cp_sequence_number: i64,
62    pub owner_kind: Option<StoredOwnerKind>,
63    pub owner_id: Option<Vec<u8>>,
64    pub package: Option<Vec<u8>>,
65    pub module: Option<String>,
66    pub name: Option<String>,
67    pub instantiation: Option<Vec<u8>>,
68}
69
70#[derive(Insertable, Debug, Clone, FieldCount, Queryable)]
71#[diesel(table_name = obj_info_deletion_reference, primary_key(cp_sequence_number, object_id))]
72pub struct StoredObjInfoDeletionReference {
73    pub object_id: Vec<u8>,
74    pub cp_sequence_number: i64,
75}
76
77#[derive(Insertable, Queryable, Debug, Clone, FieldCount, Eq, PartialEq)]
78#[diesel(table_name = coin_balance_buckets, primary_key(object_id, cp_sequence_number))]
79#[diesel(treat_none_as_default_value = false)]
80pub struct StoredCoinBalanceBucket {
81    pub object_id: Vec<u8>,
82    pub cp_sequence_number: i64,
83    pub owner_kind: Option<StoredCoinOwnerKind>,
84    pub owner_id: Option<Vec<u8>>,
85    pub coin_type: Option<Vec<u8>>,
86    pub coin_balance_bucket: Option<i16>,
87}
88
89#[derive(Insertable, Queryable, Debug, Clone, FieldCount, Eq, PartialEq)]
90#[diesel(table_name = coin_balance_buckets_deletion_reference, primary_key(cp_sequence_number, object_id))]
91pub struct StoredCoinBalanceBucketDeletionReference {
92    pub object_id: Vec<u8>,
93    pub cp_sequence_number: i64,
94}
95
96impl StoredObjInfo {
97    pub fn from_object(object: &Object, cp_sequence_number: i64) -> anyhow::Result<Self> {
98        let type_ = object.type_();
99        Ok(Self {
100            object_id: object.id().to_vec(),
101            cp_sequence_number,
102            owner_kind: Some(match object.owner() {
103                Owner::AddressOwner(_) => StoredOwnerKind::Address,
104                Owner::ObjectOwner(_) => StoredOwnerKind::Object,
105                Owner::Shared { .. } => StoredOwnerKind::Shared,
106                Owner::Immutable => StoredOwnerKind::Immutable,
107                // We do not distinguish between fastpath owned and consensus owned
108                // objects.
109                Owner::ConsensusAddressOwner { .. } => StoredOwnerKind::Address,
110            }),
111
112            owner_id: match object.owner() {
113                Owner::AddressOwner(a) => Some(a.to_vec()),
114                Owner::ObjectOwner(o) => Some(o.to_vec()),
115                Owner::Shared { .. } | Owner::Immutable => None,
116                Owner::ConsensusAddressOwner { owner, .. } => Some(owner.to_vec()),
117            },
118
119            package: type_.map(|t| t.address().to_vec()),
120            module: type_.map(|t| t.module().to_string()),
121            name: type_.map(|t| t.name().to_string()),
122            instantiation: type_
123                .map(|t| bcs::to_bytes(&t.type_params()))
124                .transpose()
125                .with_context(|| {
126                    format!(
127                        "Failed to serialize type parameters for {}",
128                        object.id().to_canonical_display(/* with_prefix */ true),
129                    )
130                })?,
131        })
132    }
133}
134
135impl<DB: Backend> serialize::ToSql<SmallInt, DB> for StoredOwnerKind
136where
137    i16: serialize::ToSql<SmallInt, DB>,
138{
139    fn to_sql<'b>(&'b self, out: &mut serialize::Output<'b, '_, DB>) -> serialize::Result {
140        match self {
141            StoredOwnerKind::Immutable => 0.to_sql(out),
142            StoredOwnerKind::Address => 1.to_sql(out),
143            StoredOwnerKind::Object => 2.to_sql(out),
144            StoredOwnerKind::Shared => 3.to_sql(out),
145        }
146    }
147}
148
149impl<DB: Backend> deserialize::FromSql<SmallInt, DB> for StoredOwnerKind
150where
151    i16: deserialize::FromSql<SmallInt, DB>,
152{
153    fn from_sql(raw: DB::RawValue<'_>) -> deserialize::Result<Self> {
154        Ok(match i16::from_sql(raw)? {
155            0 => StoredOwnerKind::Immutable,
156            1 => StoredOwnerKind::Address,
157            2 => StoredOwnerKind::Object,
158            3 => StoredOwnerKind::Shared,
159            o => return Err(format!("Unexpected StoredOwnerKind: {o}").into()),
160        })
161    }
162}
163
164impl<DB: Backend> serialize::ToSql<SmallInt, DB> for StoredCoinOwnerKind
165where
166    i16: serialize::ToSql<SmallInt, DB>,
167{
168    fn to_sql<'b>(&'b self, out: &mut serialize::Output<'b, '_, DB>) -> serialize::Result {
169        match self {
170            StoredCoinOwnerKind::Fastpath => 0.to_sql(out),
171            StoredCoinOwnerKind::Consensus => 1.to_sql(out),
172        }
173    }
174}
175
176impl<DB: Backend> deserialize::FromSql<SmallInt, DB> for StoredCoinOwnerKind
177where
178    i16: deserialize::FromSql<SmallInt, DB>,
179{
180    fn from_sql(raw: DB::RawValue<'_>) -> deserialize::Result<Self> {
181        Ok(match i16::from_sql(raw)? {
182            0 => StoredCoinOwnerKind::Fastpath,
183            1 => StoredCoinOwnerKind::Consensus,
184            o => return Err(format!("Unexpected StoredCoinOwnerKind: {o}").into()),
185        })
186    }
187}