This commit is contained in:
2026-05-05 05:03:11 +02:00
parent 3e994995d7
commit f2c227e08f
132 changed files with 5767 additions and 4461 deletions

View File

@@ -19,9 +19,7 @@ pub struct KbDatabase {
impl KbDatabase {
/// Opens a database connection without initializing the schema.
pub async fn connect(
config: &crate::KbDatabaseConfig,
) -> Result<Self, crate::KbError> {
pub async fn connect(config: &crate::KbDatabaseConfig) -> Result<Self, crate::KbError> {
if !config.enabled {
return Err(crate::KbError::Config(
"database is disabled in configuration".to_string(),
@@ -40,11 +38,11 @@ impl KbDatabase {
Ok(pool) => pool,
Err(error) => return Err(error),
};
Ok(Self {
return Ok(Self {
backend: crate::KbDatabaseBackend::Sqlite,
database_url,
connection: KbDatabaseConnection::Sqlite(pool),
})
});
},
}
}
@@ -64,47 +62,40 @@ impl KbDatabase {
return Err(error);
}
}
Ok(database)
return Ok(database);
}
/// Returns the configured backend.
pub fn backend(
&self,
) -> crate::KbDatabaseBackend {
self.backend
pub fn backend(&self) -> crate::KbDatabaseBackend {
return self.backend;
}
/// Returns a displayable database URL-like string.
pub fn database_url(
&self,
) -> &str {
&self.database_url
pub fn database_url(&self) -> &str {
return &self.database_url;
}
/// Pings the database.
pub async fn ping(
&self,
) -> Result<(), crate::KbError> {
pub async fn ping(&self) -> Result<(), crate::KbError> {
match &self.connection {
KbDatabaseConnection::Sqlite(pool) => {
let ping_result = sqlx::query("SELECT 1").execute(pool).await;
match ping_result {
Ok(_) => Ok(()),
Err(error) => Err(crate::KbError::Db(format!(
"cannot ping sqlite database '{}': {}",
self.database_url,
error
))),
Ok(_) => return Ok(()),
Err(error) => {
return Err(crate::KbError::Db(format!(
"cannot ping sqlite database '{}': {}",
self.database_url, error
)));
},
}
},
}
}
/// Returns the underlying connection enum.
pub(crate) fn connection(
&self,
) -> &KbDatabaseConnection {
&self.connection
pub(crate) fn connection(&self) -> &KbDatabaseConnection {
return &self.connection;
}
}

View File

@@ -33,7 +33,7 @@ impl KbAnalysisSignalDto {
score: std::option::Option<f64>,
payload: serde_json::Value,
) -> Self {
Self {
return Self {
id: None,
signal_kind,
severity,
@@ -42,7 +42,7 @@ impl KbAnalysisSignalDto {
score,
payload,
created_at: chrono::Utc::now(),
}
};
}
}
@@ -63,7 +63,7 @@ impl TryFrom<crate::KbAnalysisSignalEntity> for KbAnalysisSignalDto {
"cannot parse analysis signal created_at '{}': {}",
entity.created_at, error
)));
}
},
};
let payload_result = serde_json::from_str::<serde_json::Value>(&entity.payload_json);
let payload = match payload_result {
@@ -73,9 +73,9 @@ impl TryFrom<crate::KbAnalysisSignalEntity> for KbAnalysisSignalDto {
"cannot parse analysis signal payload_json '{}': {}",
entity.payload_json, error
)));
}
},
};
Ok(Self {
return Ok(Self {
id: Some(entity.id),
signal_kind: entity.signal_kind,
severity,
@@ -84,6 +84,6 @@ impl TryFrom<crate::KbAnalysisSignalEntity> for KbAnalysisSignalDto {
score: entity.score,
payload,
created_at,
})
});
}
}

View File

@@ -49,7 +49,7 @@ impl KbChainInstructionDto {
parsed_type: std::option::Option<std::string::String>,
parsed_json: std::option::Option<std::string::String>,
) -> Self {
Self {
return Self {
id: None,
transaction_id,
parent_instruction_id,
@@ -63,7 +63,7 @@ impl KbChainInstructionDto {
parsed_type,
parsed_json,
created_at: chrono::Utc::now(),
}
};
}
}
@@ -79,7 +79,7 @@ impl TryFrom<crate::KbChainInstructionEntity> for KbChainInstructionDto {
"cannot convert chain instruction instruction_index '{}' to u32: {}",
entity.instruction_index, error
)));
}
},
};
let inner_instruction_index = match entity.inner_instruction_index {
Some(inner_instruction_index) => {
@@ -91,9 +91,9 @@ impl TryFrom<crate::KbChainInstructionEntity> for KbChainInstructionDto {
"cannot convert chain instruction inner_instruction_index '{}' to u32: {}",
inner_instruction_index, error
)));
}
},
}
}
},
None => None,
};
let stack_height = match entity.stack_height {
@@ -106,9 +106,9 @@ impl TryFrom<crate::KbChainInstructionEntity> for KbChainInstructionDto {
"cannot convert chain instruction stack_height '{}' to u32: {}",
stack_height, error
)));
}
},
}
}
},
None => None,
};
let created_at_result = chrono::DateTime::parse_from_rfc3339(&entity.created_at);
@@ -119,9 +119,9 @@ impl TryFrom<crate::KbChainInstructionEntity> for KbChainInstructionDto {
"cannot parse chain instruction created_at '{}': {}",
entity.created_at, error
)));
}
},
};
Ok(Self {
return Ok(Self {
id: Some(entity.id),
transaction_id: entity.transaction_id,
parent_instruction_id: entity.parent_instruction_id,
@@ -135,6 +135,6 @@ impl TryFrom<crate::KbChainInstructionEntity> for KbChainInstructionDto {
parsed_type: entity.parsed_type,
parsed_json: entity.parsed_json,
created_at,
})
});
}
}

View File

@@ -25,13 +25,13 @@ impl KbChainSlotDto {
block_time_unix: std::option::Option<i64>,
) -> Self {
let now = chrono::Utc::now();
Self {
return Self {
slot,
parent_slot,
block_time_unix,
created_at: now,
updated_at: now,
}
};
}
}
@@ -47,7 +47,7 @@ impl TryFrom<crate::KbChainSlotEntity> for KbChainSlotDto {
"cannot convert chain slot '{}' to u64: {}",
entity.slot, error
)));
}
},
};
let parent_slot = match entity.parent_slot {
Some(parent_slot) => {
@@ -59,9 +59,9 @@ impl TryFrom<crate::KbChainSlotEntity> for KbChainSlotDto {
"cannot convert chain parent_slot '{}' to u64: {}",
parent_slot, error
)));
}
},
}
}
},
None => None,
};
let created_at_result = chrono::DateTime::parse_from_rfc3339(&entity.created_at);
@@ -72,7 +72,7 @@ impl TryFrom<crate::KbChainSlotEntity> for KbChainSlotDto {
"cannot parse chain slot created_at '{}': {}",
entity.created_at, error
)));
}
},
};
let updated_at_result = chrono::DateTime::parse_from_rfc3339(&entity.updated_at);
let updated_at = match updated_at_result {
@@ -82,14 +82,14 @@ impl TryFrom<crate::KbChainSlotEntity> for KbChainSlotDto {
"cannot parse chain slot updated_at '{}': {}",
entity.updated_at, error
)));
}
},
};
Ok(Self {
return Ok(Self {
slot,
parent_slot,
block_time_unix: entity.block_time_unix,
created_at,
updated_at,
})
});
}
}

View File

