Skip to content

Commit 4fee3cb

Browse files
committed
Start inferring schema dynamically
1 parent 2e83a99 commit 4fee3cb

3 files changed

Lines changed: 70 additions & 0 deletions

File tree

crates/core/src/schema/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
pub mod inspection;
22
mod management;
3+
mod raw_table;
34
mod table_info;
45

56
use alloc::{rc::Rc, vec::Vec};
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
use alloc::{
2+
string::{String, ToString},
3+
vec,
4+
vec::Vec,
5+
};
6+
use powersync_sqlite_nostd::{Connection, Destructor, ResultCode};
7+
8+
use crate::error::PowerSyncError;
9+
10+
pub struct InferredTableStructure {
11+
pub table_name: String,
12+
pub has_id_column: bool,
13+
pub columns: Vec<String>,
14+
}
15+
16+
impl InferredTableStructure {
17+
pub fn read_from_database(
18+
table_name: &str,
19+
db: impl Connection,
20+
) -> Result<Option<Self>, PowerSyncError> {
21+
let stmt = db.prepare_v2("select name from pragma_table_info(?)")?;
22+
stmt.bind_text(1, table_name, Destructor::STATIC)?;
23+
24+
let mut has_id_column = false;
25+
let mut columns = vec![];
26+
27+
while let ResultCode::ROW = stmt.step()? {
28+
let name = stmt.column_text(0)?;
29+
if name == "id" {
30+
has_id_column = true;
31+
} else {
32+
columns.push(name.to_string());
33+
}
34+
}
35+
36+
if !has_id_column && columns.is_empty() {
37+
Ok(None)
38+
} else {
39+
Ok(Some(Self {
40+
table_name: table_name.to_string(),
41+
has_id_column,
42+
columns,
43+
}))
44+
}
45+
}
46+
}

crates/core/src/schema/table_info.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,32 @@ pub struct Table {
2121
pub flags: TableInfoFlags,
2222
}
2323

24+
#[derive(Deserialize)]
25+
pub struct RawTableSchema {
26+
/// The actual name of the raw table in the local schema.
27+
///
28+
/// Currently, this is only used to generate `CREATE TRIGGER` statements for the raw table.
29+
#[serde(default)]
30+
table_name: Option<String>,
31+
#[serde(
32+
default,
33+
rename = "include_old",
34+
deserialize_with = "deserialize_include_old"
35+
)]
36+
pub diff_include_old: Option<DiffIncludeOld>,
37+
#[serde(flatten)]
38+
pub flags: TableInfoFlags,
39+
}
40+
2441
#[derive(Deserialize)]
2542
pub struct RawTable {
43+
/// The [crate::sync::line::OplogEntry::object_type] for which rows should be forwarded to this
44+
/// raw table.
45+
///
46+
/// This is not necessarily the same as the local name of the raw table.
2647
pub name: String,
48+
#[serde(flatten, default)]
49+
pub schema: Option<RawTableSchema>,
2750
pub put: PendingStatement,
2851
pub delete: PendingStatement,
2952
#[serde(default)]

0 commit comments

Comments
 (0)