From 5b76216ddeda2642c0b14fbac9b2fc312e911b29 Mon Sep 17 00:00:00 2001 From: Peter Smith Date: Thu, 10 Jul 2025 10:05:38 +0100 Subject: [PATCH 1/4] feat: migrate the pagination `order_by` cursor to a multi-field system --- crates/domains/src/blocks/query_params.rs | 7 ++--- .../src/infra/repository/query_builder.rs | 28 +++++++++++++++---- crates/domains/src/inputs/query_params.rs | 11 ++++---- crates/domains/src/messages/query_params.rs | 10 +++---- crates/domains/src/outputs/query_params.rs | 11 ++++---- crates/domains/src/predicates/query_params.rs | 11 ++++---- crates/domains/src/receipts/query_params.rs | 11 ++++---- .../domains/src/transactions/query_params.rs | 10 +++---- crates/domains/src/utxos/query_params.rs | 11 ++++---- 9 files changed, 57 insertions(+), 53 deletions(-) diff --git a/crates/domains/src/blocks/query_params.rs b/crates/domains/src/blocks/query_params.rs index 439f8d23..3dfadf8f 100644 --- a/crates/domains/src/blocks/query_params.rs +++ b/crates/domains/src/blocks/query_params.rs @@ -80,12 +80,9 @@ impl QueryParamsBuilder for BlocksQuery { None, ); - Self::apply_pagination( - &mut query_builder, - &self.pagination, + Self::apply_pagination(&mut query_builder, &self.pagination, &[ "block_height", - None, - ); + ]); query_builder } diff --git a/crates/domains/src/infra/repository/query_builder.rs b/crates/domains/src/infra/repository/query_builder.rs index c50c70b9..f3fd5a97 100644 --- a/crates/domains/src/infra/repository/query_builder.rs +++ b/crates/domains/src/infra/repository/query_builder.rs @@ -139,18 +139,20 @@ pub trait QueryParamsBuilder { fn apply_pagination( query_builder: &mut QueryBuilder, pagination: &QueryPagination, - cursor_field: &str, - join_prefix: Option<&str>, + order_by_fields: &[&str], ) { - let field = Self::prefix_field(cursor_field, join_prefix); match (pagination.first, pagination.last) { (Some(first), None) => { - query_builder.push(format!(" ORDER BY {field} ASC")); + let order_by_sql = + Self::order_by_statement(order_by_fields, OrderBy::Asc); + query_builder.push(order_by_sql); query_builder.push(format!(" LIMIT {first} ")); return; } (None, Some(last)) => { - query_builder.push(format!(" ORDER BY {field} DESC")); + let order_by_sql = + Self::order_by_statement(order_by_fields, OrderBy::Desc); + query_builder.push(order_by_sql); query_builder.push(format!(" LIMIT {last} ")); return; } @@ -159,13 +161,27 @@ pub trait QueryParamsBuilder { let limit = pagination.limit.unwrap_or(DEFAULT_LIMIT); let order_by = pagination.order_by.to_owned().unwrap_or(OrderBy::Desc); - query_builder.push(format!(" ORDER BY {field} {order_by}")); + let order_by_sql = Self::order_by_statement(order_by_fields, order_by); + query_builder.push(order_by_sql); query_builder.push(format!(" LIMIT {limit}")); if let Some(offset) = pagination.offset { query_builder.push(format!(" OFFSET {offset}")); } } + fn order_by_statement( + order_by_fields: &[&str], + order_by: OrderBy, + ) -> String { + let fields = order_by_fields + .iter() + .map(|field| format!("{field} {order_by}")) + .collect::>() + .join(", "); + + format!(" ORDER BY {fields}") + } + fn prefix_field(field: &str, prefix: Option<&str>) -> String { match prefix { Some(prefix) => format!("{prefix}{field}"), diff --git a/crates/domains/src/inputs/query_params.rs b/crates/domains/src/inputs/query_params.rs index 32f1ed43..731c76b4 100644 --- a/crates/domains/src/inputs/query_params.rs +++ b/crates/domains/src/inputs/query_params.rs @@ -146,12 +146,11 @@ impl QueryParamsBuilder for InputsQuery { None, ); - Self::apply_pagination( - &mut query_builder, - &self.pagination, - "cursor", - None, - ); + Self::apply_pagination(&mut query_builder, &self.pagination, &[ + "block_height", + "tx_index", + "input_index", + ]); query_builder } diff --git a/crates/domains/src/messages/query_params.rs b/crates/domains/src/messages/query_params.rs index de679701..f425903b 100644 --- a/crates/domains/src/messages/query_params.rs +++ b/crates/domains/src/messages/query_params.rs @@ -115,12 +115,10 @@ impl QueryParamsBuilder for MessagesQuery { None, ); - Self::apply_pagination( - &mut query_builder, - &self.pagination, - "cursor", - None, - ); + Self::apply_pagination(&mut query_builder, &self.pagination, &[ + "block_height", + "message_index", + ]); query_builder } diff --git a/crates/domains/src/outputs/query_params.rs b/crates/domains/src/outputs/query_params.rs index 162321a7..78ba67b8 100644 --- a/crates/domains/src/outputs/query_params.rs +++ b/crates/domains/src/outputs/query_params.rs @@ -126,12 +126,11 @@ impl QueryParamsBuilder for OutputsQuery { None, ); - Self::apply_pagination( - &mut query_builder, - &self.pagination, - "cursor", - None, - ); + Self::apply_pagination(&mut query_builder, &self.pagination, &[ + "block_height", + "tx_index", + "output_index", + ]); query_builder } diff --git a/crates/domains/src/predicates/query_params.rs b/crates/domains/src/predicates/query_params.rs index c483d084..d8108e03 100644 --- a/crates/domains/src/predicates/query_params.rs +++ b/crates/domains/src/predicates/query_params.rs @@ -95,12 +95,11 @@ impl QueryParamsBuilder for PredicatesQuery { Some("pt."), ); - Self::apply_pagination( - &mut query_builder, - &self.pagination, - "cursor", - Some("pt."), - ); + Self::apply_pagination(&mut query_builder, &self.pagination, &[ + "pt.block_height", + "pt.tx_index", + "pt.input_index", + ]); query_builder } diff --git a/crates/domains/src/receipts/query_params.rs b/crates/domains/src/receipts/query_params.rs index cde45aa5..716fba83 100644 --- a/crates/domains/src/receipts/query_params.rs +++ b/crates/domains/src/receipts/query_params.rs @@ -146,12 +146,11 @@ impl QueryParamsBuilder for ReceiptsQuery { None, ); - Self::apply_pagination( - &mut query_builder, - &self.pagination, - "cursor", - None, - ); + Self::apply_pagination(&mut query_builder, &self.pagination, &[ + "block_height", + "tx_index", + "receipt_index", + ]); query_builder } diff --git a/crates/domains/src/transactions/query_params.rs b/crates/domains/src/transactions/query_params.rs index 24da9122..42744060 100644 --- a/crates/domains/src/transactions/query_params.rs +++ b/crates/domains/src/transactions/query_params.rs @@ -123,12 +123,10 @@ impl QueryParamsBuilder for TransactionsQuery { None, ); - Self::apply_pagination( - &mut query_builder, - &self.pagination, - "cursor", - None, - ); + Self::apply_pagination(&mut query_builder, &self.pagination, &[ + "block_height", + "tx_index", + ]); query_builder } diff --git a/crates/domains/src/utxos/query_params.rs b/crates/domains/src/utxos/query_params.rs index 72c80be2..9dc41f94 100644 --- a/crates/domains/src/utxos/query_params.rs +++ b/crates/domains/src/utxos/query_params.rs @@ -179,12 +179,11 @@ impl QueryParamsBuilder for UtxosQuery { None, ); - Self::apply_pagination( - &mut query_builder, - &self.pagination, - "cursor", - None, - ); + Self::apply_pagination(&mut query_builder, &self.pagination, &[ + "block_height", + "tx_index", + "output_index", + ]); query_builder } From d4294286e0dc87940dda390182a2d64342b7d607 Mon Sep 17 00:00:00 2001 From: Peter Smith Date: Thu, 10 Jul 2025 16:08:57 +0100 Subject: [PATCH 2/4] feat: migrated away from cursor-based pagination --- crates/domains/src/blocks/query_params.rs | 12 ++- crates/domains/src/infra/db/cursor.rs | 8 +- .../src/infra/repository/query_builder.rs | 84 ++++++++++++++----- crates/domains/src/inputs/query_params.rs | 14 ++-- crates/domains/src/messages/query_params.rs | 13 +-- crates/domains/src/outputs/query_params.rs | 14 ++-- crates/domains/src/predicates/query_params.rs | 18 ++-- crates/domains/src/receipts/query_params.rs | 14 ++-- .../domains/src/transactions/query_params.rs | 13 +-- crates/domains/src/utxos/query_params.rs | 14 ++-- 10 files changed, 139 insertions(+), 65 deletions(-) diff --git a/crates/domains/src/blocks/query_params.rs b/crates/domains/src/blocks/query_params.rs index 3dfadf8f..2c483172 100644 --- a/crates/domains/src/blocks/query_params.rs +++ b/crates/domains/src/blocks/query_params.rs @@ -71,18 +71,22 @@ impl QueryParamsBuilder for BlocksQuery { conditions.push(format!("block_height = {}", height)); } + let cursor_fields = &["block_height"]; + Self::apply_conditions( &mut query_builder, &mut conditions, &self.options, &self.pagination, - "block_height", + cursor_fields, None, ); - Self::apply_pagination(&mut query_builder, &self.pagination, &[ - "block_height", - ]); + Self::apply_pagination( + &mut query_builder, + &self.pagination, + cursor_fields, + ); query_builder } diff --git a/crates/domains/src/infra/db/cursor.rs b/crates/domains/src/infra/db/cursor.rs index 2f1803d9..5e1c511c 100644 --- a/crates/domains/src/infra/db/cursor.rs +++ b/crates/domains/src/infra/db/cursor.rs @@ -12,16 +12,22 @@ use serde::{Deserialize, Serialize}; pub struct Cursor(Cow<'static, str>); impl Cursor { + const SEPARATOR: &str = "-"; + pub fn new(fields: &[&dyn ToString]) -> Self { Self(Cow::Owned( fields .iter() .map(|f| f.to_string()) .collect::>() - .join("-"), + .join(Self::SEPARATOR), )) } + pub fn split(&self) -> Vec<&str> { + self.0.split(Self::SEPARATOR).collect() + } + pub fn from_static(s: &'static str) -> Self { Self(Cow::Borrowed(s)) } diff --git a/crates/domains/src/infra/repository/query_builder.rs b/crates/domains/src/infra/repository/query_builder.rs index f3fd5a97..2ce61262 100644 --- a/crates/domains/src/infra/repository/query_builder.rs +++ b/crates/domains/src/infra/repository/query_builder.rs @@ -76,7 +76,7 @@ pub trait QueryParamsBuilder { conditions: &mut Vec, options: &QueryOptions, pagination: &QueryPagination, - cursor_field: &str, + cursor_fields: &[&str], join_prefix: Option<&str>, ) { if let Some(timestamp) = &options.timestamp { @@ -107,27 +107,15 @@ pub trait QueryParamsBuilder { } if let Some(after) = pagination.after.as_ref() { - let field = Self::prefix_field(cursor_field, join_prefix); - if cursor_field == "block_height" { - // When using block height as the cursor field, - // we need to compare the block height as a number, - // not a string. - conditions.push(format!("{field} > {}", after)); - } else { - conditions.push(format!("{field} > '{after}'")); - } + let after_conditions = + Self::create_pagination_conditions(cursor_fields, after, ">"); + conditions.push(after_conditions); } if let Some(before) = pagination.before.as_ref() { - let field = Self::prefix_field(cursor_field, join_prefix); - if cursor_field == "block_height" { - // When using block height as the cursor field, - // we need to compare the block height as a number, - // not a string. - conditions.push(format!("{field} < {}", before)); - } else { - conditions.push(format!("{field} < '{before}'")); - } + let before_conditions = + Self::create_pagination_conditions(cursor_fields, before, "<"); + conditions.push(before_conditions); } if !conditions.is_empty() { @@ -136,6 +124,64 @@ pub trait QueryParamsBuilder { } } + /// Forms the required SQL clauses to replace the cursor with the values + /// + /// Example: + /// + /// ```md + /// block_height transaction_index receipt_index + /// + /// 0001 0 0 + /// 0001 0 1 <--- + /// 0001 0 2 + /// 0001 1 0 + /// 0001 2 0 + /// 0002 0 0 + /// 0002 0 1 + /// ``` + /// + /// ```sql + /// WHERE ( + /// (block_height = 0001 AND transaction_index = 0 AND receipt_index > 1) OR + /// (block_height = 0001 AND transaction_index > 0) OR + /// (block_height > 0001) + /// ) + /// ``` + fn create_pagination_conditions( + cursor_fields: &[&str], + cursor: &Cursor, + operation: &str, + ) -> String { + if cursor_fields.is_empty() || cursor.is_empty() { + return String::new(); + } + + let cursor_values = cursor.split(); + + let result = (0..cursor_values.len()) + .rev() + .map(|i| { + let equality_conditions = (0..i) + .map(|j| { + format!("{} = {}", cursor_fields[j], cursor_values[j]) + }) + .collect::>(); + + let operation_condition = format!( + "{} {} {}", + cursor_fields[i], operation, cursor_values[i] + ); + + let mut all_conditions = equality_conditions; + all_conditions.push(operation_condition); + + format!("({})", all_conditions.join(" AND ")) + }) + .collect::>() + .join(" OR "); + return format!("({})", result); + } + fn apply_pagination( query_builder: &mut QueryBuilder, pagination: &QueryPagination, diff --git a/crates/domains/src/inputs/query_params.rs b/crates/domains/src/inputs/query_params.rs index 731c76b4..eafd977c 100644 --- a/crates/domains/src/inputs/query_params.rs +++ b/crates/domains/src/inputs/query_params.rs @@ -137,20 +137,22 @@ impl QueryParamsBuilder for InputsQuery { )); } + let cursor_fields = &["block_height", "tx_index", "input_index"]; + Self::apply_conditions( &mut query_builder, &mut conditions, &self.options, &self.pagination, - "cursor", + cursor_fields, None, ); - Self::apply_pagination(&mut query_builder, &self.pagination, &[ - "block_height", - "tx_index", - "input_index", - ]); + Self::apply_pagination( + &mut query_builder, + &self.pagination, + cursor_fields, + ); query_builder } diff --git a/crates/domains/src/messages/query_params.rs b/crates/domains/src/messages/query_params.rs index f425903b..2ef2d33b 100644 --- a/crates/domains/src/messages/query_params.rs +++ b/crates/domains/src/messages/query_params.rs @@ -106,19 +106,22 @@ impl QueryParamsBuilder for MessagesQuery { )); } + let cursor_fields = &["block_height", "message_index"]; + Self::apply_conditions( &mut query_builder, &mut conditions, &self.options, &self.pagination, - "cursor", + cursor_fields, None, ); - Self::apply_pagination(&mut query_builder, &self.pagination, &[ - "block_height", - "message_index", - ]); + Self::apply_pagination( + &mut query_builder, + &self.pagination, + cursor_fields, + ); query_builder } diff --git a/crates/domains/src/outputs/query_params.rs b/crates/domains/src/outputs/query_params.rs index 78ba67b8..7686e8c1 100644 --- a/crates/domains/src/outputs/query_params.rs +++ b/crates/domains/src/outputs/query_params.rs @@ -117,20 +117,22 @@ impl QueryParamsBuilder for OutputsQuery { conditions.push(format!("to_address = '{}'", address)); } + let cursor_fields = &["block_height", "tx_index", "output_index"]; + Self::apply_conditions( &mut query_builder, &mut conditions, &self.options, &self.pagination, - "cursor", + cursor_fields, None, ); - Self::apply_pagination(&mut query_builder, &self.pagination, &[ - "block_height", - "tx_index", - "output_index", - ]); + Self::apply_pagination( + &mut query_builder, + &self.pagination, + cursor_fields, + ); query_builder } diff --git a/crates/domains/src/predicates/query_params.rs b/crates/domains/src/predicates/query_params.rs index d8108e03..a92f1d8d 100644 --- a/crates/domains/src/predicates/query_params.rs +++ b/crates/domains/src/predicates/query_params.rs @@ -86,20 +86,24 @@ impl QueryParamsBuilder for PredicatesQuery { conditions.push(format!("pt.asset_id = '{}'", asset)); } + let cursor_fields = + &["pt.block_height", "pt.tx_index", "pt.input_index"]; + let join_prefix = Some("pt."); + Self::apply_conditions( &mut query_builder, &mut conditions, &self.options, &self.pagination, - "cursor", - Some("pt."), + cursor_fields, + join_prefix, ); - Self::apply_pagination(&mut query_builder, &self.pagination, &[ - "pt.block_height", - "pt.tx_index", - "pt.input_index", - ]); + Self::apply_pagination( + &mut query_builder, + &self.pagination, + cursor_fields, + ); query_builder } diff --git a/crates/domains/src/receipts/query_params.rs b/crates/domains/src/receipts/query_params.rs index 716fba83..850851f6 100644 --- a/crates/domains/src/receipts/query_params.rs +++ b/crates/domains/src/receipts/query_params.rs @@ -137,20 +137,22 @@ impl QueryParamsBuilder for ReceiptsQuery { )); } + let cursor_fields = &["block_height", "tx_index", "receipt_index"]; + Self::apply_conditions( &mut query_builder, &mut conditions, &self.options, &self.pagination, - "cursor", + cursor_fields, None, ); - Self::apply_pagination(&mut query_builder, &self.pagination, &[ - "block_height", - "tx_index", - "receipt_index", - ]); + Self::apply_pagination( + &mut query_builder, + &self.pagination, + cursor_fields, + ); query_builder } diff --git a/crates/domains/src/transactions/query_params.rs b/crates/domains/src/transactions/query_params.rs index 42744060..b457030a 100644 --- a/crates/domains/src/transactions/query_params.rs +++ b/crates/domains/src/transactions/query_params.rs @@ -114,19 +114,22 @@ impl QueryParamsBuilder for TransactionsQuery { )); } + let cursor_fields = &["block_height", "tx_index"]; + Self::apply_conditions( &mut query_builder, &mut conditions, &self.options, &self.pagination, - "cursor", + cursor_fields, None, ); - Self::apply_pagination(&mut query_builder, &self.pagination, &[ - "block_height", - "tx_index", - ]); + Self::apply_pagination( + &mut query_builder, + &self.pagination, + cursor_fields, + ); query_builder } diff --git a/crates/domains/src/utxos/query_params.rs b/crates/domains/src/utxos/query_params.rs index 9dc41f94..d4ee1222 100644 --- a/crates/domains/src/utxos/query_params.rs +++ b/crates/domains/src/utxos/query_params.rs @@ -170,20 +170,22 @@ impl QueryParamsBuilder for UtxosQuery { )); } + let cursor_fields = &["block_height", "tx_index", "output_index"]; + Self::apply_conditions( &mut query_builder, &mut conditions, &self.options, &self.pagination, - "cursor", + cursor_fields, None, ); - Self::apply_pagination(&mut query_builder, &self.pagination, &[ - "block_height", - "tx_index", - "output_index", - ]); + Self::apply_pagination( + &mut query_builder, + &self.pagination, + cursor_fields, + ); query_builder } From 58ea54e464d86d12b02e2a0bd7a342b73a5d1906 Mon Sep 17 00:00:00 2001 From: Peter Smith Date: Thu, 10 Jul 2025 16:11:34 +0100 Subject: [PATCH 3/4] refactor: cleaning up the `apply_pagination` logic --- .../src/infra/repository/query_builder.rs | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/crates/domains/src/infra/repository/query_builder.rs b/crates/domains/src/infra/repository/query_builder.rs index 2ce61262..2e6a1714 100644 --- a/crates/domains/src/infra/repository/query_builder.rs +++ b/crates/domains/src/infra/repository/query_builder.rs @@ -179,35 +179,34 @@ pub trait QueryParamsBuilder { }) .collect::>() .join(" OR "); - return format!("({})", result); + format!("({})", result) } fn apply_pagination( query_builder: &mut QueryBuilder, pagination: &QueryPagination, - order_by_fields: &[&str], + cursor_fields: &[&str], ) { + let order_by: OrderBy; + let limit: i32; + match (pagination.first, pagination.last) { (Some(first), None) => { - let order_by_sql = - Self::order_by_statement(order_by_fields, OrderBy::Asc); - query_builder.push(order_by_sql); - query_builder.push(format!(" LIMIT {first} ")); - return; + order_by = OrderBy::Asc; + limit = first; } (None, Some(last)) => { - let order_by_sql = - Self::order_by_statement(order_by_fields, OrderBy::Desc); - query_builder.push(order_by_sql); - query_builder.push(format!(" LIMIT {last} ")); - return; + order_by = OrderBy::Desc; + limit = last; + } + _ => { + limit = pagination.limit.unwrap_or(DEFAULT_LIMIT); + order_by = + pagination.order_by.to_owned().unwrap_or(OrderBy::Desc); } - _ => {} } - let limit = pagination.limit.unwrap_or(DEFAULT_LIMIT); - let order_by = pagination.order_by.to_owned().unwrap_or(OrderBy::Desc); - let order_by_sql = Self::order_by_statement(order_by_fields, order_by); + let order_by_sql = Self::order_by_statement(cursor_fields, order_by); query_builder.push(order_by_sql); query_builder.push(format!(" LIMIT {limit}")); if let Some(offset) = pagination.offset { From fb4d0184c18632dfa282ca246dec6caee5184148 Mon Sep 17 00:00:00 2001 From: Peter Smith Date: Mon, 14 Jul 2025 09:27:44 +0100 Subject: [PATCH 4/4] refactor: re-added the join_prefix --- crates/domains/src/blocks/query_params.rs | 1 + .../src/infra/repository/query_builder.rs | 27 +++++++++++++++---- crates/domains/src/inputs/query_params.rs | 1 + crates/domains/src/messages/query_params.rs | 1 + crates/domains/src/outputs/query_params.rs | 1 + crates/domains/src/predicates/query_params.rs | 4 +-- crates/domains/src/receipts/query_params.rs | 1 + .../domains/src/transactions/query_params.rs | 1 + crates/domains/src/utxos/query_params.rs | 1 + 9 files changed, 31 insertions(+), 7 deletions(-) diff --git a/crates/domains/src/blocks/query_params.rs b/crates/domains/src/blocks/query_params.rs index 2c483172..386a06ac 100644 --- a/crates/domains/src/blocks/query_params.rs +++ b/crates/domains/src/blocks/query_params.rs @@ -86,6 +86,7 @@ impl QueryParamsBuilder for BlocksQuery { &mut query_builder, &self.pagination, cursor_fields, + None, ); query_builder diff --git a/crates/domains/src/infra/repository/query_builder.rs b/crates/domains/src/infra/repository/query_builder.rs index 2e6a1714..7641b6b1 100644 --- a/crates/domains/src/infra/repository/query_builder.rs +++ b/crates/domains/src/infra/repository/query_builder.rs @@ -107,14 +107,22 @@ pub trait QueryParamsBuilder { } if let Some(after) = pagination.after.as_ref() { - let after_conditions = - Self::create_pagination_conditions(cursor_fields, after, ">"); + let after_conditions = Self::create_pagination_conditions( + cursor_fields, + after, + ">", + join_prefix, + ); conditions.push(after_conditions); } if let Some(before) = pagination.before.as_ref() { - let before_conditions = - Self::create_pagination_conditions(cursor_fields, before, "<"); + let before_conditions = Self::create_pagination_conditions( + cursor_fields, + before, + "<", + join_prefix, + ); conditions.push(before_conditions); } @@ -151,11 +159,16 @@ pub trait QueryParamsBuilder { cursor_fields: &[&str], cursor: &Cursor, operation: &str, + join_prefix: Option<&str>, ) -> String { if cursor_fields.is_empty() || cursor.is_empty() { return String::new(); } + let cursor_fields = cursor_fields + .iter() + .map(|f| Self::prefix_field(f, join_prefix)) + .collect::>(); let cursor_values = cursor.split(); let result = (0..cursor_values.len()) @@ -186,6 +199,7 @@ pub trait QueryParamsBuilder { query_builder: &mut QueryBuilder, pagination: &QueryPagination, cursor_fields: &[&str], + join_prefix: Option<&str>, ) { let order_by: OrderBy; let limit: i32; @@ -206,7 +220,8 @@ pub trait QueryParamsBuilder { } } - let order_by_sql = Self::order_by_statement(cursor_fields, order_by); + let order_by_sql = + Self::order_by_statement(cursor_fields, order_by, join_prefix); query_builder.push(order_by_sql); query_builder.push(format!(" LIMIT {limit}")); if let Some(offset) = pagination.offset { @@ -217,9 +232,11 @@ pub trait QueryParamsBuilder { fn order_by_statement( order_by_fields: &[&str], order_by: OrderBy, + join_prefix: Option<&str>, ) -> String { let fields = order_by_fields .iter() + .map(|field| Self::prefix_field(field, join_prefix)) .map(|field| format!("{field} {order_by}")) .collect::>() .join(", "); diff --git a/crates/domains/src/inputs/query_params.rs b/crates/domains/src/inputs/query_params.rs index eafd977c..7adfca4c 100644 --- a/crates/domains/src/inputs/query_params.rs +++ b/crates/domains/src/inputs/query_params.rs @@ -152,6 +152,7 @@ impl QueryParamsBuilder for InputsQuery { &mut query_builder, &self.pagination, cursor_fields, + None, ); query_builder diff --git a/crates/domains/src/messages/query_params.rs b/crates/domains/src/messages/query_params.rs index 2ef2d33b..8002889e 100644 --- a/crates/domains/src/messages/query_params.rs +++ b/crates/domains/src/messages/query_params.rs @@ -121,6 +121,7 @@ impl QueryParamsBuilder for MessagesQuery { &mut query_builder, &self.pagination, cursor_fields, + None, ); query_builder diff --git a/crates/domains/src/outputs/query_params.rs b/crates/domains/src/outputs/query_params.rs index 7686e8c1..eb487f1c 100644 --- a/crates/domains/src/outputs/query_params.rs +++ b/crates/domains/src/outputs/query_params.rs @@ -132,6 +132,7 @@ impl QueryParamsBuilder for OutputsQuery { &mut query_builder, &self.pagination, cursor_fields, + None, ); query_builder diff --git a/crates/domains/src/predicates/query_params.rs b/crates/domains/src/predicates/query_params.rs index a92f1d8d..f81f60e6 100644 --- a/crates/domains/src/predicates/query_params.rs +++ b/crates/domains/src/predicates/query_params.rs @@ -86,8 +86,7 @@ impl QueryParamsBuilder for PredicatesQuery { conditions.push(format!("pt.asset_id = '{}'", asset)); } - let cursor_fields = - &["pt.block_height", "pt.tx_index", "pt.input_index"]; + let cursor_fields = &["block_height", "tx_index", "input_index"]; let join_prefix = Some("pt."); Self::apply_conditions( @@ -103,6 +102,7 @@ impl QueryParamsBuilder for PredicatesQuery { &mut query_builder, &self.pagination, cursor_fields, + join_prefix, ); query_builder diff --git a/crates/domains/src/receipts/query_params.rs b/crates/domains/src/receipts/query_params.rs index 850851f6..2028c08b 100644 --- a/crates/domains/src/receipts/query_params.rs +++ b/crates/domains/src/receipts/query_params.rs @@ -152,6 +152,7 @@ impl QueryParamsBuilder for ReceiptsQuery { &mut query_builder, &self.pagination, cursor_fields, + None, ); query_builder diff --git a/crates/domains/src/transactions/query_params.rs b/crates/domains/src/transactions/query_params.rs index b457030a..9cdb71c4 100644 --- a/crates/domains/src/transactions/query_params.rs +++ b/crates/domains/src/transactions/query_params.rs @@ -129,6 +129,7 @@ impl QueryParamsBuilder for TransactionsQuery { &mut query_builder, &self.pagination, cursor_fields, + None, ); query_builder diff --git a/crates/domains/src/utxos/query_params.rs b/crates/domains/src/utxos/query_params.rs index d4ee1222..3222990f 100644 --- a/crates/domains/src/utxos/query_params.rs +++ b/crates/domains/src/utxos/query_params.rs @@ -185,6 +185,7 @@ impl QueryParamsBuilder for UtxosQuery { &mut query_builder, &self.pagination, cursor_fields, + None, ); query_builder