@@ -43,7 +43,7 @@ impl KbChainTransactionDto {
transaction_json: std::string::String,
) -> Self {
let now = chrono::Utc::now();
Self {
return Self {
id: None,
signature,
slot,
@@ -55,7 +55,7 @@ impl KbChainTransactionDto {
transaction_json,
created_at: now,
updated_at: now,
}
};
}
}
@@ -73,9 +73,9 @@ impl TryFrom<crate::KbChainTransactionEntity> for KbChainTransactionDto {
"cannot convert chain transaction slot '{}' to u64: {}",
slot, error
)));
}
},
}
}
},
None => None,
};
let created_at_result = chrono::DateTime::parse_from_rfc3339(&entity.created_at);
@@ -86,7 +86,7 @@ impl TryFrom<crate::KbChainTransactionEntity> for KbChainTransactionDto {
"cannot parse chain transaction created_at '{}': {}",
entity.created_at, error
)));
}
},
};
let updated_at_result = chrono::DateTime::parse_from_rfc3339(&entity.updated_at);
let updated_at = match updated_at_result {
@@ -96,9 +96,9 @@ impl TryFrom<crate::KbChainTransactionEntity> for KbChainTransactionDto {
"cannot parse chain transaction updated_at '{}': {}",
entity.updated_at, error
)));
}
},
};
Ok(Self {
return Ok(Self {
id: Some(entity.id),
signature: entity.signature,
slot,
@@ -110,6 +110,6 @@ impl TryFrom<crate::KbChainTransactionEntity> for KbChainTransactionDto {
transaction_json: entity.transaction_json,
created_at,
updated_at,
})
});
}
}

View File

@@ -16,11 +16,11 @@ pub struct KbDbMetadataDto {
impl KbDbMetadataDto {
/// Creates a new metadata DTO with the current UTC timestamp.
pub fn new(key: std::string::String, value: std::string::String) -> Self {
Self {
return Self {
key,
value,
updated_at: chrono::Utc::now(),
}
};
}
}
@@ -36,22 +36,22 @@ impl TryFrom<crate::KbDbMetadataEntity> for KbDbMetadataDto {
"cannot parse db metadata timestamp '{}': {}",
entity.updated_at, error
)));
}
},
};
Ok(Self {
return Ok(Self {
key: entity.key,
value: entity.value,
updated_at: parsed.with_timezone(&chrono::Utc),
})
});
}
}
impl From<KbDbMetadataDto> for crate::KbDbMetadataEntity {
fn from(dto: KbDbMetadataDto) -> Self {
Self {
return Self {
key: dto.key,
value: dto.value,
updated_at: dto.updated_at.to_rfc3339(),
}
};
}
}

View File

@@ -27,14 +27,14 @@ impl KbDbRuntimeEventDto {
source: std::string::String,
message: std::string::String,
) -> Self {
Self {
return Self {
id: None,
event_kind,
level,
source,
message,
created_at: chrono::Utc::now(),
}
};
}
}
@@ -50,20 +50,20 @@ impl TryFrom<crate::KbDbRuntimeEventEntity> for KbDbRuntimeEventDto {
"cannot parse runtime event created_at '{}': {}",
entity.created_at, error
)));
}
},
};
let level_result = crate::KbDbRuntimeEventLevel::from_i16(entity.level);
let level = match level_result {
Ok(level) => level,
Err(error) => return Err(error),
};
Ok(Self {
return Ok(Self {
id: Some(entity.id),
event_kind: entity.event_kind,
level,
source: entity.source,
message: entity.message,
created_at,
})
});
}
}

View File

@@ -33,7 +33,7 @@ impl KbDexDto {
is_enabled: bool,
) -> Self {
let now = chrono::Utc::now();
Self {
return Self {
id: None,
code,
name,
@@ -42,7 +42,7 @@ impl KbDexDto {
is_enabled,
created_at: now,
updated_at: now,
}
};
}
}
@@ -58,7 +58,7 @@ impl TryFrom<crate::KbDexEntity> for KbDexDto {
"cannot parse dex created_at '{}': {}",
entity.created_at, error
)));
}
},
};
let updated_at_result = chrono::DateTime::parse_from_rfc3339(&entity.updated_at);
let updated_at = match updated_at_result {
@@ -68,9 +68,9 @@ impl TryFrom<crate::KbDexEntity> for KbDexDto {
"cannot parse dex updated_at '{}': {}",
entity.updated_at, error
)));
}
},
};
Ok(Self {
return Ok(Self {
id: Some(entity.id),
code: entity.code,
name: entity.name,
@@ -79,6 +79,6 @@ impl TryFrom<crate::KbDexEntity> for KbDexDto {
is_enabled: entity.is_enabled != 0,
created_at,
updated_at,
})
});
}
}

View File

@@ -49,7 +49,7 @@ impl KbDexDecodedEventDto {
market_account: std::option::Option<std::string::String>,
payload_json: std::string::String,
) -> Self {
Self {
return Self {
id: None,
transaction_id,
instruction_id,
@@ -63,7 +63,7 @@ impl KbDexDecodedEventDto {
market_account,
payload_json,
created_at: chrono::Utc::now(),
}
};
}
}
@@ -79,9 +79,9 @@ impl TryFrom<crate::KbDexDecodedEventEntity> for KbDexDecodedEventDto {
"cannot parse dex decoded event created_at '{}': {}",
entity.created_at, error
)));
}
},
};
Ok(Self {
return Ok(Self {
id: Some(entity.id),
transaction_id: entity.transaction_id,
instruction_id: entity.instruction_id,
@@ -95,6 +95,6 @@ impl TryFrom<crate::KbDexDecodedEventEntity> for KbDexDecodedEventDto {
market_account: entity.market_account,
payload_json: entity.payload_json,
created_at,
})
});
}
}

View File

@@ -30,7 +30,7 @@ impl KbKnownHttpEndpointDto {
enabled: bool,
roles: std::vec::Vec<std::string::String>,
) -> Self {
Self {
return Self {
name,
provider,
url,
@@ -38,7 +38,7 @@ impl KbKnownHttpEndpointDto {
roles,
last_seen_at: None,
updated_at: chrono::Utc::now(),
}
};
}
}
@@ -55,7 +55,7 @@ impl TryFrom<crate::KbKnownHttpEndpointEntity> for KbKnownHttpEndpointDto {
"cannot parse known http endpoint roles_json '{}': {}",
entity.roles_json, error
)));
}
},
};
let updated_at_result = chrono::DateTime::parse_from_rfc3339(&entity.updated_at);
let updated_at = match updated_at_result {
@@ -65,7 +65,7 @@ impl TryFrom<crate::KbKnownHttpEndpointEntity> for KbKnownHttpEndpointDto {
"cannot parse known http endpoint updated_at '{}': {}",
entity.updated_at, error
)));
}
},
};
let last_seen_at = match entity.last_seen_at {
Some(last_seen_at_text) => {
@@ -77,12 +77,12 @@ impl TryFrom<crate::KbKnownHttpEndpointEntity> for KbKnownHttpEndpointDto {
"cannot parse known http endpoint last_seen_at '{}': {}",
last_seen_at_text, error
)));
}
},
}
}
},
None => None,
};
Ok(Self {
return Ok(Self {
name: entity.name,
provider: entity.provider,
url: entity.url,
@@ -90,7 +90,7 @@ impl TryFrom<crate::KbKnownHttpEndpointEntity> for KbKnownHttpEndpointDto {
roles,
last_seen_at,
updated_at,
})
});
}
}
@@ -106,16 +106,16 @@ impl TryFrom<KbKnownHttpEndpointDto> for crate::KbKnownHttpEndpointEntity {
"cannot serialize known http endpoint roles: {}",
error
)));
}
},
};
Ok(Self {
return Ok(Self {
name: dto.name,
provider: dto.provider,
url: dto.url,
enabled: if dto.enabled { 1 } else { 0 },
roles_json,
last_seen_at: dto.last_seen_at.map(|value| value.to_rfc3339()),
last_seen_at: dto.last_seen_at.map(|value| return value.to_rfc3339()),
updated_at: dto.updated_at.to_rfc3339(),
})
});
}
}

View File

