Skip to content

Commit 9d54a31

Browse files
committed
Unit tests for generated statements
1 parent 7ab16f2 commit 9d54a31

File tree

1 file changed

+51
-7
lines changed

1 file changed

+51
-7
lines changed

crates/core/src/schema/raw_table.rs

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,27 +66,35 @@ impl InferredTableStructure {
6666
}
6767
}
6868

69-
/// Generates a statement of the form `INSERT OR REPLACE INTO $tbl ($cols) VALUES (?, ...)` for
70-
/// the sync client.
69+
/// Generates a statement of the form `INSERT INTO $tbl ($cols) VALUES (?, ...) ON CONFLICT (id)
70+
/// DO UPDATE SET ...` for the sync client.
7171
pub fn infer_put_stmt(&self) -> PendingStatement {
7272
let mut buffer = SqlBuffer::new();
7373
let mut params = vec![];
7474

75-
buffer.push_str("INSERT OR REPLACE INTO ");
75+
buffer.push_str("INSERT INTO ");
7676
let _ = buffer.identifier().write_str(&self.name);
7777
buffer.push_str(" (id");
7878
for column in &self.columns {
7979
buffer.comma();
8080
let _ = buffer.identifier().write_str(column);
8181
}
82-
buffer.push_str(") VALUES (?");
82+
buffer.push_str(") VALUES (?1");
8383
params.push(PendingStatementValue::Id);
84-
for column in &self.columns {
84+
for (i, column) in self.columns.iter().enumerate() {
8585
buffer.comma();
86-
buffer.push_str("?");
86+
let _ = write!(&mut buffer, "?{}", i + 2);
8787
params.push(PendingStatementValue::Column(column.clone()));
8888
}
89-
buffer.push_str(")");
89+
buffer.push_str(") ON CONFLICT (id) DO UPDATE SET ");
90+
let mut do_update = buffer.comma_separated();
91+
// Generated an "x" = ? for all synced columns to update them without affecting local-only
92+
// columns.
93+
for (i, column) in self.columns.iter().enumerate() {
94+
let entry = do_update.element();
95+
let _ = entry.identifier().write_str(column);
96+
let _ = write!(entry, " = ?{}", i + 2);
97+
}
9098

9199
PendingStatement {
92100
sql: buffer.sql,
@@ -312,3 +320,39 @@ pub fn generate_raw_table_trigger(
312320
buffer.trigger_end();
313321
Ok(buffer.sql)
314322
}
323+
324+
#[cfg(test)]
325+
mod test {
326+
use alloc::{string::ToString, vec};
327+
328+
use crate::schema::{PendingStatementValue, raw_table::InferredTableStructure};
329+
330+
#[test]
331+
fn infer_sync_statements() {
332+
let structure = InferredTableStructure {
333+
name: "tbl".to_string(),
334+
columns: vec!["foo".to_string(), "bar".to_string()],
335+
};
336+
337+
let put = structure.infer_put_stmt();
338+
assert_eq!(
339+
put.sql,
340+
r#"INSERT INTO "tbl" (id, "foo", "bar") VALUES (?1, ?2, ?3) ON CONFLICT (id) DO UPDATE SET "foo" = ?2, "bar" = ?3"#
341+
);
342+
assert_eq!(put.params.len(), 3);
343+
assert!(matches!(put.params[0], PendingStatementValue::Id));
344+
assert!(matches!(
345+
put.params[1],
346+
PendingStatementValue::Column(ref name) if name == "foo"
347+
));
348+
assert!(matches!(
349+
put.params[2],
350+
PendingStatementValue::Column(ref name) if name == "bar"
351+
));
352+
353+
let delete = structure.infer_delete_stmt();
354+
assert_eq!(delete.sql, r#"DELETE FROM "tbl" WHERE id = ?"#);
355+
assert_eq!(delete.params.len(), 1);
356+
assert!(matches!(delete.params[0], PendingStatementValue::Id));
357+
}
358+
}

0 commit comments

Comments
 (0)