Skip to main content

systemprompt_database/models/
query.rs

1use anyhow::Result;
2use serde::{Deserialize, Serialize};
3use serde_json::Value;
4use sqlx::postgres::PgRow;
5use std::collections::HashMap;
6
7#[derive(Debug, Clone, Copy)]
8pub struct DatabaseQuery {
9    postgres: &'static str,
10}
11
12impl DatabaseQuery {
13    #[must_use]
14    pub const fn new(query: &'static str) -> Self {
15        Self { postgres: query }
16    }
17
18    #[must_use]
19    pub const fn postgres(&self) -> &str {
20        self.postgres
21    }
22}
23
24pub trait QuerySelector: Sync {
25    fn select_query(&self) -> &str;
26}
27
28impl QuerySelector for &str {
29    fn select_query(&self) -> &str {
30        self
31    }
32}
33
34impl QuerySelector for String {
35    fn select_query(&self) -> &str {
36        self.as_str()
37    }
38}
39
40impl QuerySelector for DatabaseQuery {
41    fn select_query(&self) -> &str {
42        self.postgres()
43    }
44}
45
46pub trait FromDatabaseRow: Sized {
47    fn from_postgres_row(row: &PgRow) -> Result<Self>;
48}
49
50#[derive(Debug, Clone, Serialize, Deserialize)]
51pub struct QueryResult {
52    pub columns: Vec<String>,
53    pub rows: Vec<QueryRow>,
54    pub row_count: usize,
55    pub execution_time_ms: u64,
56}
57
58pub type QueryRow = HashMap<String, Value>;
59
60impl QueryResult {
61    #[must_use]
62    pub const fn new() -> Self {
63        Self {
64            columns: vec![],
65            rows: vec![],
66            row_count: 0,
67            execution_time_ms: 0,
68        }
69    }
70
71    #[must_use]
72    pub fn is_empty(&self) -> bool {
73        self.rows.is_empty()
74    }
75
76    #[must_use]
77    pub fn first(&self) -> Option<&QueryRow> {
78        self.rows.first()
79    }
80}
81
82impl Default for QueryResult {
83    fn default() -> Self {
84        Self::new()
85    }
86}