Major refactor
This commit is contained in:
106
crates/siren-core/src/data/executable_query.rs
Normal file
106
crates/siren-core/src/data/executable_query.rs
Normal file
@@ -0,0 +1,106 @@
|
||||
use crate::data::Value;
|
||||
use sqlx::{FromRow, Postgres};
|
||||
|
||||
#[allow(async_fn_in_trait)]
|
||||
pub trait ExecutableQuery {
|
||||
fn build(&self) -> (String, Vec<Value>);
|
||||
|
||||
async fn execute(&self) -> Result<sqlx::postgres::PgQueryResult, sqlx::Error> {
|
||||
// Build the SQL query and its values
|
||||
let (query_string, values) = self.build();
|
||||
|
||||
// Start constructing the query
|
||||
let mut query = sqlx::query(&query_string);
|
||||
|
||||
// Bind each value to its respective placeholder
|
||||
for value in values {
|
||||
match value {
|
||||
Value::Int(n) => query = query.bind(n),
|
||||
Value::OptionalInt(n) => query = query.bind(n),
|
||||
Value::BigInt(n) => query = query.bind(n),
|
||||
Value::OptionalBigInt(n) => query = query.bind(n),
|
||||
Value::Float(n) => query = query.bind(n),
|
||||
Value::OptionalFloat(n) => query = query.bind(n),
|
||||
Value::Double(n) => query = query.bind(n),
|
||||
Value::OptionalDouble(n) => query = query.bind(n),
|
||||
Value::Bool(n) => query = query.bind(n),
|
||||
Value::OptionalBool(n) => query = query.bind(n),
|
||||
Value::Text(n) => query = query.bind(n),
|
||||
Value::OptionalText(n) => query = query.bind(n),
|
||||
Value::DateTime(n) => query = query.bind(n),
|
||||
Value::OptionalDateTime(n) => query = query.bind(n),
|
||||
}
|
||||
}
|
||||
|
||||
let pool = crate::data::pool();
|
||||
query.execute(pool).await
|
||||
}
|
||||
|
||||
async fn fetch_optional<
|
||||
T: Send + Unpin + for<'r> FromRow<'r, <Postgres as sqlx::Database>::Row>,
|
||||
>(
|
||||
&self,
|
||||
) -> Option<T> {
|
||||
let (query_string, values) = self.build();
|
||||
let mut query_as = sqlx::query_as(&query_string);
|
||||
for value in values {
|
||||
match value {
|
||||
Value::Int(n) => query_as = query_as.bind(n),
|
||||
Value::OptionalInt(n) => query_as = query_as.bind(n),
|
||||
Value::BigInt(n) => query_as = query_as.bind(n),
|
||||
Value::OptionalBigInt(n) => query_as = query_as.bind(n),
|
||||
Value::Float(n) => query_as = query_as.bind(n),
|
||||
Value::OptionalFloat(n) => query_as = query_as.bind(n),
|
||||
Value::Double(n) => query_as = query_as.bind(n),
|
||||
Value::OptionalDouble(n) => query_as = query_as.bind(n),
|
||||
Value::Bool(n) => query_as = query_as.bind(n),
|
||||
Value::OptionalBool(n) => query_as = query_as.bind(n),
|
||||
Value::Text(n) => query_as = query_as.bind(n),
|
||||
Value::OptionalText(n) => query_as = query_as.bind(n),
|
||||
Value::DateTime(n) => query_as = query_as.bind(n),
|
||||
Value::OptionalDateTime(n) => query_as = query_as.bind(n),
|
||||
}
|
||||
}
|
||||
|
||||
let pool = crate::data::pool();
|
||||
query_as.fetch_optional(pool).await.unwrap_or_else(|err| {
|
||||
log::error!(
|
||||
"Unable to fetch optional on query '{}': {}",
|
||||
query_string,
|
||||
err
|
||||
);
|
||||
None
|
||||
})
|
||||
}
|
||||
|
||||
async fn fetch_all<T: Send + Unpin + for<'r> FromRow<'r, <Postgres as sqlx::Database>::Row>>(
|
||||
&self,
|
||||
) -> Vec<T> {
|
||||
let (query_string, values) = self.build();
|
||||
let mut query_as = sqlx::query_as(&query_string);
|
||||
for value in values {
|
||||
match value {
|
||||
Value::Int(n) => query_as = query_as.bind(n),
|
||||
Value::OptionalInt(n) => query_as = query_as.bind(n),
|
||||
Value::BigInt(n) => query_as = query_as.bind(n),
|
||||
Value::OptionalBigInt(n) => query_as = query_as.bind(n),
|
||||
Value::Float(n) => query_as = query_as.bind(n),
|
||||
Value::OptionalFloat(n) => query_as = query_as.bind(n),
|
||||
Value::Double(n) => query_as = query_as.bind(n),
|
||||
Value::OptionalDouble(n) => query_as = query_as.bind(n),
|
||||
Value::Bool(n) => query_as = query_as.bind(n),
|
||||
Value::OptionalBool(n) => query_as = query_as.bind(n),
|
||||
Value::Text(n) => query_as = query_as.bind(n),
|
||||
Value::OptionalText(n) => query_as = query_as.bind(n),
|
||||
Value::DateTime(n) => query_as = query_as.bind(n),
|
||||
Value::OptionalDateTime(n) => query_as = query_as.bind(n),
|
||||
}
|
||||
}
|
||||
|
||||
let pool = crate::data::pool();
|
||||
query_as.fetch_all(pool).await.unwrap_or_else(|err| {
|
||||
log::error!("Unable to fetch all on query '{}': {}", query_string, err);
|
||||
vec![]
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user