Fixed insert

This commit is contained in:
2024-12-22 15:28:37 -05:00
parent 4c5300fa59
commit bd132d0c6b
7 changed files with 53 additions and 61 deletions

View File

@@ -11,5 +11,5 @@ post {
}
auth:bearer {
token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjI1MDg0MjI2MTIyMTI3NzY5NywibmFtZSI6ImJzaGVycmlmZiIsImlhdCI6MTczNDgwODA5MiwiZXhwIjoxNzM0ODk0NDkyLCJqdGkiOiJsSWFHaU15Wll5cnFVYmFJTGs2dzAyZTY4YkFPZjFZWSJ9.fCeooH2IdtXiy2s23WykXtOaR8dvnUinmSGFcV-fOwQ
token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjI1MDg0MjI2MTIyMTI3NzY5NywibmFtZSI6ImJzaGVycmlmZiIsImlhdCI6MTczNDg0MzA0NywiZXhwIjoxNzM0OTI5NDQ3LCJqdGkiOiIycEowbmN5YmF1TVo4TG1aQ0VwU1B2OWgzMXFzU1FwaCJ9.gYf6oAm2POBXOHUnG4dTy5maKxTjUk8WxawOrIafjEE
}

View File

@@ -8,7 +8,9 @@ use crate::api::auth::{csprng, AuthCredential};
use crate::api::auth::AuthorizationMiddleware;
use crate::AppState;
use crate::data::condition::Condition;
use crate::data::insert::InsertBuilder;
use crate::data::query::QueryBuilder;
use crate::data::update::UpdateBuilder;
use crate::data::Value;
use crate::error::{Error, SirenResult};
@@ -43,65 +45,38 @@ impl ApiKey {
}
pub async fn insert(&self) -> SirenResult<()> {
let pool = crate::data::pool();
sqlx::query(&format!(
"INSERT INTO {} (
key,
user_id,
user_name,
access_mask,
created_at,
last_used_at
) VALUES (
$1, $2, $3, $4, $5, $6
)",
TABLE_NAME
))
.bind(&self.key)
.bind(self.user_id)
.bind(&self.user_name)
.bind(self.access_mask)
.bind(self.created_at)
.bind(self.last_used_at)
.execute(pool)
.await?;
InsertBuilder::new(TABLE_NAME)
.column("key", Value::Text(self.key.clone()))
.column("user_id", Value::BigInt(self.user_id))
.column("user_name", Value::Text(self.user_name.clone()))
.column("access_mask", Value::Int(self.access_mask))
.column("created_at", Value::DateTime(self.created_at))
.column("last_used_at", Value::OptionalDateTime(self.last_used_at))
.execute().await?;
Ok(())
}
pub async fn update(&self) -> SirenResult<()> {
let pool = crate::data::pool();
sqlx::query(&format!(
"UPDATE {} SET
user_id = $2,
user_name = $3,
access_mask = $4,
created_at = $5,
last_used_at = $6
WHERE key = $1",
TABLE_NAME
))
.bind(&self.key)
.bind(self.user_id)
.bind(&self.user_name)
.bind(self.access_mask)
.bind(self.created_at)
.bind(self.last_used_at)
.execute(pool)
.await?;
Ok(())
match UpdateBuilder::new(TABLE_NAME)
.column("user_id", Value::BigInt(self.user_id))
.column("user_name", Value::Text(self.user_name.clone()))
.column("access_mask", Value::Int(self.access_mask))
.column("created_at", Value::DateTime(self.created_at))
.column("last_used_at", Value::OptionalDateTime(self.last_used_at))
.where_condition(Condition::is_equal("key", Value::Text(self.key.clone())))
.execute().await {
Ok(_) => Ok(()),
Err(err) => {
log::error!("error: {}", err);
Err(err.into())
}
}
}
pub async fn find_by_key(key: &str) -> SirenResult<Option<Self>> {
let pool = crate::data::pool();
let query = QueryBuilder::new(TABLE_NAME)
pub async fn find_by_key(key: &str) -> Option<Self> {
QueryBuilder::new(TABLE_NAME)
.where_condition(Condition::is_equal("key", Value::Text(key.to_string())))
.build();
let item = sqlx::query_as(&query.0)
.bind(key)
.fetch_optional(pool)
.await?;
Ok(item)
.fetch_optional().await
}
pub async fn delete_by_id(key: &str) -> SirenResult<()> {

View File

@@ -87,7 +87,7 @@ async fn check_bearer_auth(bearer_token: &str) -> SirenResult<Session> {
}
async fn check_api_key_auth(key: &str) -> SirenResult<ApiKey> {
let mut api_key = match ApiKey::find_by_key(key).await? {
let mut api_key = match ApiKey::find_by_key(key).await {
Some(api_key) => api_key,
None => return Err(StatusCode::UNAUTHORIZED.into()),
};

View File

@@ -50,6 +50,8 @@ impl InsertBuilder {
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),
}
}

View File

@@ -1,5 +1,6 @@
use std::{fmt, sync::OnceLock, time::Duration};
use std::fmt::Display;
use chrono::{DateTime, Utc};
use redis::{aio::MultiplexedConnection as RedisConnection, Client as RedisClient, RedisResult};
use sqlx::{postgres::PgPoolOptions, Pool, Postgres};
use crate::error::SirenResult;
@@ -11,6 +12,7 @@ pub mod insert;
pub mod messages;
pub mod query;
pub mod update;
mod executable_query;
static POOL: OnceLock<Pool<Postgres>> = OnceLock::new();
static REDIS: OnceLock<RedisClient> = OnceLock::new();
@@ -102,6 +104,8 @@ pub enum Value {
OptionalBool(Option<bool>),
Text(String),
OptionalText(Option<String>),
DateTime(DateTime<Utc>),
OptionalDateTime(Option<DateTime<Utc>>),
}
impl Display for Value {
@@ -125,6 +129,9 @@ impl Display for Value {
Value::Text(s) => write!(f, "'{}'", s.replace("'", "''")),
Value::OptionalText(Some(s)) => write!(f, "'{}'", s.replace("'", "''")),
Value::OptionalText(None) => write!(f, "NULL"),
Value::DateTime(n) => write!(f, "{}", n),
Value::OptionalDateTime(Some(n)) => write!(f, "{}", n),
Value::OptionalDateTime(None) => write!(f, "NULL"),
}
}
}

View File

@@ -66,6 +66,8 @@ impl QueryBuilder {
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),
}
}

