This commit is contained in:
2026-04-29 07:40:44 +02:00
parent 02aab8c3f6
commit d7b03c91b9
20 changed files with 1523 additions and 11 deletions

View File

@@ -0,0 +1,181 @@
// file: kb_lib/src/db/queries/launch_attribution.rs
//! Queries for `kb_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> {
match database.connection() {
crate::KbDatabaseConnection::Sqlite(pool) => {
let query_result = sqlx::query(
r#"
INSERT INTO kb_launch_attributions (
launch_surface_id,
transaction_id,
decoded_event_id,
pool_id,
pair_id,
matched_key_id,
protocol_name,
match_kind,
matched_value,
attributed_at,
updated_at
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON CONFLICT(decoded_event_id) DO UPDATE SET
launch_surface_id = excluded.launch_surface_id,
transaction_id = excluded.transaction_id,
pool_id = excluded.pool_id,
pair_id = excluded.pair_id,
matched_key_id = excluded.matched_key_id,
protocol_name = excluded.protocol_name,
match_kind = excluded.match_kind,
matched_value = excluded.matched_value,
updated_at = excluded.updated_at
"#,
)
.bind(dto.launch_surface_id)
.bind(dto.transaction_id)
.bind(dto.decoded_event_id)
.bind(dto.pool_id)
.bind(dto.pair_id)
.bind(dto.matched_key_id)
.bind(dto.protocol_name.clone())
.bind(dto.match_kind.clone())
.bind(dto.matched_value.clone())
.bind(dto.attributed_at.to_rfc3339())
.bind(dto.updated_at.to_rfc3339())
.execute(pool)
.await;
if let Err(error) = query_result {
return Err(crate::KbError::Db(format!(
"cannot upsert kb_launch_attributions on sqlite: {}",
error
)));
}
let id_result = sqlx::query_scalar::<sqlx::Sqlite, i64>(
r#"
SELECT id
FROM kb_launch_attributions
WHERE decoded_event_id = ?
LIMIT 1
"#,
)
.bind(dto.decoded_event_id)
.fetch_one(pool)
.await;
match id_result {
Ok(id) => Ok(id),
Err(error) => Err(crate::KbError::Db(format!(
"cannot fetch kb_launch_attributions id for decoded_event_id '{}' on sqlite: {}",
dto.decoded_event_id, error
))),
}
}
}
}
/// 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,
decoded_event_id: i64,
) -> Result<std::option::Option<crate::KbLaunchAttributionDto>, crate::KbError> {
match database.connection() {
crate::KbDatabaseConnection::Sqlite(pool) => {
let query_result =
sqlx::query_as::<sqlx::Sqlite, crate::KbLaunchAttributionEntity>(
r#"
SELECT
id,
launch_surface_id,
transaction_id,
decoded_event_id,
pool_id,
pair_id,
matched_key_id,
protocol_name,
match_kind,
matched_value,
attributed_at,
updated_at
FROM kb_launch_attributions
WHERE decoded_event_id = ?
LIMIT 1
"#,
)
.bind(decoded_event_id)
.fetch_optional(pool)
.await;
let entity_option = match query_result {
Ok(entity_option) => entity_option,
Err(error) => {
return Err(crate::KbError::Db(format!(
"cannot read kb_launch_attributions by decoded_event_id '{}' on sqlite: {}",
decoded_event_id, error
)));
}
};
match entity_option {
Some(entity) => crate::KbLaunchAttributionDto::try_from(entity).map(Some),
None => Ok(None),
}
}
}
}
/// Lists all launch attributions attached to one pool id.
pub async fn list_launch_attributions_by_pool_id(
database: &crate::KbDatabase,
pool_id: i64,
) -> Result<std::vec::Vec<crate::KbLaunchAttributionDto>, crate::KbError> {
match database.connection() {
crate::KbDatabaseConnection::Sqlite(pool) => {
let query_result =
sqlx::query_as::<sqlx::Sqlite, crate::KbLaunchAttributionEntity>(
r#"
SELECT
id,
launch_surface_id,
transaction_id,
decoded_event_id,
pool_id,
pair_id,
matched_key_id,
protocol_name,
match_kind,
matched_value,
attributed_at,
updated_at
FROM kb_launch_attributions
WHERE pool_id = ?
ORDER BY attributed_at ASC, id ASC
"#,
)
.bind(pool_id)
.fetch_all(pool)
.await;
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: {}",
pool_id, error
)));
}
};
let mut dtos = std::vec::Vec::new();
for entity in entities {
let dto_result = crate::KbLaunchAttributionDto::try_from(entity);
let dto = match dto_result {
Ok(dto) => dto,
Err(error) => return Err(error),
};
dtos.push(dto);
}
Ok(dtos)
}
}
}

