add: app_data table

This commit is contained in:
trisua 2025-07-17 01:30:27 -04:00
parent f802a1c8ab
commit 5c520f4308
6 changed files with 249 additions and 0 deletions

View file

@ -1,3 +1,5 @@
use std::fmt::Display;
use serde::{Deserialize, Serialize};
use tetratto_shared::{snow::Snowflake, unix_epoch_timestamp};
use crate::model::oauth::AppScope;
@ -100,3 +102,77 @@ impl ThirdPartyApp {
}
}
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct AppData {
pub id: usize,
pub owner: usize,
pub app: usize,
pub key: String,
pub value: String,
}
impl AppData {
/// Create a new [`AppData`].
pub fn new(owner: usize, app: usize, key: String, value: String) -> Self {
Self {
id: Snowflake::new().to_string().parse::<usize>().unwrap(),
owner,
app,
key,
value,
}
}
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum AppDataSelectQuery {
Like(String, String),
}
impl Display for AppDataSelectQuery {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(&match self {
Self::Like(k, v) => format!("%\"{k}\":\"{v}\"%"),
})
}
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum AppDataSelectMode {
/// Select a single row.
One,
/// Select multiple rows at once.
///
/// `(order by top level key, limit, offset)`
Many(String, usize, usize),
}
impl Display for AppDataSelectMode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(&match self {
Self::One => "LIMIT 1".to_string(),
Self::Many(order_by_top_level_key, limit, offset) => {
format!(
"ORDER BY v::jsonb->>'{order_by_top_level_key}' LIMIT {limit} OFFSET {offset}"
)
}
})
}
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct AppDataQuery {
pub app: usize,
pub query: AppDataSelectQuery,
pub mode: AppDataSelectMode,
}
impl Display for AppDataQuery {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(&format!(
"SELECT * FROM app_data WHERE app = {} AND v LIKE $1 {}",
self.app, self.mode
))
}
}