@@ -30,7 +30,7 @@ impl KbKnownWsEndpointDto {
enabled: bool,
roles: std::vec::Vec<std::string::String>,
) -> Self {
Self {
return Self {
name,
provider,
url,
@@ -38,7 +38,7 @@ impl KbKnownWsEndpointDto {
roles,
last_seen_at: None,
updated_at: chrono::Utc::now(),
}
};
}
}
@@ -55,7 +55,7 @@ impl TryFrom<crate::KbKnownWsEndpointEntity> for KbKnownWsEndpointDto {
"cannot parse known ws endpoint roles_json '{}': {}",
entity.roles_json, error
)));
}
},
};
let updated_at_result = chrono::DateTime::parse_from_rfc3339(&entity.updated_at);
let updated_at = match updated_at_result {
@@ -65,7 +65,7 @@ impl TryFrom<crate::KbKnownWsEndpointEntity> for KbKnownWsEndpointDto {
"cannot parse known ws endpoint updated_at '{}': {}",
entity.updated_at, error
)));
}
},
};
let last_seen_at = match entity.last_seen_at {
Some(last_seen_at_text) => {
@@ -77,12 +77,12 @@ impl TryFrom<crate::KbKnownWsEndpointEntity> for KbKnownWsEndpointDto {
"cannot parse known ws endpoint last_seen_at '{}': {}",
last_seen_at_text, error
)));
}
},
}
}
},
None => None,
};
Ok(Self {
return Ok(Self {
name: entity.name,
provider: entity.provider,
url: entity.url,
@@ -90,7 +90,7 @@ impl TryFrom<crate::KbKnownWsEndpointEntity> for KbKnownWsEndpointDto {
roles,
last_seen_at,
updated_at,
})
});
}
}
@@ -106,16 +106,16 @@ impl TryFrom<KbKnownWsEndpointDto> for crate::KbKnownWsEndpointEntity {
"cannot serialize known ws endpoint roles: {}",
error
)));
}
},
};
Ok(Self {
return Ok(Self {
name: dto.name,
provider: dto.provider,
url: dto.url,
enabled: if dto.enabled { 1 } else { 0 },
roles_json,
last_seen_at: dto.last_seen_at.map(|value| value.to_rfc3339()),
last_seen_at: dto.last_seen_at.map(|value| return value.to_rfc3339()),
updated_at: dto.updated_at.to_rfc3339(),
})
});
}
}

View File

@@ -45,7 +45,7 @@ impl KbLaunchAttributionDto {
matched_value: std::string::String,
) -> Self {
let now = chrono::Utc::now();
Self {
return Self {
id: None,
launch_surface_id,
transaction_id,
@@ -58,7 +58,7 @@ impl KbLaunchAttributionDto {
matched_value,
attributed_at: now,
updated_at: now,
}
};
}
}
@@ -74,7 +74,7 @@ impl TryFrom<crate::KbLaunchAttributionEntity> for KbLaunchAttributionDto {
"cannot parse launch_attribution attributed_at '{}': {}",
entity.attributed_at, error
)));
}
},
};
let updated_at_result = chrono::DateTime::parse_from_rfc3339(&entity.updated_at);
let updated_at = match updated_at_result {
@@ -84,9 +84,9 @@ impl TryFrom<crate::KbLaunchAttributionEntity> for KbLaunchAttributionDto {
"cannot parse launch_attribution updated_at '{}': {}",
entity.updated_at, error
)));
}
},
};
Ok(Self {
return Ok(Self {
id: Some(entity.id),
launch_surface_id: entity.launch_surface_id,
transaction_id: entity.transaction_id,
@@ -99,6 +99,6 @@ impl TryFrom<crate::KbLaunchAttributionEntity> for KbLaunchAttributionDto {
matched_value: entity.matched_value,
attributed_at,
updated_at,
})
});
}
}

View File

@@ -30,7 +30,7 @@ impl KbLaunchSurfaceDto {
is_enabled: bool,
) -> Self {
let now = chrono::Utc::now();
Self {
return Self {
id: None,
code,
name,
@@ -38,7 +38,7 @@ impl KbLaunchSurfaceDto {
is_enabled,
created_at: now,
updated_at: now,
}
};
}
}
@@ -54,7 +54,7 @@ impl TryFrom<crate::KbLaunchSurfaceEntity> for KbLaunchSurfaceDto {
"cannot parse launch_surface created_at '{}': {}",
entity.created_at, error
)));
}
},
};
let updated_at_result = chrono::DateTime::parse_from_rfc3339(&entity.updated_at);
let updated_at = match updated_at_result {
@@ -64,9 +64,9 @@ impl TryFrom<crate::KbLaunchSurfaceEntity> for KbLaunchSurfaceDto {
"cannot parse launch_surface updated_at '{}': {}",
entity.updated_at, error
)));
}
},
};
Ok(Self {
return Ok(Self {
id: Some(entity.id),
code: entity.code,
name: entity.name,
@@ -74,6 +74,6 @@ impl TryFrom<crate::KbLaunchSurfaceEntity> for KbLaunchSurfaceDto {
is_enabled: entity.is_enabled != 0,
created_at,
updated_at,
})
});
}
}

View File

@@ -27,14 +27,14 @@ impl KbLaunchSurfaceKeyDto {
match_value: std::string::String,
) -> Self {
let now = chrono::Utc::now();
Self {
return Self {
id: None,
launch_surface_id,
match_kind,
match_value,
created_at: now,
updated_at: now,
}
};
}
}
@@ -50,7 +50,7 @@ impl TryFrom<crate::KbLaunchSurfaceKeyEntity> for KbLaunchSurfaceKeyDto {
"cannot parse launch_surface_key created_at '{}': {}",
entity.created_at, error
)));
}
},
};
let updated_at_result = chrono::DateTime::parse_from_rfc3339(&entity.updated_at);
let updated_at = match updated_at_result {
@@ -60,15 +60,15 @@ impl TryFrom<crate::KbLaunchSurfaceKeyEntity> for KbLaunchSurfaceKeyDto {
"cannot parse launch_surface_key updated_at '{}': {}",
entity.updated_at, error
)));
}
},
};
Ok(Self {
return Ok(Self {
id: Some(entity.id),
launch_surface_id: entity.launch_surface_id,
match_kind: entity.match_kind,
match_value: entity.match_value,
created_at,
updated_at,
})
});
}
}

View File

@@ -57,7 +57,7 @@ impl KbLiquidityEventDto {
quote_amount: std::string::String,
lp_amount: std::option::Option<std::string::String>,
) -> Self {
Self {
return Self {
id: None,
dex_id,
pool_id,
@@ -74,7 +74,7 @@ impl KbLiquidityEventDto {
quote_amount,
lp_amount,
executed_at: chrono::Utc::now(),
}
};
}
}
@@ -95,7 +95,7 @@ impl TryFrom<crate::KbLiquidityEventEntity> for KbLiquidityEventDto {
"cannot parse liquidity event executed_at '{}': {}",
entity.executed_at, error
)));
}
},
};
let slot = match entity.slot {
Some(slot) => {
@@ -107,12 +107,12 @@ impl TryFrom<crate::KbLiquidityEventEntity> for KbLiquidityEventDto {
"cannot convert liquidity event slot '{}' to u64: {}",
slot, error
)));
}
},
}
}
},
None => None,
};
Ok(Self {
return Ok(Self {
id: Some(entity.id),
dex_id: entity.dex_id,
pool_id: entity.pool_id,
@@ -129,6 +129,6 @@ impl TryFrom<crate::KbLiquidityEventEntity> for KbLiquidityEventDto {
quote_amount: entity.quote_amount,
lp_amount: entity.lp_amount,
executed_at,
})
});
}
}

View File

