iota_graphql_rpc/types/event/
lookups.rs1use std::fmt::Write;
6
7use crate::{
8 data::pg::bytea_literal,
9 filter, query,
10 raw_query::RawQuery,
11 types::{
12 cursor::Page,
13 digest::Digest,
14 event::Cursor,
15 iota_address::IotaAddress,
16 type_filter::{ModuleFilter, TypeFilter},
17 },
18};
19
20fn select_ev(sender: Option<IotaAddress>, from: &str) -> RawQuery {
21 let query = query!(format!(
22 "SELECT tx_sequence_number, event_sequence_number FROM {}",
23 from
24 ));
25
26 if let Some(sender) = sender {
27 return query.filter(format!("sender = {}", bytea_literal(sender.as_slice())));
28 }
29
30 query
31}
32
33pub(crate) fn select_sender(sender: IotaAddress) -> RawQuery {
34 select_ev(Some(sender), "event_senders")
35}
36
37pub(crate) fn select_event_type(event_type: &TypeFilter, sender: Option<IotaAddress>) -> RawQuery {
38 match event_type {
39 TypeFilter::ByModule(ModuleFilter::ByPackage(p)) => {
40 filter!(
41 select_ev(sender, "event_struct_package"),
42 format!("package = {}", bytea_literal(p.as_slice()))
43 )
44 }
45 TypeFilter::ByModule(ModuleFilter::ByModule(p, m)) => {
46 filter!(
47 select_ev(sender, "event_struct_module"),
48 format!(
49 "package = {} and module = {{}}",
50 bytea_literal(p.as_slice())
51 ),
52 m
53 )
54 }
55 TypeFilter::ByType(tag) => {
56 let package = tag.address;
57 let module = tag.module.to_string();
58 let mut name = tag.name.as_str().to_owned();
59 let (table, col_name) = if tag.type_params.is_empty() {
60 ("event_struct_name", "type_name")
61 } else {
62 let mut prefix = "<";
63 for param in &tag.type_params {
64 name += prefix;
65 write!(
67 name,
68 "{}",
69 param.to_canonical_display(true)
70 )
71 .unwrap();
72 prefix = ", ";
73 }
74 name += ">";
75 ("event_struct_instantiation", "type_instantiation")
76 };
77
78 filter!(
79 select_ev(sender, table),
80 format!(
81 "package = {} and module = {{}} and {} = {{}}",
82 bytea_literal(package.as_slice()),
83 col_name
84 ),
85 module,
86 name
87 )
88 }
89 }
90}
91
92pub(crate) fn select_emit_module(
93 emit_module: &ModuleFilter,
94 sender: Option<IotaAddress>,
95) -> RawQuery {
96 match emit_module {
97 ModuleFilter::ByPackage(p) => {
98 filter!(
99 select_ev(sender, "event_emit_package"),
100 format!("package = {}", bytea_literal(p.as_slice()))
101 )
102 }
103 ModuleFilter::ByModule(p, m) => {
104 filter!(
105 select_ev(sender, "event_emit_module"),
106 format!(
107 "package = {} and module = {{}}",
108 bytea_literal(p.as_slice())
109 ),
110 m
111 )
112 }
113 }
114}
115
116pub(crate) fn add_bounds(
121 mut query: RawQuery,
122 tx_digest_filter: &Option<Digest>,
123 page: &Page<Cursor>,
124 tx_hi: i64,
125) -> RawQuery {
126 query = filter!(query, format!("tx_sequence_number < {}", tx_hi));
127
128 if let Some(after) = page.after() {
129 query = filter!(
130 query,
131 format!(
132 "ROW(tx_sequence_number, event_sequence_number) >= ({}, {})",
133 after.tx, after.e
134 )
135 );
136 }
137
138 if let Some(before) = page.before() {
139 query = filter!(
140 query,
141 format!(
142 "ROW(tx_sequence_number, event_sequence_number) <= ({}, {})",
143 before.tx, before.e
144 )
145 );
146 }
147
148 if let Some(digest) = tx_digest_filter {
149 query = filter!(
150 query,
151 format!(
152 "tx_sequence_number = (SELECT tx_sequence_number FROM tx_digests WHERE tx_digest = {})",
153 bytea_literal(digest.as_slice()),
154 )
155 );
156 }
157
158 query
159}