refactor query
This commit is contained in:
+82
-116
@@ -4,6 +4,18 @@ use sqlx::SqlitePool;
|
||||
use crate::env::Env;
|
||||
use crate::models::{Activity, Plan, Relay, Tenant};
|
||||
|
||||
fn select_tenant(tail: &str) -> String {
|
||||
format!("SELECT * FROM tenant {tail}")
|
||||
}
|
||||
|
||||
fn select_relay(tail: &str) -> String {
|
||||
format!("SELECT * FROM relay {tail}")
|
||||
}
|
||||
|
||||
fn select_activity(tail: &str) -> String {
|
||||
format!("SELECT * FROM activity {tail}")
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Query {
|
||||
pool: SqlitePool,
|
||||
@@ -18,28 +30,7 @@ impl Query {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn list_tenants(&self) -> Result<Vec<Tenant>> {
|
||||
let rows = sqlx::query_as::<_, Tenant>(
|
||||
"SELECT pubkey, nwc_url, nwc_error, created_at, stripe_customer_id, stripe_subscription_id, past_due_at
|
||||
FROM tenant
|
||||
ORDER BY pubkey",
|
||||
)
|
||||
.fetch_all(&self.pool)
|
||||
.await?;
|
||||
Ok(rows)
|
||||
}
|
||||
|
||||
pub async fn get_tenant(&self, pubkey: &str) -> Result<Option<Tenant>> {
|
||||
let row = sqlx::query_as::<_, Tenant>(
|
||||
"SELECT pubkey, nwc_url, nwc_error, created_at, stripe_customer_id, stripe_subscription_id, past_due_at
|
||||
FROM tenant
|
||||
WHERE pubkey = ?",
|
||||
)
|
||||
.bind(pubkey)
|
||||
.fetch_optional(&self.pool)
|
||||
.await?;
|
||||
Ok(row)
|
||||
}
|
||||
// Plans
|
||||
|
||||
pub fn list_plans(&self) -> Vec<Plan> {
|
||||
vec![
|
||||
@@ -77,77 +68,24 @@ impl Query {
|
||||
self.list_plans().into_iter().find(|p| p.id == plan_id)
|
||||
}
|
||||
|
||||
/// True for any plan that costs money. Doesn't require an instance because
|
||||
/// the answer doesn't depend on Stripe price ids — only the canonical plan id.
|
||||
pub fn is_paid_plan(plan_id: &str) -> bool {
|
||||
matches!(plan_id, "basic" | "growth")
|
||||
pub fn is_paid_plan(&self, plan_id: &str) -> bool {
|
||||
self.get_plan(plan_id).is_some_and(|p| p.amount > 0)
|
||||
}
|
||||
|
||||
pub async fn list_relays(&self) -> Result<Vec<Relay>> {
|
||||
let rows = sqlx::query_as::<_, Relay>(
|
||||
"SELECT id, tenant, schema, subdomain, plan, stripe_subscription_item_id,
|
||||
status, sync_error,
|
||||
info_name, info_icon, info_description,
|
||||
policy_public_join, policy_strip_signatures,
|
||||
groups_enabled, management_enabled, blossom_enabled,
|
||||
livekit_enabled, push_enabled, synced
|
||||
FROM relay
|
||||
ORDER BY id",
|
||||
)
|
||||
.fetch_all(&self.pool)
|
||||
.await?;
|
||||
// Tenants
|
||||
|
||||
pub async fn list_tenants(&self) -> Result<Vec<Tenant>> {
|
||||
let rows = sqlx::query_as::<_, Tenant>(&select_tenant(""))
|
||||
.fetch_all(&self.pool)
|
||||
.await?;
|
||||
Ok(rows)
|
||||
}
|
||||
|
||||
pub async fn list_relays_pending_sync(&self) -> Result<Vec<Relay>> {
|
||||
let rows = sqlx::query_as::<_, Relay>(
|
||||
"SELECT id, tenant, schema, subdomain, plan, stripe_subscription_item_id,
|
||||
status, sync_error,
|
||||
info_name, info_icon, info_description,
|
||||
policy_public_join, policy_strip_signatures,
|
||||
groups_enabled, management_enabled, blossom_enabled,
|
||||
livekit_enabled, push_enabled, synced
|
||||
FROM relay
|
||||
WHERE synced = 0 OR TRIM(sync_error) != ''
|
||||
ORDER BY id",
|
||||
)
|
||||
.fetch_all(&self.pool)
|
||||
.await?;
|
||||
Ok(rows)
|
||||
}
|
||||
|
||||
pub async fn list_relays_for_tenant(&self, tenant_id: &str) -> Result<Vec<Relay>> {
|
||||
let rows = sqlx::query_as::<_, Relay>(
|
||||
"SELECT id, tenant, schema, subdomain, plan, stripe_subscription_item_id,
|
||||
status, sync_error,
|
||||
info_name, info_icon, info_description,
|
||||
policy_public_join, policy_strip_signatures,
|
||||
groups_enabled, management_enabled, blossom_enabled,
|
||||
livekit_enabled, push_enabled, synced
|
||||
FROM relay
|
||||
WHERE tenant = ?
|
||||
ORDER BY id",
|
||||
)
|
||||
.bind(tenant_id)
|
||||
.fetch_all(&self.pool)
|
||||
.await?;
|
||||
Ok(rows)
|
||||
}
|
||||
|
||||
pub async fn get_relay(&self, id: &str) -> Result<Option<Relay>> {
|
||||
let row = sqlx::query_as::<_, Relay>(
|
||||
"SELECT id, tenant, schema, subdomain, plan, stripe_subscription_item_id,
|
||||
status, sync_error,
|
||||
info_name, info_icon, info_description,
|
||||
policy_public_join, policy_strip_signatures,
|
||||
groups_enabled, management_enabled, blossom_enabled,
|
||||
livekit_enabled, push_enabled, synced
|
||||
FROM relay
|
||||
WHERE id = ?",
|
||||
)
|
||||
.bind(id)
|
||||
.fetch_optional(&self.pool)
|
||||
.await?;
|
||||
pub async fn get_tenant(&self, pubkey: &str) -> Result<Option<Tenant>> {
|
||||
let row = sqlx::query_as::<_, Tenant>(&select_tenant("WHERE pubkey = ?"))
|
||||
.bind(pubkey)
|
||||
.fetch_optional(&self.pool)
|
||||
.await?;
|
||||
Ok(row)
|
||||
}
|
||||
|
||||
@@ -155,17 +93,49 @@ impl Query {
|
||||
&self,
|
||||
stripe_customer_id: &str,
|
||||
) -> Result<Option<Tenant>> {
|
||||
let row = sqlx::query_as::<_, Tenant>(
|
||||
"SELECT pubkey, nwc_url, nwc_error, created_at, stripe_customer_id, stripe_subscription_id, past_due_at
|
||||
FROM tenant
|
||||
WHERE stripe_customer_id = ?",
|
||||
)
|
||||
.bind(stripe_customer_id)
|
||||
.fetch_optional(&self.pool)
|
||||
.await?;
|
||||
let row = sqlx::query_as::<_, Tenant>(&select_tenant("WHERE stripe_customer_id = ?"))
|
||||
.bind(stripe_customer_id)
|
||||
.fetch_optional(&self.pool)
|
||||
.await?;
|
||||
Ok(row)
|
||||
}
|
||||
|
||||
// Relays
|
||||
|
||||
pub async fn list_relays(&self) -> Result<Vec<Relay>> {
|
||||
let rows = sqlx::query_as::<_, Relay>(&select_relay(""))
|
||||
.fetch_all(&self.pool)
|
||||
.await?;
|
||||
Ok(rows)
|
||||
}
|
||||
|
||||
pub async fn list_relays_pending_sync(&self) -> Result<Vec<Relay>> {
|
||||
let rows = sqlx::query_as::<_, Relay>(&select_relay(
|
||||
"WHERE synced = 0 OR TRIM(sync_error) != ''",
|
||||
))
|
||||
.fetch_all(&self.pool)
|
||||
.await?;
|
||||
Ok(rows)
|
||||
}
|
||||
|
||||
pub async fn list_relays_for_tenant(&self, tenant_id: &str) -> Result<Vec<Relay>> {
|
||||
let rows = sqlx::query_as::<_, Relay>(&select_relay("WHERE tenant = ?"))
|
||||
.bind(tenant_id)
|
||||
.fetch_all(&self.pool)
|
||||
.await?;
|
||||
Ok(rows)
|
||||
}
|
||||
|
||||
pub async fn get_relay(&self, id: &str) -> Result<Option<Relay>> {
|
||||
let row = sqlx::query_as::<_, Relay>(&select_relay("WHERE id = ?"))
|
||||
.bind(id)
|
||||
.fetch_optional(&self.pool)
|
||||
.await?;
|
||||
Ok(row)
|
||||
}
|
||||
|
||||
// Invoice state
|
||||
|
||||
pub async fn get_invoice_nwc_payment_state(&self, invoice_id: &str) -> Result<Option<String>> {
|
||||
let state = sqlx::query_scalar::<_, String>(
|
||||
"SELECT state FROM invoice_nwc_payment WHERE invoice_id = ?",
|
||||
@@ -189,32 +159,28 @@ impl Query {
|
||||
Ok(bolt11)
|
||||
}
|
||||
|
||||
pub async fn list_activity_for_relay(&self, relay_id: &str) -> Result<Vec<Activity>> {
|
||||
let rows = sqlx::query_as::<_, Activity>(
|
||||
"SELECT id, tenant, created_at, activity_type, resource_type, resource_id
|
||||
FROM activity
|
||||
WHERE resource_type = 'relay' AND resource_id = ?
|
||||
ORDER BY created_at DESC, id DESC",
|
||||
)
|
||||
.bind(relay_id)
|
||||
// Activity
|
||||
|
||||
pub async fn list_activity_for_resource(&self, resource_id: &str) -> Result<Vec<Activity>> {
|
||||
let rows = sqlx::query_as::<_, Activity>(&select_activity("WHERE resource_id = ? ORDER BY created_at DESC"))
|
||||
.bind(resource_id)
|
||||
.fetch_all(&self.pool)
|
||||
.await?;
|
||||
Ok(rows)
|
||||
}
|
||||
|
||||
pub async fn relay_has_completed_sync(&self, relay_id: &str) -> Result<bool> {
|
||||
let found = sqlx::query_scalar::<_, i64>(
|
||||
"SELECT 1
|
||||
FROM activity
|
||||
WHERE resource_type = 'relay'
|
||||
AND resource_id = ?
|
||||
AND activity_type = 'complete_relay_sync'
|
||||
LIMIT 1",
|
||||
)
|
||||
.bind(relay_id)
|
||||
pub async fn get_latest_activity_for_resource_and_type(
|
||||
&self,
|
||||
resource_id: &str,
|
||||
activity_type: &str,
|
||||
) -> Result<Option<Activity>> {
|
||||
let row = sqlx::query_as::<_, Activity>(&select_activity(
|
||||
"WHERE resource_id = ? AND activity_type = ? ORDER BY created_at DESC LIMIT 1",
|
||||
))
|
||||
.bind(resource_id)
|
||||
.bind(activity_type)
|
||||
.fetch_optional(&self.pool)
|
||||
.await?;
|
||||
|
||||
Ok(found.is_some())
|
||||
Ok(row)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user