iota_indexer/models/
move_call_metrics.rs

1// Copyright (c) Mysten Labs, Inc.
2// Modifications Copyright (c) 2024 IOTA Stiftung
3// SPDX-License-Identifier: Apache-2.0
4
5use std::str::FromStr;
6
7use diesel::{
8    QueryableByName,
9    prelude::*,
10    sql_types::{BigInt, Binary, Text},
11};
12use iota_json_rpc_types::MoveFunctionName;
13use iota_types::base_types::ObjectID;
14use move_core_types::identifier::Identifier;
15
16use crate::{
17    errors::IndexerError,
18    schema::{move_call_metrics, move_calls},
19};
20
21#[derive(Clone, Debug, Queryable, Insertable)]
22#[diesel(table_name = move_calls)]
23pub struct StoredMoveCall {
24    pub transaction_sequence_number: i64,
25    pub checkpoint_sequence_number: i64,
26    pub epoch: i64,
27    pub move_package: Vec<u8>,
28    pub move_module: String,
29    pub move_function: String,
30}
31
32#[derive(Clone, Debug, Insertable)]
33#[diesel(table_name = move_call_metrics)]
34pub struct StoredMoveCallMetrics {
35    pub id: Option<i64>,
36    pub epoch: i64,
37    pub day: i64,
38    pub move_package: String,
39    pub move_module: String,
40    pub move_function: String,
41    pub count: i64,
42}
43
44impl Default for StoredMoveCallMetrics {
45    fn default() -> Self {
46        Self {
47            id: None,
48            epoch: -1,
49            day: -1,
50            move_package: "".to_string(),
51            move_module: "".to_string(),
52            move_function: "".to_string(),
53            count: -1,
54        }
55    }
56}
57
58// for auto-incremented id, the committed id is None, so Option<i64>,
59// but when querying, the returned type is i64, thus a separate type is needed.
60#[derive(Clone, Debug, Queryable, QueryableByName)]
61#[diesel(table_name = move_call_metrics)]
62pub struct QueriedMoveCallMetrics {
63    pub id: i64,
64    pub epoch: i64,
65    pub day: i64,
66    pub move_package: String,
67    pub move_module: String,
68    pub move_function: String,
69    pub count: i64,
70}
71
72impl TryInto<(MoveFunctionName, usize)> for QueriedMoveCallMetrics {
73    type Error = IndexerError;
74
75    fn try_into(self) -> Result<(MoveFunctionName, usize), Self::Error> {
76        let package = ObjectID::from_str(&self.move_package)?;
77        let module = Identifier::from_str(&self.move_module)?;
78        let function = Identifier::from_str(&self.move_function)?;
79        Ok((
80            MoveFunctionName {
81                package,
82                module,
83                function,
84            },
85            self.count as usize,
86        ))
87    }
88}
89
90impl From<QueriedMoveCallMetrics> for StoredMoveCallMetrics {
91    fn from(q: QueriedMoveCallMetrics) -> Self {
92        StoredMoveCallMetrics {
93            id: Some(q.id),
94            epoch: q.epoch,
95            day: q.day,
96            move_package: q.move_package,
97            move_module: q.move_module,
98            move_function: q.move_function,
99            count: q.count,
100        }
101    }
102}
103
104#[derive(QueryableByName, Debug, Clone, Default)]
105pub struct QueriedMoveMetrics {
106    #[diesel(sql_type = BigInt)]
107    pub epoch: i64,
108    #[diesel(sql_type = BigInt)]
109    pub day: i64,
110    #[diesel(sql_type = Binary)]
111    pub move_package: Vec<u8>,
112    #[diesel(sql_type = Text)]
113    pub move_module: String,
114    #[diesel(sql_type = Text)]
115    pub move_function: String,
116    #[diesel(sql_type = BigInt)]
117    pub count: i64,
118}
119
120pub fn build_move_call_metric_query(epoch: i64, days: i64) -> String {
121    format!("SELECT {}::BIGINT AS epoch, {}::BIGINT AS day, move_package, move_module, move_function, COUNT(*)::BIGINT AS count
122        FROM move_calls
123        WHERE epoch >= {}
124        GROUP BY move_package, move_module, move_function
125        ORDER BY count DESC
126        LIMIT 10;", epoch, days, epoch - days)
127}