0.7.27 +Refactor
This commit is contained in:
@@ -4,33 +4,33 @@
|
||||
|
||||
/// Root application configuration loaded from `config.json`.
|
||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbConfig {
|
||||
pub struct Config {
|
||||
/// Application-level metadata and global behavior.
|
||||
pub app: KbAppConfig,
|
||||
pub app: AppConfig,
|
||||
/// Tracing and log output configuration.
|
||||
pub logging: KbLoggingConfig,
|
||||
pub logging: LoggingConfig,
|
||||
/// Data directory configuration.
|
||||
pub data: KbDataConfig,
|
||||
pub data: DataConfig,
|
||||
/// Solana endpoint configuration.
|
||||
pub solana: KbSolanaConfig,
|
||||
pub solana: SolanaConfig,
|
||||
/// Database configuration.
|
||||
pub database: KbDatabaseConfig,
|
||||
pub database: DatabaseConfig,
|
||||
}
|
||||
|
||||
impl KbConfig {
|
||||
impl Config {
|
||||
/// Returns the default path of the JSON configuration file.
|
||||
pub fn default_path() -> std::path::PathBuf {
|
||||
return kb_workspace_root_dir().join("config.json");
|
||||
return workspace_root_dir().join("config.json");
|
||||
}
|
||||
|
||||
/// Loads a configuration from a JSON file and validates it.
|
||||
pub fn load_from_path<P: AsRef<std::path::Path>>(path: P) -> Result<Self, crate::KbError> {
|
||||
pub fn load_from_path<P: AsRef<std::path::Path>>(path: P) -> Result<Self, crate::Error> {
|
||||
let path_ref = path.as_ref();
|
||||
let content_result = std::fs::read_to_string(path_ref);
|
||||
let content = match content_result {
|
||||
Ok(content) => content,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Io(format!(
|
||||
return Err(crate::Error::Io(format!(
|
||||
"cannot read configuration file '{}': {error}",
|
||||
path_ref.display()
|
||||
)));
|
||||
@@ -40,7 +40,7 @@ impl KbConfig {
|
||||
let config = match config_result {
|
||||
Ok(config) => config,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Json(format!(
|
||||
return Err(crate::Error::Json(format!(
|
||||
"cannot parse configuration file '{}': {error}",
|
||||
path_ref.display()
|
||||
)));
|
||||
@@ -54,29 +54,27 @@ impl KbConfig {
|
||||
}
|
||||
|
||||
/// Validates the current configuration.
|
||||
pub fn validate(&self) -> Result<(), crate::KbError> {
|
||||
pub fn validate(&self) -> Result<(), crate::Error> {
|
||||
if self.app.name.trim().is_empty() {
|
||||
return Err(crate::KbError::Config("app.name must not be empty".to_string()));
|
||||
return Err(crate::Error::Config("app.name must not be empty".to_string()));
|
||||
}
|
||||
if self.app.environment.trim().is_empty() {
|
||||
return Err(crate::KbError::Config("app.environment must not be empty".to_string()));
|
||||
return Err(crate::Error::Config("app.environment must not be empty".to_string()));
|
||||
}
|
||||
if self.logging.level.trim().is_empty() {
|
||||
return Err(crate::KbError::Config("logging.level must not be empty".to_string()));
|
||||
return Err(crate::Error::Config("logging.level must not be empty".to_string()));
|
||||
}
|
||||
if self.logging.directory.trim().is_empty() {
|
||||
return Err(crate::KbError::Config("logging.directory must not be empty".to_string()));
|
||||
return Err(crate::Error::Config("logging.directory must not be empty".to_string()));
|
||||
}
|
||||
if self.logging.file_prefix.trim().is_empty() {
|
||||
return Err(crate::KbError::Config(
|
||||
"logging.file_prefix must not be empty".to_string(),
|
||||
));
|
||||
return Err(crate::Error::Config("logging.file_prefix must not be empty".to_string()));
|
||||
}
|
||||
if self.data.sqlite_path.trim().is_empty() {
|
||||
return Err(crate::KbError::Config("data.sqlite_path must not be empty".to_string()));
|
||||
return Err(crate::Error::Config("data.sqlite_path must not be empty".to_string()));
|
||||
}
|
||||
if self.data.wallets_directory.trim().is_empty() {
|
||||
return Err(crate::KbError::Config(
|
||||
return Err(crate::Error::Config(
|
||||
"data.wallets_directory must not be empty".to_string(),
|
||||
));
|
||||
}
|
||||
@@ -84,7 +82,7 @@ impl KbConfig {
|
||||
&& self.logging.rotation != "hourly"
|
||||
&& self.logging.rotation != "never"
|
||||
{
|
||||
return Err(crate::KbError::Config(format!(
|
||||
return Err(crate::Error::Config(format!(
|
||||
"unsupported logging.rotation '{}'",
|
||||
self.logging.rotation
|
||||
)));
|
||||
@@ -94,7 +92,7 @@ impl KbConfig {
|
||||
&& self.logging.message_format != "pretty"
|
||||
&& self.logging.message_format != "json"
|
||||
{
|
||||
return Err(crate::KbError::Config(format!(
|
||||
return Err(crate::Error::Config(format!(
|
||||
"unsupported logging.message_format '{}'",
|
||||
self.logging.message_format
|
||||
)));
|
||||
@@ -103,7 +101,7 @@ impl KbConfig {
|
||||
&& self.logging.time_format != "rfc3339_millis"
|
||||
&& self.logging.time_format != "none"
|
||||
{
|
||||
return Err(crate::KbError::Config(format!(
|
||||
return Err(crate::Error::Config(format!(
|
||||
"unsupported logging.time_format '{}'",
|
||||
self.logging.time_format
|
||||
)));
|
||||
@@ -125,11 +123,11 @@ impl KbConfig {
|
||||
}
|
||||
|
||||
/// Creates the basic runtime directories required by the current configuration.
|
||||
pub fn prepare_filesystem(&self) -> Result<(), crate::KbError> {
|
||||
pub fn prepare_filesystem(&self) -> Result<(), crate::Error> {
|
||||
let logging_directory = self.logging.directory_path();
|
||||
let create_logs_result = std::fs::create_dir_all(&logging_directory);
|
||||
if let Err(error) = create_logs_result {
|
||||
return Err(crate::KbError::Io(format!(
|
||||
return Err(crate::Error::Io(format!(
|
||||
"cannot create logging directory '{}': {error}",
|
||||
logging_directory.display()
|
||||
)));
|
||||
@@ -137,7 +135,7 @@ impl KbConfig {
|
||||
let wallets_directory = self.data.wallets_directory_path();
|
||||
let create_wallets_result = std::fs::create_dir_all(&wallets_directory);
|
||||
if let Err(error) = create_wallets_result {
|
||||
return Err(crate::KbError::Io(format!(
|
||||
return Err(crate::Error::Io(format!(
|
||||
"cannot create wallets directory '{}': {error}",
|
||||
wallets_directory.display()
|
||||
)));
|
||||
@@ -148,7 +146,7 @@ impl KbConfig {
|
||||
if !sqlite_parent.as_os_str().is_empty() {
|
||||
let create_db_parent_result = std::fs::create_dir_all(sqlite_parent);
|
||||
if let Err(error) = create_db_parent_result {
|
||||
return Err(crate::KbError::Io(format!(
|
||||
return Err(crate::Error::Io(format!(
|
||||
"cannot create database parent directory '{}': {error}",
|
||||
sqlite_parent.display()
|
||||
)));
|
||||
@@ -162,7 +160,7 @@ impl KbConfig {
|
||||
pub fn find_http_endpoint(
|
||||
&self,
|
||||
endpoint_name: &str,
|
||||
) -> std::option::Option<&KbHttpEndpointConfig> {
|
||||
) -> std::option::Option<&HttpEndpointConfig> {
|
||||
return self
|
||||
.solana
|
||||
.http_endpoints
|
||||
@@ -171,10 +169,7 @@ impl KbConfig {
|
||||
}
|
||||
|
||||
/// Returns a named WebSocket endpoint by reference.
|
||||
pub fn find_ws_endpoint(
|
||||
&self,
|
||||
endpoint_name: &str,
|
||||
) -> std::option::Option<&KbWsEndpointConfig> {
|
||||
pub fn find_ws_endpoint(&self, endpoint_name: &str) -> std::option::Option<&WsEndpointConfig> {
|
||||
return self
|
||||
.solana
|
||||
.ws_endpoints
|
||||
@@ -184,44 +179,44 @@ impl KbConfig {
|
||||
|
||||
fn validate_http_endpoint(
|
||||
&self,
|
||||
endpoint: &KbHttpEndpointConfig,
|
||||
endpoint: &HttpEndpointConfig,
|
||||
endpoint_names: &mut std::vec::Vec<std::string::String>,
|
||||
) -> Result<(), crate::KbError> {
|
||||
) -> Result<(), crate::Error> {
|
||||
if endpoint.name.trim().is_empty() {
|
||||
return Err(crate::KbError::Config("http endpoint name must not be empty".to_string()));
|
||||
return Err(crate::Error::Config("http endpoint name must not be empty".to_string()));
|
||||
}
|
||||
if endpoint_names.iter().any(|name| return name == &endpoint.name) {
|
||||
return Err(crate::KbError::Config(format!(
|
||||
return Err(crate::Error::Config(format!(
|
||||
"duplicated endpoint name '{}'",
|
||||
endpoint.name
|
||||
)));
|
||||
}
|
||||
if !endpoint.url.starts_with("http://") && !endpoint.url.starts_with("https://") {
|
||||
return Err(crate::KbError::Config(format!(
|
||||
return Err(crate::Error::Config(format!(
|
||||
"http endpoint '{}' must start with http:// or https://",
|
||||
endpoint.name
|
||||
)));
|
||||
}
|
||||
if endpoint.requests_per_second == 0 {
|
||||
return Err(crate::KbError::Config(format!(
|
||||
return Err(crate::Error::Config(format!(
|
||||
"http endpoint '{}' requests_per_second must be > 0",
|
||||
endpoint.name
|
||||
)));
|
||||
}
|
||||
if endpoint.burst_capacity == 0 {
|
||||
return Err(crate::KbError::Config(format!(
|
||||
return Err(crate::Error::Config(format!(
|
||||
"http endpoint '{}' burst_capacity must be > 0",
|
||||
endpoint.name
|
||||
)));
|
||||
}
|
||||
if endpoint.connect_timeout_ms == 0 {
|
||||
return Err(crate::KbError::Config(format!(
|
||||
return Err(crate::Error::Config(format!(
|
||||
"http endpoint '{}' connect_timeout_ms must be > 0",
|
||||
endpoint.name
|
||||
)));
|
||||
}
|
||||
if endpoint.request_timeout_ms == 0 {
|
||||
return Err(crate::KbError::Config(format!(
|
||||
return Err(crate::Error::Config(format!(
|
||||
"http endpoint '{}' request_timeout_ms must be > 0",
|
||||
endpoint.name
|
||||
)));
|
||||
@@ -232,56 +227,56 @@ impl KbConfig {
|
||||
|
||||
fn validate_ws_endpoint(
|
||||
&self,
|
||||
endpoint: &KbWsEndpointConfig,
|
||||
endpoint: &WsEndpointConfig,
|
||||
endpoint_names: &mut std::vec::Vec<std::string::String>,
|
||||
) -> Result<(), crate::KbError> {
|
||||
) -> Result<(), crate::Error> {
|
||||
if endpoint.name.trim().is_empty() {
|
||||
return Err(crate::KbError::Config("ws endpoint name must not be empty".to_string()));
|
||||
return Err(crate::Error::Config("ws endpoint name must not be empty".to_string()));
|
||||
}
|
||||
if endpoint_names.iter().any(|name| return name == &endpoint.name) {
|
||||
return Err(crate::KbError::Config(format!(
|
||||
return Err(crate::Error::Config(format!(
|
||||
"duplicated endpoint name '{}'",
|
||||
endpoint.name
|
||||
)));
|
||||
}
|
||||
if !endpoint.url.starts_with("ws://") && !endpoint.url.starts_with("wss://") {
|
||||
return Err(crate::KbError::Config(format!(
|
||||
return Err(crate::Error::Config(format!(
|
||||
"ws endpoint '{}' must start with ws:// or wss://",
|
||||
endpoint.name
|
||||
)));
|
||||
}
|
||||
if endpoint.max_subscriptions == 0 {
|
||||
return Err(crate::KbError::Config(format!(
|
||||
return Err(crate::Error::Config(format!(
|
||||
"ws endpoint '{}' max_subscriptions must be > 0",
|
||||
endpoint.name
|
||||
)));
|
||||
}
|
||||
if endpoint.connect_timeout_ms == 0 {
|
||||
return Err(crate::KbError::Config(format!(
|
||||
return Err(crate::Error::Config(format!(
|
||||
"ws endpoint '{}' connect_timeout_ms must be > 0",
|
||||
endpoint.name
|
||||
)));
|
||||
}
|
||||
if endpoint.request_timeout_ms == 0 {
|
||||
return Err(crate::KbError::Config(format!(
|
||||
return Err(crate::Error::Config(format!(
|
||||
"ws endpoint '{}' request_timeout_ms must be > 0",
|
||||
endpoint.name
|
||||
)));
|
||||
}
|
||||
if endpoint.unsubscribe_timeout_ms == 0 {
|
||||
return Err(crate::KbError::Config(format!(
|
||||
return Err(crate::Error::Config(format!(
|
||||
"ws endpoint '{}' unsubscribe_timeout_ms must be > 0",
|
||||
endpoint.name
|
||||
)));
|
||||
}
|
||||
if endpoint.write_channel_capacity == 0 {
|
||||
return Err(crate::KbError::Config(format!(
|
||||
return Err(crate::Error::Config(format!(
|
||||
"ws endpoint '{}' write_channel_capacity must be > 0",
|
||||
endpoint.name
|
||||
)));
|
||||
}
|
||||
if endpoint.event_channel_capacity == 0 {
|
||||
return Err(crate::KbError::Config(format!(
|
||||
return Err(crate::Error::Config(format!(
|
||||
"ws endpoint '{}' event_channel_capacity must be > 0",
|
||||
endpoint.name
|
||||
)));
|
||||
@@ -293,7 +288,7 @@ impl KbConfig {
|
||||
|
||||
/// Generic application settings.
|
||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbAppConfig {
|
||||
pub struct AppConfig {
|
||||
/// Human-readable application name.
|
||||
pub name: std::string::String,
|
||||
/// Current environment name such as `development` or `production`.
|
||||
@@ -312,7 +307,7 @@ pub struct KbAppConfig {
|
||||
/// configuration so that the format policy is stabilized early, even though
|
||||
/// their handling will be refined in later versions.
|
||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbLoggingConfig {
|
||||
pub struct LoggingConfig {
|
||||
/// Global default log level.
|
||||
pub level: std::string::String,
|
||||
/// Enables console logging.
|
||||
@@ -335,47 +330,47 @@ pub struct KbLoggingConfig {
|
||||
pub target_filters: std::collections::BTreeMap<std::string::String, std::string::String>,
|
||||
}
|
||||
|
||||
impl KbLoggingConfig {
|
||||
impl LoggingConfig {
|
||||
/// Returns the resolved logging directory path.
|
||||
pub fn directory_path(&self) -> std::path::PathBuf {
|
||||
return kb_resolve_workspace_relative_path(&self.directory);
|
||||
return resolve_workspace_relative_path(&self.directory);
|
||||
}
|
||||
}
|
||||
|
||||
/// Local data paths used by the application.
|
||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbDataConfig {
|
||||
pub struct DataConfig {
|
||||
/// SQLite database path.
|
||||
pub sqlite_path: std::string::String,
|
||||
/// Directory storing Solana wallets and related material in future versions.
|
||||
pub wallets_directory: std::string::String,
|
||||
}
|
||||
|
||||
impl KbDataConfig {
|
||||
impl DataConfig {
|
||||
/// Returns the resolved SQLite database path.
|
||||
pub fn sqlite_path_buf(&self) -> std::path::PathBuf {
|
||||
return kb_resolve_workspace_relative_path(&self.sqlite_path);
|
||||
return resolve_workspace_relative_path(&self.sqlite_path);
|
||||
}
|
||||
|
||||
/// Returns the resolved wallets directory path.
|
||||
pub fn wallets_directory_path(&self) -> std::path::PathBuf {
|
||||
return kb_resolve_workspace_relative_path(&self.wallets_directory);
|
||||
return resolve_workspace_relative_path(&self.wallets_directory);
|
||||
}
|
||||
}
|
||||
|
||||
/// Solana transport configuration.
|
||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbSolanaConfig {
|
||||
pub struct SolanaConfig {
|
||||
/// Named HTTP endpoints.
|
||||
pub http_endpoints: std::vec::Vec<KbHttpEndpointConfig>,
|
||||
pub http_endpoints: std::vec::Vec<HttpEndpointConfig>,
|
||||
/// Named WebSocket endpoints.
|
||||
pub ws_endpoints: std::vec::Vec<KbWsEndpointConfig>,
|
||||
pub ws_endpoints: std::vec::Vec<WsEndpointConfig>,
|
||||
}
|
||||
|
||||
/// HTTP endpoint configuration.
|
||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct KbHttpEndpointConfig {
|
||||
pub struct HttpEndpointConfig {
|
||||
/// Logical endpoint name.
|
||||
pub name: std::string::String,
|
||||
/// Whether this endpoint is enabled.
|
||||
@@ -412,10 +407,10 @@ pub struct KbHttpEndpointConfig {
|
||||
pub max_concurrent_requests_per_endpoint: usize,
|
||||
}
|
||||
|
||||
impl KbHttpEndpointConfig {
|
||||
impl HttpEndpointConfig {
|
||||
/// Returns the resolved URL, replacing an `${ENV_VAR}` placeholder when
|
||||
/// `api_key_env_var` is configured.
|
||||
pub fn resolved_url(&self) -> Result<std::string::String, crate::KbError> {
|
||||
pub fn resolved_url(&self) -> Result<std::string::String, crate::Error> {
|
||||
let env_var_name_option = self.api_key_env_var.as_ref();
|
||||
let env_var_name = match env_var_name_option {
|
||||
Some(env_var_name) => env_var_name,
|
||||
@@ -427,7 +422,7 @@ impl KbHttpEndpointConfig {
|
||||
let api_key = match api_key_result {
|
||||
Ok(api_key) => api_key,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Config(format!(
|
||||
return Err(crate::Error::Config(format!(
|
||||
"cannot resolve api key env var '{}' for http endpoint '{}': {}",
|
||||
env_var_name, self.name, error
|
||||
)));
|
||||
@@ -443,7 +438,7 @@ impl KbHttpEndpointConfig {
|
||||
|
||||
/// WebSocket endpoint configuration.
|
||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbWsEndpointConfig {
|
||||
pub struct WsEndpointConfig {
|
||||
/// Stable internal endpoint name used by the application.
|
||||
pub name: std::string::String,
|
||||
/// Enables or disables the endpoint.
|
||||
@@ -472,17 +467,17 @@ pub struct KbWsEndpointConfig {
|
||||
pub auto_reconnect: bool,
|
||||
}
|
||||
|
||||
impl KbWsEndpointConfig {
|
||||
impl WsEndpointConfig {
|
||||
/// Returns the resolved endpoint URL.
|
||||
pub fn resolved_url(&self) -> Result<std::string::String, crate::KbError> {
|
||||
return kb_resolve_endpoint_url(&self.url, &self.api_key_env_var);
|
||||
pub fn resolved_url(&self) -> Result<std::string::String, crate::Error> {
|
||||
return resolve_endpoint_url(&self.url, &self.api_key_env_var);
|
||||
}
|
||||
}
|
||||
|
||||
/// SQLite configuration.
|
||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct KbSqliteDatabaseConfig {
|
||||
pub struct SqliteDatabaseConfig {
|
||||
/// SQLite database path.
|
||||
pub path: std::string::String,
|
||||
/// Whether the file should be created if missing.
|
||||
@@ -497,26 +492,26 @@ pub struct KbSqliteDatabaseConfig {
|
||||
pub use_wal: bool,
|
||||
}
|
||||
|
||||
impl KbSqliteDatabaseConfig {
|
||||
impl SqliteDatabaseConfig {
|
||||
/// Returns the resolved SQLite database path.
|
||||
pub fn path_buf(&self) -> std::path::PathBuf {
|
||||
return kb_resolve_workspace_relative_path(&self.path);
|
||||
return resolve_workspace_relative_path(&self.path);
|
||||
}
|
||||
}
|
||||
|
||||
/// Database configuration.
|
||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct KbDatabaseConfig {
|
||||
pub struct DatabaseConfig {
|
||||
/// Whether the database layer is enabled.
|
||||
pub enabled: bool,
|
||||
/// Selected backend.
|
||||
pub backend: crate::KbDatabaseBackend,
|
||||
pub backend: crate::DatabaseBackend,
|
||||
/// SQLite-specific configuration.
|
||||
pub sqlite: KbSqliteDatabaseConfig,
|
||||
pub sqlite: SqliteDatabaseConfig,
|
||||
}
|
||||
|
||||
fn kb_workspace_root_dir() -> std::path::PathBuf {
|
||||
fn workspace_root_dir() -> std::path::PathBuf {
|
||||
let manifest_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
match manifest_dir.parent() {
|
||||
Some(parent) => return parent.to_path_buf(),
|
||||
@@ -524,18 +519,18 @@ fn kb_workspace_root_dir() -> std::path::PathBuf {
|
||||
}
|
||||
}
|
||||
|
||||
fn kb_resolve_workspace_relative_path<P: AsRef<std::path::Path>>(path: P) -> std::path::PathBuf {
|
||||
fn resolve_workspace_relative_path<P: AsRef<std::path::Path>>(path: P) -> std::path::PathBuf {
|
||||
let input_path = std::path::PathBuf::from(path.as_ref());
|
||||
if input_path.is_absolute() {
|
||||
return input_path;
|
||||
}
|
||||
return kb_workspace_root_dir().join(input_path);
|
||||
return workspace_root_dir().join(input_path);
|
||||
}
|
||||
|
||||
fn kb_resolve_endpoint_url(
|
||||
fn resolve_endpoint_url(
|
||||
url: &str,
|
||||
api_key_env_var: &std::option::Option<std::string::String>,
|
||||
) -> Result<std::string::String, crate::KbError> {
|
||||
) -> Result<std::string::String, crate::Error> {
|
||||
let env_var_name_option = api_key_env_var.as_deref();
|
||||
let env_var_name = match env_var_name_option {
|
||||
Some(env_var_name) => env_var_name,
|
||||
@@ -551,7 +546,7 @@ fn kb_resolve_endpoint_url(
|
||||
let env_value = match env_value_result {
|
||||
Ok(env_value) => env_value,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Config(format!(
|
||||
return Err(crate::Error::Config(format!(
|
||||
"environment variable '{}' is required to resolve endpoint url '{}': {error}",
|
||||
env_var_name, url
|
||||
)));
|
||||
|
||||
@@ -2,22 +2,59 @@
|
||||
|
||||
//! Solana program and mint constants reused by the project.
|
||||
|
||||
/// SPL Token program identifier.
|
||||
pub const SPL_TOKEN_PROGRAM_ID: solana_sdk::pubkey::Pubkey = spl_token_interface::ID;
|
||||
/// SPL Token program identifier. ("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA").
|
||||
/// @see solana_sdk::pubkey::Pubkey = spl_token_interface::ID
|
||||
pub const SPL_TOKEN_PROGRAM_ID: &str = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
|
||||
|
||||
/// SPL Token-2022 program identifier.
|
||||
pub const SPL_TOKEN_2022_PROGRAM_ID: solana_sdk::pubkey::Pubkey = spl_token_2022_interface::ID;
|
||||
/// SPL Token-2022 program identifier. ("TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb").
|
||||
/// @see solana_sdk::pubkey::Pubkey = spl_token_2022_interface::ID
|
||||
pub const SPL_TOKEN_2022_PROGRAM_ID: &str = "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb";
|
||||
|
||||
/// Associated Token Account program identifier.
|
||||
pub const ASSOCIATED_TOKEN_PROGRAM_ID: solana_sdk::pubkey::Pubkey =
|
||||
spl_associated_token_account_interface::program::ID;
|
||||
/// Associated Token Account program identifier. ("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL").
|
||||
/// @see solana_sdk::pubkey::Pubkey = spl_associated_token_account_interface::program::ID
|
||||
pub const ASSOCIATED_TOKEN_PROGRAM_ID: &str = "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL";
|
||||
|
||||
/// Wrapped SOL mint identifier.
|
||||
pub const WSOL_MINT_ID: solana_sdk::pubkey::Pubkey = spl_token_interface::native_mint::ID;
|
||||
/// Wrapped SOL mint identifier. ("So11111111111111111111111111111111111111112").
|
||||
/// @see solana_sdk::pubkey::Pubkey = spl_token_interface::native_mint::ID
|
||||
pub const WSOL_MINT_ID: &str = "So11111111111111111111111111111111111111112";
|
||||
|
||||
/// System program identifier.
|
||||
pub const SYSTEM_PROGRAM_ID: solana_sdk::pubkey::Pubkey = solana_sdk_ids::system_program::ID;
|
||||
/// System program identifier. ("11111111111111111111111111111111").
|
||||
/// @see solana_sdk::pubkey::Pubkey = solana_sdk_ids::system_program::ID
|
||||
pub const SYSTEM_PROGRAM_ID: &str = "11111111111111111111111111111111";
|
||||
|
||||
/// Compute Budget program identifier.
|
||||
pub const COMPUTE_BUDGET_PROGRAM_ID: solana_sdk::pubkey::Pubkey =
|
||||
solana_sdk_ids::compute_budget::ID;
|
||||
/// Compute Budget program identifier. ("ComputeBudget111111111111111111111111111111").
|
||||
/// @see solana_sdk_ids::compute_budget::ID
|
||||
pub const COMPUTE_BUDGET_PROGRAM_ID: &str = "ComputeBudget111111111111111111111111111111";
|
||||
|
||||
/// DexLab Swap/Pool program id. ("DSwpgjMvXhtGn6BsbqmacdBZyfLj6jSWf3HJpdJtmg6N").
|
||||
pub const DEXLAB_PROGRAM_ID: &str = "DSwpgjMvXhtGn6BsbqmacdBZyfLj6jSWf3HJpdJtmg6N";
|
||||
|
||||
/// FluxBeam program id. ("FLUXubRmkEi2q6K3Y9kBPg9248ggaZVsoSFhtJHSrm1X").
|
||||
pub const FLUXBEAM_PROGRAM_ID: &str = "FLUXubRmkEi2q6K3Y9kBPg9248ggaZVsoSFhtJHSrm1X";
|
||||
|
||||
/// Meteora DAMM v1 program id. ("Eo7WjKq67rjJQSZxS6z3YkapzY3eMj6Xy8X5EQVn5UaB").
|
||||
pub const METEORA_DAMM_V1_PROGRAM_ID: &str = "Eo7WjKq67rjJQSZxS6z3YkapzY3eMj6Xy8X5EQVn5UaB";
|
||||
|
||||
/// Meteora DAMM v2 program id. ("cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG").
|
||||
pub const METEORA_DAMM_V2_PROGRAM_ID: &str = "cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG";
|
||||
|
||||
/// Meteora DBC program id. ("dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN").
|
||||
pub const METEORA_DBC_PROGRAM_ID: &str = "dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN";
|
||||
|
||||
/// Orca Whirlpools program id. ("whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc").
|
||||
pub const ORCA_WHIRLPOOLS_PROGRAM_ID: &str = "whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc";
|
||||
|
||||
/// Pump.fun program id. ("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P").
|
||||
pub const PUMP_FUN_PROGRAM_ID: &str = "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P";
|
||||
|
||||
/// PumpSwap / PumpAMM program id. ("pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA").
|
||||
pub const PUMP_SWAP_PROGRAM_ID: &str = "pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA";
|
||||
|
||||
/// Raydium AmmV4 program id. ("675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8").
|
||||
pub const RAYDIUM_AMM_V4_PROGRAM_ID: &str = "675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8";
|
||||
|
||||
/// Raydium CLMM program id. ("CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK").
|
||||
pub const RAYDIUM_CLMM_PROGRAM_ID: &str = "CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK";
|
||||
|
||||
/// Raydium CPMM mainnet program id. ("CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C").
|
||||
pub const RAYDIUM_CPMM_PROGRAM_ID: &str = "CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C";
|
||||
|
||||
392
kb_lib/src/db.rs
392
kb_lib/src/db.rs
@@ -13,201 +13,197 @@ mod schema;
|
||||
mod sqlite;
|
||||
mod types;
|
||||
|
||||
pub use connection::KbDatabase;
|
||||
pub use connection::KbDatabaseConnection;
|
||||
pub use dtos::KbAnalysisSignalDto;
|
||||
pub use dtos::KbChainInstructionDto;
|
||||
pub use dtos::KbChainSlotDto;
|
||||
pub use dtos::KbChainTransactionDto;
|
||||
pub use dtos::KbDbMetadataDto;
|
||||
pub use dtos::KbDbRuntimeEventDto;
|
||||
pub use dtos::KbDexDecodedEventDto;
|
||||
pub use dtos::KbDexDto;
|
||||
pub use dtos::KbKnownHttpEndpointDto;
|
||||
pub use dtos::KbKnownWsEndpointDto;
|
||||
pub use dtos::KbLaunchAttributionDto;
|
||||
pub use dtos::KbLaunchSurfaceDto;
|
||||
pub use dtos::KbLaunchSurfaceKeyDto;
|
||||
pub use dtos::KbLiquidityEventDto;
|
||||
pub use dtos::KbLocalDecodedEventDiagnosticSummaryDto;
|
||||
pub(crate) use dtos::KbLocalDecodedEventDiagnosticSummaryRow;
|
||||
pub use dtos::KbLocalDexDiagnosticSummaryDto;
|
||||
pub(crate) use dtos::KbLocalDexDiagnosticSummaryRow;
|
||||
pub use dtos::KbLocalDuplicateDecodedEventTradeDiagnosticSampleDto;
|
||||
pub(crate) use dtos::KbLocalDuplicateDecodedEventTradeDiagnosticSampleRow;
|
||||
pub use dtos::KbLocalMissingTradeEventDiagnosticSampleDto;
|
||||
pub(crate) use dtos::KbLocalMissingTradeEventDiagnosticSampleRow;
|
||||
pub use dtos::KbLocalMultiTradeSignaturePairDiagnosticSampleDto;
|
||||
pub(crate) use dtos::KbLocalMultiTradeSignaturePairDiagnosticSampleRow;
|
||||
pub use dtos::KbLocalPairDiagnosticSummaryDto;
|
||||
pub(crate) use dtos::KbLocalPairDiagnosticSummaryRow;
|
||||
pub use dtos::KbLocalPairGapDiagnosticSampleDto;
|
||||
pub(crate) use dtos::KbLocalPairGapDiagnosticSampleRow;
|
||||
pub use dtos::KbLocalPipelineDiagnosticCountersDto;
|
||||
pub(crate) use dtos::KbLocalPipelineDiagnosticCountersRow;
|
||||
pub use dtos::KbLocalPipelineDiagnosticSummaryDto;
|
||||
pub use dtos::KbObservedTokenDto;
|
||||
pub use dtos::KbOnchainObservationDto;
|
||||
pub use dtos::KbPairAnalyticSignalDto;
|
||||
pub use dtos::KbPairCandleDto;
|
||||
pub use dtos::KbPairDto;
|
||||
pub use dtos::KbPairMetricDto;
|
||||
pub use dtos::KbPoolDto;
|
||||
pub use dtos::KbPoolListingDto;
|
||||
pub use dtos::KbPoolOriginDto;
|
||||
pub use dtos::KbPoolTokenDto;
|
||||
pub use dtos::KbSwapDto;
|
||||
pub use dtos::KbTokenBurnEventDto;
|
||||
pub use dtos::KbTokenDto;
|
||||
pub use dtos::KbTokenMintEventDto;
|
||||
pub use dtos::KbTradeEventDto;
|
||||
pub use dtos::KbWalletDto;
|
||||
pub use dtos::KbWalletHoldingDto;
|
||||
pub use dtos::KbWalletParticipationDto;
|
||||
pub use entities::KbAnalysisSignalEntity;
|
||||
pub use entities::KbChainInstructionEntity;
|
||||
pub use entities::KbChainSlotEntity;
|
||||
pub use entities::KbChainTransactionEntity;
|
||||
pub use entities::KbDbMetadataEntity;
|
||||
pub use entities::KbDbRuntimeEventEntity;
|
||||
pub use entities::KbDexDecodedEventEntity;
|
||||
pub use entities::KbDexEntity;
|
||||
pub use entities::KbKnownHttpEndpointEntity;
|
||||
pub use entities::KbKnownWsEndpointEntity;
|
||||
pub use entities::KbLaunchAttributionEntity;
|
||||
pub use entities::KbLaunchSurfaceEntity;
|
||||
pub use entities::KbLaunchSurfaceKeyEntity;
|
||||
pub use entities::KbLiquidityEventEntity;
|
||||
pub use entities::KbObservedTokenEntity;
|
||||
pub use entities::KbOnchainObservationEntity;
|
||||
pub use entities::KbPairAnalyticSignalEntity;
|
||||
pub use entities::KbPairCandleEntity;
|
||||
pub use entities::KbPairEntity;
|
||||
pub use entities::KbPairMetricEntity;
|
||||
pub use entities::KbPoolEntity;
|
||||
pub use entities::KbPoolListingEntity;
|
||||
pub use entities::KbPoolOriginEntity;
|
||||
pub use entities::KbPoolTokenEntity;
|
||||
pub use entities::KbSwapEntity;
|
||||
pub use entities::KbTokenBurnEventEntity;
|
||||
pub use entities::KbTokenEntity;
|
||||
pub use entities::KbTokenMintEventEntity;
|
||||
pub use entities::KbTradeEventEntity;
|
||||
pub use entities::KbWalletEntity;
|
||||
pub use entities::KbWalletHoldingEntity;
|
||||
pub use entities::KbWalletParticipationEntity;
|
||||
pub use queries::delete_chain_instructions_by_transaction_id;
|
||||
pub use queries::get_chain_instruction_by_id;
|
||||
pub use queries::get_chain_slot;
|
||||
pub use queries::get_chain_transaction_by_signature;
|
||||
pub use queries::get_db_metadata;
|
||||
pub use queries::get_dex_by_code;
|
||||
pub use queries::get_dex_decoded_event_by_key;
|
||||
pub use queries::get_known_http_endpoint;
|
||||
pub use queries::get_known_ws_endpoint;
|
||||
pub use queries::get_latest_pump_fun_create_payload_by_mint;
|
||||
pub use queries::get_launch_attribution_by_decoded_event_id;
|
||||
pub use queries::get_launch_surface_by_code;
|
||||
pub use queries::get_launch_surface_key_by_match;
|
||||
pub use queries::get_local_pipeline_diagnostic_counters;
|
||||
pub use queries::get_observed_token_by_mint;
|
||||
pub use queries::get_pair_analytic_signal_by_key;
|
||||
pub use queries::get_pair_by_pool_id;
|
||||
pub use queries::get_pair_candle_by_key;
|
||||
pub use queries::get_pair_metric_by_pair_id;
|
||||
pub use queries::get_pool_by_address;
|
||||
pub use queries::get_pool_listing_by_pool_id;
|
||||
pub use queries::get_pool_origin_by_pool_id;
|
||||
pub use queries::get_token_by_id;
|
||||
pub use queries::get_token_by_mint;
|
||||
pub use queries::get_trade_event_by_decoded_event_id;
|
||||
pub use queries::get_wallet_by_address;
|
||||
pub use queries::get_wallet_holding_by_wallet_and_token;
|
||||
pub use queries::get_wallet_participation_by_unique_key;
|
||||
pub use queries::insert_analysis_signal;
|
||||
pub use queries::insert_chain_instruction;
|
||||
pub use queries::insert_db_runtime_event;
|
||||
pub use queries::insert_onchain_observation;
|
||||
pub use queries::list_chain_instructions_by_transaction_id;
|
||||
pub use queries::list_chain_transaction_signatures_for_replay;
|
||||
pub use queries::list_db_metadata;
|
||||
pub use queries::list_dex_decoded_events_by_transaction_id;
|
||||
pub use queries::list_dexes;
|
||||
pub use queries::list_known_http_endpoints;
|
||||
pub use queries::list_known_ws_endpoints;
|
||||
pub use queries::list_launch_attributions_by_pool_id;
|
||||
pub use queries::list_launch_surface_keys_by_surface_id;
|
||||
pub use queries::list_launch_surfaces;
|
||||
pub use queries::list_local_decoded_event_diagnostic_summaries;
|
||||
pub use queries::list_local_dex_diagnostic_summaries;
|
||||
pub use queries::list_local_duplicate_decoded_event_trade_diagnostic_samples;
|
||||
pub use queries::list_local_missing_trade_event_diagnostic_samples;
|
||||
pub use queries::list_local_multi_trade_signature_pair_diagnostic_samples;
|
||||
pub use queries::list_local_pair_diagnostic_summaries;
|
||||
pub use queries::list_local_pair_without_candle_diagnostic_samples;
|
||||
pub use queries::list_local_pair_without_trade_diagnostic_samples;
|
||||
pub use queries::list_observed_tokens;
|
||||
pub use queries::list_pair_analytic_signals_by_pair_id;
|
||||
pub use queries::list_pair_candles_by_pair_and_timeframe;
|
||||
pub use queries::list_pair_metrics;
|
||||
pub use queries::list_pairs;
|
||||
pub use queries::list_pool_listings;
|
||||
pub use queries::list_pool_origins;
|
||||
pub use queries::list_pool_tokens_by_pool_id;
|
||||
pub use queries::list_pools;
|
||||
pub use queries::list_recent_analysis_signals;
|
||||
pub use queries::list_recent_chain_slots;
|
||||
pub use queries::list_recent_chain_transactions;
|
||||
pub use queries::list_recent_db_runtime_events;
|
||||
pub use queries::list_recent_liquidity_events;
|
||||
pub use queries::list_recent_onchain_observations;
|
||||
pub use queries::list_recent_swaps;
|
||||
pub use queries::list_recent_token_burn_events;
|
||||
pub use queries::list_recent_token_mint_events;
|
||||
pub use queries::list_tokens;
|
||||
pub use queries::list_tokens_missing_metadata;
|
||||
pub use queries::list_trade_events_by_pair_id;
|
||||
pub use queries::list_trade_events_by_transaction_id;
|
||||
pub use queries::list_wallet_holdings_by_wallet_id;
|
||||
pub use queries::list_wallet_participations_by_pool_id;
|
||||
pub use queries::list_wallet_participations_by_wallet_id;
|
||||
pub use queries::list_wallets;
|
||||
pub use queries::update_pair_symbol;
|
||||
pub use queries::upsert_chain_slot;
|
||||
pub use queries::upsert_chain_transaction;
|
||||
pub use queries::upsert_db_metadata;
|
||||
pub use queries::upsert_dex;
|
||||
pub use queries::upsert_dex_decoded_event;
|
||||
pub use queries::upsert_known_http_endpoint;
|
||||
pub use queries::upsert_known_ws_endpoint;
|
||||
pub use queries::upsert_launch_attribution;
|
||||
pub use queries::upsert_launch_surface;
|
||||
pub use queries::upsert_launch_surface_key;
|
||||
pub use queries::upsert_liquidity_event;
|
||||
pub use queries::upsert_observed_token;
|
||||
pub use queries::upsert_pair;
|
||||
pub use queries::upsert_pair_analytic_signal;
|
||||
pub use queries::upsert_pair_candle;
|
||||
pub use queries::upsert_pair_metric;
|
||||
pub use queries::upsert_pool;
|
||||
pub use queries::upsert_pool_listing;
|
||||
pub use queries::upsert_pool_origin;
|
||||
pub use queries::upsert_pool_token;
|
||||
pub use queries::upsert_swap;
|
||||
pub use queries::upsert_token;
|
||||
pub use queries::upsert_token_burn_event;
|
||||
pub use queries::upsert_token_mint_event;
|
||||
pub use queries::upsert_trade_event;
|
||||
pub use queries::upsert_wallet;
|
||||
pub use queries::upsert_wallet_holding;
|
||||
pub use queries::upsert_wallet_participation;
|
||||
pub use types::KbAnalysisSignalSeverity;
|
||||
pub use types::KbDatabaseBackend;
|
||||
pub use types::KbDbRuntimeEventLevel;
|
||||
pub use types::KbLiquidityEventKind;
|
||||
pub use types::KbObservationSourceKind;
|
||||
pub use types::KbObservedTokenStatus;
|
||||
pub use types::KbPoolKind;
|
||||
pub use types::KbPoolStatus;
|
||||
pub use types::KbPoolTokenRole;
|
||||
pub use types::KbSwapTradeSide;
|
||||
pub use connection::Database;
|
||||
pub use connection::DatabaseConnection;
|
||||
pub use dtos::AnalysisSignalDto;
|
||||
pub use dtos::ChainInstructionDto;
|
||||
pub use dtos::ChainSlotDto;
|
||||
pub use dtos::ChainTransactionDto;
|
||||
pub use dtos::DbMetadataDto;
|
||||
pub use dtos::DbRuntimeEventDto;
|
||||
pub use dtos::DexDecodedEventDto;
|
||||
pub use dtos::DexDto;
|
||||
pub use dtos::KnownHttpEndpointDto;
|
||||
pub use dtos::KnownWsEndpointDto;
|
||||
pub use dtos::LaunchAttributionDto;
|
||||
pub use dtos::LaunchSurfaceDto;
|
||||
pub use dtos::LaunchSurfaceKeyDto;
|
||||
pub use dtos::LiquidityEventDto;
|
||||
pub use dtos::LocalDecodedEventDiagnosticSummaryDto;
|
||||
pub use dtos::LocalDexDiagnosticSummaryDto;
|
||||
pub use dtos::LocalDuplicateDecodedEventTradeDiagnosticSampleDto;
|
||||
pub use dtos::LocalMissingTradeEventDiagnosticSampleDto;
|
||||
pub use dtos::LocalMissingTradeEventReasonSummaryDto;
|
||||
pub use dtos::LocalMultiTradeSignaturePairDiagnosticSampleDto;
|
||||
pub use dtos::LocalNonActionablePairDiagnosticSummaryDto;
|
||||
pub use dtos::LocalPairDiagnosticSummaryDto;
|
||||
pub use dtos::LocalPairGapDiagnosticSampleDto;
|
||||
pub use dtos::LocalPipelineDiagnosticCountersDto;
|
||||
pub use dtos::LocalPipelineDiagnosticSummaryDto;
|
||||
pub use dtos::ObservedTokenDto;
|
||||
pub use dtos::OnchainObservationDto;
|
||||
pub use dtos::PairAnalyticSignalDto;
|
||||
pub use dtos::PairCandleDto;
|
||||
pub use dtos::PairDto;
|
||||
pub use dtos::PairMetricDto;
|
||||
pub use dtos::PoolDto;
|
||||
pub use dtos::PoolListingDto;
|
||||
pub use dtos::PoolOriginDto;
|
||||
pub use dtos::PoolTokenDto;
|
||||
pub use dtos::SwapDto;
|
||||
pub use dtos::TokenBurnEventDto;
|
||||
pub use dtos::TokenDto;
|
||||
pub use dtos::TokenMintEventDto;
|
||||
pub use dtos::TradeEventDto;
|
||||
pub use dtos::WalletDto;
|
||||
pub use dtos::WalletHoldingDto;
|
||||
pub use dtos::WalletParticipationDto;
|
||||
pub use entities::AnalysisSignalEntity;
|
||||
pub use entities::ChainInstructionEntity;
|
||||
pub use entities::ChainSlotEntity;
|
||||
pub use entities::ChainTransactionEntity;
|
||||
pub use entities::DbMetadataEntity;
|
||||
pub use entities::DbRuntimeEventEntity;
|
||||
pub use entities::DexDecodedEventEntity;
|
||||
pub use entities::DexEntity;
|
||||
pub use entities::KnownHttpEndpointEntity;
|
||||
pub use entities::KnownWsEndpointEntity;
|
||||
pub use entities::LaunchAttributionEntity;
|
||||
pub use entities::LaunchSurfaceEntity;
|
||||
pub use entities::LaunchSurfaceKeyEntity;
|
||||
pub use entities::LiquidityEventEntity;
|
||||
pub use entities::ObservedTokenEntity;
|
||||
pub use entities::OnchainObservationEntity;
|
||||
pub use entities::PairAnalyticSignalEntity;
|
||||
pub use entities::PairCandleEntity;
|
||||
pub use entities::PairEntity;
|
||||
pub use entities::PairMetricEntity;
|
||||
pub use entities::PoolEntity;
|
||||
pub use entities::PoolListingEntity;
|
||||
pub use entities::PoolOriginEntity;
|
||||
pub use entities::PoolTokenEntity;
|
||||
pub use entities::SwapEntity;
|
||||
pub use entities::TokenBurnEventEntity;
|
||||
pub use entities::TokenEntity;
|
||||
pub use entities::TokenMintEventEntity;
|
||||
pub use entities::TradeEventEntity;
|
||||
pub use entities::WalletEntity;
|
||||
pub use entities::WalletHoldingEntity;
|
||||
pub use entities::WalletParticipationEntity;
|
||||
pub use queries::query_analysis_signals_insert;
|
||||
pub use queries::query_analysis_signals_list;
|
||||
pub use queries::query_chain_instructions_delete_by_transaction_id;
|
||||
pub use queries::query_chain_instructions_get_by_id;
|
||||
pub use queries::query_chain_instructions_insert;
|
||||
pub use queries::query_chain_instructions_list_by_transaction_id;
|
||||
pub use queries::query_chain_slots_get;
|
||||
pub use queries::query_chain_slots_list_recent;
|
||||
pub use queries::query_chain_slots_upsert;
|
||||
pub use queries::query_chain_transactions_get_by_signature;
|
||||
pub use queries::query_chain_transactions_list_recent;
|
||||
pub use queries::query_chain_transactions_list_signatures_for_replay;
|
||||
pub use queries::query_chain_transactions_upsert;
|
||||
pub use queries::query_db_metadatas_get;
|
||||
pub use queries::query_db_metadatas_list;
|
||||
pub use queries::query_db_metadatas_upsert;
|
||||
pub use queries::query_db_runtime_events_insert;
|
||||
pub use queries::query_db_runtime_events_list_recent;
|
||||
pub use queries::query_dex_decoded_events_get_by_key;
|
||||
pub use queries::query_dex_decoded_events_get_latest_pump_fun_create_payload_by_mint;
|
||||
pub use queries::query_dex_decoded_events_list_by_transaction_id;
|
||||
pub use queries::query_dex_decoded_events_upsert;
|
||||
pub use queries::query_dexs_get_by_code;
|
||||
pub use queries::query_dexs_list;
|
||||
pub use queries::query_dexs_upsert;
|
||||
pub use queries::query_known_http_endpoints_get;
|
||||
pub use queries::query_known_http_endpoints_list;
|
||||
pub use queries::query_known_http_endpoints_upsert;
|
||||
pub use queries::query_known_ws_endpoints_get;
|
||||
pub use queries::query_known_ws_endpoints_list;
|
||||
pub use queries::query_known_ws_endpoints_upsert;
|
||||
pub use queries::query_launch_attributions_get_by_decoded_event_id;
|
||||
pub use queries::query_launch_attributions_list_by_pool_id;
|
||||
pub use queries::query_launch_attributions_upsert;
|
||||
pub use queries::query_launch_surface_keys_get_by_match;
|
||||
pub use queries::query_launch_surface_keys_list_by_surface_id;
|
||||
pub use queries::query_launch_surface_keys_upsert;
|
||||
pub use queries::query_launch_surfaces_get_by_code;
|
||||
pub use queries::query_launch_surfaces_list;
|
||||
pub use queries::query_launch_surfaces_upsert;
|
||||
pub use queries::query_liquidity_events_list_recent;
|
||||
pub use queries::query_liquidity_events_upsert;
|
||||
pub use queries::query_local_decoded_event_diagnostic_list_summaries;
|
||||
pub use queries::query_local_duplicate_decoded_event_trade_diagnostic_list_samples;
|
||||
pub use queries::query_local_missing_trade_event_diagnostic_list_samples;
|
||||
pub use queries::query_local_missing_trade_event_reason_list_summaries;
|
||||
pub use queries::query_local_multi_trade_signature_pair_diagnostic_list_samples;
|
||||
pub use queries::query_local_non_actionable_pair_diagnostic_list_summaries;
|
||||
pub use queries::query_local_pair_diagnostic_list_summaries;
|
||||
pub use queries::query_local_pair_without_candle_diagnostic_list_samples;
|
||||
pub use queries::query_local_pair_without_trade_diagnostic_list_samples;
|
||||
pub use queries::query_local_pipeline_diagnostic_get_counters;
|
||||
pub use queries::query_local_pipeline_diagnostic_list_summaries;
|
||||
pub use queries::query_observed_tokens_get_by_mint;
|
||||
pub use queries::query_observed_tokens_list;
|
||||
pub use queries::query_observed_tokens_upsert;
|
||||
pub use queries::query_onchain_observations_insert;
|
||||
pub use queries::query_onchain_observations_list_recent;
|
||||
pub use queries::query_pair_analytic_signals_get_by_key;
|
||||
pub use queries::query_pair_analytic_signals_list_by_pair_id;
|
||||
pub use queries::query_pair_analytic_signals_upsert;
|
||||
pub use queries::query_pair_candles_get_by_key;
|
||||
pub use queries::query_pair_candles_list_by_pair_and_timeframe;
|
||||
pub use queries::query_pair_candles_upsert;
|
||||
pub use queries::query_pair_metrics_get_by_pair_id;
|
||||
pub use queries::query_pair_metrics_list;
|
||||
pub use queries::query_pair_metrics_upsert;
|
||||
pub use queries::query_pairs_get_by_pool_id;
|
||||
pub use queries::query_pairs_list;
|
||||
pub use queries::query_pairs_update_symbol;
|
||||
pub use queries::query_pairs_upsert;
|
||||
pub use queries::query_pool_listings_get_by_pool_id;
|
||||
pub use queries::query_pool_listings_list;
|
||||
pub use queries::query_pool_listings_upsert;
|
||||
pub use queries::query_pool_origins_get_by_pool_id;
|
||||
pub use queries::query_pool_origins_list;
|
||||
pub use queries::query_pool_origins_upsert;
|
||||
pub use queries::query_pool_tokens_list_by_pool_id;
|
||||
pub use queries::query_pool_tokens_upsert;
|
||||
pub use queries::query_pools_get_by_address;
|
||||
pub use queries::query_pools_list;
|
||||
pub use queries::query_pools_upsert;
|
||||
pub use queries::query_swaps_list_recent;
|
||||
pub use queries::query_swaps_upsert;
|
||||
pub use queries::query_token_burn_events_list_recent;
|
||||
pub use queries::query_token_burn_events_upsert;
|
||||
pub use queries::query_token_mint_events_list_recent;
|
||||
pub use queries::query_token_mint_events_upsert;
|
||||
pub use queries::query_tokens_get_by_id;
|
||||
pub use queries::query_tokens_get_by_mint;
|
||||
pub use queries::query_tokens_list;
|
||||
pub use queries::query_tokens_list_missing_metadata;
|
||||
pub use queries::query_tokens_upsert;
|
||||
pub use queries::query_trade_events_get_by_decoded_event_id;
|
||||
pub use queries::query_trade_events_list_by_pair_id;
|
||||
pub use queries::query_trade_events_list_by_transaction_id;
|
||||
pub use queries::query_trade_events_upsert;
|
||||
pub use queries::query_wallet_holdings_get_by_wallet_and_token;
|
||||
pub use queries::query_wallet_holdings_list_by_wallet_id;
|
||||
pub use queries::query_wallet_holdings_upsert;
|
||||
pub use queries::query_wallet_participations_get_by_unique_key;
|
||||
pub use queries::query_wallet_participations_list_by_pool_id;
|
||||
pub use queries::query_wallet_participations_list_by_wallet_id;
|
||||
pub use queries::query_wallet_participations_upsert;
|
||||
pub use queries::query_wallets_get_by_address;
|
||||
pub use queries::query_wallets_list;
|
||||
pub use queries::query_wallets_upsert;
|
||||
pub use types::AnalysisSignalSeverity;
|
||||
pub use types::DatabaseBackend;
|
||||
pub use types::DbRuntimeEventLevel;
|
||||
pub use types::LiquidityEventKind;
|
||||
pub use types::ObservationSourceKind;
|
||||
pub use types::ObservedTokenStatus;
|
||||
pub use types::PoolKind;
|
||||
pub use types::PoolStatus;
|
||||
pub use types::PoolTokenRole;
|
||||
pub use types::SwapTradeSide;
|
||||
|
||||
@@ -4,29 +4,27 @@
|
||||
|
||||
/// Concrete database connection.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum KbDatabaseConnection {
|
||||
pub enum DatabaseConnection {
|
||||
/// SQLite connection pool.
|
||||
Sqlite(sqlx::SqlitePool),
|
||||
}
|
||||
|
||||
/// Database facade.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct KbDatabase {
|
||||
backend: crate::KbDatabaseBackend,
|
||||
pub struct Database {
|
||||
backend: crate::DatabaseBackend,
|
||||
database_url: std::string::String,
|
||||
connection: KbDatabaseConnection,
|
||||
connection: DatabaseConnection,
|
||||
}
|
||||
|
||||
impl KbDatabase {
|
||||
impl Database {
|
||||
/// 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::DatabaseConfig) -> Result<Self, crate::Error> {
|
||||
if !config.enabled {
|
||||
return Err(crate::KbError::Config(
|
||||
"database is disabled in configuration".to_string(),
|
||||
));
|
||||
return Err(crate::Error::Config("database is disabled in configuration".to_string()));
|
||||
}
|
||||
match config.backend {
|
||||
crate::KbDatabaseBackend::Sqlite => {
|
||||
crate::DatabaseBackend::Sqlite => {
|
||||
let database_url_result =
|
||||
crate::db::sqlite::sqlite_database_url_from_config(config);
|
||||
let database_url = match database_url_result {
|
||||
@@ -39,9 +37,9 @@ impl KbDatabase {
|
||||
Err(error) => return Err(error),
|
||||
};
|
||||
return Ok(Self {
|
||||
backend: crate::KbDatabaseBackend::Sqlite,
|
||||
backend: crate::DatabaseBackend::Sqlite,
|
||||
database_url,
|
||||
connection: KbDatabaseConnection::Sqlite(pool),
|
||||
connection: DatabaseConnection::Sqlite(pool),
|
||||
});
|
||||
},
|
||||
}
|
||||
@@ -49,8 +47,8 @@ impl KbDatabase {
|
||||
|
||||
/// Opens a database connection and initializes the schema if configured.
|
||||
pub async fn connect_and_initialize(
|
||||
config: &crate::KbDatabaseConfig,
|
||||
) -> Result<Self, crate::KbError> {
|
||||
config: &crate::DatabaseConfig,
|
||||
) -> Result<Self, crate::Error> {
|
||||
let connect_result = Self::connect(config).await;
|
||||
let database = match connect_result {
|
||||
Ok(database) => database,
|
||||
@@ -66,7 +64,7 @@ impl KbDatabase {
|
||||
}
|
||||
|
||||
/// Returns the configured backend.
|
||||
pub fn backend(&self) -> crate::KbDatabaseBackend {
|
||||
pub fn backend(&self) -> crate::DatabaseBackend {
|
||||
return self.backend;
|
||||
}
|
||||
|
||||
@@ -76,14 +74,14 @@ impl KbDatabase {
|
||||
}
|
||||
|
||||
/// Pings the database.
|
||||
pub async fn ping(&self) -> Result<(), crate::KbError> {
|
||||
pub async fn ping(&self) -> Result<(), crate::Error> {
|
||||
match &self.connection {
|
||||
KbDatabaseConnection::Sqlite(pool) => {
|
||||
DatabaseConnection::Sqlite(pool) => {
|
||||
let ping_result = sqlx::query("SELECT 1").execute(pool).await;
|
||||
match ping_result {
|
||||
Ok(_) => return Ok(()),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot ping sqlite database '{}': {}",
|
||||
self.database_url, error
|
||||
)));
|
||||
@@ -94,7 +92,7 @@ impl KbDatabase {
|
||||
}
|
||||
|
||||
/// Returns the underlying connection enum.
|
||||
pub(crate) fn connection(&self) -> &KbDatabaseConnection {
|
||||
pub(crate) fn connection(&self) -> &DatabaseConnection {
|
||||
return &self.connection;
|
||||
}
|
||||
}
|
||||
@@ -105,10 +103,10 @@ mod tests {
|
||||
async fn connect_and_ping_sqlite_database_works() {
|
||||
let tempdir = tempfile::tempdir().expect("tempdir must succeed");
|
||||
let database_path = tempdir.path().join("connection.sqlite3");
|
||||
let config = crate::KbDatabaseConfig {
|
||||
let config = crate::DatabaseConfig {
|
||||
enabled: true,
|
||||
backend: crate::KbDatabaseBackend::Sqlite,
|
||||
sqlite: crate::KbSqliteDatabaseConfig {
|
||||
backend: crate::DatabaseBackend::Sqlite,
|
||||
sqlite: crate::SqliteDatabaseConfig {
|
||||
path: database_path.to_string_lossy().to_string(),
|
||||
create_if_missing: true,
|
||||
busy_timeout_ms: 5000,
|
||||
@@ -117,13 +115,13 @@ mod tests {
|
||||
use_wal: true,
|
||||
},
|
||||
};
|
||||
let database = crate::KbDatabase::connect_and_initialize(&config)
|
||||
let database = crate::Database::connect_and_initialize(&config)
|
||||
.await
|
||||
.expect("database init must succeed");
|
||||
assert_eq!(database.backend(), crate::KbDatabaseBackend::Sqlite);
|
||||
assert_eq!(database.backend(), crate::DatabaseBackend::Sqlite);
|
||||
assert!(database.database_url().starts_with("sqlite://"));
|
||||
database.ping().await.expect("ping must succeed");
|
||||
let metadata = crate::get_db_metadata(&database, "schema_version")
|
||||
let metadata = crate::query_db_metadatas_get(&database, "schema_version")
|
||||
.await
|
||||
.expect("metadata fetch must succeed");
|
||||
assert!(metadata.is_some());
|
||||
|
||||
@@ -36,52 +36,57 @@ mod wallet;
|
||||
mod wallet_holding;
|
||||
mod wallet_participation;
|
||||
|
||||
pub use analysis_signal::KbAnalysisSignalDto;
|
||||
pub use chain_instruction::KbChainInstructionDto;
|
||||
pub use chain_slot::KbChainSlotDto;
|
||||
pub use chain_transaction::KbChainTransactionDto;
|
||||
pub use db_metadata::KbDbMetadataDto;
|
||||
pub use db_runtime_event::KbDbRuntimeEventDto;
|
||||
pub use dex::KbDexDto;
|
||||
pub use dex_decoded_event::KbDexDecodedEventDto;
|
||||
pub use known_http_endpoint::KbKnownHttpEndpointDto;
|
||||
pub use known_ws_endpoint::KbKnownWsEndpointDto;
|
||||
pub use launch_attribution::KbLaunchAttributionDto;
|
||||
pub use launch_surface::KbLaunchSurfaceDto;
|
||||
pub use launch_surface_key::KbLaunchSurfaceKeyDto;
|
||||
pub use liquidity_event::KbLiquidityEventDto;
|
||||
pub use local_pipeline_diagnostics::KbLocalDecodedEventDiagnosticSummaryDto;
|
||||
pub(crate) use local_pipeline_diagnostics::KbLocalDecodedEventDiagnosticSummaryRow;
|
||||
pub use local_pipeline_diagnostics::KbLocalDexDiagnosticSummaryDto;
|
||||
pub(crate) use local_pipeline_diagnostics::KbLocalDexDiagnosticSummaryRow;
|
||||
pub use local_pipeline_diagnostics::KbLocalDuplicateDecodedEventTradeDiagnosticSampleDto;
|
||||
pub(crate) use local_pipeline_diagnostics::KbLocalDuplicateDecodedEventTradeDiagnosticSampleRow;
|
||||
pub use local_pipeline_diagnostics::KbLocalMissingTradeEventDiagnosticSampleDto;
|
||||
pub(crate) use local_pipeline_diagnostics::KbLocalMissingTradeEventDiagnosticSampleRow;
|
||||
pub use local_pipeline_diagnostics::KbLocalMultiTradeSignaturePairDiagnosticSampleDto;
|
||||
pub(crate) use local_pipeline_diagnostics::KbLocalMultiTradeSignaturePairDiagnosticSampleRow;
|
||||
pub use local_pipeline_diagnostics::KbLocalPairDiagnosticSummaryDto;
|
||||
pub(crate) use local_pipeline_diagnostics::KbLocalPairDiagnosticSummaryRow;
|
||||
pub use local_pipeline_diagnostics::KbLocalPairGapDiagnosticSampleDto;
|
||||
pub(crate) use local_pipeline_diagnostics::KbLocalPairGapDiagnosticSampleRow;
|
||||
pub use local_pipeline_diagnostics::KbLocalPipelineDiagnosticCountersDto;
|
||||
pub(crate) use local_pipeline_diagnostics::KbLocalPipelineDiagnosticCountersRow;
|
||||
pub use local_pipeline_diagnostics::KbLocalPipelineDiagnosticSummaryDto;
|
||||
pub use observed_token::KbObservedTokenDto;
|
||||
pub use onchain_observation::KbOnchainObservationDto;
|
||||
pub use pair::KbPairDto;
|
||||
pub use pair_analytic_signal::KbPairAnalyticSignalDto;
|
||||
pub use pair_candle::KbPairCandleDto;
|
||||
pub use pair_metric::KbPairMetricDto;
|
||||
pub use pool::KbPoolDto;
|
||||
pub use pool_listing::KbPoolListingDto;
|
||||
pub use pool_origin::KbPoolOriginDto;
|
||||
pub use pool_token::KbPoolTokenDto;
|
||||
pub use swap::KbSwapDto;
|
||||
pub use token::KbTokenDto;
|
||||
pub use token_burn_event::KbTokenBurnEventDto;
|
||||
pub use token_mint_event::KbTokenMintEventDto;
|
||||
pub use trade_event::KbTradeEventDto;
|
||||
pub use wallet::KbWalletDto;
|
||||
pub use wallet_holding::KbWalletHoldingDto;
|
||||
pub use wallet_participation::KbWalletParticipationDto;
|
||||
pub(crate) use local_pipeline_diagnostics::LocalDecodedEventDiagnosticSummaryRow;
|
||||
pub(crate) use local_pipeline_diagnostics::LocalDexDiagnosticSummaryRow;
|
||||
pub(crate) use local_pipeline_diagnostics::LocalDuplicateDecodedEventTradeDiagnosticSampleRow;
|
||||
pub(crate) use local_pipeline_diagnostics::LocalMissingTradeEventDiagnosticSampleRow;
|
||||
pub(crate) use local_pipeline_diagnostics::LocalMissingTradeEventReasonSummaryRow;
|
||||
pub(crate) use local_pipeline_diagnostics::LocalMultiTradeSignaturePairDiagnosticSampleRow;
|
||||
pub(crate) use local_pipeline_diagnostics::LocalNonActionablePairDiagnosticSummaryRow;
|
||||
pub(crate) use local_pipeline_diagnostics::LocalPairDiagnosticSummaryRow;
|
||||
pub(crate) use local_pipeline_diagnostics::LocalPairGapDiagnosticSampleRow;
|
||||
pub(crate) use local_pipeline_diagnostics::LocalPipelineDiagnosticCountersRow;
|
||||
|
||||
pub use analysis_signal::AnalysisSignalDto;
|
||||
pub use chain_instruction::ChainInstructionDto;
|
||||
pub use chain_slot::ChainSlotDto;
|
||||
pub use chain_transaction::ChainTransactionDto;
|
||||
pub use db_metadata::DbMetadataDto;
|
||||
pub use db_runtime_event::DbRuntimeEventDto;
|
||||
pub use dex::DexDto;
|
||||
pub use dex_decoded_event::DexDecodedEventDto;
|
||||
pub use known_http_endpoint::KnownHttpEndpointDto;
|
||||
pub use known_ws_endpoint::KnownWsEndpointDto;
|
||||
pub use launch_attribution::LaunchAttributionDto;
|
||||
pub use launch_surface::LaunchSurfaceDto;
|
||||
pub use launch_surface_key::LaunchSurfaceKeyDto;
|
||||
pub use liquidity_event::LiquidityEventDto;
|
||||
pub use local_pipeline_diagnostics::LocalDecodedEventDiagnosticSummaryDto;
|
||||
pub use local_pipeline_diagnostics::LocalDexDiagnosticSummaryDto;
|
||||
pub use local_pipeline_diagnostics::LocalDuplicateDecodedEventTradeDiagnosticSampleDto;
|
||||
pub use local_pipeline_diagnostics::LocalMissingTradeEventDiagnosticSampleDto;
|
||||
pub use local_pipeline_diagnostics::LocalMissingTradeEventReasonSummaryDto;
|
||||
pub use local_pipeline_diagnostics::LocalMultiTradeSignaturePairDiagnosticSampleDto;
|
||||
pub use local_pipeline_diagnostics::LocalNonActionablePairDiagnosticSummaryDto;
|
||||
pub use local_pipeline_diagnostics::LocalPairDiagnosticSummaryDto;
|
||||
pub use local_pipeline_diagnostics::LocalPairGapDiagnosticSampleDto;
|
||||
pub use local_pipeline_diagnostics::LocalPipelineDiagnosticCountersDto;
|
||||
pub use local_pipeline_diagnostics::LocalPipelineDiagnosticSummaryDto;
|
||||
pub use observed_token::ObservedTokenDto;
|
||||
pub use onchain_observation::OnchainObservationDto;
|
||||
pub use pair::PairDto;
|
||||
pub use pair_analytic_signal::PairAnalyticSignalDto;
|
||||
pub use pair_candle::PairCandleDto;
|
||||
pub use pair_metric::PairMetricDto;
|
||||
pub use pool::PoolDto;
|
||||
pub use pool_listing::PoolListingDto;
|
||||
pub use pool_origin::PoolOriginDto;
|
||||
pub use pool_token::PoolTokenDto;
|
||||
pub use swap::SwapDto;
|
||||
pub use token::TokenDto;
|
||||
pub use token_burn_event::TokenBurnEventDto;
|
||||
pub use token_mint_event::TokenMintEventDto;
|
||||
pub use trade_event::TradeEventDto;
|
||||
pub use wallet::WalletDto;
|
||||
pub use wallet_holding::WalletHoldingDto;
|
||||
pub use wallet_participation::WalletParticipationDto;
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
|
||||
/// Application-facing analysis signal DTO.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbAnalysisSignalDto {
|
||||
pub struct AnalysisSignalDto {
|
||||
/// Optional numeric primary key.
|
||||
pub id: std::option::Option<i64>,
|
||||
/// Signal kind.
|
||||
pub signal_kind: std::string::String,
|
||||
/// Signal severity.
|
||||
pub severity: crate::KbAnalysisSignalSeverity,
|
||||
pub severity: crate::AnalysisSignalSeverity,
|
||||
/// Logical object key, for example a mint, signature or pool address.
|
||||
pub object_key: std::string::String,
|
||||
/// Optional related on-chain observation id.
|
||||
@@ -23,11 +23,11 @@ pub struct KbAnalysisSignalDto {
|
||||
pub created_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl KbAnalysisSignalDto {
|
||||
impl AnalysisSignalDto {
|
||||
/// Creates a new analysis signal DTO with the current timestamp.
|
||||
pub fn new(
|
||||
signal_kind: std::string::String,
|
||||
severity: crate::KbAnalysisSignalSeverity,
|
||||
severity: crate::AnalysisSignalSeverity,
|
||||
object_key: std::string::String,
|
||||
related_observation_id: std::option::Option<i64>,
|
||||
score: std::option::Option<f64>,
|
||||
@@ -46,11 +46,11 @@ impl KbAnalysisSignalDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::KbAnalysisSignalEntity> for KbAnalysisSignalDto {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<crate::AnalysisSignalEntity> for AnalysisSignalDto {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(entity: crate::KbAnalysisSignalEntity) -> Result<Self, Self::Error> {
|
||||
let severity_result = crate::KbAnalysisSignalSeverity::from_i16(entity.severity);
|
||||
fn try_from(entity: crate::AnalysisSignalEntity) -> Result<Self, Self::Error> {
|
||||
let severity_result = crate::AnalysisSignalSeverity::from_i16(entity.severity);
|
||||
let severity = match severity_result {
|
||||
Ok(severity) => severity,
|
||||
Err(error) => return Err(error),
|
||||
@@ -59,7 +59,7 @@ impl TryFrom<crate::KbAnalysisSignalEntity> for KbAnalysisSignalDto {
|
||||
let created_at = match created_at_result {
|
||||
Ok(created_at) => created_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse analysis signal created_at '{}': {}",
|
||||
entity.created_at, error
|
||||
)));
|
||||
@@ -69,7 +69,7 @@ impl TryFrom<crate::KbAnalysisSignalEntity> for KbAnalysisSignalDto {
|
||||
let payload = match payload_result {
|
||||
Ok(payload) => payload,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse analysis signal payload_json '{}': {}",
|
||||
entity.payload_json, error
|
||||
)));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Application-facing normalized chain instruction DTO.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbChainInstructionDto {
|
||||
pub struct ChainInstructionDto {
|
||||
/// Optional numeric primary key.
|
||||
pub id: std::option::Option<i64>,
|
||||
/// Parent transaction id.
|
||||
@@ -33,7 +33,7 @@ pub struct KbChainInstructionDto {
|
||||
pub created_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl KbChainInstructionDto {
|
||||
impl ChainInstructionDto {
|
||||
/// Creates a new chain instruction DTO.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
@@ -67,15 +67,15 @@ impl KbChainInstructionDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::KbChainInstructionEntity> for KbChainInstructionDto {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<crate::ChainInstructionEntity> for ChainInstructionDto {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(entity: crate::KbChainInstructionEntity) -> Result<Self, Self::Error> {
|
||||
fn try_from(entity: crate::ChainInstructionEntity) -> Result<Self, Self::Error> {
|
||||
let instruction_index_result = u32::try_from(entity.instruction_index);
|
||||
let instruction_index = match instruction_index_result {
|
||||
Ok(instruction_index) => instruction_index,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot convert chain instruction instruction_index '{}' to u32: {}",
|
||||
entity.instruction_index, error
|
||||
)));
|
||||
@@ -87,7 +87,7 @@ impl TryFrom<crate::KbChainInstructionEntity> for KbChainInstructionDto {
|
||||
match inner_instruction_index_result {
|
||||
Ok(inner_instruction_index) => Some(inner_instruction_index),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot convert chain instruction inner_instruction_index '{}' to u32: {}",
|
||||
inner_instruction_index, error
|
||||
)));
|
||||
@@ -102,7 +102,7 @@ impl TryFrom<crate::KbChainInstructionEntity> for KbChainInstructionDto {
|
||||
match stack_height_result {
|
||||
Ok(stack_height) => Some(stack_height),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot convert chain instruction stack_height '{}' to u32: {}",
|
||||
stack_height, error
|
||||
)));
|
||||
@@ -115,7 +115,7 @@ impl TryFrom<crate::KbChainInstructionEntity> for KbChainInstructionDto {
|
||||
let created_at = match created_at_result {
|
||||
Ok(created_at) => created_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse chain instruction created_at '{}': {}",
|
||||
entity.created_at, error
|
||||
)));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Application-facing normalized chain slot DTO.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbChainSlotDto {
|
||||
pub struct ChainSlotDto {
|
||||
/// Slot number.
|
||||
pub slot: u64,
|
||||
/// Optional parent slot number.
|
||||
@@ -17,7 +17,7 @@ pub struct KbChainSlotDto {
|
||||
pub updated_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl KbChainSlotDto {
|
||||
impl ChainSlotDto {
|
||||
/// Creates a new chain slot DTO.
|
||||
pub fn new(
|
||||
slot: u64,
|
||||
@@ -35,15 +35,15 @@ impl KbChainSlotDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::KbChainSlotEntity> for KbChainSlotDto {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<crate::ChainSlotEntity> for ChainSlotDto {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(entity: crate::KbChainSlotEntity) -> Result<Self, Self::Error> {
|
||||
fn try_from(entity: crate::ChainSlotEntity) -> Result<Self, Self::Error> {
|
||||
let slot_result = u64::try_from(entity.slot);
|
||||
let slot = match slot_result {
|
||||
Ok(slot) => slot,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot convert chain slot '{}' to u64: {}",
|
||||
entity.slot, error
|
||||
)));
|
||||
@@ -55,7 +55,7 @@ impl TryFrom<crate::KbChainSlotEntity> for KbChainSlotDto {
|
||||
match parent_slot_result {
|
||||
Ok(parent_slot) => Some(parent_slot),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot convert chain parent_slot '{}' to u64: {}",
|
||||
parent_slot, error
|
||||
)));
|
||||
@@ -68,7 +68,7 @@ impl TryFrom<crate::KbChainSlotEntity> for KbChainSlotDto {
|
||||
let created_at = match created_at_result {
|
||||
Ok(created_at) => created_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse chain slot created_at '{}': {}",
|
||||
entity.created_at, error
|
||||
)));
|
||||
@@ -78,7 +78,7 @@ impl TryFrom<crate::KbChainSlotEntity> for KbChainSlotDto {
|
||||
let updated_at = match updated_at_result {
|
||||
Ok(updated_at) => updated_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse chain slot updated_at '{}': {}",
|
||||
entity.updated_at, error
|
||||
)));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Application-facing normalized chain transaction DTO.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbChainTransactionDto {
|
||||
pub struct ChainTransactionDto {
|
||||
/// Optional numeric primary key.
|
||||
pub id: std::option::Option<i64>,
|
||||
/// Transaction signature.
|
||||
@@ -29,7 +29,7 @@ pub struct KbChainTransactionDto {
|
||||
pub updated_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl KbChainTransactionDto {
|
||||
impl ChainTransactionDto {
|
||||
/// Creates a new chain transaction DTO.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
@@ -59,17 +59,17 @@ impl KbChainTransactionDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::KbChainTransactionEntity> for KbChainTransactionDto {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<crate::ChainTransactionEntity> for ChainTransactionDto {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(entity: crate::KbChainTransactionEntity) -> Result<Self, Self::Error> {
|
||||
fn try_from(entity: crate::ChainTransactionEntity) -> Result<Self, Self::Error> {
|
||||
let slot = match entity.slot {
|
||||
Some(slot) => {
|
||||
let slot_result = u64::try_from(slot);
|
||||
match slot_result {
|
||||
Ok(slot) => Some(slot),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot convert chain transaction slot '{}' to u64: {}",
|
||||
slot, error
|
||||
)));
|
||||
@@ -82,7 +82,7 @@ impl TryFrom<crate::KbChainTransactionEntity> for KbChainTransactionDto {
|
||||
let created_at = match created_at_result {
|
||||
Ok(created_at) => created_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse chain transaction created_at '{}': {}",
|
||||
entity.created_at, error
|
||||
)));
|
||||
@@ -92,7 +92,7 @@ impl TryFrom<crate::KbChainTransactionEntity> for KbChainTransactionDto {
|
||||
let updated_at = match updated_at_result {
|
||||
Ok(updated_at) => updated_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse chain transaction updated_at '{}': {}",
|
||||
entity.updated_at, error
|
||||
)));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Metadata DTO used by the application layer.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbDbMetadataDto {
|
||||
pub struct DbMetadataDto {
|
||||
/// Metadata key.
|
||||
pub key: std::string::String,
|
||||
/// Metadata value.
|
||||
@@ -13,7 +13,7 @@ pub struct KbDbMetadataDto {
|
||||
pub updated_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl KbDbMetadataDto {
|
||||
impl DbMetadataDto {
|
||||
/// Creates a new metadata DTO with the current UTC timestamp.
|
||||
pub fn new(key: std::string::String, value: std::string::String) -> Self {
|
||||
return Self {
|
||||
@@ -24,15 +24,15 @@ impl KbDbMetadataDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::KbDbMetadataEntity> for KbDbMetadataDto {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<crate::DbMetadataEntity> for DbMetadataDto {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(entity: crate::KbDbMetadataEntity) -> Result<Self, Self::Error> {
|
||||
fn try_from(entity: crate::DbMetadataEntity) -> Result<Self, Self::Error> {
|
||||
let parsed_result = chrono::DateTime::parse_from_rfc3339(&entity.updated_at);
|
||||
let parsed = match parsed_result {
|
||||
Ok(parsed) => parsed,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse db metadata timestamp '{}': {}",
|
||||
entity.updated_at, error
|
||||
)));
|
||||
@@ -46,8 +46,8 @@ impl TryFrom<crate::KbDbMetadataEntity> for KbDbMetadataDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<KbDbMetadataDto> for crate::KbDbMetadataEntity {
|
||||
fn from(dto: KbDbMetadataDto) -> Self {
|
||||
impl From<DbMetadataDto> for crate::DbMetadataEntity {
|
||||
fn from(dto: DbMetadataDto) -> Self {
|
||||
return Self {
|
||||
key: dto.key,
|
||||
value: dto.value,
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
|
||||
/// Application-facing runtime event DTO.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbDbRuntimeEventDto {
|
||||
pub struct DbRuntimeEventDto {
|
||||
/// Optional numeric primary key.
|
||||
pub id: std::option::Option<i64>,
|
||||
/// Event kind.
|
||||
pub event_kind: std::string::String,
|
||||
/// Severity level.
|
||||
pub level: crate::KbDbRuntimeEventLevel,
|
||||
pub level: crate::DbRuntimeEventLevel,
|
||||
/// Event source.
|
||||
pub source: std::string::String,
|
||||
/// Human-readable message.
|
||||
@@ -19,11 +19,11 @@ pub struct KbDbRuntimeEventDto {
|
||||
pub created_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl KbDbRuntimeEventDto {
|
||||
impl DbRuntimeEventDto {
|
||||
/// Creates a new runtime event DTO with the current creation timestamp.
|
||||
pub fn new(
|
||||
event_kind: std::string::String,
|
||||
level: crate::KbDbRuntimeEventLevel,
|
||||
level: crate::DbRuntimeEventLevel,
|
||||
source: std::string::String,
|
||||
message: std::string::String,
|
||||
) -> Self {
|
||||
@@ -38,21 +38,21 @@ impl KbDbRuntimeEventDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::KbDbRuntimeEventEntity> for KbDbRuntimeEventDto {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<crate::DbRuntimeEventEntity> for DbRuntimeEventDto {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(entity: crate::KbDbRuntimeEventEntity) -> Result<Self, Self::Error> {
|
||||
fn try_from(entity: crate::DbRuntimeEventEntity) -> Result<Self, Self::Error> {
|
||||
let created_at_result = chrono::DateTime::parse_from_rfc3339(&entity.created_at);
|
||||
let created_at = match created_at_result {
|
||||
Ok(created_at) => created_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse runtime event created_at '{}': {}",
|
||||
entity.created_at, error
|
||||
)));
|
||||
},
|
||||
};
|
||||
let level_result = crate::KbDbRuntimeEventLevel::from_i16(entity.level);
|
||||
let level_result = crate::DbRuntimeEventLevel::from_i16(entity.level);
|
||||
let level = match level_result {
|
||||
Ok(level) => level,
|
||||
Err(error) => return Err(error),
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Application-facing normalized DEX DTO.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbDexDto {
|
||||
pub struct DexDto {
|
||||
/// Optional numeric primary key.
|
||||
pub id: std::option::Option<i64>,
|
||||
/// Stable short code.
|
||||
@@ -23,7 +23,7 @@ pub struct KbDexDto {
|
||||
pub updated_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl KbDexDto {
|
||||
impl DexDto {
|
||||
/// Creates a new DEX DTO.
|
||||
pub fn new(
|
||||
code: std::string::String,
|
||||
@@ -46,15 +46,15 @@ impl KbDexDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::KbDexEntity> for KbDexDto {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<crate::DexEntity> for DexDto {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(entity: crate::KbDexEntity) -> Result<Self, Self::Error> {
|
||||
fn try_from(entity: crate::DexEntity) -> Result<Self, Self::Error> {
|
||||
let created_at_result = chrono::DateTime::parse_from_rfc3339(&entity.created_at);
|
||||
let created_at = match created_at_result {
|
||||
Ok(created_at) => created_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse dex created_at '{}': {}",
|
||||
entity.created_at, error
|
||||
)));
|
||||
@@ -64,7 +64,7 @@ impl TryFrom<crate::KbDexEntity> for KbDexDto {
|
||||
let updated_at = match updated_at_result {
|
||||
Ok(updated_at) => updated_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse dex updated_at '{}': {}",
|
||||
entity.updated_at, error
|
||||
)));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Application-facing decoded DEX event DTO.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbDexDecodedEventDto {
|
||||
pub struct DexDecodedEventDto {
|
||||
/// Optional numeric primary key.
|
||||
pub id: std::option::Option<i64>,
|
||||
/// Parent transaction id.
|
||||
@@ -33,7 +33,7 @@ pub struct KbDexDecodedEventDto {
|
||||
pub created_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl KbDexDecodedEventDto {
|
||||
impl DexDecodedEventDto {
|
||||
/// Creates a new decoded DEX event DTO.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
@@ -67,15 +67,15 @@ impl KbDexDecodedEventDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::KbDexDecodedEventEntity> for KbDexDecodedEventDto {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<crate::DexDecodedEventEntity> for DexDecodedEventDto {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(entity: crate::KbDexDecodedEventEntity) -> Result<Self, Self::Error> {
|
||||
fn try_from(entity: crate::DexDecodedEventEntity) -> Result<Self, Self::Error> {
|
||||
let created_at_result = chrono::DateTime::parse_from_rfc3339(&entity.created_at);
|
||||
let created_at = match created_at_result {
|
||||
Ok(created_at) => created_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse dex decoded event created_at '{}': {}",
|
||||
entity.created_at, error
|
||||
)));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Application-facing known HTTP endpoint DTO.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbKnownHttpEndpointDto {
|
||||
pub struct KnownHttpEndpointDto {
|
||||
/// Logical endpoint name.
|
||||
pub name: std::string::String,
|
||||
/// Provider name.
|
||||
@@ -21,7 +21,7 @@ pub struct KbKnownHttpEndpointDto {
|
||||
pub updated_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl KbKnownHttpEndpointDto {
|
||||
impl KnownHttpEndpointDto {
|
||||
/// Creates a new DTO with the current update timestamp.
|
||||
pub fn new(
|
||||
name: std::string::String,
|
||||
@@ -42,16 +42,16 @@ impl KbKnownHttpEndpointDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::KbKnownHttpEndpointEntity> for KbKnownHttpEndpointDto {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<crate::KnownHttpEndpointEntity> for KnownHttpEndpointDto {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(entity: crate::KbKnownHttpEndpointEntity) -> Result<Self, Self::Error> {
|
||||
fn try_from(entity: crate::KnownHttpEndpointEntity) -> Result<Self, Self::Error> {
|
||||
let roles_result =
|
||||
serde_json::from_str::<std::vec::Vec<std::string::String>>(&entity.roles_json);
|
||||
let roles = match roles_result {
|
||||
Ok(roles) => roles,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse known http endpoint roles_json '{}': {}",
|
||||
entity.roles_json, error
|
||||
)));
|
||||
@@ -61,7 +61,7 @@ impl TryFrom<crate::KbKnownHttpEndpointEntity> for KbKnownHttpEndpointDto {
|
||||
let updated_at = match updated_at_result {
|
||||
Ok(updated_at) => updated_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse known http endpoint updated_at '{}': {}",
|
||||
entity.updated_at, error
|
||||
)));
|
||||
@@ -73,7 +73,7 @@ impl TryFrom<crate::KbKnownHttpEndpointEntity> for KbKnownHttpEndpointDto {
|
||||
match parsed_result {
|
||||
Ok(parsed) => Some(parsed.with_timezone(&chrono::Utc)),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse known http endpoint last_seen_at '{}': {}",
|
||||
last_seen_at_text, error
|
||||
)));
|
||||
@@ -94,15 +94,15 @@ impl TryFrom<crate::KbKnownHttpEndpointEntity> for KbKnownHttpEndpointDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<KbKnownHttpEndpointDto> for crate::KbKnownHttpEndpointEntity {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<KnownHttpEndpointDto> for crate::KnownHttpEndpointEntity {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(dto: KbKnownHttpEndpointDto) -> Result<Self, Self::Error> {
|
||||
fn try_from(dto: KnownHttpEndpointDto) -> Result<Self, Self::Error> {
|
||||
let roles_json_result = serde_json::to_string(&dto.roles);
|
||||
let roles_json = match roles_json_result {
|
||||
Ok(roles_json) => roles_json,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot serialize known http endpoint roles: {}",
|
||||
error
|
||||
)));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Application-facing known WebSocket endpoint DTO.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbKnownWsEndpointDto {
|
||||
pub struct KnownWsEndpointDto {
|
||||
/// Logical endpoint name.
|
||||
pub name: std::string::String,
|
||||
/// Provider name.
|
||||
@@ -21,7 +21,7 @@ pub struct KbKnownWsEndpointDto {
|
||||
pub updated_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl KbKnownWsEndpointDto {
|
||||
impl KnownWsEndpointDto {
|
||||
/// Creates a new DTO with the current update timestamp.
|
||||
pub fn new(
|
||||
name: std::string::String,
|
||||
@@ -42,16 +42,16 @@ impl KbKnownWsEndpointDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::KbKnownWsEndpointEntity> for KbKnownWsEndpointDto {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<crate::KnownWsEndpointEntity> for KnownWsEndpointDto {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(entity: crate::KbKnownWsEndpointEntity) -> Result<Self, Self::Error> {
|
||||
fn try_from(entity: crate::KnownWsEndpointEntity) -> Result<Self, Self::Error> {
|
||||
let roles_result =
|
||||
serde_json::from_str::<std::vec::Vec<std::string::String>>(&entity.roles_json);
|
||||
let roles = match roles_result {
|
||||
Ok(roles) => roles,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse known ws endpoint roles_json '{}': {}",
|
||||
entity.roles_json, error
|
||||
)));
|
||||
@@ -61,7 +61,7 @@ impl TryFrom<crate::KbKnownWsEndpointEntity> for KbKnownWsEndpointDto {
|
||||
let updated_at = match updated_at_result {
|
||||
Ok(updated_at) => updated_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse known ws endpoint updated_at '{}': {}",
|
||||
entity.updated_at, error
|
||||
)));
|
||||
@@ -73,7 +73,7 @@ impl TryFrom<crate::KbKnownWsEndpointEntity> for KbKnownWsEndpointDto {
|
||||
match parsed_result {
|
||||
Ok(parsed) => Some(parsed.with_timezone(&chrono::Utc)),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse known ws endpoint last_seen_at '{}': {}",
|
||||
last_seen_at_text, error
|
||||
)));
|
||||
@@ -94,15 +94,15 @@ impl TryFrom<crate::KbKnownWsEndpointEntity> for KbKnownWsEndpointDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<KbKnownWsEndpointDto> for crate::KbKnownWsEndpointEntity {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<KnownWsEndpointDto> for crate::KnownWsEndpointEntity {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(dto: KbKnownWsEndpointDto) -> Result<Self, Self::Error> {
|
||||
fn try_from(dto: KnownWsEndpointDto) -> Result<Self, Self::Error> {
|
||||
let roles_json_result = serde_json::to_string(&dto.roles);
|
||||
let roles_json = match roles_json_result {
|
||||
Ok(roles_json) => roles_json,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot serialize known ws endpoint roles: {}",
|
||||
error
|
||||
)));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Application-facing launch attribution DTO.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbLaunchAttributionDto {
|
||||
pub struct LaunchAttributionDto {
|
||||
/// Optional numeric primary key.
|
||||
pub id: std::option::Option<i64>,
|
||||
/// Related launch surface id.
|
||||
@@ -31,7 +31,7 @@ pub struct KbLaunchAttributionDto {
|
||||
pub updated_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl KbLaunchAttributionDto {
|
||||
impl LaunchAttributionDto {
|
||||
/// Creates a new launch attribution DTO.
|
||||
pub fn new(
|
||||
launch_surface_id: i64,
|
||||
@@ -62,15 +62,15 @@ impl KbLaunchAttributionDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::KbLaunchAttributionEntity> for KbLaunchAttributionDto {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<crate::LaunchAttributionEntity> for LaunchAttributionDto {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(entity: crate::KbLaunchAttributionEntity) -> Result<Self, Self::Error> {
|
||||
fn try_from(entity: crate::LaunchAttributionEntity) -> Result<Self, Self::Error> {
|
||||
let attributed_at_result = chrono::DateTime::parse_from_rfc3339(&entity.attributed_at);
|
||||
let attributed_at = match attributed_at_result {
|
||||
Ok(attributed_at) => attributed_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse launch_attribution attributed_at '{}': {}",
|
||||
entity.attributed_at, error
|
||||
)));
|
||||
@@ -80,7 +80,7 @@ impl TryFrom<crate::KbLaunchAttributionEntity> for KbLaunchAttributionDto {
|
||||
let updated_at = match updated_at_result {
|
||||
Ok(updated_at) => updated_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse launch_attribution updated_at '{}': {}",
|
||||
entity.updated_at, error
|
||||
)));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Application-facing launch surface DTO.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbLaunchSurfaceDto {
|
||||
pub struct LaunchSurfaceDto {
|
||||
/// Optional numeric primary key.
|
||||
pub id: std::option::Option<i64>,
|
||||
/// Stable short code.
|
||||
@@ -21,7 +21,7 @@ pub struct KbLaunchSurfaceDto {
|
||||
pub updated_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl KbLaunchSurfaceDto {
|
||||
impl LaunchSurfaceDto {
|
||||
/// Creates a new launch surface DTO.
|
||||
pub fn new(
|
||||
code: std::string::String,
|
||||
@@ -42,15 +42,15 @@ impl KbLaunchSurfaceDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::KbLaunchSurfaceEntity> for KbLaunchSurfaceDto {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<crate::LaunchSurfaceEntity> for LaunchSurfaceDto {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(entity: crate::KbLaunchSurfaceEntity) -> Result<Self, Self::Error> {
|
||||
fn try_from(entity: crate::LaunchSurfaceEntity) -> Result<Self, Self::Error> {
|
||||
let created_at_result = chrono::DateTime::parse_from_rfc3339(&entity.created_at);
|
||||
let created_at = match created_at_result {
|
||||
Ok(created_at) => created_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse launch_surface created_at '{}': {}",
|
||||
entity.created_at, error
|
||||
)));
|
||||
@@ -60,7 +60,7 @@ impl TryFrom<crate::KbLaunchSurfaceEntity> for KbLaunchSurfaceDto {
|
||||
let updated_at = match updated_at_result {
|
||||
Ok(updated_at) => updated_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse launch_surface updated_at '{}': {}",
|
||||
entity.updated_at, error
|
||||
)));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Application-facing launch surface key DTO.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbLaunchSurfaceKeyDto {
|
||||
pub struct LaunchSurfaceKeyDto {
|
||||
/// Optional numeric primary key.
|
||||
pub id: std::option::Option<i64>,
|
||||
/// Related launch surface id.
|
||||
@@ -19,7 +19,7 @@ pub struct KbLaunchSurfaceKeyDto {
|
||||
pub updated_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl KbLaunchSurfaceKeyDto {
|
||||
impl LaunchSurfaceKeyDto {
|
||||
/// Creates a new launch surface key DTO.
|
||||
pub fn new(
|
||||
launch_surface_id: i64,
|
||||
@@ -38,15 +38,15 @@ impl KbLaunchSurfaceKeyDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::KbLaunchSurfaceKeyEntity> for KbLaunchSurfaceKeyDto {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<crate::LaunchSurfaceKeyEntity> for LaunchSurfaceKeyDto {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(entity: crate::KbLaunchSurfaceKeyEntity) -> Result<Self, Self::Error> {
|
||||
fn try_from(entity: crate::LaunchSurfaceKeyEntity) -> Result<Self, Self::Error> {
|
||||
let created_at_result = chrono::DateTime::parse_from_rfc3339(&entity.created_at);
|
||||
let created_at = match created_at_result {
|
||||
Ok(created_at) => created_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse launch_surface_key created_at '{}': {}",
|
||||
entity.created_at, error
|
||||
)));
|
||||
@@ -56,7 +56,7 @@ impl TryFrom<crate::KbLaunchSurfaceKeyEntity> for KbLaunchSurfaceKeyDto {
|
||||
let updated_at = match updated_at_result {
|
||||
Ok(updated_at) => updated_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse launch_surface_key updated_at '{}': {}",
|
||||
entity.updated_at, error
|
||||
)));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Application-facing normalized liquidity event DTO.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbLiquidityEventDto {
|
||||
pub struct LiquidityEventDto {
|
||||
/// Optional numeric primary key.
|
||||
pub id: std::option::Option<i64>,
|
||||
/// Related DEX id.
|
||||
@@ -20,7 +20,7 @@ pub struct KbLiquidityEventDto {
|
||||
/// Optional slot number.
|
||||
pub slot: std::option::Option<u64>,
|
||||
/// Liquidity event kind.
|
||||
pub event_kind: crate::KbLiquidityEventKind,
|
||||
pub event_kind: crate::LiquidityEventKind,
|
||||
/// Optional actor wallet.
|
||||
pub actor_wallet: std::option::Option<std::string::String>,
|
||||
/// Base token id.
|
||||
@@ -39,7 +39,7 @@ pub struct KbLiquidityEventDto {
|
||||
pub executed_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl KbLiquidityEventDto {
|
||||
impl LiquidityEventDto {
|
||||
/// Creates a new liquidity event DTO.
|
||||
pub fn new(
|
||||
dex_id: i64,
|
||||
@@ -48,7 +48,7 @@ impl KbLiquidityEventDto {
|
||||
signature: std::string::String,
|
||||
instruction_index: i64,
|
||||
slot: std::option::Option<u64>,
|
||||
event_kind: crate::KbLiquidityEventKind,
|
||||
event_kind: crate::LiquidityEventKind,
|
||||
actor_wallet: std::option::Option<std::string::String>,
|
||||
base_token_id: i64,
|
||||
quote_token_id: i64,
|
||||
@@ -78,11 +78,11 @@ impl KbLiquidityEventDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::KbLiquidityEventEntity> for KbLiquidityEventDto {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<crate::LiquidityEventEntity> for LiquidityEventDto {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(entity: crate::KbLiquidityEventEntity) -> Result<Self, Self::Error> {
|
||||
let event_kind_result = crate::KbLiquidityEventKind::from_i16(entity.event_kind);
|
||||
fn try_from(entity: crate::LiquidityEventEntity) -> Result<Self, Self::Error> {
|
||||
let event_kind_result = crate::LiquidityEventKind::from_i16(entity.event_kind);
|
||||
let event_kind = match event_kind_result {
|
||||
Ok(event_kind) => event_kind,
|
||||
Err(error) => return Err(error),
|
||||
@@ -91,7 +91,7 @@ impl TryFrom<crate::KbLiquidityEventEntity> for KbLiquidityEventDto {
|
||||
let executed_at = match executed_at_result {
|
||||
Ok(executed_at) => executed_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse liquidity event executed_at '{}': {}",
|
||||
entity.executed_at, error
|
||||
)));
|
||||
@@ -103,7 +103,7 @@ impl TryFrom<crate::KbLiquidityEventEntity> for KbLiquidityEventDto {
|
||||
match slot_result {
|
||||
Ok(slot) => Some(slot),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot convert liquidity event slot '{}' to u64: {}",
|
||||
slot, error
|
||||
)));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Local pipeline diagnostics summary.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbLocalPipelineDiagnosticSummaryDto {
|
||||
pub struct LocalPipelineDiagnosticSummaryDto {
|
||||
/// Total persisted chain transactions.
|
||||
pub transaction_count: i64,
|
||||
/// Total successful chain transactions.
|
||||
@@ -64,29 +64,37 @@ pub struct KbLocalPipelineDiagnosticSummaryDto {
|
||||
/// Total pairs without candle.
|
||||
pub pair_without_candle_count: i64,
|
||||
/// Diagnostics grouped by DEX.
|
||||
pub dex_summaries: std::vec::Vec<crate::KbLocalDexDiagnosticSummaryDto>,
|
||||
pub dex_summaries: std::vec::Vec<crate::LocalDexDiagnosticSummaryDto>,
|
||||
/// Diagnostics grouped by pair.
|
||||
pub pair_summaries: std::vec::Vec<crate::KbLocalPairDiagnosticSummaryDto>,
|
||||
pub pair_summaries: std::vec::Vec<crate::LocalPairDiagnosticSummaryDto>,
|
||||
/// Diagnostics grouped by decoded event kind.
|
||||
pub decoded_event_summaries: std::vec::Vec<crate::KbLocalDecodedEventDiagnosticSummaryDto>,
|
||||
pub decoded_event_summaries: std::vec::Vec<crate::LocalDecodedEventDiagnosticSummaryDto>,
|
||||
/// Missing trade events grouped by diagnostic reason.
|
||||
pub missing_trade_event_reason_summaries:
|
||||
std::vec::Vec<crate::LocalMissingTradeEventReasonSummaryDto>,
|
||||
/// Total pairs with only non-actionable missing trade events.
|
||||
pub non_actionable_pair_count: i64,
|
||||
/// Pair summaries for non-actionable missing trade events.
|
||||
pub non_actionable_pair_summaries:
|
||||
std::vec::Vec<crate::LocalNonActionablePairDiagnosticSummaryDto>,
|
||||
/// Samples of decoded trade candidates without linked trade event.
|
||||
pub missing_trade_event_samples:
|
||||
std::vec::Vec<crate::KbLocalMissingTradeEventDiagnosticSampleDto>,
|
||||
std::vec::Vec<crate::LocalMissingTradeEventDiagnosticSampleDto>,
|
||||
/// Samples of duplicated trade rows by decoded event id.
|
||||
pub duplicate_decoded_event_trade_samples:
|
||||
std::vec::Vec<crate::KbLocalDuplicateDecodedEventTradeDiagnosticSampleDto>,
|
||||
std::vec::Vec<crate::LocalDuplicateDecodedEventTradeDiagnosticSampleDto>,
|
||||
/// Samples of multi-trade signature/pair groups.
|
||||
pub multi_trade_signature_pair_samples:
|
||||
std::vec::Vec<crate::KbLocalMultiTradeSignaturePairDiagnosticSampleDto>,
|
||||
std::vec::Vec<crate::LocalMultiTradeSignaturePairDiagnosticSampleDto>,
|
||||
/// Samples of pairs without trade.
|
||||
pub pair_without_trade_samples: std::vec::Vec<crate::KbLocalPairGapDiagnosticSampleDto>,
|
||||
pub pair_without_trade_samples: std::vec::Vec<crate::LocalPairGapDiagnosticSampleDto>,
|
||||
/// Samples of pairs without candle.
|
||||
pub pair_without_candle_samples: std::vec::Vec<crate::KbLocalPairGapDiagnosticSampleDto>,
|
||||
pub pair_without_candle_samples: std::vec::Vec<crate::LocalPairGapDiagnosticSampleDto>,
|
||||
}
|
||||
|
||||
/// Local DEX diagnostics summary.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbLocalDexDiagnosticSummaryDto {
|
||||
pub struct LocalDexDiagnosticSummaryDto {
|
||||
/// DEX code or protocol name.
|
||||
pub dex_code: std::string::String,
|
||||
/// Total known pools for this DEX.
|
||||
@@ -107,7 +115,7 @@ pub struct KbLocalDexDiagnosticSummaryDto {
|
||||
|
||||
/// Local pair diagnostics summary.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbLocalPairDiagnosticSummaryDto {
|
||||
pub struct LocalPairDiagnosticSummaryDto {
|
||||
/// Pair id.
|
||||
pub pair_id: i64,
|
||||
/// Pool address.
|
||||
@@ -142,7 +150,7 @@ pub struct KbLocalPairDiagnosticSummaryDto {
|
||||
|
||||
/// Local decoded-event diagnostics summary.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbLocalDecodedEventDiagnosticSummaryDto {
|
||||
pub struct LocalDecodedEventDiagnosticSummaryDto {
|
||||
/// Protocol name.
|
||||
pub protocol_name: std::string::String,
|
||||
/// Event kind.
|
||||
@@ -159,9 +167,65 @@ pub struct KbLocalDecodedEventDiagnosticSummaryDto {
|
||||
pub trade_event_count: i64,
|
||||
}
|
||||
|
||||
/// Missing trade event diagnostics grouped by reason.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct LocalMissingTradeEventReasonSummaryDto {
|
||||
/// Diagnostic reason.
|
||||
pub reason: std::string::String,
|
||||
/// Whether grouped source transactions failed.
|
||||
pub transaction_failed: bool,
|
||||
/// Whether grouped missing trade events are actionable.
|
||||
pub actionable: bool,
|
||||
/// Total missing trade events in this group.
|
||||
pub event_count: i64,
|
||||
/// Total events in this group with an explicit base amount payload.
|
||||
pub has_base_amount_payload_count: i64,
|
||||
/// Total events in this group with an explicit quote amount payload.
|
||||
pub has_quote_amount_payload_count: i64,
|
||||
/// Total events in this group with an explicit price payload.
|
||||
pub has_price_payload_count: i64,
|
||||
}
|
||||
|
||||
/// Local pair diagnostics for pairs whose missing trade events are non-actionable.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct LocalNonActionablePairDiagnosticSummaryDto {
|
||||
/// Pair id.
|
||||
pub pair_id: i64,
|
||||
/// Pool address.
|
||||
pub pool_address: std::string::String,
|
||||
/// DEX code.
|
||||
pub dex_code: std::string::String,
|
||||
/// Base token mint.
|
||||
pub base_mint: std::string::String,
|
||||
/// Base token symbol.
|
||||
pub base_symbol: std::option::Option<std::string::String>,
|
||||
/// Quote token mint.
|
||||
pub quote_mint: std::string::String,
|
||||
/// Quote token symbol.
|
||||
pub quote_symbol: std::option::Option<std::string::String>,
|
||||
/// Pair symbol.
|
||||
pub pair_symbol: std::option::Option<std::string::String>,
|
||||
/// Total decoded trade candidates attached to the pool.
|
||||
pub decoded_trade_candidate_count: i64,
|
||||
/// Total non-actionable missing trade events attached to the pair.
|
||||
pub non_actionable_missing_trade_event_count: i64,
|
||||
/// Total missing trade candidates caused by failed transactions.
|
||||
pub failed_transaction_candidate_count: i64,
|
||||
/// Total successful missing trade candidates without token mints.
|
||||
pub ok_transaction_without_token_mints_count: i64,
|
||||
/// Total successful missing trade candidates without amount payload.
|
||||
pub ok_transaction_without_amount_payload_count: i64,
|
||||
/// Distinct non-actionable diagnostic reasons seen for this pair.
|
||||
pub reason_summary: std::option::Option<std::string::String>,
|
||||
/// Total trade events attached to the pair.
|
||||
pub trade_event_count: i64,
|
||||
/// Total candle buckets attached to the pair.
|
||||
pub pair_candle_count: i64,
|
||||
}
|
||||
|
||||
/// Internal flat counter row for local diagnostics.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct KbLocalPipelineDiagnosticCountersDto {
|
||||
pub struct LocalPipelineDiagnosticCountersDto {
|
||||
/// Total persisted chain transactions.
|
||||
pub transaction_count: i64,
|
||||
/// Total successful chain transactions.
|
||||
@@ -208,6 +272,8 @@ pub struct KbLocalPipelineDiagnosticCountersDto {
|
||||
pub pool_count: i64,
|
||||
/// Total known pairs.
|
||||
pub pair_count: i64,
|
||||
/// Total pairs with only non-actionable missing trade events.
|
||||
pub non_actionable_pair_count: i64,
|
||||
/// Total pairs without trade.
|
||||
pub pair_without_trade_count: i64,
|
||||
/// Total pairs without candle.
|
||||
@@ -216,7 +282,7 @@ pub struct KbLocalPipelineDiagnosticCountersDto {
|
||||
|
||||
/// SQL row for global local pipeline diagnostic counters.
|
||||
#[derive(Debug, Clone, sqlx::FromRow)]
|
||||
pub(crate) struct KbLocalPipelineDiagnosticCountersRow {
|
||||
pub(crate) struct LocalPipelineDiagnosticCountersRow {
|
||||
pub(crate) transaction_count: i64,
|
||||
pub(crate) ok_transaction_count: i64,
|
||||
pub(crate) failed_transaction_count: i64,
|
||||
@@ -240,13 +306,14 @@ pub(crate) struct KbLocalPipelineDiagnosticCountersRow {
|
||||
pub(crate) token_metadata_missing_count: i64,
|
||||
pub(crate) pool_count: i64,
|
||||
pub(crate) pair_count: i64,
|
||||
pub(crate) non_actionable_pair_count: i64,
|
||||
pub(crate) pair_without_trade_count: i64,
|
||||
pub(crate) pair_without_candle_count: i64,
|
||||
}
|
||||
|
||||
/// SQL row for local DEX diagnostics.
|
||||
#[derive(Debug, Clone, sqlx::FromRow)]
|
||||
pub(crate) struct KbLocalDexDiagnosticSummaryRow {
|
||||
pub(crate) struct LocalDexDiagnosticSummaryRow {
|
||||
pub(crate) dex_code: std::string::String,
|
||||
pub(crate) pool_count: i64,
|
||||
pub(crate) pair_count: i64,
|
||||
@@ -259,7 +326,7 @@ pub(crate) struct KbLocalDexDiagnosticSummaryRow {
|
||||
|
||||
/// SQL row for local pair diagnostics.
|
||||
#[derive(Debug, Clone, sqlx::FromRow)]
|
||||
pub(crate) struct KbLocalPairDiagnosticSummaryRow {
|
||||
pub(crate) struct LocalPairDiagnosticSummaryRow {
|
||||
pub(crate) pair_id: i64,
|
||||
pub(crate) pool_address: std::string::String,
|
||||
pub(crate) dex_code: std::string::String,
|
||||
@@ -279,7 +346,7 @@ pub(crate) struct KbLocalPairDiagnosticSummaryRow {
|
||||
|
||||
/// SQL row for local decoded-event diagnostics.
|
||||
#[derive(Debug, Clone, sqlx::FromRow)]
|
||||
pub(crate) struct KbLocalDecodedEventDiagnosticSummaryRow {
|
||||
pub(crate) struct LocalDecodedEventDiagnosticSummaryRow {
|
||||
pub(crate) protocol_name: std::string::String,
|
||||
pub(crate) event_kind: std::string::String,
|
||||
pub(crate) event_category: std::option::Option<std::string::String>,
|
||||
@@ -291,7 +358,7 @@ pub(crate) struct KbLocalDecodedEventDiagnosticSummaryRow {
|
||||
|
||||
/// Sample of a decoded trade candidate without linked trade event.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbLocalMissingTradeEventDiagnosticSampleDto {
|
||||
pub struct LocalMissingTradeEventDiagnosticSampleDto {
|
||||
/// Decoded event id.
|
||||
pub decoded_event_id: i64,
|
||||
/// Chain transaction id.
|
||||
@@ -306,6 +373,14 @@ pub struct KbLocalMissingTradeEventDiagnosticSampleDto {
|
||||
pub pool_account: std::option::Option<std::string::String>,
|
||||
/// Whether the source transaction failed.
|
||||
pub transaction_failed: bool,
|
||||
/// Whether this missing trade event is actionable for validation.
|
||||
///
|
||||
/// A missing trade event is actionable only when the source transaction
|
||||
/// succeeded, the decoded event has a pool account and both token mints,
|
||||
/// and the pool is already attached to a known pair. Failed transactions
|
||||
/// and incomplete decoded hints remain visible as samples, but they should
|
||||
/// not block the non-regression profile.
|
||||
pub actionable: bool,
|
||||
/// Diagnostic reason explaining why no trade event was linked.
|
||||
pub reason: std::string::String,
|
||||
/// Whether payload has an explicit base amount.
|
||||
@@ -318,7 +393,7 @@ pub struct KbLocalMissingTradeEventDiagnosticSampleDto {
|
||||
|
||||
/// Sample of duplicated trade rows grouped by decoded event id.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbLocalDuplicateDecodedEventTradeDiagnosticSampleDto {
|
||||
pub struct LocalDuplicateDecodedEventTradeDiagnosticSampleDto {
|
||||
/// Decoded event id.
|
||||
pub decoded_event_id: i64,
|
||||
/// Protocol name.
|
||||
@@ -337,7 +412,7 @@ pub struct KbLocalDuplicateDecodedEventTradeDiagnosticSampleDto {
|
||||
|
||||
/// Sample of multi-trade groups sharing the same signature and pair id.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbLocalMultiTradeSignaturePairDiagnosticSampleDto {
|
||||
pub struct LocalMultiTradeSignaturePairDiagnosticSampleDto {
|
||||
/// Transaction signature.
|
||||
pub signature: std::string::String,
|
||||
/// Pair id.
|
||||
@@ -358,7 +433,7 @@ pub struct KbLocalMultiTradeSignaturePairDiagnosticSampleDto {
|
||||
|
||||
/// Sample of a pair gap.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbLocalPairGapDiagnosticSampleDto {
|
||||
pub struct LocalPairGapDiagnosticSampleDto {
|
||||
/// Pair id.
|
||||
pub pair_id: i64,
|
||||
/// Pool address.
|
||||
@@ -385,9 +460,42 @@ pub struct KbLocalPairGapDiagnosticSampleDto {
|
||||
pub pair_candle_count: i64,
|
||||
}
|
||||
|
||||
/// SQL row for missing trade event reason summaries.
|
||||
#[derive(Debug, Clone, sqlx::FromRow)]
|
||||
pub(crate) struct LocalMissingTradeEventReasonSummaryRow {
|
||||
pub(crate) reason: std::string::String,
|
||||
pub(crate) transaction_failed: i64,
|
||||
pub(crate) actionable: i64,
|
||||
pub(crate) event_count: i64,
|
||||
pub(crate) has_base_amount_payload_count: i64,
|
||||
pub(crate) has_quote_amount_payload_count: i64,
|
||||
pub(crate) has_price_payload_count: i64,
|
||||
}
|
||||
|
||||
/// SQL row for non-actionable pair diagnostic summaries.
|
||||
#[derive(Debug, Clone, sqlx::FromRow)]
|
||||
pub(crate) struct LocalNonActionablePairDiagnosticSummaryRow {
|
||||
pub(crate) pair_id: i64,
|
||||
pub(crate) pool_address: std::string::String,
|
||||
pub(crate) dex_code: std::string::String,
|
||||
pub(crate) base_mint: std::string::String,
|
||||
pub(crate) base_symbol: std::option::Option<std::string::String>,
|
||||
pub(crate) quote_mint: std::string::String,
|
||||
pub(crate) quote_symbol: std::option::Option<std::string::String>,
|
||||
pub(crate) pair_symbol: std::option::Option<std::string::String>,
|
||||
pub(crate) decoded_trade_candidate_count: i64,
|
||||
pub(crate) non_actionable_missing_trade_event_count: i64,
|
||||
pub(crate) failed_transaction_candidate_count: i64,
|
||||
pub(crate) ok_transaction_without_token_mints_count: i64,
|
||||
pub(crate) ok_transaction_without_amount_payload_count: i64,
|
||||
pub(crate) reason_summary: std::option::Option<std::string::String>,
|
||||
pub(crate) trade_event_count: i64,
|
||||
pub(crate) pair_candle_count: i64,
|
||||
}
|
||||
|
||||
/// SQL row for missing trade event samples.
|
||||
#[derive(Debug, Clone, sqlx::FromRow)]
|
||||
pub(crate) struct KbLocalMissingTradeEventDiagnosticSampleRow {
|
||||
pub(crate) struct LocalMissingTradeEventDiagnosticSampleRow {
|
||||
pub(crate) decoded_event_id: i64,
|
||||
pub(crate) transaction_id: std::option::Option<i64>,
|
||||
pub(crate) signature: std::option::Option<std::string::String>,
|
||||
@@ -395,6 +503,7 @@ pub(crate) struct KbLocalMissingTradeEventDiagnosticSampleRow {
|
||||
pub(crate) event_kind: std::string::String,
|
||||
pub(crate) pool_account: std::option::Option<std::string::String>,
|
||||
pub(crate) transaction_failed: i64,
|
||||
pub(crate) actionable: i64,
|
||||
pub(crate) reason: std::string::String,
|
||||
pub(crate) has_base_amount_payload: i64,
|
||||
pub(crate) has_quote_amount_payload: i64,
|
||||
@@ -403,7 +512,7 @@ pub(crate) struct KbLocalMissingTradeEventDiagnosticSampleRow {
|
||||
|
||||
/// SQL row for duplicated decoded event trade samples.
|
||||
#[derive(Debug, Clone, sqlx::FromRow)]
|
||||
pub(crate) struct KbLocalDuplicateDecodedEventTradeDiagnosticSampleRow {
|
||||
pub(crate) struct LocalDuplicateDecodedEventTradeDiagnosticSampleRow {
|
||||
pub(crate) decoded_event_id: i64,
|
||||
pub(crate) protocol_name: std::option::Option<std::string::String>,
|
||||
pub(crate) event_kind: std::option::Option<std::string::String>,
|
||||
@@ -415,7 +524,7 @@ pub(crate) struct KbLocalDuplicateDecodedEventTradeDiagnosticSampleRow {
|
||||
|
||||
/// SQL row for multi-trade signature/pair samples.
|
||||
#[derive(Debug, Clone, sqlx::FromRow)]
|
||||
pub(crate) struct KbLocalMultiTradeSignaturePairDiagnosticSampleRow {
|
||||
pub(crate) struct LocalMultiTradeSignaturePairDiagnosticSampleRow {
|
||||
pub(crate) signature: std::string::String,
|
||||
pub(crate) pair_id: i64,
|
||||
pub(crate) pool_address: std::option::Option<std::string::String>,
|
||||
@@ -428,7 +537,7 @@ pub(crate) struct KbLocalMultiTradeSignaturePairDiagnosticSampleRow {
|
||||
|
||||
/// SQL row for pair gap samples.
|
||||
#[derive(Debug, Clone, sqlx::FromRow)]
|
||||
pub(crate) struct KbLocalPairGapDiagnosticSampleRow {
|
||||
pub(crate) struct LocalPairGapDiagnosticSampleRow {
|
||||
pub(crate) pair_id: i64,
|
||||
pub(crate) pool_address: std::string::String,
|
||||
pub(crate) dex_code: std::string::String,
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Application-facing observed token DTO.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbObservedTokenDto {
|
||||
pub struct ObservedTokenDto {
|
||||
/// Optional numeric primary key.
|
||||
pub id: std::option::Option<i64>,
|
||||
/// Token mint address.
|
||||
@@ -18,7 +18,7 @@ pub struct KbObservedTokenDto {
|
||||
/// Token program id.
|
||||
pub token_program: std::string::String,
|
||||
/// Local status.
|
||||
pub status: crate::KbObservedTokenStatus,
|
||||
pub status: crate::ObservedTokenStatus,
|
||||
/// First seen timestamp.
|
||||
pub first_seen_at: chrono::DateTime<chrono::Utc>,
|
||||
/// Last seen timestamp.
|
||||
@@ -27,7 +27,7 @@ pub struct KbObservedTokenDto {
|
||||
pub updated_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl KbObservedTokenDto {
|
||||
impl ObservedTokenDto {
|
||||
/// Creates a new observed token DTO with current timestamps.
|
||||
pub fn new(
|
||||
mint: std::string::String,
|
||||
@@ -35,7 +35,7 @@ impl KbObservedTokenDto {
|
||||
name: std::option::Option<std::string::String>,
|
||||
decimals: std::option::Option<u8>,
|
||||
token_program: std::string::String,
|
||||
status: crate::KbObservedTokenStatus,
|
||||
status: crate::ObservedTokenStatus,
|
||||
) -> Self {
|
||||
let now = chrono::Utc::now();
|
||||
return Self {
|
||||
@@ -53,11 +53,11 @@ impl KbObservedTokenDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::KbObservedTokenEntity> for KbObservedTokenDto {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<crate::ObservedTokenEntity> for ObservedTokenDto {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(entity: crate::KbObservedTokenEntity) -> Result<Self, Self::Error> {
|
||||
let status_result = crate::KbObservedTokenStatus::from_i16(entity.status);
|
||||
fn try_from(entity: crate::ObservedTokenEntity) -> Result<Self, Self::Error> {
|
||||
let status_result = crate::ObservedTokenStatus::from_i16(entity.status);
|
||||
let status = match status_result {
|
||||
Ok(status) => status,
|
||||
Err(error) => return Err(error),
|
||||
@@ -66,7 +66,7 @@ impl TryFrom<crate::KbObservedTokenEntity> for KbObservedTokenDto {
|
||||
let first_seen_at = match first_seen_at_result {
|
||||
Ok(first_seen_at) => first_seen_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse observed token first_seen_at '{}': {}",
|
||||
entity.first_seen_at, error
|
||||
)));
|
||||
@@ -76,7 +76,7 @@ impl TryFrom<crate::KbObservedTokenEntity> for KbObservedTokenDto {
|
||||
let last_seen_at = match last_seen_at_result {
|
||||
Ok(last_seen_at) => last_seen_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse observed token last_seen_at '{}': {}",
|
||||
entity.last_seen_at, error
|
||||
)));
|
||||
@@ -86,7 +86,7 @@ impl TryFrom<crate::KbObservedTokenEntity> for KbObservedTokenDto {
|
||||
let updated_at = match updated_at_result {
|
||||
Ok(updated_at) => updated_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse observed token updated_at '{}': {}",
|
||||
entity.updated_at, error
|
||||
)));
|
||||
@@ -98,7 +98,7 @@ impl TryFrom<crate::KbObservedTokenEntity> for KbObservedTokenDto {
|
||||
match decimals_u8_result {
|
||||
Ok(decimals_u8) => Some(decimals_u8),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot convert observed token decimals '{}' to u8: {}",
|
||||
decimals, error
|
||||
)));
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
|
||||
/// Application-facing on-chain observation DTO.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbOnchainObservationDto {
|
||||
pub struct OnchainObservationDto {
|
||||
/// Optional numeric primary key.
|
||||
pub id: std::option::Option<i64>,
|
||||
/// Observation kind.
|
||||
pub observation_kind: std::string::String,
|
||||
/// Observation source family.
|
||||
pub source_kind: crate::KbObservationSourceKind,
|
||||
pub source_kind: crate::ObservationSourceKind,
|
||||
/// Optional source endpoint logical name.
|
||||
pub endpoint_name: std::option::Option<std::string::String>,
|
||||
/// Logical object key, for example a mint, signature or pool address.
|
||||
@@ -23,11 +23,11 @@ pub struct KbOnchainObservationDto {
|
||||
pub observed_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl KbOnchainObservationDto {
|
||||
impl OnchainObservationDto {
|
||||
/// Creates a new on-chain observation DTO with the current timestamp.
|
||||
pub fn new(
|
||||
observation_kind: std::string::String,
|
||||
source_kind: crate::KbObservationSourceKind,
|
||||
source_kind: crate::ObservationSourceKind,
|
||||
endpoint_name: std::option::Option<std::string::String>,
|
||||
object_key: std::string::String,
|
||||
slot: std::option::Option<u64>,
|
||||
@@ -46,11 +46,11 @@ impl KbOnchainObservationDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::KbOnchainObservationEntity> for KbOnchainObservationDto {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<crate::OnchainObservationEntity> for OnchainObservationDto {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(entity: crate::KbOnchainObservationEntity) -> Result<Self, Self::Error> {
|
||||
let source_kind_result = crate::KbObservationSourceKind::from_i16(entity.source_kind);
|
||||
fn try_from(entity: crate::OnchainObservationEntity) -> Result<Self, Self::Error> {
|
||||
let source_kind_result = crate::ObservationSourceKind::from_i16(entity.source_kind);
|
||||
let source_kind = match source_kind_result {
|
||||
Ok(source_kind) => source_kind,
|
||||
Err(error) => return Err(error),
|
||||
@@ -59,7 +59,7 @@ impl TryFrom<crate::KbOnchainObservationEntity> for KbOnchainObservationDto {
|
||||
let observed_at = match observed_at_result {
|
||||
Ok(observed_at) => observed_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse on-chain observation observed_at '{}': {}",
|
||||
entity.observed_at, error
|
||||
)));
|
||||
@@ -69,7 +69,7 @@ impl TryFrom<crate::KbOnchainObservationEntity> for KbOnchainObservationDto {
|
||||
let payload = match payload_result {
|
||||
Ok(payload) => payload,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse on-chain observation payload_json '{}': {}",
|
||||
entity.payload_json, error
|
||||
)));
|
||||
@@ -81,7 +81,7 @@ impl TryFrom<crate::KbOnchainObservationEntity> for KbOnchainObservationDto {
|
||||
match slot_result {
|
||||
Ok(slot) => Some(slot),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot convert on-chain observation slot '{}' to u64: {}",
|
||||
slot, error
|
||||
)));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Application-facing normalized pair DTO.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbPairDto {
|
||||
pub struct PairDto {
|
||||
/// Optional numeric primary key.
|
||||
pub id: std::option::Option<i64>,
|
||||
/// Related DEX id.
|
||||
@@ -23,7 +23,7 @@ pub struct KbPairDto {
|
||||
pub updated_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl KbPairDto {
|
||||
impl PairDto {
|
||||
/// Creates a new pair DTO.
|
||||
pub fn new(
|
||||
dex_id: i64,
|
||||
@@ -46,15 +46,15 @@ impl KbPairDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::KbPairEntity> for KbPairDto {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<crate::PairEntity> for PairDto {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(entity: crate::KbPairEntity) -> Result<Self, Self::Error> {
|
||||
fn try_from(entity: crate::PairEntity) -> Result<Self, Self::Error> {
|
||||
let first_seen_at_result = chrono::DateTime::parse_from_rfc3339(&entity.first_seen_at);
|
||||
let first_seen_at = match first_seen_at_result {
|
||||
Ok(first_seen_at) => first_seen_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse pair first_seen_at '{}': {}",
|
||||
entity.first_seen_at, error
|
||||
)));
|
||||
@@ -64,7 +64,7 @@ impl TryFrom<crate::KbPairEntity> for KbPairDto {
|
||||
let updated_at = match updated_at_result {
|
||||
Ok(updated_at) => updated_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse pair updated_at '{}': {}",
|
||||
entity.updated_at, error
|
||||
)));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Application-facing pair-analytic-signal DTO.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbPairAnalyticSignalDto {
|
||||
pub struct PairAnalyticSignalDto {
|
||||
/// Optional numeric primary key.
|
||||
pub id: std::option::Option<i64>,
|
||||
/// Related pair id.
|
||||
@@ -12,7 +12,7 @@ pub struct KbPairAnalyticSignalDto {
|
||||
/// Stable signal kind.
|
||||
pub signal_kind: std::string::String,
|
||||
/// Signal severity.
|
||||
pub severity: crate::KbAnalysisSignalSeverity,
|
||||
pub severity: crate::AnalysisSignalSeverity,
|
||||
/// Timeframe in seconds. Zero means non-bucketed signal.
|
||||
pub timeframe_seconds: i64,
|
||||
/// Inclusive bucket start in unix seconds. Zero means non-bucketed signal.
|
||||
@@ -31,12 +31,12 @@ pub struct KbPairAnalyticSignalDto {
|
||||
pub updated_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl KbPairAnalyticSignalDto {
|
||||
impl PairAnalyticSignalDto {
|
||||
/// Creates a new pair-analytic-signal DTO.
|
||||
pub fn new(
|
||||
pair_id: i64,
|
||||
signal_kind: std::string::String,
|
||||
severity: crate::KbAnalysisSignalSeverity,
|
||||
severity: crate::AnalysisSignalSeverity,
|
||||
timeframe_seconds: i64,
|
||||
bucket_start_unix: i64,
|
||||
score: std::option::Option<f64>,
|
||||
@@ -62,11 +62,11 @@ impl KbPairAnalyticSignalDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::KbPairAnalyticSignalEntity> for KbPairAnalyticSignalDto {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<crate::PairAnalyticSignalEntity> for PairAnalyticSignalDto {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(entity: crate::KbPairAnalyticSignalEntity) -> Result<Self, Self::Error> {
|
||||
let severity_result = crate::KbAnalysisSignalSeverity::from_i16(entity.severity);
|
||||
fn try_from(entity: crate::PairAnalyticSignalEntity) -> Result<Self, Self::Error> {
|
||||
let severity_result = crate::AnalysisSignalSeverity::from_i16(entity.severity);
|
||||
let severity = match severity_result {
|
||||
Ok(severity) => severity,
|
||||
Err(error) => return Err(error),
|
||||
@@ -76,7 +76,7 @@ impl TryFrom<crate::KbPairAnalyticSignalEntity> for KbPairAnalyticSignalDto {
|
||||
let signal_value = match signal_value_result {
|
||||
Ok(signal_value) => signal_value,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse pair_analytic_signal signal_value_json '{}': {}",
|
||||
entity.signal_value_json, error
|
||||
)));
|
||||
@@ -86,7 +86,7 @@ impl TryFrom<crate::KbPairAnalyticSignalEntity> for KbPairAnalyticSignalDto {
|
||||
let created_at = match created_at_result {
|
||||
Ok(created_at) => created_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse pair_analytic_signal created_at '{}': {}",
|
||||
entity.created_at, error
|
||||
)));
|
||||
@@ -96,7 +96,7 @@ impl TryFrom<crate::KbPairAnalyticSignalEntity> for KbPairAnalyticSignalDto {
|
||||
let updated_at = match updated_at_result {
|
||||
Ok(updated_at) => updated_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse pair_analytic_signal updated_at '{}': {}",
|
||||
entity.updated_at, error
|
||||
)));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Application-facing pair-candle DTO.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbPairCandleDto {
|
||||
pub struct PairCandleDto {
|
||||
/// Optional numeric primary key.
|
||||
pub id: std::option::Option<i64>,
|
||||
/// Related pair id.
|
||||
@@ -43,7 +43,7 @@ pub struct KbPairCandleDto {
|
||||
pub updated_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl KbPairCandleDto {
|
||||
impl PairCandleDto {
|
||||
/// Creates a new pair-candle DTO.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
@@ -87,15 +87,15 @@ impl KbPairCandleDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::KbPairCandleEntity> for KbPairCandleDto {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<crate::PairCandleEntity> for PairCandleDto {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(entity: crate::KbPairCandleEntity) -> Result<Self, Self::Error> {
|
||||
fn try_from(entity: crate::PairCandleEntity) -> Result<Self, Self::Error> {
|
||||
let created_at_result = chrono::DateTime::parse_from_rfc3339(&entity.created_at);
|
||||
let created_at = match created_at_result {
|
||||
Ok(created_at) => created_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse pair_candle created_at '{}': {}",
|
||||
entity.created_at, error
|
||||
)));
|
||||
@@ -105,7 +105,7 @@ impl TryFrom<crate::KbPairCandleEntity> for KbPairCandleDto {
|
||||
let updated_at = match updated_at_result {
|
||||
Ok(updated_at) => updated_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse pair_candle updated_at '{}': {}",
|
||||
entity.updated_at, error
|
||||
)));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Application-facing pair-metric DTO.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbPairMetricDto {
|
||||
pub struct PairMetricDto {
|
||||
/// Optional numeric primary key.
|
||||
pub id: std::option::Option<i64>,
|
||||
/// Related pair id.
|
||||
@@ -35,7 +35,7 @@ pub struct KbPairMetricDto {
|
||||
pub updated_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl KbPairMetricDto {
|
||||
impl PairMetricDto {
|
||||
/// Creates a new pair-metric DTO.
|
||||
pub fn new(pair_id: i64) -> Self {
|
||||
let now = chrono::Utc::now();
|
||||
@@ -58,15 +58,15 @@ impl KbPairMetricDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::KbPairMetricEntity> for KbPairMetricDto {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<crate::PairMetricEntity> for PairMetricDto {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(entity: crate::KbPairMetricEntity) -> Result<Self, Self::Error> {
|
||||
fn try_from(entity: crate::PairMetricEntity) -> Result<Self, Self::Error> {
|
||||
let created_at_result = chrono::DateTime::parse_from_rfc3339(&entity.created_at);
|
||||
let created_at = match created_at_result {
|
||||
Ok(created_at) => created_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse pair_metric created_at '{}': {}",
|
||||
entity.created_at, error
|
||||
)));
|
||||
@@ -76,7 +76,7 @@ impl TryFrom<crate::KbPairMetricEntity> for KbPairMetricDto {
|
||||
let updated_at = match updated_at_result {
|
||||
Ok(updated_at) => updated_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse pair_metric updated_at '{}': {}",
|
||||
entity.updated_at, error
|
||||
)));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Application-facing normalized pool DTO.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbPoolDto {
|
||||
pub struct PoolDto {
|
||||
/// Optional numeric primary key.
|
||||
pub id: std::option::Option<i64>,
|
||||
/// Related DEX id.
|
||||
@@ -12,22 +12,22 @@ pub struct KbPoolDto {
|
||||
/// Pool address.
|
||||
pub address: std::string::String,
|
||||
/// Pool kind.
|
||||
pub pool_kind: crate::KbPoolKind,
|
||||
pub pool_kind: crate::PoolKind,
|
||||
/// Pool status.
|
||||
pub status: crate::KbPoolStatus,
|
||||
pub status: crate::PoolStatus,
|
||||
/// First seen timestamp.
|
||||
pub first_seen_at: chrono::DateTime<chrono::Utc>,
|
||||
/// Update timestamp.
|
||||
pub updated_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl KbPoolDto {
|
||||
impl PoolDto {
|
||||
/// Creates a new pool DTO.
|
||||
pub fn new(
|
||||
dex_id: i64,
|
||||
address: std::string::String,
|
||||
pool_kind: crate::KbPoolKind,
|
||||
status: crate::KbPoolStatus,
|
||||
pool_kind: crate::PoolKind,
|
||||
status: crate::PoolStatus,
|
||||
) -> Self {
|
||||
let now = chrono::Utc::now();
|
||||
return Self {
|
||||
@@ -42,16 +42,16 @@ impl KbPoolDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::KbPoolEntity> for KbPoolDto {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<crate::PoolEntity> for PoolDto {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(entity: crate::KbPoolEntity) -> Result<Self, Self::Error> {
|
||||
let pool_kind_result = crate::KbPoolKind::from_i16(entity.pool_kind);
|
||||
fn try_from(entity: crate::PoolEntity) -> Result<Self, Self::Error> {
|
||||
let pool_kind_result = crate::PoolKind::from_i16(entity.pool_kind);
|
||||
let pool_kind = match pool_kind_result {
|
||||
Ok(pool_kind) => pool_kind,
|
||||
Err(error) => return Err(error),
|
||||
};
|
||||
let status_result = crate::KbPoolStatus::from_i16(entity.status);
|
||||
let status_result = crate::PoolStatus::from_i16(entity.status);
|
||||
let status = match status_result {
|
||||
Ok(status) => status,
|
||||
Err(error) => return Err(error),
|
||||
@@ -60,7 +60,7 @@ impl TryFrom<crate::KbPoolEntity> for KbPoolDto {
|
||||
let first_seen_at = match first_seen_at_result {
|
||||
Ok(first_seen_at) => first_seen_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse pool first_seen_at '{}': {}",
|
||||
entity.first_seen_at, error
|
||||
)));
|
||||
@@ -70,7 +70,7 @@ impl TryFrom<crate::KbPoolEntity> for KbPoolDto {
|
||||
let updated_at = match updated_at_result {
|
||||
Ok(updated_at) => updated_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse pool updated_at '{}': {}",
|
||||
entity.updated_at, error
|
||||
)));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Application-facing normalized pool listing DTO.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbPoolListingDto {
|
||||
pub struct PoolListingDto {
|
||||
/// Optional numeric primary key.
|
||||
pub id: std::option::Option<i64>,
|
||||
/// Related DEX id.
|
||||
@@ -14,7 +14,7 @@ pub struct KbPoolListingDto {
|
||||
/// Optional related pair id.
|
||||
pub pair_id: std::option::Option<i64>,
|
||||
/// Discovery source family.
|
||||
pub source_kind: crate::KbObservationSourceKind,
|
||||
pub source_kind: crate::ObservationSourceKind,
|
||||
/// Optional source endpoint logical name.
|
||||
pub source_endpoint_name: std::option::Option<std::string::String>,
|
||||
/// Detection timestamp.
|
||||
@@ -29,13 +29,13 @@ pub struct KbPoolListingDto {
|
||||
pub updated_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl KbPoolListingDto {
|
||||
impl PoolListingDto {
|
||||
/// Creates a new pool listing DTO.
|
||||
pub fn new(
|
||||
dex_id: i64,
|
||||
pool_id: i64,
|
||||
pair_id: std::option::Option<i64>,
|
||||
source_kind: crate::KbObservationSourceKind,
|
||||
source_kind: crate::ObservationSourceKind,
|
||||
source_endpoint_name: std::option::Option<std::string::String>,
|
||||
initial_base_reserve: std::option::Option<f64>,
|
||||
initial_quote_reserve: std::option::Option<f64>,
|
||||
@@ -58,11 +58,11 @@ impl KbPoolListingDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::KbPoolListingEntity> for KbPoolListingDto {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<crate::PoolListingEntity> for PoolListingDto {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(entity: crate::KbPoolListingEntity) -> Result<Self, Self::Error> {
|
||||
let source_kind_result = crate::KbObservationSourceKind::from_i16(entity.source_kind);
|
||||
fn try_from(entity: crate::PoolListingEntity) -> Result<Self, Self::Error> {
|
||||
let source_kind_result = crate::ObservationSourceKind::from_i16(entity.source_kind);
|
||||
let source_kind = match source_kind_result {
|
||||
Ok(source_kind) => source_kind,
|
||||
Err(error) => return Err(error),
|
||||
@@ -71,7 +71,7 @@ impl TryFrom<crate::KbPoolListingEntity> for KbPoolListingDto {
|
||||
let detected_at = match detected_at_result {
|
||||
Ok(detected_at) => detected_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse pool_listing detected_at '{}': {}",
|
||||
entity.detected_at, error
|
||||
)));
|
||||
@@ -81,7 +81,7 @@ impl TryFrom<crate::KbPoolListingEntity> for KbPoolListingDto {
|
||||
let updated_at = match updated_at_result {
|
||||
Ok(updated_at) => updated_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse pool_listing updated_at '{}': {}",
|
||||
entity.updated_at, error
|
||||
)));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Application-facing pool-origin DTO.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbPoolOriginDto {
|
||||
pub struct PoolOriginDto {
|
||||
/// Optional numeric primary key.
|
||||
pub id: std::option::Option<i64>,
|
||||
/// Related DEX id.
|
||||
@@ -26,7 +26,7 @@ pub struct KbPoolOriginDto {
|
||||
/// Founding event kind.
|
||||
pub founding_event_kind: std::string::String,
|
||||
/// Discovery source kind.
|
||||
pub source_kind: crate::KbObservationSourceKind,
|
||||
pub source_kind: crate::ObservationSourceKind,
|
||||
/// Optional source endpoint logical name.
|
||||
pub source_endpoint_name: std::option::Option<std::string::String>,
|
||||
/// Optional related launch attribution id.
|
||||
@@ -37,7 +37,7 @@ pub struct KbPoolOriginDto {
|
||||
pub updated_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl KbPoolOriginDto {
|
||||
impl PoolOriginDto {
|
||||
/// Creates a new pool-origin DTO.
|
||||
pub fn new(
|
||||
dex_id: i64,
|
||||
@@ -49,7 +49,7 @@ impl KbPoolOriginDto {
|
||||
founding_signature: std::string::String,
|
||||
founding_protocol_name: std::string::String,
|
||||
founding_event_kind: std::string::String,
|
||||
source_kind: crate::KbObservationSourceKind,
|
||||
source_kind: crate::ObservationSourceKind,
|
||||
source_endpoint_name: std::option::Option<std::string::String>,
|
||||
launch_attribution_id: std::option::Option<i64>,
|
||||
) -> Self {
|
||||
@@ -74,11 +74,11 @@ impl KbPoolOriginDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::KbPoolOriginEntity> for KbPoolOriginDto {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<crate::PoolOriginEntity> for PoolOriginDto {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(entity: crate::KbPoolOriginEntity) -> Result<Self, Self::Error> {
|
||||
let source_kind_result = crate::KbObservationSourceKind::from_i16(entity.source_kind);
|
||||
fn try_from(entity: crate::PoolOriginEntity) -> Result<Self, Self::Error> {
|
||||
let source_kind_result = crate::ObservationSourceKind::from_i16(entity.source_kind);
|
||||
let source_kind = match source_kind_result {
|
||||
Ok(source_kind) => source_kind,
|
||||
Err(error) => return Err(error),
|
||||
@@ -87,7 +87,7 @@ impl TryFrom<crate::KbPoolOriginEntity> for KbPoolOriginDto {
|
||||
let created_at = match created_at_result {
|
||||
Ok(created_at) => created_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse pool_origin created_at '{}': {}",
|
||||
entity.created_at, error
|
||||
)));
|
||||
@@ -97,7 +97,7 @@ impl TryFrom<crate::KbPoolOriginEntity> for KbPoolOriginDto {
|
||||
let updated_at = match updated_at_result {
|
||||
Ok(updated_at) => updated_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse pool_origin updated_at '{}': {}",
|
||||
entity.updated_at, error
|
||||
)));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Application-facing normalized pool token DTO.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbPoolTokenDto {
|
||||
pub struct PoolTokenDto {
|
||||
/// Optional numeric primary key.
|
||||
pub id: std::option::Option<i64>,
|
||||
/// Related pool id.
|
||||
@@ -12,7 +12,7 @@ pub struct KbPoolTokenDto {
|
||||
/// Related token id.
|
||||
pub token_id: i64,
|
||||
/// Token role.
|
||||
pub role: crate::KbPoolTokenRole,
|
||||
pub role: crate::PoolTokenRole,
|
||||
/// Optional vault address.
|
||||
pub vault_address: std::option::Option<std::string::String>,
|
||||
/// Optional token order inside the pool.
|
||||
@@ -23,12 +23,12 @@ pub struct KbPoolTokenDto {
|
||||
pub updated_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl KbPoolTokenDto {
|
||||
impl PoolTokenDto {
|
||||
/// Creates a new pool token DTO.
|
||||
pub fn new(
|
||||
pool_id: i64,
|
||||
token_id: i64,
|
||||
role: crate::KbPoolTokenRole,
|
||||
role: crate::PoolTokenRole,
|
||||
vault_address: std::option::Option<std::string::String>,
|
||||
token_order: std::option::Option<i64>,
|
||||
) -> Self {
|
||||
@@ -46,11 +46,11 @@ impl KbPoolTokenDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::KbPoolTokenEntity> for KbPoolTokenDto {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<crate::PoolTokenEntity> for PoolTokenDto {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(entity: crate::KbPoolTokenEntity) -> Result<Self, Self::Error> {
|
||||
let role_result = crate::KbPoolTokenRole::from_i16(entity.role);
|
||||
fn try_from(entity: crate::PoolTokenEntity) -> Result<Self, Self::Error> {
|
||||
let role_result = crate::PoolTokenRole::from_i16(entity.role);
|
||||
let role = match role_result {
|
||||
Ok(role) => role,
|
||||
Err(error) => return Err(error),
|
||||
@@ -59,7 +59,7 @@ impl TryFrom<crate::KbPoolTokenEntity> for KbPoolTokenDto {
|
||||
let created_at = match created_at_result {
|
||||
Ok(created_at) => created_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse pool_token created_at '{}': {}",
|
||||
entity.created_at, error
|
||||
)));
|
||||
@@ -69,7 +69,7 @@ impl TryFrom<crate::KbPoolTokenEntity> for KbPoolTokenDto {
|
||||
let updated_at = match updated_at_result {
|
||||
Ok(updated_at) => updated_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse pool_token updated_at '{}': {}",
|
||||
entity.updated_at, error
|
||||
)));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Application-facing normalized swap DTO.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbSwapDto {
|
||||
pub struct SwapDto {
|
||||
/// Optional numeric primary key.
|
||||
pub id: std::option::Option<i64>,
|
||||
/// Related DEX id.
|
||||
@@ -32,12 +32,12 @@ pub struct KbSwapDto {
|
||||
/// Optional price in quote units as decimal text.
|
||||
pub price_quote: std::option::Option<std::string::String>,
|
||||
/// Trade side relative to the base token.
|
||||
pub trade_side: crate::KbSwapTradeSide,
|
||||
pub trade_side: crate::SwapTradeSide,
|
||||
/// Execution timestamp.
|
||||
pub executed_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl KbSwapDto {
|
||||
impl SwapDto {
|
||||
/// Creates a new swap DTO.
|
||||
pub fn new(
|
||||
dex_id: i64,
|
||||
@@ -52,7 +52,7 @@ impl KbSwapDto {
|
||||
base_amount: std::string::String,
|
||||
quote_amount: std::string::String,
|
||||
price_quote: std::option::Option<std::string::String>,
|
||||
trade_side: crate::KbSwapTradeSide,
|
||||
trade_side: crate::SwapTradeSide,
|
||||
) -> Self {
|
||||
return Self {
|
||||
id: None,
|
||||
@@ -74,11 +74,11 @@ impl KbSwapDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::KbSwapEntity> for KbSwapDto {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<crate::SwapEntity> for SwapDto {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(entity: crate::KbSwapEntity) -> Result<Self, Self::Error> {
|
||||
let trade_side_result = crate::KbSwapTradeSide::from_i16(entity.trade_side);
|
||||
fn try_from(entity: crate::SwapEntity) -> Result<Self, Self::Error> {
|
||||
let trade_side_result = crate::SwapTradeSide::from_i16(entity.trade_side);
|
||||
let trade_side = match trade_side_result {
|
||||
Ok(trade_side) => trade_side,
|
||||
Err(error) => return Err(error),
|
||||
@@ -87,7 +87,7 @@ impl TryFrom<crate::KbSwapEntity> for KbSwapDto {
|
||||
let executed_at = match executed_at_result {
|
||||
Ok(executed_at) => executed_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse swap executed_at '{}': {}",
|
||||
entity.executed_at, error
|
||||
)));
|
||||
@@ -99,7 +99,7 @@ impl TryFrom<crate::KbSwapEntity> for KbSwapDto {
|
||||
match slot_result {
|
||||
Ok(slot) => Some(slot),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot convert swap slot '{}' to u64: {}",
|
||||
slot, error
|
||||
)));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Application-facing normalized token DTO.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbTokenDto {
|
||||
pub struct TokenDto {
|
||||
/// Optional numeric primary key.
|
||||
pub id: std::option::Option<i64>,
|
||||
/// Mint address.
|
||||
@@ -25,7 +25,7 @@ pub struct KbTokenDto {
|
||||
pub updated_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl KbTokenDto {
|
||||
impl TokenDto {
|
||||
/// Creates a new token DTO.
|
||||
pub fn new(
|
||||
mint: std::string::String,
|
||||
@@ -50,15 +50,15 @@ impl KbTokenDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::KbTokenEntity> for KbTokenDto {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<crate::TokenEntity> for TokenDto {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(entity: crate::KbTokenEntity) -> Result<Self, Self::Error> {
|
||||
fn try_from(entity: crate::TokenEntity) -> Result<Self, Self::Error> {
|
||||
let first_seen_at_result = chrono::DateTime::parse_from_rfc3339(&entity.first_seen_at);
|
||||
let first_seen_at = match first_seen_at_result {
|
||||
Ok(first_seen_at) => first_seen_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse token first_seen_at '{}': {}",
|
||||
entity.first_seen_at, error
|
||||
)));
|
||||
@@ -68,7 +68,7 @@ impl TryFrom<crate::KbTokenEntity> for KbTokenDto {
|
||||
let updated_at = match updated_at_result {
|
||||
Ok(updated_at) => updated_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse token updated_at '{}': {}",
|
||||
entity.updated_at, error
|
||||
)));
|
||||
@@ -80,7 +80,7 @@ impl TryFrom<crate::KbTokenEntity> for KbTokenDto {
|
||||
match decimals_result {
|
||||
Ok(decimals) => Some(decimals),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot convert token decimals '{}' to u8: {}",
|
||||
decimals, error
|
||||
)));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Application-facing normalized token burn event DTO.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbTokenBurnEventDto {
|
||||
pub struct TokenBurnEventDto {
|
||||
/// Optional numeric primary key.
|
||||
pub id: std::option::Option<i64>,
|
||||
/// Related token id.
|
||||
@@ -27,7 +27,7 @@ pub struct KbTokenBurnEventDto {
|
||||
pub executed_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl KbTokenBurnEventDto {
|
||||
impl TokenBurnEventDto {
|
||||
/// Creates a new token burn event DTO.
|
||||
pub fn new(
|
||||
token_id: i64,
|
||||
@@ -54,15 +54,15 @@ impl KbTokenBurnEventDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::KbTokenBurnEventEntity> for KbTokenBurnEventDto {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<crate::TokenBurnEventEntity> for TokenBurnEventDto {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(entity: crate::KbTokenBurnEventEntity) -> Result<Self, Self::Error> {
|
||||
fn try_from(entity: crate::TokenBurnEventEntity) -> 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!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse token burn event executed_at '{}': {}",
|
||||
entity.executed_at, error
|
||||
)));
|
||||
@@ -74,7 +74,7 @@ impl TryFrom<crate::KbTokenBurnEventEntity> for KbTokenBurnEventDto {
|
||||
match slot_result {
|
||||
Ok(slot) => Some(slot),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot convert token burn event slot '{}' to u64: {}",
|
||||
slot, error
|
||||
)));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Application-facing normalized token mint event DTO.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbTokenMintEventDto {
|
||||
pub struct TokenMintEventDto {
|
||||
/// Optional numeric primary key.
|
||||
pub id: std::option::Option<i64>,
|
||||
/// Related token id.
|
||||
@@ -27,7 +27,7 @@ pub struct KbTokenMintEventDto {
|
||||
pub executed_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl KbTokenMintEventDto {
|
||||
impl TokenMintEventDto {
|
||||
/// Creates a new token mint event DTO.
|
||||
pub fn new(
|
||||
token_id: i64,
|
||||
@@ -54,15 +54,15 @@ impl KbTokenMintEventDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::KbTokenMintEventEntity> for KbTokenMintEventDto {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<crate::TokenMintEventEntity> for TokenMintEventDto {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(entity: crate::KbTokenMintEventEntity) -> Result<Self, Self::Error> {
|
||||
fn try_from(entity: crate::TokenMintEventEntity) -> 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!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse token mint event executed_at '{}': {}",
|
||||
entity.executed_at, error
|
||||
)));
|
||||
@@ -74,7 +74,7 @@ impl TryFrom<crate::KbTokenMintEventEntity> for KbTokenMintEventDto {
|
||||
match slot_result {
|
||||
Ok(slot) => Some(slot),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot convert token mint event slot '{}' to u64: {}",
|
||||
slot, error
|
||||
)));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Application-facing trade-event DTO.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbTradeEventDto {
|
||||
pub struct TradeEventDto {
|
||||
/// Optional numeric primary key.
|
||||
pub id: std::option::Option<i64>,
|
||||
/// Related DEX id.
|
||||
@@ -22,7 +22,7 @@ pub struct KbTradeEventDto {
|
||||
/// Optional observed slot.
|
||||
pub slot: std::option::Option<i64>,
|
||||
/// Stable trade side.
|
||||
pub trade_side: crate::KbSwapTradeSide,
|
||||
pub trade_side: crate::SwapTradeSide,
|
||||
/// Related base token id.
|
||||
pub base_token_id: i64,
|
||||
/// Related quote token id.
|
||||
@@ -34,7 +34,7 @@ pub struct KbTradeEventDto {
|
||||
/// Optional derived quote-per-base price.
|
||||
pub price_quote_per_base: std::option::Option<f64>,
|
||||
/// Observation source kind.
|
||||
pub source_kind: crate::KbObservationSourceKind,
|
||||
pub source_kind: crate::ObservationSourceKind,
|
||||
/// Optional logical source endpoint name.
|
||||
pub source_endpoint_name: std::option::Option<std::string::String>,
|
||||
/// Persisted payload JSON.
|
||||
@@ -45,7 +45,7 @@ pub struct KbTradeEventDto {
|
||||
pub updated_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl KbTradeEventDto {
|
||||
impl TradeEventDto {
|
||||
/// Creates a new trade-event DTO.
|
||||
pub fn new(
|
||||
dex_id: i64,
|
||||
@@ -55,13 +55,13 @@ impl KbTradeEventDto {
|
||||
decoded_event_id: i64,
|
||||
signature: std::string::String,
|
||||
slot: std::option::Option<i64>,
|
||||
trade_side: crate::KbSwapTradeSide,
|
||||
trade_side: crate::SwapTradeSide,
|
||||
base_token_id: i64,
|
||||
quote_token_id: i64,
|
||||
base_amount_raw: std::option::Option<std::string::String>,
|
||||
quote_amount_raw: std::option::Option<std::string::String>,
|
||||
price_quote_per_base: std::option::Option<f64>,
|
||||
source_kind: crate::KbObservationSourceKind,
|
||||
source_kind: crate::ObservationSourceKind,
|
||||
source_endpoint_name: std::option::Option<std::string::String>,
|
||||
payload_json: std::string::String,
|
||||
) -> Self {
|
||||
@@ -90,12 +90,12 @@ impl KbTradeEventDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::KbTradeEventEntity> for KbTradeEventDto {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<crate::TradeEventEntity> for TradeEventDto {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(entity: crate::KbTradeEventEntity) -> Result<Self, Self::Error> {
|
||||
let trade_side = kb_trade_side_from_string(entity.trade_side.as_str());
|
||||
let source_kind_result = crate::KbObservationSourceKind::from_i16(entity.source_kind);
|
||||
fn try_from(entity: crate::TradeEventEntity) -> Result<Self, Self::Error> {
|
||||
let trade_side = trade_side_from_string(entity.trade_side.as_str());
|
||||
let source_kind_result = crate::ObservationSourceKind::from_i16(entity.source_kind);
|
||||
let source_kind = match source_kind_result {
|
||||
Ok(source_kind) => source_kind,
|
||||
Err(error) => return Err(error),
|
||||
@@ -104,7 +104,7 @@ impl TryFrom<crate::KbTradeEventEntity> for KbTradeEventDto {
|
||||
let created_at = match created_at_result {
|
||||
Ok(created_at) => created_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse trade_event created_at '{}': {}",
|
||||
entity.created_at, error
|
||||
)));
|
||||
@@ -114,7 +114,7 @@ impl TryFrom<crate::KbTradeEventEntity> for KbTradeEventDto {
|
||||
let updated_at = match updated_at_result {
|
||||
Ok(updated_at) => updated_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse trade_event updated_at '{}': {}",
|
||||
entity.updated_at, error
|
||||
)));
|
||||
@@ -144,10 +144,10 @@ impl TryFrom<crate::KbTradeEventEntity> for KbTradeEventDto {
|
||||
}
|
||||
}
|
||||
|
||||
fn kb_trade_side_from_string(value: &str) -> crate::KbSwapTradeSide {
|
||||
fn trade_side_from_string(value: &str) -> crate::SwapTradeSide {
|
||||
match value {
|
||||
"BuyBase" => return crate::KbSwapTradeSide::BuyBase,
|
||||
"SellBase" => return crate::KbSwapTradeSide::SellBase,
|
||||
_ => return crate::KbSwapTradeSide::Unknown,
|
||||
"BuyBase" => return crate::SwapTradeSide::BuyBase,
|
||||
"SellBase" => return crate::SwapTradeSide::SellBase,
|
||||
_ => return crate::SwapTradeSide::Unknown,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Application-facing wallet DTO.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbWalletDto {
|
||||
pub struct WalletDto {
|
||||
/// Optional numeric primary key.
|
||||
pub id: std::option::Option<i64>,
|
||||
/// Stable wallet address.
|
||||
@@ -17,7 +17,7 @@ pub struct KbWalletDto {
|
||||
pub last_seen_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl KbWalletDto {
|
||||
impl WalletDto {
|
||||
/// Creates a new wallet DTO.
|
||||
pub fn new(
|
||||
address: std::string::String,
|
||||
@@ -34,15 +34,15 @@ impl KbWalletDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::KbWalletEntity> for KbWalletDto {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<crate::WalletEntity> for WalletDto {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(entity: crate::KbWalletEntity) -> Result<Self, Self::Error> {
|
||||
fn try_from(entity: crate::WalletEntity) -> Result<Self, Self::Error> {
|
||||
let first_seen_at_result = chrono::DateTime::parse_from_rfc3339(&entity.first_seen_at);
|
||||
let first_seen_at = match first_seen_at_result {
|
||||
Ok(first_seen_at) => first_seen_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse wallet first_seen_at '{}': {}",
|
||||
entity.first_seen_at, error
|
||||
)));
|
||||
@@ -52,7 +52,7 @@ impl TryFrom<crate::KbWalletEntity> for KbWalletDto {
|
||||
let last_seen_at = match last_seen_at_result {
|
||||
Ok(last_seen_at) => last_seen_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse wallet last_seen_at '{}': {}",
|
||||
entity.last_seen_at, error
|
||||
)));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Application-facing wallet-holding DTO.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbWalletHoldingDto {
|
||||
pub struct WalletHoldingDto {
|
||||
/// Optional numeric primary key.
|
||||
pub id: std::option::Option<i64>,
|
||||
/// Related wallet id.
|
||||
@@ -28,7 +28,7 @@ pub struct KbWalletHoldingDto {
|
||||
/// Optional last observed slot.
|
||||
pub last_slot_observed: std::option::Option<i64>,
|
||||
/// Observation source kind.
|
||||
pub source_kind: crate::KbObservationSourceKind,
|
||||
pub source_kind: crate::ObservationSourceKind,
|
||||
/// Optional logical source endpoint name.
|
||||
pub source_endpoint_name: std::option::Option<std::string::String>,
|
||||
/// Creation timestamp.
|
||||
@@ -37,7 +37,7 @@ pub struct KbWalletHoldingDto {
|
||||
pub updated_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl KbWalletHoldingDto {
|
||||
impl WalletHoldingDto {
|
||||
/// Creates a new wallet-holding DTO.
|
||||
pub fn new(
|
||||
wallet_id: i64,
|
||||
@@ -50,7 +50,7 @@ impl KbWalletHoldingDto {
|
||||
last_role: std::option::Option<std::string::String>,
|
||||
balance_raw: std::option::Option<std::string::String>,
|
||||
last_slot_observed: std::option::Option<i64>,
|
||||
source_kind: crate::KbObservationSourceKind,
|
||||
source_kind: crate::ObservationSourceKind,
|
||||
source_endpoint_name: std::option::Option<std::string::String>,
|
||||
) -> Self {
|
||||
let now = chrono::Utc::now();
|
||||
@@ -74,11 +74,11 @@ impl KbWalletHoldingDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::KbWalletHoldingEntity> for KbWalletHoldingDto {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<crate::WalletHoldingEntity> for WalletHoldingDto {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(entity: crate::KbWalletHoldingEntity) -> Result<Self, Self::Error> {
|
||||
let source_kind_result = crate::KbObservationSourceKind::from_i16(entity.source_kind);
|
||||
fn try_from(entity: crate::WalletHoldingEntity) -> Result<Self, Self::Error> {
|
||||
let source_kind_result = crate::ObservationSourceKind::from_i16(entity.source_kind);
|
||||
let source_kind = match source_kind_result {
|
||||
Ok(source_kind) => source_kind,
|
||||
Err(error) => return Err(error),
|
||||
@@ -87,7 +87,7 @@ impl TryFrom<crate::KbWalletHoldingEntity> for KbWalletHoldingDto {
|
||||
let created_at = match created_at_result {
|
||||
Ok(created_at) => created_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse wallet_holding created_at '{}': {}",
|
||||
entity.created_at, error
|
||||
)));
|
||||
@@ -97,7 +97,7 @@ impl TryFrom<crate::KbWalletHoldingEntity> for KbWalletHoldingDto {
|
||||
let updated_at = match updated_at_result {
|
||||
Ok(updated_at) => updated_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse wallet_holding updated_at '{}': {}",
|
||||
entity.updated_at, error
|
||||
)));
|
||||
@@ -119,6 +119,6 @@ impl TryFrom<crate::KbWalletHoldingEntity> for KbWalletHoldingDto {
|
||||
source_endpoint_name: entity.source_endpoint_name,
|
||||
created_at,
|
||||
updated_at,
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Application-facing wallet-participation DTO.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct KbWalletParticipationDto {
|
||||
pub struct WalletParticipationDto {
|
||||
/// Optional numeric primary key.
|
||||
pub id: std::option::Option<i64>,
|
||||
/// Related wallet id.
|
||||
@@ -22,7 +22,7 @@ pub struct KbWalletParticipationDto {
|
||||
/// Stable unique key used for idempotent upserts.
|
||||
pub unique_key: std::string::String,
|
||||
/// Observation source kind.
|
||||
pub source_kind: crate::KbObservationSourceKind,
|
||||
pub source_kind: crate::ObservationSourceKind,
|
||||
/// Optional logical source endpoint name.
|
||||
pub source_endpoint_name: std::option::Option<std::string::String>,
|
||||
/// Creation timestamp.
|
||||
@@ -31,7 +31,7 @@ pub struct KbWalletParticipationDto {
|
||||
pub updated_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl KbWalletParticipationDto {
|
||||
impl WalletParticipationDto {
|
||||
/// Creates a new wallet-participation DTO.
|
||||
pub fn new(
|
||||
wallet_id: i64,
|
||||
@@ -40,11 +40,11 @@ impl KbWalletParticipationDto {
|
||||
pool_id: std::option::Option<i64>,
|
||||
pair_id: std::option::Option<i64>,
|
||||
role: std::string::String,
|
||||
source_kind: crate::KbObservationSourceKind,
|
||||
source_kind: crate::ObservationSourceKind,
|
||||
source_endpoint_name: std::option::Option<std::string::String>,
|
||||
) -> Self {
|
||||
let now = chrono::Utc::now();
|
||||
let unique_key = kb_build_wallet_participation_unique_key(
|
||||
let unique_key = build_wallet_participation_unique_key(
|
||||
wallet_id,
|
||||
transaction_id,
|
||||
decoded_event_id,
|
||||
@@ -69,11 +69,11 @@ impl KbWalletParticipationDto {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::KbWalletParticipationEntity> for KbWalletParticipationDto {
|
||||
type Error = crate::KbError;
|
||||
impl TryFrom<crate::WalletParticipationEntity> for WalletParticipationDto {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(entity: crate::KbWalletParticipationEntity) -> Result<Self, Self::Error> {
|
||||
let source_kind_result = crate::KbObservationSourceKind::from_i16(entity.source_kind);
|
||||
fn try_from(entity: crate::WalletParticipationEntity) -> Result<Self, Self::Error> {
|
||||
let source_kind_result = crate::ObservationSourceKind::from_i16(entity.source_kind);
|
||||
let source_kind = match source_kind_result {
|
||||
Ok(source_kind) => source_kind,
|
||||
Err(error) => return Err(error),
|
||||
@@ -82,7 +82,7 @@ impl TryFrom<crate::KbWalletParticipationEntity> for KbWalletParticipationDto {
|
||||
let created_at = match created_at_result {
|
||||
Ok(created_at) => created_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse wallet_participation created_at '{}': {}",
|
||||
entity.created_at, error
|
||||
)));
|
||||
@@ -92,7 +92,7 @@ impl TryFrom<crate::KbWalletParticipationEntity> for KbWalletParticipationDto {
|
||||
let updated_at = match updated_at_result {
|
||||
Ok(updated_at) => updated_at.with_timezone(&chrono::Utc),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot parse wallet_participation updated_at '{}': {}",
|
||||
entity.updated_at, error
|
||||
)));
|
||||
@@ -115,7 +115,7 @@ impl TryFrom<crate::KbWalletParticipationEntity> for KbWalletParticipationDto {
|
||||
}
|
||||
}
|
||||
|
||||
fn kb_build_wallet_participation_unique_key(
|
||||
fn build_wallet_participation_unique_key(
|
||||
wallet_id: i64,
|
||||
transaction_id: i64,
|
||||
decoded_event_id: std::option::Option<i64>,
|
||||
|
||||
@@ -37,35 +37,35 @@ mod wallet;
|
||||
mod wallet_holding;
|
||||
mod wallet_participation;
|
||||
|
||||
pub use analysis_signal::KbAnalysisSignalEntity;
|
||||
pub use chain_instruction::KbChainInstructionEntity;
|
||||
pub use chain_slot::KbChainSlotEntity;
|
||||
pub use chain_transaction::KbChainTransactionEntity;
|
||||
pub use db_metadata::KbDbMetadataEntity;
|
||||
pub use db_runtime_event::KbDbRuntimeEventEntity;
|
||||
pub use dex::KbDexEntity;
|
||||
pub use dex_decoded_event::KbDexDecodedEventEntity;
|
||||
pub use known_http_endpoint::KbKnownHttpEndpointEntity;
|
||||
pub use known_ws_endpoint::KbKnownWsEndpointEntity;
|
||||
pub use launch_attribution::KbLaunchAttributionEntity;
|
||||
pub use launch_surface::KbLaunchSurfaceEntity;
|
||||
pub use launch_surface_key::KbLaunchSurfaceKeyEntity;
|
||||
pub use liquidity_event::KbLiquidityEventEntity;
|
||||
pub use observed_token::KbObservedTokenEntity;
|
||||
pub use onchain_observation::KbOnchainObservationEntity;
|
||||
pub use pair::KbPairEntity;
|
||||
pub use pair_analytic_signal::KbPairAnalyticSignalEntity;
|
||||
pub use pair_candle::KbPairCandleEntity;
|
||||
pub use pair_metric::KbPairMetricEntity;
|
||||
pub use pool::KbPoolEntity;
|
||||
pub use pool_listing::KbPoolListingEntity;
|
||||
pub use pool_origin::KbPoolOriginEntity;
|
||||
pub use pool_token::KbPoolTokenEntity;
|
||||
pub use swap::KbSwapEntity;
|
||||
pub use token::KbTokenEntity;
|
||||
pub use token_burn_event::KbTokenBurnEventEntity;
|
||||
pub use token_mint_event::KbTokenMintEventEntity;
|
||||
pub use trade_event::KbTradeEventEntity;
|
||||
pub use wallet::KbWalletEntity;
|
||||
pub use wallet_holding::KbWalletHoldingEntity;
|
||||
pub use wallet_participation::KbWalletParticipationEntity;
|
||||
pub use analysis_signal::AnalysisSignalEntity;
|
||||
pub use chain_instruction::ChainInstructionEntity;
|
||||
pub use chain_slot::ChainSlotEntity;
|
||||
pub use chain_transaction::ChainTransactionEntity;
|
||||
pub use db_metadata::DbMetadataEntity;
|
||||
pub use db_runtime_event::DbRuntimeEventEntity;
|
||||
pub use dex::DexEntity;
|
||||
pub use dex_decoded_event::DexDecodedEventEntity;
|
||||
pub use known_http_endpoint::KnownHttpEndpointEntity;
|
||||
pub use known_ws_endpoint::KnownWsEndpointEntity;
|
||||
pub use launch_attribution::LaunchAttributionEntity;
|
||||
pub use launch_surface::LaunchSurfaceEntity;
|
||||
pub use launch_surface_key::LaunchSurfaceKeyEntity;
|
||||
pub use liquidity_event::LiquidityEventEntity;
|
||||
pub use observed_token::ObservedTokenEntity;
|
||||
pub use onchain_observation::OnchainObservationEntity;
|
||||
pub use pair::PairEntity;
|
||||
pub use pair_analytic_signal::PairAnalyticSignalEntity;
|
||||
pub use pair_candle::PairCandleEntity;
|
||||
pub use pair_metric::PairMetricEntity;
|
||||
pub use pool::PoolEntity;
|
||||
pub use pool_listing::PoolListingEntity;
|
||||
pub use pool_origin::PoolOriginEntity;
|
||||
pub use pool_token::PoolTokenEntity;
|
||||
pub use swap::SwapEntity;
|
||||
pub use token::TokenEntity;
|
||||
pub use token_burn_event::TokenBurnEventEntity;
|
||||
pub use token_mint_event::TokenMintEventEntity;
|
||||
pub use trade_event::TradeEventEntity;
|
||||
pub use wallet::WalletEntity;
|
||||
pub use wallet_holding::WalletHoldingEntity;
|
||||
pub use wallet_participation::WalletParticipationEntity;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Persisted analysis signal row.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct KbAnalysisSignalEntity {
|
||||
pub struct AnalysisSignalEntity {
|
||||
/// Numeric primary key.
|
||||
pub id: i64,
|
||||
/// Signal kind.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Persisted Solana instruction row.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct KbChainInstructionEntity {
|
||||
pub struct ChainInstructionEntity {
|
||||
/// Internal row id.
|
||||
pub id: i64,
|
||||
/// Parent transaction id.
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
|
||||
// file: kb_lib/src/db/entities/chain_slot.rs
|
||||
|
||||
//! Database entity for one observed Solana slot.
|
||||
|
||||
/// Persisted Solana slot row.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct KbChainSlotEntity {
|
||||
pub struct ChainSlotEntity {
|
||||
/// Slot number.
|
||||
pub slot: i64,
|
||||
/// Optional parent slot number.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Persisted Solana transaction row.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct KbChainTransactionEntity {
|
||||
pub struct ChainTransactionEntity {
|
||||
/// Internal row id.
|
||||
pub id: i64,
|
||||
/// Transaction signature.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Persisted metadata row.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct KbDbMetadataEntity {
|
||||
pub struct DbMetadataEntity {
|
||||
/// Metadata key.
|
||||
pub key: std::string::String,
|
||||
/// Metadata value.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Persisted runtime event row.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct KbDbRuntimeEventEntity {
|
||||
pub struct DbRuntimeEventEntity {
|
||||
/// Numeric primary key.
|
||||
pub id: i64,
|
||||
/// Event kind.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Persisted normalized DEX row.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct KbDexEntity {
|
||||
pub struct DexEntity {
|
||||
/// Numeric primary key.
|
||||
pub id: i64,
|
||||
/// Stable short code.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Persisted decoded DEX event row.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct KbDexDecodedEventEntity {
|
||||
pub struct DexDecodedEventEntity {
|
||||
/// Internal row id.
|
||||
pub id: i64,
|
||||
/// Parent transaction id.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Persisted known HTTP endpoint row.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct KbKnownHttpEndpointEntity {
|
||||
pub struct KnownHttpEndpointEntity {
|
||||
/// Logical endpoint name.
|
||||
pub name: std::string::String,
|
||||
/// Provider name.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Persisted known WebSocket endpoint row.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct KbKnownWsEndpointEntity {
|
||||
pub struct KnownWsEndpointEntity {
|
||||
/// Logical endpoint name.
|
||||
pub name: std::string::String,
|
||||
/// Provider name.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Persisted launch attribution row.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct KbLaunchAttributionEntity {
|
||||
pub struct LaunchAttributionEntity {
|
||||
/// Numeric primary key.
|
||||
pub id: i64,
|
||||
/// Related launch surface id.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Persisted launch surface row.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct KbLaunchSurfaceEntity {
|
||||
pub struct LaunchSurfaceEntity {
|
||||
/// Numeric primary key.
|
||||
pub id: i64,
|
||||
/// Stable short code.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Persisted launch surface matching key row.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct KbLaunchSurfaceKeyEntity {
|
||||
pub struct LaunchSurfaceKeyEntity {
|
||||
/// Numeric primary key.
|
||||
pub id: i64,
|
||||
/// Related launch surface id.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Persisted normalized liquidity event row.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct KbLiquidityEventEntity {
|
||||
pub struct LiquidityEventEntity {
|
||||
/// Numeric primary key.
|
||||
pub id: i64,
|
||||
/// Related DEX id.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Persisted observed token row.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct KbObservedTokenEntity {
|
||||
pub struct ObservedTokenEntity {
|
||||
/// Numeric primary key.
|
||||
pub id: i64,
|
||||
/// Token mint address.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Persisted on-chain observation row.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct KbOnchainObservationEntity {
|
||||
pub struct OnchainObservationEntity {
|
||||
/// Numeric primary key.
|
||||
pub id: i64,
|
||||
/// Observation kind.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Persisted normalized pair row.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct KbPairEntity {
|
||||
pub struct PairEntity {
|
||||
/// Numeric primary key.
|
||||
pub id: i64,
|
||||
/// Related DEX id.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Persisted pair-analytic-signal row.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct KbPairAnalyticSignalEntity {
|
||||
pub struct PairAnalyticSignalEntity {
|
||||
/// Numeric primary key.
|
||||
pub id: i64,
|
||||
/// Related pair id.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Persisted pair-candle row.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct KbPairCandleEntity {
|
||||
pub struct PairCandleEntity {
|
||||
/// Numeric primary key.
|
||||
pub id: i64,
|
||||
/// Related pair id.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Persisted pair-metric row.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct KbPairMetricEntity {
|
||||
pub struct PairMetricEntity {
|
||||
/// Numeric primary key.
|
||||
pub id: i64,
|
||||
/// Related pair id.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Persisted normalized pool row.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct KbPoolEntity {
|
||||
pub struct PoolEntity {
|
||||
/// Numeric primary key.
|
||||
pub id: i64,
|
||||
/// Related DEX id.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Persisted normalized pool listing row.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct KbPoolListingEntity {
|
||||
pub struct PoolListingEntity {
|
||||
/// Numeric primary key.
|
||||
pub id: i64,
|
||||
/// Related DEX id.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Persisted pool-origin row.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct KbPoolOriginEntity {
|
||||
pub struct PoolOriginEntity {
|
||||
/// Numeric primary key.
|
||||
pub id: i64,
|
||||
/// Related DEX id.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Persisted normalized pool token composition row.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct KbPoolTokenEntity {
|
||||
pub struct PoolTokenEntity {
|
||||
/// Numeric primary key.
|
||||
pub id: i64,
|
||||
/// Related pool id.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Persisted normalized swap row.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct KbSwapEntity {
|
||||
pub struct SwapEntity {
|
||||
/// Numeric primary key.
|
||||
pub id: i64,
|
||||
/// Related DEX id.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Persisted normalized token row.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct KbTokenEntity {
|
||||
pub struct TokenEntity {
|
||||
/// Numeric primary key.
|
||||
pub id: i64,
|
||||
/// Mint address.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Persisted normalized token burn event row.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct KbTokenBurnEventEntity {
|
||||
pub struct TokenBurnEventEntity {
|
||||
/// Numeric primary key.
|
||||
pub id: i64,
|
||||
/// Related token id.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Persisted normalized token mint event row.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct KbTokenMintEventEntity {
|
||||
pub struct TokenMintEventEntity {
|
||||
/// Numeric primary key.
|
||||
pub id: i64,
|
||||
/// Related token id.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Persisted trade-event row.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct KbTradeEventEntity {
|
||||
pub struct TradeEventEntity {
|
||||
/// Numeric primary key.
|
||||
pub id: i64,
|
||||
/// Related DEX id.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Persisted wallet row.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct KbWalletEntity {
|
||||
pub struct WalletEntity {
|
||||
/// Numeric primary key.
|
||||
pub id: i64,
|
||||
/// Stable wallet address.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Persisted wallet-holding row.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct KbWalletHoldingEntity {
|
||||
pub struct WalletHoldingEntity {
|
||||
/// Numeric primary key.
|
||||
pub id: i64,
|
||||
/// Related wallet id.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/// Persisted wallet-participation row.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, sqlx::FromRow)]
|
||||
pub struct KbWalletParticipationEntity {
|
||||
pub struct WalletParticipationEntity {
|
||||
/// Numeric primary key.
|
||||
pub id: i64,
|
||||
/// Related wallet id.
|
||||
|
||||
@@ -2,10 +2,6 @@
|
||||
|
||||
//! Database queries.
|
||||
|
||||
// file: kb_lib/src/db/queries.rs
|
||||
|
||||
//! Database queries.
|
||||
|
||||
mod analysis_signal;
|
||||
mod chain_instruction;
|
||||
mod chain_slot;
|
||||
@@ -40,108 +36,110 @@ mod wallet;
|
||||
mod wallet_holding;
|
||||
mod wallet_participation;
|
||||
|
||||
pub use analysis_signal::insert_analysis_signal;
|
||||
pub use analysis_signal::list_recent_analysis_signals;
|
||||
pub use chain_instruction::delete_chain_instructions_by_transaction_id;
|
||||
pub use chain_instruction::get_chain_instruction_by_id;
|
||||
pub use chain_instruction::insert_chain_instruction;
|
||||
pub use chain_instruction::list_chain_instructions_by_transaction_id;
|
||||
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;
|
||||
pub use db_metadata::list_db_metadata;
|
||||
pub use db_metadata::upsert_db_metadata;
|
||||
pub use db_runtime_event::insert_db_runtime_event;
|
||||
pub use db_runtime_event::list_recent_db_runtime_events;
|
||||
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;
|
||||
pub use known_http_endpoint::list_known_http_endpoints;
|
||||
pub use known_http_endpoint::upsert_known_http_endpoint;
|
||||
pub use known_ws_endpoint::get_known_ws_endpoint;
|
||||
pub use known_ws_endpoint::list_known_ws_endpoints;
|
||||
pub use known_ws_endpoint::upsert_known_ws_endpoint;
|
||||
pub use launch_attribution::get_launch_attribution_by_decoded_event_id;
|
||||
pub use launch_attribution::list_launch_attributions_by_pool_id;
|
||||
pub use launch_attribution::upsert_launch_attribution;
|
||||
pub use launch_surface::get_launch_surface_by_code;
|
||||
pub use launch_surface::list_launch_surfaces;
|
||||
pub use launch_surface::upsert_launch_surface;
|
||||
pub use launch_surface_key::get_launch_surface_key_by_match;
|
||||
pub use launch_surface_key::list_launch_surface_keys_by_surface_id;
|
||||
pub use launch_surface_key::upsert_launch_surface_key;
|
||||
pub use liquidity_event::list_recent_liquidity_events;
|
||||
pub use liquidity_event::upsert_liquidity_event;
|
||||
pub use local_pipeline_diagnostics::get_local_pipeline_diagnostic_counters;
|
||||
pub use local_pipeline_diagnostics::list_local_decoded_event_diagnostic_summaries;
|
||||
pub use local_pipeline_diagnostics::list_local_dex_diagnostic_summaries;
|
||||
pub use local_pipeline_diagnostics::list_local_duplicate_decoded_event_trade_diagnostic_samples;
|
||||
pub use local_pipeline_diagnostics::list_local_missing_trade_event_diagnostic_samples;
|
||||
pub use local_pipeline_diagnostics::list_local_multi_trade_signature_pair_diagnostic_samples;
|
||||
pub use local_pipeline_diagnostics::list_local_pair_diagnostic_summaries;
|
||||
pub use local_pipeline_diagnostics::list_local_pair_without_candle_diagnostic_samples;
|
||||
pub use local_pipeline_diagnostics::list_local_pair_without_trade_diagnostic_samples;
|
||||
pub use observed_token::get_observed_token_by_mint;
|
||||
pub use observed_token::list_observed_tokens;
|
||||
pub use observed_token::upsert_observed_token;
|
||||
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;
|
||||
pub use pair_analytic_signal::upsert_pair_analytic_signal;
|
||||
pub use pair_candle::get_pair_candle_by_key;
|
||||
pub use pair_candle::list_pair_candles_by_pair_and_timeframe;
|
||||
pub use pair_candle::upsert_pair_candle;
|
||||
pub use pair_metric::get_pair_metric_by_pair_id;
|
||||
pub use pair_metric::list_pair_metrics;
|
||||
pub use pair_metric::upsert_pair_metric;
|
||||
pub use pool::get_pool_by_address;
|
||||
pub use pool::list_pools;
|
||||
pub use pool::upsert_pool;
|
||||
pub use pool_listing::get_pool_listing_by_pool_id;
|
||||
pub use pool_listing::list_pool_listings;
|
||||
pub use pool_listing::upsert_pool_listing;
|
||||
pub use pool_origin::get_pool_origin_by_pool_id;
|
||||
pub use pool_origin::list_pool_origins;
|
||||
pub use pool_origin::upsert_pool_origin;
|
||||
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;
|
||||
pub use token_mint_event::list_recent_token_mint_events;
|
||||
pub use token_mint_event::upsert_token_mint_event;
|
||||
pub use trade_event::get_trade_event_by_decoded_event_id;
|
||||
pub use trade_event::list_trade_events_by_pair_id;
|
||||
pub use trade_event::list_trade_events_by_transaction_id;
|
||||
pub use trade_event::upsert_trade_event;
|
||||
pub use wallet::get_wallet_by_address;
|
||||
pub use wallet::list_wallets;
|
||||
pub use wallet::upsert_wallet;
|
||||
pub use wallet_holding::get_wallet_holding_by_wallet_and_token;
|
||||
pub use wallet_holding::list_wallet_holdings_by_wallet_id;
|
||||
pub use wallet_holding::upsert_wallet_holding;
|
||||
pub use wallet_participation::get_wallet_participation_by_unique_key;
|
||||
pub use wallet_participation::list_wallet_participations_by_pool_id;
|
||||
pub use wallet_participation::list_wallet_participations_by_wallet_id;
|
||||
pub use wallet_participation::upsert_wallet_participation;
|
||||
pub use analysis_signal::query_analysis_signals_insert;
|
||||
pub use analysis_signal::query_analysis_signals_list;
|
||||
pub use chain_instruction::query_chain_instructions_delete_by_transaction_id;
|
||||
pub use chain_instruction::query_chain_instructions_get_by_id;
|
||||
pub use chain_instruction::query_chain_instructions_insert;
|
||||
pub use chain_instruction::query_chain_instructions_list_by_transaction_id;
|
||||
pub use chain_slot::query_chain_slots_get;
|
||||
pub use chain_slot::query_chain_slots_list_recent;
|
||||
pub use chain_slot::query_chain_slots_upsert;
|
||||
pub use chain_transaction::query_chain_transactions_get_by_signature;
|
||||
pub use chain_transaction::query_chain_transactions_list_recent;
|
||||
pub use chain_transaction::query_chain_transactions_list_signatures_for_replay;
|
||||
pub use chain_transaction::query_chain_transactions_upsert;
|
||||
pub use db_metadata::query_db_metadatas_get;
|
||||
pub use db_metadata::query_db_metadatas_list;
|
||||
pub use db_metadata::query_db_metadatas_upsert;
|
||||
pub use db_runtime_event::query_db_runtime_events_insert;
|
||||
pub use db_runtime_event::query_db_runtime_events_list_recent;
|
||||
pub use dex::query_dexs_get_by_code;
|
||||
pub use dex::query_dexs_list;
|
||||
pub use dex::query_dexs_upsert;
|
||||
pub use dex_decoded_event::query_dex_decoded_events_get_by_key;
|
||||
pub use dex_decoded_event::query_dex_decoded_events_get_latest_pump_fun_create_payload_by_mint;
|
||||
pub use dex_decoded_event::query_dex_decoded_events_list_by_transaction_id;
|
||||
pub use dex_decoded_event::query_dex_decoded_events_upsert;
|
||||
pub use known_http_endpoint::query_known_http_endpoints_get;
|
||||
pub use known_http_endpoint::query_known_http_endpoints_list;
|
||||
pub use known_http_endpoint::query_known_http_endpoints_upsert;
|
||||
pub use known_ws_endpoint::query_known_ws_endpoints_get;
|
||||
pub use known_ws_endpoint::query_known_ws_endpoints_list;
|
||||
pub use known_ws_endpoint::query_known_ws_endpoints_upsert;
|
||||
pub use launch_attribution::query_launch_attributions_get_by_decoded_event_id;
|
||||
pub use launch_attribution::query_launch_attributions_list_by_pool_id;
|
||||
pub use launch_attribution::query_launch_attributions_upsert;
|
||||
pub use launch_surface::query_launch_surfaces_get_by_code;
|
||||
pub use launch_surface::query_launch_surfaces_list;
|
||||
pub use launch_surface::query_launch_surfaces_upsert;
|
||||
pub use launch_surface_key::query_launch_surface_keys_get_by_match;
|
||||
pub use launch_surface_key::query_launch_surface_keys_list_by_surface_id;
|
||||
pub use launch_surface_key::query_launch_surface_keys_upsert;
|
||||
pub use liquidity_event::query_liquidity_events_list_recent;
|
||||
pub use liquidity_event::query_liquidity_events_upsert;
|
||||
pub use local_pipeline_diagnostics::query_local_decoded_event_diagnostic_list_summaries;
|
||||
pub use local_pipeline_diagnostics::query_local_duplicate_decoded_event_trade_diagnostic_list_samples;
|
||||
pub use local_pipeline_diagnostics::query_local_missing_trade_event_diagnostic_list_samples;
|
||||
pub use local_pipeline_diagnostics::query_local_missing_trade_event_reason_list_summaries;
|
||||
pub use local_pipeline_diagnostics::query_local_multi_trade_signature_pair_diagnostic_list_samples;
|
||||
pub use local_pipeline_diagnostics::query_local_non_actionable_pair_diagnostic_list_summaries;
|
||||
pub use local_pipeline_diagnostics::query_local_pair_diagnostic_list_summaries;
|
||||
pub use local_pipeline_diagnostics::query_local_pair_without_candle_diagnostic_list_samples;
|
||||
pub use local_pipeline_diagnostics::query_local_pair_without_trade_diagnostic_list_samples;
|
||||
pub use local_pipeline_diagnostics::query_local_pipeline_diagnostic_get_counters;
|
||||
pub use local_pipeline_diagnostics::query_local_pipeline_diagnostic_list_summaries;
|
||||
pub use observed_token::query_observed_tokens_get_by_mint;
|
||||
pub use observed_token::query_observed_tokens_list;
|
||||
pub use observed_token::query_observed_tokens_upsert;
|
||||
pub use onchain_observation::query_onchain_observations_insert;
|
||||
pub use onchain_observation::query_onchain_observations_list_recent;
|
||||
pub use pair::query_pairs_get_by_pool_id;
|
||||
pub use pair::query_pairs_list;
|
||||
pub use pair::query_pairs_update_symbol;
|
||||
pub use pair::query_pairs_upsert;
|
||||
pub use pair_analytic_signal::query_pair_analytic_signals_get_by_key;
|
||||
pub use pair_analytic_signal::query_pair_analytic_signals_list_by_pair_id;
|
||||
pub use pair_analytic_signal::query_pair_analytic_signals_upsert;
|
||||
pub use pair_candle::query_pair_candles_get_by_key;
|
||||
pub use pair_candle::query_pair_candles_list_by_pair_and_timeframe;
|
||||
pub use pair_candle::query_pair_candles_upsert;
|
||||
pub use pair_metric::query_pair_metrics_get_by_pair_id;
|
||||
pub use pair_metric::query_pair_metrics_list;
|
||||
pub use pair_metric::query_pair_metrics_upsert;
|
||||
pub use pool::query_pools_get_by_address;
|
||||
pub use pool::query_pools_list;
|
||||
pub use pool::query_pools_upsert;
|
||||
pub use pool_listing::query_pool_listings_get_by_pool_id;
|
||||
pub use pool_listing::query_pool_listings_list;
|
||||
pub use pool_listing::query_pool_listings_upsert;
|
||||
pub use pool_origin::query_pool_origins_get_by_pool_id;
|
||||
pub use pool_origin::query_pool_origins_list;
|
||||
pub use pool_origin::query_pool_origins_upsert;
|
||||
pub use pool_token::query_pool_tokens_list_by_pool_id;
|
||||
pub use pool_token::query_pool_tokens_upsert;
|
||||
pub use swap::query_swaps_list_recent;
|
||||
pub use swap::query_swaps_upsert;
|
||||
pub use token::query_tokens_get_by_id;
|
||||
pub use token::query_tokens_get_by_mint;
|
||||
pub use token::query_tokens_list;
|
||||
pub use token::query_tokens_list_missing_metadata;
|
||||
pub use token::query_tokens_upsert;
|
||||
pub use token_burn_event::query_token_burn_events_list_recent;
|
||||
pub use token_burn_event::query_token_burn_events_upsert;
|
||||
pub use token_mint_event::query_token_mint_events_list_recent;
|
||||
pub use token_mint_event::query_token_mint_events_upsert;
|
||||
pub use trade_event::query_trade_events_get_by_decoded_event_id;
|
||||
pub use trade_event::query_trade_events_list_by_pair_id;
|
||||
pub use trade_event::query_trade_events_list_by_transaction_id;
|
||||
pub use trade_event::query_trade_events_upsert;
|
||||
pub use wallet::query_wallets_get_by_address;
|
||||
pub use wallet::query_wallets_list;
|
||||
pub use wallet::query_wallets_upsert;
|
||||
pub use wallet_holding::query_wallet_holdings_get_by_wallet_and_token;
|
||||
pub use wallet_holding::query_wallet_holdings_list_by_wallet_id;
|
||||
pub use wallet_holding::query_wallet_holdings_upsert;
|
||||
pub use wallet_participation::query_wallet_participations_get_by_unique_key;
|
||||
pub use wallet_participation::query_wallet_participations_list_by_pool_id;
|
||||
pub use wallet_participation::query_wallet_participations_list_by_wallet_id;
|
||||
pub use wallet_participation::query_wallet_participations_upsert;
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
// file: kb_lib/src/db/queries/analysis_signal.rs
|
||||
|
||||
//! Queries for `kb_analysis_signals`.
|
||||
//! Queries for `k_sol_analysis_signals`.
|
||||
|
||||
/// Inserts one analysis signal row and returns its numeric id.
|
||||
pub async fn insert_analysis_signal(
|
||||
database: &crate::KbDatabase,
|
||||
dto: &crate::KbAnalysisSignalDto,
|
||||
) -> Result<i64, crate::KbError> {
|
||||
pub async fn query_analysis_signals_insert(
|
||||
database: &crate::Database,
|
||||
dto: &crate::AnalysisSignalDto,
|
||||
) -> Result<i64, crate::Error> {
|
||||
let payload_json_result = serde_json::to_string(&dto.payload);
|
||||
let payload_json = match payload_json_result {
|
||||
Ok(payload_json) => payload_json,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot serialize analysis signal payload: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
};
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query(
|
||||
r#"
|
||||
INSERT INTO kb_analysis_signals (
|
||||
INSERT INTO k_sol_analysis_signals (
|
||||
signal_kind,
|
||||
severity,
|
||||
object_key,
|
||||
@@ -45,8 +45,8 @@ VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
let query_result = match query_result {
|
||||
Ok(query_result) => query_result,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot insert kb_analysis_signals on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot insert k_sol_analysis_signals on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
@@ -57,16 +57,16 @@ VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
}
|
||||
|
||||
/// Lists recent analysis signals ordered from newest to oldest.
|
||||
pub async fn list_recent_analysis_signals(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_analysis_signals_list(
|
||||
database: &crate::Database,
|
||||
limit: u32,
|
||||
) -> Result<std::vec::Vec<crate::KbAnalysisSignalDto>, crate::KbError> {
|
||||
) -> Result<std::vec::Vec<crate::AnalysisSignalDto>, crate::Error> {
|
||||
if limit == 0 {
|
||||
return Ok(std::vec::Vec::new());
|
||||
}
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbAnalysisSignalEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::AnalysisSignalEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -77,7 +77,7 @@ SELECT
|
||||
score,
|
||||
payload_json,
|
||||
created_at
|
||||
FROM kb_analysis_signals
|
||||
FROM k_sol_analysis_signals
|
||||
ORDER BY id DESC
|
||||
LIMIT ?
|
||||
"#,
|
||||
@@ -88,7 +88,7 @@ LIMIT ?
|
||||
let entities = match query_result {
|
||||
Ok(entities) => entities,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot list analysis signals on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
@@ -96,7 +96,7 @@ LIMIT ?
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
let dto_result = crate::KbAnalysisSignalDto::try_from(entity);
|
||||
let dto_result = crate::AnalysisSignalDto::try_from(entity);
|
||||
let dto = match dto_result {
|
||||
Ok(dto) => dto,
|
||||
Err(error) => return Err(error),
|
||||
@@ -114,10 +114,10 @@ mod tests {
|
||||
async fn analysis_signal_roundtrip_works() {
|
||||
let tempdir = tempfile::tempdir().expect("tempdir must succeed");
|
||||
let database_path = tempdir.path().join("analysis_signal.sqlite3");
|
||||
let config = crate::KbDatabaseConfig {
|
||||
let config = crate::DatabaseConfig {
|
||||
enabled: true,
|
||||
backend: crate::KbDatabaseBackend::Sqlite,
|
||||
sqlite: crate::KbSqliteDatabaseConfig {
|
||||
backend: crate::DatabaseBackend::Sqlite,
|
||||
sqlite: crate::SqliteDatabaseConfig {
|
||||
path: database_path.to_string_lossy().to_string(),
|
||||
create_if_missing: true,
|
||||
busy_timeout_ms: 5000,
|
||||
@@ -126,29 +126,29 @@ mod tests {
|
||||
use_wal: true,
|
||||
},
|
||||
};
|
||||
let database = crate::KbDatabase::connect_and_initialize(&config)
|
||||
let database = crate::Database::connect_and_initialize(&config)
|
||||
.await
|
||||
.expect("database init must succeed");
|
||||
let dto = crate::KbAnalysisSignalDto::new(
|
||||
let dto = crate::AnalysisSignalDto::new(
|
||||
"candidate_token".to_string(),
|
||||
crate::KbAnalysisSignalSeverity::Medium,
|
||||
"So11111111111111111111111111111111111111112".to_string(),
|
||||
crate::AnalysisSignalSeverity::Medium,
|
||||
crate::WSOL_MINT_ID.to_string(),
|
||||
None,
|
||||
Some(0.72),
|
||||
serde_json::json!({
|
||||
"reason": "fresh_token_with_activity"
|
||||
}),
|
||||
);
|
||||
let inserted_id = crate::insert_analysis_signal(&database, &dto)
|
||||
let inserted_id = crate::query_analysis_signals_insert(&database, &dto)
|
||||
.await
|
||||
.expect("insert must succeed");
|
||||
assert!(inserted_id > 0);
|
||||
let listed = crate::list_recent_analysis_signals(&database, 10)
|
||||
let listed = crate::query_analysis_signals_list(&database, 10)
|
||||
.await
|
||||
.expect("list must succeed");
|
||||
assert_eq!(listed.len(), 1);
|
||||
assert_eq!(listed[0].signal_kind, "candidate_token");
|
||||
assert_eq!(listed[0].severity, crate::KbAnalysisSignalSeverity::Medium);
|
||||
assert_eq!(listed[0].severity, crate::AnalysisSignalSeverity::Medium);
|
||||
assert_eq!(listed[0].score, Some(0.72));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
// file: kb_lib/src/db/queries/chain_instruction.rs
|
||||
|
||||
//! Queries for `kb_chain_instructions`.
|
||||
//! Queries for `k_sol_chain_instructions`.
|
||||
|
||||
/// Inserts one normalized chain instruction row.
|
||||
pub async fn insert_chain_instruction(
|
||||
database: &crate::KbDatabase,
|
||||
dto: &crate::KbChainInstructionDto,
|
||||
) -> Result<i64, crate::KbError> {
|
||||
pub async fn query_chain_instructions_insert(
|
||||
database: &crate::Database,
|
||||
dto: &crate::ChainInstructionDto,
|
||||
) -> Result<i64, crate::Error> {
|
||||
let instruction_index_result = i64::from(dto.instruction_index);
|
||||
let inner_instruction_index = match dto.inner_instruction_index {
|
||||
Some(inner_instruction_index) => Some(i64::from(inner_instruction_index)),
|
||||
@@ -17,10 +17,10 @@ pub async fn insert_chain_instruction(
|
||||
None => None,
|
||||
};
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query(
|
||||
r#"
|
||||
INSERT INTO kb_chain_instructions (
|
||||
INSERT INTO k_sol_chain_instructions (
|
||||
transaction_id,
|
||||
parent_instruction_id,
|
||||
instruction_index,
|
||||
@@ -54,8 +54,8 @@ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
let insert_result = match query_result {
|
||||
Ok(insert_result) => insert_result,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot insert kb_chain_instructions on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot insert k_sol_chain_instructions on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
@@ -66,13 +66,13 @@ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
}
|
||||
|
||||
/// Reads one chain instruction by its internal id.
|
||||
pub async fn get_chain_instruction_by_id(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_chain_instructions_get_by_id(
|
||||
database: &crate::Database,
|
||||
instruction_id: i64,
|
||||
) -> Result<std::option::Option<crate::KbChainInstructionDto>, crate::KbError> {
|
||||
) -> Result<std::option::Option<crate::ChainInstructionDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbChainInstructionEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::ChainInstructionEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -88,7 +88,7 @@ SELECT
|
||||
parsed_type,
|
||||
parsed_json,
|
||||
created_at
|
||||
FROM kb_chain_instructions
|
||||
FROM k_sol_chain_instructions
|
||||
WHERE id = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -99,15 +99,15 @@ LIMIT 1
|
||||
let entity_option = match query_result {
|
||||
Ok(entity_option) => entity_option,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_chain_instructions id '{}' on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot fetch k_sol_chain_instructions id '{}' on sqlite: {}",
|
||||
instruction_id, error
|
||||
)));
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => {
|
||||
let dto_result = crate::KbChainInstructionDto::try_from(entity);
|
||||
let dto_result = crate::ChainInstructionDto::try_from(entity);
|
||||
match dto_result {
|
||||
Ok(dto) => return Ok(Some(dto)),
|
||||
Err(error) => return Err(error),
|
||||
@@ -120,13 +120,13 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Lists instructions for one transaction ordered from outer to inner.
|
||||
pub async fn list_chain_instructions_by_transaction_id(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_chain_instructions_list_by_transaction_id(
|
||||
database: &crate::Database,
|
||||
transaction_id: i64,
|
||||
) -> Result<std::vec::Vec<crate::KbChainInstructionDto>, crate::KbError> {
|
||||
) -> Result<std::vec::Vec<crate::ChainInstructionDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbChainInstructionEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::ChainInstructionEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -142,7 +142,7 @@ SELECT
|
||||
parsed_type,
|
||||
parsed_json,
|
||||
created_at
|
||||
FROM kb_chain_instructions
|
||||
FROM k_sol_chain_instructions
|
||||
WHERE transaction_id = ?
|
||||
ORDER BY instruction_index ASC, inner_instruction_index ASC, id ASC
|
||||
"#,
|
||||
@@ -153,15 +153,15 @@ ORDER BY instruction_index ASC, inner_instruction_index ASC, id ASC
|
||||
let entities = match query_result {
|
||||
Ok(entities) => entities,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot list kb_chain_instructions for transaction_id '{}' on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot list k_sol_chain_instructions for transaction_id '{}' on sqlite: {}",
|
||||
transaction_id, error
|
||||
)));
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
let dto_result = crate::KbChainInstructionDto::try_from(entity);
|
||||
let dto_result = crate::ChainInstructionDto::try_from(entity);
|
||||
let dto = match dto_result {
|
||||
Ok(dto) => dto,
|
||||
Err(error) => return Err(error),
|
||||
@@ -174,15 +174,15 @@ ORDER BY instruction_index ASC, inner_instruction_index ASC, id ASC
|
||||
}
|
||||
|
||||
/// Deletes all instructions for one transaction id.
|
||||
pub async fn delete_chain_instructions_by_transaction_id(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_chain_instructions_delete_by_transaction_id(
|
||||
database: &crate::Database,
|
||||
transaction_id: i64,
|
||||
) -> Result<(), crate::KbError> {
|
||||
) -> Result<(), crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query(
|
||||
r#"
|
||||
DELETE FROM kb_chain_instructions
|
||||
DELETE FROM k_sol_chain_instructions
|
||||
WHERE transaction_id = ?
|
||||
"#,
|
||||
)
|
||||
@@ -190,8 +190,8 @@ WHERE transaction_id = ?
|
||||
.execute(pool)
|
||||
.await;
|
||||
if let Err(error) = query_result {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot delete kb_chain_instructions for transaction_id '{}' on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot delete k_sol_chain_instructions for transaction_id '{}' on sqlite: {}",
|
||||
transaction_id, error
|
||||
)));
|
||||
}
|
||||
@@ -202,13 +202,13 @@ WHERE transaction_id = ?
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
async fn make_database() -> crate::KbDatabase {
|
||||
async fn make_database() -> crate::Database {
|
||||
let tempdir = tempfile::tempdir().expect("tempdir must succeed");
|
||||
let database_path = tempdir.path().join("chain_instruction.sqlite3");
|
||||
let config = crate::KbDatabaseConfig {
|
||||
let config = crate::DatabaseConfig {
|
||||
enabled: true,
|
||||
backend: crate::KbDatabaseBackend::Sqlite,
|
||||
sqlite: crate::KbSqliteDatabaseConfig {
|
||||
backend: crate::DatabaseBackend::Sqlite,
|
||||
sqlite: crate::SqliteDatabaseConfig {
|
||||
path: database_path.to_string_lossy().to_string(),
|
||||
create_if_missing: true,
|
||||
busy_timeout_ms: 5000,
|
||||
@@ -217,13 +217,13 @@ mod tests {
|
||||
use_wal: true,
|
||||
},
|
||||
};
|
||||
return crate::KbDatabase::connect_and_initialize(&config)
|
||||
return crate::Database::connect_and_initialize(&config)
|
||||
.await
|
||||
.expect("database init must succeed");
|
||||
}
|
||||
|
||||
async fn make_transaction(database: &crate::KbDatabase) -> i64 {
|
||||
let dto = crate::KbChainTransactionDto::new(
|
||||
async fn make_transaction(database: &crate::Database) -> i64 {
|
||||
let dto = crate::ChainTransactionDto::new(
|
||||
"sig-chain-instruction-1".to_string(),
|
||||
None,
|
||||
None,
|
||||
@@ -233,7 +233,7 @@ mod tests {
|
||||
None,
|
||||
r#"{"transaction":{"message":{"instructions":[]}}}"#.to_string(),
|
||||
);
|
||||
return crate::upsert_chain_transaction(database, &dto)
|
||||
return crate::query_chain_transactions_upsert(database, &dto)
|
||||
.await
|
||||
.expect("chain transaction upsert must succeed");
|
||||
}
|
||||
@@ -242,7 +242,7 @@ mod tests {
|
||||
async fn chain_instruction_insert_list_delete_works() {
|
||||
let database = make_database().await;
|
||||
let transaction_id = make_transaction(&database).await;
|
||||
let outer_dto = crate::KbChainInstructionDto::new(
|
||||
let outer_dto = crate::ChainInstructionDto::new(
|
||||
transaction_id,
|
||||
None,
|
||||
0,
|
||||
@@ -255,11 +255,11 @@ mod tests {
|
||||
Some("transfer".to_string()),
|
||||
Some(r#"{"type":"transfer","info":{"amount":"10"}}"#.to_string()),
|
||||
);
|
||||
let outer_instruction_id = crate::insert_chain_instruction(&database, &outer_dto)
|
||||
let outer_instruction_id = crate::query_chain_instructions_insert(&database, &outer_dto)
|
||||
.await
|
||||
.expect("outer instruction insert must succeed");
|
||||
assert!(outer_instruction_id > 0);
|
||||
let inner_dto = crate::KbChainInstructionDto::new(
|
||||
let inner_dto = crate::ChainInstructionDto::new(
|
||||
transaction_id,
|
||||
Some(outer_instruction_id),
|
||||
0,
|
||||
@@ -272,13 +272,14 @@ mod tests {
|
||||
Some("mintTo".to_string()),
|
||||
Some(r#"{"type":"mintTo","info":{"amount":"5"}}"#.to_string()),
|
||||
);
|
||||
let inner_instruction_id = crate::insert_chain_instruction(&database, &inner_dto)
|
||||
let inner_instruction_id = crate::query_chain_instructions_insert(&database, &inner_dto)
|
||||
.await
|
||||
.expect("inner instruction insert must succeed");
|
||||
assert!(inner_instruction_id > outer_instruction_id);
|
||||
let listed = crate::list_chain_instructions_by_transaction_id(&database, transaction_id)
|
||||
.await
|
||||
.expect("chain instruction list must succeed");
|
||||
let listed =
|
||||
crate::query_chain_instructions_list_by_transaction_id(&database, transaction_id)
|
||||
.await
|
||||
.expect("chain instruction list must succeed");
|
||||
assert_eq!(listed.len(), 2);
|
||||
assert_eq!(listed[0].parent_instruction_id, None);
|
||||
assert_eq!(listed[0].instruction_index, 0);
|
||||
@@ -288,11 +289,11 @@ mod tests {
|
||||
assert_eq!(listed[1].instruction_index, 0);
|
||||
assert_eq!(listed[1].inner_instruction_index, Some(0));
|
||||
assert_eq!(listed[1].parsed_type, Some("mintTo".to_string()));
|
||||
crate::delete_chain_instructions_by_transaction_id(&database, transaction_id)
|
||||
crate::query_chain_instructions_delete_by_transaction_id(&database, transaction_id)
|
||||
.await
|
||||
.expect("chain instruction delete must succeed");
|
||||
let listed_after_delete =
|
||||
crate::list_chain_instructions_by_transaction_id(&database, transaction_id)
|
||||
crate::query_chain_instructions_list_by_transaction_id(&database, transaction_id)
|
||||
.await
|
||||
.expect("chain instruction list after delete must succeed");
|
||||
assert_eq!(listed_after_delete.len(), 0);
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
// file: kb_lib/src/db/queries/chain_slot.rs
|
||||
|
||||
//! Queries for `kb_chain_slots`.
|
||||
//! Queries for `k_sol_chain_slots`.
|
||||
|
||||
/// Inserts or updates one normalized chain slot row.
|
||||
pub async fn upsert_chain_slot(
|
||||
database: &crate::KbDatabase,
|
||||
dto: &crate::KbChainSlotDto,
|
||||
) -> Result<u64, crate::KbError> {
|
||||
pub async fn query_chain_slots_upsert(
|
||||
database: &crate::Database,
|
||||
dto: &crate::ChainSlotDto,
|
||||
) -> Result<u64, crate::Error> {
|
||||
let slot_result = i64::try_from(dto.slot);
|
||||
let slot = match slot_result {
|
||||
Ok(slot) => slot,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot convert chain slot '{}' to i64: {}",
|
||||
dto.slot, error
|
||||
)));
|
||||
@@ -23,7 +23,7 @@ pub async fn upsert_chain_slot(
|
||||
match parent_slot_result {
|
||||
Ok(parent_slot) => Some(parent_slot),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot convert chain parent_slot '{}' to i64: {}",
|
||||
parent_slot, error
|
||||
)));
|
||||
@@ -33,10 +33,10 @@ pub async fn upsert_chain_slot(
|
||||
None => None,
|
||||
};
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query(
|
||||
r#"
|
||||
INSERT INTO kb_chain_slots (
|
||||
INSERT INTO k_sol_chain_slots (
|
||||
slot,
|
||||
parent_slot,
|
||||
block_time_unix,
|
||||
@@ -58,8 +58,8 @@ ON CONFLICT(slot) DO UPDATE SET
|
||||
.execute(pool)
|
||||
.await;
|
||||
if let Err(error) = query_result {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot upsert kb_chain_slots on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot upsert k_sol_chain_slots on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
@@ -69,23 +69,23 @@ ON CONFLICT(slot) DO UPDATE SET
|
||||
}
|
||||
|
||||
/// Reads one chain slot row by slot number.
|
||||
pub async fn get_chain_slot(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_chain_slots_get(
|
||||
database: &crate::Database,
|
||||
slot: u64,
|
||||
) -> Result<std::option::Option<crate::KbChainSlotDto>, crate::KbError> {
|
||||
) -> Result<std::option::Option<crate::ChainSlotDto>, crate::Error> {
|
||||
let slot_result = i64::try_from(slot);
|
||||
let slot_i64 = match slot_result {
|
||||
Ok(slot_i64) => slot_i64,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot convert requested chain slot '{}' to i64: {}",
|
||||
slot, error
|
||||
)));
|
||||
},
|
||||
};
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbChainSlotEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::ChainSlotEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
slot,
|
||||
@@ -93,7 +93,7 @@ SELECT
|
||||
block_time_unix,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM kb_chain_slots
|
||||
FROM k_sol_chain_slots
|
||||
WHERE slot = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -104,15 +104,15 @@ LIMIT 1
|
||||
let entity_option = match query_result {
|
||||
Ok(entity_option) => entity_option,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_chain_slots for slot '{}' on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot fetch k_sol_chain_slots for slot '{}' on sqlite: {}",
|
||||
slot, error
|
||||
)));
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => {
|
||||
let dto_result = crate::KbChainSlotDto::try_from(entity);
|
||||
let dto_result = crate::ChainSlotDto::try_from(entity);
|
||||
match dto_result {
|
||||
Ok(dto) => return Ok(Some(dto)),
|
||||
Err(error) => return Err(error),
|
||||
@@ -125,16 +125,16 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Lists recent chain slots ordered from newest to oldest.
|
||||
pub async fn list_recent_chain_slots(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_chain_slots_list_recent(
|
||||
database: &crate::Database,
|
||||
limit: u32,
|
||||
) -> Result<std::vec::Vec<crate::KbChainSlotDto>, crate::KbError> {
|
||||
) -> Result<std::vec::Vec<crate::ChainSlotDto>, crate::Error> {
|
||||
if limit == 0 {
|
||||
return Ok(std::vec::Vec::new());
|
||||
}
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbChainSlotEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::ChainSlotEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
slot,
|
||||
@@ -142,7 +142,7 @@ SELECT
|
||||
block_time_unix,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM kb_chain_slots
|
||||
FROM k_sol_chain_slots
|
||||
ORDER BY slot DESC
|
||||
LIMIT ?
|
||||
"#,
|
||||
@@ -153,15 +153,15 @@ LIMIT ?
|
||||
let entities = match query_result {
|
||||
Ok(entities) => entities,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot list kb_chain_slots on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot list k_sol_chain_slots on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
let dto_result = crate::KbChainSlotDto::try_from(entity);
|
||||
let dto_result = crate::ChainSlotDto::try_from(entity);
|
||||
let dto = match dto_result {
|
||||
Ok(dto) => dto,
|
||||
Err(error) => return Err(error),
|
||||
@@ -175,13 +175,13 @@ LIMIT ?
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
async fn make_database() -> crate::KbDatabase {
|
||||
async fn make_database() -> crate::Database {
|
||||
let tempdir = tempfile::tempdir().expect("tempdir must succeed");
|
||||
let database_path = tempdir.path().join("chain_slot.sqlite3");
|
||||
let config = crate::KbDatabaseConfig {
|
||||
let config = crate::DatabaseConfig {
|
||||
enabled: true,
|
||||
backend: crate::KbDatabaseBackend::Sqlite,
|
||||
sqlite: crate::KbSqliteDatabaseConfig {
|
||||
backend: crate::DatabaseBackend::Sqlite,
|
||||
sqlite: crate::SqliteDatabaseConfig {
|
||||
path: database_path.to_string_lossy().to_string(),
|
||||
create_if_missing: true,
|
||||
busy_timeout_ms: 5000,
|
||||
@@ -190,7 +190,7 @@ mod tests {
|
||||
use_wal: true,
|
||||
},
|
||||
};
|
||||
return crate::KbDatabase::connect_and_initialize(&config)
|
||||
return crate::Database::connect_and_initialize(&config)
|
||||
.await
|
||||
.expect("database init must succeed");
|
||||
}
|
||||
@@ -198,19 +198,19 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn chain_slot_roundtrip_works() {
|
||||
let database = make_database().await;
|
||||
let dto = crate::KbChainSlotDto::new(424242, Some(424241), Some(1_777_777_777));
|
||||
let slot = crate::upsert_chain_slot(&database, &dto)
|
||||
let dto = crate::ChainSlotDto::new(424242, Some(424241), Some(1_777_777_777));
|
||||
let slot = crate::query_chain_slots_upsert(&database, &dto)
|
||||
.await
|
||||
.expect("chain slot upsert must succeed");
|
||||
assert_eq!(slot, 424242);
|
||||
let fetched = crate::get_chain_slot(&database, 424242)
|
||||
let fetched = crate::query_chain_slots_get(&database, 424242)
|
||||
.await
|
||||
.expect("chain slot fetch must succeed")
|
||||
.expect("chain slot must exist");
|
||||
assert_eq!(fetched.slot, 424242);
|
||||
assert_eq!(fetched.parent_slot, Some(424241));
|
||||
assert_eq!(fetched.block_time_unix, Some(1_777_777_777));
|
||||
let listed = crate::list_recent_chain_slots(&database, 10)
|
||||
let listed = crate::query_chain_slots_list_recent(&database, 10)
|
||||
.await
|
||||
.expect("chain slot list must succeed");
|
||||
assert_eq!(listed.len(), 1);
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
// file: kb_lib/src/db/queries/chain_transaction.rs
|
||||
|
||||
//! Queries for `kb_chain_transactions`.
|
||||
//! Queries for `k_sol_chain_transactions`.
|
||||
|
||||
/// Inserts or updates one normalized chain transaction row.
|
||||
pub async fn upsert_chain_transaction(
|
||||
database: &crate::KbDatabase,
|
||||
dto: &crate::KbChainTransactionDto,
|
||||
) -> Result<i64, crate::KbError> {
|
||||
pub async fn query_chain_transactions_upsert(
|
||||
database: &crate::Database,
|
||||
dto: &crate::ChainTransactionDto,
|
||||
) -> Result<i64, crate::Error> {
|
||||
let slot_i64 = match dto.slot {
|
||||
Some(slot) => {
|
||||
let slot_result = i64::try_from(slot);
|
||||
match slot_result {
|
||||
Ok(slot) => Some(slot),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot convert chain transaction slot '{}' to i64: {}",
|
||||
slot, error
|
||||
)));
|
||||
@@ -23,10 +23,10 @@ pub async fn upsert_chain_transaction(
|
||||
None => None,
|
||||
};
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query(
|
||||
r#"
|
||||
INSERT INTO kb_chain_transactions (
|
||||
INSERT INTO k_sol_chain_transactions (
|
||||
signature,
|
||||
slot,
|
||||
block_time_unix,
|
||||
@@ -63,15 +63,15 @@ ON CONFLICT(signature) DO UPDATE SET
|
||||
.execute(pool)
|
||||
.await;
|
||||
if let Err(error) = query_result {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot upsert kb_chain_transactions on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot upsert k_sol_chain_transactions on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
let id_result = sqlx::query_scalar::<sqlx::Sqlite, i64>(
|
||||
r#"
|
||||
SELECT id
|
||||
FROM kb_chain_transactions
|
||||
FROM k_sol_chain_transactions
|
||||
WHERE signature = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -82,8 +82,8 @@ LIMIT 1
|
||||
match id_result {
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_chain_transactions id for signature '{}' on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot fetch k_sol_chain_transactions id for signature '{}' on sqlite: {}",
|
||||
dto.signature, error
|
||||
)));
|
||||
},
|
||||
@@ -93,13 +93,13 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Reads one chain transaction row by signature.
|
||||
pub async fn get_chain_transaction_by_signature(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_chain_transactions_get_by_signature(
|
||||
database: &crate::Database,
|
||||
signature: &str,
|
||||
) -> Result<std::option::Option<crate::KbChainTransactionDto>, crate::KbError> {
|
||||
) -> Result<std::option::Option<crate::ChainTransactionDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbChainTransactionEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::ChainTransactionEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -113,7 +113,7 @@ SELECT
|
||||
transaction_json,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM kb_chain_transactions
|
||||
FROM k_sol_chain_transactions
|
||||
WHERE signature = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -124,15 +124,15 @@ LIMIT 1
|
||||
let entity_option = match query_result {
|
||||
Ok(entity_option) => entity_option,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_chain_transactions for signature '{}' on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot fetch k_sol_chain_transactions for signature '{}' on sqlite: {}",
|
||||
signature, error
|
||||
)));
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => {
|
||||
let dto_result = crate::KbChainTransactionDto::try_from(entity);
|
||||
let dto_result = crate::ChainTransactionDto::try_from(entity);
|
||||
match dto_result {
|
||||
Ok(dto) => return Ok(Some(dto)),
|
||||
Err(error) => return Err(error),
|
||||
@@ -145,16 +145,16 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Lists recent chain transactions ordered from newest to oldest.
|
||||
pub async fn list_recent_chain_transactions(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_chain_transactions_list_recent(
|
||||
database: &crate::Database,
|
||||
limit: u32,
|
||||
) -> Result<std::vec::Vec<crate::KbChainTransactionDto>, crate::KbError> {
|
||||
) -> Result<std::vec::Vec<crate::ChainTransactionDto>, crate::Error> {
|
||||
if limit == 0 {
|
||||
return Ok(std::vec::Vec::new());
|
||||
}
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbChainTransactionEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::ChainTransactionEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -168,7 +168,7 @@ SELECT
|
||||
transaction_json,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM kb_chain_transactions
|
||||
FROM k_sol_chain_transactions
|
||||
ORDER BY id DESC
|
||||
LIMIT ?
|
||||
"#,
|
||||
@@ -179,15 +179,15 @@ LIMIT ?
|
||||
let entities = match query_result {
|
||||
Ok(entities) => entities,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot list kb_chain_transactions on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot list k_sol_chain_transactions on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
let dto_result = crate::KbChainTransactionDto::try_from(entity);
|
||||
let dto_result = crate::ChainTransactionDto::try_from(entity);
|
||||
let dto = match dto_result {
|
||||
Ok(dto) => dto,
|
||||
Err(error) => return Err(error),
|
||||
@@ -200,12 +200,12 @@ LIMIT ?
|
||||
}
|
||||
|
||||
/// Lists persisted chain transaction signatures for local pipeline replay.
|
||||
pub async fn list_chain_transaction_signatures_for_replay(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_chain_transactions_list_signatures_for_replay(
|
||||
database: &crate::Database,
|
||||
limit: std::option::Option<i64>,
|
||||
) -> Result<std::vec::Vec<std::string::String>, crate::KbError> {
|
||||
) -> Result<std::vec::Vec<std::string::String>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let effective_limit = match limit {
|
||||
Some(limit) => {
|
||||
if limit <= 0 {
|
||||
@@ -219,7 +219,7 @@ pub async fn list_chain_transaction_signatures_for_replay(
|
||||
let query_result = sqlx::query_scalar::<sqlx::Sqlite, std::string::String>(
|
||||
r#"
|
||||
SELECT signature
|
||||
FROM kb_chain_transactions
|
||||
FROM k_sol_chain_transactions
|
||||
ORDER BY id ASC
|
||||
LIMIT ?
|
||||
"#,
|
||||
@@ -230,8 +230,8 @@ LIMIT ?
|
||||
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: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot list k_sol_chain_transactions signatures for local replay on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
@@ -242,13 +242,13 @@ LIMIT ?
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
async fn make_database() -> crate::KbDatabase {
|
||||
async fn make_database() -> crate::Database {
|
||||
let tempdir = tempfile::tempdir().expect("tempdir must succeed");
|
||||
let database_path = tempdir.path().join("chain_transaction.sqlite3");
|
||||
let config = crate::KbDatabaseConfig {
|
||||
let config = crate::DatabaseConfig {
|
||||
enabled: true,
|
||||
backend: crate::KbDatabaseBackend::Sqlite,
|
||||
sqlite: crate::KbSqliteDatabaseConfig {
|
||||
backend: crate::DatabaseBackend::Sqlite,
|
||||
sqlite: crate::SqliteDatabaseConfig {
|
||||
path: database_path.to_string_lossy().to_string(),
|
||||
create_if_missing: true,
|
||||
busy_timeout_ms: 5000,
|
||||
@@ -257,7 +257,7 @@ mod tests {
|
||||
use_wal: true,
|
||||
},
|
||||
};
|
||||
return crate::KbDatabase::connect_and_initialize(&config)
|
||||
return crate::Database::connect_and_initialize(&config)
|
||||
.await
|
||||
.expect("database init must succeed");
|
||||
}
|
||||
@@ -265,11 +265,11 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn chain_transaction_roundtrip_works() {
|
||||
let database = make_database().await;
|
||||
let slot_dto = crate::KbChainSlotDto::new(515151, Some(515150), Some(1_700_000_001));
|
||||
crate::upsert_chain_slot(&database, &slot_dto)
|
||||
let slot_dto = crate::ChainSlotDto::new(515151, Some(515150), Some(1_700_000_001));
|
||||
crate::query_chain_slots_upsert(&database, &slot_dto)
|
||||
.await
|
||||
.expect("chain slot upsert must succeed");
|
||||
let dto = crate::KbChainTransactionDto::new(
|
||||
let dto = crate::ChainTransactionDto::new(
|
||||
"sig-chain-transaction-1".to_string(),
|
||||
Some(515151),
|
||||
Some(1_700_000_001),
|
||||
@@ -279,12 +279,12 @@ mod tests {
|
||||
Some(r#"{"fee":5000}"#.to_string()),
|
||||
r#"{"slot":515151,"transaction":{"message":{"instructions":[]}}}"#.to_string(),
|
||||
);
|
||||
let transaction_id = crate::upsert_chain_transaction(&database, &dto)
|
||||
let transaction_id = crate::query_chain_transactions_upsert(&database, &dto)
|
||||
.await
|
||||
.expect("chain transaction upsert must succeed");
|
||||
assert!(transaction_id > 0);
|
||||
let fetched =
|
||||
crate::get_chain_transaction_by_signature(&database, "sig-chain-transaction-1")
|
||||
crate::query_chain_transactions_get_by_signature(&database, "sig-chain-transaction-1")
|
||||
.await
|
||||
.expect("chain transaction fetch must succeed")
|
||||
.expect("chain transaction must exist");
|
||||
@@ -295,7 +295,7 @@ mod tests {
|
||||
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)
|
||||
let listed = crate::query_chain_transactions_list_recent(&database, 10)
|
||||
.await
|
||||
.expect("chain transaction list must succeed");
|
||||
assert_eq!(listed.len(), 1);
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
// file: kb_lib/src/db/queries/db_metadata.rs
|
||||
|
||||
//! Queries for `kb_db_metadata`.
|
||||
//! Queries for `k_sol_db_metadata`.
|
||||
|
||||
/// Inserts or updates one metadata row.
|
||||
pub async fn upsert_db_metadata(
|
||||
database: &crate::KbDatabase,
|
||||
dto: &crate::KbDbMetadataDto,
|
||||
) -> Result<(), crate::KbError> {
|
||||
let entity = crate::KbDbMetadataEntity::from(dto.clone());
|
||||
pub async fn query_db_metadatas_upsert(
|
||||
database: &crate::Database,
|
||||
dto: &crate::DbMetadataDto,
|
||||
) -> Result<(), crate::Error> {
|
||||
let entity = crate::DbMetadataEntity::from(dto.clone());
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query(
|
||||
r#"
|
||||
INSERT INTO kb_db_metadata (
|
||||
INSERT INTO k_sol_db_metadata (
|
||||
key,
|
||||
value,
|
||||
updated_at
|
||||
@@ -31,8 +31,8 @@ ON CONFLICT(key) DO UPDATE SET
|
||||
match query_result {
|
||||
Ok(_) => return Ok(()),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot upsert kb_db_metadata on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot upsert k_sol_db_metadata on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
@@ -42,19 +42,19 @@ ON CONFLICT(key) DO UPDATE SET
|
||||
}
|
||||
|
||||
/// Reads one metadata row by key.
|
||||
pub async fn get_db_metadata(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_db_metadatas_get(
|
||||
database: &crate::Database,
|
||||
key: &str,
|
||||
) -> Result<std::option::Option<crate::KbDbMetadataDto>, crate::KbError> {
|
||||
) -> Result<std::option::Option<crate::DbMetadataDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbDbMetadataEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::DbMetadataEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
key,
|
||||
value,
|
||||
updated_at
|
||||
FROM kb_db_metadata
|
||||
FROM k_sol_db_metadata
|
||||
WHERE key = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -65,15 +65,15 @@ LIMIT 1
|
||||
let entity_option = match query_result {
|
||||
Ok(entity_option) => entity_option,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot read kb_db_metadata '{}' on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot read k_sol_db_metadata '{}' on sqlite: {}",
|
||||
key, error
|
||||
)));
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => {
|
||||
let dto_result = crate::KbDbMetadataDto::try_from(entity);
|
||||
let dto_result = crate::DbMetadataDto::try_from(entity);
|
||||
match dto_result {
|
||||
Ok(dto) => return Ok(Some(dto)),
|
||||
Err(error) => return Err(error),
|
||||
@@ -86,18 +86,18 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Lists all metadata rows.
|
||||
pub async fn list_db_metadata(
|
||||
database: &crate::KbDatabase,
|
||||
) -> Result<std::vec::Vec<crate::KbDbMetadataDto>, crate::KbError> {
|
||||
pub async fn query_db_metadatas_list(
|
||||
database: &crate::Database,
|
||||
) -> Result<std::vec::Vec<crate::DbMetadataDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbDbMetadataEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::DbMetadataEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
key,
|
||||
value,
|
||||
updated_at
|
||||
FROM kb_db_metadata
|
||||
FROM k_sol_db_metadata
|
||||
ORDER BY key ASC
|
||||
"#,
|
||||
)
|
||||
@@ -106,15 +106,15 @@ ORDER BY key ASC
|
||||
let entities = match query_result {
|
||||
Ok(entities) => entities,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot list kb_db_metadata on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot list k_sol_db_metadata on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
let dto_result = crate::KbDbMetadataDto::try_from(entity);
|
||||
let dto_result = crate::DbMetadataDto::try_from(entity);
|
||||
let dto = match dto_result {
|
||||
Ok(dto) => dto,
|
||||
Err(error) => return Err(error),
|
||||
@@ -132,10 +132,10 @@ mod tests {
|
||||
async fn db_metadata_roundtrip_works() {
|
||||
let tempdir = tempfile::tempdir().expect("tempdir must succeed");
|
||||
let database_path = tempdir.path().join("roundtrip.sqlite3");
|
||||
let config = crate::KbDatabaseConfig {
|
||||
let config = crate::DatabaseConfig {
|
||||
enabled: true,
|
||||
backend: crate::KbDatabaseBackend::Sqlite,
|
||||
sqlite: crate::KbSqliteDatabaseConfig {
|
||||
backend: crate::DatabaseBackend::Sqlite,
|
||||
sqlite: crate::SqliteDatabaseConfig {
|
||||
path: database_path.to_string_lossy().to_string(),
|
||||
create_if_missing: true,
|
||||
busy_timeout_ms: 5000,
|
||||
@@ -144,19 +144,21 @@ mod tests {
|
||||
use_wal: true,
|
||||
},
|
||||
};
|
||||
let database = crate::KbDatabase::connect_and_initialize(&config)
|
||||
let database = crate::Database::connect_and_initialize(&config)
|
||||
.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");
|
||||
let fetched = crate::get_db_metadata(&database, "schema_version")
|
||||
let dto = crate::DbMetadataDto::new("schema_version".to_string(), "0.5.0".to_string());
|
||||
crate::query_db_metadatas_upsert(&database, &dto)
|
||||
.await
|
||||
.expect("upsert must succeed");
|
||||
let fetched = crate::query_db_metadatas_get(&database, "schema_version")
|
||||
.await
|
||||
.expect("fetch must succeed");
|
||||
assert!(fetched.is_some());
|
||||
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::query_db_metadatas_list(&database).await.expect("list must succeed");
|
||||
assert!(!listed.is_empty());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
// file: kb_lib/src/db/queries/db_runtime_event.rs
|
||||
|
||||
//! Queries for `kb_db_runtime_events`.
|
||||
//! Queries for `k_sol_db_runtime_events`.
|
||||
|
||||
/// Inserts one runtime event row and returns its numeric id.
|
||||
pub async fn insert_db_runtime_event(
|
||||
database: &crate::KbDatabase,
|
||||
dto: &crate::KbDbRuntimeEventDto,
|
||||
) -> Result<i64, crate::KbError> {
|
||||
pub async fn query_db_runtime_events_insert(
|
||||
database: &crate::Database,
|
||||
dto: &crate::DbRuntimeEventDto,
|
||||
) -> Result<i64, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query(
|
||||
r#"
|
||||
INSERT INTO kb_db_runtime_events (
|
||||
INSERT INTO k_sol_db_runtime_events (
|
||||
event_kind,
|
||||
level,
|
||||
source,
|
||||
@@ -31,8 +31,8 @@ VALUES (?, ?, ?, ?, ?)
|
||||
let query_result = match query_result {
|
||||
Ok(query_result) => query_result,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot insert kb_db_runtime_events on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot insert k_sol_db_runtime_events on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
@@ -43,16 +43,16 @@ VALUES (?, ?, ?, ?, ?)
|
||||
}
|
||||
|
||||
/// Lists recent runtime events ordered from newest to oldest.
|
||||
pub async fn list_recent_db_runtime_events(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_db_runtime_events_list_recent(
|
||||
database: &crate::Database,
|
||||
limit: u32,
|
||||
) -> Result<std::vec::Vec<crate::KbDbRuntimeEventDto>, crate::KbError> {
|
||||
) -> Result<std::vec::Vec<crate::DbRuntimeEventDto>, crate::Error> {
|
||||
if limit == 0 {
|
||||
return Ok(std::vec::Vec::new());
|
||||
}
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbDbRuntimeEventEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::DbRuntimeEventEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -61,7 +61,7 @@ SELECT
|
||||
source,
|
||||
message,
|
||||
created_at
|
||||
FROM kb_db_runtime_events
|
||||
FROM k_sol_db_runtime_events
|
||||
ORDER BY id DESC
|
||||
LIMIT ?
|
||||
"#,
|
||||
@@ -72,7 +72,7 @@ LIMIT ?
|
||||
let entities = match query_result {
|
||||
Ok(entities) => entities,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot list runtime events on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
@@ -80,7 +80,7 @@ LIMIT ?
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
let dto_result = crate::KbDbRuntimeEventDto::try_from(entity);
|
||||
let dto_result = crate::DbRuntimeEventDto::try_from(entity);
|
||||
let dto = match dto_result {
|
||||
Ok(dto) => dto,
|
||||
Err(error) => return Err(error),
|
||||
@@ -98,10 +98,10 @@ mod tests {
|
||||
async fn runtime_event_roundtrip_works() {
|
||||
let tempdir = tempfile::tempdir().expect("tempdir must succeed");
|
||||
let database_path = tempdir.path().join("runtime_event.sqlite3");
|
||||
let config = crate::KbDatabaseConfig {
|
||||
let config = crate::DatabaseConfig {
|
||||
enabled: true,
|
||||
backend: crate::KbDatabaseBackend::Sqlite,
|
||||
sqlite: crate::KbSqliteDatabaseConfig {
|
||||
backend: crate::DatabaseBackend::Sqlite,
|
||||
sqlite: crate::SqliteDatabaseConfig {
|
||||
path: database_path.to_string_lossy().to_string(),
|
||||
create_if_missing: true,
|
||||
busy_timeout_ms: 5000,
|
||||
@@ -110,24 +110,24 @@ mod tests {
|
||||
use_wal: true,
|
||||
},
|
||||
};
|
||||
let database = crate::KbDatabase::connect_and_initialize(&config)
|
||||
let database = crate::Database::connect_and_initialize(&config)
|
||||
.await
|
||||
.expect("database init must succeed");
|
||||
let dto = crate::KbDbRuntimeEventDto::new(
|
||||
let dto = crate::DbRuntimeEventDto::new(
|
||||
"http_request".to_string(),
|
||||
crate::KbDbRuntimeEventLevel::Info,
|
||||
crate::DbRuntimeEventLevel::Info,
|
||||
"demo_http".to_string(),
|
||||
"getHealth executed".to_string(),
|
||||
);
|
||||
let inserted_id = crate::insert_db_runtime_event(&database, &dto)
|
||||
let inserted_id = crate::query_db_runtime_events_insert(&database, &dto)
|
||||
.await
|
||||
.expect("insert must succeed");
|
||||
assert!(inserted_id > 0);
|
||||
let listed = crate::list_recent_db_runtime_events(&database, 10)
|
||||
let listed = crate::query_db_runtime_events_list_recent(&database, 10)
|
||||
.await
|
||||
.expect("list must succeed");
|
||||
assert_eq!(listed.len(), 1);
|
||||
assert_eq!(listed[0].event_kind, "http_request");
|
||||
assert_eq!(listed[0].level, crate::KbDbRuntimeEventLevel::Info);
|
||||
assert_eq!(listed[0].level, crate::DbRuntimeEventLevel::Info);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
// file: kb_lib/src/db/queries/dex.rs
|
||||
|
||||
//! Queries for `kb_dexes`.
|
||||
//! Queries for `k_sol_dexes`.
|
||||
|
||||
/// Inserts or updates one normalized DEX row by code.
|
||||
pub async fn upsert_dex(
|
||||
database: &crate::KbDatabase,
|
||||
dto: &crate::KbDexDto,
|
||||
) -> Result<i64, crate::KbError> {
|
||||
pub async fn query_dexs_upsert(
|
||||
database: &crate::Database,
|
||||
dto: &crate::DexDto,
|
||||
) -> Result<i64, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query(
|
||||
r#"
|
||||
INSERT INTO kb_dexes (
|
||||
INSERT INTO k_sol_dexes (
|
||||
code,
|
||||
name,
|
||||
program_id,
|
||||
@@ -39,15 +39,15 @@ ON CONFLICT(code) DO UPDATE SET
|
||||
.execute(pool)
|
||||
.await;
|
||||
if let Err(error) = query_result {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot upsert kb_dexes on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot upsert k_sol_dexes on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
let id_result = sqlx::query_scalar::<sqlx::Sqlite, i64>(
|
||||
r#"
|
||||
SELECT id
|
||||
FROM kb_dexes
|
||||
FROM k_sol_dexes
|
||||
WHERE code = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -58,8 +58,8 @@ LIMIT 1
|
||||
match id_result {
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_dexes id for code '{}' on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot fetch k_sol_dexes id for code '{}' on sqlite: {}",
|
||||
dto.code, error
|
||||
)));
|
||||
},
|
||||
@@ -69,13 +69,13 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Reads one normalized DEX row by code.
|
||||
pub async fn get_dex_by_code(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_dexs_get_by_code(
|
||||
database: &crate::Database,
|
||||
code: &str,
|
||||
) -> Result<std::option::Option<crate::KbDexDto>, crate::KbError> {
|
||||
) -> Result<std::option::Option<crate::DexDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbDexEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::DexEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -86,7 +86,7 @@ SELECT
|
||||
is_enabled,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM kb_dexes
|
||||
FROM k_sol_dexes
|
||||
WHERE code = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -97,15 +97,15 @@ LIMIT 1
|
||||
let entity_option = match query_result {
|
||||
Ok(entity_option) => entity_option,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot read kb_dexes '{}' on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot read k_sol_dexes '{}' on sqlite: {}",
|
||||
code, error
|
||||
)));
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => {
|
||||
let dto_result = crate::KbDexDto::try_from(entity);
|
||||
let dto_result = crate::DexDto::try_from(entity);
|
||||
match dto_result {
|
||||
Ok(dto) => return Ok(Some(dto)),
|
||||
Err(error) => return Err(error),
|
||||
@@ -118,12 +118,12 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Lists normalized DEX rows.
|
||||
pub async fn list_dexes(
|
||||
database: &crate::KbDatabase,
|
||||
) -> Result<std::vec::Vec<crate::KbDexDto>, crate::KbError> {
|
||||
pub async fn query_dexs_list(
|
||||
database: &crate::Database,
|
||||
) -> Result<std::vec::Vec<crate::DexDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbDexEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::DexEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -134,7 +134,7 @@ SELECT
|
||||
is_enabled,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM kb_dexes
|
||||
FROM k_sol_dexes
|
||||
ORDER BY code ASC
|
||||
"#,
|
||||
)
|
||||
@@ -143,15 +143,15 @@ ORDER BY code ASC
|
||||
let entities = match query_result {
|
||||
Ok(entities) => entities,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot list kb_dexes on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot list k_sol_dexes on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
let dto_result = crate::KbDexDto::try_from(entity);
|
||||
let dto_result = crate::DexDto::try_from(entity);
|
||||
let dto = match dto_result {
|
||||
Ok(dto) => dto,
|
||||
Err(error) => return Err(error),
|
||||
@@ -169,10 +169,10 @@ mod tests {
|
||||
async fn dex_roundtrip_works() {
|
||||
let tempdir = tempfile::tempdir().expect("tempdir must succeed");
|
||||
let database_path = tempdir.path().join("dex_roundtrip.sqlite3");
|
||||
let config = crate::KbDatabaseConfig {
|
||||
let config = crate::DatabaseConfig {
|
||||
enabled: true,
|
||||
backend: crate::KbDatabaseBackend::Sqlite,
|
||||
sqlite: crate::KbSqliteDatabaseConfig {
|
||||
backend: crate::DatabaseBackend::Sqlite,
|
||||
sqlite: crate::SqliteDatabaseConfig {
|
||||
path: database_path.to_string_lossy().to_string(),
|
||||
create_if_missing: true,
|
||||
busy_timeout_ms: 5000,
|
||||
@@ -181,22 +181,22 @@ mod tests {
|
||||
use_wal: true,
|
||||
},
|
||||
};
|
||||
let database = crate::KbDatabase::connect_and_initialize(&config)
|
||||
let database = crate::Database::connect_and_initialize(&config)
|
||||
.await
|
||||
.expect("database init must succeed");
|
||||
let dex_id = crate::upsert_dex(
|
||||
let dex_id = crate::query_dexs_upsert(
|
||||
&database,
|
||||
&crate::KbDexDto::new("raydium".to_string(), "Raydium".to_string(), None, None, true),
|
||||
&crate::DexDto::new("raydium".to_string(), "Raydium".to_string(), None, None, true),
|
||||
)
|
||||
.await
|
||||
.expect("dex upsert must succeed");
|
||||
assert!(dex_id > 0);
|
||||
let dex = crate::get_dex_by_code(&database, "raydium")
|
||||
let dex = crate::query_dexs_get_by_code(&database, "raydium")
|
||||
.await
|
||||
.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::query_dexs_list(&database).await.expect("list dexes must succeed");
|
||||
assert_eq!(dexes.len(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
// file: kb_lib/src/db/queries/dex_decoded_event.rs
|
||||
|
||||
//! Queries for `kb_dex_decoded_events`.
|
||||
//! Queries for `k_sol_dex_decoded_events`.
|
||||
|
||||
/// Inserts or updates one decoded DEX event row.
|
||||
pub async fn upsert_dex_decoded_event(
|
||||
database: &crate::KbDatabase,
|
||||
dto: &crate::KbDexDecodedEventDto,
|
||||
) -> Result<i64, crate::KbError> {
|
||||
pub async fn query_dex_decoded_events_upsert(
|
||||
database: &crate::Database,
|
||||
dto: &crate::DexDecodedEventDto,
|
||||
) -> Result<i64, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query(
|
||||
r#"
|
||||
INSERT INTO kb_dex_decoded_events (
|
||||
INSERT INTO k_sol_dex_decoded_events (
|
||||
transaction_id,
|
||||
instruction_id,
|
||||
protocol_name,
|
||||
@@ -52,15 +52,15 @@ ON CONFLICT(transaction_id, instruction_id, event_kind) DO UPDATE SET
|
||||
.execute(pool)
|
||||
.await;
|
||||
if let Err(error) = query_result {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot upsert kb_dex_decoded_events on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot upsert k_sol_dex_decoded_events on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
let id_result = sqlx::query_scalar::<sqlx::Sqlite, i64>(
|
||||
r#"
|
||||
SELECT id
|
||||
FROM kb_dex_decoded_events
|
||||
FROM k_sol_dex_decoded_events
|
||||
WHERE transaction_id = ?
|
||||
AND (
|
||||
(instruction_id IS NULL AND ? IS NULL)
|
||||
@@ -79,8 +79,8 @@ LIMIT 1
|
||||
match id_result {
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_dex_decoded_events id on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot fetch k_sol_dex_decoded_events id on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
@@ -90,15 +90,15 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Reads one decoded DEX event by its natural key.
|
||||
pub async fn get_dex_decoded_event_by_key(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_dex_decoded_events_get_by_key(
|
||||
database: &crate::Database,
|
||||
transaction_id: i64,
|
||||
instruction_id: std::option::Option<i64>,
|
||||
event_kind: &str,
|
||||
) -> Result<std::option::Option<crate::KbDexDecodedEventDto>, crate::KbError> {
|
||||
) -> Result<std::option::Option<crate::DexDecodedEventDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbDexDecodedEventEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::DexDecodedEventEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -114,7 +114,7 @@ SELECT
|
||||
market_account,
|
||||
payload_json,
|
||||
created_at
|
||||
FROM kb_dex_decoded_events
|
||||
FROM k_sol_dex_decoded_events
|
||||
WHERE transaction_id = ?
|
||||
AND (
|
||||
(instruction_id IS NULL AND ? IS NULL)
|
||||
@@ -133,15 +133,15 @@ LIMIT 1
|
||||
let entity_option = match query_result {
|
||||
Ok(entity_option) => entity_option,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_dex_decoded_events on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot fetch k_sol_dex_decoded_events on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => {
|
||||
let dto_result = crate::KbDexDecodedEventDto::try_from(entity);
|
||||
let dto_result = crate::DexDecodedEventDto::try_from(entity);
|
||||
match dto_result {
|
||||
Ok(dto) => return Ok(Some(dto)),
|
||||
Err(error) => return Err(error),
|
||||
@@ -154,13 +154,13 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Lists decoded DEX events for one transaction.
|
||||
pub async fn list_dex_decoded_events_by_transaction_id(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_dex_decoded_events_list_by_transaction_id(
|
||||
database: &crate::Database,
|
||||
transaction_id: i64,
|
||||
) -> Result<std::vec::Vec<crate::KbDexDecodedEventDto>, crate::KbError> {
|
||||
) -> Result<std::vec::Vec<crate::DexDecodedEventDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbDexDecodedEventEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::DexDecodedEventEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -176,7 +176,7 @@ SELECT
|
||||
market_account,
|
||||
payload_json,
|
||||
created_at
|
||||
FROM kb_dex_decoded_events
|
||||
FROM k_sol_dex_decoded_events
|
||||
WHERE transaction_id = ?
|
||||
ORDER BY id ASC
|
||||
"#,
|
||||
@@ -187,15 +187,15 @@ ORDER BY id ASC
|
||||
let entities = match query_result {
|
||||
Ok(entities) => entities,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot list kb_dex_decoded_events on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot list k_sol_dex_decoded_events on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
let dto_result = crate::KbDexDecodedEventDto::try_from(entity);
|
||||
let dto_result = crate::DexDecodedEventDto::try_from(entity);
|
||||
let dto = match dto_result {
|
||||
Ok(dto) => dto,
|
||||
Err(error) => return Err(error),
|
||||
@@ -208,16 +208,16 @@ ORDER BY id ASC
|
||||
}
|
||||
|
||||
/// 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,
|
||||
pub async fn query_dex_decoded_events_get_latest_pump_fun_create_payload_by_mint(
|
||||
database: &crate::Database,
|
||||
mint: &str,
|
||||
) -> Result<std::option::Option<std::string::String>, crate::KbError> {
|
||||
) -> Result<std::option::Option<std::string::String>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let payload_result = sqlx::query_scalar::<sqlx::Sqlite, std::string::String>(
|
||||
r#"
|
||||
SELECT payload_json
|
||||
FROM kb_dex_decoded_events
|
||||
FROM k_sol_dex_decoded_events
|
||||
WHERE protocol_name = 'pump_fun'
|
||||
AND event_kind IN ('pump_fun.create', 'pump_fun.create_v2_token')
|
||||
AND (
|
||||
@@ -237,7 +237,7 @@ LIMIT 1
|
||||
match payload_result {
|
||||
Ok(payload_option) => return Ok(payload_option),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot read latest pump.fun create payload for mint '{}' on sqlite: {}",
|
||||
mint, error
|
||||
)));
|
||||
@@ -249,17 +249,17 @@ LIMIT 1
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
async fn make_database() -> crate::KbDatabase {
|
||||
async fn make_database() -> crate::Database {
|
||||
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("dex_decoded_event.sqlite3");
|
||||
let config = crate::KbDatabaseConfig {
|
||||
let config = crate::DatabaseConfig {
|
||||
enabled: true,
|
||||
backend: crate::KbDatabaseBackend::Sqlite,
|
||||
sqlite: crate::KbSqliteDatabaseConfig {
|
||||
backend: crate::DatabaseBackend::Sqlite,
|
||||
sqlite: crate::SqliteDatabaseConfig {
|
||||
path: database_path.to_string_lossy().to_string(),
|
||||
create_if_missing: true,
|
||||
busy_timeout_ms: 5000,
|
||||
@@ -268,7 +268,7 @@ mod tests {
|
||||
use_wal: true,
|
||||
},
|
||||
};
|
||||
let database_result = crate::KbDatabase::connect_and_initialize(&config).await;
|
||||
let database_result = crate::Database::connect_and_initialize(&config).await;
|
||||
match database_result {
|
||||
Ok(database) => return database,
|
||||
Err(error) => panic!("database init must succeed: {}", error),
|
||||
@@ -278,7 +278,7 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn dex_decoded_event_roundtrip_works() {
|
||||
let database = make_database().await;
|
||||
let transaction_dto = crate::KbChainTransactionDto::new(
|
||||
let transaction_dto = crate::ChainTransactionDto::new(
|
||||
"sig-dex-event-test-1".to_string(),
|
||||
None,
|
||||
None,
|
||||
@@ -289,17 +289,17 @@ mod tests {
|
||||
r#"{"transaction":{"message":{"instructions":[]}}}"#.to_string(),
|
||||
);
|
||||
let transaction_id_result =
|
||||
crate::upsert_chain_transaction(&database, &transaction_dto).await;
|
||||
crate::query_chain_transactions_upsert(&database, &transaction_dto).await;
|
||||
let transaction_id = match transaction_id_result {
|
||||
Ok(transaction_id) => transaction_id,
|
||||
Err(error) => panic!("transaction upsert must succeed: {}", error),
|
||||
};
|
||||
let instruction_dto = crate::KbChainInstructionDto::new(
|
||||
let instruction_dto = crate::ChainInstructionDto::new(
|
||||
transaction_id,
|
||||
None,
|
||||
0,
|
||||
None,
|
||||
Some(crate::KB_RAYDIUM_AMM_V4_PROGRAM_ID.to_string()),
|
||||
Some(crate::RAYDIUM_AMM_V4_PROGRAM_ID.to_string()),
|
||||
Some("raydium-amm-v4".to_string()),
|
||||
Some(1),
|
||||
r#"["Account0","Pool111","Lp111","TokenA111","TokenB111"]"#.to_string(),
|
||||
@@ -308,16 +308,16 @@ mod tests {
|
||||
None,
|
||||
);
|
||||
let instruction_id_result =
|
||||
crate::insert_chain_instruction(&database, &instruction_dto).await;
|
||||
crate::query_chain_instructions_insert(&database, &instruction_dto).await;
|
||||
let instruction_id = match instruction_id_result {
|
||||
Ok(instruction_id) => instruction_id,
|
||||
Err(error) => panic!("instruction insert must succeed: {}", error),
|
||||
};
|
||||
let dto = crate::KbDexDecodedEventDto::new(
|
||||
let dto = crate::DexDecodedEventDto::new(
|
||||
transaction_id,
|
||||
Some(instruction_id),
|
||||
"raydium_amm_v4".to_string(),
|
||||
crate::KB_RAYDIUM_AMM_V4_PROGRAM_ID.to_string(),
|
||||
crate::RAYDIUM_AMM_V4_PROGRAM_ID.to_string(),
|
||||
"raydium_amm_v4.initialize2_pool".to_string(),
|
||||
Some("Pool111".to_string()),
|
||||
Some("Lp111".to_string()),
|
||||
@@ -326,13 +326,13 @@ mod tests {
|
||||
Some("Market111".to_string()),
|
||||
r#"{"k":"v"}"#.to_string(),
|
||||
);
|
||||
let event_id_result = crate::upsert_dex_decoded_event(&database, &dto).await;
|
||||
let event_id_result = crate::query_dex_decoded_events_upsert(&database, &dto).await;
|
||||
let event_id = match event_id_result {
|
||||
Ok(event_id) => event_id,
|
||||
Err(error) => panic!("event upsert must succeed: {}", error),
|
||||
};
|
||||
assert!(event_id > 0);
|
||||
let fetched_result = crate::get_dex_decoded_event_by_key(
|
||||
let fetched_result = crate::query_dex_decoded_events_get_by_key(
|
||||
&database,
|
||||
transaction_id,
|
||||
Some(instruction_id),
|
||||
@@ -353,7 +353,7 @@ mod tests {
|
||||
assert_eq!(fetched.protocol_name, "raydium_amm_v4");
|
||||
assert_eq!(fetched.pool_account, Some("Pool111".to_string()));
|
||||
let listed_result =
|
||||
crate::list_dex_decoded_events_by_transaction_id(&database, transaction_id).await;
|
||||
crate::query_dex_decoded_events_list_by_transaction_id(&database, transaction_id).await;
|
||||
let listed = match listed_result {
|
||||
Ok(listed) => listed,
|
||||
Err(error) => panic!("event list must succeed: {}", error),
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
// file: kb_lib/src/db/queries/known_http_endpoint.rs
|
||||
|
||||
//! Queries for `kb_known_http_endpoints`.
|
||||
//! Queries for `k_sol_known_http_endpoints`.
|
||||
|
||||
/// Inserts or updates one known HTTP endpoint row.
|
||||
pub async fn upsert_known_http_endpoint(
|
||||
database: &crate::KbDatabase,
|
||||
dto: &crate::KbKnownHttpEndpointDto,
|
||||
) -> Result<(), crate::KbError> {
|
||||
let entity_result = crate::KbKnownHttpEndpointEntity::try_from(dto.clone());
|
||||
pub async fn query_known_http_endpoints_upsert(
|
||||
database: &crate::Database,
|
||||
dto: &crate::KnownHttpEndpointDto,
|
||||
) -> Result<(), crate::Error> {
|
||||
let entity_result = crate::KnownHttpEndpointEntity::try_from(dto.clone());
|
||||
let entity = match entity_result {
|
||||
Ok(entity) => entity,
|
||||
Err(error) => return Err(error),
|
||||
};
|
||||
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query(
|
||||
r#"
|
||||
INSERT INTO kb_known_http_endpoints (
|
||||
INSERT INTO k_sol_known_http_endpoints (
|
||||
name,
|
||||
provider,
|
||||
url,
|
||||
@@ -48,8 +48,8 @@ ON CONFLICT(name) DO UPDATE SET
|
||||
match query_result {
|
||||
Ok(_) => return Ok(()),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot upsert kb_known_http_endpoints on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot upsert k_sol_known_http_endpoints on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
@@ -59,13 +59,13 @@ ON CONFLICT(name) DO UPDATE SET
|
||||
}
|
||||
|
||||
/// Reads one known HTTP endpoint by name.
|
||||
pub async fn get_known_http_endpoint(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_known_http_endpoints_get(
|
||||
database: &crate::Database,
|
||||
name: &str,
|
||||
) -> Result<std::option::Option<crate::KbKnownHttpEndpointDto>, crate::KbError> {
|
||||
) -> Result<std::option::Option<crate::KnownHttpEndpointDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbKnownHttpEndpointEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KnownHttpEndpointEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
name,
|
||||
@@ -75,7 +75,7 @@ SELECT
|
||||
roles_json,
|
||||
last_seen_at,
|
||||
updated_at
|
||||
FROM kb_known_http_endpoints
|
||||
FROM k_sol_known_http_endpoints
|
||||
WHERE name = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -86,7 +86,7 @@ LIMIT 1
|
||||
let entity_option = match query_result {
|
||||
Ok(entity_option) => entity_option,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot read known http endpoint '{}' on sqlite: {}",
|
||||
name, error
|
||||
)));
|
||||
@@ -94,7 +94,7 @@ LIMIT 1
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => {
|
||||
let dto_result = crate::KbKnownHttpEndpointDto::try_from(entity);
|
||||
let dto_result = crate::KnownHttpEndpointDto::try_from(entity);
|
||||
match dto_result {
|
||||
Ok(dto) => return Ok(Some(dto)),
|
||||
Err(error) => return Err(error),
|
||||
@@ -107,12 +107,12 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Lists all known HTTP endpoints.
|
||||
pub async fn list_known_http_endpoints(
|
||||
database: &crate::KbDatabase,
|
||||
) -> Result<std::vec::Vec<crate::KbKnownHttpEndpointDto>, crate::KbError> {
|
||||
pub async fn query_known_http_endpoints_list(
|
||||
database: &crate::Database,
|
||||
) -> Result<std::vec::Vec<crate::KnownHttpEndpointDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbKnownHttpEndpointEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KnownHttpEndpointEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
name,
|
||||
@@ -122,7 +122,7 @@ SELECT
|
||||
roles_json,
|
||||
last_seen_at,
|
||||
updated_at
|
||||
FROM kb_known_http_endpoints
|
||||
FROM k_sol_known_http_endpoints
|
||||
ORDER BY name ASC
|
||||
"#,
|
||||
)
|
||||
@@ -131,7 +131,7 @@ ORDER BY name ASC
|
||||
let entities = match query_result {
|
||||
Ok(entities) => entities,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot list known http endpoints on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
@@ -139,7 +139,7 @@ ORDER BY name ASC
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
let dto_result = crate::KbKnownHttpEndpointDto::try_from(entity);
|
||||
let dto_result = crate::KnownHttpEndpointDto::try_from(entity);
|
||||
let dto = match dto_result {
|
||||
Ok(dto) => dto,
|
||||
Err(error) => return Err(error),
|
||||
@@ -157,10 +157,10 @@ mod tests {
|
||||
async fn known_http_endpoint_roundtrip_works() {
|
||||
let tempdir = tempfile::tempdir().expect("tempdir must succeed");
|
||||
let database_path = tempdir.path().join("known_http_endpoint.sqlite3");
|
||||
let config = crate::KbDatabaseConfig {
|
||||
let config = crate::DatabaseConfig {
|
||||
enabled: true,
|
||||
backend: crate::KbDatabaseBackend::Sqlite,
|
||||
sqlite: crate::KbSqliteDatabaseConfig {
|
||||
backend: crate::DatabaseBackend::Sqlite,
|
||||
sqlite: crate::SqliteDatabaseConfig {
|
||||
path: database_path.to_string_lossy().to_string(),
|
||||
create_if_missing: true,
|
||||
busy_timeout_ms: 5000,
|
||||
@@ -169,27 +169,29 @@ mod tests {
|
||||
use_wal: true,
|
||||
},
|
||||
};
|
||||
let database = crate::KbDatabase::connect_and_initialize(&config)
|
||||
let database = crate::Database::connect_and_initialize(&config)
|
||||
.await
|
||||
.expect("database init must succeed");
|
||||
let dto = crate::KbKnownHttpEndpointDto::new(
|
||||
let dto = crate::KnownHttpEndpointDto::new(
|
||||
"helius_primary_http".to_string(),
|
||||
"helius".to_string(),
|
||||
"https://mainnet.helius-rpc.com".to_string(),
|
||||
true,
|
||||
vec!["http_queries".to_string(), "http_transactions".to_string()],
|
||||
);
|
||||
crate::upsert_known_http_endpoint(&database, &dto)
|
||||
crate::query_known_http_endpoints_upsert(&database, &dto)
|
||||
.await
|
||||
.expect("upsert must succeed");
|
||||
let fetched = crate::get_known_http_endpoint(&database, "helius_primary_http")
|
||||
let fetched = crate::query_known_http_endpoints_get(&database, "helius_primary_http")
|
||||
.await
|
||||
.expect("fetch must succeed");
|
||||
assert!(fetched.is_some());
|
||||
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::query_known_http_endpoints_list(&database)
|
||||
.await
|
||||
.expect("list must succeed");
|
||||
assert_eq!(listed.len(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
// file: kb_lib/src/db/queries/known_ws_endpoint.rs
|
||||
|
||||
//! Queries for `kb_known_ws_endpoints`.
|
||||
//! Queries for `k_sol_known_ws_endpoints`.
|
||||
|
||||
/// Inserts or updates one known WS endpoint row.
|
||||
pub async fn upsert_known_ws_endpoint(
|
||||
database: &crate::KbDatabase,
|
||||
dto: &crate::KbKnownWsEndpointDto,
|
||||
) -> Result<(), crate::KbError> {
|
||||
let entity_result = crate::KbKnownWsEndpointEntity::try_from(dto.clone());
|
||||
pub async fn query_known_ws_endpoints_upsert(
|
||||
database: &crate::Database,
|
||||
dto: &crate::KnownWsEndpointDto,
|
||||
) -> Result<(), crate::Error> {
|
||||
let entity_result = crate::KnownWsEndpointEntity::try_from(dto.clone());
|
||||
let entity = match entity_result {
|
||||
Ok(entity) => entity,
|
||||
Err(error) => return Err(error),
|
||||
};
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query(
|
||||
r#"
|
||||
INSERT INTO kb_known_ws_endpoints (
|
||||
INSERT INTO k_sol_known_ws_endpoints (
|
||||
name,
|
||||
provider,
|
||||
url,
|
||||
@@ -47,8 +47,8 @@ ON CONFLICT(name) DO UPDATE SET
|
||||
match query_result {
|
||||
Ok(_) => return Ok(()),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot upsert kb_known_ws_endpoints on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot upsert k_sol_known_ws_endpoints on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
@@ -58,13 +58,13 @@ ON CONFLICT(name) DO UPDATE SET
|
||||
}
|
||||
|
||||
/// Reads one known WS endpoint by name.
|
||||
pub async fn get_known_ws_endpoint(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_known_ws_endpoints_get(
|
||||
database: &crate::Database,
|
||||
name: &str,
|
||||
) -> Result<std::option::Option<crate::KbKnownWsEndpointDto>, crate::KbError> {
|
||||
) -> Result<std::option::Option<crate::KnownWsEndpointDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbKnownWsEndpointEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KnownWsEndpointEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
name,
|
||||
@@ -74,7 +74,7 @@ SELECT
|
||||
roles_json,
|
||||
last_seen_at,
|
||||
updated_at
|
||||
FROM kb_known_ws_endpoints
|
||||
FROM k_sol_known_ws_endpoints
|
||||
WHERE name = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -85,7 +85,7 @@ LIMIT 1
|
||||
let entity_option = match query_result {
|
||||
Ok(entity_option) => entity_option,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot read known ws endpoint '{}' on sqlite: {}",
|
||||
name, error
|
||||
)));
|
||||
@@ -93,7 +93,7 @@ LIMIT 1
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => {
|
||||
let dto_result = crate::KbKnownWsEndpointDto::try_from(entity);
|
||||
let dto_result = crate::KnownWsEndpointDto::try_from(entity);
|
||||
match dto_result {
|
||||
Ok(dto) => return Ok(Some(dto)),
|
||||
Err(error) => return Err(error),
|
||||
@@ -106,12 +106,12 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Lists all known WS endpoints.
|
||||
pub async fn list_known_ws_endpoints(
|
||||
database: &crate::KbDatabase,
|
||||
) -> Result<std::vec::Vec<crate::KbKnownWsEndpointDto>, crate::KbError> {
|
||||
pub async fn query_known_ws_endpoints_list(
|
||||
database: &crate::Database,
|
||||
) -> Result<std::vec::Vec<crate::KnownWsEndpointDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbKnownWsEndpointEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KnownWsEndpointEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
name,
|
||||
@@ -121,7 +121,7 @@ SELECT
|
||||
roles_json,
|
||||
last_seen_at,
|
||||
updated_at
|
||||
FROM kb_known_ws_endpoints
|
||||
FROM k_sol_known_ws_endpoints
|
||||
ORDER BY name ASC
|
||||
"#,
|
||||
)
|
||||
@@ -130,7 +130,7 @@ ORDER BY name ASC
|
||||
let entities = match query_result {
|
||||
Ok(entities) => entities,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot list known ws endpoints on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
@@ -138,7 +138,7 @@ ORDER BY name ASC
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
let dto_result = crate::KbKnownWsEndpointDto::try_from(entity);
|
||||
let dto_result = crate::KnownWsEndpointDto::try_from(entity);
|
||||
let dto = match dto_result {
|
||||
Ok(dto) => dto,
|
||||
Err(error) => return Err(error),
|
||||
@@ -156,10 +156,10 @@ mod tests {
|
||||
async fn known_ws_endpoint_roundtrip_works() {
|
||||
let tempdir = tempfile::tempdir().expect("tempdir must succeed");
|
||||
let database_path = tempdir.path().join("known_ws_endpoint.sqlite3");
|
||||
let config = crate::KbDatabaseConfig {
|
||||
let config = crate::DatabaseConfig {
|
||||
enabled: true,
|
||||
backend: crate::KbDatabaseBackend::Sqlite,
|
||||
sqlite: crate::KbSqliteDatabaseConfig {
|
||||
backend: crate::DatabaseBackend::Sqlite,
|
||||
sqlite: crate::SqliteDatabaseConfig {
|
||||
path: database_path.to_string_lossy().to_string(),
|
||||
create_if_missing: true,
|
||||
busy_timeout_ms: 5000,
|
||||
@@ -168,27 +168,29 @@ mod tests {
|
||||
use_wal: true,
|
||||
},
|
||||
};
|
||||
let database = crate::KbDatabase::connect_and_initialize(&config)
|
||||
let database = crate::Database::connect_and_initialize(&config)
|
||||
.await
|
||||
.expect("database init must succeed");
|
||||
let dto = crate::KbKnownWsEndpointDto::new(
|
||||
let dto = crate::KnownWsEndpointDto::new(
|
||||
"mainnet_public_ws_slots".to_string(),
|
||||
"solana".to_string(),
|
||||
"wss://api.mainnet.solana.com".to_string(),
|
||||
true,
|
||||
vec!["ws_slots".to_string(), "ws_subscriptions".to_string()],
|
||||
);
|
||||
crate::upsert_known_ws_endpoint(&database, &dto)
|
||||
crate::query_known_ws_endpoints_upsert(&database, &dto)
|
||||
.await
|
||||
.expect("upsert must succeed");
|
||||
let fetched = crate::get_known_ws_endpoint(&database, "mainnet_public_ws_slots")
|
||||
let fetched = crate::query_known_ws_endpoints_get(&database, "mainnet_public_ws_slots")
|
||||
.await
|
||||
.expect("fetch must succeed");
|
||||
assert!(fetched.is_some());
|
||||
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::query_known_ws_endpoints_list(&database)
|
||||
.await
|
||||
.expect("list must succeed");
|
||||
assert_eq!(listed.len(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
// file: kb_lib/src/db/queries/launch_attribution.rs
|
||||
|
||||
//! Queries for `kb_launch_attributions`.
|
||||
//! Queries for `k_sol_launch_attributions`.
|
||||
|
||||
/// Inserts or updates one launch attribution row and returns its stable internal id.
|
||||
pub async fn upsert_launch_attribution(
|
||||
database: &crate::KbDatabase,
|
||||
dto: &crate::KbLaunchAttributionDto,
|
||||
) -> Result<i64, crate::KbError> {
|
||||
pub async fn query_launch_attributions_upsert(
|
||||
database: &crate::Database,
|
||||
dto: &crate::LaunchAttributionDto,
|
||||
) -> Result<i64, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query(
|
||||
r#"
|
||||
INSERT INTO kb_launch_attributions (
|
||||
INSERT INTO k_sol_launch_attributions (
|
||||
launch_surface_id,
|
||||
transaction_id,
|
||||
decoded_event_id,
|
||||
@@ -51,15 +51,15 @@ ON CONFLICT(decoded_event_id) DO UPDATE SET
|
||||
.execute(pool)
|
||||
.await;
|
||||
if let Err(error) = query_result {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot upsert kb_launch_attributions on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot upsert k_sol_launch_attributions on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
let id_result = sqlx::query_scalar::<sqlx::Sqlite, i64>(
|
||||
r#"
|
||||
SELECT id
|
||||
FROM kb_launch_attributions
|
||||
FROM k_sol_launch_attributions
|
||||
WHERE decoded_event_id = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -70,8 +70,8 @@ LIMIT 1
|
||||
match id_result {
|
||||
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: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot fetch k_sol_launch_attributions id for decoded_event_id '{}' on sqlite: {}",
|
||||
dto.decoded_event_id, error
|
||||
)));
|
||||
},
|
||||
@@ -81,13 +81,13 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Returns one launch attribution identified by its decoded-event id, if it exists.
|
||||
pub async fn get_launch_attribution_by_decoded_event_id(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_launch_attributions_get_by_decoded_event_id(
|
||||
database: &crate::Database,
|
||||
decoded_event_id: i64,
|
||||
) -> Result<std::option::Option<crate::KbLaunchAttributionDto>, crate::KbError> {
|
||||
) -> Result<std::option::Option<crate::LaunchAttributionDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbLaunchAttributionEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::LaunchAttributionEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -102,7 +102,7 @@ SELECT
|
||||
matched_value,
|
||||
attributed_at,
|
||||
updated_at
|
||||
FROM kb_launch_attributions
|
||||
FROM k_sol_launch_attributions
|
||||
WHERE decoded_event_id = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -113,14 +113,14 @@ LIMIT 1
|
||||
let entity_option = match query_result {
|
||||
Ok(entity_option) => entity_option,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot read kb_launch_attributions by decoded_event_id '{}' on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot read k_sol_launch_attributions by decoded_event_id '{}' on sqlite: {}",
|
||||
decoded_event_id, error
|
||||
)));
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => return crate::KbLaunchAttributionDto::try_from(entity).map(Some),
|
||||
Some(entity) => return crate::LaunchAttributionDto::try_from(entity).map(Some),
|
||||
None => return Ok(None),
|
||||
}
|
||||
},
|
||||
@@ -128,13 +128,13 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Lists all launch attributions attached to one pool id.
|
||||
pub async fn list_launch_attributions_by_pool_id(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_launch_attributions_list_by_pool_id(
|
||||
database: &crate::Database,
|
||||
pool_id: i64,
|
||||
) -> Result<std::vec::Vec<crate::KbLaunchAttributionDto>, crate::KbError> {
|
||||
) -> Result<std::vec::Vec<crate::LaunchAttributionDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbLaunchAttributionEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::LaunchAttributionEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -149,7 +149,7 @@ SELECT
|
||||
matched_value,
|
||||
attributed_at,
|
||||
updated_at
|
||||
FROM kb_launch_attributions
|
||||
FROM k_sol_launch_attributions
|
||||
WHERE pool_id = ?
|
||||
ORDER BY attributed_at ASC, id ASC
|
||||
"#,
|
||||
@@ -160,15 +160,15 @@ ORDER BY attributed_at ASC, id ASC
|
||||
let entities = match query_result {
|
||||
Ok(entities) => entities,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot list kb_launch_attributions by pool_id '{}' on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot list k_sol_launch_attributions by pool_id '{}' on sqlite: {}",
|
||||
pool_id, error
|
||||
)));
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
let dto_result = crate::KbLaunchAttributionDto::try_from(entity);
|
||||
let dto_result = crate::LaunchAttributionDto::try_from(entity);
|
||||
let dto = match dto_result {
|
||||
Ok(dto) => dto,
|
||||
Err(error) => return Err(error),
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
// file: kb_lib/src/db/queries/launch_surface.rs
|
||||
|
||||
//! Queries for `kb_launch_surfaces`.
|
||||
//! Queries for `k_sol_launch_surfaces`.
|
||||
|
||||
/// Inserts or updates one launch surface row and returns its stable internal id.
|
||||
pub async fn upsert_launch_surface(
|
||||
database: &crate::KbDatabase,
|
||||
dto: &crate::KbLaunchSurfaceDto,
|
||||
) -> Result<i64, crate::KbError> {
|
||||
pub async fn query_launch_surfaces_upsert(
|
||||
database: &crate::Database,
|
||||
dto: &crate::LaunchSurfaceDto,
|
||||
) -> Result<i64, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query(
|
||||
r#"
|
||||
INSERT INTO kb_launch_surfaces (
|
||||
INSERT INTO k_sol_launch_surfaces (
|
||||
code,
|
||||
name,
|
||||
protocol_family,
|
||||
@@ -36,15 +36,15 @@ ON CONFLICT(code) DO UPDATE SET
|
||||
.execute(pool)
|
||||
.await;
|
||||
if let Err(error) = query_result {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot upsert kb_launch_surfaces on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot upsert k_sol_launch_surfaces on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
let id_result = sqlx::query_scalar::<sqlx::Sqlite, i64>(
|
||||
r#"
|
||||
SELECT id
|
||||
FROM kb_launch_surfaces
|
||||
FROM k_sol_launch_surfaces
|
||||
WHERE code = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -55,8 +55,8 @@ LIMIT 1
|
||||
match id_result {
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_launch_surfaces id for code '{}' on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot fetch k_sol_launch_surfaces id for code '{}' on sqlite: {}",
|
||||
dto.code, error
|
||||
)));
|
||||
},
|
||||
@@ -66,13 +66,13 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Returns one launch surface identified by its stable short code, if it exists.
|
||||
pub async fn get_launch_surface_by_code(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_launch_surfaces_get_by_code(
|
||||
database: &crate::Database,
|
||||
code: &str,
|
||||
) -> Result<std::option::Option<crate::KbLaunchSurfaceDto>, crate::KbError> {
|
||||
) -> Result<std::option::Option<crate::LaunchSurfaceDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbLaunchSurfaceEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::LaunchSurfaceEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -82,7 +82,7 @@ SELECT
|
||||
is_enabled,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM kb_launch_surfaces
|
||||
FROM k_sol_launch_surfaces
|
||||
WHERE code = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -93,14 +93,14 @@ LIMIT 1
|
||||
let entity_option = match query_result {
|
||||
Ok(entity_option) => entity_option,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot read kb_launch_surfaces '{}' on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot read k_sol_launch_surfaces '{}' on sqlite: {}",
|
||||
code, error
|
||||
)));
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => return crate::KbLaunchSurfaceDto::try_from(entity).map(Some),
|
||||
Some(entity) => return crate::LaunchSurfaceDto::try_from(entity).map(Some),
|
||||
None => return Ok(None),
|
||||
}
|
||||
},
|
||||
@@ -108,12 +108,12 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Lists all persisted launch surfaces ordered by code.
|
||||
pub async fn list_launch_surfaces(
|
||||
database: &crate::KbDatabase,
|
||||
) -> Result<std::vec::Vec<crate::KbLaunchSurfaceDto>, crate::KbError> {
|
||||
pub async fn query_launch_surfaces_list(
|
||||
database: &crate::Database,
|
||||
) -> Result<std::vec::Vec<crate::LaunchSurfaceDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbLaunchSurfaceEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::LaunchSurfaceEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -123,7 +123,7 @@ SELECT
|
||||
is_enabled,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM kb_launch_surfaces
|
||||
FROM k_sol_launch_surfaces
|
||||
ORDER BY code ASC
|
||||
"#,
|
||||
)
|
||||
@@ -132,15 +132,15 @@ ORDER BY code ASC
|
||||
let entities = match query_result {
|
||||
Ok(entities) => entities,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot list kb_launch_surfaces on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot list k_sol_launch_surfaces on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
let dto_result = crate::KbLaunchSurfaceDto::try_from(entity);
|
||||
let dto_result = crate::LaunchSurfaceDto::try_from(entity);
|
||||
let dto = match dto_result {
|
||||
Ok(dto) => dto,
|
||||
Err(error) => return Err(error),
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
// file: kb_lib/src/db/queries/launch_surface_key.rs
|
||||
|
||||
//! Queries for `kb_launch_surface_keys`.
|
||||
//! Queries for `k_sol_launch_surface_keys`.
|
||||
|
||||
/// Inserts or updates one launch-surface matching key and returns its stable internal id.
|
||||
pub async fn upsert_launch_surface_key(
|
||||
database: &crate::KbDatabase,
|
||||
dto: &crate::KbLaunchSurfaceKeyDto,
|
||||
) -> Result<i64, crate::KbError> {
|
||||
pub async fn query_launch_surface_keys_upsert(
|
||||
database: &crate::Database,
|
||||
dto: &crate::LaunchSurfaceKeyDto,
|
||||
) -> Result<i64, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query(
|
||||
r#"
|
||||
INSERT INTO kb_launch_surface_keys (
|
||||
INSERT INTO k_sol_launch_surface_keys (
|
||||
launch_surface_id,
|
||||
match_kind,
|
||||
match_value,
|
||||
@@ -32,15 +32,15 @@ ON CONFLICT(match_kind, match_value) DO UPDATE SET
|
||||
.execute(pool)
|
||||
.await;
|
||||
if let Err(error) = query_result {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot upsert kb_launch_surface_keys on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot upsert k_sol_launch_surface_keys on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
let id_result = sqlx::query_scalar::<sqlx::Sqlite, i64>(
|
||||
r#"
|
||||
SELECT id
|
||||
FROM kb_launch_surface_keys
|
||||
FROM k_sol_launch_surface_keys
|
||||
WHERE match_kind = ? AND match_value = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -52,8 +52,8 @@ LIMIT 1
|
||||
match id_result {
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_launch_surface_keys id for '{}:{}' on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot fetch k_sol_launch_surface_keys id for '{}:{}' on sqlite: {}",
|
||||
dto.match_kind, dto.match_value, error
|
||||
)));
|
||||
},
|
||||
@@ -63,14 +63,14 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Returns one launch-surface matching key identified by its kind and value, if it exists.
|
||||
pub async fn get_launch_surface_key_by_match(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_launch_surface_keys_get_by_match(
|
||||
database: &crate::Database,
|
||||
match_kind: &str,
|
||||
match_value: &str,
|
||||
) -> Result<std::option::Option<crate::KbLaunchSurfaceKeyDto>, crate::KbError> {
|
||||
) -> Result<std::option::Option<crate::LaunchSurfaceKeyDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbLaunchSurfaceKeyEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::LaunchSurfaceKeyEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -79,7 +79,7 @@ SELECT
|
||||
match_value,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM kb_launch_surface_keys
|
||||
FROM k_sol_launch_surface_keys
|
||||
WHERE match_kind = ? AND match_value = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -91,14 +91,14 @@ LIMIT 1
|
||||
let entity_option = match query_result {
|
||||
Ok(entity_option) => entity_option,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot read kb_launch_surface_keys '{}:{}' on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot read k_sol_launch_surface_keys '{}:{}' on sqlite: {}",
|
||||
match_kind, match_value, error
|
||||
)));
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => return crate::KbLaunchSurfaceKeyDto::try_from(entity).map(Some),
|
||||
Some(entity) => return crate::LaunchSurfaceKeyDto::try_from(entity).map(Some),
|
||||
None => return Ok(None),
|
||||
}
|
||||
},
|
||||
@@ -106,13 +106,13 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Lists all launch-surface matching keys attached to one launch surface id.
|
||||
pub async fn list_launch_surface_keys_by_surface_id(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_launch_surface_keys_list_by_surface_id(
|
||||
database: &crate::Database,
|
||||
launch_surface_id: i64,
|
||||
) -> Result<std::vec::Vec<crate::KbLaunchSurfaceKeyDto>, crate::KbError> {
|
||||
) -> Result<std::vec::Vec<crate::LaunchSurfaceKeyDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbLaunchSurfaceKeyEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::LaunchSurfaceKeyEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -121,7 +121,7 @@ SELECT
|
||||
match_value,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM kb_launch_surface_keys
|
||||
FROM k_sol_launch_surface_keys
|
||||
WHERE launch_surface_id = ?
|
||||
ORDER BY match_kind ASC, match_value ASC
|
||||
"#,
|
||||
@@ -132,15 +132,15 @@ ORDER BY match_kind ASC, match_value ASC
|
||||
let entities = match query_result {
|
||||
Ok(entities) => entities,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot list kb_launch_surface_keys by surface_id '{}' on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot list k_sol_launch_surface_keys by surface_id '{}' on sqlite: {}",
|
||||
launch_surface_id, error
|
||||
)));
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
let dto_result = crate::KbLaunchSurfaceKeyDto::try_from(entity);
|
||||
let dto_result = crate::LaunchSurfaceKeyDto::try_from(entity);
|
||||
let dto = match dto_result {
|
||||
Ok(dto) => dto,
|
||||
Err(error) => return Err(error),
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
// file: kb_lib/src/db/queries/liquidity_event.rs
|
||||
|
||||
//! Queries for `kb_liquidity_events`.
|
||||
//! Queries for `k_sol_liquidity_events`.
|
||||
|
||||
/// Inserts or updates one normalized liquidity event row.
|
||||
pub async fn upsert_liquidity_event(
|
||||
database: &crate::KbDatabase,
|
||||
dto: &crate::KbLiquidityEventDto,
|
||||
) -> Result<i64, crate::KbError> {
|
||||
pub async fn query_liquidity_events_upsert(
|
||||
database: &crate::Database,
|
||||
dto: &crate::LiquidityEventDto,
|
||||
) -> Result<i64, crate::Error> {
|
||||
let slot_i64 = match dto.slot {
|
||||
Some(slot) => {
|
||||
let slot_result = i64::try_from(slot);
|
||||
match slot_result {
|
||||
Ok(slot) => Some(slot),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot convert liquidity event slot '{}' to i64: {}",
|
||||
slot, error
|
||||
)));
|
||||
@@ -23,10 +23,10 @@ pub async fn upsert_liquidity_event(
|
||||
None => None,
|
||||
};
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query(
|
||||
r#"
|
||||
INSERT INTO kb_liquidity_events (
|
||||
INSERT INTO k_sol_liquidity_events (
|
||||
dex_id,
|
||||
pool_id,
|
||||
pair_id,
|
||||
@@ -78,15 +78,15 @@ ON CONFLICT(signature, instruction_index) DO UPDATE SET
|
||||
.execute(pool)
|
||||
.await;
|
||||
if let Err(error) = query_result {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot upsert kb_liquidity_events on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot upsert k_sol_liquidity_events on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
let id_result = sqlx::query_scalar::<sqlx::Sqlite, i64>(
|
||||
r#"
|
||||
SELECT id
|
||||
FROM kb_liquidity_events
|
||||
FROM k_sol_liquidity_events
|
||||
WHERE signature = ? AND instruction_index = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -98,8 +98,8 @@ LIMIT 1
|
||||
match id_result {
|
||||
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: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot fetch k_sol_liquidity_events id for signature '{}' and instruction_index '{}' on sqlite: {}",
|
||||
dto.signature, dto.instruction_index, error
|
||||
)));
|
||||
},
|
||||
@@ -109,16 +109,16 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Lists recent liquidity events ordered from newest to oldest.
|
||||
pub async fn list_recent_liquidity_events(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_liquidity_events_list_recent(
|
||||
database: &crate::Database,
|
||||
limit: u32,
|
||||
) -> Result<std::vec::Vec<crate::KbLiquidityEventDto>, crate::KbError> {
|
||||
) -> Result<std::vec::Vec<crate::LiquidityEventDto>, crate::Error> {
|
||||
if limit == 0 {
|
||||
return Ok(std::vec::Vec::new());
|
||||
}
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbLiquidityEventEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::LiquidityEventEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -137,7 +137,7 @@ SELECT
|
||||
quote_amount,
|
||||
lp_amount,
|
||||
executed_at
|
||||
FROM kb_liquidity_events
|
||||
FROM k_sol_liquidity_events
|
||||
ORDER BY id DESC
|
||||
LIMIT ?
|
||||
"#,
|
||||
@@ -148,15 +148,15 @@ LIMIT ?
|
||||
let entities = match query_result {
|
||||
Ok(entities) => entities,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot list kb_liquidity_events on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot list k_sol_liquidity_events on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
let dto_result = crate::KbLiquidityEventDto::try_from(entity);
|
||||
let dto_result = crate::LiquidityEventDto::try_from(entity);
|
||||
let dto = match dto_result {
|
||||
Ok(dto) => dto,
|
||||
Err(error) => return Err(error),
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,18 +1,18 @@
|
||||
// file: kb_lib/src/db/queries/observed_token.rs
|
||||
|
||||
//! Queries for `kb_observed_tokens`.
|
||||
//! Queries for `k_sol_observed_tokens`.
|
||||
|
||||
/// Inserts or updates one observed token by mint.
|
||||
pub async fn upsert_observed_token(
|
||||
database: &crate::KbDatabase,
|
||||
dto: &crate::KbObservedTokenDto,
|
||||
) -> Result<i64, crate::KbError> {
|
||||
pub async fn query_observed_tokens_upsert(
|
||||
database: &crate::Database,
|
||||
dto: &crate::ObservedTokenDto,
|
||||
) -> Result<i64, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let decimals_i64 = dto.decimals.map(i64::from);
|
||||
let insert_result = sqlx::query(
|
||||
r#"
|
||||
INSERT INTO kb_observed_tokens (
|
||||
INSERT INTO k_sol_observed_tokens (
|
||||
mint,
|
||||
symbol,
|
||||
name,
|
||||
@@ -46,15 +46,15 @@ ON CONFLICT(mint) DO UPDATE SET
|
||||
.execute(pool)
|
||||
.await;
|
||||
if let Err(error) = insert_result {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot upsert kb_observed_tokens on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot upsert k_sol_observed_tokens on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
let select_result = sqlx::query_scalar::<sqlx::Sqlite, i64>(
|
||||
r#"
|
||||
SELECT id
|
||||
FROM kb_observed_tokens
|
||||
FROM k_sol_observed_tokens
|
||||
WHERE mint = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -65,8 +65,8 @@ LIMIT 1
|
||||
match select_result {
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_observed_tokens id for mint '{}' on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot fetch k_sol_observed_tokens id for mint '{}' on sqlite: {}",
|
||||
dto.mint, error
|
||||
)));
|
||||
},
|
||||
@@ -76,13 +76,13 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Reads one observed token by mint.
|
||||
pub async fn get_observed_token_by_mint(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_observed_tokens_get_by_mint(
|
||||
database: &crate::Database,
|
||||
mint: &str,
|
||||
) -> Result<std::option::Option<crate::KbObservedTokenDto>, crate::KbError> {
|
||||
) -> Result<std::option::Option<crate::ObservedTokenDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbObservedTokenEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::ObservedTokenEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -95,7 +95,7 @@ SELECT
|
||||
first_seen_at,
|
||||
last_seen_at,
|
||||
updated_at
|
||||
FROM kb_observed_tokens
|
||||
FROM k_sol_observed_tokens
|
||||
WHERE mint = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -106,7 +106,7 @@ LIMIT 1
|
||||
let entity_option = match query_result {
|
||||
Ok(entity_option) => entity_option,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot read observed token '{}' on sqlite: {}",
|
||||
mint, error
|
||||
)));
|
||||
@@ -114,7 +114,7 @@ LIMIT 1
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => {
|
||||
let dto_result = crate::KbObservedTokenDto::try_from(entity);
|
||||
let dto_result = crate::ObservedTokenDto::try_from(entity);
|
||||
match dto_result {
|
||||
Ok(dto) => return Ok(Some(dto)),
|
||||
Err(error) => return Err(error),
|
||||
@@ -127,16 +127,16 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Lists observed tokens ordered by newest first.
|
||||
pub async fn list_observed_tokens(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_observed_tokens_list(
|
||||
database: &crate::Database,
|
||||
limit: u32,
|
||||
) -> Result<std::vec::Vec<crate::KbObservedTokenDto>, crate::KbError> {
|
||||
) -> Result<std::vec::Vec<crate::ObservedTokenDto>, crate::Error> {
|
||||
if limit == 0 {
|
||||
return Ok(std::vec::Vec::new());
|
||||
}
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbObservedTokenEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::ObservedTokenEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -149,7 +149,7 @@ SELECT
|
||||
first_seen_at,
|
||||
last_seen_at,
|
||||
updated_at
|
||||
FROM kb_observed_tokens
|
||||
FROM k_sol_observed_tokens
|
||||
ORDER BY id DESC
|
||||
LIMIT ?
|
||||
"#,
|
||||
@@ -160,7 +160,7 @@ LIMIT ?
|
||||
let entities = match query_result {
|
||||
Ok(entities) => entities,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot list observed tokens on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
@@ -168,7 +168,7 @@ LIMIT ?
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
let dto_result = crate::KbObservedTokenDto::try_from(entity);
|
||||
let dto_result = crate::ObservedTokenDto::try_from(entity);
|
||||
let dto = match dto_result {
|
||||
Ok(dto) => dto,
|
||||
Err(error) => return Err(error),
|
||||
@@ -186,10 +186,10 @@ mod tests {
|
||||
async fn observed_token_roundtrip_works() {
|
||||
let tempdir = tempfile::tempdir().expect("tempdir must succeed");
|
||||
let database_path = tempdir.path().join("observed_token.sqlite3");
|
||||
let config = crate::KbDatabaseConfig {
|
||||
let config = crate::DatabaseConfig {
|
||||
enabled: true,
|
||||
backend: crate::KbDatabaseBackend::Sqlite,
|
||||
sqlite: crate::KbSqliteDatabaseConfig {
|
||||
backend: crate::DatabaseBackend::Sqlite,
|
||||
sqlite: crate::SqliteDatabaseConfig {
|
||||
path: database_path.to_string_lossy().to_string(),
|
||||
create_if_missing: true,
|
||||
busy_timeout_ms: 5000,
|
||||
@@ -198,33 +198,32 @@ mod tests {
|
||||
use_wal: true,
|
||||
},
|
||||
};
|
||||
let database = crate::KbDatabase::connect_and_initialize(&config)
|
||||
let database = crate::Database::connect_and_initialize(&config)
|
||||
.await
|
||||
.expect("database init must succeed");
|
||||
let dto = crate::KbObservedTokenDto::new(
|
||||
"So11111111111111111111111111111111111111112".to_string(),
|
||||
let dto = crate::ObservedTokenDto::new(
|
||||
crate::WSOL_MINT_ID.to_string(),
|
||||
Some("WSOL".to_string()),
|
||||
Some("Wrapped SOL".to_string()),
|
||||
Some(9),
|
||||
crate::SPL_TOKEN_PROGRAM_ID.to_string(),
|
||||
crate::KbObservedTokenStatus::Active,
|
||||
crate::ObservedTokenStatus::Active,
|
||||
);
|
||||
let inserted_id = crate::upsert_observed_token(&database, &dto)
|
||||
let inserted_id = crate::query_observed_tokens_upsert(&database, &dto)
|
||||
.await
|
||||
.expect("upsert must succeed");
|
||||
assert!(inserted_id > 0);
|
||||
let fetched = crate::get_observed_token_by_mint(
|
||||
&database,
|
||||
"So11111111111111111111111111111111111111112",
|
||||
)
|
||||
.await
|
||||
.expect("fetch must succeed");
|
||||
let fetched = crate::query_observed_tokens_get_by_mint(&database, crate::WSOL_MINT_ID)
|
||||
.await
|
||||
.expect("fetch must succeed");
|
||||
assert!(fetched.is_some());
|
||||
let fetched = fetched.expect("token must exist");
|
||||
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");
|
||||
assert_eq!(fetched.status, crate::ObservedTokenStatus::Active);
|
||||
let listed = crate::query_observed_tokens_list(&database, 10)
|
||||
.await
|
||||
.expect("list must succeed");
|
||||
assert_eq!(listed.len(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
// file: kb_lib/src/db/queries/onchain_observation.rs
|
||||
|
||||
//! Queries for `kb_onchain_observations`.
|
||||
//! Queries for `k_sol_onchain_observations`.
|
||||
|
||||
/// Inserts one on-chain observation row and returns its numeric id.
|
||||
pub async fn insert_onchain_observation(
|
||||
database: &crate::KbDatabase,
|
||||
dto: &crate::KbOnchainObservationDto,
|
||||
) -> Result<i64, crate::KbError> {
|
||||
pub async fn query_onchain_observations_insert(
|
||||
database: &crate::Database,
|
||||
dto: &crate::OnchainObservationDto,
|
||||
) -> Result<i64, crate::Error> {
|
||||
let payload_json_result = serde_json::to_string(&dto.payload);
|
||||
let payload_json = match payload_json_result {
|
||||
Ok(payload_json) => payload_json,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot serialize on-chain observation payload: {}",
|
||||
error
|
||||
)));
|
||||
@@ -23,7 +23,7 @@ pub async fn insert_onchain_observation(
|
||||
match slot_result {
|
||||
Ok(slot) => Some(slot),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot convert on-chain observation slot '{}' to i64: {}",
|
||||
slot, error
|
||||
)));
|
||||
@@ -33,10 +33,10 @@ pub async fn insert_onchain_observation(
|
||||
None => None,
|
||||
};
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query(
|
||||
r#"
|
||||
INSERT INTO kb_onchain_observations (
|
||||
INSERT INTO k_sol_onchain_observations (
|
||||
observation_kind,
|
||||
source_kind,
|
||||
endpoint_name,
|
||||
@@ -60,8 +60,8 @@ VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
let query_result = match query_result {
|
||||
Ok(query_result) => query_result,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot insert kb_onchain_observations on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot insert k_sol_onchain_observations on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
@@ -72,16 +72,16 @@ VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
}
|
||||
|
||||
/// Lists recent on-chain observations ordered from newest to oldest.
|
||||
pub async fn list_recent_onchain_observations(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_onchain_observations_list_recent(
|
||||
database: &crate::Database,
|
||||
limit: u32,
|
||||
) -> Result<std::vec::Vec<crate::KbOnchainObservationDto>, crate::KbError> {
|
||||
) -> Result<std::vec::Vec<crate::OnchainObservationDto>, crate::Error> {
|
||||
if limit == 0 {
|
||||
return Ok(std::vec::Vec::new());
|
||||
}
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbOnchainObservationEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::OnchainObservationEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -92,7 +92,7 @@ SELECT
|
||||
slot,
|
||||
payload_json,
|
||||
observed_at
|
||||
FROM kb_onchain_observations
|
||||
FROM k_sol_onchain_observations
|
||||
ORDER BY id DESC
|
||||
LIMIT ?
|
||||
"#,
|
||||
@@ -103,7 +103,7 @@ LIMIT ?
|
||||
let entities = match query_result {
|
||||
Ok(entities) => entities,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot list on-chain observations on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
@@ -111,7 +111,7 @@ LIMIT ?
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
let dto_result = crate::KbOnchainObservationDto::try_from(entity);
|
||||
let dto_result = crate::OnchainObservationDto::try_from(entity);
|
||||
let dto = match dto_result {
|
||||
Ok(dto) => dto,
|
||||
Err(error) => return Err(error),
|
||||
@@ -129,10 +129,10 @@ mod tests {
|
||||
async fn onchain_observation_roundtrip_works() {
|
||||
let tempdir = tempfile::tempdir().expect("tempdir must succeed");
|
||||
let database_path = tempdir.path().join("onchain_observation.sqlite3");
|
||||
let config = crate::KbDatabaseConfig {
|
||||
let config = crate::DatabaseConfig {
|
||||
enabled: true,
|
||||
backend: crate::KbDatabaseBackend::Sqlite,
|
||||
sqlite: crate::KbSqliteDatabaseConfig {
|
||||
backend: crate::DatabaseBackend::Sqlite,
|
||||
sqlite: crate::SqliteDatabaseConfig {
|
||||
path: database_path.to_string_lossy().to_string(),
|
||||
create_if_missing: true,
|
||||
busy_timeout_ms: 5000,
|
||||
@@ -141,30 +141,30 @@ mod tests {
|
||||
use_wal: true,
|
||||
},
|
||||
};
|
||||
let database = crate::KbDatabase::connect_and_initialize(&config)
|
||||
let database = crate::Database::connect_and_initialize(&config)
|
||||
.await
|
||||
.expect("database init must succeed");
|
||||
let dto = crate::KbOnchainObservationDto::new(
|
||||
let dto = crate::OnchainObservationDto::new(
|
||||
"token_discovered".to_string(),
|
||||
crate::KbObservationSourceKind::WsRpc,
|
||||
crate::ObservationSourceKind::WsRpc,
|
||||
Some("mainnet_public_ws_slots".to_string()),
|
||||
"So11111111111111111111111111111111111111112".to_string(),
|
||||
crate::WSOL_MINT_ID.to_string(),
|
||||
Some(123456u64),
|
||||
serde_json::json!({
|
||||
"mint": "So11111111111111111111111111111111111111112",
|
||||
"mint": crate::WSOL_MINT_ID,
|
||||
"source": "ws"
|
||||
}),
|
||||
);
|
||||
let inserted_id = crate::insert_onchain_observation(&database, &dto)
|
||||
let inserted_id = crate::query_onchain_observations_insert(&database, &dto)
|
||||
.await
|
||||
.expect("insert must succeed");
|
||||
assert!(inserted_id > 0);
|
||||
let listed = crate::list_recent_onchain_observations(&database, 10)
|
||||
let listed = crate::query_onchain_observations_list_recent(&database, 10)
|
||||
.await
|
||||
.expect("list must succeed");
|
||||
assert_eq!(listed.len(), 1);
|
||||
assert_eq!(listed[0].observation_kind, "token_discovered");
|
||||
assert_eq!(listed[0].source_kind, crate::KbObservationSourceKind::WsRpc);
|
||||
assert_eq!(listed[0].source_kind, crate::ObservationSourceKind::WsRpc);
|
||||
assert_eq!(listed[0].slot, Some(123456u64));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
// file: kb_lib/src/db/queries/pair.rs
|
||||
|
||||
//! Queries for `kb_pairs`.
|
||||
//! Queries for `k_sol_pairs`.
|
||||
|
||||
/// Inserts or updates one normalized pair row by pool id.
|
||||
pub async fn upsert_pair(
|
||||
database: &crate::KbDatabase,
|
||||
dto: &crate::KbPairDto,
|
||||
) -> Result<i64, crate::KbError> {
|
||||
pub async fn query_pairs_upsert(
|
||||
database: &crate::Database,
|
||||
dto: &crate::PairDto,
|
||||
) -> Result<i64, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query(
|
||||
r#"
|
||||
INSERT INTO kb_pairs (
|
||||
INSERT INTO k_sol_pairs (
|
||||
dex_id,
|
||||
pool_id,
|
||||
base_token_id,
|
||||
@@ -28,7 +28,7 @@ ON CONFLICT(pool_id) DO UPDATE SET
|
||||
symbol = CASE
|
||||
WHEN excluded.symbol IS NOT NULL AND trim(excluded.symbol) <> ''
|
||||
THEN excluded.symbol
|
||||
ELSE kb_pairs.symbol
|
||||
ELSE k_sol_pairs.symbol
|
||||
END,
|
||||
updated_at = excluded.updated_at
|
||||
"#,
|
||||
@@ -43,15 +43,15 @@ ON CONFLICT(pool_id) DO UPDATE SET
|
||||
.execute(pool)
|
||||
.await;
|
||||
if let Err(error) = query_result {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot upsert kb_pairs on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot upsert k_sol_pairs on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
let id_result = sqlx::query_scalar::<sqlx::Sqlite, i64>(
|
||||
r#"
|
||||
SELECT id
|
||||
FROM kb_pairs
|
||||
FROM k_sol_pairs
|
||||
WHERE pool_id = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -62,8 +62,8 @@ LIMIT 1
|
||||
match id_result {
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_pairs id for pool_id '{}' on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot fetch k_sol_pairs id for pool_id '{}' on sqlite: {}",
|
||||
dto.pool_id, error
|
||||
)));
|
||||
},
|
||||
@@ -73,13 +73,13 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Reads one normalized pair row by pool id.
|
||||
pub async fn get_pair_by_pool_id(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_pairs_get_by_pool_id(
|
||||
database: &crate::Database,
|
||||
pool_id: i64,
|
||||
) -> Result<std::option::Option<crate::KbPairDto>, crate::KbError> {
|
||||
) -> Result<std::option::Option<crate::PairDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbPairEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::PairEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -90,7 +90,7 @@ SELECT
|
||||
symbol,
|
||||
first_seen_at,
|
||||
updated_at
|
||||
FROM kb_pairs
|
||||
FROM k_sol_pairs
|
||||
WHERE pool_id = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -101,15 +101,15 @@ LIMIT 1
|
||||
let entity_option = match query_result {
|
||||
Ok(entity_option) => entity_option,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot read kb_pairs by pool_id '{}' on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot read k_sol_pairs by pool_id '{}' on sqlite: {}",
|
||||
pool_id, error
|
||||
)));
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => {
|
||||
let dto_result = crate::KbPairDto::try_from(entity);
|
||||
let dto_result = crate::PairDto::try_from(entity);
|
||||
match dto_result {
|
||||
Ok(dto) => return Ok(Some(dto)),
|
||||
Err(error) => return Err(error),
|
||||
@@ -122,16 +122,16 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Updates the display symbol of one normalized pair row.
|
||||
pub async fn update_pair_symbol(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_pairs_update_symbol(
|
||||
database: &crate::Database,
|
||||
pair_id: i64,
|
||||
symbol: std::option::Option<&str>,
|
||||
) -> Result<bool, crate::KbError> {
|
||||
) -> Result<bool, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query(
|
||||
r#"
|
||||
UPDATE kb_pairs
|
||||
UPDATE k_sol_pairs
|
||||
SET
|
||||
symbol = ?,
|
||||
updated_at = ?
|
||||
@@ -146,8 +146,8 @@ WHERE id = ?
|
||||
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: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot update k_sol_pairs symbol for id '{}' on sqlite: {}",
|
||||
pair_id, error
|
||||
)));
|
||||
},
|
||||
@@ -157,12 +157,12 @@ WHERE id = ?
|
||||
}
|
||||
|
||||
/// Lists normalized pairs ordered by id ascending.
|
||||
pub async fn list_pairs(
|
||||
database: &crate::KbDatabase,
|
||||
) -> Result<std::vec::Vec<crate::KbPairDto>, crate::KbError> {
|
||||
pub async fn query_pairs_list(
|
||||
database: &crate::Database,
|
||||
) -> Result<std::vec::Vec<crate::PairDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbPairEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::PairEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -173,7 +173,7 @@ SELECT
|
||||
symbol,
|
||||
first_seen_at,
|
||||
updated_at
|
||||
FROM kb_pairs
|
||||
FROM k_sol_pairs
|
||||
ORDER BY id ASC
|
||||
"#,
|
||||
)
|
||||
@@ -182,15 +182,15 @@ ORDER BY id ASC
|
||||
let entities = match query_result {
|
||||
Ok(entities) => entities,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot list kb_pairs on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot list k_sol_pairs on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
let dto_result = crate::KbPairDto::try_from(entity);
|
||||
let dto_result = crate::PairDto::try_from(entity);
|
||||
let dto = match dto_result {
|
||||
Ok(dto) => dto,
|
||||
Err(error) => return Err(error),
|
||||
@@ -208,10 +208,10 @@ mod tests {
|
||||
async fn pair_roundtrip_works() {
|
||||
let tempdir = tempfile::tempdir().expect("tempdir must succeed");
|
||||
let database_path = tempdir.path().join("pair_roundtrip.sqlite3");
|
||||
let config = crate::KbDatabaseConfig {
|
||||
let config = crate::DatabaseConfig {
|
||||
enabled: true,
|
||||
backend: crate::KbDatabaseBackend::Sqlite,
|
||||
sqlite: crate::KbSqliteDatabaseConfig {
|
||||
backend: crate::DatabaseBackend::Sqlite,
|
||||
sqlite: crate::SqliteDatabaseConfig {
|
||||
path: database_path.to_string_lossy().to_string(),
|
||||
create_if_missing: true,
|
||||
busy_timeout_ms: 5000,
|
||||
@@ -220,18 +220,18 @@ mod tests {
|
||||
use_wal: true,
|
||||
},
|
||||
};
|
||||
let database = crate::KbDatabase::connect_and_initialize(&config)
|
||||
let database = crate::Database::connect_and_initialize(&config)
|
||||
.await
|
||||
.expect("database init must succeed");
|
||||
let dex_id = crate::upsert_dex(
|
||||
let dex_id = crate::query_dexs_upsert(
|
||||
&database,
|
||||
&crate::KbDexDto::new("raydium".to_string(), "Raydium".to_string(), None, None, true),
|
||||
&crate::DexDto::new("raydium".to_string(), "Raydium".to_string(), None, None, true),
|
||||
)
|
||||
.await
|
||||
.expect("dex upsert must succeed");
|
||||
let base_token_id = crate::upsert_token(
|
||||
let base_token_id = crate::query_tokens_upsert(
|
||||
&database,
|
||||
&crate::KbTokenDto::new(
|
||||
&crate::TokenDto::new(
|
||||
"Base111111111111111111111111111111111111111".to_string(),
|
||||
Some("BASE".to_string()),
|
||||
Some("Base Token".to_string()),
|
||||
@@ -242,10 +242,10 @@ mod tests {
|
||||
)
|
||||
.await
|
||||
.expect("base token upsert must succeed");
|
||||
let quote_token_id = crate::upsert_token(
|
||||
let quote_token_id = crate::query_tokens_upsert(
|
||||
&database,
|
||||
&crate::KbTokenDto::new(
|
||||
"So11111111111111111111111111111111111111112".to_string(),
|
||||
&crate::TokenDto::new(
|
||||
crate::WSOL_MINT_ID.to_string(),
|
||||
Some("WSOL".to_string()),
|
||||
Some("Wrapped SOL".to_string()),
|
||||
Some(9),
|
||||
@@ -255,20 +255,20 @@ mod tests {
|
||||
)
|
||||
.await
|
||||
.expect("quote token upsert must succeed");
|
||||
let pool_id = crate::upsert_pool(
|
||||
let pool_id = crate::query_pools_upsert(
|
||||
&database,
|
||||
&crate::KbPoolDto::new(
|
||||
&crate::PoolDto::new(
|
||||
dex_id,
|
||||
"Pool111111111111111111111111111111111111111".to_string(),
|
||||
crate::KbPoolKind::Amm,
|
||||
crate::KbPoolStatus::Active,
|
||||
crate::PoolKind::Amm,
|
||||
crate::PoolStatus::Active,
|
||||
),
|
||||
)
|
||||
.await
|
||||
.expect("pool upsert must succeed");
|
||||
let pair_id = crate::upsert_pair(
|
||||
let pair_id = crate::query_pairs_upsert(
|
||||
&database,
|
||||
&crate::KbPairDto::new(
|
||||
&crate::PairDto::new(
|
||||
dex_id,
|
||||
pool_id,
|
||||
base_token_id,
|
||||
@@ -279,12 +279,12 @@ mod tests {
|
||||
.await
|
||||
.expect("pair upsert must succeed");
|
||||
assert!(pair_id > 0);
|
||||
let pair = crate::get_pair_by_pool_id(&database, pool_id)
|
||||
let pair = crate::query_pairs_get_by_pool_id(&database, pool_id)
|
||||
.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");
|
||||
let pairs = crate::query_pairs_list(&database).await.expect("list pairs must succeed");
|
||||
assert_eq!(pairs.len(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
// file: kb_lib/src/db/queries/pair_analytic_signal.rs
|
||||
|
||||
//! Queries for `kb_pair_analytic_signals`.
|
||||
//! Queries for `k_sol_pair_analytic_signals`.
|
||||
|
||||
/// Inserts or updates one pair-analytic-signal row and returns its stable internal id.
|
||||
pub async fn upsert_pair_analytic_signal(
|
||||
database: &crate::KbDatabase,
|
||||
dto: &crate::KbPairAnalyticSignalDto,
|
||||
) -> Result<i64, crate::KbError> {
|
||||
pub async fn query_pair_analytic_signals_upsert(
|
||||
database: &crate::Database,
|
||||
dto: &crate::PairAnalyticSignalDto,
|
||||
) -> Result<i64, crate::Error> {
|
||||
let signal_value_json_result = serde_json::to_string(&dto.signal_value);
|
||||
let signal_value_json = match signal_value_json_result {
|
||||
Ok(signal_value_json) => signal_value_json,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot serialize pair analytic signal payload: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
};
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query(
|
||||
r#"
|
||||
INSERT INTO kb_pair_analytic_signals (
|
||||
INSERT INTO k_sol_pair_analytic_signals (
|
||||
pair_id,
|
||||
signal_kind,
|
||||
severity,
|
||||
@@ -57,15 +57,15 @@ ON CONFLICT(pair_id, signal_kind, timeframe_seconds, bucket_start_unix) DO UPDAT
|
||||
.execute(pool)
|
||||
.await;
|
||||
if let Err(error) = query_result {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot upsert kb_pair_analytic_signals on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot upsert k_sol_pair_analytic_signals on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
let id_result = sqlx::query_scalar::<sqlx::Sqlite, i64>(
|
||||
r#"
|
||||
SELECT id
|
||||
FROM kb_pair_analytic_signals
|
||||
FROM k_sol_pair_analytic_signals
|
||||
WHERE pair_id = ? AND signal_kind = ? AND timeframe_seconds = ? AND bucket_start_unix = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -79,8 +79,8 @@ LIMIT 1
|
||||
match id_result {
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_pair_analytic_signals id on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot fetch k_sol_pair_analytic_signals id on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
@@ -90,16 +90,16 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Returns one pair-analytic-signal row identified by its key, if it exists.
|
||||
pub async fn get_pair_analytic_signal_by_key(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_pair_analytic_signals_get_by_key(
|
||||
database: &crate::Database,
|
||||
pair_id: i64,
|
||||
signal_kind: &str,
|
||||
timeframe_seconds: i64,
|
||||
bucket_start_unix: i64,
|
||||
) -> Result<std::option::Option<crate::KbPairAnalyticSignalDto>, crate::KbError> {
|
||||
) -> Result<std::option::Option<crate::PairAnalyticSignalDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbPairAnalyticSignalEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::PairAnalyticSignalEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -114,7 +114,7 @@ SELECT
|
||||
last_transaction_id,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM kb_pair_analytic_signals
|
||||
FROM k_sol_pair_analytic_signals
|
||||
WHERE pair_id = ? AND signal_kind = ? AND timeframe_seconds = ? AND bucket_start_unix = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -128,14 +128,14 @@ LIMIT 1
|
||||
let entity_option = match query_result {
|
||||
Ok(entity_option) => entity_option,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot read kb_pair_analytic_signals by key on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot read k_sol_pair_analytic_signals by key on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => return crate::KbPairAnalyticSignalDto::try_from(entity).map(Some),
|
||||
Some(entity) => return crate::PairAnalyticSignalDto::try_from(entity).map(Some),
|
||||
None => return Ok(None),
|
||||
}
|
||||
},
|
||||
@@ -143,13 +143,13 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Lists all pair-analytic signals for one pair ordered by key.
|
||||
pub async fn list_pair_analytic_signals_by_pair_id(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_pair_analytic_signals_list_by_pair_id(
|
||||
database: &crate::Database,
|
||||
pair_id: i64,
|
||||
) -> Result<std::vec::Vec<crate::KbPairAnalyticSignalDto>, crate::KbError> {
|
||||
) -> Result<std::vec::Vec<crate::PairAnalyticSignalDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbPairAnalyticSignalEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::PairAnalyticSignalEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -164,7 +164,7 @@ SELECT
|
||||
last_transaction_id,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM kb_pair_analytic_signals
|
||||
FROM k_sol_pair_analytic_signals
|
||||
WHERE pair_id = ?
|
||||
ORDER BY timeframe_seconds ASC, bucket_start_unix ASC, signal_kind ASC, id ASC
|
||||
"#,
|
||||
@@ -175,15 +175,15 @@ ORDER BY timeframe_seconds ASC, bucket_start_unix ASC, signal_kind ASC, id ASC
|
||||
let entities = match query_result {
|
||||
Ok(entities) => entities,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot list kb_pair_analytic_signals by pair_id '{}' on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot list k_sol_pair_analytic_signals by pair_id '{}' on sqlite: {}",
|
||||
pair_id, error
|
||||
)));
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
let dto_result = crate::KbPairAnalyticSignalDto::try_from(entity);
|
||||
let dto_result = crate::PairAnalyticSignalDto::try_from(entity);
|
||||
let dto = match dto_result {
|
||||
Ok(dto) => dto,
|
||||
Err(error) => return Err(error),
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
// file: kb_lib/src/db/queries/pair_candle.rs
|
||||
|
||||
//! Queries for `kb_pair_candles`.
|
||||
//! Queries for `k_sol_pair_candles`.
|
||||
|
||||
/// Inserts or updates one pair-candle row and returns its stable internal id.
|
||||
pub async fn upsert_pair_candle(
|
||||
database: &crate::KbDatabase,
|
||||
dto: &crate::KbPairCandleDto,
|
||||
) -> Result<i64, crate::KbError> {
|
||||
pub async fn query_pair_candles_upsert(
|
||||
database: &crate::Database,
|
||||
dto: &crate::PairCandleDto,
|
||||
) -> Result<i64, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query(
|
||||
r#"
|
||||
INSERT INTO kb_pair_candles (
|
||||
INSERT INTO k_sol_pair_candles (
|
||||
pair_id,
|
||||
timeframe_seconds,
|
||||
bucket_start_unix,
|
||||
@@ -67,8 +67,8 @@ ON CONFLICT(pair_id, timeframe_seconds, bucket_start_unix) DO UPDATE SET
|
||||
.execute(pool)
|
||||
.await;
|
||||
if let Err(error) = query_result {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot upsert kb_pair_candles on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot upsert k_sol_pair_candles on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
@@ -76,7 +76,7 @@ ON CONFLICT(pair_id, timeframe_seconds, bucket_start_unix) DO UPDATE SET
|
||||
let id_result = sqlx::query_scalar::<sqlx::Sqlite, i64>(
|
||||
r#"
|
||||
SELECT id
|
||||
FROM kb_pair_candles
|
||||
FROM k_sol_pair_candles
|
||||
WHERE pair_id = ? AND timeframe_seconds = ? AND bucket_start_unix = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -89,8 +89,8 @@ LIMIT 1
|
||||
match id_result {
|
||||
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: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot fetch k_sol_pair_candles id for pair_id '{}' timeframe '{}' bucket '{}' on sqlite: {}",
|
||||
dto.pair_id, dto.timeframe_seconds, dto.bucket_start_unix, error
|
||||
)));
|
||||
},
|
||||
@@ -100,15 +100,15 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Returns one pair-candle row identified by `(pair_id, timeframe_seconds, bucket_start_unix)`.
|
||||
pub async fn get_pair_candle_by_key(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_pair_candles_get_by_key(
|
||||
database: &crate::Database,
|
||||
pair_id: i64,
|
||||
timeframe_seconds: i64,
|
||||
bucket_start_unix: i64,
|
||||
) -> Result<std::option::Option<crate::KbPairCandleDto>, crate::KbError> {
|
||||
) -> Result<std::option::Option<crate::PairCandleDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbPairCandleEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::PairCandleEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -129,7 +129,7 @@ SELECT
|
||||
last_trade_signature,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM kb_pair_candles
|
||||
FROM k_sol_pair_candles
|
||||
WHERE pair_id = ? AND timeframe_seconds = ? AND bucket_start_unix = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -142,14 +142,14 @@ LIMIT 1
|
||||
let entity_option = match query_result {
|
||||
Ok(entity_option) => entity_option,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot read kb_pair_candles by key on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot read k_sol_pair_candles by key on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => return crate::KbPairCandleDto::try_from(entity).map(Some),
|
||||
Some(entity) => return crate::PairCandleDto::try_from(entity).map(Some),
|
||||
None => return Ok(None),
|
||||
}
|
||||
},
|
||||
@@ -157,14 +157,14 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Lists candles for one pair and one timeframe ordered by bucket start.
|
||||
pub async fn list_pair_candles_by_pair_and_timeframe(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_pair_candles_list_by_pair_and_timeframe(
|
||||
database: &crate::Database,
|
||||
pair_id: i64,
|
||||
timeframe_seconds: i64,
|
||||
) -> Result<std::vec::Vec<crate::KbPairCandleDto>, crate::KbError> {
|
||||
) -> Result<std::vec::Vec<crate::PairCandleDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbPairCandleEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::PairCandleEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -185,7 +185,7 @@ SELECT
|
||||
last_trade_signature,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM kb_pair_candles
|
||||
FROM k_sol_pair_candles
|
||||
WHERE pair_id = ? AND timeframe_seconds = ?
|
||||
ORDER BY bucket_start_unix ASC, id ASC
|
||||
"#,
|
||||
@@ -197,15 +197,15 @@ ORDER BY bucket_start_unix ASC, id ASC
|
||||
let entities = match query_result {
|
||||
Ok(entities) => entities,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot list kb_pair_candles by pair_id '{}' timeframe '{}' on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot list k_sol_pair_candles by pair_id '{}' timeframe '{}' on sqlite: {}",
|
||||
pair_id, timeframe_seconds, error
|
||||
)));
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
let dto_result = crate::KbPairCandleDto::try_from(entity);
|
||||
let dto_result = crate::PairCandleDto::try_from(entity);
|
||||
let dto = match dto_result {
|
||||
Ok(dto) => dto,
|
||||
Err(error) => return Err(error),
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
// file: kb_lib/src/db/queries/pair_metric.rs
|
||||
|
||||
//! Queries for `kb_pair_metrics`.
|
||||
//! Queries for `k_sol_pair_metrics`.
|
||||
|
||||
/// Inserts or updates one pair-metric row and returns its stable internal id.
|
||||
pub async fn upsert_pair_metric(
|
||||
database: &crate::KbDatabase,
|
||||
dto: &crate::KbPairMetricDto,
|
||||
) -> Result<i64, crate::KbError> {
|
||||
pub async fn query_pair_metrics_upsert(
|
||||
database: &crate::Database,
|
||||
dto: &crate::PairMetricDto,
|
||||
) -> Result<i64, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query(
|
||||
r#"
|
||||
INSERT INTO kb_pair_metrics (
|
||||
INSERT INTO k_sol_pair_metrics (
|
||||
pair_id,
|
||||
first_slot,
|
||||
last_slot,
|
||||
@@ -57,15 +57,15 @@ ON CONFLICT(pair_id) DO UPDATE SET
|
||||
.execute(pool)
|
||||
.await;
|
||||
if let Err(error) = query_result {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot upsert kb_pair_metrics on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot upsert k_sol_pair_metrics on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
let id_result = sqlx::query_scalar::<sqlx::Sqlite, i64>(
|
||||
r#"
|
||||
SELECT id
|
||||
FROM kb_pair_metrics
|
||||
FROM k_sol_pair_metrics
|
||||
WHERE pair_id = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -76,8 +76,8 @@ LIMIT 1
|
||||
match id_result {
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_pair_metrics id for pair_id '{}' on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot fetch k_sol_pair_metrics id for pair_id '{}' on sqlite: {}",
|
||||
dto.pair_id, error
|
||||
)));
|
||||
},
|
||||
@@ -87,13 +87,13 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Returns one pair-metric row identified by its pair id, if it exists.
|
||||
pub async fn get_pair_metric_by_pair_id(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_pair_metrics_get_by_pair_id(
|
||||
database: &crate::Database,
|
||||
pair_id: i64,
|
||||
) -> Result<std::option::Option<crate::KbPairMetricDto>, crate::KbError> {
|
||||
) -> Result<std::option::Option<crate::PairMetricDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbPairMetricEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::PairMetricEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -110,7 +110,7 @@ SELECT
|
||||
last_price_quote_per_base,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM kb_pair_metrics
|
||||
FROM k_sol_pair_metrics
|
||||
WHERE pair_id = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -121,14 +121,14 @@ LIMIT 1
|
||||
let entity_option = match query_result {
|
||||
Ok(entity_option) => entity_option,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot read kb_pair_metrics by pair_id '{}' on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot read k_sol_pair_metrics by pair_id '{}' on sqlite: {}",
|
||||
pair_id, error
|
||||
)));
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => return crate::KbPairMetricDto::try_from(entity).map(Some),
|
||||
Some(entity) => return crate::PairMetricDto::try_from(entity).map(Some),
|
||||
None => return Ok(None),
|
||||
}
|
||||
},
|
||||
@@ -136,12 +136,12 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Lists all pair-metric rows ordered by pair id.
|
||||
pub async fn list_pair_metrics(
|
||||
database: &crate::KbDatabase,
|
||||
) -> Result<std::vec::Vec<crate::KbPairMetricDto>, crate::KbError> {
|
||||
pub async fn query_pair_metrics_list(
|
||||
database: &crate::Database,
|
||||
) -> Result<std::vec::Vec<crate::PairMetricDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbPairMetricEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::PairMetricEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -158,7 +158,7 @@ SELECT
|
||||
last_price_quote_per_base,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM kb_pair_metrics
|
||||
FROM k_sol_pair_metrics
|
||||
ORDER BY pair_id ASC
|
||||
"#,
|
||||
)
|
||||
@@ -167,15 +167,15 @@ ORDER BY pair_id ASC
|
||||
let entities = match query_result {
|
||||
Ok(entities) => entities,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot list kb_pair_metrics on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot list k_sol_pair_metrics on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
let dto_result = crate::KbPairMetricDto::try_from(entity);
|
||||
let dto_result = crate::PairMetricDto::try_from(entity);
|
||||
let dto = match dto_result {
|
||||
Ok(dto) => dto,
|
||||
Err(error) => return Err(error),
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
// file: kb_lib/src/db/queries/pool.rs
|
||||
|
||||
//! Queries for `kb_pools`.
|
||||
//! Queries for `k_sol_pools`.
|
||||
|
||||
/// Inserts or updates one normalized pool row by address.
|
||||
pub async fn upsert_pool(
|
||||
database: &crate::KbDatabase,
|
||||
dto: &crate::KbPoolDto,
|
||||
) -> Result<i64, crate::KbError> {
|
||||
pub async fn query_pools_upsert(
|
||||
database: &crate::Database,
|
||||
dto: &crate::PoolDto,
|
||||
) -> Result<i64, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query(
|
||||
r#"
|
||||
INSERT INTO kb_pools (
|
||||
INSERT INTO k_sol_pools (
|
||||
dex_id,
|
||||
address,
|
||||
pool_kind,
|
||||
@@ -36,15 +36,15 @@ ON CONFLICT(address) DO UPDATE SET
|
||||
.execute(pool)
|
||||
.await;
|
||||
if let Err(error) = query_result {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot upsert kb_pools on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot upsert k_sol_pools on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
let id_result = sqlx::query_scalar::<sqlx::Sqlite, i64>(
|
||||
r#"
|
||||
SELECT id
|
||||
FROM kb_pools
|
||||
FROM k_sol_pools
|
||||
WHERE address = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -55,8 +55,8 @@ LIMIT 1
|
||||
match id_result {
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_pools id for address '{}' on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot fetch k_sol_pools id for address '{}' on sqlite: {}",
|
||||
dto.address, error
|
||||
)));
|
||||
},
|
||||
@@ -66,13 +66,13 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Reads one normalized pool row by address.
|
||||
pub async fn get_pool_by_address(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_pools_get_by_address(
|
||||
database: &crate::Database,
|
||||
address: &str,
|
||||
) -> Result<std::option::Option<crate::KbPoolDto>, crate::KbError> {
|
||||
) -> Result<std::option::Option<crate::PoolDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbPoolEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::PoolEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -82,7 +82,7 @@ SELECT
|
||||
status,
|
||||
first_seen_at,
|
||||
updated_at
|
||||
FROM kb_pools
|
||||
FROM k_sol_pools
|
||||
WHERE address = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -93,15 +93,15 @@ LIMIT 1
|
||||
let entity_option = match query_result {
|
||||
Ok(entity_option) => entity_option,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot read kb_pools '{}' on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot read k_sol_pools '{}' on sqlite: {}",
|
||||
address, error
|
||||
)));
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => {
|
||||
let dto_result = crate::KbPoolDto::try_from(entity);
|
||||
let dto_result = crate::PoolDto::try_from(entity);
|
||||
match dto_result {
|
||||
Ok(dto) => return Ok(Some(dto)),
|
||||
Err(error) => return Err(error),
|
||||
@@ -114,12 +114,12 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Lists normalized pools ordered by id ascending.
|
||||
pub async fn list_pools(
|
||||
database: &crate::KbDatabase,
|
||||
) -> Result<std::vec::Vec<crate::KbPoolDto>, crate::KbError> {
|
||||
pub async fn query_pools_list(
|
||||
database: &crate::Database,
|
||||
) -> Result<std::vec::Vec<crate::PoolDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbPoolEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::PoolEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -129,7 +129,7 @@ SELECT
|
||||
status,
|
||||
first_seen_at,
|
||||
updated_at
|
||||
FROM kb_pools
|
||||
FROM k_sol_pools
|
||||
ORDER BY id ASC
|
||||
"#,
|
||||
)
|
||||
@@ -138,15 +138,15 @@ ORDER BY id ASC
|
||||
let entities = match query_result {
|
||||
Ok(entities) => entities,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot list kb_pools on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot list k_sol_pools on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
let dto_result = crate::KbPoolDto::try_from(entity);
|
||||
let dto_result = crate::PoolDto::try_from(entity);
|
||||
let dto = match dto_result {
|
||||
Ok(dto) => dto,
|
||||
Err(error) => return Err(error),
|
||||
@@ -164,10 +164,10 @@ mod tests {
|
||||
async fn pool_roundtrip_works() {
|
||||
let tempdir = tempfile::tempdir().expect("tempdir must succeed");
|
||||
let database_path = tempdir.path().join("pool_roundtrip.sqlite3");
|
||||
let config = crate::KbDatabaseConfig {
|
||||
let config = crate::DatabaseConfig {
|
||||
enabled: true,
|
||||
backend: crate::KbDatabaseBackend::Sqlite,
|
||||
sqlite: crate::KbSqliteDatabaseConfig {
|
||||
backend: crate::DatabaseBackend::Sqlite,
|
||||
sqlite: crate::SqliteDatabaseConfig {
|
||||
path: database_path.to_string_lossy().to_string(),
|
||||
create_if_missing: true,
|
||||
busy_timeout_ms: 5000,
|
||||
@@ -176,34 +176,36 @@ mod tests {
|
||||
use_wal: true,
|
||||
},
|
||||
};
|
||||
let database = crate::KbDatabase::connect_and_initialize(&config)
|
||||
let database = crate::Database::connect_and_initialize(&config)
|
||||
.await
|
||||
.expect("database init must succeed");
|
||||
let dex_id = crate::upsert_dex(
|
||||
let dex_id = crate::query_dexs_upsert(
|
||||
&database,
|
||||
&crate::KbDexDto::new("raydium".to_string(), "Raydium".to_string(), None, None, true),
|
||||
&crate::DexDto::new("raydium".to_string(), "Raydium".to_string(), None, None, true),
|
||||
)
|
||||
.await
|
||||
.expect("dex upsert must succeed");
|
||||
let pool_id = crate::upsert_pool(
|
||||
let pool_id = crate::query_pools_upsert(
|
||||
&database,
|
||||
&crate::KbPoolDto::new(
|
||||
&crate::PoolDto::new(
|
||||
dex_id,
|
||||
"Pool111111111111111111111111111111111111111".to_string(),
|
||||
crate::KbPoolKind::Amm,
|
||||
crate::KbPoolStatus::Active,
|
||||
crate::PoolKind::Amm,
|
||||
crate::PoolStatus::Active,
|
||||
),
|
||||
)
|
||||
.await
|
||||
.expect("pool upsert must succeed");
|
||||
assert!(pool_id > 0);
|
||||
let pool =
|
||||
crate::get_pool_by_address(&database, "Pool111111111111111111111111111111111111111")
|
||||
.await
|
||||
.expect("get pool must succeed");
|
||||
let pool = crate::query_pools_get_by_address(
|
||||
&database,
|
||||
"Pool111111111111111111111111111111111111111",
|
||||
)
|
||||
.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::PoolKind::Amm);
|
||||
let pools = crate::query_pools_list(&database).await.expect("list pools must succeed");
|
||||
assert_eq!(pools.len(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
// file: kb_lib/src/db/queries/pool_listing.rs
|
||||
|
||||
//! Queries for `kb_pool_listings`.
|
||||
//! Queries for `k_sol_pool_listings`.
|
||||
|
||||
/// Inserts or updates one normalized pool listing row by pool id.
|
||||
pub async fn upsert_pool_listing(
|
||||
database: &crate::KbDatabase,
|
||||
dto: &crate::KbPoolListingDto,
|
||||
) -> Result<i64, crate::KbError> {
|
||||
pub async fn query_pool_listings_upsert(
|
||||
database: &crate::Database,
|
||||
dto: &crate::PoolListingDto,
|
||||
) -> Result<i64, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query(
|
||||
r#"
|
||||
INSERT INTO kb_pool_listings (
|
||||
INSERT INTO k_sol_pool_listings (
|
||||
dex_id,
|
||||
pool_id,
|
||||
pair_id,
|
||||
@@ -49,15 +49,15 @@ ON CONFLICT(pool_id) DO UPDATE SET
|
||||
.execute(pool)
|
||||
.await;
|
||||
if let Err(error) = query_result {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot upsert kb_pool_listings on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot upsert k_sol_pool_listings on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
let id_result = sqlx::query_scalar::<sqlx::Sqlite, i64>(
|
||||
r#"
|
||||
SELECT id
|
||||
FROM kb_pool_listings
|
||||
FROM k_sol_pool_listings
|
||||
WHERE pool_id = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -68,8 +68,8 @@ LIMIT 1
|
||||
match id_result {
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_pool_listings id for pool_id '{}' on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot fetch k_sol_pool_listings id for pool_id '{}' on sqlite: {}",
|
||||
dto.pool_id, error
|
||||
)));
|
||||
},
|
||||
@@ -79,13 +79,13 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Reads one normalized pool listing row by pool id.
|
||||
pub async fn get_pool_listing_by_pool_id(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_pool_listings_get_by_pool_id(
|
||||
database: &crate::Database,
|
||||
pool_id: i64,
|
||||
) -> Result<std::option::Option<crate::KbPoolListingDto>, crate::KbError> {
|
||||
) -> Result<std::option::Option<crate::PoolListingDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbPoolListingEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::PoolListingEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -99,7 +99,7 @@ SELECT
|
||||
initial_quote_reserve,
|
||||
initial_price_quote,
|
||||
updated_at
|
||||
FROM kb_pool_listings
|
||||
FROM k_sol_pool_listings
|
||||
WHERE pool_id = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -110,15 +110,15 @@ LIMIT 1
|
||||
let entity_option = match query_result {
|
||||
Ok(entity_option) => entity_option,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot read kb_pool_listings by pool_id '{}' on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot read k_sol_pool_listings by pool_id '{}' on sqlite: {}",
|
||||
pool_id, error
|
||||
)));
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => {
|
||||
let dto_result = crate::KbPoolListingDto::try_from(entity);
|
||||
let dto_result = crate::PoolListingDto::try_from(entity);
|
||||
match dto_result {
|
||||
Ok(dto) => return Ok(Some(dto)),
|
||||
Err(error) => return Err(error),
|
||||
@@ -131,12 +131,12 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Lists normalized pool listings ordered by detected date then id.
|
||||
pub async fn list_pool_listings(
|
||||
database: &crate::KbDatabase,
|
||||
) -> Result<std::vec::Vec<crate::KbPoolListingDto>, crate::KbError> {
|
||||
pub async fn query_pool_listings_list(
|
||||
database: &crate::Database,
|
||||
) -> Result<std::vec::Vec<crate::PoolListingDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbPoolListingEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::PoolListingEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -150,7 +150,7 @@ SELECT
|
||||
initial_quote_reserve,
|
||||
initial_price_quote,
|
||||
updated_at
|
||||
FROM kb_pool_listings
|
||||
FROM k_sol_pool_listings
|
||||
ORDER BY detected_at ASC, id ASC
|
||||
"#,
|
||||
)
|
||||
@@ -159,15 +159,15 @@ ORDER BY detected_at ASC, id ASC
|
||||
let entities = match query_result {
|
||||
Ok(entities) => entities,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot list kb_pool_listings on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot list k_sol_pool_listings on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
let dto_result = crate::KbPoolListingDto::try_from(entity);
|
||||
let dto_result = crate::PoolListingDto::try_from(entity);
|
||||
let dto = match dto_result {
|
||||
Ok(dto) => dto,
|
||||
Err(error) => return Err(error),
|
||||
@@ -185,10 +185,10 @@ mod tests {
|
||||
async fn pool_listing_roundtrip_works() {
|
||||
let tempdir = tempfile::tempdir().expect("tempdir must succeed");
|
||||
let database_path = tempdir.path().join("pool_listing_roundtrip.sqlite3");
|
||||
let config = crate::KbDatabaseConfig {
|
||||
let config = crate::DatabaseConfig {
|
||||
enabled: true,
|
||||
backend: crate::KbDatabaseBackend::Sqlite,
|
||||
sqlite: crate::KbSqliteDatabaseConfig {
|
||||
backend: crate::DatabaseBackend::Sqlite,
|
||||
sqlite: crate::SqliteDatabaseConfig {
|
||||
path: database_path.to_string_lossy().to_string(),
|
||||
create_if_missing: true,
|
||||
busy_timeout_ms: 5000,
|
||||
@@ -197,18 +197,18 @@ mod tests {
|
||||
use_wal: true,
|
||||
},
|
||||
};
|
||||
let database = crate::KbDatabase::connect_and_initialize(&config)
|
||||
let database = crate::Database::connect_and_initialize(&config)
|
||||
.await
|
||||
.expect("database init must succeed");
|
||||
let dex_id = crate::upsert_dex(
|
||||
let dex_id = crate::query_dexs_upsert(
|
||||
&database,
|
||||
&crate::KbDexDto::new("raydium".to_string(), "Raydium".to_string(), None, None, true),
|
||||
&crate::DexDto::new("raydium".to_string(), "Raydium".to_string(), None, None, true),
|
||||
)
|
||||
.await
|
||||
.expect("dex upsert must succeed");
|
||||
let base_token_id = crate::upsert_token(
|
||||
let base_token_id = crate::query_tokens_upsert(
|
||||
&database,
|
||||
&crate::KbTokenDto::new(
|
||||
&crate::TokenDto::new(
|
||||
"Base111111111111111111111111111111111111111".to_string(),
|
||||
Some("BASE".to_string()),
|
||||
Some("Base Token".to_string()),
|
||||
@@ -219,10 +219,10 @@ mod tests {
|
||||
)
|
||||
.await
|
||||
.expect("base token upsert must succeed");
|
||||
let quote_token_id = crate::upsert_token(
|
||||
let quote_token_id = crate::query_tokens_upsert(
|
||||
&database,
|
||||
&crate::KbTokenDto::new(
|
||||
"So11111111111111111111111111111111111111112".to_string(),
|
||||
&crate::TokenDto::new(
|
||||
crate::WSOL_MINT_ID.to_string(),
|
||||
Some("WSOL".to_string()),
|
||||
Some("Wrapped SOL".to_string()),
|
||||
Some(9),
|
||||
@@ -232,20 +232,20 @@ mod tests {
|
||||
)
|
||||
.await
|
||||
.expect("quote token upsert must succeed");
|
||||
let pool_id = crate::upsert_pool(
|
||||
let pool_id = crate::query_pools_upsert(
|
||||
&database,
|
||||
&crate::KbPoolDto::new(
|
||||
&crate::PoolDto::new(
|
||||
dex_id,
|
||||
"Pool111111111111111111111111111111111111111".to_string(),
|
||||
crate::KbPoolKind::Amm,
|
||||
crate::KbPoolStatus::Active,
|
||||
crate::PoolKind::Amm,
|
||||
crate::PoolStatus::Active,
|
||||
),
|
||||
)
|
||||
.await
|
||||
.expect("pool upsert must succeed");
|
||||
let pair_id = crate::upsert_pair(
|
||||
let pair_id = crate::query_pairs_upsert(
|
||||
&database,
|
||||
&crate::KbPairDto::new(
|
||||
&crate::PairDto::new(
|
||||
dex_id,
|
||||
pool_id,
|
||||
base_token_id,
|
||||
@@ -255,13 +255,13 @@ mod tests {
|
||||
)
|
||||
.await
|
||||
.expect("pair upsert must succeed");
|
||||
let pool_listing_id = crate::upsert_pool_listing(
|
||||
let pool_listing_id = crate::query_pool_listings_upsert(
|
||||
&database,
|
||||
&crate::KbPoolListingDto::new(
|
||||
&crate::PoolListingDto::new(
|
||||
dex_id,
|
||||
pool_id,
|
||||
Some(pair_id),
|
||||
crate::KbObservationSourceKind::WsRpc,
|
||||
crate::ObservationSourceKind::WsRpc,
|
||||
Some("mainnet_public_ws_slots".to_string()),
|
||||
Some(1000.0),
|
||||
Some(10.0),
|
||||
@@ -271,15 +271,15 @@ mod tests {
|
||||
.await
|
||||
.expect("pool listing upsert must succeed");
|
||||
assert!(pool_listing_id > 0);
|
||||
let pool_listing = crate::get_pool_listing_by_pool_id(&database, pool_id)
|
||||
let pool_listing = crate::query_pool_listings_get_by_pool_id(&database, pool_id)
|
||||
.await
|
||||
.expect("get pool listing must succeed");
|
||||
assert!(pool_listing.is_some());
|
||||
assert_eq!(
|
||||
pool_listing.expect("pool listing must exist").source_kind,
|
||||
crate::KbObservationSourceKind::WsRpc
|
||||
crate::ObservationSourceKind::WsRpc
|
||||
);
|
||||
let pool_listings = crate::list_pool_listings(&database)
|
||||
let pool_listings = crate::query_pool_listings_list(&database)
|
||||
.await
|
||||
.expect("list pool listings must succeed");
|
||||
assert_eq!(pool_listings.len(), 1);
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
// file: kb_lib/src/db/queries/pool_origin.rs
|
||||
|
||||
//! Queries for `kb_pool_origins`.
|
||||
//! Queries for `k_sol_pool_origins`.
|
||||
|
||||
/// Inserts or updates one pool-origin row and returns its stable internal id.
|
||||
pub async fn upsert_pool_origin(
|
||||
database: &crate::KbDatabase,
|
||||
dto: &crate::KbPoolOriginDto,
|
||||
) -> Result<i64, crate::KbError> {
|
||||
pub async fn query_pool_origins_upsert(
|
||||
database: &crate::Database,
|
||||
dto: &crate::PoolOriginDto,
|
||||
) -> Result<i64, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query(
|
||||
r#"
|
||||
INSERT INTO kb_pool_origins (
|
||||
INSERT INTO k_sol_pool_origins (
|
||||
dex_id,
|
||||
pool_id,
|
||||
pair_id,
|
||||
@@ -29,9 +29,9 @@ INSERT INTO kb_pool_origins (
|
||||
)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
ON CONFLICT(pool_id) DO UPDATE SET
|
||||
pair_id = COALESCE(kb_pool_origins.pair_id, excluded.pair_id),
|
||||
pool_listing_id = COALESCE(kb_pool_origins.pool_listing_id, excluded.pool_listing_id),
|
||||
launch_attribution_id = COALESCE(kb_pool_origins.launch_attribution_id, excluded.launch_attribution_id),
|
||||
pair_id = COALESCE(k_sol_pool_origins.pair_id, excluded.pair_id),
|
||||
pool_listing_id = COALESCE(k_sol_pool_origins.pool_listing_id, excluded.pool_listing_id),
|
||||
launch_attribution_id = COALESCE(k_sol_pool_origins.launch_attribution_id, excluded.launch_attribution_id),
|
||||
updated_at = excluded.updated_at
|
||||
"#,
|
||||
)
|
||||
@@ -52,15 +52,15 @@ ON CONFLICT(pool_id) DO UPDATE SET
|
||||
.execute(pool)
|
||||
.await;
|
||||
if let Err(error) = query_result {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot upsert kb_pool_origins on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot upsert k_sol_pool_origins on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
let id_result = sqlx::query_scalar::<sqlx::Sqlite, i64>(
|
||||
r#"
|
||||
SELECT id
|
||||
FROM kb_pool_origins
|
||||
FROM k_sol_pool_origins
|
||||
WHERE pool_id = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -71,8 +71,8 @@ LIMIT 1
|
||||
match id_result {
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_pool_origins id for pool_id '{}' on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot fetch k_sol_pool_origins id for pool_id '{}' on sqlite: {}",
|
||||
dto.pool_id, error
|
||||
)));
|
||||
},
|
||||
@@ -82,13 +82,13 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Returns one pool-origin row identified by its pool id, if it exists.
|
||||
pub async fn get_pool_origin_by_pool_id(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_pool_origins_get_by_pool_id(
|
||||
database: &crate::Database,
|
||||
pool_id: i64,
|
||||
) -> Result<std::option::Option<crate::KbPoolOriginDto>, crate::KbError> {
|
||||
) -> Result<std::option::Option<crate::PoolOriginDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbPoolOriginEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::PoolOriginEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -106,7 +106,7 @@ SELECT
|
||||
launch_attribution_id,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM kb_pool_origins
|
||||
FROM k_sol_pool_origins
|
||||
WHERE pool_id = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -117,14 +117,14 @@ LIMIT 1
|
||||
let entity_option = match query_result {
|
||||
Ok(entity_option) => entity_option,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot read kb_pool_origins by pool_id '{}' on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot read k_sol_pool_origins by pool_id '{}' on sqlite: {}",
|
||||
pool_id, error
|
||||
)));
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => return crate::KbPoolOriginDto::try_from(entity).map(Some),
|
||||
Some(entity) => return crate::PoolOriginDto::try_from(entity).map(Some),
|
||||
None => return Ok(None),
|
||||
}
|
||||
},
|
||||
@@ -132,12 +132,12 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Lists all pool-origin rows ordered by creation time then id.
|
||||
pub async fn list_pool_origins(
|
||||
database: &crate::KbDatabase,
|
||||
) -> Result<std::vec::Vec<crate::KbPoolOriginDto>, crate::KbError> {
|
||||
pub async fn query_pool_origins_list(
|
||||
database: &crate::Database,
|
||||
) -> Result<std::vec::Vec<crate::PoolOriginDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbPoolOriginEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::PoolOriginEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -155,7 +155,7 @@ SELECT
|
||||
launch_attribution_id,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM kb_pool_origins
|
||||
FROM k_sol_pool_origins
|
||||
ORDER BY created_at ASC, id ASC
|
||||
"#,
|
||||
)
|
||||
@@ -164,15 +164,15 @@ ORDER BY created_at ASC, id ASC
|
||||
let entities = match query_result {
|
||||
Ok(entities) => entities,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot list kb_pool_origins on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot list k_sol_pool_origins on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
let dto_result = crate::KbPoolOriginDto::try_from(entity);
|
||||
let dto_result = crate::PoolOriginDto::try_from(entity);
|
||||
let dto = match dto_result {
|
||||
Ok(dto) => dto,
|
||||
Err(error) => return Err(error),
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
// file: kb_lib/src/db/queries/pool_token.rs
|
||||
|
||||
//! Queries for `kb_pool_tokens`.
|
||||
//! Queries for `k_sol_pool_tokens`.
|
||||
|
||||
/// Inserts or updates one normalized pool token composition row.
|
||||
pub async fn upsert_pool_token(
|
||||
database: &crate::KbDatabase,
|
||||
dto: &crate::KbPoolTokenDto,
|
||||
) -> Result<i64, crate::KbError> {
|
||||
pub async fn query_pool_tokens_upsert(
|
||||
database: &crate::Database,
|
||||
dto: &crate::PoolTokenDto,
|
||||
) -> Result<i64, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query(
|
||||
r#"
|
||||
INSERT INTO kb_pool_tokens (
|
||||
INSERT INTO k_sol_pool_tokens (
|
||||
pool_id,
|
||||
token_id,
|
||||
role,
|
||||
@@ -37,15 +37,15 @@ ON CONFLICT(pool_id, token_id, role) DO UPDATE SET
|
||||
.execute(pool)
|
||||
.await;
|
||||
if let Err(error) = query_result {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot upsert kb_pool_tokens on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot upsert k_sol_pool_tokens on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
let id_result = sqlx::query_scalar::<sqlx::Sqlite, i64>(
|
||||
r#"
|
||||
SELECT id
|
||||
FROM kb_pool_tokens
|
||||
FROM k_sol_pool_tokens
|
||||
WHERE pool_id = ? AND token_id = ? AND role = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -58,8 +58,8 @@ LIMIT 1
|
||||
match id_result {
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_pool_tokens id on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot fetch k_sol_pool_tokens id on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
@@ -69,13 +69,13 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Lists normalized pool token rows by pool id.
|
||||
pub async fn list_pool_tokens_by_pool_id(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_pool_tokens_list_by_pool_id(
|
||||
database: &crate::Database,
|
||||
pool_id: i64,
|
||||
) -> Result<std::vec::Vec<crate::KbPoolTokenDto>, crate::KbError> {
|
||||
) -> Result<std::vec::Vec<crate::PoolTokenDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbPoolTokenEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::PoolTokenEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -86,7 +86,7 @@ SELECT
|
||||
token_order,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM kb_pool_tokens
|
||||
FROM k_sol_pool_tokens
|
||||
WHERE pool_id = ?
|
||||
ORDER BY token_order ASC, id ASC
|
||||
"#,
|
||||
@@ -97,15 +97,15 @@ ORDER BY token_order ASC, id ASC
|
||||
let entities = match query_result {
|
||||
Ok(entities) => entities,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot list kb_pool_tokens for pool_id '{}' on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot list k_sol_pool_tokens for pool_id '{}' on sqlite: {}",
|
||||
pool_id, error
|
||||
)));
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
let dto_result = crate::KbPoolTokenDto::try_from(entity);
|
||||
let dto_result = crate::PoolTokenDto::try_from(entity);
|
||||
let dto = match dto_result {
|
||||
Ok(dto) => dto,
|
||||
Err(error) => return Err(error),
|
||||
@@ -123,10 +123,10 @@ mod tests {
|
||||
async fn pool_token_roundtrip_works() {
|
||||
let tempdir = tempfile::tempdir().expect("tempdir must succeed");
|
||||
let database_path = tempdir.path().join("pool_token_roundtrip.sqlite3");
|
||||
let config = crate::KbDatabaseConfig {
|
||||
let config = crate::DatabaseConfig {
|
||||
enabled: true,
|
||||
backend: crate::KbDatabaseBackend::Sqlite,
|
||||
sqlite: crate::KbSqliteDatabaseConfig {
|
||||
backend: crate::DatabaseBackend::Sqlite,
|
||||
sqlite: crate::SqliteDatabaseConfig {
|
||||
path: database_path.to_string_lossy().to_string(),
|
||||
create_if_missing: true,
|
||||
busy_timeout_ms: 5000,
|
||||
@@ -135,18 +135,18 @@ mod tests {
|
||||
use_wal: true,
|
||||
},
|
||||
};
|
||||
let database = crate::KbDatabase::connect_and_initialize(&config)
|
||||
let database = crate::Database::connect_and_initialize(&config)
|
||||
.await
|
||||
.expect("database init must succeed");
|
||||
let dex_id = crate::upsert_dex(
|
||||
let dex_id = crate::query_dexs_upsert(
|
||||
&database,
|
||||
&crate::KbDexDto::new("raydium".to_string(), "Raydium".to_string(), None, None, true),
|
||||
&crate::DexDto::new("raydium".to_string(), "Raydium".to_string(), None, None, true),
|
||||
)
|
||||
.await
|
||||
.expect("dex upsert must succeed");
|
||||
let token_id = crate::upsert_token(
|
||||
let token_id = crate::query_tokens_upsert(
|
||||
&database,
|
||||
&crate::KbTokenDto::new(
|
||||
&crate::TokenDto::new(
|
||||
"Base111111111111111111111111111111111111111".to_string(),
|
||||
Some("BASE".to_string()),
|
||||
Some("Base Token".to_string()),
|
||||
@@ -157,23 +157,23 @@ mod tests {
|
||||
)
|
||||
.await
|
||||
.expect("token upsert must succeed");
|
||||
let pool_id = crate::upsert_pool(
|
||||
let pool_id = crate::query_pools_upsert(
|
||||
&database,
|
||||
&crate::KbPoolDto::new(
|
||||
&crate::PoolDto::new(
|
||||
dex_id,
|
||||
"Pool111111111111111111111111111111111111111".to_string(),
|
||||
crate::KbPoolKind::Amm,
|
||||
crate::KbPoolStatus::Active,
|
||||
crate::PoolKind::Amm,
|
||||
crate::PoolStatus::Active,
|
||||
),
|
||||
)
|
||||
.await
|
||||
.expect("pool upsert must succeed");
|
||||
let pool_token_id = crate::upsert_pool_token(
|
||||
let pool_token_id = crate::query_pool_tokens_upsert(
|
||||
&database,
|
||||
&crate::KbPoolTokenDto::new(
|
||||
&crate::PoolTokenDto::new(
|
||||
pool_id,
|
||||
token_id,
|
||||
crate::KbPoolTokenRole::Base,
|
||||
crate::PoolTokenRole::Base,
|
||||
Some("Vault111111111111111111111111111111111111".to_string()),
|
||||
Some(0),
|
||||
),
|
||||
@@ -181,10 +181,10 @@ mod tests {
|
||||
.await
|
||||
.expect("pool token upsert must succeed");
|
||||
assert!(pool_token_id > 0);
|
||||
let pool_tokens = crate::list_pool_tokens_by_pool_id(&database, pool_id)
|
||||
let pool_tokens = crate::query_pool_tokens_list_by_pool_id(&database, pool_id)
|
||||
.await
|
||||
.expect("list pool tokens must succeed");
|
||||
assert_eq!(pool_tokens.len(), 1);
|
||||
assert_eq!(pool_tokens[0].role, crate::KbPoolTokenRole::Base);
|
||||
assert_eq!(pool_tokens[0].role, crate::PoolTokenRole::Base);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
// file: kb_lib/src/db/queries/swap.rs
|
||||
|
||||
//! Queries for `kb_swaps`.
|
||||
//! Queries for `k_sol_swaps`.
|
||||
|
||||
/// Inserts or updates one normalized swap row.
|
||||
pub async fn upsert_swap(
|
||||
database: &crate::KbDatabase,
|
||||
dto: &crate::KbSwapDto,
|
||||
) -> Result<i64, crate::KbError> {
|
||||
pub async fn query_swaps_upsert(
|
||||
database: &crate::Database,
|
||||
dto: &crate::SwapDto,
|
||||
) -> Result<i64, crate::Error> {
|
||||
let slot_i64 = match dto.slot {
|
||||
Some(slot) => {
|
||||
let slot_result = i64::try_from(slot);
|
||||
match slot_result {
|
||||
Ok(slot) => Some(slot),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot convert swap slot '{}' to i64: {}",
|
||||
slot, error
|
||||
)));
|
||||
@@ -23,10 +23,10 @@ pub async fn upsert_swap(
|
||||
None => None,
|
||||
};
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query(
|
||||
r#"
|
||||
INSERT INTO kb_swaps (
|
||||
INSERT INTO k_sol_swaps (
|
||||
dex_id,
|
||||
pool_id,
|
||||
pair_id,
|
||||
@@ -75,15 +75,15 @@ ON CONFLICT(signature, instruction_index) DO UPDATE SET
|
||||
.execute(pool)
|
||||
.await;
|
||||
if let Err(error) = query_result {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot upsert kb_swaps on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot upsert k_sol_swaps on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
let id_result = sqlx::query_scalar::<sqlx::Sqlite, i64>(
|
||||
r#"
|
||||
SELECT id
|
||||
FROM kb_swaps
|
||||
FROM k_sol_swaps
|
||||
WHERE signature = ? AND instruction_index = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -95,8 +95,8 @@ LIMIT 1
|
||||
match id_result {
|
||||
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: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot fetch k_sol_swaps id for signature '{}' and instruction_index '{}' on sqlite: {}",
|
||||
dto.signature, dto.instruction_index, error
|
||||
)));
|
||||
},
|
||||
@@ -106,16 +106,16 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Lists recent swaps ordered from newest to oldest.
|
||||
pub async fn list_recent_swaps(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_swaps_list_recent(
|
||||
database: &crate::Database,
|
||||
limit: u32,
|
||||
) -> Result<std::vec::Vec<crate::KbSwapDto>, crate::KbError> {
|
||||
) -> Result<std::vec::Vec<crate::SwapDto>, crate::Error> {
|
||||
if limit == 0 {
|
||||
return Ok(std::vec::Vec::new());
|
||||
}
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbSwapEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::SwapEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -133,7 +133,7 @@ SELECT
|
||||
price_quote,
|
||||
trade_side,
|
||||
executed_at
|
||||
FROM kb_swaps
|
||||
FROM k_sol_swaps
|
||||
ORDER BY id DESC
|
||||
LIMIT ?
|
||||
"#,
|
||||
@@ -144,15 +144,15 @@ LIMIT ?
|
||||
let entities = match query_result {
|
||||
Ok(entities) => entities,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot list kb_swaps on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot list k_sol_swaps on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
let dto_result = crate::KbSwapDto::try_from(entity);
|
||||
let dto_result = crate::SwapDto::try_from(entity);
|
||||
let dto = match dto_result {
|
||||
Ok(dto) => dto,
|
||||
Err(error) => return Err(error),
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
// file: kb_lib/src/db/queries/token.rs
|
||||
|
||||
//! Queries for `kb_tokens`.
|
||||
//! Queries for `k_sol_tokens`.
|
||||
|
||||
/// Inserts or updates one normalized token row by mint.
|
||||
pub async fn upsert_token(
|
||||
database: &crate::KbDatabase,
|
||||
dto: &crate::KbTokenDto,
|
||||
) -> Result<i64, crate::KbError> {
|
||||
pub async fn query_tokens_upsert(
|
||||
database: &crate::Database,
|
||||
dto: &crate::TokenDto,
|
||||
) -> Result<i64, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let decimals = dto.decimals.map(i64::from);
|
||||
let query_result = sqlx::query(
|
||||
r#"
|
||||
INSERT INTO kb_tokens (
|
||||
INSERT INTO k_sol_tokens (
|
||||
mint,
|
||||
symbol,
|
||||
name,
|
||||
@@ -43,15 +43,15 @@ ON CONFLICT(mint) DO UPDATE SET
|
||||
.execute(pool)
|
||||
.await;
|
||||
if let Err(error) = query_result {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot upsert kb_tokens on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot upsert k_sol_tokens on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
let id_result = sqlx::query_scalar::<sqlx::Sqlite, i64>(
|
||||
r#"
|
||||
SELECT id
|
||||
FROM kb_tokens
|
||||
FROM k_sol_tokens
|
||||
WHERE mint = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -62,8 +62,8 @@ LIMIT 1
|
||||
match id_result {
|
||||
Ok(id) => return Ok(id),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot fetch kb_tokens id for mint '{}' on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot fetch k_sol_tokens id for mint '{}' on sqlite: {}",
|
||||
dto.mint, error
|
||||
)));
|
||||
},
|
||||
@@ -73,13 +73,13 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Reads one normalized token row by mint.
|
||||
pub async fn get_token_by_mint(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_tokens_get_by_mint(
|
||||
database: &crate::Database,
|
||||
mint: &str,
|
||||
) -> Result<std::option::Option<crate::KbTokenDto>, crate::KbError> {
|
||||
) -> Result<std::option::Option<crate::TokenDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbTokenEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::TokenEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -91,7 +91,7 @@ SELECT
|
||||
is_quote_token,
|
||||
first_seen_at,
|
||||
updated_at
|
||||
FROM kb_tokens
|
||||
FROM k_sol_tokens
|
||||
WHERE mint = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -102,15 +102,15 @@ LIMIT 1
|
||||
let entity_option = match query_result {
|
||||
Ok(entity_option) => entity_option,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot read kb_tokens '{}' on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot read k_sol_tokens '{}' on sqlite: {}",
|
||||
mint, error
|
||||
)));
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => {
|
||||
let dto_result = crate::KbTokenDto::try_from(entity);
|
||||
let dto_result = crate::TokenDto::try_from(entity);
|
||||
match dto_result {
|
||||
Ok(dto) => return Ok(Some(dto)),
|
||||
Err(error) => return Err(error),
|
||||
@@ -123,13 +123,13 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Reads one normalized token row by internal id.
|
||||
pub async fn get_token_by_id(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_tokens_get_by_id(
|
||||
database: &crate::Database,
|
||||
token_id: i64,
|
||||
) -> Result<std::option::Option<crate::KbTokenDto>, crate::KbError> {
|
||||
) -> Result<std::option::Option<crate::TokenDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbTokenEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::TokenEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -141,7 +141,7 @@ SELECT
|
||||
is_quote_token,
|
||||
first_seen_at,
|
||||
updated_at
|
||||
FROM kb_tokens
|
||||
FROM k_sol_tokens
|
||||
WHERE id = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -152,15 +152,15 @@ LIMIT 1
|
||||
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: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot read k_sol_tokens id '{}' on sqlite: {}",
|
||||
token_id, error
|
||||
)));
|
||||
},
|
||||
};
|
||||
match entity_option {
|
||||
Some(entity) => {
|
||||
let dto_result = crate::KbTokenDto::try_from(entity);
|
||||
let dto_result = crate::TokenDto::try_from(entity);
|
||||
match dto_result {
|
||||
Ok(dto) => return Ok(Some(dto)),
|
||||
Err(error) => return Err(error),
|
||||
@@ -173,12 +173,12 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Lists all normalized token rows ordered by mint.
|
||||
pub async fn list_tokens(
|
||||
database: &crate::KbDatabase,
|
||||
) -> Result<std::vec::Vec<crate::KbTokenDto>, crate::KbError> {
|
||||
pub async fn query_tokens_list(
|
||||
database: &crate::Database,
|
||||
) -> Result<std::vec::Vec<crate::TokenDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbTokenEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::TokenEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -190,7 +190,7 @@ SELECT
|
||||
is_quote_token,
|
||||
first_seen_at,
|
||||
updated_at
|
||||
FROM kb_tokens
|
||||
FROM k_sol_tokens
|
||||
ORDER BY mint ASC, id ASC
|
||||
"#,
|
||||
)
|
||||
@@ -199,15 +199,15 @@ ORDER BY mint ASC, id ASC
|
||||
let entities = match query_result {
|
||||
Ok(entities) => entities,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot list kb_tokens on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot list k_sol_tokens on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
let dto_result = crate::KbTokenDto::try_from(entity);
|
||||
let dto_result = crate::TokenDto::try_from(entity);
|
||||
let dto = match dto_result {
|
||||
Ok(dto) => dto,
|
||||
Err(error) => return Err(error),
|
||||
@@ -220,15 +220,15 @@ ORDER BY mint ASC, id ASC
|
||||
}
|
||||
|
||||
/// Lists token rows whose display or mint metadata is incomplete.
|
||||
pub async fn list_tokens_missing_metadata(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_tokens_list_missing_metadata(
|
||||
database: &crate::Database,
|
||||
limit: std::option::Option<i64>,
|
||||
) -> Result<std::vec::Vec<crate::KbTokenDto>, crate::KbError> {
|
||||
) -> Result<std::vec::Vec<crate::TokenDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let entities_result = match limit {
|
||||
Some(limit) => {
|
||||
sqlx::query_as::<sqlx::Sqlite, crate::KbTokenEntity>(
|
||||
sqlx::query_as::<sqlx::Sqlite, crate::TokenEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -240,7 +240,7 @@ SELECT
|
||||
is_quote_token,
|
||||
first_seen_at,
|
||||
updated_at
|
||||
FROM kb_tokens
|
||||
FROM k_sol_tokens
|
||||
WHERE symbol IS NULL
|
||||
OR trim(symbol) = ''
|
||||
OR name IS NULL
|
||||
@@ -257,7 +257,7 @@ LIMIT ?
|
||||
.await
|
||||
},
|
||||
None => {
|
||||
sqlx::query_as::<sqlx::Sqlite, crate::KbTokenEntity>(
|
||||
sqlx::query_as::<sqlx::Sqlite, crate::TokenEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -269,7 +269,7 @@ SELECT
|
||||
is_quote_token,
|
||||
first_seen_at,
|
||||
updated_at
|
||||
FROM kb_tokens
|
||||
FROM k_sol_tokens
|
||||
WHERE symbol IS NULL
|
||||
OR trim(symbol) = ''
|
||||
OR name IS NULL
|
||||
@@ -287,15 +287,15 @@ ORDER BY updated_at ASC, id ASC
|
||||
let entities = match entities_result {
|
||||
Ok(entities) => entities,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot list kb_tokens missing metadata on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot list k_sol_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_result = crate::TokenDto::try_from(entity);
|
||||
let dto = match dto_result {
|
||||
Ok(dto) => dto,
|
||||
Err(error) => return Err(error),
|
||||
@@ -309,17 +309,17 @@ ORDER BY updated_at ASC, id ASC
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
async fn make_database() -> std::sync::Arc<crate::KbDatabase> {
|
||||
async fn make_database() -> std::sync::Arc<crate::Database> {
|
||||
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 {
|
||||
let config = crate::DatabaseConfig {
|
||||
enabled: true,
|
||||
backend: crate::KbDatabaseBackend::Sqlite,
|
||||
sqlite: crate::KbSqliteDatabaseConfig {
|
||||
backend: crate::DatabaseBackend::Sqlite,
|
||||
sqlite: crate::SqliteDatabaseConfig {
|
||||
path: database_path.to_string_lossy().to_string(),
|
||||
create_if_missing: true,
|
||||
busy_timeout_ms: 5000,
|
||||
@@ -328,7 +328,7 @@ mod tests {
|
||||
use_wal: true,
|
||||
},
|
||||
};
|
||||
let database_result = crate::KbDatabase::connect_and_initialize(&config).await;
|
||||
let database_result = crate::Database::connect_and_initialize(&config).await;
|
||||
let database = match database_result {
|
||||
Ok(database) => database,
|
||||
Err(error) => panic!("database init must succeed: {}", error),
|
||||
@@ -339,7 +339,7 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn list_tokens_missing_metadata_only_returns_incomplete_rows() {
|
||||
let database = make_database().await;
|
||||
let incomplete = crate::KbTokenDto::new(
|
||||
let incomplete = crate::TokenDto::new(
|
||||
"IncompleteMint111".to_string(),
|
||||
None,
|
||||
None,
|
||||
@@ -347,7 +347,7 @@ mod tests {
|
||||
crate::SPL_TOKEN_PROGRAM_ID.to_string(),
|
||||
false,
|
||||
);
|
||||
let complete = crate::KbTokenDto::new(
|
||||
let complete = crate::TokenDto::new(
|
||||
"CompleteMint111".to_string(),
|
||||
Some("CMP".to_string()),
|
||||
Some("Complete".to_string()),
|
||||
@@ -355,15 +355,16 @@ mod tests {
|
||||
crate::SPL_TOKEN_PROGRAM_ID.to_string(),
|
||||
false,
|
||||
);
|
||||
let incomplete_result = crate::upsert_token(database.as_ref(), &incomplete).await;
|
||||
let incomplete_result = crate::query_tokens_upsert(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;
|
||||
let complete_result = crate::query_tokens_upsert(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_result =
|
||||
crate::query_tokens_list_missing_metadata(database.as_ref(), None).await;
|
||||
let missing = match missing_result {
|
||||
Ok(missing) => missing,
|
||||
Err(error) => panic!("missing metadata list must succeed: {}", error),
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
// file: kb_lib/src/db/queries/token_burn_event.rs
|
||||
|
||||
//! Queries for `kb_token_burn_events`.
|
||||
//! Queries for `k_sol_token_burn_events`.
|
||||
|
||||
/// Inserts or updates one normalized token burn event row.
|
||||
pub async fn upsert_token_burn_event(
|
||||
database: &crate::KbDatabase,
|
||||
dto: &crate::KbTokenBurnEventDto,
|
||||
) -> Result<i64, crate::KbError> {
|
||||
pub async fn query_token_burn_events_upsert(
|
||||
database: &crate::Database,
|
||||
dto: &crate::TokenBurnEventDto,
|
||||
) -> Result<i64, crate::Error> {
|
||||
let slot_i64 = match dto.slot {
|
||||
Some(slot) => {
|
||||
let slot_result = i64::try_from(slot);
|
||||
match slot_result {
|
||||
Ok(slot) => Some(slot),
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot convert token burn event slot '{}' to i64: {}",
|
||||
slot, error
|
||||
)));
|
||||
@@ -23,10 +23,10 @@ pub async fn upsert_token_burn_event(
|
||||
None => None,
|
||||
};
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query(
|
||||
r#"
|
||||
INSERT INTO kb_token_burn_events (
|
||||
INSERT INTO k_sol_token_burn_events (
|
||||
token_id,
|
||||
signature,
|
||||
instruction_index,
|
||||
@@ -60,15 +60,15 @@ ON CONFLICT(signature, instruction_index) DO UPDATE SET
|
||||
.execute(pool)
|
||||
.await;
|
||||
if let Err(error) = query_result {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot upsert kb_token_burn_events on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot upsert k_sol_token_burn_events on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
}
|
||||
let id_result = sqlx::query_scalar::<sqlx::Sqlite, i64>(
|
||||
r#"
|
||||
SELECT id
|
||||
FROM kb_token_burn_events
|
||||
FROM k_sol_token_burn_events
|
||||
WHERE signature = ? AND instruction_index = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
@@ -80,8 +80,8 @@ LIMIT 1
|
||||
match id_result {
|
||||
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: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot fetch k_sol_token_burn_events id for signature '{}' and instruction_index '{}' on sqlite: {}",
|
||||
dto.signature, dto.instruction_index, error
|
||||
)));
|
||||
},
|
||||
@@ -91,16 +91,16 @@ LIMIT 1
|
||||
}
|
||||
|
||||
/// Lists recent token burn events ordered from newest to oldest.
|
||||
pub async fn list_recent_token_burn_events(
|
||||
database: &crate::KbDatabase,
|
||||
pub async fn query_token_burn_events_list_recent(
|
||||
database: &crate::Database,
|
||||
limit: u32,
|
||||
) -> Result<std::vec::Vec<crate::KbTokenBurnEventDto>, crate::KbError> {
|
||||
) -> Result<std::vec::Vec<crate::TokenBurnEventDto>, crate::Error> {
|
||||
if limit == 0 {
|
||||
return Ok(std::vec::Vec::new());
|
||||
}
|
||||
match database.connection() {
|
||||
crate::KbDatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::KbTokenBurnEventEntity>(
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let query_result = sqlx::query_as::<sqlx::Sqlite, crate::TokenBurnEventEntity>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@@ -113,7 +113,7 @@ SELECT
|
||||
amount,
|
||||
supply_after,
|
||||
executed_at
|
||||
FROM kb_token_burn_events
|
||||
FROM k_sol_token_burn_events
|
||||
ORDER BY id DESC
|
||||
LIMIT ?
|
||||
"#,
|
||||
@@ -124,15 +124,15 @@ LIMIT ?
|
||||
let entities = match query_result {
|
||||
Ok(entities) => entities,
|
||||
Err(error) => {
|
||||
return Err(crate::KbError::Db(format!(
|
||||
"cannot list kb_token_burn_events on sqlite: {}",
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot list k_sol_token_burn_events on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
};
|
||||
let mut dtos = std::vec::Vec::new();
|
||||
for entity in entities {
|
||||
let dto_result = crate::KbTokenBurnEventDto::try_from(entity);
|
||||
let dto_result = crate::TokenBurnEventDto::try_from(entity);
|
||||
let dto = match dto_result {
|
||||
Ok(dto) => dto,
|
||||
Err(error) => return Err(error),
|
||||
@@ -150,10 +150,10 @@ mod tests {
|
||||
async fn normalized_activity_roundtrip_works() {
|
||||
let tempdir = tempfile::tempdir().expect("tempdir must succeed");
|
||||
let database_path = tempdir.path().join("normalized_activity.sqlite3");
|
||||
let config = crate::KbDatabaseConfig {
|
||||
let config = crate::DatabaseConfig {
|
||||
enabled: true,
|
||||
backend: crate::KbDatabaseBackend::Sqlite,
|
||||
sqlite: crate::KbSqliteDatabaseConfig {
|
||||
backend: crate::DatabaseBackend::Sqlite,
|
||||
sqlite: crate::SqliteDatabaseConfig {
|
||||
path: database_path.to_string_lossy().to_string(),
|
||||
create_if_missing: true,
|
||||
busy_timeout_ms: 5000,
|
||||
@@ -162,18 +162,18 @@ mod tests {
|
||||
use_wal: true,
|
||||
},
|
||||
};
|
||||
let database = crate::KbDatabase::connect_and_initialize(&config)
|
||||
let database = crate::Database::connect_and_initialize(&config)
|
||||
.await
|
||||
.expect("database init must succeed");
|
||||
let dex_id = crate::upsert_dex(
|
||||
let dex_id = crate::query_dexs_upsert(
|
||||
&database,
|
||||
&crate::KbDexDto::new("raydium".to_string(), "Raydium".to_string(), None, None, true),
|
||||
&crate::DexDto::new("raydium".to_string(), "Raydium".to_string(), None, None, true),
|
||||
)
|
||||
.await
|
||||
.expect("dex upsert must succeed");
|
||||
let base_token_id = crate::upsert_token(
|
||||
let base_token_id = crate::query_tokens_upsert(
|
||||
&database,
|
||||
&crate::KbTokenDto::new(
|
||||
&crate::TokenDto::new(
|
||||
"Base111111111111111111111111111111111111111".to_string(),
|
||||
Some("BASE".to_string()),
|
||||
Some("Base Token".to_string()),
|
||||
@@ -184,10 +184,10 @@ mod tests {
|
||||
)
|
||||
.await
|
||||
.expect("base token upsert must succeed");
|
||||
let quote_token_id = crate::upsert_token(
|
||||
let quote_token_id = crate::query_tokens_upsert(
|
||||
&database,
|
||||
&crate::KbTokenDto::new(
|
||||
"So11111111111111111111111111111111111111112".to_string(),
|
||||
&crate::TokenDto::new(
|
||||
crate::WSOL_MINT_ID.to_string(),
|
||||
Some("WSOL".to_string()),
|
||||
Some("Wrapped SOL".to_string()),
|
||||
Some(9),
|
||||
@@ -197,20 +197,20 @@ mod tests {
|
||||
)
|
||||
.await
|
||||
.expect("quote token upsert must succeed");
|
||||
let pool_id = crate::upsert_pool(
|
||||
let pool_id = crate::query_pools_upsert(
|
||||
&database,
|
||||
&crate::KbPoolDto::new(
|
||||
&crate::PoolDto::new(
|
||||
dex_id,
|
||||
"Pool111111111111111111111111111111111111111".to_string(),
|
||||
crate::KbPoolKind::Amm,
|
||||
crate::KbPoolStatus::Active,
|
||||
crate::PoolKind::Amm,
|
||||
crate::PoolStatus::Active,
|
||||
),
|
||||
)
|
||||
.await
|
||||
.expect("pool upsert must succeed");
|
||||
let pair_id = crate::upsert_pair(
|
||||
let pair_id = crate::query_pairs_upsert(
|
||||
&database,
|
||||
&crate::KbPairDto::new(
|
||||
&crate::PairDto::new(
|
||||
dex_id,
|
||||
pool_id,
|
||||
base_token_id,
|
||||
@@ -220,9 +220,9 @@ mod tests {
|
||||
)
|
||||
.await
|
||||
.expect("pair upsert must succeed");
|
||||
let swap_id = crate::upsert_swap(
|
||||
let swap_id = crate::query_swaps_upsert(
|
||||
&database,
|
||||
&crate::KbSwapDto::new(
|
||||
&crate::SwapDto::new(
|
||||
dex_id,
|
||||
pool_id,
|
||||
Some(pair_id),
|
||||
@@ -235,21 +235,21 @@ mod tests {
|
||||
"1000.50".to_string(),
|
||||
"2.75".to_string(),
|
||||
Some("0.002748625687156422".to_string()),
|
||||
crate::KbSwapTradeSide::BuyBase,
|
||||
crate::SwapTradeSide::BuyBase,
|
||||
),
|
||||
)
|
||||
.await
|
||||
.expect("swap upsert must succeed");
|
||||
let liquidity_id = crate::upsert_liquidity_event(
|
||||
let liquidity_id = crate::query_liquidity_events_upsert(
|
||||
&database,
|
||||
&crate::KbLiquidityEventDto::new(
|
||||
&crate::LiquidityEventDto::new(
|
||||
dex_id,
|
||||
pool_id,
|
||||
Some(pair_id),
|
||||
"liq-signature-1".to_string(),
|
||||
1,
|
||||
Some(1001),
|
||||
crate::KbLiquidityEventKind::Add,
|
||||
crate::LiquidityEventKind::Add,
|
||||
Some("LpUser1111111111111111111111111111111111".to_string()),
|
||||
base_token_id,
|
||||
quote_token_id,
|
||||
@@ -261,9 +261,9 @@ mod tests {
|
||||
)
|
||||
.await
|
||||
.expect("liquidity event upsert must succeed");
|
||||
let mint_id = crate::upsert_token_mint_event(
|
||||
let mint_id = crate::query_token_mint_events_upsert(
|
||||
&database,
|
||||
&crate::KbTokenMintEventDto::new(
|
||||
&crate::TokenMintEventDto::new(
|
||||
base_token_id,
|
||||
"mint-signature-1".to_string(),
|
||||
2,
|
||||
@@ -276,9 +276,9 @@ mod tests {
|
||||
)
|
||||
.await
|
||||
.expect("token mint event upsert must succeed");
|
||||
let burn_id = crate::upsert_token_burn_event(
|
||||
let burn_id = crate::query_token_burn_events_upsert(
|
||||
&database,
|
||||
&crate::KbTokenBurnEventDto::new(
|
||||
&crate::TokenBurnEventDto::new(
|
||||
base_token_id,
|
||||
"burn-signature-1".to_string(),
|
||||
3,
|
||||
@@ -295,14 +295,16 @@ 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 liquidity_events = crate::list_recent_liquidity_events(&database, 10)
|
||||
let swaps = crate::query_swaps_list_recent(&database, 10)
|
||||
.await
|
||||
.expect("swaps list must succeed");
|
||||
let liquidity_events = crate::query_liquidity_events_list_recent(&database, 10)
|
||||
.await
|
||||
.expect("liquidity list must succeed");
|
||||
let mint_events = crate::list_recent_token_mint_events(&database, 10)
|
||||
let mint_events = crate::query_token_mint_events_list_recent(&database, 10)
|
||||
.await
|
||||
.expect("mint events list must succeed");
|
||||
let burn_events = crate::list_recent_token_burn_events(&database, 10)
|
||||
let burn_events = crate::query_token_burn_events_list_recent(&database, 10)
|
||||
.await
|
||||
.expect("burn events list must succeed");
|
||||
assert_eq!(swaps.len(), 1);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user