use lix::{LixError, Value};
simulation_test!(
internal_storage_relations_are_not_public,
|sim| async move {
let engine = sim.boot_engine().await;
let session = sim.wrap_session(
engine.open_session().await.expect("session should open"),
&engine,
);
for surface_name in [
"lix_state",
"lix_state_by_branch",
"lix_state_history",
"lix_label",
"lix_label_by_branch",
"lix_label_history",
"lix_label_assignment",
"lix_label_assignment_by_branch",
"lix_label_assignment_history",
"lix_binary_blob_ref",
"lix_binary_blob_ref_by_branch",
"lix_binary_blob_ref_history",
"lix_branch_descriptor",
"lix_branch_descriptor_by_branch",
"lix_branch_descriptor_history",
"lix_branch_ref",
"lix_branch_ref_by_branch",
"lix_branch_ref_history",
"lix_directory_descriptor",
"lix_directory_descriptor_by_branch",
"lix_directory_descriptor_history",
"lix_file_descriptor",
"lix_file_descriptor_by_branch",
"lix_file_descriptor_history",
] {
let error = session
.execute(&format!("SELECT * FROM {surface_name}"), &[])
.await
.expect_err("private storage relation should not resolve");
assert_eq!(
error.code,
LixError::CODE_TABLE_NOT_FOUND,
"{surface_name}: {error:?}"
);
}
}
);
#[cfg(any())]
simulation_test!(read_only_history_views_reject_dml, |sim| async move {
let engine = sim.boot_engine().await;
let session = sim.wrap_session(
engine.open_session().await.expect("session should open"),
&engine,
);
assert_read_only_error(
session
.execute(
"INSERT INTO lix_file_history (id, path) VALUES ('68697374-6f72-892d-8669-6c6500000000', '/x.txt')",
&[],
)
.await
.expect_err("history insert should be read-only"),
"lix_file_history",
"History views are query-only",
);
assert_read_only_error(
session
.execute("UPDATE lix_directory_history SET name = 'renamed'", &[])
.await
.expect_err("history update should be read-only"),
"lix_directory_history",
"History views are query-only",
);
});
#[cfg(any())]
simulation_test!(read_only_typed_history_views_reject_dml, |sim| async move {
let engine = sim.boot_engine().await;
let session = sim.wrap_session(
engine.open_session().await.expect("session should open"),
&engine,
);
session
.execute(
"INSERT INTO lix_registered_schema (value, lixcol_global, lixcol_untracked) \
VALUES (\
CAST('{\"$schema\":\"https://lix.dev/schema-v1.json\",\"key\":\"read_only_history_row\",\"columns\":[{\"name\":\"id\",\"type\":\"text\",\"nullable\":false}],\"primary_key\":[\"id\"]}' AS JSONB),\
false,\
true\
)",
&[],
)
.await
.expect("registered schema insert should succeed");
assert_read_only_error(
session
.execute(
"INSERT INTO read_only_history_row_history (id) VALUES ('row-a')",
&[],
)
.await
.expect_err("typed history insert should be read-only"),
"read_only_history_row_history",
"History views are query-only",
);
});
simulation_test!(
cached_read_syntax_uses_a_fresh_storage_snapshot,
|sim| async move {
let engine = sim.boot_engine().await;
let reader = sim.wrap_session(
engine
.open_session()
.await
.expect("reader session should open"),
&engine,
);
let writer = sim.wrap_session(
engine
.open_session()
.await
.expect("writer session should open"),
&engine,
);
let select_sql = "SELECT content FROM lix_file WHERE id = $1";
let params = [Value::Text(
"66726573-682d-836e-8170-73686f742d00".to_string(),
)];
let before = reader
.execute(select_sql, ¶ms)
.await
.expect("initial cached-syntax read should succeed");
assert_eq!(before.len(), 0);
writer
.execute(
"INSERT INTO lix_file (id, path, content) VALUES ($1, $2, $3)",
&[
Value::Text("66726573-682d-836e-8170-73686f742d00".to_string()),
Value::Text("/fresh-snapshot.txt".to_string()),
Value::Blob(b"fresh".to_vec().into()),
],
)
.await
.expect("intervening write should commit");
let after = reader
.execute(select_sql, ¶ms)
.await
.expect("repeated syntax should use a fresh provider snapshot");
assert_eq!(
after.rows()[0].values(),
&[Value::Blob(b"fresh".to_vec().into())]
);
}
);