@@ -38,7 +38,7 @@ impl KbObservedTokenDto {
status: crate::KbObservedTokenStatus,
) -> Self {
let now = chrono::Utc::now();
Self {
return Self {
id: None,
mint,
symbol,
@@ -49,16 +49,14 @@ impl KbObservedTokenDto {
first_seen_at: now,
last_seen_at: now,
updated_at: now,
}
};
}
}
impl TryFrom<crate::KbObservedTokenEntity> for KbObservedTokenDto {
type Error = crate::KbError;
fn try_from(
entity: crate::KbObservedTokenEntity,
) -> Result<Self, Self::Error> {
fn try_from(entity: crate::KbObservedTokenEntity) -> Result<Self, Self::Error> {
let status_result = crate::KbObservedTokenStatus::from_i16(entity.status);
let status = match status_result {
Ok(status) => status,
@@ -70,8 +68,7 @@ impl TryFrom<crate::KbObservedTokenEntity> for KbObservedTokenDto {
Err(error) => {
return Err(crate::KbError::Db(format!(
"cannot parse observed token first_seen_at '{}': {}",
entity.first_seen_at,
error
entity.first_seen_at, error
)));
},
};
@@ -81,8 +78,7 @@ impl TryFrom<crate::KbObservedTokenEntity> for KbObservedTokenDto {
Err(error) => {
return Err(crate::KbError::Db(format!(
"cannot parse observed token last_seen_at '{}': {}",
entity.last_seen_at,
error
entity.last_seen_at, error
)));
},
};
@@ -92,8 +88,7 @@ impl TryFrom<crate::KbObservedTokenEntity> for KbObservedTokenDto {
Err(error) => {
return Err(crate::KbError::Db(format!(
"cannot parse observed token updated_at '{}': {}",
entity.updated_at,
error
entity.updated_at, error
)));
},
};
@@ -105,15 +100,14 @@ impl TryFrom<crate::KbObservedTokenEntity> for KbObservedTokenDto {
Err(error) => {
return Err(crate::KbError::Db(format!(
"cannot convert observed token decimals '{}' to u8: {}",
decimals,
error
decimals, error
)));
},
}
},
None => None,
};
Ok(Self {
return Ok(Self {
id: Some(entity.id),
mint: entity.mint,
symbol: entity.symbol,
@@ -124,6 +118,6 @@ impl TryFrom<crate::KbObservedTokenEntity> for KbObservedTokenDto {
first_seen_at,
last_seen_at,
updated_at,
})
});
}
}

View File

@@ -33,7 +33,7 @@ impl KbOnchainObservationDto {
slot: std::option::Option<u64>,
payload: serde_json::Value,
) -> Self {
Self {
return Self {
id: None,
observation_kind,
source_kind,
@@ -42,7 +42,7 @@ impl KbOnchainObservationDto {
slot,
payload,
observed_at: chrono::Utc::now(),
}
};
}
}
@@ -63,7 +63,7 @@ impl TryFrom<crate::KbOnchainObservationEntity> for KbOnchainObservationDto {
"cannot parse on-chain observation observed_at '{}': {}",
entity.observed_at, error
)));
}
},
};
let payload_result = serde_json::from_str::<serde_json::Value>(&entity.payload_json);
let payload = match payload_result {
@@ -73,7 +73,7 @@ impl TryFrom<crate::KbOnchainObservationEntity> for KbOnchainObservationDto {
"cannot parse on-chain observation payload_json '{}': {}",
entity.payload_json, error
)));
}
},
};
let slot = match entity.slot {
Some(slot) => {
@@ -85,12 +85,12 @@ impl TryFrom<crate::KbOnchainObservationEntity> for KbOnchainObservationDto {
"cannot convert on-chain observation slot '{}' to u64: {}",
slot, error
)));
}
},
}
}
},
None => None,
};
Ok(Self {
return Ok(Self {
id: Some(entity.id),
observation_kind: entity.observation_kind,
source_kind,
@@ -99,6 +99,6 @@ impl TryFrom<crate::KbOnchainObservationEntity> for KbOnchainObservationDto {
slot,
payload,
observed_at,
})
});
}
}

View File

@@ -33,7 +33,7 @@ impl KbPairDto {
symbol: std::option::Option<std::string::String>,
) -> Self {
let now = chrono::Utc::now();
Self {
return Self {
id: None,
dex_id,
pool_id,
@@ -42,7 +42,7 @@ impl KbPairDto {
symbol,
first_seen_at: now,
updated_at: now,
}
};
}
}
@@ -58,7 +58,7 @@ impl TryFrom<crate::KbPairEntity> for KbPairDto {
"cannot parse pair first_seen_at '{}': {}",
entity.first_seen_at, error
)));
}
},
};
let updated_at_result = chrono::DateTime::parse_from_rfc3339(&entity.updated_at);
let updated_at = match updated_at_result {
@@ -68,9 +68,9 @@ impl TryFrom<crate::KbPairEntity> for KbPairDto {
"cannot parse pair updated_at '{}': {}",
entity.updated_at, error
)));
}
},
};
Ok(Self {
return Ok(Self {
id: Some(entity.id),
dex_id: entity.dex_id,
pool_id: entity.pool_id,
@@ -79,6 +79,6 @@ impl TryFrom<crate::KbPairEntity> for KbPairDto {
symbol: entity.symbol,
first_seen_at,
updated_at,
})
});
}
}

View File

@@ -45,7 +45,7 @@ impl KbPairAnalyticSignalDto {
last_transaction_id: std::option::Option<i64>,
) -> Self {
let now = chrono::Utc::now();
Self {
return Self {
id: None,
pair_id,
signal_kind,
@@ -58,7 +58,7 @@ impl KbPairAnalyticSignalDto {
last_transaction_id,
created_at: now,
updated_at: now,
}
};
}
}
@@ -80,7 +80,7 @@ impl TryFrom<crate::KbPairAnalyticSignalEntity> for KbPairAnalyticSignalDto {
"cannot parse pair_analytic_signal signal_value_json '{}': {}",
entity.signal_value_json, error
)));
}
},
};
let created_at_result = chrono::DateTime::parse_from_rfc3339(entity.created_at.as_str());
let created_at = match created_at_result {
@@ -90,7 +90,7 @@ impl TryFrom<crate::KbPairAnalyticSignalEntity> for KbPairAnalyticSignalDto {
"cannot parse pair_analytic_signal created_at '{}': {}",
entity.created_at, error
)));
}
},
};
let updated_at_result = chrono::DateTime::parse_from_rfc3339(entity.updated_at.as_str());
let updated_at = match updated_at_result {
@@ -100,9 +100,9 @@ impl TryFrom<crate::KbPairAnalyticSignalEntity> for KbPairAnalyticSignalDto {
"cannot parse pair_analytic_signal updated_at '{}': {}",
entity.updated_at, error
)));
}
},
};
Ok(Self {
return Ok(Self {
id: Some(entity.id),
pair_id: entity.pair_id,
signal_kind: entity.signal_kind,
@@ -115,6 +115,6 @@ impl TryFrom<crate::KbPairAnalyticSignalEntity> for KbPairAnalyticSignalDto {
last_transaction_id: entity.last_transaction_id,
created_at,
updated_at,
})
});
}
}

View File

@@ -64,7 +64,7 @@ impl KbPairCandleDto {
last_trade_signature: std::option::Option<std::string::String>,
) -> Self {
let now = chrono::Utc::now();
Self {
return Self {
id: None,
pair_id,
timeframe_seconds,
@@ -83,7 +83,7 @@ impl KbPairCandleDto {
last_trade_signature,
created_at: now,
updated_at: now,
}
};
}
}
@@ -99,7 +99,7 @@ impl TryFrom<crate::KbPairCandleEntity> for KbPairCandleDto {
"cannot parse pair_candle created_at '{}': {}",
entity.created_at, error
)));
}
},
};
let updated_at_result = chrono::DateTime::parse_from_rfc3339(&entity.updated_at);
let updated_at = match updated_at_result {
@@ -109,9 +109,9 @@ impl TryFrom<crate::KbPairCandleEntity> for KbPairCandleDto {
"cannot parse pair_candle updated_at '{}': {}",
entity.updated_at, error
)));
}
},
};
Ok(Self {
return Ok(Self {
id: Some(entity.id),
pair_id: entity.pair_id,
timeframe_seconds: entity.timeframe_seconds,
@@ -130,6 +130,6 @@ impl TryFrom<crate::KbPairCandleEntity> for KbPairCandleDto {
last_trade_signature: entity.last_trade_signature,
created_at,
updated_at,
})
});
}
}

View File

@@ -39,7 +39,7 @@ impl KbPairMetricDto {
/// Creates a new pair-metric DTO.
pub fn new(pair_id: i64) -> Self {
let now = chrono::Utc::now();
Self {
return Self {
id: None,
pair_id,
first_slot: None,
@@ -54,7 +54,7 @@ impl KbPairMetricDto {
last_price_quote_per_base: None,
created_at: now,
updated_at: now,
}
};
}
}
@@ -70,7 +70,7 @@ impl TryFrom<crate::KbPairMetricEntity> for KbPairMetricDto {
"cannot parse pair_metric created_at '{}': {}",
entity.created_at, error
)));
}
},
};
let updated_at_result = chrono::DateTime::parse_from_rfc3339(&entity.updated_at);
let updated_at = match updated_at_result {
@@ -80,9 +80,9 @@ impl TryFrom<crate::KbPairMetricEntity> for KbPairMetricDto {
"cannot parse pair_metric updated_at '{}': {}",
entity.updated_at, error
)));
}
},
};
Ok(Self {
return Ok(Self {
id: Some(entity.id),
pair_id: entity.pair_id,
first_slot: entity.first_slot,
@@ -97,6 +97,6 @@ impl TryFrom<crate::KbPairMetricEntity> for KbPairMetricDto {
last_price_quote_per_base: entity.last_price_quote_per_base,
created_at,
updated_at,
})
});
}
}

