1use async_trait::async_trait;
12use chrono::{DateTime, Utc};
13use sbol_db_core::DomainError;
14use serde::Serialize;
15
16#[derive(Clone, Debug, Serialize)]
17pub struct DatabaseSize {
18 pub database: String,
19 pub total_bytes: i64,
20}
21
22#[derive(Clone, Debug, Serialize)]
23pub struct TableStats {
24 pub name: String,
25 pub rows_estimate: i64,
26 pub total_bytes: i64,
27 pub index_bytes: i64,
28 pub n_live_tup: i64,
29 pub n_dead_tup: i64,
30 pub last_vacuum: Option<DateTime<Utc>>,
31 pub last_autovacuum: Option<DateTime<Utc>>,
32 pub last_analyze: Option<DateTime<Utc>>,
33}
34
35#[derive(Clone, Debug, Serialize)]
36pub struct IndexStats {
37 pub table: String,
38 pub index: String,
39 pub idx_scan: i64,
40 pub bytes: i64,
41}
42
43#[derive(Clone, Debug, Serialize)]
44pub struct Activity {
45 pub pid: i32,
46 pub application_name: Option<String>,
47 pub state: Option<String>,
48 pub wait_event_type: Option<String>,
49 pub wait_event: Option<String>,
50 pub query: Option<String>,
51 pub query_start: Option<DateTime<Utc>>,
52 pub duration_secs: Option<f64>,
53 pub client_addr: Option<String>,
54}
55
56#[derive(Clone, Debug, Serialize)]
57pub struct BlockingLock {
58 pub blocker_pid: i32,
59 pub blocker_query: Option<String>,
60 pub blocked_pid: i32,
61 pub blocked_query: Option<String>,
62 pub mode: Option<String>,
63 pub locktype: Option<String>,
64}
65
66#[derive(Clone, Debug, Serialize)]
67pub struct SlowQuery {
68 pub queryid: String,
69 pub query: Option<String>,
70 pub calls: i64,
71 pub total_exec_ms: f64,
72 pub mean_exec_ms: f64,
73 pub rows: i64,
74}
75
76#[derive(Clone, Debug, Serialize)]
77pub struct TableSchema {
78 pub name: String,
79 pub comment: Option<String>,
80 pub columns: Vec<TableColumn>,
81 pub foreign_keys_out: Vec<OutgoingForeignKey>,
82 pub foreign_keys_in: Vec<IncomingForeignKey>,
83}
84
85#[derive(Clone, Debug, Serialize)]
86pub struct TableColumn {
87 pub name: String,
88 pub column_type: String,
91 pub nullable: bool,
92 pub default_expr: Option<String>,
93 pub ordinal: i32,
94 pub comment: Option<String>,
95 pub is_primary_key: bool,
96}
97
98#[derive(Clone, Debug, Serialize)]
99pub struct OutgoingForeignKey {
100 pub name: String,
101 pub columns: Vec<String>,
102 pub target_table: String,
103 pub target_columns: Vec<String>,
104}
105
106#[derive(Clone, Debug, Serialize)]
107pub struct IncomingForeignKey {
108 pub name: String,
109 pub source_table: String,
110 pub source_columns: Vec<String>,
111 pub target_columns: Vec<String>,
112}
113
114#[derive(Clone, Debug, Serialize)]
117pub struct RelationalSchema {
118 pub tables: Vec<RelationalTable>,
119}
120
121#[derive(Clone, Debug, Serialize)]
122pub struct RelationalTable {
123 pub name: String,
124 pub columns: Vec<RelationalColumn>,
125}
126
127#[derive(Clone, Debug, Serialize)]
128pub struct RelationalColumn {
129 pub name: String,
130 pub column_type: String,
132 pub nullable: bool,
133}
134
135#[async_trait]
145pub trait DbStats: Send + Sync {
146 async fn schema_overview(&self) -> Result<RelationalSchema, DomainError>;
148 async fn database_size(&self) -> Result<DatabaseSize, DomainError>;
149 async fn table_stats(&self, limit: i64, offset: i64) -> Result<Vec<TableStats>, DomainError>;
150 async fn index_stats(&self, limit: i64) -> Result<Vec<IndexStats>, DomainError>;
151 async fn activity(&self, limit: i64) -> Result<Vec<Activity>, DomainError>;
152 async fn blocking_locks(&self) -> Result<Vec<BlockingLock>, DomainError>;
153 async fn table_schema(&self, name: &str) -> Result<Option<TableSchema>, DomainError>;
154 async fn has_slow_query_stats(&self) -> Result<bool, DomainError>;
157 async fn slow_queries(&self, limit: i64) -> Result<Vec<SlowQuery>, DomainError>;
158
159 async fn optimize(&self) -> Result<(), DomainError> {
164 Ok(())
165 }
166}