#![cfg(feature = "std")]
use graphitesql::{Connection, Value};
fn texts(c: &Connection, sql: &str) -> Vec<String> {
c.query(sql)
.unwrap()
.rows
.iter()
.map(|r| match &r[0] {
Value::Text(s) => s.to_string(),
Value::Integer(i) => i.to_string(),
other => panic!("unexpected {other:?}"),
})
.collect()
}
#[test]
fn before_insert_fires_before_replace_deletes_conflict() {
let mut c = Connection::open_memory().unwrap();
c.execute("CREATE TABLE t(id INTEGER PRIMARY KEY, v)")
.unwrap();
c.execute("CREATE TABLE log(msg)").unwrap();
c.execute(
"CREATE TRIGGER bi BEFORE INSERT ON t BEGIN \
INSERT INTO log VALUES('before:'||(SELECT count(*) FROM t)); END",
)
.unwrap();
c.execute("INSERT INTO t VALUES(1,'a')").unwrap();
c.execute("INSERT OR REPLACE INTO t VALUES(1,'b')").unwrap();
assert_eq!(
texts(&c, "SELECT msg FROM log"),
vec!["before:0", "before:1"]
);
assert_eq!(texts(&c, "SELECT v FROM t"), vec!["b"]);
}
#[test]
fn before_insert_side_effects_persist_when_or_ignore_skips_not_null() {
let mut c = Connection::open_memory().unwrap();
c.execute("CREATE TABLE t(id INTEGER PRIMARY KEY, v NOT NULL)")
.unwrap();
c.execute("CREATE TABLE log(msg)").unwrap();
c.execute("CREATE TRIGGER bi BEFORE INSERT ON t BEGIN INSERT INTO log VALUES('fired'); END")
.unwrap();
c.execute("INSERT OR IGNORE INTO t VALUES(1,NULL)").unwrap();
assert_eq!(c.query("SELECT * FROM t").unwrap().rows.len(), 0);
assert_eq!(texts(&c, "SELECT msg FROM log"), vec!["fired"]);
}
#[test]
fn before_insert_fires_before_or_ignore_skips_unique() {
let mut c = Connection::open_memory().unwrap();
c.execute("CREATE TABLE t(id INTEGER PRIMARY KEY, v UNIQUE)")
.unwrap();
c.execute("CREATE TABLE log(msg)").unwrap();
c.execute(
"CREATE TRIGGER bi BEFORE INSERT ON t BEGIN \
INSERT INTO log VALUES('f'||(SELECT count(*) FROM t)); END",
)
.unwrap();
c.execute("INSERT INTO t VALUES(1,5)").unwrap();
c.execute("INSERT OR IGNORE INTO t VALUES(2,5)").unwrap();
assert_eq!(texts(&c, "SELECT msg FROM log"), vec!["f0", "f1"]);
assert_eq!(texts(&c, "SELECT count(*) FROM t"), vec!["1"]);
}