0.7.25
This commit is contained in:
@@ -15,7 +15,7 @@ pub async fn insert_analysis_signal(
|
||||
"cannot serialize analysis signal payload: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
@@ -49,10 +49,10 @@ VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
"cannot insert kb_analysis_signals on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
Ok(query_result.last_insert_rowid())
|
||||
}
|
||||
return Ok(query_result.last_insert_rowid());
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ LIMIT ?
|
||||
"cannot list analysis signals on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -103,8 +103,8 @@ LIMIT ?
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -58,10 +58,10 @@ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
"cannot insert kb_chain_instructions on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
Ok(insert_result.last_insert_rowid())
|
||||
}
|
||||
return Ok(insert_result.last_insert_rowid());
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ ORDER BY instruction_index ASC, inner_instruction_index ASC, id ASC
|
||||
"cannot list kb_chain_instructions for transaction_id '{}' on sqlite: {}",
|
||||
transaction_id, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -114,8 +114,8 @@ ORDER BY instruction_index ASC, inner_instruction_index ASC, id ASC
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,8 +141,8 @@ WHERE transaction_id = ?
|
||||
transaction_id, error
|
||||
)));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
return Ok(());
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,9 +163,9 @@ mod tests {
|
||||
use_wal: true,
|
||||
},
|
||||
};
|
||||
crate::KbDatabase::connect_and_initialize(&config)
|
||||
return crate::KbDatabase::connect_and_initialize(&config)
|
||||
.await
|
||||
.expect("database init must succeed")
|
||||
.expect("database init must succeed");
|
||||
}
|
||||
|
||||
async fn make_transaction(database: &crate::KbDatabase) -> i64 {
|
||||
@@ -179,9 +179,9 @@ mod tests {
|
||||
None,
|
||||
r#"{"transaction":{"message":{"instructions":[]}}}"#.to_string(),
|
||||
);
|
||||
crate::upsert_chain_transaction(database, &dto)
|
||||
return crate::upsert_chain_transaction(database, &dto)
|
||||
.await
|
||||
.expect("chain transaction upsert must succeed")
|
||||
.expect("chain transaction upsert must succeed");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
||||
@@ -15,7 +15,7 @@ pub async fn upsert_chain_slot(
|
||||
"cannot convert chain slot '{}' to i64: {}",
|
||||
dto.slot, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let parent_slot = match dto.parent_slot {
|
||||
Some(parent_slot) => {
|
||||
@@ -27,9 +27,9 @@ pub async fn upsert_chain_slot(
|
||||
"cannot convert chain parent_slot '{}' to i64: {}",
|
||||
parent_slot, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
None => None,
|
||||
};
|
||||
match database.connection() {
|
||||
@@ -63,8 +63,8 @@ ON CONFLICT(slot) DO UPDATE SET
|
||||
error
|
||||
)));
|
||||
}
|
||||
Ok(dto.slot)
|
||||
}
|
||||
return Ok(dto.slot);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ pub async fn get_chain_slot(
|
||||
"cannot convert requested chain slot '{}' to i64: {}",
|
||||
slot, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
@@ -108,19 +108,19 @@ LIMIT 1
|
||||
"cannot fetch kb_chain_slots for slot '{}' on sqlite: {}",
|
||||
slot, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => {
|
||||
let dto_result = crate::KbChainSlotDto::try_from(entity);
|
||||
match dto_result {
|
||||
Ok(dto) => Ok(Some(dto)),
|
||||
Err(error) => Err(error),
|
||||
Ok(dto) => return Ok(Some(dto)),
|
||||
Err(error) => return Err(error),
|
||||
}
|
||||
}
|
||||
None => Ok(None),
|
||||
},
|
||||
None => return Ok(None),
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ LIMIT ?
|
||||
"cannot list kb_chain_slots on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -168,8 +168,8 @@ LIMIT ?
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,9 +190,9 @@ mod tests {
|
||||
use_wal: true,
|
||||
},
|
||||
};
|
||||
crate::KbDatabase::connect_and_initialize(&config)
|
||||
return crate::KbDatabase::connect_and_initialize(&config)
|
||||
.await
|
||||
.expect("database init must succeed")
|
||||
.expect("database init must succeed");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
||||
@@ -17,9 +17,9 @@ pub async fn upsert_chain_transaction(
|
||||
"cannot convert chain transaction slot '{}' to i64: {}",
|
||||
slot, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
None => None,
|
||||
};
|
||||
match database.connection() {
|
||||
@@ -80,13 +80,15 @@ LIMIT 1
|
||||
.fetch_one(pool)
|
||||
.await;
|
||||
match id_result {
|
||||
Ok(id) => Ok(id),
|
||||
Err(error) => Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_chain_transactions id for signature '{}' on sqlite: {}",
|
||||
dto.signature, error
|
||||
))),
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_chain_transactions id for signature '{}' on sqlite: {}",
|
||||
dto.signature, error
|
||||
)));
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,19 +128,19 @@ LIMIT 1
|
||||
"cannot fetch kb_chain_transactions for signature '{}' on sqlite: {}",
|
||||
signature, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => {
|
||||
let dto_result = crate::KbChainTransactionDto::try_from(entity);
|
||||
match dto_result {
|
||||
Ok(dto) => Ok(Some(dto)),
|
||||
Err(error) => Err(error),
|
||||
Ok(dto) => return Ok(Some(dto)),
|
||||
Err(error) => return Err(error),
|
||||
}
|
||||
}
|
||||
None => Ok(None),
|
||||
},
|
||||
None => return Ok(None),
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,7 +183,7 @@ LIMIT ?
|
||||
"cannot list kb_chain_transactions on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -192,8 +194,49 @@ LIMIT ?
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Lists persisted chain transaction signatures for local pipeline replay.
|
||||
pub async fn list_chain_transaction_signatures_for_replay(
|
||||
database: &crate::KbDatabase,
|
||||
limit: std::option::Option<i64>,
|
||||
) -> Result<std::vec::Vec<std::string::String>, crate::KbError> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let effective_limit = match limit {
|
||||
Some(limit) => {
|
||||
if limit <= 0 {
|
||||
10_000
|
||||
} else {
|
||||
limit
|
||||
}
|
||||
},
|
||||
None => 10_000,
|
||||
};
|
||||
let query_result = sqlx::query_scalar::<sqlx::Sqlite, std::string::String>(
|
||||
r#"
|
||||
SELECT signature
|
||||
FROM kb_chain_transactions
|
||||
ORDER BY id ASC
|
||||
LIMIT ?
|
||||
"#,
|
||||
)
|
||||
.bind(effective_limit)
|
||||
.fetch_all(pool)
|
||||
.await;
|
||||
match query_result {
|
||||
Ok(signatures) => return Ok(signatures),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot list kb_chain_transactions signatures for local replay on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,9 +257,9 @@ mod tests {
|
||||
use_wal: true,
|
||||
},
|
||||
};
|
||||
crate::KbDatabase::connect_and_initialize(&config)
|
||||
return crate::KbDatabase::connect_and_initialize(&config)
|
||||
.await
|
||||
.expect("database init must succeed")
|
||||
.expect("database init must succeed");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -249,10 +292,7 @@ mod tests {
|
||||
assert_eq!(fetched.signature, "sig-chain-transaction-1");
|
||||
assert_eq!(fetched.slot, Some(515151));
|
||||
assert_eq!(fetched.block_time_unix, Some(1_700_000_001));
|
||||
assert_eq!(
|
||||
fetched.source_endpoint_name,
|
||||
Some("helius_primary_http".to_string())
|
||||
);
|
||||
assert_eq!(fetched.source_endpoint_name, Some("helius_primary_http".to_string()));
|
||||
assert_eq!(fetched.version_text, Some("0".to_string()));
|
||||
assert_eq!(fetched.meta_json, Some(r#"{"fee":5000}"#.to_string()));
|
||||
let listed = crate::list_recent_chain_transactions(&database, 10)
|
||||
|
||||
@@ -29,13 +29,15 @@ ON CONFLICT(key) DO UPDATE SET
|
||||
.execute(pool)
|
||||
.await;
|
||||
match query_result {
|
||||
Ok(_) => Ok(()),
|
||||
Err(error) => Err(crate::KbError::Db(format!(
|
||||
"cannot upsert kb_db_metadata on sqlite: {}",
|
||||
error
|
||||
))),
|
||||
Ok(_) => return Ok(()),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot upsert kb_db_metadata on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,19 +69,19 @@ LIMIT 1
|
||||
"cannot read kb_db_metadata '{}' on sqlite: {}",
|
||||
key, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => {
|
||||
let dto_result = crate::KbDbMetadataDto::try_from(entity);
|
||||
match dto_result {
|
||||
Ok(dto) => Ok(Some(dto)),
|
||||
Err(error) => Err(error),
|
||||
Ok(dto) => return Ok(Some(dto)),
|
||||
Err(error) => return Err(error),
|
||||
}
|
||||
}
|
||||
None => Ok(None),
|
||||
},
|
||||
None => return Ok(None),
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,7 +110,7 @@ ORDER BY key ASC
|
||||
"cannot list kb_db_metadata on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -119,8 +121,8 @@ ORDER BY key ASC
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,9 +148,7 @@ mod tests {
|
||||
.await
|
||||
.expect("database init must succeed");
|
||||
let dto = crate::KbDbMetadataDto::new("schema_version".to_string(), "0.5.0".to_string());
|
||||
crate::upsert_db_metadata(&database, &dto)
|
||||
.await
|
||||
.expect("upsert must succeed");
|
||||
crate::upsert_db_metadata(&database, &dto).await.expect("upsert must succeed");
|
||||
let fetched = crate::get_db_metadata(&database, "schema_version")
|
||||
.await
|
||||
.expect("fetch must succeed");
|
||||
@@ -156,9 +156,7 @@ mod tests {
|
||||
let fetched = fetched.expect("metadata must exist");
|
||||
assert_eq!(fetched.key, "schema_version");
|
||||
assert_eq!(fetched.value, "0.5.0");
|
||||
let listed = crate::list_db_metadata(&database)
|
||||
.await
|
||||
.expect("list must succeed");
|
||||
let listed = crate::list_db_metadata(&database).await.expect("list must succeed");
|
||||
assert!(!listed.is_empty());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,10 +35,10 @@ VALUES (?, ?, ?, ?, ?)
|
||||
"cannot insert kb_db_runtime_events on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
Ok(query_result.last_insert_rowid())
|
||||
}
|
||||
return Ok(query_result.last_insert_rowid());
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ LIMIT ?
|
||||
"cannot list runtime events on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -87,8 +87,8 @@ LIMIT ?
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,13 +56,15 @@ LIMIT 1
|
||||
.fetch_one(pool)
|
||||
.await;
|
||||
match id_result {
|
||||
Ok(id) => Ok(id),
|
||||
Err(error) => Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_dexes id for code '{}' on sqlite: {}",
|
||||
dto.code, error
|
||||
))),
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_dexes id for code '{}' on sqlite: {}",
|
||||
dto.code, error
|
||||
)));
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,19 +101,19 @@ LIMIT 1
|
||||
"cannot read kb_dexes '{}' on sqlite: {}",
|
||||
code, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => {
|
||||
let dto_result = crate::KbDexDto::try_from(entity);
|
||||
match dto_result {
|
||||
Ok(dto) => Ok(Some(dto)),
|
||||
Err(error) => Err(error),
|
||||
Ok(dto) => return Ok(Some(dto)),
|
||||
Err(error) => return Err(error),
|
||||
}
|
||||
}
|
||||
None => Ok(None),
|
||||
},
|
||||
None => return Ok(None),
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,7 +147,7 @@ ORDER BY code ASC
|
||||
"cannot list kb_dexes on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -156,8 +158,8 @@ ORDER BY code ASC
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,13 +186,7 @@ mod tests {
|
||||
.expect("database init must succeed");
|
||||
let dex_id = crate::upsert_dex(
|
||||
&database,
|
||||
&crate::KbDexDto::new(
|
||||
"raydium".to_string(),
|
||||
"Raydium".to_string(),
|
||||
None,
|
||||
None,
|
||||
true,
|
||||
),
|
||||
&crate::KbDexDto::new("raydium".to_string(), "Raydium".to_string(), None, None, true),
|
||||
)
|
||||
.await
|
||||
.expect("dex upsert must succeed");
|
||||
@@ -200,9 +196,7 @@ mod tests {
|
||||
.expect("get dex must succeed");
|
||||
assert!(dex.is_some());
|
||||
assert_eq!(dex.expect("dex must exist").name, "Raydium");
|
||||
let dexes = crate::list_dexes(&database)
|
||||
.await
|
||||
.expect("list dexes must succeed");
|
||||
let dexes = crate::list_dexes(&database).await.expect("list dexes must succeed");
|
||||
assert_eq!(dexes.len(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,13 +77,15 @@ LIMIT 1
|
||||
.fetch_one(pool)
|
||||
.await;
|
||||
match id_result {
|
||||
Ok(id) => Ok(id),
|
||||
Err(error) => Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_dex_decoded_events id on sqlite: {}",
|
||||
error
|
||||
))),
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_dex_decoded_events id on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,19 +137,19 @@ LIMIT 1
|
||||
"cannot fetch kb_dex_decoded_events on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => {
|
||||
let dto_result = crate::KbDexDecodedEventDto::try_from(entity);
|
||||
match dto_result {
|
||||
Ok(dto) => Ok(Some(dto)),
|
||||
Err(error) => Err(error),
|
||||
Ok(dto) => return Ok(Some(dto)),
|
||||
Err(error) => return Err(error),
|
||||
}
|
||||
}
|
||||
None => Ok(None),
|
||||
},
|
||||
None => return Ok(None),
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,7 +191,7 @@ ORDER BY id ASC
|
||||
"cannot list kb_dex_decoded_events on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -200,8 +202,48 @@ ORDER BY id ASC
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the latest Pump.fun create payload associated with a token mint.
|
||||
pub async fn get_latest_pump_fun_create_payload_by_mint(
|
||||
database: &crate::KbDatabase,
|
||||
mint: &str,
|
||||
) -> Result<std::option::Option<std::string::String>, crate::KbError> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let payload_result = sqlx::query_scalar::<sqlx::Sqlite, std::string::String>(
|
||||
r#"
|
||||
SELECT payload_json
|
||||
FROM kb_dex_decoded_events
|
||||
WHERE protocol_name = 'pump_fun'
|
||||
AND event_kind IN ('pump_fun.create', 'pump_fun.create_v2_token')
|
||||
AND (
|
||||
token_a_mint = ?
|
||||
OR json_extract(payload_json, '$.mint') = ?
|
||||
OR json_extract(payload_json, '$.tokenMint') = ?
|
||||
)
|
||||
ORDER BY id DESC
|
||||
LIMIT 1
|
||||
"#,
|
||||
)
|
||||
.bind(mint)
|
||||
.bind(mint)
|
||||
.bind(mint)
|
||||
.fetch_optional(pool)
|
||||
.await;
|
||||
match payload_result {
|
||||
Ok(payload_option) => return Ok(payload_option),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot read latest pump.fun create payload for mint '{}' on sqlite: {}",
|
||||
mint, error
|
||||
)));
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,7 +270,7 @@ mod tests {
|
||||
};
|
||||
let database_result = crate::KbDatabase::connect_and_initialize(&config).await;
|
||||
match database_result {
|
||||
Ok(database) => database,
|
||||
Ok(database) => return database,
|
||||
Err(error) => panic!("database init must succeed: {}", error),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,13 +46,15 @@ ON CONFLICT(name) DO UPDATE SET
|
||||
.execute(pool)
|
||||
.await;
|
||||
match query_result {
|
||||
Ok(_) => Ok(()),
|
||||
Err(error) => Err(crate::KbError::Db(format!(
|
||||
"cannot upsert kb_known_http_endpoints on sqlite: {}",
|
||||
error
|
||||
))),
|
||||
Ok(_) => return Ok(()),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot upsert kb_known_http_endpoints on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,19 +90,19 @@ LIMIT 1
|
||||
"cannot read known http endpoint '{}' on sqlite: {}",
|
||||
name, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => {
|
||||
let dto_result = crate::KbKnownHttpEndpointDto::try_from(entity);
|
||||
match dto_result {
|
||||
Ok(dto) => Ok(Some(dto)),
|
||||
Err(error) => Err(error),
|
||||
Ok(dto) => return Ok(Some(dto)),
|
||||
Err(error) => return Err(error),
|
||||
}
|
||||
}
|
||||
None => Ok(None),
|
||||
},
|
||||
None => return Ok(None),
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,7 +135,7 @@ ORDER BY name ASC
|
||||
"cannot list known http endpoints on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -144,8 +146,8 @@ ORDER BY name ASC
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,9 +189,7 @@ mod tests {
|
||||
let fetched = fetched.expect("endpoint must exist");
|
||||
assert_eq!(fetched.provider, "helius");
|
||||
assert_eq!(fetched.roles.len(), 2);
|
||||
let listed = crate::list_known_http_endpoints(&database)
|
||||
.await
|
||||
.expect("list must succeed");
|
||||
let listed = crate::list_known_http_endpoints(&database).await.expect("list must succeed");
|
||||
assert_eq!(listed.len(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ pub async fn upsert_known_ws_endpoint(
|
||||
Ok(entity) => entity,
|
||||
Err(error) => return Err(error),
|
||||
};
|
||||
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query(
|
||||
@@ -46,13 +45,15 @@ ON CONFLICT(name) DO UPDATE SET
|
||||
.execute(pool)
|
||||
.await;
|
||||
match query_result {
|
||||
Ok(_) => Ok(()),
|
||||
Err(error) => Err(crate::KbError::Db(format!(
|
||||
"cannot upsert kb_known_ws_endpoints on sqlite: {}",
|
||||
error
|
||||
))),
|
||||
Ok(_) => return Ok(()),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot upsert kb_known_ws_endpoints on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,19 +89,19 @@ LIMIT 1
|
||||
"cannot read known ws endpoint '{}' on sqlite: {}",
|
||||
name, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => {
|
||||
let dto_result = crate::KbKnownWsEndpointDto::try_from(entity);
|
||||
match dto_result {
|
||||
Ok(dto) => Ok(Some(dto)),
|
||||
Err(error) => Err(error),
|
||||
Ok(dto) => return Ok(Some(dto)),
|
||||
Err(error) => return Err(error),
|
||||
}
|
||||
}
|
||||
None => Ok(None),
|
||||
},
|
||||
None => return Ok(None),
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,7 +134,7 @@ ORDER BY name ASC
|
||||
"cannot list known ws endpoints on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -144,8 +145,8 @@ ORDER BY name ASC
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,9 +188,7 @@ mod tests {
|
||||
let fetched = fetched.expect("endpoint must exist");
|
||||
assert_eq!(fetched.provider, "solana");
|
||||
assert_eq!(fetched.roles.len(), 2);
|
||||
let listed = crate::list_known_ws_endpoints(&database)
|
||||
.await
|
||||
.expect("list must succeed");
|
||||
let listed = crate::list_known_ws_endpoints(&database).await.expect("list must succeed");
|
||||
assert_eq!(listed.len(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,13 +68,15 @@ LIMIT 1
|
||||
.fetch_one(pool)
|
||||
.await;
|
||||
match id_result {
|
||||
Ok(id) => Ok(id),
|
||||
Err(error) => Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_launch_attributions id for decoded_event_id '{}' on sqlite: {}",
|
||||
dto.decoded_event_id, error
|
||||
))),
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_launch_attributions id for decoded_event_id '{}' on sqlite: {}",
|
||||
dto.decoded_event_id, error
|
||||
)));
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,9 +87,8 @@ pub async fn get_launch_attribution_by_decoded_event_id(
|
||||
) -> Result<std::option::Option<crate::KbLaunchAttributionDto>, crate::KbError> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result =
|
||||
sqlx::query_as::<sqlx::Sqlite, crate::KbLaunchAttributionEntity>(
|
||||
r#"
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbLaunchAttributionEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
launch_surface_id,
|
||||
@@ -105,10 +106,10 @@ FROM kb_launch_attributions
|
||||
WHERE decoded_event_id = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
)
|
||||
.bind(decoded_event_id)
|
||||
.fetch_optional(pool)
|
||||
.await;
|
||||
)
|
||||
.bind(decoded_event_id)
|
||||
.fetch_optional(pool)
|
||||
.await;
|
||||
let entity_option = match query_result {
|
||||
Ok(entity_option) => entity_option,
|
||||
Err(error) => {
|
||||
@@ -116,13 +117,13 @@ LIMIT 1
|
||||
"cannot read kb_launch_attributions by decoded_event_id '{}' on sqlite: {}",
|
||||
decoded_event_id, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => crate::KbLaunchAttributionDto::try_from(entity).map(Some),
|
||||
None => Ok(None),
|
||||
Some(entity) => return crate::KbLaunchAttributionDto::try_from(entity).map(Some),
|
||||
None => return Ok(None),
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,9 +134,8 @@ pub async fn list_launch_attributions_by_pool_id(
|
||||
) -> Result<std::vec::Vec<crate::KbLaunchAttributionDto>, crate::KbError> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result =
|
||||
sqlx::query_as::<sqlx::Sqlite, crate::KbLaunchAttributionEntity>(
|
||||
r#"
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbLaunchAttributionEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
launch_surface_id,
|
||||
@@ -153,10 +153,10 @@ FROM kb_launch_attributions
|
||||
WHERE pool_id = ?
|
||||
ORDER BY attributed_at ASC, id ASC
|
||||
"#,
|
||||
)
|
||||
.bind(pool_id)
|
||||
.fetch_all(pool)
|
||||
.await;
|
||||
)
|
||||
.bind(pool_id)
|
||||
.fetch_all(pool)
|
||||
.await;
|
||||
let entities = match query_result {
|
||||
Ok(entities) => entities,
|
||||
Err(error) => {
|
||||
@@ -164,7 +164,7 @@ ORDER BY attributed_at ASC, id ASC
|
||||
"cannot list kb_launch_attributions by pool_id '{}' on sqlite: {}",
|
||||
pool_id, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -175,7 +175,7 @@ ORDER BY attributed_at ASC, id ASC
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,13 +53,15 @@ LIMIT 1
|
||||
.fetch_one(pool)
|
||||
.await;
|
||||
match id_result {
|
||||
Ok(id) => Ok(id),
|
||||
Err(error) => Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_launch_surfaces id for code '{}' on sqlite: {}",
|
||||
dto.code, error
|
||||
))),
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_launch_surfaces id for code '{}' on sqlite: {}",
|
||||
dto.code, error
|
||||
)));
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,9 +72,8 @@ pub async fn get_launch_surface_by_code(
|
||||
) -> Result<std::option::Option<crate::KbLaunchSurfaceDto>, crate::KbError> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result =
|
||||
sqlx::query_as::<sqlx::Sqlite, crate::KbLaunchSurfaceEntity>(
|
||||
r#"
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbLaunchSurfaceEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
code,
|
||||
@@ -85,10 +86,10 @@ FROM kb_launch_surfaces
|
||||
WHERE code = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
)
|
||||
.bind(code)
|
||||
.fetch_optional(pool)
|
||||
.await;
|
||||
)
|
||||
.bind(code)
|
||||
.fetch_optional(pool)
|
||||
.await;
|
||||
let entity_option = match query_result {
|
||||
Ok(entity_option) => entity_option,
|
||||
Err(error) => {
|
||||
@@ -96,13 +97,13 @@ LIMIT 1
|
||||
"cannot read kb_launch_surfaces '{}' on sqlite: {}",
|
||||
code, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => crate::KbLaunchSurfaceDto::try_from(entity).map(Some),
|
||||
None => Ok(None),
|
||||
Some(entity) => return crate::KbLaunchSurfaceDto::try_from(entity).map(Some),
|
||||
None => return Ok(None),
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,9 +113,8 @@ pub async fn list_launch_surfaces(
|
||||
) -> Result<std::vec::Vec<crate::KbLaunchSurfaceDto>, crate::KbError> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result =
|
||||
sqlx::query_as::<sqlx::Sqlite, crate::KbLaunchSurfaceEntity>(
|
||||
r#"
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbLaunchSurfaceEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
code,
|
||||
@@ -126,9 +126,9 @@ SELECT
|
||||
FROM kb_launch_surfaces
|
||||
ORDER BY code ASC
|
||||
"#,
|
||||
)
|
||||
.fetch_all(pool)
|
||||
.await;
|
||||
)
|
||||
.fetch_all(pool)
|
||||
.await;
|
||||
let entities = match query_result {
|
||||
Ok(entities) => entities,
|
||||
Err(error) => {
|
||||
@@ -136,7 +136,7 @@ ORDER BY code ASC
|
||||
"cannot list kb_launch_surfaces on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -147,7 +147,7 @@ ORDER BY code ASC
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,13 +50,15 @@ LIMIT 1
|
||||
.fetch_one(pool)
|
||||
.await;
|
||||
match id_result {
|
||||
Ok(id) => Ok(id),
|
||||
Err(error) => Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_launch_surface_keys id for '{}:{}' on sqlite: {}",
|
||||
dto.match_kind, dto.match_value, error
|
||||
))),
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_launch_surface_keys id for '{}:{}' on sqlite: {}",
|
||||
dto.match_kind, dto.match_value, error
|
||||
)));
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,9 +70,8 @@ pub async fn get_launch_surface_key_by_match(
|
||||
) -> Result<std::option::Option<crate::KbLaunchSurfaceKeyDto>, crate::KbError> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result =
|
||||
sqlx::query_as::<sqlx::Sqlite, crate::KbLaunchSurfaceKeyEntity>(
|
||||
r#"
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbLaunchSurfaceKeyEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
launch_surface_id,
|
||||
@@ -82,11 +83,11 @@ FROM kb_launch_surface_keys
|
||||
WHERE match_kind = ? AND match_value = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
)
|
||||
.bind(match_kind)
|
||||
.bind(match_value)
|
||||
.fetch_optional(pool)
|
||||
.await;
|
||||
)
|
||||
.bind(match_kind)
|
||||
.bind(match_value)
|
||||
.fetch_optional(pool)
|
||||
.await;
|
||||
let entity_option = match query_result {
|
||||
Ok(entity_option) => entity_option,
|
||||
Err(error) => {
|
||||
@@ -94,13 +95,13 @@ LIMIT 1
|
||||
"cannot read kb_launch_surface_keys '{}:{}' on sqlite: {}",
|
||||
match_kind, match_value, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => crate::KbLaunchSurfaceKeyDto::try_from(entity).map(Some),
|
||||
None => Ok(None),
|
||||
Some(entity) => return crate::KbLaunchSurfaceKeyDto::try_from(entity).map(Some),
|
||||
None => return Ok(None),
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,9 +112,8 @@ pub async fn list_launch_surface_keys_by_surface_id(
|
||||
) -> Result<std::vec::Vec<crate::KbLaunchSurfaceKeyDto>, crate::KbError> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result =
|
||||
sqlx::query_as::<sqlx::Sqlite, crate::KbLaunchSurfaceKeyEntity>(
|
||||
r#"
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbLaunchSurfaceKeyEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
launch_surface_id,
|
||||
@@ -125,10 +125,10 @@ FROM kb_launch_surface_keys
|
||||
WHERE launch_surface_id = ?
|
||||
ORDER BY match_kind ASC, match_value ASC
|
||||
"#,
|
||||
)
|
||||
.bind(launch_surface_id)
|
||||
.fetch_all(pool)
|
||||
.await;
|
||||
)
|
||||
.bind(launch_surface_id)
|
||||
.fetch_all(pool)
|
||||
.await;
|
||||
let entities = match query_result {
|
||||
Ok(entities) => entities,
|
||||
Err(error) => {
|
||||
@@ -136,7 +136,7 @@ ORDER BY match_kind ASC, match_value ASC
|
||||
"cannot list kb_launch_surface_keys by surface_id '{}' on sqlite: {}",
|
||||
launch_surface_id, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -147,7 +147,7 @@ ORDER BY match_kind ASC, match_value ASC
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,9 +17,9 @@ pub async fn upsert_liquidity_event(
|
||||
"cannot convert liquidity event slot '{}' to i64: {}",
|
||||
slot, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
None => None,
|
||||
};
|
||||
match database.connection() {
|
||||
@@ -96,13 +96,15 @@ LIMIT 1
|
||||
.fetch_one(pool)
|
||||
.await;
|
||||
match id_result {
|
||||
Ok(id) => Ok(id),
|
||||
Err(error) => Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_liquidity_events id for signature '{}' and instruction_index '{}' on sqlite: {}",
|
||||
dto.signature, dto.instruction_index, error
|
||||
))),
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_liquidity_events id for signature '{}' and instruction_index '{}' on sqlite: {}",
|
||||
dto.signature, dto.instruction_index, error
|
||||
)));
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,7 +152,7 @@ LIMIT ?
|
||||
"cannot list kb_liquidity_events on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -161,7 +163,7 @@ LIMIT ?
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,13 +63,15 @@ LIMIT 1
|
||||
.fetch_one(pool)
|
||||
.await;
|
||||
match select_result {
|
||||
Ok(id) => Ok(id),
|
||||
Err(error) => Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_observed_tokens id for mint '{}' on sqlite: {}",
|
||||
dto.mint, error
|
||||
))),
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_observed_tokens id for mint '{}' on sqlite: {}",
|
||||
dto.mint, error
|
||||
)));
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,19 +110,19 @@ LIMIT 1
|
||||
"cannot read observed token '{}' on sqlite: {}",
|
||||
mint, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => {
|
||||
let dto_result = crate::KbObservedTokenDto::try_from(entity);
|
||||
match dto_result {
|
||||
Ok(dto) => Ok(Some(dto)),
|
||||
Err(error) => Err(error),
|
||||
Ok(dto) => return Ok(Some(dto)),
|
||||
Err(error) => return Err(error),
|
||||
}
|
||||
}
|
||||
None => Ok(None),
|
||||
},
|
||||
None => return Ok(None),
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,7 +164,7 @@ LIMIT ?
|
||||
"cannot list observed tokens on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -173,8 +175,8 @@ LIMIT ?
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,9 +224,7 @@ mod tests {
|
||||
assert_eq!(fetched.symbol.as_deref(), Some("WSOL"));
|
||||
assert_eq!(fetched.decimals, Some(9));
|
||||
assert_eq!(fetched.status, crate::KbObservedTokenStatus::Active);
|
||||
let listed = crate::list_observed_tokens(&database, 10)
|
||||
.await
|
||||
.expect("list must succeed");
|
||||
let listed = crate::list_observed_tokens(&database, 10).await.expect("list must succeed");
|
||||
assert_eq!(listed.len(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ pub async fn insert_onchain_observation(
|
||||
"cannot serialize on-chain observation payload: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let slot_i64 = match dto.slot {
|
||||
Some(slot) => {
|
||||
@@ -27,9 +27,9 @@ pub async fn insert_onchain_observation(
|
||||
"cannot convert on-chain observation slot '{}' to i64: {}",
|
||||
slot, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
None => None,
|
||||
};
|
||||
match database.connection() {
|
||||
@@ -64,10 +64,10 @@ VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
"cannot insert kb_onchain_observations on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
Ok(query_result.last_insert_rowid())
|
||||
}
|
||||
return Ok(query_result.last_insert_rowid());
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ LIMIT ?
|
||||
"cannot list on-chain observations on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -118,8 +118,8 @@ LIMIT ?
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,11 @@ ON CONFLICT(pool_id) DO UPDATE SET
|
||||
dex_id = excluded.dex_id,
|
||||
base_token_id = excluded.base_token_id,
|
||||
quote_token_id = excluded.quote_token_id,
|
||||
symbol = excluded.symbol,
|
||||
symbol = CASE
|
||||
WHEN excluded.symbol IS NOT NULL AND trim(excluded.symbol) <> ''
|
||||
THEN excluded.symbol
|
||||
ELSE kb_pairs.symbol
|
||||
END,
|
||||
updated_at = excluded.updated_at
|
||||
"#,
|
||||
)
|
||||
@@ -56,13 +60,15 @@ LIMIT 1
|
||||
.fetch_one(pool)
|
||||
.await;
|
||||
match id_result {
|
||||
Ok(id) => Ok(id),
|
||||
Err(error) => Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_pairs id for pool_id '{}' on sqlite: {}",
|
||||
dto.pool_id, error
|
||||
))),
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_pairs id for pool_id '{}' on sqlite: {}",
|
||||
dto.pool_id, error
|
||||
)));
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,19 +105,54 @@ LIMIT 1
|
||||
"cannot read kb_pairs by pool_id '{}' on sqlite: {}",
|
||||
pool_id, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => {
|
||||
let dto_result = crate::KbPairDto::try_from(entity);
|
||||
match dto_result {
|
||||
Ok(dto) => Ok(Some(dto)),
|
||||
Err(error) => Err(error),
|
||||
Ok(dto) => return Ok(Some(dto)),
|
||||
Err(error) => return Err(error),
|
||||
}
|
||||
}
|
||||
None => Ok(None),
|
||||
},
|
||||
None => return Ok(None),
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Updates the display symbol of one normalized pair row.
|
||||
pub async fn update_pair_symbol(
|
||||
database: &crate::KbDatabase,
|
||||
pair_id: i64,
|
||||
symbol: std::option::Option<&str>,
|
||||
) -> Result<bool, crate::KbError> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query(
|
||||
r#"
|
||||
UPDATE kb_pairs
|
||||
SET
|
||||
symbol = ?,
|
||||
updated_at = ?
|
||||
WHERE id = ?
|
||||
"#,
|
||||
)
|
||||
.bind(symbol)
|
||||
.bind(chrono::Utc::now().to_rfc3339())
|
||||
.bind(pair_id)
|
||||
.execute(pool)
|
||||
.await;
|
||||
match query_result {
|
||||
Ok(done) => return Ok(done.rows_affected() > 0),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot update kb_pairs symbol for id '{}' on sqlite: {}",
|
||||
pair_id, error
|
||||
)));
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,7 +186,7 @@ ORDER BY id ASC
|
||||
"cannot list kb_pairs on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -156,8 +197,8 @@ ORDER BY id ASC
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,13 +225,7 @@ mod tests {
|
||||
.expect("database init must succeed");
|
||||
let dex_id = crate::upsert_dex(
|
||||
&database,
|
||||
&crate::KbDexDto::new(
|
||||
"raydium".to_string(),
|
||||
"Raydium".to_string(),
|
||||
None,
|
||||
None,
|
||||
true,
|
||||
),
|
||||
&crate::KbDexDto::new("raydium".to_string(), "Raydium".to_string(), None, None, true),
|
||||
)
|
||||
.await
|
||||
.expect("dex upsert must succeed");
|
||||
@@ -248,13 +283,8 @@ mod tests {
|
||||
.await
|
||||
.expect("get pair must succeed");
|
||||
assert!(pair.is_some());
|
||||
assert_eq!(
|
||||
pair.expect("pair must exist").symbol.as_deref(),
|
||||
Some("BASE/WSOL")
|
||||
);
|
||||
let pairs = crate::list_pairs(&database)
|
||||
.await
|
||||
.expect("list pairs must succeed");
|
||||
assert_eq!(pair.expect("pair must exist").symbol.as_deref(), Some("BASE/WSOL"));
|
||||
let pairs = crate::list_pairs(&database).await.expect("list pairs must succeed");
|
||||
assert_eq!(pairs.len(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ pub async fn upsert_pair_analytic_signal(
|
||||
"cannot serialize pair analytic signal payload: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
@@ -77,13 +77,15 @@ LIMIT 1
|
||||
.fetch_one(pool)
|
||||
.await;
|
||||
match id_result {
|
||||
Ok(id) => Ok(id),
|
||||
Err(error) => Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_pair_analytic_signals id on sqlite: {}",
|
||||
error
|
||||
))),
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_pair_analytic_signals id on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,9 +99,8 @@ pub async fn get_pair_analytic_signal_by_key(
|
||||
) -> Result<std::option::Option<crate::KbPairAnalyticSignalDto>, crate::KbError> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result =
|
||||
sqlx::query_as::<sqlx::Sqlite, crate::KbPairAnalyticSignalEntity>(
|
||||
r#"
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbPairAnalyticSignalEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
pair_id,
|
||||
@@ -117,13 +118,13 @@ FROM kb_pair_analytic_signals
|
||||
WHERE pair_id = ? AND signal_kind = ? AND timeframe_seconds = ? AND bucket_start_unix = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
)
|
||||
.bind(pair_id)
|
||||
.bind(signal_kind)
|
||||
.bind(timeframe_seconds)
|
||||
.bind(bucket_start_unix)
|
||||
.fetch_optional(pool)
|
||||
.await;
|
||||
)
|
||||
.bind(pair_id)
|
||||
.bind(signal_kind)
|
||||
.bind(timeframe_seconds)
|
||||
.bind(bucket_start_unix)
|
||||
.fetch_optional(pool)
|
||||
.await;
|
||||
let entity_option = match query_result {
|
||||
Ok(entity_option) => entity_option,
|
||||
Err(error) => {
|
||||
@@ -131,13 +132,13 @@ LIMIT 1
|
||||
"cannot read kb_pair_analytic_signals by key on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => crate::KbPairAnalyticSignalDto::try_from(entity).map(Some),
|
||||
None => Ok(None),
|
||||
Some(entity) => return crate::KbPairAnalyticSignalDto::try_from(entity).map(Some),
|
||||
None => return Ok(None),
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,9 +149,8 @@ pub async fn list_pair_analytic_signals_by_pair_id(
|
||||
) -> Result<std::vec::Vec<crate::KbPairAnalyticSignalDto>, crate::KbError> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result =
|
||||
sqlx::query_as::<sqlx::Sqlite, crate::KbPairAnalyticSignalEntity>(
|
||||
r#"
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbPairAnalyticSignalEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
pair_id,
|
||||
@@ -168,10 +168,10 @@ FROM kb_pair_analytic_signals
|
||||
WHERE pair_id = ?
|
||||
ORDER BY timeframe_seconds ASC, bucket_start_unix ASC, signal_kind ASC, id ASC
|
||||
"#,
|
||||
)
|
||||
.bind(pair_id)
|
||||
.fetch_all(pool)
|
||||
.await;
|
||||
)
|
||||
.bind(pair_id)
|
||||
.fetch_all(pool)
|
||||
.await;
|
||||
let entities = match query_result {
|
||||
Ok(entities) => entities,
|
||||
Err(error) => {
|
||||
@@ -179,7 +179,7 @@ ORDER BY timeframe_seconds ASC, bucket_start_unix ASC, signal_kind ASC, id ASC
|
||||
"cannot list kb_pair_analytic_signals by pair_id '{}' on sqlite: {}",
|
||||
pair_id, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -190,7 +190,7 @@ ORDER BY timeframe_seconds ASC, bucket_start_unix ASC, signal_kind ASC, id ASC
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,13 +87,15 @@ LIMIT 1
|
||||
.fetch_one(pool)
|
||||
.await;
|
||||
match id_result {
|
||||
Ok(id) => Ok(id),
|
||||
Err(error) => Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_pair_candles id for pair_id '{}' timeframe '{}' bucket '{}' on sqlite: {}",
|
||||
dto.pair_id, dto.timeframe_seconds, dto.bucket_start_unix, error
|
||||
))),
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_pair_candles id for pair_id '{}' timeframe '{}' bucket '{}' on sqlite: {}",
|
||||
dto.pair_id, dto.timeframe_seconds, dto.bucket_start_unix, error
|
||||
)));
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,13 +146,13 @@ LIMIT 1
|
||||
"cannot read kb_pair_candles by key on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => crate::KbPairCandleDto::try_from(entity).map(Some),
|
||||
None => Ok(None),
|
||||
Some(entity) => return crate::KbPairCandleDto::try_from(entity).map(Some),
|
||||
None => return Ok(None),
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,7 +201,7 @@ ORDER BY bucket_start_unix ASC, id ASC
|
||||
"cannot list kb_pair_candles by pair_id '{}' timeframe '{}' on sqlite: {}",
|
||||
pair_id, timeframe_seconds, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -210,7 +212,7 @@ ORDER BY bucket_start_unix ASC, id ASC
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,13 +74,15 @@ LIMIT 1
|
||||
.fetch_one(pool)
|
||||
.await;
|
||||
match id_result {
|
||||
Ok(id) => Ok(id),
|
||||
Err(error) => Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_pair_metrics id for pair_id '{}' on sqlite: {}",
|
||||
dto.pair_id, error
|
||||
))),
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_pair_metrics id for pair_id '{}' on sqlite: {}",
|
||||
dto.pair_id, error
|
||||
)));
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,13 +125,13 @@ LIMIT 1
|
||||
"cannot read kb_pair_metrics by pair_id '{}' on sqlite: {}",
|
||||
pair_id, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => crate::KbPairMetricDto::try_from(entity).map(Some),
|
||||
None => Ok(None),
|
||||
Some(entity) => return crate::KbPairMetricDto::try_from(entity).map(Some),
|
||||
None => return Ok(None),
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,7 +171,7 @@ ORDER BY pair_id ASC
|
||||
"cannot list kb_pair_metrics on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -180,7 +182,7 @@ ORDER BY pair_id ASC
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,13 +53,15 @@ LIMIT 1
|
||||
.fetch_one(pool)
|
||||
.await;
|
||||
match id_result {
|
||||
Ok(id) => Ok(id),
|
||||
Err(error) => Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_pools id for address '{}' on sqlite: {}",
|
||||
dto.address, error
|
||||
))),
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_pools id for address '{}' on sqlite: {}",
|
||||
dto.address, error
|
||||
)));
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,19 +97,19 @@ LIMIT 1
|
||||
"cannot read kb_pools '{}' on sqlite: {}",
|
||||
address, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => {
|
||||
let dto_result = crate::KbPoolDto::try_from(entity);
|
||||
match dto_result {
|
||||
Ok(dto) => Ok(Some(dto)),
|
||||
Err(error) => Err(error),
|
||||
Ok(dto) => return Ok(Some(dto)),
|
||||
Err(error) => return Err(error),
|
||||
}
|
||||
}
|
||||
None => Ok(None),
|
||||
},
|
||||
None => return Ok(None),
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,7 +142,7 @@ ORDER BY id ASC
|
||||
"cannot list kb_pools on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -151,8 +153,8 @@ ORDER BY id ASC
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,13 +181,7 @@ mod tests {
|
||||
.expect("database init must succeed");
|
||||
let dex_id = crate::upsert_dex(
|
||||
&database,
|
||||
&crate::KbDexDto::new(
|
||||
"raydium".to_string(),
|
||||
"Raydium".to_string(),
|
||||
None,
|
||||
None,
|
||||
true,
|
||||
),
|
||||
&crate::KbDexDto::new("raydium".to_string(), "Raydium".to_string(), None, None, true),
|
||||
)
|
||||
.await
|
||||
.expect("dex upsert must succeed");
|
||||
@@ -206,13 +202,8 @@ mod tests {
|
||||
.await
|
||||
.expect("get pool must succeed");
|
||||
assert!(pool.is_some());
|
||||
assert_eq!(
|
||||
pool.expect("pool must exist").pool_kind,
|
||||
crate::KbPoolKind::Amm
|
||||
);
|
||||
let pools = crate::list_pools(&database)
|
||||
.await
|
||||
.expect("list pools must succeed");
|
||||
assert_eq!(pool.expect("pool must exist").pool_kind, crate::KbPoolKind::Amm);
|
||||
let pools = crate::list_pools(&database).await.expect("list pools must succeed");
|
||||
assert_eq!(pools.len(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,13 +66,15 @@ LIMIT 1
|
||||
.fetch_one(pool)
|
||||
.await;
|
||||
match id_result {
|
||||
Ok(id) => Ok(id),
|
||||
Err(error) => Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_pool_listings id for pool_id '{}' on sqlite: {}",
|
||||
dto.pool_id, error
|
||||
))),
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_pool_listings id for pool_id '{}' on sqlite: {}",
|
||||
dto.pool_id, error
|
||||
)));
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,19 +114,19 @@ LIMIT 1
|
||||
"cannot read kb_pool_listings by pool_id '{}' on sqlite: {}",
|
||||
pool_id, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => {
|
||||
let dto_result = crate::KbPoolListingDto::try_from(entity);
|
||||
match dto_result {
|
||||
Ok(dto) => Ok(Some(dto)),
|
||||
Err(error) => Err(error),
|
||||
Ok(dto) => return Ok(Some(dto)),
|
||||
Err(error) => return Err(error),
|
||||
}
|
||||
}
|
||||
None => Ok(None),
|
||||
},
|
||||
None => return Ok(None),
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,7 +163,7 @@ ORDER BY detected_at ASC, id ASC
|
||||
"cannot list kb_pool_listings on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -172,8 +174,8 @@ ORDER BY detected_at ASC, id ASC
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,13 +202,7 @@ mod tests {
|
||||
.expect("database init must succeed");
|
||||
let dex_id = crate::upsert_dex(
|
||||
&database,
|
||||
&crate::KbDexDto::new(
|
||||
"raydium".to_string(),
|
||||
"Raydium".to_string(),
|
||||
None,
|
||||
None,
|
||||
true,
|
||||
),
|
||||
&crate::KbDexDto::new("raydium".to_string(), "Raydium".to_string(), None, None, true),
|
||||
)
|
||||
.await
|
||||
.expect("dex upsert must succeed");
|
||||
|
||||
@@ -69,13 +69,15 @@ LIMIT 1
|
||||
.fetch_one(pool)
|
||||
.await;
|
||||
match id_result {
|
||||
Ok(id) => Ok(id),
|
||||
Err(error) => Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_pool_origins id for pool_id '{}' on sqlite: {}",
|
||||
dto.pool_id, error
|
||||
))),
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_pool_origins id for pool_id '{}' on sqlite: {}",
|
||||
dto.pool_id, error
|
||||
)));
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,13 +121,13 @@ LIMIT 1
|
||||
"cannot read kb_pool_origins by pool_id '{}' on sqlite: {}",
|
||||
pool_id, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => crate::KbPoolOriginDto::try_from(entity).map(Some),
|
||||
None => Ok(None),
|
||||
Some(entity) => return crate::KbPoolOriginDto::try_from(entity).map(Some),
|
||||
None => return Ok(None),
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,7 +168,7 @@ ORDER BY created_at ASC, id ASC
|
||||
"cannot list kb_pool_origins on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -177,7 +179,7 @@ ORDER BY created_at ASC, id ASC
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,13 +56,15 @@ LIMIT 1
|
||||
.fetch_one(pool)
|
||||
.await;
|
||||
match id_result {
|
||||
Ok(id) => Ok(id),
|
||||
Err(error) => Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_pool_tokens id on sqlite: {}",
|
||||
error
|
||||
))),
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_pool_tokens id on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +101,7 @@ ORDER BY token_order ASC, id ASC
|
||||
"cannot list kb_pool_tokens for pool_id '{}' on sqlite: {}",
|
||||
pool_id, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -110,8 +112,8 @@ ORDER BY token_order ASC, id ASC
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,13 +140,7 @@ mod tests {
|
||||
.expect("database init must succeed");
|
||||
let dex_id = crate::upsert_dex(
|
||||
&database,
|
||||
&crate::KbDexDto::new(
|
||||
"raydium".to_string(),
|
||||
"Raydium".to_string(),
|
||||
None,
|
||||
None,
|
||||
true,
|
||||
),
|
||||
&crate::KbDexDto::new("raydium".to_string(), "Raydium".to_string(), None, None, true),
|
||||
)
|
||||
.await
|
||||
.expect("dex upsert must succeed");
|
||||
|
||||
@@ -17,9 +17,9 @@ pub async fn upsert_swap(
|
||||
"cannot convert swap slot '{}' to i64: {}",
|
||||
slot, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
None => None,
|
||||
};
|
||||
match database.connection() {
|
||||
@@ -93,13 +93,15 @@ LIMIT 1
|
||||
.fetch_one(pool)
|
||||
.await;
|
||||
match id_result {
|
||||
Ok(id) => Ok(id),
|
||||
Err(error) => Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_swaps id for signature '{}' and instruction_index '{}' on sqlite: {}",
|
||||
dto.signature, dto.instruction_index, error
|
||||
))),
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_swaps id for signature '{}' and instruction_index '{}' on sqlite: {}",
|
||||
dto.signature, dto.instruction_index, error
|
||||
)));
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,7 +148,7 @@ LIMIT ?
|
||||
"cannot list kb_swaps on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -157,7 +159,7 @@ LIMIT ?
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,13 +60,15 @@ LIMIT 1
|
||||
.fetch_one(pool)
|
||||
.await;
|
||||
match id_result {
|
||||
Ok(id) => Ok(id),
|
||||
Err(error) => Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_tokens id for mint '{}' on sqlite: {}",
|
||||
dto.mint, error
|
||||
))),
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_tokens id for mint '{}' on sqlite: {}",
|
||||
dto.mint, error
|
||||
)));
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,22 +106,71 @@ LIMIT 1
|
||||
"cannot read kb_tokens '{}' on sqlite: {}",
|
||||
mint, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => {
|
||||
let dto_result = crate::KbTokenDto::try_from(entity);
|
||||
match dto_result {
|
||||
Ok(dto) => Ok(Some(dto)),
|
||||
Err(error) => Err(error),
|
||||
Ok(dto) => return Ok(Some(dto)),
|
||||
Err(error) => return Err(error),
|
||||
}
|
||||
}
|
||||
None => Ok(None),
|
||||
},
|
||||
None => return Ok(None),
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Reads one normalized token row by internal id.
|
||||
pub async fn get_token_by_id(
|
||||
database: &crate::KbDatabase,
|
||||
token_id: i64,
|
||||
) -> Result<std::option::Option<crate::KbTokenDto>, crate::KbError> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbTokenEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
mint,
|
||||
symbol,
|
||||
name,
|
||||
decimals,
|
||||
token_program,
|
||||
is_quote_token,
|
||||
first_seen_at,
|
||||
updated_at
|
||||
FROM kb_tokens
|
||||
WHERE id = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
)
|
||||
.bind(token_id)
|
||||
.fetch_optional(pool)
|
||||
.await;
|
||||
let entity_option = match query_result {
|
||||
Ok(entity_option) => entity_option,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot read kb_tokens id '{}' on sqlite: {}",
|
||||
token_id, error
|
||||
)));
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => {
|
||||
let dto_result = crate::KbTokenDto::try_from(entity);
|
||||
match dto_result {
|
||||
Ok(dto) => return Ok(Some(dto)),
|
||||
Err(error) => return Err(error),
|
||||
}
|
||||
},
|
||||
None => return Ok(None),
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Lists all normalized token rows ordered by mint.
|
||||
pub async fn list_tokens(
|
||||
@@ -152,7 +203,7 @@ ORDER BY mint ASC, id ASC
|
||||
"cannot list kb_tokens on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -163,7 +214,161 @@ ORDER BY mint ASC, id ASC
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Lists token rows whose display or mint metadata is incomplete.
|
||||
pub async fn list_tokens_missing_metadata(
|
||||
database: &crate::KbDatabase,
|
||||
limit: std::option::Option<i64>,
|
||||
) -> Result<std::vec::Vec<crate::KbTokenDto>, crate::KbError> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let entities_result = match limit {
|
||||
Some(limit) => {
|
||||
sqlx::query_as::<sqlx::Sqlite, crate::KbTokenEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
mint,
|
||||
symbol,
|
||||
name,
|
||||
decimals,
|
||||
token_program,
|
||||
is_quote_token,
|
||||
first_seen_at,
|
||||
updated_at
|
||||
FROM kb_tokens
|
||||
WHERE symbol IS NULL
|
||||
OR trim(symbol) = ''
|
||||
OR name IS NULL
|
||||
OR trim(name) = ''
|
||||
OR decimals IS NULL
|
||||
OR token_program IS NULL
|
||||
OR trim(token_program) = ''
|
||||
ORDER BY updated_at ASC, id ASC
|
||||
LIMIT ?
|
||||
"#,
|
||||
)
|
||||
.bind(limit)
|
||||
.fetch_all(pool)
|
||||
.await
|
||||
},
|
||||
None => {
|
||||
sqlx::query_as::<sqlx::Sqlite, crate::KbTokenEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
mint,
|
||||
symbol,
|
||||
name,
|
||||
decimals,
|
||||
token_program,
|
||||
is_quote_token,
|
||||
first_seen_at,
|
||||
updated_at
|
||||
FROM kb_tokens
|
||||
WHERE symbol IS NULL
|
||||
OR trim(symbol) = ''
|
||||
OR name IS NULL
|
||||
OR trim(name) = ''
|
||||
OR decimals IS NULL
|
||||
OR token_program IS NULL
|
||||
OR trim(token_program) = ''
|
||||
ORDER BY updated_at ASC, id ASC
|
||||
"#,
|
||||
)
|
||||
.fetch_all(pool)
|
||||
.await
|
||||
},
|
||||
};
|
||||
let entities = match entities_result {
|
||||
Ok(entities) => entities,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot list kb_tokens missing metadata on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
let dto_result = crate::KbTokenDto::try_from(entity);
|
||||
let dto = match dto_result {
|
||||
Ok(dto) => dto,
|
||||
Err(error) => return Err(error),
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
async fn make_database() -> std::sync::Arc<crate::KbDatabase> {
|
||||
let tempdir_result = tempfile::tempdir();
|
||||
let tempdir = match tempdir_result {
|
||||
Ok(tempdir) => tempdir,
|
||||
Err(error) => panic!("tempdir must succeed: {}", error),
|
||||
};
|
||||
let database_path = tempdir.path().join("token_query.sqlite3");
|
||||
let config = crate::KbDatabaseConfig {
|
||||
enabled: true,
|
||||
backend: crate::KbDatabaseBackend::Sqlite,
|
||||
sqlite: crate::KbSqliteDatabaseConfig {
|
||||
path: database_path.to_string_lossy().to_string(),
|
||||
create_if_missing: true,
|
||||
busy_timeout_ms: 5000,
|
||||
max_connections: 1,
|
||||
auto_initialize_schema: true,
|
||||
use_wal: true,
|
||||
},
|
||||
};
|
||||
let database_result = crate::KbDatabase::connect_and_initialize(&config).await;
|
||||
let database = match database_result {
|
||||
Ok(database) => database,
|
||||
Err(error) => panic!("database init must succeed: {}", error),
|
||||
};
|
||||
return std::sync::Arc::new(database);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn list_tokens_missing_metadata_only_returns_incomplete_rows() {
|
||||
let database = make_database().await;
|
||||
let incomplete = crate::KbTokenDto::new(
|
||||
"IncompleteMint111".to_string(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
crate::SPL_TOKEN_PROGRAM_ID.to_string(),
|
||||
false,
|
||||
);
|
||||
let complete = crate::KbTokenDto::new(
|
||||
"CompleteMint111".to_string(),
|
||||
Some("CMP".to_string()),
|
||||
Some("Complete".to_string()),
|
||||
Some(6),
|
||||
crate::SPL_TOKEN_PROGRAM_ID.to_string(),
|
||||
false,
|
||||
);
|
||||
let incomplete_result = crate::upsert_token(database.as_ref(), &incomplete).await;
|
||||
if let Err(error) = incomplete_result {
|
||||
panic!("incomplete token upsert must succeed: {}", error);
|
||||
}
|
||||
let complete_result = crate::upsert_token(database.as_ref(), &complete).await;
|
||||
if let Err(error) = complete_result {
|
||||
panic!("complete token upsert must succeed: {}", error);
|
||||
}
|
||||
let missing_result = crate::list_tokens_missing_metadata(database.as_ref(), None).await;
|
||||
let missing = match missing_result {
|
||||
Ok(missing) => missing,
|
||||
Err(error) => panic!("missing metadata list must succeed: {}", error),
|
||||
};
|
||||
assert_eq!(missing.len(), 1);
|
||||
assert_eq!(missing[0].mint, "IncompleteMint111");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,9 +17,9 @@ pub async fn upsert_token_burn_event(
|
||||
"cannot convert token burn event slot '{}' to i64: {}",
|
||||
slot, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
None => None,
|
||||
};
|
||||
match database.connection() {
|
||||
@@ -78,13 +78,15 @@ LIMIT 1
|
||||
.fetch_one(pool)
|
||||
.await;
|
||||
match id_result {
|
||||
Ok(id) => Ok(id),
|
||||
Err(error) => Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_token_burn_events id for signature '{}' and instruction_index '{}' on sqlite: {}",
|
||||
dto.signature, dto.instruction_index, error
|
||||
))),
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_token_burn_events id for signature '{}' and instruction_index '{}' on sqlite: {}",
|
||||
dto.signature, dto.instruction_index, error
|
||||
)));
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,7 +128,7 @@ LIMIT ?
|
||||
"cannot list kb_token_burn_events on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -137,8 +139,8 @@ LIMIT ?
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,13 +167,7 @@ mod tests {
|
||||
.expect("database init must succeed");
|
||||
let dex_id = crate::upsert_dex(
|
||||
&database,
|
||||
&crate::KbDexDto::new(
|
||||
"raydium".to_string(),
|
||||
"Raydium".to_string(),
|
||||
None,
|
||||
None,
|
||||
true,
|
||||
),
|
||||
&crate::KbDexDto::new("raydium".to_string(), "Raydium".to_string(), None, None, true),
|
||||
)
|
||||
.await
|
||||
.expect("dex upsert must succeed");
|
||||
@@ -299,9 +295,7 @@ mod tests {
|
||||
assert!(liquidity_id > 0);
|
||||
assert!(mint_id > 0);
|
||||
assert!(burn_id > 0);
|
||||
let swaps = crate::list_recent_swaps(&database, 10)
|
||||
.await
|
||||
.expect("swaps list must succeed");
|
||||
let swaps = crate::list_recent_swaps(&database, 10).await.expect("swaps list must succeed");
|
||||
let liquidity_events = crate::list_recent_liquidity_events(&database, 10)
|
||||
.await
|
||||
.expect("liquidity list must succeed");
|
||||
|
||||
@@ -17,9 +17,9 @@ pub async fn upsert_token_mint_event(
|
||||
"cannot convert token mint event slot '{}' to i64: {}",
|
||||
slot, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
None => None,
|
||||
};
|
||||
match database.connection() {
|
||||
@@ -78,13 +78,15 @@ LIMIT 1
|
||||
.fetch_one(pool)
|
||||
.await;
|
||||
match id_result {
|
||||
Ok(id) => Ok(id),
|
||||
Err(error) => Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_token_mint_events id for signature '{}' and instruction_index '{}' on sqlite: {}",
|
||||
dto.signature, dto.instruction_index, error
|
||||
))),
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_token_mint_events id for signature '{}' and instruction_index '{}' on sqlite: {}",
|
||||
dto.signature, dto.instruction_index, error
|
||||
)));
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,7 +128,7 @@ LIMIT ?
|
||||
"cannot list kb_token_mint_events on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -137,7 +139,7 @@ LIMIT ?
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,13 +90,15 @@ LIMIT 1
|
||||
.fetch_one(pool)
|
||||
.await;
|
||||
match id_result {
|
||||
Ok(id) => Ok(id),
|
||||
Err(error) => Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_trade_events id for decoded_event_id '{}' on sqlite: {}",
|
||||
dto.decoded_event_id, error
|
||||
))),
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_trade_events id for decoded_event_id '{}' on sqlite: {}",
|
||||
dto.decoded_event_id, error
|
||||
)));
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,13 +146,13 @@ LIMIT 1
|
||||
"cannot read kb_trade_events by decoded_event_id '{}' on sqlite: {}",
|
||||
decoded_event_id, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => crate::KbTradeEventDto::try_from(entity).map(Some),
|
||||
None => Ok(None),
|
||||
Some(entity) => return crate::KbTradeEventDto::try_from(entity).map(Some),
|
||||
None => return Ok(None),
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,7 +200,7 @@ ORDER BY created_at ASC, id ASC
|
||||
"cannot list kb_trade_events by pair_id '{}' on sqlite: {}",
|
||||
pair_id, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -209,8 +211,8 @@ ORDER BY created_at ASC, id ASC
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,7 +260,7 @@ ORDER BY id ASC
|
||||
"cannot list kb_trade_events by transaction_id '{}' on sqlite: {}",
|
||||
transaction_id, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -269,15 +271,15 @@ ORDER BY id ASC
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn kb_trade_side_to_string(value: crate::KbSwapTradeSide) -> &'static str {
|
||||
match value {
|
||||
crate::KbSwapTradeSide::BuyBase => "BuyBase",
|
||||
crate::KbSwapTradeSide::SellBase => "SellBase",
|
||||
crate::KbSwapTradeSide::Unknown => "Unknown",
|
||||
crate::KbSwapTradeSide::BuyBase => return "BuyBase",
|
||||
crate::KbSwapTradeSide::SellBase => return "SellBase",
|
||||
crate::KbSwapTradeSide::Unknown => return "Unknown",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,13 +47,15 @@ LIMIT 1
|
||||
.fetch_one(pool)
|
||||
.await;
|
||||
match id_result {
|
||||
Ok(id) => Ok(id),
|
||||
Err(error) => Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_wallets id for address '{}' on sqlite: {}",
|
||||
dto.address, error
|
||||
))),
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_wallets id for address '{}' on sqlite: {}",
|
||||
dto.address, error
|
||||
)));
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,13 +89,13 @@ LIMIT 1
|
||||
"cannot read kb_wallets '{}' on sqlite: {}",
|
||||
address, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => crate::KbWalletDto::try_from(entity).map(Some),
|
||||
None => Ok(None),
|
||||
Some(entity) => return crate::KbWalletDto::try_from(entity).map(Some),
|
||||
None => return Ok(None),
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,7 +126,7 @@ ORDER BY address ASC
|
||||
"cannot list kb_wallets on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -135,7 +137,7 @@ ORDER BY address ASC
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,13 +76,15 @@ LIMIT 1
|
||||
.fetch_one(pool)
|
||||
.await;
|
||||
match id_result {
|
||||
Ok(id) => Ok(id),
|
||||
Err(error) => Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_wallet_holdings id for wallet_id '{}' token_id '{}' on sqlite: {}",
|
||||
dto.wallet_id, dto.token_id, error
|
||||
))),
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_wallet_holdings id for wallet_id '{}' token_id '{}' on sqlite: {}",
|
||||
dto.wallet_id, dto.token_id, error
|
||||
)));
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,13 +130,13 @@ LIMIT 1
|
||||
"cannot read kb_wallet_holdings by wallet_id '{}' token_id '{}' on sqlite: {}",
|
||||
wallet_id, token_id, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => crate::KbWalletHoldingDto::try_from(entity).map(Some),
|
||||
None => Ok(None),
|
||||
Some(entity) => return crate::KbWalletHoldingDto::try_from(entity).map(Some),
|
||||
None => return Ok(None),
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,7 +180,7 @@ ORDER BY token_id ASC, id ASC
|
||||
"cannot list kb_wallet_holdings by wallet_id '{}' on sqlite: {}",
|
||||
wallet_id, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -189,7 +191,7 @@ ORDER BY token_id ASC, id ASC
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,13 +60,15 @@ LIMIT 1
|
||||
.fetch_one(pool)
|
||||
.await;
|
||||
match id_result {
|
||||
Ok(id) => Ok(id),
|
||||
Err(error) => Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_wallet_participations id for unique_key '{}' on sqlite: {}",
|
||||
dto.unique_key, error
|
||||
))),
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_wallet_participations id for unique_key '{}' on sqlite: {}",
|
||||
dto.unique_key, error
|
||||
)));
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,13 +109,13 @@ LIMIT 1
|
||||
"cannot read kb_wallet_participations by unique_key '{}' on sqlite: {}",
|
||||
unique_key, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => crate::KbWalletParticipationDto::try_from(entity).map(Some),
|
||||
None => Ok(None),
|
||||
Some(entity) => return crate::KbWalletParticipationDto::try_from(entity).map(Some),
|
||||
None => return Ok(None),
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,7 +156,7 @@ ORDER BY created_at ASC, id ASC
|
||||
"cannot list kb_wallet_participations by wallet_id '{}' on sqlite: {}",
|
||||
wallet_id, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -165,8 +167,8 @@ ORDER BY created_at ASC, id ASC
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,7 +209,7 @@ ORDER BY created_at ASC, id ASC
|
||||
"cannot list kb_wallet_participations by pool_id '{}' on sqlite: {}",
|
||||
pool_id, error
|
||||
)));
|
||||
}
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
@@ -218,7 +220,7 @@ ORDER BY created_at ASC, id ASC
|
||||
};
|
||||
dtos.push(dto);
|
||||
}
|
||||
Ok(dtos)
|
||||
}
|
||||
return Ok(dtos);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user