#![cfg(feature = "kv-surrealkv")]
use std::sync::Arc;
use surrealdb_kvs::TransactionType::Write;
use temp_dir::TempDir;
use crate::catalog::providers::{DatabaseProvider, NamespaceProvider, TableProvider};
use crate::dbs::{Capabilities, Session};
use crate::kvs::Datastore;
use crate::val::TableName;
async fn versioned_datastore() -> (TempDir, Arc<Datastore>) {
let dir = TempDir::new().unwrap();
let path = format!("surrealkv://{}?versioned=true&retention=1h", dir.path().to_string_lossy());
let ds = Datastore::builder()
.with_capabilities(Capabilities::all())
.build_with_path(&path)
.await
.unwrap();
(dir, ds)
}
#[tokio::test]
async fn test_versioned_read_does_not_pollute_table_cache() {
let (_dir, ds) = versioned_datastore().await;
let ses = Session::owner().with_ns("test").with_db("test");
ds.execute("DEFINE NAMESPACE test", &Session::owner(), None).await.unwrap();
ds.execute("DEFINE DATABASE test", &ses, None).await.unwrap();
ds.execute("DEFINE TABLE my_table", &ses, None).await.unwrap();
let tx = ds.transaction(Write).await.unwrap();
let ns_def = tx.get_ns_by_name("test", None).await.unwrap().unwrap();
let db_def = tx.get_db_by_name("test", "test", None).await.unwrap().unwrap();
let ns = ns_def.namespace_id;
let db = db_def.database_id;
let tables = tx.all_tb(ns, db, None).await.unwrap();
assert_eq!(tables.len(), 1, "Current view should have 1 table");
let old_tables = tx.all_tb(ns, db, Some(0)).await.unwrap();
assert_eq!(old_tables.len(), 0, "Historical read at version 0 should be empty");
let tables_again = tx.all_tb(ns, db, None).await.unwrap();
assert_eq!(tables_again.len(), 1, "Current view must still have 1 table after versioned read");
tx.cancel().await.unwrap();
}
#[tokio::test]
async fn test_versioned_read_does_not_pollute_field_cache() {
let (_dir, ds) = versioned_datastore().await;
let ses = Session::owner().with_ns("test").with_db("test");
ds.execute("DEFINE NAMESPACE test", &Session::owner(), None).await.unwrap();
ds.execute("DEFINE DATABASE test", &ses, None).await.unwrap();
ds.execute("DEFINE TABLE my_table", &ses, None).await.unwrap();
ds.execute("DEFINE FIELD name ON TABLE my_table TYPE string", &ses, None).await.unwrap();
let tx = ds.transaction(Write).await.unwrap();
let ns_def = tx.get_ns_by_name("test", None).await.unwrap().unwrap();
let db_def = tx.get_db_by_name("test", "test", None).await.unwrap().unwrap();
let ns = ns_def.namespace_id;
let db = db_def.database_id;
let tb = TableName::from("my_table");
let fields = tx.all_tb_fields(ns, db, &tb, None).await.unwrap();
assert_eq!(fields.len(), 1, "Current view should have 1 field");
let old_fields = tx.all_tb_fields(ns, db, &tb, Some(0)).await.unwrap();
assert_eq!(old_fields.len(), 0, "Historical read at version 0 should be empty");
let fields_again = tx.all_tb_fields(ns, db, &tb, None).await.unwrap();
assert_eq!(fields_again.len(), 1, "Current view must still have 1 field after versioned read");
tx.cancel().await.unwrap();
}