-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
172 additions
and
15 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ use app_context::SqsProducer; | |
|
||
mod app_context; | ||
mod error; | ||
mod models; | ||
mod types; | ||
|
||
#[tokio::main] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
use chrono::{DateTime, Utc}; | ||
use macon::Builder; | ||
use serde::{Deserialize, Serialize}; | ||
use sqlx::PgPool; | ||
|
||
use crate::error::HistoFluxError; | ||
|
||
#[derive(sqlx::FromRow, Debug, PartialEq, Clone, Builder, Serialize, Deserialize)] | ||
#[sqlx(type_name = "histoflux_cursor")] | ||
pub struct HistoFluxCursor { | ||
pub id: i64, | ||
pub last_processed_id: i64, | ||
pub updated_at: DateTime<Utc>, | ||
} | ||
|
||
impl Default for HistoFluxCursor { | ||
fn default() -> Self { | ||
Self { | ||
id: 1, | ||
last_processed_id: 0, | ||
updated_at: Utc::now(), | ||
} | ||
} | ||
} | ||
|
||
impl HistoFluxCursor { | ||
/// Upsert the cursor into the DB. | ||
pub async fn upsert(&self, db: &PgPool, schema: &str) -> Result<Self, HistoFluxError> { | ||
let query = format!( | ||
r#" | ||
INSERT INTO {schema}.histoflux_cursor (id, last_processed_id) | ||
VALUES ($1::numeric, $2) | ||
ON CONFLICT (id) DO UPDATE SET | ||
last_processed_id = $2, | ||
updated_at = CURRENT_TIMESTAMP | ||
RETURNING id, last_processed_id, updated_at::timestamptz as updated_at | ||
"#, | ||
schema = schema, | ||
); | ||
|
||
sqlx::query_as::<_, HistoFluxCursor>(&query) | ||
.bind(self.id) | ||
.bind(self.last_processed_id) | ||
.fetch_one(db) | ||
.await | ||
.map_err(HistoFluxError::SQLXError) | ||
} | ||
|
||
/// Find the cursor in the DB. | ||
pub async fn find(db: &PgPool, schema: &str) -> Result<Option<Self>, HistoFluxError> { | ||
let query = format!( | ||
r#" | ||
SELECT id, last_processed_id, updated_at::timestamptz as updated_at | ||
FROM {}.histoflux_cursor | ||
WHERE id = 1 | ||
"#, | ||
schema, | ||
); | ||
|
||
sqlx::query_as::<_, HistoFluxCursor>(&query) | ||
.fetch_optional(db) | ||
.await | ||
.map_err(HistoFluxError::SQLXError) | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
use chrono::Duration; | ||
use models::test_helpers::{setup_test_db, TEST_PROXY_SCHEMA}; | ||
|
||
#[sqlx::test] | ||
async fn test_cursor_upsert_and_find() { | ||
let pool = setup_test_db().await; | ||
|
||
let cursor = HistoFluxCursor { | ||
id: 1, | ||
last_processed_id: 100, | ||
updated_at: Utc::now(), | ||
}; | ||
|
||
// First upsert | ||
let saved = cursor.upsert(&pool, TEST_PROXY_SCHEMA).await.unwrap(); | ||
|
||
// Find and verify first insert | ||
let found = HistoFluxCursor::find(&pool, TEST_PROXY_SCHEMA) | ||
.await | ||
.unwrap() | ||
.unwrap(); | ||
assert_eq!(found.last_processed_id, 100); | ||
assert_eq!(found.updated_at, saved.updated_at); | ||
|
||
// Wait a bit to ensure timestamp changes | ||
tokio::time::sleep(Duration::milliseconds(100).to_std().unwrap()).await; | ||
|
||
// Second upsert with new block number | ||
let cursor2 = HistoFluxCursor { | ||
id: 1, | ||
last_processed_id: 200, | ||
updated_at: found.updated_at, | ||
}; | ||
let saved2 = cursor2.upsert(&pool, TEST_PROXY_SCHEMA).await.unwrap(); | ||
|
||
// Find and verify update | ||
let found2 = HistoFluxCursor::find(&pool, TEST_PROXY_SCHEMA) | ||
.await | ||
.unwrap() | ||
.unwrap(); | ||
assert_eq!(found2.last_processed_id, 200); | ||
assert_eq!(found2.updated_at, saved2.updated_at); | ||
|
||
// Verify updated_at changed | ||
assert!(found2.updated_at > found.updated_at); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub mod cursor; |
1 change: 1 addition & 0 deletions
1
indexer-and-cache-migrations/20250120145501_histoflux_cursor.down.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
DROP TABLE base_sepolia_indexer.histoflux_cursor; |
10 changes: 10 additions & 0 deletions
10
indexer-and-cache-migrations/20250120145501_histoflux_cursor.up.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
-- Add migration script here | ||
CREATE TABLE base_sepolia_indexer.histoflux_cursor( | ||
id BIGINT PRIMARY KEY, | ||
last_processed_id BIGINT NOT NULL, | ||
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP | ||
); | ||
|
||
CREATE INDEX idx_histoflux_cursor_id ON base_sepolia_indexer.histoflux_cursor(id); | ||
|
||
INSERT INTO base_sepolia_indexer.histoflux_cursor (id, last_processed_id) VALUES (1, 50232); |