#![cfg(all(feature = "git", feature = "sql"))]
mod common;
use gluesql_core::prelude::Glue;
use prollytree::sql::ProllyStorage;
fn setup_glue() -> (tempfile::TempDir, Glue<ProllyStorage<32>>) {
let (temp, dataset) = common::setup_repo_and_dataset();
let storage = ProllyStorage::<32>::init(&dataset).expect("ProllyStorage init");
let glue = Glue::new(storage);
(temp, glue)
}
async fn exec(glue: &mut Glue<ProllyStorage<32>>, sql: &str) {
glue.execute(sql).await.unwrap_or_else(|e| {
panic!("SQL failed: {sql}\nError: {e}");
});
}
#[tokio::test]
async fn test_sql_create_insert_select() {
#[allow(unused_mut)]
let (_temp, mut glue) = setup_glue();
exec(&mut glue, "CREATE TABLE users (id INTEGER, name TEXT)").await;
exec(&mut glue, "INSERT INTO users VALUES (1, 'Alice')").await;
exec(&mut glue, "INSERT INTO users VALUES (2, 'Bob')").await;
let results = glue.execute("SELECT * FROM users").await.unwrap();
assert!(!results.is_empty(), "SELECT should return payload");
}
#[tokio::test]
async fn test_sql_update_and_delete() {
#[allow(unused_mut)]
let (_temp, mut glue) = setup_glue();
exec(&mut glue, "CREATE TABLE items (id INTEGER, name TEXT)").await;
exec(&mut glue, "INSERT INTO items VALUES (1, 'Old')").await;
exec(&mut glue, "UPDATE items SET name = 'New' WHERE id = 1").await;
let results = glue
.execute("SELECT name FROM items WHERE id = 1")
.await
.unwrap();
assert!(!results.is_empty());
exec(&mut glue, "DELETE FROM items WHERE id = 1").await;
let results = glue.execute("SELECT * FROM items").await.unwrap();
assert!(!results.is_empty());
}
#[tokio::test]
async fn test_sql_multiple_tables() {
#[allow(unused_mut)]
let (_temp, mut glue) = setup_glue();
exec(&mut glue, "CREATE TABLE t1 (id INTEGER, val TEXT)").await;
exec(&mut glue, "CREATE TABLE t2 (id INTEGER, val TEXT)").await;
exec(&mut glue, "INSERT INTO t1 VALUES (1, 'a')").await;
exec(&mut glue, "INSERT INTO t2 VALUES (2, 'b')").await;
let r1 = glue.execute("SELECT * FROM t1").await.unwrap();
let r2 = glue.execute("SELECT * FROM t2").await.unwrap();
assert!(!r1.is_empty());
assert!(!r2.is_empty());
}
#[tokio::test]
async fn test_sql_drop_table() {
#[allow(unused_mut)]
let (_temp, mut glue) = setup_glue();
exec(&mut glue, "CREATE TABLE droppable (id INTEGER)").await;
exec(&mut glue, "INSERT INTO droppable VALUES (1)").await;
exec(&mut glue, "DROP TABLE droppable").await;
let result = glue.execute("SELECT * FROM droppable").await;
assert!(result.is_err(), "SELECT from dropped table should fail");
}
#[tokio::test]
async fn test_sql_commit_persists_across_reopen() {
let (temp, dataset) = common::setup_repo_and_dataset();
{
let mut storage = ProllyStorage::<32>::init(&dataset).expect("init");
let mut glue = Glue::new(storage);
exec(&mut glue, "CREATE TABLE persist (id INTEGER, name TEXT)").await;
exec(&mut glue, "INSERT INTO persist VALUES (1, 'saved')").await;
glue.execute("COMMIT").await.unwrap();
}
let storage = ProllyStorage::<32>::open(&dataset).expect("open");
let mut glue = Glue::new(storage);
let results = glue.execute("SELECT * FROM persist").await.unwrap();
assert!(!results.is_empty());
drop(temp);
}
#[tokio::test]
async fn test_sql_schema_persistence() {
use gluesql_core::store::Store;
let (temp, dataset) = common::setup_repo_and_dataset();
{
let mut storage = ProllyStorage::<32>::init(&dataset).expect("init");
let mut glue = Glue::new(storage);
exec(&mut glue, "CREATE TABLE schema_test (id INTEGER, val TEXT)").await;
glue.execute("COMMIT").await.unwrap();
}
let storage = ProllyStorage::<32>::open(&dataset).expect("open");
let schemas = storage.fetch_all_schemas().await.unwrap();
assert!(
schemas.iter().any(|s| s.table_name == "schema_test"),
"schema_test should persist"
);
drop(temp);
}