Skip to content

Commit 607c45f

Browse files
committed
test
1 parent 4c357a5 commit 607c45f

2 files changed

Lines changed: 90 additions & 36 deletions

File tree

crates/core/src/db/relational_db.rs

Lines changed: 85 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -821,7 +821,7 @@ impl RelationalDB {
821821

822822
let is_ephemeral_tables = |table_id: &TableId| -> bool {
823823
tx_data
824-
.ephermal_tables()
824+
.ephemeral_tables()
825825
.map(|etables| etables.contains(table_id))
826826
.unwrap_or(false)
827827
};
@@ -2542,46 +2542,68 @@ mod tests {
25422542
Ok(())
25432543
}
25442544

2545-
#[test]
2546-
fn test_views() -> ResultTest<()> {
2547-
let stdb = TestDB::durable()?;
2545+
fn setup_view(stdb: &TestDB) -> ResultTest<(ViewId, TableId, ModuleDef, ViewDef)> {
25482546
let module_def = view_module_def();
25492547
let view_def = module_def.view("my_view").unwrap();
25502548

2551-
let row_type = view_def.product_type_ref;
2552-
let typespace = module_def.typespace();
2549+
let mut tx = begin_mut_tx(stdb);
2550+
let (view_id, table_id) = stdb.create_view(&mut tx, &module_def, view_def)?;
2551+
stdb.commit_tx(tx)?;
2552+
2553+
Ok((view_id, table_id, module_def.clone(), view_def.clone()))
2554+
}
25532555

2556+
fn insert_view_row(
2557+
stdb: &TestDB,
2558+
view_id: ViewId,
2559+
table_id: TableId,
2560+
typespace: &Typespace,
2561+
row_type: AlgebraicTypeRef,
2562+
sender: Identity,
2563+
v: u8,
2564+
) -> ResultTest<()> {
25542565
let to_bstan = |pv: &ProductValue| {
25552566
Bytes::from(to_vec(&AlgebraicValue::Array([pv.clone()].into())).expect("bstan serialization failed"))
25562567
};
2557-
let row_pv = |v: u8| ProductValue::from_iter(vec![AlgebraicValue::U8(v)]);
25582568

2559-
let project_views = |stdb: &TestDB, table_id: TableId, sender: Identity| {
2560-
let tx = begin_tx(stdb);
2561-
stdb.iter_by_col_eq(&tx, table_id, 0, &sender.into())
2562-
.unwrap()
2563-
.map(|row| ProductValue {
2564-
elements: row.to_product_value().elements.iter().skip(1).cloned().collect(),
2565-
})
2566-
.collect::<Vec<_>>()
2567-
};
2569+
let row_pv = |v: u8| ProductValue::from_iter(vec![AlgebraicValue::U8(v)]);
25682570

2569-
// Create the view
2570-
let mut tx = begin_mut_tx(&stdb);
2571-
let (view_id, table_id) = stdb.create_view(&mut tx, &module_def, view_def)?;
2571+
let mut tx = begin_mut_tx(stdb);
2572+
tx.subscribe_view(view_id, ArgId::SENTINEL, sender)?;
2573+
stdb.materialize_view(&mut tx, table_id, sender, row_type, to_bstan(&row_pv(v)), typespace)?;
25722574
stdb.commit_tx(tx)?;
25732575

2574-
let apply_view_update = |sender: Identity, val: u8| -> ResultTest<()> {
2575-
let mut tx = begin_mut_tx(&stdb);
2576-
tx.subscribe_view(view_id, ArgId::SENTINEL, sender)?;
2577-
stdb.materialize_view(&mut tx, table_id, sender, row_type, to_bstan(&row_pv(val)), typespace)?;
2578-
stdb.commit_tx(tx)?;
2579-
Ok(())
2580-
};
2576+
Ok(())
2577+
}
2578+
2579+
fn project_views(stdb: &TestDB, table_id: TableId, sender: Identity) -> Vec<ProductValue> {
2580+
let tx = begin_tx(stdb);
2581+
2582+
stdb.iter_by_col_eq(&tx, table_id, 0, &sender.into())
2583+
.unwrap()
2584+
.map(|row| {
2585+
let pv = row.to_product_value();
2586+
ProductValue {
2587+
elements: pv.elements.iter().skip(1).cloned().collect(),
2588+
}
2589+
})
2590+
.collect()
2591+
}
2592+
2593+
#[test]
2594+
fn test_views() -> ResultTest<()> {
2595+
let stdb = TestDB::durable()?;
2596+
2597+
let (view_id, table_id, module_def, view_def) = setup_view(&stdb)?;
2598+
let row_type = view_def.product_type_ref;
2599+
let typespace = module_def.typespace();
2600+
2601+
let row_pv = |v: u8| ProductValue::from_iter(vec![AlgebraicValue::U8(v)]);
25812602

25822603
// Sender 1
25832604
let sender1 = Identity::ONE;
2584-
apply_view_update(sender1, 42)?;
2605+
insert_view_row(&stdb, view_id, table_id, typespace, row_type, sender1, 42)?;
2606+
25852607
let mut tx = begin_mut_tx(&stdb);
25862608
tx.unsubscribe_view(view_id, ArgId::SENTINEL, sender1)?;
25872609
stdb.commit_tx(tx)?;
@@ -2595,7 +2617,7 @@ mod tests {
25952617
// Sender 2
25962618
let sender2 = Identity::ZERO;
25972619
let before_sender2 = Instant::now();
2598-
apply_view_update(sender2, 84)?;
2620+
insert_view_row(&stdb, view_id, table_id, typespace, row_type, sender2, 84)?;
25992621

26002622
assert_eq!(
26012623
project_views(&stdb, table_id, sender2)[0],
@@ -2622,11 +2644,43 @@ mod tests {
26222644
let tx = begin_mut_tx(&stdb);
26232645
let st_view_row = tx.lookup_st_view_subs(view_id)?;
26242646
assert_eq!(st_view_row.len(), 1, "Sender 1 should be removed from st_view_subs");
2625-
assert_eq!(
2626-
st_view_row[0].identity.0, sender2,
2627-
"Sender 1 should be removed from st_view_subs"
2647+
assert_eq!(st_view_row[0].identity.0, sender2);
2648+
2649+
Ok(())
2650+
}
2651+
2652+
#[test]
2653+
fn test_view_tables_are_ephemeral() -> ResultTest<()> {
2654+
let stdb = TestDB::durable()?;
2655+
2656+
let (view_id, table_id, module_def, view_def) = setup_view(&stdb)?;
2657+
let row_type = view_def.product_type_ref;
2658+
let typespace = module_def.typespace();
2659+
2660+
// Write some rows (reusing the same helper)
2661+
insert_view_row(&stdb, view_id, table_id, typespace, row_type, Identity::ONE, 10)?;
2662+
insert_view_row(&stdb, view_id, table_id, typespace, row_type, Identity::ZERO, 20)?;
2663+
2664+
assert!(
2665+
!project_views(&stdb, table_id, Identity::ZERO).is_empty(),
2666+
"View table should NOT be empty after insert"
26282667
);
26292668

2669+
// Reopen the database — view tables must not persist
2670+
let stdb = stdb.reopen()?;
2671+
2672+
// Validate that the view's backing table has been removed
2673+
assert!(
2674+
project_views(&stdb, table_id, Identity::ZERO).is_empty(),
2675+
"View table should be empty after reopening the database"
2676+
);
2677+
2678+
let tx = begin_mut_tx(&stdb);
2679+
let subs_rows = tx.lookup_st_view_subs(view_id)?;
2680+
assert!(
2681+
subs_rows.is_empty(),
2682+
"st_view_subs should be empty after reopening the database"
2683+
);
26302684
Ok(())
26312685
}
26322686

crates/datastore/src/traits.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ pub struct TxData {
197197
/// Set of ephemeral tables modified in this transaction (only populated when a view is executed).
198198
/// These tables do not need to be persisted to disk.
199199
/// Every table listed here must appear in either `inserts` or `deletes`.
200-
ephermal_tables: Option<EphemeralTables>,
200+
ephemeral_tables: Option<EphemeralTables>,
201201
}
202202

203203
impl TxData {
@@ -241,15 +241,15 @@ impl TxData {
241241
pub fn set_ephemeral_tables(&mut self, all_ephemeral_tables: &EphemeralTables) {
242242
for tid in self.tables.keys() {
243243
if all_ephemeral_tables.contains(tid) {
244-
self.ephermal_tables
244+
self.ephemeral_tables
245245
.get_or_insert_with(EphemeralTables::default)
246246
.insert(*tid);
247247
}
248248
}
249249
}
250250

251-
pub fn ephermal_tables(&self) -> Option<&EphemeralTables> {
252-
self.ephermal_tables.as_ref()
251+
pub fn ephemeral_tables(&self) -> Option<&EphemeralTables> {
252+
self.ephemeral_tables.as_ref()
253253
}
254254

255255
/// Obtain an iterator over the inserted rows per table.
@@ -286,7 +286,7 @@ impl TxData {
286286
pub fn durable_deletes(&self) -> impl Iterator<Item = (&TableId, &Arc<[ProductValue]>)> + '_ {
287287
self.deletes.iter().filter(move |(table_id, _)| {
288288
!self
289-
.ephermal_tables
289+
.ephemeral_tables
290290
.as_ref()
291291
.is_some_and(|etables| etables.contains(*table_id))
292292
})

0 commit comments

Comments
 (0)