systemprompt_database/models/
query.rs1use 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>;
60
61impl QueryResult {
62 #[must_use]
63 pub const fn new() -> Self {
64 Self {
65 columns: vec![],
66 rows: vec![],
67 row_count: 0,
68 execution_time_ms: 0,
69 }
70 }
71
72 #[must_use]
73 pub fn is_empty(&self) -> bool {
74 self.rows.is_empty()
75 }
76
77 #[must_use]
78 pub fn first(&self) -> Option<&QueryRow> {
79 self.rows.first()
80 }
81}
82
83impl Default for QueryResult {
84 fn default() -> Self {
85 Self::new()
86 }
87}