View File

@@ -0,0 +1,153 @@
// file: kb_lib/src/db/queries/launch_surface.rs
//! Queries for `kb_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> {
match database.connection() {
crate::KbDatabaseConnection::Sqlite(pool) => {
let query_result = sqlx::query(
r#"
INSERT INTO kb_launch_surfaces (
code,
name,
protocol_family,
is_enabled,
created_at,
updated_at
)
VALUES (?, ?, ?, ?, ?, ?)
ON CONFLICT(code) DO UPDATE SET
name = excluded.name,
protocol_family = excluded.protocol_family,
is_enabled = excluded.is_enabled,
updated_at = excluded.updated_at
"#,
)
.bind(dto.code.clone())
.bind(dto.name.clone())
.bind(dto.protocol_family.clone())
.bind(if dto.is_enabled { 1_i64 } else { 0_i64 })
.bind(dto.created_at.to_rfc3339())
.bind(dto.updated_at.to_rfc3339())
.execute(pool)
.await;
if let Err(error) = query_result {
return Err(crate::KbError::Db(format!(
"cannot upsert kb_launch_surfaces on sqlite: {}",
error
)));
}
let id_result = sqlx::query_scalar::<sqlx::Sqlite, i64>(
r#"
SELECT id
FROM kb_launch_surfaces
WHERE code = ?
LIMIT 1
"#,
)
.bind(dto.code.clone())
.fetch_one(pool)
.await;
match id_result {
Ok(id) => Ok(id),
Err(error) => Err(crate::KbError::Db(format!(
"cannot fetch kb_launch_surfaces id for code '{}' on sqlite: {}",
dto.code, error
))),
}
}
}
}
/// Returns one launch surface identified by its stable short code, if it exists.
pub async fn get_launch_surface_by_code(
database: &crate::KbDatabase,
code: &str,
) -> Result<std::option::Option<crate::KbLaunchSurfaceDto>, crate::KbError> {
match database.connection() {
crate::KbDatabaseConnection::Sqlite(pool) => {
let query_result =
sqlx::query_as::<sqlx::Sqlite, crate::KbLaunchSurfaceEntity>(
r#"
SELECT
id,
code,
name,
protocol_family,
is_enabled,
created_at,
updated_at
FROM kb_launch_surfaces
WHERE code = ?
LIMIT 1
"#,
)
.bind(code)
.fetch_optional(pool)
.await;
let entity_option = match query_result {
Ok(entity_option) => entity_option,
Err(error) => {
return Err(crate::KbError::Db(format!(
"cannot read kb_launch_surfaces '{}' on sqlite: {}",
code, error
)));
}
};
match entity_option {
Some(entity) => crate::KbLaunchSurfaceDto::try_from(entity).map(Some),
None => Ok(None),
}
}
}
}
/// 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> {
match database.connection() {
crate::KbDatabaseConnection::Sqlite(pool) => {
let query_result =
sqlx::query_as::<sqlx::Sqlite, crate::KbLaunchSurfaceEntity>(
r#"
SELECT
id,
code,
name,
protocol_family,
is_enabled,
created_at,
updated_at
FROM kb_launch_surfaces
ORDER BY code ASC
"#,
)
.fetch_all(pool)
.await;
let entities = match query_result {
Ok(entities) => entities,
Err(error) => {
return Err(crate::KbError::Db(format!(
"cannot list kb_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 = match dto_result {
Ok(dto) => dto,
Err(error) => return Err(error),
};
dtos.push(dto);
}
Ok(dtos)
}
}
}

View File

@@ -0,0 +1,153 @@
// file: kb_lib/src/db/queries/launch_surface_key.rs
//! Queries for `kb_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> {
match database.connection() {
crate::KbDatabaseConnection::Sqlite(pool) => {
let query_result = sqlx::query(
r#"
INSERT INTO kb_launch_surface_keys (
launch_surface_id,
match_kind,
match_value,
created_at,
updated_at
)
VALUES (?, ?, ?, ?, ?)
ON CONFLICT(match_kind, match_value) DO UPDATE SET
launch_surface_id = excluded.launch_surface_id,
updated_at = excluded.updated_at
"#,
)
.bind(dto.launch_surface_id)
.bind(dto.match_kind.clone())
.bind(dto.match_value.clone())
.bind(dto.created_at.to_rfc3339())
.bind(dto.updated_at.to_rfc3339())
.execute(pool)
.await;
if let Err(error) = query_result {
return Err(crate::KbError::Db(format!(
"cannot upsert kb_launch_surface_keys on sqlite: {}",
error
)));
}
let id_result = sqlx::query_scalar::<sqlx::Sqlite, i64>(
r#"
SELECT id
FROM kb_launch_surface_keys
WHERE match_kind = ? AND match_value = ?
LIMIT 1
"#,
)
.bind(dto.match_kind.clone())
.bind(dto.match_value.clone())
.fetch_one(pool)
.await;
match id_result {
Ok(id) => Ok(id),
Err(error) => Err(crate::KbError::Db(format!(
"cannot fetch kb_launch_surface_keys id for '{}:{}' on sqlite: {}",
dto.match_kind, dto.match_value, error
))),
}
}
}
}
/// 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,
match_kind: &str,
match_value: &str,
) -> Result<std::option::Option<crate::KbLaunchSurfaceKeyDto>, crate::KbError> {
match database.connection() {
crate::KbDatabaseConnection::Sqlite(pool) => {
let query_result =
sqlx::query_as::<sqlx::Sqlite, crate::KbLaunchSurfaceKeyEntity>(
r#"
SELECT
id,
launch_surface_id,
match_kind,
match_value,
created_at,
updated_at
FROM kb_launch_surface_keys
WHERE match_kind = ? AND match_value = ?
LIMIT 1
"#,
)
.bind(match_kind)
.bind(match_value)
.fetch_optional(pool)
.await;
let entity_option = match query_result {
Ok(entity_option) => entity_option,
Err(error) => {
return Err(crate::KbError::Db(format!(
"cannot read kb_launch_surface_keys '{}:{}' on sqlite: {}",
match_kind, match_value, error
)));
}
};
match entity_option {
Some(entity) => crate::KbLaunchSurfaceKeyDto::try_from(entity).map(Some),
None => Ok(None),
}
}
}
}
/// 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,
launch_surface_id: i64,
) -> Result<std::vec::Vec<crate::KbLaunchSurfaceKeyDto>, crate::KbError> {
match database.connection() {
crate::KbDatabaseConnection::Sqlite(pool) => {
let query_result =
sqlx::query_as::<sqlx::Sqlite, crate::KbLaunchSurfaceKeyEntity>(
r#"
SELECT
id,
launch_surface_id,
match_kind,
match_value,
created_at,
updated_at
FROM kb_launch_surface_keys
WHERE launch_surface_id = ?
ORDER BY match_kind ASC, match_value ASC
"#,
)
.bind(launch_surface_id)
.fetch_all(pool)
.await;
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: {}",
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 = match dto_result {
Ok(dto) => dto,
Err(error) => return Err(error),
};
dtos.push(dto);
}
Ok(dtos)
}
}
}