View File

@@ -3,7 +3,8 @@ use crate::data::Value;
pub struct UpdateBuilder {
table: String,
columns: Vec<(String, Value)>,
columns: Vec<String>,
values: Vec<Value>,
condition: Option<Condition>,
}
@@ -12,12 +13,14 @@ impl UpdateBuilder {
Self {
table: table.to_string(),
columns: Vec::new(),
values: Vec::new(),
condition: None,
}
}
pub fn column(mut self, column: &str, value: Value) -> Self {
self.columns.push((column.to_string(), value));
self.columns.push(column.to_string());
self.values.push(value);
self
}
@@ -48,6 +51,8 @@ impl UpdateBuilder {
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),
}
}
@@ -65,18 +70,19 @@ impl UpdateBuilder {
.columns
.iter()
.enumerate()
.map(|(i, (col, _))| format!("{} = ${}", col, i + 1))
.map(|(i, col)| format!("{} = ${}", col, i + 1))
.collect::<Vec<_>>()
.join(", ");
// Prepare the WHERE clause if conditions are present
let mut query = format!("UPDATE {} SET {}", self.table, set_clause);
let mut counter = self.values.len();
let mut values: Vec<Value> = self.values;
let mut values: Vec<Value> = Vec::new();
// Build where clause
if let Some(condition) = self.condition {
let where_condition = condition.to_sql(&mut 0);
let where_condition = condition.to_sql(&mut counter);
query.push_str(&format!(" WHERE {}", where_condition.0));
values = where_condition.1;
values.extend(where_condition.1);
}
(query, values)