1791 lines
55 KiB
Rust
1791 lines
55 KiB
Rust
// file: kb_lib/src/db/schema.rs
|
|
|
|
//! Database schema initialization.
|
|
|
|
/// Ensures that the database schema exists.
|
|
pub(crate) async fn ensure_schema(database: &crate::KbDatabase) -> Result<(), crate::KbError> {
|
|
match database.connection() {
|
|
crate::KbDatabaseConnection::Sqlite(pool) => {
|
|
let result = create_kb_db_metadata_table(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_known_http_endpoints_table(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_known_ws_endpoints_table(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_db_runtime_events_table(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_db_runtime_events_created_at(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_observed_tokens_table(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_observed_tokens_mint(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_observed_tokens_status(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_onchain_observations_table(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_onchain_observations_object_key(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_onchain_observations_observed_at(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_analysis_signals_table(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_analysis_signals_object_key(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_analysis_signals_created_at(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_dexes_table(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_tokens_table(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_tokens_token_program(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_tokens_is_quote_token(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_pools_table(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_pools_dex_id(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_pairs_table(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_pairs_dex_id(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_pairs_base_token_id(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_pairs_quote_token_id(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_pool_tokens_table(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_pool_tokens_pool_id(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_pool_tokens_token_id(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_pool_listings_table(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_pool_listings_detected_at(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_pool_listings_dex_id(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_swaps_table(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_swaps_pool_id(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_swaps_executed_at(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_swaps_pair_id(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_swaps_slot(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_liquidity_events_table(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_liquidity_events_pool_id(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_liquidity_events_executed_at(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_liquidity_events_pair_id(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_liquidity_events_slot(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_token_mint_events_table(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_token_mint_events_token_id(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_token_mint_events_executed_at(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_token_burn_events_table(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_token_burn_events_token_id(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_token_burn_events_executed_at(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_chain_slots_table(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_chain_transactions_table(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_chain_transactions_slot(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_chain_instructions_table(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_chain_instructions_transaction_id(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_chain_instructions_program_id(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = update_schema_version_metadata(database).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_dex_decoded_events_table(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_dex_decoded_events_transaction_id(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_uq_dex_decoded_events_transaction_instruction_event(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_launch_surfaces_table(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_launch_surface_keys_table(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_launch_surface_keys_surface_id(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_launch_attributions_table(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_launch_attributions_surface_id(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_launch_attributions_pool_id(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_pool_origins_table(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_pool_origins_dex_id(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_pool_origins_pair_id(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_pool_origins_listing_id(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_pool_origins_transaction_id(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_wallets_table(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_wallet_participations_table(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_wallet_participations_wallet_id(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_wallet_participations_pool_id(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_wallet_participations_transaction_id(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_trade_events_table(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_trade_events_pair_id(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_trade_events_pool_id(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_pair_metrics_table(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_wallet_holdings_table(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_wallet_holdings_wallet_id(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
let result = create_kb_idx_wallet_holdings_token_id(pool).await;
|
|
if let Err(error) = result {
|
|
return Err(error);
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Executes one SQLite schema statement.
|
|
async fn execute_sqlite_schema_statement(
|
|
pool: &sqlx::SqlitePool,
|
|
statement_name: &str,
|
|
statement_sql: &str,
|
|
) -> Result<(), crate::KbError> {
|
|
let execute_result = sqlx::query(statement_sql).execute(pool).await;
|
|
match execute_result {
|
|
Ok(_) => Ok(()),
|
|
Err(error) => Err(crate::KbError::Db(format!(
|
|
"cannot initialize sqlite schema statement '{}': {}",
|
|
statement_name, error
|
|
))),
|
|
}
|
|
}
|
|
|
|
/// Updates the persisted schema version metadata entry.
|
|
async fn update_schema_version_metadata(
|
|
database: &crate::KbDatabase,
|
|
) -> Result<(), crate::KbError> {
|
|
let schema_version = crate::KbDbMetadataDto::new(
|
|
"schema_version".to_string(),
|
|
env!("CARGO_PKG_VERSION").to_string(),
|
|
);
|
|
let upsert_result = crate::upsert_db_metadata(database, &schema_version).await;
|
|
match upsert_result {
|
|
Ok(_) => Ok(()),
|
|
Err(error) => Err(error),
|
|
}
|
|
}
|
|
|
|
/// Creates `kb_db_metadata`.
|
|
async fn create_kb_db_metadata_table(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_db_metadata_table",
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS kb_db_metadata (
|
|
key TEXT NOT NULL PRIMARY KEY,
|
|
value TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL
|
|
)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates `kb_known_http_endpoints`.
|
|
async fn create_kb_known_http_endpoints_table(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_known_http_endpoints_table",
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS kb_known_http_endpoints (
|
|
name TEXT NOT NULL PRIMARY KEY,
|
|
provider TEXT NOT NULL,
|
|
url TEXT NOT NULL,
|
|
enabled INTEGER NOT NULL,
|
|
roles_json TEXT NOT NULL,
|
|
last_seen_at TEXT NULL,
|
|
updated_at TEXT NOT NULL
|
|
)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates `kb_known_ws_endpoints`.
|
|
async fn create_kb_known_ws_endpoints_table(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_known_ws_endpoints_table",
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS kb_known_ws_endpoints (
|
|
name TEXT NOT NULL PRIMARY KEY,
|
|
provider TEXT NOT NULL,
|
|
url TEXT NOT NULL,
|
|
enabled INTEGER NOT NULL,
|
|
roles_json TEXT NOT NULL,
|
|
last_seen_at TEXT NULL,
|
|
updated_at TEXT NOT NULL
|
|
)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates `kb_db_runtime_events`.
|
|
async fn create_kb_db_runtime_events_table(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_db_runtime_events_table",
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS kb_db_runtime_events (
|
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
event_kind TEXT NOT NULL,
|
|
level INTEGER NOT NULL,
|
|
source TEXT NOT NULL,
|
|
message TEXT NOT NULL,
|
|
created_at TEXT NOT NULL
|
|
)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates index on `kb_db_runtime_events(created_at)`.
|
|
async fn create_kb_idx_db_runtime_events_created_at(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_db_runtime_events_created_at",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_db_runtime_events_created_at
|
|
ON kb_db_runtime_events (created_at)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates `kb_observed_tokens`.
|
|
async fn create_kb_observed_tokens_table(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_observed_tokens_table",
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS kb_observed_tokens (
|
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
mint TEXT NOT NULL UNIQUE,
|
|
symbol TEXT NULL,
|
|
name TEXT NULL,
|
|
decimals INTEGER NULL,
|
|
token_program TEXT NOT NULL,
|
|
status INTEGER NOT NULL,
|
|
first_seen_at TEXT NOT NULL,
|
|
last_seen_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL
|
|
)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates unique index on `kb_observed_tokens(mint)`.
|
|
async fn create_kb_idx_observed_tokens_mint(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_observed_tokens_mint",
|
|
r#"
|
|
CREATE UNIQUE INDEX IF NOT EXISTS kb_idx_observed_tokens_mint
|
|
ON kb_observed_tokens (mint)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates index on `kb_observed_tokens(status)`.
|
|
async fn create_kb_idx_observed_tokens_status(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_observed_tokens_status",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_observed_tokens_status
|
|
ON kb_observed_tokens (status)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates `kb_onchain_observations`.
|
|
async fn create_kb_onchain_observations_table(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_onchain_observations_table",
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS kb_onchain_observations (
|
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
observation_kind TEXT NOT NULL,
|
|
source_kind INTEGER NOT NULL,
|
|
endpoint_name TEXT NULL,
|
|
object_key TEXT NOT NULL,
|
|
slot INTEGER NULL,
|
|
payload_json TEXT NOT NULL,
|
|
observed_at TEXT NOT NULL
|
|
)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates index on `kb_onchain_observations(object_key)`.
|
|
async fn create_kb_idx_onchain_observations_object_key(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_onchain_observations_object_key",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_onchain_observations_object_key
|
|
ON kb_onchain_observations (object_key)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates index on `kb_onchain_observations(observed_at)`.
|
|
async fn create_kb_idx_onchain_observations_observed_at(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_onchain_observations_observed_at",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_onchain_observations_observed_at
|
|
ON kb_onchain_observations (observed_at)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates `kb_analysis_signals`.
|
|
async fn create_kb_analysis_signals_table(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_analysis_signals_table",
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS kb_analysis_signals (
|
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
signal_kind TEXT NOT NULL,
|
|
severity INTEGER NOT NULL,
|
|
object_key TEXT NOT NULL,
|
|
related_observation_id INTEGER NULL,
|
|
score REAL NULL,
|
|
payload_json TEXT NOT NULL,
|
|
created_at TEXT NOT NULL,
|
|
FOREIGN KEY(related_observation_id) REFERENCES kb_onchain_observations(id)
|
|
)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates index on `kb_analysis_signals(object_key)`.
|
|
async fn create_kb_idx_analysis_signals_object_key(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_analysis_signals_object_key",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_analysis_signals_object_key
|
|
ON kb_analysis_signals (object_key)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates index on `kb_analysis_signals(created_at)`.
|
|
async fn create_kb_idx_analysis_signals_created_at(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_analysis_signals_created_at",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_analysis_signals_created_at
|
|
ON kb_analysis_signals (created_at)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates `kb_dexes`.
|
|
async fn create_kb_dexes_table(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_dexes_table",
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS kb_dexes (
|
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
code TEXT NOT NULL UNIQUE,
|
|
name TEXT NOT NULL,
|
|
program_id TEXT NULL,
|
|
router_program_id TEXT NULL,
|
|
is_enabled INTEGER NOT NULL,
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL
|
|
)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates `kb_tokens`.
|
|
async fn create_kb_tokens_table(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_tokens_table",
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS kb_tokens (
|
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
mint TEXT NOT NULL UNIQUE,
|
|
symbol TEXT NULL,
|
|
name TEXT NULL,
|
|
decimals INTEGER NULL,
|
|
token_program TEXT NOT NULL,
|
|
is_quote_token INTEGER NOT NULL,
|
|
first_seen_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL
|
|
)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates index on `kb_tokens(token_program)`.
|
|
async fn create_kb_idx_tokens_token_program(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_tokens_token_program",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_tokens_token_program
|
|
ON kb_tokens (token_program)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates index on `kb_tokens(is_quote_token)`.
|
|
async fn create_kb_idx_tokens_is_quote_token(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_tokens_is_quote_token",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_tokens_is_quote_token
|
|
ON kb_tokens (is_quote_token)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates `kb_pools`.
|
|
async fn create_kb_pools_table(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_pools_table",
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS kb_pools (
|
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
dex_id INTEGER NOT NULL,
|
|
address TEXT NOT NULL UNIQUE,
|
|
pool_kind INTEGER NOT NULL,
|
|
status INTEGER NOT NULL,
|
|
first_seen_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL,
|
|
FOREIGN KEY(dex_id) REFERENCES kb_dexes(id)
|
|
)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates index on `kb_pools(dex_id)`.
|
|
async fn create_kb_idx_pools_dex_id(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_pools_dex_id",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_pools_dex_id
|
|
ON kb_pools (dex_id)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates `kb_pairs`.
|
|
async fn create_kb_pairs_table(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_pairs_table",
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS kb_pairs (
|
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
dex_id INTEGER NOT NULL,
|
|
pool_id INTEGER NOT NULL UNIQUE,
|
|
base_token_id INTEGER NOT NULL,
|
|
quote_token_id INTEGER NOT NULL,
|
|
symbol TEXT NULL,
|
|
first_seen_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL,
|
|
FOREIGN KEY(dex_id) REFERENCES kb_dexes(id),
|
|
FOREIGN KEY(pool_id) REFERENCES kb_pools(id),
|
|
FOREIGN KEY(base_token_id) REFERENCES kb_tokens(id),
|
|
FOREIGN KEY(quote_token_id) REFERENCES kb_tokens(id)
|
|
)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates index on `kb_pairs(dex_id)`.
|
|
async fn create_kb_idx_pairs_dex_id(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_pairs_dex_id",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_pairs_dex_id
|
|
ON kb_pairs (dex_id)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates index on `kb_pairs(base_token_id)`.
|
|
async fn create_kb_idx_pairs_base_token_id(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_pairs_base_token_id",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_pairs_base_token_id
|
|
ON kb_pairs (base_token_id)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates index on `kb_pairs(quote_token_id)`.
|
|
async fn create_kb_idx_pairs_quote_token_id(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_pairs_quote_token_id",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_pairs_quote_token_id
|
|
ON kb_pairs (quote_token_id)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates `kb_pool_tokens`.
|
|
async fn create_kb_pool_tokens_table(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_pool_tokens_table",
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS kb_pool_tokens (
|
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
pool_id INTEGER NOT NULL,
|
|
token_id INTEGER NOT NULL,
|
|
role INTEGER NOT NULL,
|
|
vault_address TEXT NULL,
|
|
token_order INTEGER NULL,
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL,
|
|
FOREIGN KEY(pool_id) REFERENCES kb_pools(id),
|
|
FOREIGN KEY(token_id) REFERENCES kb_tokens(id),
|
|
UNIQUE(pool_id, token_id, role)
|
|
)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates index on `kb_pool_tokens(pool_id)`.
|
|
async fn create_kb_idx_pool_tokens_pool_id(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_pool_tokens_pool_id",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_pool_tokens_pool_id
|
|
ON kb_pool_tokens (pool_id)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates index on `kb_pool_tokens(token_id)`.
|
|
async fn create_kb_idx_pool_tokens_token_id(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_pool_tokens_token_id",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_pool_tokens_token_id
|
|
ON kb_pool_tokens (token_id)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates `kb_pool_listings`.
|
|
async fn create_kb_pool_listings_table(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_pool_listings_table",
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS kb_pool_listings (
|
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
dex_id INTEGER NOT NULL,
|
|
pool_id INTEGER NOT NULL UNIQUE,
|
|
pair_id INTEGER NULL,
|
|
source_kind INTEGER NOT NULL,
|
|
source_endpoint_name TEXT NULL,
|
|
detected_at TEXT NOT NULL,
|
|
initial_base_reserve REAL NULL,
|
|
initial_quote_reserve REAL NULL,
|
|
initial_price_quote REAL NULL,
|
|
updated_at TEXT NOT NULL,
|
|
FOREIGN KEY(dex_id) REFERENCES kb_dexes(id),
|
|
FOREIGN KEY(pool_id) REFERENCES kb_pools(id),
|
|
FOREIGN KEY(pair_id) REFERENCES kb_pairs(id)
|
|
)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates index on `kb_pool_listings(detected_at)`.
|
|
async fn create_kb_idx_pool_listings_detected_at(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_pool_listings_detected_at",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_pool_listings_detected_at
|
|
ON kb_pool_listings (detected_at)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates index on `kb_pool_listings(dex_id)`.
|
|
async fn create_kb_idx_pool_listings_dex_id(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_pool_listings_dex_id",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_pool_listings_dex_id
|
|
ON kb_pool_listings (dex_id)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates `kb_swaps`.
|
|
async fn create_kb_swaps_table(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_swaps_table",
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS kb_swaps (
|
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
dex_id INTEGER NOT NULL,
|
|
pool_id INTEGER NOT NULL,
|
|
pair_id INTEGER NULL,
|
|
signature TEXT NOT NULL,
|
|
instruction_index INTEGER NOT NULL,
|
|
slot INTEGER NULL,
|
|
trader_wallet TEXT NULL,
|
|
base_token_id INTEGER NOT NULL,
|
|
quote_token_id INTEGER NOT NULL,
|
|
base_amount TEXT NOT NULL,
|
|
quote_amount TEXT NOT NULL,
|
|
price_quote TEXT NULL,
|
|
trade_side INTEGER NOT NULL,
|
|
executed_at TEXT NOT NULL,
|
|
FOREIGN KEY(dex_id) REFERENCES kb_dexes(id),
|
|
FOREIGN KEY(pool_id) REFERENCES kb_pools(id),
|
|
FOREIGN KEY(pair_id) REFERENCES kb_pairs(id),
|
|
FOREIGN KEY(base_token_id) REFERENCES kb_tokens(id),
|
|
FOREIGN KEY(quote_token_id) REFERENCES kb_tokens(id),
|
|
UNIQUE(signature, instruction_index)
|
|
)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates index on `kb_swaps(pool_id)`.
|
|
async fn create_kb_idx_swaps_pool_id(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_swaps_pool_id",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_swaps_pool_id
|
|
ON kb_swaps (pool_id)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates index on `kb_swaps(executed_at)`.
|
|
async fn create_kb_idx_swaps_executed_at(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_swaps_executed_at",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_swaps_executed_at
|
|
ON kb_swaps (executed_at)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates index on `kb_swaps(pair_id)`.
|
|
async fn create_kb_idx_swaps_pair_id(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_swaps_pair_id",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_swaps_pair_id
|
|
ON kb_swaps (pair_id)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates index on `kb_swaps(slot)`.
|
|
async fn create_kb_idx_swaps_slot(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_swaps_slot",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_swaps_slot
|
|
ON kb_swaps (slot)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates `kb_liquidity_events`.
|
|
async fn create_kb_liquidity_events_table(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_liquidity_events_table",
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS kb_liquidity_events (
|
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
dex_id INTEGER NOT NULL,
|
|
pool_id INTEGER NOT NULL,
|
|
pair_id INTEGER NULL,
|
|
signature TEXT NOT NULL,
|
|
instruction_index INTEGER NOT NULL,
|
|
slot INTEGER NULL,
|
|
event_kind INTEGER NOT NULL,
|
|
actor_wallet TEXT NULL,
|
|
base_token_id INTEGER NOT NULL,
|
|
quote_token_id INTEGER NOT NULL,
|
|
lp_token_id INTEGER NULL,
|
|
base_amount TEXT NOT NULL,
|
|
quote_amount TEXT NOT NULL,
|
|
lp_amount TEXT NULL,
|
|
executed_at TEXT NOT NULL,
|
|
FOREIGN KEY(dex_id) REFERENCES kb_dexes(id),
|
|
FOREIGN KEY(pool_id) REFERENCES kb_pools(id),
|
|
FOREIGN KEY(pair_id) REFERENCES kb_pairs(id),
|
|
FOREIGN KEY(base_token_id) REFERENCES kb_tokens(id),
|
|
FOREIGN KEY(quote_token_id) REFERENCES kb_tokens(id),
|
|
FOREIGN KEY(lp_token_id) REFERENCES kb_tokens(id),
|
|
UNIQUE(signature, instruction_index)
|
|
)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates index on `kb_liquidity_events(pool_id)`.
|
|
async fn create_kb_idx_liquidity_events_pool_id(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_liquidity_events_pool_id",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_liquidity_events_pool_id
|
|
ON kb_liquidity_events (pool_id)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates index on `kb_liquidity_events(executed_at)`.
|
|
async fn create_kb_idx_liquidity_events_executed_at(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_liquidity_events_executed_at",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_liquidity_events_executed_at
|
|
ON kb_liquidity_events (executed_at)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates index on `kb_liquidity_events(pair_id)`.
|
|
async fn create_kb_idx_liquidity_events_pair_id(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_liquidity_events_pair_id",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_liquidity_events_pair_id
|
|
ON kb_liquidity_events (pair_id)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates index on `kb_liquidity_events(slot)`.
|
|
async fn create_kb_idx_liquidity_events_slot(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_liquidity_events_slot",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_liquidity_events_slot
|
|
ON kb_liquidity_events (slot)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates `kb_token_mint_events`.
|
|
async fn create_kb_token_mint_events_table(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_token_mint_events_table",
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS kb_token_mint_events (
|
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
token_id INTEGER NOT NULL,
|
|
signature TEXT NOT NULL,
|
|
instruction_index INTEGER NOT NULL,
|
|
slot INTEGER NULL,
|
|
authority_wallet TEXT NULL,
|
|
destination_wallet TEXT NULL,
|
|
amount TEXT NOT NULL,
|
|
supply_after TEXT NULL,
|
|
executed_at TEXT NOT NULL,
|
|
FOREIGN KEY(token_id) REFERENCES kb_tokens(id),
|
|
UNIQUE(signature, instruction_index)
|
|
)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates index on `kb_token_mint_events(token_id)`.
|
|
async fn create_kb_idx_token_mint_events_token_id(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_token_mint_events_token_id",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_token_mint_events_token_id
|
|
ON kb_token_mint_events (token_id)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates index on `kb_token_mint_events(executed_at)`.
|
|
async fn create_kb_idx_token_mint_events_executed_at(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_token_mint_events_executed_at",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_token_mint_events_executed_at
|
|
ON kb_token_mint_events (executed_at)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates `kb_token_burn_events`.
|
|
async fn create_kb_token_burn_events_table(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_token_burn_events_table",
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS kb_token_burn_events (
|
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
token_id INTEGER NOT NULL,
|
|
signature TEXT NOT NULL,
|
|
instruction_index INTEGER NOT NULL,
|
|
slot INTEGER NULL,
|
|
authority_wallet TEXT NULL,
|
|
source_wallet TEXT NULL,
|
|
amount TEXT NOT NULL,
|
|
supply_after TEXT NULL,
|
|
executed_at TEXT NOT NULL,
|
|
FOREIGN KEY(token_id) REFERENCES kb_tokens(id),
|
|
UNIQUE(signature, instruction_index)
|
|
)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates index on `kb_token_burn_events(token_id)`.
|
|
async fn create_kb_idx_token_burn_events_token_id(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_token_burn_events_token_id",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_token_burn_events_token_id
|
|
ON kb_token_burn_events (token_id)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates index on `kb_token_burn_events(executed_at)`.
|
|
async fn create_kb_idx_token_burn_events_executed_at(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_token_burn_events_executed_at",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_token_burn_events_executed_at
|
|
ON kb_token_burn_events (executed_at)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates `kb_chain_slots`.
|
|
async fn create_kb_chain_slots_table(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_chain_slots_table",
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS kb_chain_slots (
|
|
slot INTEGER NOT NULL PRIMARY KEY,
|
|
parent_slot INTEGER NULL,
|
|
block_time_unix INTEGER NULL,
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL
|
|
)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates `kb_chain_transactions`.
|
|
async fn create_kb_chain_transactions_table(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_chain_transactions_table",
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS kb_chain_transactions (
|
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
signature TEXT NOT NULL UNIQUE,
|
|
slot INTEGER NULL,
|
|
block_time_unix INTEGER NULL,
|
|
source_endpoint_name TEXT NULL,
|
|
version_text TEXT NULL,
|
|
err_json TEXT NULL,
|
|
meta_json TEXT NULL,
|
|
transaction_json TEXT NOT NULL,
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL,
|
|
FOREIGN KEY(slot) REFERENCES kb_chain_slots(slot)
|
|
)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates index on `kb_chain_transactions(slot)`.
|
|
async fn create_kb_idx_chain_transactions_slot(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_chain_transactions_slot",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_chain_transactions_slot
|
|
ON kb_chain_transactions (slot)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates `kb_chain_instructions`.
|
|
async fn create_kb_chain_instructions_table(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_chain_instructions_table",
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS kb_chain_instructions (
|
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
transaction_id INTEGER NOT NULL,
|
|
parent_instruction_id INTEGER NULL,
|
|
instruction_index INTEGER NOT NULL,
|
|
inner_instruction_index INTEGER NULL,
|
|
program_id TEXT NULL,
|
|
program_name TEXT NULL,
|
|
stack_height INTEGER NULL,
|
|
accounts_json TEXT NOT NULL,
|
|
data_json TEXT NULL,
|
|
parsed_type TEXT NULL,
|
|
parsed_json TEXT NULL,
|
|
created_at TEXT NOT NULL,
|
|
FOREIGN KEY(transaction_id) REFERENCES kb_chain_transactions(id),
|
|
FOREIGN KEY(parent_instruction_id) REFERENCES kb_chain_instructions(id)
|
|
)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates index on `kb_chain_instructions(transaction_id)`.
|
|
async fn create_kb_idx_chain_instructions_transaction_id(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_chain_instructions_transaction_id",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_chain_instructions_transaction_id
|
|
ON kb_chain_instructions (transaction_id)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates index on `kb_chain_instructions(program_id)`.
|
|
async fn create_kb_idx_chain_instructions_program_id(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_chain_instructions_program_id",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_chain_instructions_program_id
|
|
ON kb_chain_instructions (program_id)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates `kb_dex_decoded_events`.
|
|
async fn create_kb_dex_decoded_events_table(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_dex_decoded_events_table",
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS kb_dex_decoded_events (
|
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
transaction_id INTEGER NOT NULL,
|
|
instruction_id INTEGER NULL,
|
|
protocol_name TEXT NOT NULL,
|
|
program_id TEXT NOT NULL,
|
|
event_kind TEXT NOT NULL,
|
|
pool_account TEXT NULL,
|
|
lp_mint TEXT NULL,
|
|
token_a_mint TEXT NULL,
|
|
token_b_mint TEXT NULL,
|
|
market_account TEXT NULL,
|
|
payload_json TEXT NOT NULL,
|
|
created_at TEXT NOT NULL,
|
|
FOREIGN KEY(transaction_id) REFERENCES kb_chain_transactions(id),
|
|
FOREIGN KEY(instruction_id) REFERENCES kb_chain_instructions(id)
|
|
)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates index on `kb_dex_decoded_events(transaction_id)`.
|
|
async fn create_kb_idx_dex_decoded_events_transaction_id(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_dex_decoded_events_transaction_id",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_dex_decoded_events_transaction_id
|
|
ON kb_dex_decoded_events (transaction_id)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
/// Creates unique index on `(transaction_id, instruction_id, event_kind)`.
|
|
async fn create_kb_uq_dex_decoded_events_transaction_instruction_event(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_uq_dex_decoded_events_transaction_instruction_event",
|
|
r#"
|
|
CREATE UNIQUE INDEX IF NOT EXISTS kb_uq_dex_decoded_events_transaction_instruction_event
|
|
ON kb_dex_decoded_events (transaction_id, instruction_id, event_kind)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
async fn create_kb_launch_surfaces_table(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_launch_surfaces_table",
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS kb_launch_surfaces (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
code TEXT NOT NULL UNIQUE,
|
|
name TEXT NOT NULL,
|
|
protocol_family TEXT NULL,
|
|
is_enabled INTEGER NOT NULL,
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL
|
|
)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
async fn create_kb_launch_surface_keys_table(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_launch_surface_keys_table",
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS kb_launch_surface_keys (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
launch_surface_id INTEGER NOT NULL,
|
|
match_kind TEXT NOT NULL,
|
|
match_value TEXT NOT NULL,
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL,
|
|
FOREIGN KEY(launch_surface_id) REFERENCES kb_launch_surfaces(id) ON DELETE CASCADE,
|
|
UNIQUE(match_kind, match_value)
|
|
)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
async fn create_kb_idx_launch_surface_keys_surface_id(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_launch_surface_keys_surface_id",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_launch_surface_keys_surface_id
|
|
ON kb_launch_surface_keys(launch_surface_id)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
async fn create_kb_launch_attributions_table(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_launch_attributions_table",
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS kb_launch_attributions (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
launch_surface_id INTEGER NOT NULL,
|
|
transaction_id INTEGER NOT NULL,
|
|
decoded_event_id INTEGER NOT NULL UNIQUE,
|
|
pool_id INTEGER NULL,
|
|
pair_id INTEGER NULL,
|
|
matched_key_id INTEGER NULL,
|
|
protocol_name TEXT NOT NULL,
|
|
match_kind TEXT NOT NULL,
|
|
matched_value TEXT NOT NULL,
|
|
attributed_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL,
|
|
FOREIGN KEY(launch_surface_id) REFERENCES kb_launch_surfaces(id) ON DELETE CASCADE,
|
|
FOREIGN KEY(transaction_id) REFERENCES kb_chain_transactions(id) ON DELETE CASCADE,
|
|
FOREIGN KEY(decoded_event_id) REFERENCES kb_dex_decoded_events(id) ON DELETE CASCADE,
|
|
FOREIGN KEY(pool_id) REFERENCES kb_pools(id) ON DELETE SET NULL,
|
|
FOREIGN KEY(pair_id) REFERENCES kb_pairs(id) ON DELETE SET NULL,
|
|
FOREIGN KEY(matched_key_id) REFERENCES kb_launch_surface_keys(id) ON DELETE SET NULL
|
|
)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
async fn create_kb_idx_launch_attributions_surface_id(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_launch_attributions_surface_id",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_launch_attributions_surface_id
|
|
ON kb_launch_attributions(launch_surface_id)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
async fn create_kb_idx_launch_attributions_pool_id(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_launch_attributions_pool_id",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_launch_attributions_pool_id
|
|
ON kb_launch_attributions(pool_id)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
async fn create_kb_pool_origins_table(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_pool_origins_table",
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS kb_pool_origins (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
dex_id INTEGER NOT NULL,
|
|
pool_id INTEGER NOT NULL UNIQUE,
|
|
pair_id INTEGER NULL,
|
|
pool_listing_id INTEGER NULL,
|
|
founding_transaction_id INTEGER NOT NULL,
|
|
founding_decoded_event_id INTEGER NOT NULL UNIQUE,
|
|
founding_signature TEXT NOT NULL,
|
|
founding_protocol_name TEXT NOT NULL,
|
|
founding_event_kind TEXT NOT NULL,
|
|
source_kind INTEGER NOT NULL,
|
|
source_endpoint_name TEXT NULL,
|
|
launch_attribution_id INTEGER NULL,
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL,
|
|
FOREIGN KEY(dex_id) REFERENCES kb_dexes(id) ON DELETE CASCADE,
|
|
FOREIGN KEY(pool_id) REFERENCES kb_pools(id) ON DELETE CASCADE,
|
|
FOREIGN KEY(pair_id) REFERENCES kb_pairs(id) ON DELETE SET NULL,
|
|
FOREIGN KEY(pool_listing_id) REFERENCES kb_pool_listings(id) ON DELETE SET NULL,
|
|
FOREIGN KEY(founding_transaction_id) REFERENCES kb_chain_transactions(id) ON DELETE CASCADE,
|
|
FOREIGN KEY(founding_decoded_event_id) REFERENCES kb_dex_decoded_events(id) ON DELETE CASCADE,
|
|
FOREIGN KEY(launch_attribution_id) REFERENCES kb_launch_attributions(id) ON DELETE SET NULL
|
|
)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
async fn create_kb_idx_pool_origins_dex_id(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_pool_origins_dex_id",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_pool_origins_dex_id
|
|
ON kb_pool_origins(dex_id)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
async fn create_kb_idx_pool_origins_pair_id(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_pool_origins_pair_id",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_pool_origins_pair_id
|
|
ON kb_pool_origins(pair_id)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
async fn create_kb_idx_pool_origins_listing_id(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_pool_origins_listing_id",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_pool_origins_listing_id
|
|
ON kb_pool_origins(pool_listing_id)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
async fn create_kb_idx_pool_origins_transaction_id(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_pool_origins_transaction_id",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_pool_origins_transaction_id
|
|
ON kb_pool_origins(founding_transaction_id)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
async fn create_kb_wallets_table(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_wallets_table",
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS kb_wallets (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
address TEXT NOT NULL UNIQUE,
|
|
label TEXT NULL,
|
|
first_seen_at TEXT NOT NULL,
|
|
last_seen_at TEXT NOT NULL
|
|
)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
async fn create_kb_wallet_participations_table(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_wallet_participations_table",
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS kb_wallet_participations (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
wallet_id INTEGER NOT NULL,
|
|
transaction_id INTEGER NOT NULL,
|
|
decoded_event_id INTEGER NULL,
|
|
pool_id INTEGER NULL,
|
|
pair_id INTEGER NULL,
|
|
role TEXT NOT NULL,
|
|
unique_key TEXT NOT NULL UNIQUE,
|
|
source_kind INTEGER NOT NULL,
|
|
source_endpoint_name TEXT NULL,
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL,
|
|
FOREIGN KEY(wallet_id) REFERENCES kb_wallets(id) ON DELETE CASCADE,
|
|
FOREIGN KEY(transaction_id) REFERENCES kb_chain_transactions(id) ON DELETE CASCADE,
|
|
FOREIGN KEY(decoded_event_id) REFERENCES kb_dex_decoded_events(id) ON DELETE SET NULL,
|
|
FOREIGN KEY(pool_id) REFERENCES kb_pools(id) ON DELETE SET NULL,
|
|
FOREIGN KEY(pair_id) REFERENCES kb_pairs(id) ON DELETE SET NULL
|
|
)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
async fn create_kb_idx_wallet_participations_wallet_id(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_wallet_participations_wallet_id",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_wallet_participations_wallet_id
|
|
ON kb_wallet_participations(wallet_id)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
async fn create_kb_idx_wallet_participations_pool_id(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_wallet_participations_pool_id",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_wallet_participations_pool_id
|
|
ON kb_wallet_participations(pool_id)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
async fn create_kb_idx_wallet_participations_transaction_id(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_wallet_participations_transaction_id",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_wallet_participations_transaction_id
|
|
ON kb_wallet_participations(transaction_id)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
async fn create_kb_trade_events_table(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_trade_events_table",
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS kb_trade_events (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
dex_id INTEGER NOT NULL,
|
|
pool_id INTEGER NOT NULL,
|
|
pair_id INTEGER NOT NULL,
|
|
transaction_id INTEGER NOT NULL,
|
|
decoded_event_id INTEGER NOT NULL UNIQUE,
|
|
signature TEXT NOT NULL,
|
|
slot INTEGER NULL,
|
|
trade_side TEXT NOT NULL,
|
|
base_token_id INTEGER NOT NULL,
|
|
quote_token_id INTEGER NOT NULL,
|
|
base_amount_raw TEXT NULL,
|
|
quote_amount_raw TEXT NULL,
|
|
price_quote_per_base REAL NULL,
|
|
source_kind INTEGER NOT NULL,
|
|
source_endpoint_name TEXT NULL,
|
|
payload_json TEXT NOT NULL,
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL,
|
|
FOREIGN KEY(dex_id) REFERENCES kb_dexes(id) ON DELETE CASCADE,
|
|
FOREIGN KEY(pool_id) REFERENCES kb_pools(id) ON DELETE CASCADE,
|
|
FOREIGN KEY(pair_id) REFERENCES kb_pairs(id) ON DELETE CASCADE,
|
|
FOREIGN KEY(transaction_id) REFERENCES kb_chain_transactions(id) ON DELETE CASCADE,
|
|
FOREIGN KEY(decoded_event_id) REFERENCES kb_dex_decoded_events(id) ON DELETE CASCADE,
|
|
FOREIGN KEY(base_token_id) REFERENCES kb_tokens(id) ON DELETE CASCADE,
|
|
FOREIGN KEY(quote_token_id) REFERENCES kb_tokens(id) ON DELETE CASCADE
|
|
)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
async fn create_kb_idx_trade_events_pair_id(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_trade_events_pair_id",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_trade_events_pair_id
|
|
ON kb_trade_events(pair_id)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
async fn create_kb_idx_trade_events_pool_id(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_trade_events_pool_id",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_trade_events_pool_id
|
|
ON kb_trade_events(pool_id)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
async fn create_kb_pair_metrics_table(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_pair_metrics_table",
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS kb_pair_metrics (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
pair_id INTEGER NOT NULL UNIQUE,
|
|
first_slot INTEGER NULL,
|
|
last_slot INTEGER NULL,
|
|
first_signature TEXT NULL,
|
|
last_signature TEXT NULL,
|
|
trade_count INTEGER NOT NULL,
|
|
buy_count INTEGER NOT NULL,
|
|
sell_count INTEGER NOT NULL,
|
|
cumulative_base_amount_raw TEXT NULL,
|
|
cumulative_quote_amount_raw TEXT NULL,
|
|
last_price_quote_per_base REAL NULL,
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL,
|
|
FOREIGN KEY(pair_id) REFERENCES kb_pairs(id) ON DELETE CASCADE
|
|
)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
async fn create_kb_wallet_holdings_table(pool: &sqlx::SqlitePool) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_wallet_holdings_table",
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS kb_wallet_holdings (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
wallet_id INTEGER NOT NULL,
|
|
token_id INTEGER NOT NULL,
|
|
first_transaction_id INTEGER NOT NULL,
|
|
last_transaction_id INTEGER NOT NULL,
|
|
last_decoded_event_id INTEGER NULL,
|
|
last_pool_id INTEGER NULL,
|
|
last_pair_id INTEGER NULL,
|
|
last_role TEXT NULL,
|
|
balance_raw TEXT NULL,
|
|
last_slot_observed INTEGER NULL,
|
|
source_kind INTEGER NOT NULL,
|
|
source_endpoint_name TEXT NULL,
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL,
|
|
UNIQUE(wallet_id, token_id),
|
|
FOREIGN KEY(wallet_id) REFERENCES kb_wallets(id) ON DELETE CASCADE,
|
|
FOREIGN KEY(token_id) REFERENCES kb_tokens(id) ON DELETE CASCADE,
|
|
FOREIGN KEY(first_transaction_id) REFERENCES kb_chain_transactions(id) ON DELETE CASCADE,
|
|
FOREIGN KEY(last_transaction_id) REFERENCES kb_chain_transactions(id) ON DELETE CASCADE,
|
|
FOREIGN KEY(last_decoded_event_id) REFERENCES kb_dex_decoded_events(id) ON DELETE SET NULL,
|
|
FOREIGN KEY(last_pool_id) REFERENCES kb_pools(id) ON DELETE SET NULL,
|
|
FOREIGN KEY(last_pair_id) REFERENCES kb_pairs(id) ON DELETE SET NULL
|
|
)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
async fn create_kb_idx_wallet_holdings_wallet_id(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_wallet_holdings_wallet_id",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_wallet_holdings_wallet_id
|
|
ON kb_wallet_holdings(wallet_id)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|
|
|
|
async fn create_kb_idx_wallet_holdings_token_id(
|
|
pool: &sqlx::SqlitePool,
|
|
) -> Result<(), crate::KbError> {
|
|
execute_sqlite_schema_statement(
|
|
pool,
|
|
"create_kb_idx_wallet_holdings_token_id",
|
|
r#"
|
|
CREATE INDEX IF NOT EXISTS kb_idx_wallet_holdings_token_id
|
|
ON kb_wallet_holdings(token_id)
|
|
"#,
|
|
)
|
|
.await
|
|
}
|