sqlx_gen/introspect/
sqlite.rs1use crate::error::Result;
2use sqlx::SqlitePool;
3
4use super::{ColumnInfo, SchemaInfo, TableInfo};
5
6pub async fn introspect(pool: &SqlitePool, include_views: bool) -> Result<SchemaInfo> {
7 let tables = fetch_tables(pool).await?;
8 let views = if include_views {
9 fetch_views(pool).await?
10 } else {
11 Vec::new()
12 };
13
14 Ok(SchemaInfo {
15 tables,
16 views,
17 enums: Vec::new(),
18 composite_types: Vec::new(),
19 domains: Vec::new(),
20 })
21}
22
23async fn fetch_tables(pool: &SqlitePool) -> Result<Vec<TableInfo>> {
24 let table_names: Vec<(String,)> = sqlx::query_as(
25 "SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%' ORDER BY name",
26 )
27 .fetch_all(pool)
28 .await?;
29
30 let mut tables = Vec::new();
31
32 for (table_name,) in table_names {
33 let columns = fetch_columns(pool, &table_name).await?;
34 tables.push(TableInfo {
35 schema_name: "main".to_string(),
36 name: table_name,
37 columns,
38 });
39 }
40
41 Ok(tables)
42}
43
44async fn fetch_views(pool: &SqlitePool) -> Result<Vec<TableInfo>> {
45 let view_names: Vec<(String,)> = sqlx::query_as(
46 "SELECT name FROM sqlite_master WHERE type = 'view' ORDER BY name",
47 )
48 .fetch_all(pool)
49 .await?;
50
51 let mut views = Vec::new();
52
53 for (view_name,) in view_names {
54 let columns = fetch_columns(pool, &view_name).await?;
55 views.push(TableInfo {
56 schema_name: "main".to_string(),
57 name: view_name,
58 columns,
59 });
60 }
61
62 Ok(views)
63}
64
65async fn fetch_columns(pool: &SqlitePool, table_name: &str) -> Result<Vec<ColumnInfo>> {
66 let pragma_query = format!("PRAGMA table_info(\"{}\")", table_name.replace('"', "\"\""));
68 let rows: Vec<(i32, String, String, bool, Option<String>, i32)> =
69 sqlx::query_as(&pragma_query).fetch_all(pool).await?;
70
71 Ok(rows
72 .into_iter()
73 .map(|(cid, name, declared_type, notnull, dflt_value, pk)| {
74 let upper = declared_type.to_uppercase();
75 ColumnInfo {
76 name,
77 data_type: upper.clone(),
78 udt_name: upper,
79 is_nullable: !notnull,
80 is_primary_key: pk > 0,
81 ordinal_position: cid,
82 schema_name: "main".to_string(),
83 column_default: dflt_value,
84 }
85 })
86 .collect())
87}