Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ members = ["codegen", "examples", "performance_measurement", "performance_measur

[package]
name = "worktable"
version = "0.7.1"
version = "0.7.2"
edition = "2024"
authors = ["Handy-caT"]
license = "MIT"
Expand All @@ -16,7 +16,7 @@ perf_measurements = ["dep:performance_measurement", "dep:performance_measurement
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
worktable_codegen = { path = "codegen", version = "0.7.1" }
worktable_codegen = { path = "codegen", version = "0.7.2" }

eyre = "0.6.12"
derive_more = { version = "1.0.0", features = ["from", "error", "display", "into"] }
Expand Down
2 changes: 1 addition & 1 deletion codegen/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "worktable_codegen"
version = "0.7.1"
version = "0.7.2"
edition = "2024"
license = "MIT"
description = "WorkTable codegeneration crate"
Expand Down
34 changes: 20 additions & 14 deletions codegen/src/worktable/generator/index/cdc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,22 +119,28 @@ impl Generator {
#index_field_name.extend(events.into_iter().map(|ev| ev.into()).collect::<Vec<_>>());
}
};
let insert = quote! {
let mut #index_field_name = if row_new.#i != row_old.#i {
let #index_field_name: Vec<_> = if let Some(events) = self.#index_field_name.insert_checked_cdc(row_new.#i.clone(), link_new) {
events.into_iter().map(|ev| ev.into()).collect()
let insert = if idx.is_unique {
quote! {
let mut #index_field_name = if row_new.#i != row_old.#i {
let #index_field_name: Vec<_> = if let Some(events) = self.#index_field_name.insert_checked_cdc(row_new.#i.clone(), link_new) {
events.into_iter().map(|ev| ev.into()).collect()
} else {
return Err(IndexError::AlreadyExists {
at: #available_index_ident::#index_variant,
inserted_already: inserted_indexes.clone(),
});
};
inserted_indexes.push(#available_index_ident::#index_variant);

#index_field_name
} else {
return Err(IndexError::AlreadyExists {
at: #available_index_ident::#index_variant,
inserted_already: inserted_indexes.clone(),
});
vec![]
};
inserted_indexes.push(#available_index_ident::#index_variant);

#index_field_name
} else {
vec![]
};
}
} else {
quote! {
let mut #index_field_name = vec![];
}
};
(insert, remove)
})
Expand Down
28 changes: 16 additions & 12 deletions codegen/src/worktable/generator/index/usual.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,20 +136,24 @@ impl Generator {
TableIndex::remove(&self.#index_field_name, val_old, link_old);
}
};
let insert = quote! {
let row = &row_new;
let val_new = #row.clone();
let row = &row_old;
let val_old = #row.clone();
if val_new != val_old {
if self.#index_field_name.insert_checked(val_new.clone(), link_new).is_none() {
return Err(IndexError::AlreadyExists {
at: #available_index_ident::#index_variant,
inserted_already: inserted_indexes.clone(),
})
let insert = if idx.is_unique {
quote! {
let row = &row_new;
let val_new = #row.clone();
let row = &row_old;
let val_old = #row.clone();
if val_new != val_old {
if self.#index_field_name.insert_checked(val_new.clone(), link_new).is_none() {
return Err(IndexError::AlreadyExists {
at: #available_index_ident::#index_variant,
inserted_already: inserted_indexes.clone(),
})
}
inserted_indexes.push(#available_index_ident::#index_variant);
}
inserted_indexes.push(#available_index_ident::#index_variant);
}
} else {
quote! {}
};
let remove = quote! {
let row = &row_new;
Expand Down
2 changes: 2 additions & 0 deletions src/table/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ where
at,
inserted_already,
} => {
self.pk_map.insert(pk.clone(), old_link);
self.indexes
.delete_from_indexes(row_new, new_link, inserted_already)?;
self.data
Expand Down Expand Up @@ -432,6 +433,7 @@ where
at,
inserted_already,
} => {
self.pk_map.insert(pk.clone(), old_link);
self.indexes
.delete_from_indexes(row_new, new_link, inserted_already)?;
self.data
Expand Down
6 changes: 6 additions & 0 deletions tests/worktable/index/update_full.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,17 +306,19 @@
};
test_table.insert(row2.clone()).unwrap();
let mut update = row1.clone();
update.id = row2.id.clone();

Check failure on line 309 in tests/worktable/index/update_full.rs

View workflow job for this annotation

GitHub Actions / clippy

using `clone` on type `u64` which implements the `Copy` trait

error: using `clone` on type `u64` which implements the `Copy` trait --> tests/worktable/index/update_full.rs:309:17 | 309 | update.id = row2.id.clone(); | ^^^^^^^^^^^^^^^ help: try removing the `clone` call: `row2.id` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#clone_on_copy = note: `-D clippy::clone-on-copy` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::clone_on_copy)]`
update.attr1 = "TEST_______________________1".to_string();
assert!(test_table.update(update).await.is_err());

assert_eq!(test_table.select(row1.id).unwrap(), row1);
assert_eq!(
test_table.select_by_attr1(row1.attr1.clone()).unwrap(),
row1
);
assert_eq!(test_table.select_by_attr2(row1.attr2).unwrap(), row1);
assert_eq!(test_table.select_by_attr3(row1.attr3).unwrap(), row1);

assert_eq!(test_table.select(row2.id).unwrap(), row2);
assert_eq!(
test_table.select_by_attr1(row2.attr1.clone()).unwrap(),
row2
Expand Down Expand Up @@ -349,13 +351,15 @@
update.attr1 = row2.attr1.clone();
assert!(test_table.update(update).await.is_err());

assert_eq!(test_table.select(row1.id).unwrap(), row1);
assert_eq!(
test_table.select_by_attr1(row1.attr1.clone()).unwrap(),
row1
);
assert_eq!(test_table.select_by_attr2(row1.attr2).unwrap(), row1);
assert_eq!(test_table.select_by_attr3(row1.attr3).unwrap(), row1);

assert_eq!(test_table.select(row2.id).unwrap(), row2);
assert_eq!(
test_table.select_by_attr1(row2.attr1.clone()).unwrap(),
row2
Expand Down Expand Up @@ -385,16 +389,18 @@
};
test_table.insert(row2.clone()).unwrap();
let mut update = row1.clone();
update.attr2 = row2.attr2.clone();

Check failure on line 392 in tests/worktable/index/update_full.rs

View workflow job for this annotation

GitHub Actions / clippy

using `clone` on type `i16` which implements the `Copy` trait

error: using `clone` on type `i16` which implements the `Copy` trait --> tests/worktable/index/update_full.rs:392:20 | 392 | update.attr2 = row2.attr2.clone(); | ^^^^^^^^^^^^^^^^^^ help: try removing the `clone` call: `row2.attr2` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#clone_on_copy
assert!(test_table.update(update).await.is_err());

assert_eq!(test_table.select(row1.id).unwrap(), row1);
assert_eq!(
test_table.select_by_attr1(row1.attr1.clone()).unwrap(),
row1
);
assert_eq!(test_table.select_by_attr2(row1.attr2).unwrap(), row1);
assert_eq!(test_table.select_by_attr3(row1.attr3).unwrap(), row1);

assert_eq!(test_table.select(row2.id).unwrap(), row2);
assert_eq!(
test_table.select_by_attr1(row2.attr1.clone()).unwrap(),
row2
Expand Down
95 changes: 94 additions & 1 deletion tests/worktable/index/update_query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,114 @@ async fn update_two_via_query_unique_indexes() {
test_table
.update_unique_two_attr_by_third(
UniqueTwoAttrByThirdQuery {
attr1: attr1_new,
attr1: attr1_new.clone(),
attr2: attr2_new,
},
attr3_old,
)
.await
.unwrap();

let mut new_row = row.clone();
new_row.attr1 = attr1_new;
new_row.attr2 = attr2_new;

// Check old idx removed
let updated = test_table.select_by_attr1(attr1_old.clone());
assert_eq!(updated, None);
let updated = test_table.select_by_attr2(attr2_old);
assert_eq!(updated, None);
let updated = test_table.select_by_attr3(attr3_old);
assert!(updated.is_some());
assert_eq!(updated, Some(new_row))
}

#[tokio::test]
async fn update_with_reinsert_and_secondary_unique_violation() {
let test_table = Test3UniqueWorkTable::default();

let row1 = Test3UniqueRow {
val: 1,
attr1: "TEST".to_string(),
attr2: 1000,
attr3: 65000,
id: 0,
};
test_table.insert(row1.clone()).unwrap();
let row2 = Test3UniqueRow {
val: 1,
attr1: "TEST__________________1".to_string(),
attr2: 1001,
attr3: 65001,
id: 1,
};
test_table.insert(row2.clone()).unwrap();
let update = UniqueTwoAttrByThirdQuery {
attr1: row2.attr1.clone(),
attr2: 999,
};
assert!(test_table
.update_unique_two_attr_by_third(update, row1.attr3,)
.await
.is_err());

assert_eq!(
test_table.select_by_attr1(row1.attr1.clone()).unwrap(),
row1
);
assert_eq!(test_table.select_by_attr2(row1.attr2).unwrap(), row1);
assert_eq!(test_table.select_by_attr3(row1.attr3).unwrap(), row1);

assert_eq!(
test_table.select_by_attr1(row2.attr1.clone()).unwrap(),
row2
);
assert_eq!(test_table.select_by_attr2(row2.attr2).unwrap(), row2);
assert_eq!(test_table.select_by_attr3(row2.attr3).unwrap(), row2);
}

#[tokio::test]
async fn update_with_secondary_unique_violation() {
let test_table = Test3UniqueWorkTable::default();

let row1 = Test3UniqueRow {
val: 1,
attr1: "TEST".to_string(),
attr2: 1000,
attr3: 65000,
id: 0,
};
test_table.insert(row1.clone()).unwrap();
let row2 = Test3UniqueRow {
val: 1,
attr1: "TEST__________________1".to_string(),
attr2: 1001,
attr3: 65001,
id: 1,
};
test_table.insert(row2.clone()).unwrap();
let update = UniqueTwoAttrByThirdQuery {
attr1: row1.attr1.clone(),
attr2: row2.attr2,
};
assert!(test_table
.update_unique_two_attr_by_third(update, row1.attr3)
.await
.is_err());

assert_eq!(
test_table.select_by_attr1(row1.attr1.clone()).unwrap(),
row1
);
assert_eq!(test_table.select_by_attr2(row1.attr2).unwrap(), row1);
assert_eq!(test_table.select_by_attr3(row1.attr3).unwrap(), row1);

assert_eq!(
test_table.select_by_attr1(row2.attr1.clone()).unwrap(),
row2
);
assert_eq!(test_table.select_by_attr2(row2.attr2).unwrap(), row2);
assert_eq!(test_table.select_by_attr3(row2.attr3).unwrap(), row2);
}

#[tokio::test]
Expand Down
Loading