Load a single table schema directly from database (bypassing cache)
(&self, conn: &Connection, table_name: &str)
| 162 | |
| 163 | /// Load a single table schema directly from database (bypassing cache) |
| 164 | fn load_table_schema_direct(&self, conn: &Connection, table_name: &str) -> Result<TableSchema, rusqlite::Error> { |
| 165 | let mut column_data = Vec::new(); |
| 166 | |
| 167 | // First get all columns from SQLite schema |
| 168 | let pragma_query = format!("PRAGMA table_info({table_name})"); |
| 169 | let mut stmt = conn.prepare(&pragma_query)?; |
| 170 | let rows = stmt.query_map([], |row| { |
| 171 | let name: String = row.get(1)?; |
| 172 | let sqlite_type: String = row.get(2)?; |
| 173 | Ok((name, sqlite_type)) |
| 174 | })?; |
| 175 | |
| 176 | let mut sqlite_columns = Vec::new(); |
| 177 | for row in rows { |
| 178 | sqlite_columns.push(row?); |
| 179 | } |
| 180 | |
| 181 | // Bulk query for all PostgreSQL types for this table |
| 182 | let mut pg_metadata = HashMap::new(); |
| 183 | if let Ok(mut stmt) = conn.prepare("SELECT column_name, pg_type FROM __pgsqlite_schema WHERE table_name = ?1") |
| 184 | && let Ok(rows) = stmt.query_map([table_name], |row| { |
| 185 | let col_name: String = row.get(0)?; |
| 186 | let pg_type: String = row.get(1)?; |
| 187 | Ok((col_name, pg_type)) |
| 188 | }) { |
| 189 | for row in rows.flatten() { |
| 190 | pg_metadata.insert(row.0, row.1); |
| 191 | } |
| 192 | } |
| 193 | |
| 194 | // Build column data |
| 195 | for (col_name, sqlite_type) in sqlite_columns { |
| 196 | let (pg_type, pg_oid) = if let Some(pg_type_str) = pg_metadata.get(&col_name) { |
| 197 | let oid = crate::types::SchemaTypeMapper::pg_type_string_to_oid(pg_type_str); |
| 198 | (pg_type_str.clone(), oid) |
| 199 | } else { |
| 200 | // Fallback to type mapping |
| 201 | let type_mapper = crate::types::TypeMapper::new(); |
| 202 | let pg_type = type_mapper.sqlite_to_pg(&sqlite_type); |
| 203 | let oid = pg_type.to_oid(); |
| 204 | let pg_type_str = match pg_type { |
| 205 | crate::types::PgType::Text => "text", |
| 206 | crate::types::PgType::Int8 => "int8", |
| 207 | crate::types::PgType::Int4 => "int4", |
| 208 | crate::types::PgType::Int2 => "int2", |
| 209 | crate::types::PgType::Float8 => "float8", |
| 210 | crate::types::PgType::Float4 => "float4", |
| 211 | crate::types::PgType::Bool => "boolean", |
| 212 | crate::types::PgType::Bytea => "bytea", |
| 213 | crate::types::PgType::Date => "date", |
| 214 | crate::types::PgType::Timestamp => "timestamp", |
| 215 | crate::types::PgType::Timestamptz => "timestamptz", |
| 216 | crate::types::PgType::Uuid => "uuid", |
| 217 | crate::types::PgType::Numeric => "numeric", |
| 218 | crate::types::PgType::Json => "json", |
| 219 | crate::types::PgType::Jsonb => "jsonb", |
| 220 | crate::types::PgType::Money => "money", |
| 221 | crate::types::PgType::Int4range => "int4range", |