View File

@@ -30,7 +30,7 @@ impl KbPoolDto {
status: crate::KbPoolStatus,
) -> Self {
let now = chrono::Utc::now();
Self {
return Self {
id: None,
dex_id,
address,
@@ -38,7 +38,7 @@ impl KbPoolDto {
status,
first_seen_at: now,
updated_at: now,
}
};
}
}
@@ -64,7 +64,7 @@ impl TryFrom<crate::KbPoolEntity> for KbPoolDto {
"cannot parse pool first_seen_at '{}': {}",
entity.first_seen_at, error
)));
}
},
};
let updated_at_result = chrono::DateTime::parse_from_rfc3339(&entity.updated_at);
let updated_at = match updated_at_result {
@@ -74,9 +74,9 @@ impl TryFrom<crate::KbPoolEntity> for KbPoolDto {
"cannot parse pool updated_at '{}': {}",
entity.updated_at, error
)));
}
},
};
Ok(Self {
return Ok(Self {
id: Some(entity.id),
dex_id: entity.dex_id,
address: entity.address,
@@ -84,6 +84,6 @@ impl TryFrom<crate::KbPoolEntity> for KbPoolDto {
status,
first_seen_at,
updated_at,
})
});
}
}

View File

@@ -42,7 +42,7 @@ impl KbPoolListingDto {
initial_price_quote: std::option::Option<f64>,
) -> Self {
let now = chrono::Utc::now();
Self {
return Self {
id: None,
dex_id,
pool_id,
@@ -54,7 +54,7 @@ impl KbPoolListingDto {
initial_quote_reserve,
initial_price_quote,
updated_at: now,
}
};
}
}
@@ -75,7 +75,7 @@ impl TryFrom<crate::KbPoolListingEntity> for KbPoolListingDto {
"cannot parse pool_listing detected_at '{}': {}",
entity.detected_at, error
)));
}
},
};
let updated_at_result = chrono::DateTime::parse_from_rfc3339(&entity.updated_at);
let updated_at = match updated_at_result {
@@ -85,9 +85,9 @@ impl TryFrom<crate::KbPoolListingEntity> for KbPoolListingDto {
"cannot parse pool_listing updated_at '{}': {}",
entity.updated_at, error
)));
}
},
};
Ok(Self {
return Ok(Self {
id: Some(entity.id),
dex_id: entity.dex_id,
pool_id: entity.pool_id,
@@ -99,6 +99,6 @@ impl TryFrom<crate::KbPoolListingEntity> for KbPoolListingDto {
initial_quote_reserve: entity.initial_quote_reserve,
initial_price_quote: entity.initial_price_quote,
updated_at,
})
});
}
}

View File

@@ -54,7 +54,7 @@ impl KbPoolOriginDto {
launch_attribution_id: std::option::Option<i64>,
) -> Self {
let now = chrono::Utc::now();
Self {
return Self {
id: None,
dex_id,
pool_id,
@@ -70,7 +70,7 @@ impl KbPoolOriginDto {
launch_attribution_id,
created_at: now,
updated_at: now,
}
};
}
}
@@ -91,7 +91,7 @@ impl TryFrom<crate::KbPoolOriginEntity> for KbPoolOriginDto {
"cannot parse pool_origin created_at '{}': {}",
entity.created_at, error
)));
}
},
};
let updated_at_result = chrono::DateTime::parse_from_rfc3339(&entity.updated_at);
let updated_at = match updated_at_result {
@@ -101,9 +101,9 @@ impl TryFrom<crate::KbPoolOriginEntity> for KbPoolOriginDto {
"cannot parse pool_origin updated_at '{}': {}",
entity.updated_at, error
)));
}
},
};
Ok(Self {
return Ok(Self {
id: Some(entity.id),
dex_id: entity.dex_id,
pool_id: entity.pool_id,
@@ -119,6 +119,6 @@ impl TryFrom<crate::KbPoolOriginEntity> for KbPoolOriginDto {
launch_attribution_id: entity.launch_attribution_id,
created_at,
updated_at,
})
});
}
}

View File

@@ -33,7 +33,7 @@ impl KbPoolTokenDto {
token_order: std::option::Option<i64>,
) -> Self {
let now = chrono::Utc::now();
Self {
return Self {
id: None,
pool_id,
token_id,
@@ -42,7 +42,7 @@ impl KbPoolTokenDto {
token_order,
created_at: now,
updated_at: now,
}
};
}
}
@@ -63,7 +63,7 @@ impl TryFrom<crate::KbPoolTokenEntity> for KbPoolTokenDto {
"cannot parse pool_token created_at '{}': {}",
entity.created_at, error
)));
}
},
};
let updated_at_result = chrono::DateTime::parse_from_rfc3339(&entity.updated_at);
let updated_at = match updated_at_result {
@@ -73,9 +73,9 @@ impl TryFrom<crate::KbPoolTokenEntity> for KbPoolTokenDto {
"cannot parse pool_token updated_at '{}': {}",
entity.updated_at, error
)));
}
},
};
Ok(Self {
return Ok(Self {
id: Some(entity.id),
pool_id: entity.pool_id,
token_id: entity.token_id,
@@ -84,6 +84,6 @@ impl TryFrom<crate::KbPoolTokenEntity> for KbPoolTokenDto {
token_order: entity.token_order,
created_at,
updated_at,
})
});
}
}

View File

@@ -54,7 +54,7 @@ impl KbSwapDto {
price_quote: std::option::Option<std::string::String>,
trade_side: crate::KbSwapTradeSide,
) -> Self {
Self {
return Self {
id: None,
dex_id,
pool_id,
@@ -70,7 +70,7 @@ impl KbSwapDto {
price_quote,
trade_side,
executed_at: chrono::Utc::now(),
}
};
}
}
@@ -91,7 +91,7 @@ impl TryFrom<crate::KbSwapEntity> for KbSwapDto {
"cannot parse swap executed_at '{}': {}",
entity.executed_at, error
)));
}
},
};
let slot = match entity.slot {
Some(slot) => {
@@ -103,12 +103,12 @@ impl TryFrom<crate::KbSwapEntity> for KbSwapDto {
"cannot convert swap slot '{}' to u64: {}",
slot, error
)));
}
},
}
}
},
None => None,
};
Ok(Self {
return Ok(Self {
id: Some(entity.id),
dex_id: entity.dex_id,
pool_id: entity.pool_id,
@@ -124,6 +124,6 @@ impl TryFrom<crate::KbSwapEntity> for KbSwapDto {
price_quote: entity.price_quote,
trade_side,
executed_at,
})
});
}
}

View File

@@ -36,7 +36,7 @@ impl KbTokenDto {
is_quote_token: bool,
) -> Self {
let now = chrono::Utc::now();
Self {
return Self {
id: None,
mint,
symbol,
@@ -46,7 +46,7 @@ impl KbTokenDto {
is_quote_token,
first_seen_at: now,
updated_at: now,
}
};
}
}
@@ -62,7 +62,7 @@ impl TryFrom<crate::KbTokenEntity> for KbTokenDto {
"cannot parse token first_seen_at '{}': {}",
entity.first_seen_at, error
)));
}
},
};
let updated_at_result = chrono::DateTime::parse_from_rfc3339(&entity.updated_at);
let updated_at = match updated_at_result {
@@ -72,7 +72,7 @@ impl TryFrom<crate::KbTokenEntity> for KbTokenDto {
"cannot parse token updated_at '{}': {}",
entity.updated_at, error
)));
}
},
};
let decimals = match entity.decimals {
Some(decimals) => {
@@ -84,12 +84,12 @@ impl TryFrom<crate::KbTokenEntity> for KbTokenDto {
"cannot convert token decimals '{}' to u8: {}",
decimals, error
)));
}
},
}
}
},
None => None,
};
Ok(Self {
return Ok(Self {
id: Some(entity.id),
mint: entity.mint,
symbol: entity.symbol,
@@ -99,6 +99,6 @@ impl TryFrom<crate::KbTokenEntity> for KbTokenDto {
is_quote_token: entity.is_quote_token != 0,
first_seen_at,
updated_at,
})
});
}
}

View File

