diff --git a/src/sqlite/def/column.rs b/src/sqlite/def/column.rs index b6caaf2..57f8e66 100644 --- a/src/sqlite/def/column.rs +++ b/src/sqlite/def/column.rs @@ -1,5 +1,5 @@ use super::DefaultType; -use crate::sqlx_types::SqlxRow; +use crate::{sqlite::def::ColumnVisibility, sqlx_types::SqlxRow}; use sea_query::{ Alias, ColumnType, Index, IndexCreateStatement, foreign_key::ForeignKeyAction as SeaQueryForeignKeyAction, @@ -9,12 +9,19 @@ use std::num::ParseIntError; /// An SQLite column definition #[derive(Debug, PartialEq, Clone)] pub struct ColumnInfo { + /// Column id pub cid: i64, + /// Column name. pub name: String, + /// Declared type pub r#type: ColumnType, + /// Whether a NOT NULL constraint is present. pub not_null: bool, pub default_value: DefaultType, + /// Column is part of the PRIMARY KEY. pub primary_key: bool, + /// Hidden status + pub hidden: ColumnVisibility, } #[cfg(feature = "sqlx-sqlite")] @@ -27,6 +34,7 @@ impl ColumnInfo { let is_pk: i8 = row.get(5); let default_value: Option = row.get(4); let default_value = default_value.unwrap_or_default(); + let hidden: i8 = row.get(6); Ok(ColumnInfo { cid: row.get(0), name: row.get(1), @@ -50,8 +58,14 @@ impl ColumnInfo { } }, primary_key: is_pk != 0, + hidden: ColumnVisibility::from_hidden(hidden), }) } + + #[inline] + pub fn is_hidden(&self) -> bool { + self.hidden == ColumnVisibility::HiddenVirtual + } } #[cfg(not(feature = "sqlx-sqlite"))] @@ -59,6 +73,11 @@ impl ColumnInfo { pub fn to_column_def(_: SqlxRow) -> Result { unimplemented!() } + + #[inline] + pub fn is_hidden(&self) -> bool { + unimplemented!() + } } /// Maps the index and all columns in the index which is the result of queries diff --git a/src/sqlite/def/table.rs b/src/sqlite/def/table.rs index af3bf00..dfd4db1 100644 --- a/src/sqlite/def/table.rs +++ b/src/sqlite/def/table.rs @@ -177,17 +177,19 @@ impl TableDef { Ok(self) } - /// Get a list of all the columns in the table mapped as [ColumnInfo] pub async fn get_column_info(&mut self, conn: &impl Connection) -> DiscoveryResult<&TableDef> { - let mut index_query = String::default(); - index_query.push_str("PRAGMA table_info('"); - index_query.push_str(&self.name); - index_query.push_str("')"); + let mut query = String::with_capacity(64 + self.name.len()); + query.push_str("PRAGMA table_xinfo('"); + query.push_str(&self.name); + query.push_str("')"); - let index_info_rows = conn.query_all_raw(index_query).await?; + let rows = conn.query_all_raw(query).await?; - for info in index_info_rows { - let column = ColumnInfo::to_column_def(info)?; + for row in rows { + let column = ColumnInfo::to_column_def(row)?; + if column.is_hidden() { + continue; // Skip hidden columns + } self.columns.push(column); } diff --git a/src/sqlite/def/types.rs b/src/sqlite/def/types.rs index b902181..e3729ad 100644 --- a/src/sqlite/def/types.rs +++ b/src/sqlite/def/types.rs @@ -89,6 +89,30 @@ pub fn parse_type(data_type: String) -> Result { }) } +/// The `hidden` field returned by `PRAGMA table_xinfo`. +#[derive(Debug, PartialEq, Clone)] +pub enum ColumnVisibility { + /// `0` - ordinary column + Visible, + /// `1` - hidden column in a virtual table + HiddenVirtual, + /// `2` - generated VIRTUAL column + GeneratedVirtual, + /// `3` - generated STORED column + GeneratedStored, +} + +impl ColumnVisibility { + pub fn from_hidden(value: i8) -> Self { + match value { + 1 => Self::HiddenVirtual, + 2 => Self::GeneratedVirtual, + 3 => Self::GeneratedStored, + _ => Self::Visible, + } + } +} + /// The default types for an SQLite `dflt_value` #[derive(Debug, PartialEq, Clone)] pub enum DefaultType { diff --git a/tests/discovery/sqlite/src/main.rs b/tests/discovery/sqlite/src/main.rs index dfa566f..cd27a44 100644 --- a/tests/discovery/sqlite/src/main.rs +++ b/tests/discovery/sqlite/src/main.rs @@ -28,6 +28,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: true, + hidden: Visible, }, ColumnInfo { cid: 1, @@ -40,6 +41,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 2, @@ -52,6 +54,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 3, @@ -60,6 +63,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: CurrentTimestamp, primary_key: false, + hidden: Visible, }, ], auto_increment: true, @@ -77,6 +81,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: true, + hidden: Visible, }, ColumnInfo { cid: 1, @@ -89,6 +94,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 2, @@ -97,6 +103,7 @@ async fn main() -> DiscoveryResult<()> { not_null: false, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ], auto_increment: false, @@ -129,6 +136,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: true, + hidden: Visible, }, ColumnInfo { cid: 1, @@ -141,6 +149,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 2, @@ -149,6 +158,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 3, @@ -157,6 +167,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ], auto_increment: false, @@ -189,6 +200,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: true, + hidden: Visible, }, ColumnInfo { cid: 1, @@ -201,6 +213,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 2, @@ -213,6 +226,7 @@ async fn main() -> DiscoveryResult<()> { not_null: false, default_value: Null, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 3, @@ -225,6 +239,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 4, @@ -233,6 +248,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 5, @@ -245,6 +261,7 @@ async fn main() -> DiscoveryResult<()> { not_null: false, default_value: Null, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 6, @@ -257,6 +274,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 7, @@ -265,6 +283,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ], auto_increment: false, @@ -282,6 +301,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: true, + hidden: Visible, }, ColumnInfo { cid: 1, @@ -294,6 +314,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 2, @@ -302,6 +323,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ], auto_increment: false, @@ -319,6 +341,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: true, + hidden: Visible, }, ColumnInfo { cid: 1, @@ -331,6 +354,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 2, @@ -339,6 +363,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ], auto_increment: false, @@ -385,6 +410,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: true, + hidden: Visible, }, ColumnInfo { cid: 1, @@ -393,6 +419,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 2, @@ -405,6 +432,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 3, @@ -417,6 +445,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 4, @@ -429,6 +458,7 @@ async fn main() -> DiscoveryResult<()> { not_null: false, default_value: Null, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 5, @@ -437,6 +467,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 6, @@ -451,6 +482,7 @@ async fn main() -> DiscoveryResult<()> { "Y", ), primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 7, @@ -459,6 +491,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 8, @@ -467,6 +500,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ], auto_increment: false, @@ -513,6 +547,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: true, + hidden: Visible, }, ColumnInfo { cid: 1, @@ -525,6 +560,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 2, @@ -533,6 +569,7 @@ async fn main() -> DiscoveryResult<()> { not_null: false, default_value: Null, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 3, @@ -545,6 +582,7 @@ async fn main() -> DiscoveryResult<()> { not_null: false, default_value: Null, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 4, @@ -553,6 +591,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 5, @@ -561,6 +600,7 @@ async fn main() -> DiscoveryResult<()> { not_null: false, default_value: Null, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 6, @@ -571,6 +611,7 @@ async fn main() -> DiscoveryResult<()> { 3, ), primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 7, @@ -588,6 +629,7 @@ async fn main() -> DiscoveryResult<()> { 4.99, ), primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 8, @@ -596,6 +638,7 @@ async fn main() -> DiscoveryResult<()> { not_null: false, default_value: Null, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 9, @@ -613,6 +656,7 @@ async fn main() -> DiscoveryResult<()> { 19.99, ), primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 10, @@ -627,6 +671,7 @@ async fn main() -> DiscoveryResult<()> { "G", ), primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 11, @@ -639,6 +684,7 @@ async fn main() -> DiscoveryResult<()> { not_null: false, default_value: Null, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 12, @@ -647,6 +693,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ], auto_increment: false, @@ -693,6 +740,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: true, + hidden: Visible, }, ColumnInfo { cid: 1, @@ -701,6 +749,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: true, + hidden: Visible, }, ColumnInfo { cid: 2, @@ -709,6 +758,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ], auto_increment: false, @@ -755,6 +805,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: true, + hidden: Visible, }, ColumnInfo { cid: 1, @@ -763,6 +814,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: true, + hidden: Visible, }, ColumnInfo { cid: 2, @@ -771,6 +823,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ], auto_increment: false, @@ -788,6 +841,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: true, + hidden: Visible, }, ColumnInfo { cid: 1, @@ -800,6 +854,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 2, @@ -808,6 +863,7 @@ async fn main() -> DiscoveryResult<()> { not_null: false, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ], auto_increment: false, @@ -854,6 +910,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: true, + hidden: Visible, }, ColumnInfo { cid: 1, @@ -862,6 +919,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 2, @@ -870,6 +928,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 3, @@ -878,6 +937,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ], auto_increment: false, @@ -924,6 +984,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: true, + hidden: Visible, }, ColumnInfo { cid: 1, @@ -936,6 +997,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 2, @@ -948,6 +1010,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 3, @@ -956,6 +1019,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 4, @@ -964,6 +1028,7 @@ async fn main() -> DiscoveryResult<()> { not_null: false, default_value: Null, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 5, @@ -976,6 +1041,7 @@ async fn main() -> DiscoveryResult<()> { not_null: false, default_value: Null, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 6, @@ -984,6 +1050,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 7, @@ -994,6 +1061,7 @@ async fn main() -> DiscoveryResult<()> { 1, ), primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 8, @@ -1006,6 +1074,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 9, @@ -1018,6 +1087,7 @@ async fn main() -> DiscoveryResult<()> { not_null: false, default_value: Null, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 10, @@ -1026,6 +1096,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ], auto_increment: false, @@ -1072,6 +1143,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: true, + hidden: Visible, }, ColumnInfo { cid: 1, @@ -1080,6 +1152,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 2, @@ -1088,6 +1161,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 3, @@ -1096,6 +1170,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ], auto_increment: false, @@ -1156,6 +1231,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: true, + hidden: Visible, }, ColumnInfo { cid: 1, @@ -1164,6 +1240,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 2, @@ -1172,6 +1249,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 3, @@ -1180,6 +1258,7 @@ async fn main() -> DiscoveryResult<()> { not_null: false, default_value: Null, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 4, @@ -1195,6 +1274,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 5, @@ -1203,6 +1283,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 6, @@ -1211,6 +1292,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ], auto_increment: false, @@ -1271,6 +1353,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: true, + hidden: Visible, }, ColumnInfo { cid: 1, @@ -1279,6 +1362,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 2, @@ -1287,6 +1371,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 3, @@ -1295,6 +1380,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 4, @@ -1303,6 +1389,7 @@ async fn main() -> DiscoveryResult<()> { not_null: false, default_value: Null, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 5, @@ -1311,6 +1398,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ColumnInfo { cid: 6, @@ -1319,6 +1407,7 @@ async fn main() -> DiscoveryResult<()> { not_null: true, default_value: Unspecified, primary_key: false, + hidden: Visible, }, ], auto_increment: false,