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