@@ -39,7 +39,7 @@ impl KbTokenBurnEventDto {
amount: std::string::String,
supply_after: std::option::Option<std::string::String>,
) -> Self {
Self {
return Self {
id: None,
token_id,
signature,
@@ -50,24 +50,21 @@ impl KbTokenBurnEventDto {
amount,
supply_after,
executed_at: chrono::Utc::now(),
}
};
}
}
impl TryFrom<crate::KbTokenBurnEventEntity> for KbTokenBurnEventDto {
type Error = crate::KbError;
fn try_from(
entity: crate::KbTokenBurnEventEntity,
) -> Result<Self, Self::Error> {
fn try_from(entity: crate::KbTokenBurnEventEntity) -> Result<Self, Self::Error> {
let executed_at_result = chrono::DateTime::parse_from_rfc3339(&entity.executed_at);
let executed_at = match executed_at_result {
Ok(executed_at) => executed_at.with_timezone(&chrono::Utc),
Err(error) => {
return Err(crate::KbError::Db(format!(
"cannot parse token burn event executed_at '{}': {}",
entity.executed_at,
error
entity.executed_at, error
)));
},
};
@@ -79,15 +76,14 @@ impl TryFrom<crate::KbTokenBurnEventEntity> for KbTokenBurnEventDto {
Err(error) => {
return Err(crate::KbError::Db(format!(
"cannot convert token burn event slot '{}' to u64: {}",
slot,
error
slot, error
)));
},
}
},
None => None,
};
Ok(Self {
return Ok(Self {
id: Some(entity.id),
token_id: entity.token_id,
signature: entity.signature,
@@ -98,6 +94,6 @@ impl TryFrom<crate::KbTokenBurnEventEntity> for KbTokenBurnEventDto {
amount: entity.amount,
supply_after: entity.supply_after,
executed_at,
})
});
}
}

View File

@@ -39,7 +39,7 @@ impl KbTokenMintEventDto {
amount: std::string::String,
supply_after: std::option::Option<std::string::String>,
) -> Self {
Self {
return Self {
id: None,
token_id,
signature,
@@ -50,7 +50,7 @@ impl KbTokenMintEventDto {
amount,
supply_after,
executed_at: chrono::Utc::now(),
}
};
}
}
@@ -66,7 +66,7 @@ impl TryFrom<crate::KbTokenMintEventEntity> for KbTokenMintEventDto {
"cannot parse token mint event executed_at '{}': {}",
entity.executed_at, error
)));
}
},
};
let slot = match entity.slot {
Some(slot) => {
@@ -78,12 +78,12 @@ impl TryFrom<crate::KbTokenMintEventEntity> for KbTokenMintEventDto {
"cannot convert token mint event slot '{}' to u64: {}",
slot, error
)));
}
},
}
}
},
None => None,
};
Ok(Self {
return Ok(Self {
id: Some(entity.id),
token_id: entity.token_id,
signature: entity.signature,
@@ -94,6 +94,6 @@ impl TryFrom<crate::KbTokenMintEventEntity> for KbTokenMintEventDto {
amount: entity.amount,
supply_after: entity.supply_after,
executed_at,
})
});
}
}

View File

@@ -66,7 +66,7 @@ impl KbTradeEventDto {
payload_json: std::string::String,
) -> Self {
let now = chrono::Utc::now();
Self {
return Self {
id: None,
dex_id,
pool_id,
@@ -86,7 +86,7 @@ impl KbTradeEventDto {
payload_json,
created_at: now,
updated_at: now,
}
};
}
}
@@ -108,7 +108,7 @@ impl TryFrom<crate::KbTradeEventEntity> for KbTradeEventDto {
"cannot parse trade_event created_at '{}': {}",
entity.created_at, error
)));
}
},
};
let updated_at_result = chrono::DateTime::parse_from_rfc3339(&entity.updated_at);
let updated_at = match updated_at_result {
@@ -118,9 +118,9 @@ impl TryFrom<crate::KbTradeEventEntity> for KbTradeEventDto {
"cannot parse trade_event updated_at '{}': {}",
entity.updated_at, error
)));
}
},
};
Ok(Self {
return Ok(Self {
id: Some(entity.id),
dex_id: entity.dex_id,
pool_id: entity.pool_id,
@@ -140,14 +140,14 @@ impl TryFrom<crate::KbTradeEventEntity> for KbTradeEventDto {
payload_json: entity.payload_json,
created_at,
updated_at,
})
});
}
}
fn kb_trade_side_from_string(value: &str) -> crate::KbSwapTradeSide {
match value {
"BuyBase" => crate::KbSwapTradeSide::BuyBase,
"SellBase" => crate::KbSwapTradeSide::SellBase,
_ => crate::KbSwapTradeSide::Unknown,
"BuyBase" => return crate::KbSwapTradeSide::BuyBase,
"SellBase" => return crate::KbSwapTradeSide::SellBase,
_ => return crate::KbSwapTradeSide::Unknown,
}
}

View File

@@ -24,13 +24,13 @@ impl KbWalletDto {
label: std::option::Option<std::string::String>,
) -> Self {
let now = chrono::Utc::now();
Self {
return Self {
id: None,
address,
label,
first_seen_at: now,
last_seen_at: now,
}
};
}
}
@@ -46,7 +46,7 @@ impl TryFrom<crate::KbWalletEntity> for KbWalletDto {
"cannot parse wallet first_seen_at '{}': {}",
entity.first_seen_at, error
)));
}
},
};
let last_seen_at_result = chrono::DateTime::parse_from_rfc3339(&entity.last_seen_at);
let last_seen_at = match last_seen_at_result {
@@ -56,14 +56,14 @@ impl TryFrom<crate::KbWalletEntity> for KbWalletDto {
"cannot parse wallet last_seen_at '{}': {}",
entity.last_seen_at, error
)));
}
},
};
Ok(Self {
return Ok(Self {
id: Some(entity.id),
address: entity.address,
label: entity.label,
first_seen_at,
last_seen_at,
})
});
}
}

View File

@@ -54,7 +54,7 @@ impl KbWalletHoldingDto {
source_endpoint_name: std::option::Option<std::string::String>,
) -> Self {
let now = chrono::Utc::now();
Self {
return Self {
id: None,
wallet_id,
token_id,
@@ -70,7 +70,7 @@ impl KbWalletHoldingDto {
source_endpoint_name,
created_at: now,
updated_at: now,
}
};
}
}
@@ -91,7 +91,7 @@ impl TryFrom<crate::KbWalletHoldingEntity> for KbWalletHoldingDto {
"cannot parse wallet_holding created_at '{}': {}",
entity.created_at, error
)));
}
},
};
let updated_at_result = chrono::DateTime::parse_from_rfc3339(&entity.updated_at);
let updated_at = match updated_at_result {
@@ -101,9 +101,9 @@ impl TryFrom<crate::KbWalletHoldingEntity> for KbWalletHoldingDto {
"cannot parse wallet_holding updated_at '{}': {}",
entity.updated_at, error
)));
}
},
};
Ok(Self {
return Ok(Self {
id: Some(entity.id),
wallet_id: entity.wallet_id,
token_id: entity.token_id,

View File

@@ -52,8 +52,7 @@ impl KbWalletParticipationDto {
pair_id,
role.as_str(),
);
Self {
return Self {
id: None,
wallet_id,
transaction_id,
@@ -66,7 +65,7 @@ impl KbWalletParticipationDto {
source_endpoint_name,
created_at: now,
updated_at: now,
}
};
}
}
@@ -87,7 +86,7 @@ impl TryFrom<crate::KbWalletParticipationEntity> for KbWalletParticipationDto {
"cannot parse wallet_participation created_at '{}': {}",
entity.created_at, error
)));
}
},
};
let updated_at_result = chrono::DateTime::parse_from_rfc3339(&entity.updated_at);
let updated_at = match updated_at_result {
@@ -97,9 +96,9 @@ impl TryFrom<crate::KbWalletParticipationEntity> for KbWalletParticipationDto {
"cannot parse wallet_participation updated_at '{}': {}",
entity.updated_at, error
)));
}
},
};
Ok(Self {
return Ok(Self {
id: Some(entity.id),
wallet_id: entity.wallet_id,
transaction_id: entity.transaction_id,
@@ -112,7 +111,7 @@ impl TryFrom<crate::KbWalletParticipationEntity> for KbWalletParticipationDto {
source_endpoint_name: entity.source_endpoint_name,
created_at,
updated_at,
})
});
}
}
@@ -127,8 +126,8 @@ fn kb_build_wallet_participation_unique_key(
let decoded_event_id_value = decoded_event_id.unwrap_or_default();
let pool_id_value = pool_id.unwrap_or_default();
let pair_id_value = pair_id.unwrap_or_default();
format!(
return format!(
"{}:{}:{}:{}:{}:{}",
wallet_id, transaction_id, decoded_event_id_value, pool_id_value, pair_id_value, role
)
);
}

