1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
use async_trait::async_trait;
use tokio::sync::mpsc;
use crate::core::error::DbResult;
use crate::core::models::*;
/// A batch of rows streamed from a query.
pub struct QueryBatch {
pub columns: Vec<String>,
pub rows: Vec<Vec<String>>,
pub done: bool,
}
#[allow(dead_code)]
#[async_trait]
pub trait DatabaseAdapter: Send + Sync {
/// Database engine name (e.g., "Oracle", "PostgreSQL", "MySQL")
fn name(&self) -> &str;
/// Database type enum variant
fn db_type(&self) -> DatabaseType;
/// Fetch all schemas (or databases for MySQL)
async fn get_schemas(&self) -> DbResult<Vec<Schema>>;
/// Fetch tables in a schema
async fn get_tables(&self, schema: &str) -> DbResult<Vec<Table>>;
/// Fetch views in a schema
async fn get_views(&self, schema: &str) -> DbResult<Vec<View>>;
/// Fetch procedures in a schema
async fn get_procedures(&self, schema: &str) -> DbResult<Vec<Procedure>>;
/// Fetch functions in a schema
async fn get_functions(&self, schema: &str) -> DbResult<Vec<Function>>;
/// Fetch column metadata for a table
async fn get_columns(&self, schema: &str, table: &str) -> DbResult<Vec<Column>>;
/// Execute an arbitrary SQL query
async fn execute(&self, query: &str) -> DbResult<QueryResult>;
/// Execute a query and stream results in batches via the provided sender.
/// Default implementation falls back to `execute()` and sends a single batch.
async fn execute_streaming(
&self,
query: &str,
tx: mpsc::Sender<DbResult<QueryBatch>>,
) -> DbResult<()> {
let result = self.execute(query).await?;
let _ = tx
.send(Ok(QueryBatch {
columns: result.columns,
rows: result.rows,
done: true,
}))
.await;
Ok(())
}
/// Fetch packages in a schema. Returns empty vec if not supported.
async fn get_packages(&self, _schema: &str) -> DbResult<Vec<Package>> {
Ok(vec![])
}
/// Fetch package declaration and body. Returns None if not supported.
async fn get_package_content(
&self,
_schema: &str,
_name: &str,
) -> DbResult<Option<PackageContent>> {
Ok(None)
}
/// Fetch materialized views in a schema. Returns empty vec if not supported.
async fn get_materialized_views(&self, _schema: &str) -> DbResult<Vec<MaterializedView>> {
Ok(vec![])
}
/// Fetch indexes in a schema. Returns empty vec if not supported.
async fn get_indexes(&self, _schema: &str) -> DbResult<Vec<Index>> {
Ok(vec![])
}
/// Fetch sequences in a schema. Returns empty vec if not supported.
async fn get_sequences(&self, _schema: &str) -> DbResult<Vec<Sequence>> {
Ok(vec![])
}
/// Fetch types in a schema. Returns empty vec if not supported.
async fn get_types(&self, _schema: &str) -> DbResult<Vec<DbType>> {
Ok(vec![])
}
/// Fetch triggers in a schema. Returns empty vec if not supported.
async fn get_triggers(&self, _schema: &str) -> DbResult<Vec<Trigger>> {
Ok(vec![])
}
/// Fetch events in a schema (MySQL). Returns empty vec if not supported.
async fn get_events(&self, _schema: &str) -> DbResult<Vec<DbEvent>> {
Ok(vec![])
}
/// Fetch type attributes. Returns (columns, rows) as a QueryResult.
async fn get_type_attributes(&self, _schema: &str, _name: &str) -> DbResult<QueryResult> {
Ok(QueryResult {
columns: vec![],
rows: vec![],
elapsed: None,
})
}
/// Fetch type methods. Returns (columns, rows) as a QueryResult.
async fn get_type_methods(&self, _schema: &str, _name: &str) -> DbResult<QueryResult> {
Ok(QueryResult {
columns: vec![],
rows: vec![],
elapsed: None,
})
}
/// Fetch trigger column info. Returns (columns, rows) as a QueryResult.
async fn get_trigger_info(&self, _schema: &str, _name: &str) -> DbResult<QueryResult> {
Ok(QueryResult {
columns: vec![],
rows: vec![],
elapsed: None,
})
}
/// Fetch DDL for a table. Returns empty string if not supported.
async fn get_table_ddl(&self, _schema: &str, _table: &str) -> DbResult<String> {
Ok(String::new())
}
/// Fetch source code for a stored object. Returns empty string if not supported.
async fn get_source_code(
&self,
_schema: &str,
_name: &str,
_obj_type: &str,
) -> DbResult<String> {
Ok(String::new())
}
/// Fetch foreign key constraints for a table. Returns empty vec if not supported.
async fn get_foreign_keys(&self, _schema: &str, _table: &str) -> DbResult<Vec<ForeignKeyInfo>> {
Ok(vec![])
}
/// Compile/validate SQL on the server without executing it.
/// Returns diagnostics from the server (e.g., Oracle USER_ERRORS, PG PREPARE errors).
async fn compile_check(&self, _sql: &str) -> DbResult<Vec<CompileDiagnostic>> {
Ok(vec![])
}
/// Resolve the pseudo-columns a PL/SQL function returns when used inside
/// `TABLE(...)` in a FROM clause — i.e. the attributes of the `TABLE OF
/// <object_type>` the function returns. `schema` and `package` are
/// optional for top-level functions. Returns an empty vec if the driver
/// does not support table functions (Postgres/MySQL).
async fn get_function_return_columns(
&self,
_schema: Option<&str>,
_package: Option<&str>,
_function: &str,
) -> DbResult<Vec<Column>> {
Ok(vec![])
}
}