Changed SQLez migrations to be executed eagerly

Added fix for terminal working directory's sometimes getting lost
co-authored-by: Kay <kay@zed.dev>
This commit is contained in:
Mikayla Maki 2023-01-30 14:38:48 -08:00
parent 65641b1d3e
commit e682e2dd72
5 changed files with 130 additions and 3 deletions

View file

@ -4,12 +4,36 @@
// to creating a new db?)
// Otherwise any missing migrations are run on the connection
use anyhow::{anyhow, Result};
use std::ffi::CString;
use anyhow::{anyhow, Context, Result};
use indoc::{formatdoc, indoc};
use libsqlite3_sys::sqlite3_exec;
use crate::connection::Connection;
impl Connection {
fn eager_exec(&self, sql: &str) -> anyhow::Result<()> {
let sql_str = CString::new(sql).context("Error creating cstr")?;
unsafe {
sqlite3_exec(
self.sqlite3,
sql_str.as_c_str().as_ptr(),
None,
0 as *mut _,
0 as *mut _,
);
}
self.last_error()
.with_context(|| format!("Prepare call failed for query:\n{}", sql))?;
Ok(())
}
/// Migrate the database, for the given domain.
/// Note: Unlike everything else in SQLez, migrations are run eagerly, without first
/// preparing the SQL statements. This makes it possible to do multi-statement schema
/// updates in a single string without running into prepare errors.
pub fn migrate(&self, domain: &'static str, migrations: &[&'static str]) -> Result<()> {
self.with_savepoint("migrating", || {
// Setup the migrations table unconditionally
@ -47,7 +71,7 @@ impl Connection {
}
}
self.exec(migration)?()?;
self.eager_exec(migration)?;
store_completed_migration((domain, index, *migration))?;
}
@ -59,6 +83,7 @@ impl Connection {
#[cfg(test)]
mod test {
use indoc::indoc;
use sqlez_macros::sql;
use crate::connection::Connection;
@ -257,4 +282,46 @@ mod test {
// Verify new migration returns error when run
assert!(second_migration_result.is_err())
}
#[test]
fn test_create_alter_drop() {
let connection = Connection::open_memory(Some("test_create_alter_drop"));
connection
.migrate(
"first_migration",
&[sql!( CREATE TABLE table1(a TEXT) STRICT; )],
)
.unwrap();
connection
.exec(sql!( INSERT INTO table1(a) VALUES ("test text"); ))
.unwrap()()
.unwrap();
connection
.migrate(
"second_migration",
&[sql!(
CREATE TABLE table2(b TEXT) STRICT;
INSERT INTO table2 (b)
SELECT a FROM table1;
DROP TABLE table1;
ALTER TABLE table2 RENAME TO table1;
)],
)
.unwrap();
let res = &connection
.select::<String>(sql!(
SELECT b FROM table1
))
.unwrap()()
.unwrap()[0];
assert_eq!(res, "test text");
}
}