View File

@@ -48,6 +48,7 @@ pub use chain_slot::get_chain_slot;
pub use chain_slot::list_recent_chain_slots;
pub use chain_slot::upsert_chain_slot;
pub use chain_transaction::get_chain_transaction_by_signature;
pub use chain_transaction::list_chain_transaction_signatures_for_replay;
pub use chain_transaction::list_recent_chain_transactions;
pub use chain_transaction::upsert_chain_transaction;
pub use db_metadata::get_db_metadata;
@@ -59,6 +60,7 @@ pub use dex::get_dex_by_code;
pub use dex::list_dexes;
pub use dex::upsert_dex;
pub use dex_decoded_event::get_dex_decoded_event_by_key;
pub use dex_decoded_event::get_latest_pump_fun_create_payload_by_mint;
pub use dex_decoded_event::list_dex_decoded_events_by_transaction_id;
pub use dex_decoded_event::upsert_dex_decoded_event;
pub use known_http_endpoint::get_known_http_endpoint;
@@ -85,6 +87,7 @@ pub use onchain_observation::insert_onchain_observation;
pub use onchain_observation::list_recent_onchain_observations;
pub use pair::get_pair_by_pool_id;
pub use pair::list_pairs;
pub use pair::update_pair_symbol;
pub use pair::upsert_pair;
pub use pair_analytic_signal::get_pair_analytic_signal_by_key;
pub use pair_analytic_signal::list_pair_analytic_signals_by_pair_id;
@@ -108,8 +111,10 @@ pub use pool_token::list_pool_tokens_by_pool_id;
pub use pool_token::upsert_pool_token;
pub use swap::list_recent_swaps;
pub use swap::upsert_swap;
pub use token::get_token_by_id;
pub use token::get_token_by_mint;
pub use token::list_tokens;
pub use token::list_tokens_missing_metadata;
pub use token::upsert_token;
pub use token_burn_event::list_recent_token_burn_events;
pub use token_burn_event::upsert_token_burn_event;

View File

@@ -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);
},
}
}

View File

@@ -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]

View File

@@ -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]

View File

@@ -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)

View File

@@ -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());
}
}

View File

@@ -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);
},
}
}

View File

@@ -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);
}
}

View File

@@ -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),
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
},
}
}

View File

@@ -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);
},
}
}

View File

@@ -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);
},
}
}

View File

@@ -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);
},
}
}

View File

@@ -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);
}
}

View File

@@ -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);
},
}
}

View File

@@ -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);
}
}

View File

@@ -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);
},
}
}

View File

@@ -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);
},
}
}

View File

@@ -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);
},
}
}

View File

@@ -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);
}
}

View File

@@ -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");

View File

@@ -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);
},
}
}

View File

@@ -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");

View File

@@ -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);
},
}
}

View File

@@ -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");
}
}

View File

@@ -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");

View File

@@ -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);
},
}
}

View File

@@ -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",
}
}

View File

@@ -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);
},
}
}

View File

@@ -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);
},
}
}

View File

@@ -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);
},
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -8,12 +8,10 @@ pub(crate) fn sqlite_database_url_from_config(
) -> Result<std::string::String, crate::KbError> {
let path = config.sqlite.path.trim();
if path.is_empty() {
return Err(crate::KbError::Config(
"database.sqlite.path must not be empty".to_string(),
));
return Err(crate::KbError::Config("database.sqlite.path must not be empty".to_string()));
}
let database_path = config.sqlite.path_buf();
Ok(format!("sqlite://{}", database_path.display()))
return Ok(format!("sqlite://{}", database_path.display()));
}
/// Opens a SQLite pool according to configuration.
@@ -22,9 +20,7 @@ pub(crate) async fn connect_sqlite(
) -> Result<sqlx::SqlitePool, crate::KbError> {
let path = config.sqlite.path.trim();
if path.is_empty() {
return Err(crate::KbError::Config(
"database.sqlite.path must not be empty".to_string(),
));
return Err(crate::KbError::Config("database.sqlite.path must not be empty".to_string()));
}
if config.sqlite.max_connections == 0 {
return Err(crate::KbError::Config(
@@ -49,9 +45,7 @@ pub(crate) async fn connect_sqlite(
.filename(&database_path)
.create_if_missing(config.sqlite.create_if_missing)
.foreign_keys(true)
.busy_timeout(std::time::Duration::from_millis(
config.sqlite.busy_timeout_ms,
));
.busy_timeout(std::time::Duration::from_millis(config.sqlite.busy_timeout_ms));
if config.sqlite.use_wal {
connect_options = connect_options.journal_mode(sqlx::sqlite::SqliteJournalMode::Wal);
}
@@ -59,10 +53,13 @@ pub(crate) async fn connect_sqlite(
sqlx::sqlite::SqlitePoolOptions::new().max_connections(config.sqlite.max_connections);
let connect_result = pool_options.connect_with(connect_options).await;
match connect_result {
Ok(pool) => Ok(pool),
Err(error) => Err(crate::KbError::Db(format!(
"cannot open sqlite database '{}': {}",
database_path.display(), error
))),
Ok(pool) => return Ok(pool),
Err(error) => {
return Err(crate::KbError::Db(format!(
"cannot open sqlite database '{}': {}",
database_path.display(),
error
)));
},
}
}

View File

@@ -21,28 +21,28 @@ impl KbAnalysisSignalSeverity {
/// Converts the severity to its stable integer representation.
pub fn to_i16(self) -> i16 {
match self {
Self::Info => 0,
Self::Low => 1,
Self::Medium => 2,
Self::High => 3,
Self::Critical => 4,
Self::Info => return 0,
Self::Low => return 1,
Self::Medium => return 2,
Self::High => return 3,
Self::Critical => return 4,
}
}
/// Restores a severity from its stable integer representation.
pub fn from_i16(
value: i16,
) -> Result<Self, crate::KbError> {
pub fn from_i16(value: i16) -> Result<Self, crate::KbError> {
match value {
0 => Ok(Self::Info),
1 => Ok(Self::Low),
2 => Ok(Self::Medium),
3 => Ok(Self::High),
4 => Ok(Self::Critical),
_ => Err(crate::KbError::Db(format!(
"invalid KbAnalysisSignalSeverity value: {}",
value
))),
0 => return Ok(Self::Info),
1 => return Ok(Self::Low),
2 => return Ok(Self::Medium),
3 => return Ok(Self::High),
4 => return Ok(Self::Critical),
_ => {
return Err(crate::KbError::Db(format!(
"invalid KbAnalysisSignalSeverity value: {}",
value
)));
},
}
}
}

View File

@@ -15,20 +15,22 @@ impl KbLiquidityEventKind {
/// Converts the event kind to its stable integer representation.
pub fn to_i16(self) -> i16 {
match self {
Self::Add => 0,
Self::Remove => 1,
Self::Add => return 0,
Self::Remove => return 1,
}
}
/// Restores an event kind from its stable integer representation.
pub fn from_i16(value: i16) -> Result<Self, crate::KbError> {
match value {
0 => Ok(Self::Add),
1 => Ok(Self::Remove),
_ => Err(crate::KbError::Db(format!(
"invalid KbLiquidityEventKind value: {}",
value
))),
0 => return Ok(Self::Add),
1 => return Ok(Self::Remove),
_ => {
return Err(crate::KbError::Db(format!(
"invalid KbLiquidityEventKind value: {}",
value
)));
},
}
}
}

View File

@@ -21,26 +21,28 @@ impl KbObservationSourceKind {
/// Converts the source kind to its stable integer representation.
pub fn to_i16(self) -> i16 {
match self {
Self::HttpRpc => 0,
Self::WsRpc => 1,
Self::Grpc => 2,
Self::Dex => 3,
Self::Other => 4,
Self::HttpRpc => return 0,
Self::WsRpc => return 1,
Self::Grpc => return 2,
Self::Dex => return 3,
Self::Other => return 4,
}
}
/// Restores a source kind from its stable integer representation.
pub fn from_i16(value: i16) -> Result<Self, crate::KbError> {
match value {
0 => Ok(Self::HttpRpc),
1 => Ok(Self::WsRpc),
2 => Ok(Self::Grpc),
3 => Ok(Self::Dex),
4 => Ok(Self::Other),
_ => Err(crate::KbError::Db(format!(
"invalid KbObservationSourceKind value: {}",
value
))),
0 => return Ok(Self::HttpRpc),
1 => return Ok(Self::WsRpc),
2 => return Ok(Self::Grpc),
3 => return Ok(Self::Dex),
4 => return Ok(Self::Other),
_ => {
return Err(crate::KbError::Db(format!(
"invalid KbObservationSourceKind value: {}",
value
)));
},
}
}
}

View File

@@ -19,24 +19,26 @@ impl KbObservedTokenStatus {
/// Converts the status to its stable integer representation.
pub fn to_i16(self) -> i16 {
match self {
Self::New => 0,
Self::Active => 1,
Self::Ignored => 2,
Self::Blocked => 3,
Self::New => return 0,
Self::Active => return 1,
Self::Ignored => return 2,
Self::Blocked => return 3,
}
}
/// Restores a status from its stable integer representation.
pub fn from_i16(value: i16) -> Result<Self, crate::KbError> {
match value {
0 => Ok(Self::New),
1 => Ok(Self::Active),
2 => Ok(Self::Ignored),
3 => Ok(Self::Blocked),
_ => Err(crate::KbError::Db(format!(
"invalid KbObservedTokenStatus value: {}",
value
))),
0 => return Ok(Self::New),
1 => return Ok(Self::Active),
2 => return Ok(Self::Ignored),
3 => return Ok(Self::Blocked),
_ => {
return Err(crate::KbError::Db(format!(
"invalid KbObservedTokenStatus value: {}",
value
)));
},
}
}
}

View File

@@ -1,4 +1,3 @@
// file: kb_lib/src/db/types/pool_kind.rs
//! Pool kind.
@@ -22,28 +21,23 @@ impl KbPoolKind {
/// Converts the kind to its stable integer representation.
pub fn to_i16(self) -> i16 {
match self {
Self::Unknown => 0,
Self::Amm => 1,
Self::Clmm => 2,
Self::BondingCurve => 3,
Self::OrderBook => 4,
Self::Unknown => return 0,
Self::Amm => return 1,
Self::Clmm => return 2,
Self::BondingCurve => return 3,
Self::OrderBook => return 4,
}
}
/// Restores a kind from its stable integer representation.
pub fn from_i16(
value: i16,
) -> Result<Self, crate::KbError> {
pub fn from_i16(value: i16) -> Result<Self, crate::KbError> {
match value {
0 => Ok(Self::Unknown),
1 => Ok(Self::Amm),
2 => Ok(Self::Clmm),
3 => Ok(Self::BondingCurve),
4 => Ok(Self::OrderBook),
_ => Err(crate::KbError::Db(format!(
"invalid KbPoolKind value: {}",
value
))),
0 => return Ok(Self::Unknown),
1 => return Ok(Self::Amm),
2 => return Ok(Self::Clmm),
3 => return Ok(Self::BondingCurve),
4 => return Ok(Self::OrderBook),
_ => return Err(crate::KbError::Db(format!("invalid KbPoolKind value: {}", value))),
}
}
}

View File

@@ -21,26 +21,23 @@ impl KbPoolStatus {
/// Converts the status to its stable integer representation.
pub fn to_i16(self) -> i16 {
match self {
Self::Unknown => 0,
Self::Pending => 1,
Self::Active => 2,
Self::Inactive => 3,
Self::Closed => 4,
Self::Unknown => return 0,
Self::Pending => return 1,
Self::Active => return 2,
Self::Inactive => return 3,
Self::Closed => return 4,
}
}
/// Restores a status from its stable integer representation.
pub fn from_i16(value: i16) -> Result<Self, crate::KbError> {
match value {
0 => Ok(Self::Unknown),
1 => Ok(Self::Pending),
2 => Ok(Self::Active),
3 => Ok(Self::Inactive),
4 => Ok(Self::Closed),
_ => Err(crate::KbError::Db(format!(
"invalid KbPoolStatus value: {}",
value
))),
0 => return Ok(Self::Unknown),
1 => return Ok(Self::Pending),
2 => return Ok(Self::Active),
3 => return Ok(Self::Inactive),
4 => return Ok(Self::Closed),
_ => return Err(crate::KbError::Db(format!("invalid KbPoolStatus value: {}", value))),
}
}
}

View File

@@ -21,26 +21,25 @@ impl KbPoolTokenRole {
/// Converts the role to its stable integer representation.
pub fn to_i16(self) -> i16 {
match self {
Self::Base => 0,
Self::Quote => 1,
Self::LpMint => 2,
Self::Reserve => 3,
Self::Other => 4,
Self::Base => return 0,
Self::Quote => return 1,
Self::LpMint => return 2,
Self::Reserve => return 3,
Self::Other => return 4,
}
}
/// Restores a role from its stable integer representation.
pub fn from_i16(value: i16) -> Result<Self, crate::KbError> {
match value {
0 => Ok(Self::Base),
1 => Ok(Self::Quote),
2 => Ok(Self::LpMint),
3 => Ok(Self::Reserve),
4 => Ok(Self::Other),
_ => Err(crate::KbError::Db(format!(
"invalid KbPoolTokenRole value: {}",
value
))),
0 => return Ok(Self::Base),
1 => return Ok(Self::Quote),
2 => return Ok(Self::LpMint),
3 => return Ok(Self::Reserve),
4 => return Ok(Self::Other),
_ => {
return Err(crate::KbError::Db(format!("invalid KbPoolTokenRole value: {}", value)));
},
}
}
}

View File

@@ -21,26 +21,28 @@ impl KbDbRuntimeEventLevel {
/// Converts the level to its stable integer representation.
pub fn to_i16(self) -> i16 {
match self {
Self::Trace => 0,
Self::Debug => 1,
Self::Info => 2,
Self::Warn => 3,
Self::Error => 4,
Self::Trace => return 0,
Self::Debug => return 1,
Self::Info => return 2,
Self::Warn => return 3,
Self::Error => return 4,
}
}
/// Restores a level from its stable integer representation.
pub fn from_i16(value: i16) -> Result<Self, crate::KbError> {
match value {
0 => Ok(Self::Trace),
1 => Ok(Self::Debug),
2 => Ok(Self::Info),
3 => Ok(Self::Warn),
4 => Ok(Self::Error),
_ => Err(crate::KbError::Db(format!(
"invalid KbDbRuntimeEventLevel value: {}",
value
))),
0 => return Ok(Self::Trace),
1 => return Ok(Self::Debug),
2 => return Ok(Self::Info),
3 => return Ok(Self::Warn),
4 => return Ok(Self::Error),
_ => {
return Err(crate::KbError::Db(format!(
"invalid KbDbRuntimeEventLevel value: {}",
value
)));
},
}
}
}

View File

@@ -17,22 +17,24 @@ impl KbSwapTradeSide {
/// Converts the trade side to its stable integer representation.
pub fn to_i16(self) -> i16 {
match self {
Self::Unknown => 0,
Self::BuyBase => 1,
Self::SellBase => 2,
Self::Unknown => return 0,
Self::BuyBase => return 1,
Self::SellBase => return 2,
}
}
/// Restores a trade side from its stable integer representation.
pub fn from_i16(value: i16) -> Result<Self, crate::KbError> {
match value {
0 => Ok(Self::Unknown),
1 => Ok(Self::BuyBase),
2 => Ok(Self::SellBase),
_ => Err(crate::KbError::Db(format!(
"invalid KbSwapTradeSide value: {}",
value
))),
0 => return Ok(Self::Unknown),
1 => return Ok(Self::BuyBase),
2 => return Ok(Self::SellBase),
_ => {
return Err(crate::KbError::Db(format!(
"invalid KbSwapTradeSide value: {}",
value
)));
},
}
}
}