pub struct DiffSetBuilder<F: Format<S, B>, T: SchemaWithPK, S, B> { /* private fields */ }Expand description
Builder for constructing changeset or patchset binary data.
DiffSetBuilder tracks rows in DML insertion order. When build
is called, it simulates SQLite’s session-extension hash table to produce
byte-identical output.
For parsed (frozen) data that should be emitted in its original order,
see DiffSet.
Generic over the format F (Changeset or Patchset), table schema T, and value types S, B.
Implementations§
Source§impl<F: Format<S, B>, T: SchemaWithPK, S: AsRef<str> + Hash + Eq, B: AsRef<[u8]> + Hash + Eq> DiffSetBuilder<F, T, S, B>
impl<F: Format<S, B>, T: SchemaWithPK, S: AsRef<str> + Hash + Eq, B: AsRef<[u8]> + Hash + Eq> DiffSetBuilder<F, T, S, B>
Sourcepub fn add_table(&mut self, table: &T) -> &mut Self
pub fn add_table(&mut self, table: &T) -> &mut Self
Register a table schema without adding any operations.
This is useful when you need the table present (e.g. before calling
DiffSetBuilder::digest_sql) but don’t have operations yet.
If the table is already registered, this is a no-op.
Source§impl<T: NamedColumns, S: Clone + Hash + Eq + AsRef<str> + for<'a> From<&'a str>> DiffSetBuilder<PatchsetFormat, T, S, Vec<u8>>
impl<T: NamedColumns, S: Clone + Hash + Eq + AsRef<str> + for<'a> From<&'a str>> DiffSetBuilder<PatchsetFormat, T, S, Vec<u8>>
Sourcepub fn digest_sql<'input>(
&mut self,
input: &'input str,
) -> Result<&mut Self, ParseError<'input>>
pub fn digest_sql<'input>( &mut self, input: &'input str, ) -> Result<&mut Self, ParseError<'input>>
Digest a SQL string containing INSERT, UPDATE, and DELETE statements into this patchset builder.
The SQL statements are parsed and their effects are directly applied to the builder, consolidating operations by primary key as usual.
§Errors
Returns a crate::builders::sql::ParseError if the SQL cannot be parsed.
Source§impl<T: SchemaWithPK, S: Clone + Debug + Hash + Eq + AsRef<str>, B: Clone + Debug + Hash + Eq + AsRef<[u8]>> DiffSetBuilder<ChangesetFormat, T, S, B>
impl<T: SchemaWithPK, S: Clone + Debug + Hash + Eq + AsRef<str>, B: Clone + Debug + Hash + Eq + AsRef<[u8]>> DiffSetBuilder<ChangesetFormat, T, S, B>
Source§impl<T: SchemaWithPK, S: Clone + Hash + Eq + AsRef<str>, B: Clone + Hash + Eq + AsRef<[u8]>> DiffSetBuilder<PatchsetFormat, T, S, B>
impl<T: SchemaWithPK, S: Clone + Hash + Eq + AsRef<str>, B: Clone + Hash + Eq + AsRef<[u8]>> DiffSetBuilder<PatchsetFormat, T, S, B>
Source§impl<T: ColumnNames, S: AsRef<str> + Clone + Debug + Hash + Eq, B: AsRef<[u8]> + Clone + Debug + Hash + Eq> DiffSetBuilder<ChangesetFormat, T, S, B>
impl<T: ColumnNames, S: AsRef<str> + Clone + Debug + Hash + Eq, B: AsRef<[u8]> + Clone + Debug + Hash + Eq> DiffSetBuilder<ChangesetFormat, T, S, B>
Sourcepub fn sql_statements(&self) -> impl Iterator<Item = String> + '_
pub fn sql_statements(&self) -> impl Iterator<Item = String> + '_
Iterate over operations as SQL statements.
Each operation is converted to an INSERT, UPDATE, or DELETE statement. Identifiers (table and column names) are quoted with double quotes. Statements do not include trailing semicolons.
§Example
use sqlite_diff_rs::{SimpleTable, ChangeSet, DiffOps, Insert};
let table = SimpleTable::new("users", &["id", "name"], &[0]);
let insert = Insert::from(table.clone())
.set(0, 1i64).unwrap()
.set(1, "Alice").unwrap();
let changeset = ChangeSet::<SimpleTable, String, Vec<u8>>::new().insert(insert);
for sql in changeset.sql_statements() {
assert_eq!(sql, r#"INSERT INTO "users" ("id", "name") VALUES (1, 'Alice')"#);
}Source§impl<T: ColumnNames, S: AsRef<str> + Clone + Hash + Eq, B: AsRef<[u8]> + Clone + Hash + Eq> DiffSetBuilder<PatchsetFormat, T, S, B>
impl<T: ColumnNames, S: AsRef<str> + Clone + Hash + Eq, B: AsRef<[u8]> + Clone + Hash + Eq> DiffSetBuilder<PatchsetFormat, T, S, B>
Sourcepub fn sql_statements(&self) -> impl Iterator<Item = String> + '_
pub fn sql_statements(&self) -> impl Iterator<Item = String> + '_
Iterate over operations as SQL statements.
Each operation is converted to an INSERT, UPDATE, or DELETE statement. Identifiers (table and column names) are quoted with double quotes. Statements do not include trailing semicolons.
§Example
use sqlite_diff_rs::{SimpleTable, PatchSet, DiffOps, Insert};
let table = SimpleTable::new("users", &["id", "name"], &[0]);
let insert = Insert::from(table.clone())
.set(0, 1i64).unwrap()
.set(1, "Alice").unwrap();
let patchset = PatchSet::<SimpleTable, String, Vec<u8>>::new().insert(insert);
for sql in patchset.sql_statements() {
assert_eq!(sql, r#"INSERT INTO "users" ("id", "name") VALUES (1, 'Alice')"#);
}Trait Implementations§
Source§impl<F: Format<S, B>, T: SchemaWithPK, S: Clone + Hash + Eq + AsRef<str>, B: Clone + Hash + Eq + AsRef<[u8]>> BitOr for DiffSetBuilder<F, T, S, B>
impl<F: Format<S, B>, T: SchemaWithPK, S: Clone + Hash + Eq + AsRef<str>, B: Clone + Hash + Eq + AsRef<[u8]>> BitOr for DiffSetBuilder<F, T, S, B>
Source§impl<F: Format<S, B>, T: SchemaWithPK, S: Clone + Hash + Eq + AsRef<str>, B: Clone + Hash + Eq + AsRef<[u8]>> BitOrAssign for DiffSetBuilder<F, T, S, B>
impl<F: Format<S, B>, T: SchemaWithPK, S: Clone + Hash + Eq + AsRef<str>, B: Clone + Hash + Eq + AsRef<[u8]>> BitOrAssign for DiffSetBuilder<F, T, S, B>
Source§fn bitor_assign(&mut self, rhs: Self)
fn bitor_assign(&mut self, rhs: Self)
Merge another diff set into this one, consolidating operations on the same row.
Source§impl<F: Clone + Format<S, B>, T: Clone + SchemaWithPK, S: Clone, B: Clone> Clone for DiffSetBuilder<F, T, S, B>
impl<F: Clone + Format<S, B>, T: Clone + SchemaWithPK, S: Clone, B: Clone> Clone for DiffSetBuilder<F, T, S, B>
Source§fn clone(&self) -> DiffSetBuilder<F, T, S, B>
fn clone(&self) -> DiffSetBuilder<F, T, S, B>
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl<F: Debug + Format<S, B>, T: Debug + SchemaWithPK, S: Debug, B: Debug> Debug for DiffSetBuilder<F, T, S, B>
impl<F: Debug + Format<S, B>, T: Debug + SchemaWithPK, S: Debug, B: Debug> Debug for DiffSetBuilder<F, T, S, B>
Source§impl<F: Format<S, B>, T: SchemaWithPK, S: AsRef<str> + Hash + Eq, B: AsRef<[u8]> + Hash + Eq> Default for DiffSetBuilder<F, T, S, B>
impl<F: Format<S, B>, T: SchemaWithPK, S: AsRef<str> + Hash + Eq, B: AsRef<[u8]> + Hash + Eq> Default for DiffSetBuilder<F, T, S, B>
Source§impl<T: SchemaWithPK, S: Clone + Debug + Hash + Eq + AsRef<str>, B: Clone + Debug + Hash + Eq + AsRef<[u8]>> DiffOps<T, S, B> for DiffSetBuilder<ChangesetFormat, T, S, B>
impl<T: SchemaWithPK, S: Clone + Debug + Hash + Eq + AsRef<str>, B: Clone + Debug + Hash + Eq + AsRef<[u8]>> DiffOps<T, S, B> for DiffSetBuilder<ChangesetFormat, T, S, B>
Source§type Format = ChangesetFormat
type Format = ChangesetFormat
Source§fn delete(self, delete: ChangeDelete<T, S, B>) -> Self
fn delete(self, delete: ChangeDelete<T, S, B>) -> Self
Source§fn update(self, update: Update<T, ChangesetFormat, S, B>) -> Self
fn update(self, update: Update<T, ChangesetFormat, S, B>) -> Self
Source§impl<T: SchemaWithPK, S: Clone + Hash + Eq + AsRef<str>, B: Clone + Hash + Eq + AsRef<[u8]>> DiffOps<T, S, B> for DiffSetBuilder<PatchsetFormat, T, S, B>
impl<T: SchemaWithPK, S: Clone + Hash + Eq + AsRef<str>, B: Clone + Hash + Eq + AsRef<[u8]>> DiffOps<T, S, B> for DiffSetBuilder<PatchsetFormat, T, S, B>
Source§fn delete(self, delete: PatchDelete<T, S, B>) -> Self
fn delete(self, delete: PatchDelete<T, S, B>) -> Self
Delete by primary key.
§Example
use sqlite_diff_rs::{DiffOps, PatchDelete, PatchSet, SchemaWithPK, TableSchema};
// CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)
let schema: TableSchema<String> = TableSchema::new("users".into(), 2, vec![1, 0]);
// Delete row where id = 1
let patchset = PatchSet::<_, String, Vec<u8>>::new()
.delete(PatchDelete::new(schema, vec![1i64.into()]));Source§fn update(self, update: Update<T, PatchsetFormat, S, B>) -> Self
fn update(self, update: Update<T, PatchsetFormat, S, B>) -> Self
Update by primary key.
§Example
use sqlite_diff_rs::{DiffOps, PatchSet, PatchsetFormat, Update, TableSchema};
// CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)
let schema: TableSchema<String> = TableSchema::new("users".into(), 2, vec![1, 0]);
// UPDATE users SET name = 'Bob' WHERE id = 1
let update = Update::<_, PatchsetFormat, String, Vec<u8>>::from(schema)
.set(0, 1i64).unwrap() // PK value
.set(1, "Bob").unwrap();
let patchset = PatchSet::<_, String, Vec<u8>>::new()
.update(update);Source§type Format = PatchsetFormat
type Format = PatchsetFormat
impl<F: Format<S, B>, T: SchemaWithPK, S, B> Eq for DiffSetBuilder<F, T, S, B>
Source§impl<T: SchemaWithPK, S: Clone + Debug + Hash + Eq + AsRef<str>, B: Clone + Debug + Hash + Eq + AsRef<[u8]>> From<&DiffSetBuilder<ChangesetFormat, T, S, B>> for Vec<u8>
impl<T: SchemaWithPK, S: Clone + Debug + Hash + Eq + AsRef<str>, B: Clone + Debug + Hash + Eq + AsRef<[u8]>> From<&DiffSetBuilder<ChangesetFormat, T, S, B>> for Vec<u8>
Source§fn from(builder: &DiffSetBuilder<ChangesetFormat, T, S, B>) -> Self
fn from(builder: &DiffSetBuilder<ChangesetFormat, T, S, B>) -> Self
Source§impl<T: SchemaWithPK, S: AsRef<str> + Clone + Hash + Eq, B: AsRef<[u8]> + Clone + Hash + Eq> From<&DiffSetBuilder<PatchsetFormat, T, S, B>> for Vec<u8>
impl<T: SchemaWithPK, S: AsRef<str> + Clone + Hash + Eq, B: AsRef<[u8]> + Clone + Hash + Eq> From<&DiffSetBuilder<PatchsetFormat, T, S, B>> for Vec<u8>
Source§fn from(builder: &DiffSetBuilder<PatchsetFormat, T, S, B>) -> Self
fn from(builder: &DiffSetBuilder<PatchsetFormat, T, S, B>) -> Self
Source§impl<F: Format<S, B>, T: SchemaWithPK, S: Hash + Eq + AsRef<str>, B: Hash + Eq + AsRef<[u8]>> From<DiffSet<F, T, S, B>> for DiffSetBuilder<F, T, S, B>
impl<F: Format<S, B>, T: SchemaWithPK, S: Hash + Eq + AsRef<str>, B: Hash + Eq + AsRef<[u8]>> From<DiffSet<F, T, S, B>> for DiffSetBuilder<F, T, S, B>
Source§impl<T: SchemaWithPK, S: Clone + Debug + Hash + Eq + AsRef<str>, B: Clone + Debug + Hash + Eq + AsRef<[u8]>> From<DiffSetBuilder<ChangesetFormat, T, S, B>> for Vec<u8>
impl<T: SchemaWithPK, S: Clone + Debug + Hash + Eq + AsRef<str>, B: Clone + Debug + Hash + Eq + AsRef<[u8]>> From<DiffSetBuilder<ChangesetFormat, T, S, B>> for Vec<u8>
Source§fn from(builder: DiffSetBuilder<ChangesetFormat, T, S, B>) -> Self
fn from(builder: DiffSetBuilder<ChangesetFormat, T, S, B>) -> Self
Source§impl<F: Format<S, B>, T: SchemaWithPK, S: Hash + Eq + AsRef<str>, B: Hash + Eq + AsRef<[u8]>> From<DiffSetBuilder<F, T, S, B>> for DiffSet<F, T, S, B>
impl<F: Format<S, B>, T: SchemaWithPK, S: Hash + Eq + AsRef<str>, B: Hash + Eq + AsRef<[u8]>> From<DiffSetBuilder<F, T, S, B>> for DiffSet<F, T, S, B>
Source§fn from(builder: DiffSetBuilder<F, T, S, B>) -> Self
fn from(builder: DiffSetBuilder<F, T, S, B>) -> Self
Source§impl<T: SchemaWithPK, S: AsRef<str> + Clone + Hash + Eq, B: AsRef<[u8]> + Clone + Hash + Eq> From<DiffSetBuilder<PatchsetFormat, T, S, B>> for Vec<u8>
impl<T: SchemaWithPK, S: AsRef<str> + Clone + Hash + Eq, B: AsRef<[u8]> + Clone + Hash + Eq> From<DiffSetBuilder<PatchsetFormat, T, S, B>> for Vec<u8>
Source§fn from(builder: DiffSetBuilder<PatchsetFormat, T, S, B>) -> Self
fn from(builder: DiffSetBuilder<PatchsetFormat, T, S, B>) -> Self
Source§impl<F: Format<S, B>, T: SchemaWithPK, S, B> PartialEq for DiffSetBuilder<F, T, S, B>
Custom PartialEq that ignores tables with empty operations.
impl<F: Format<S, B>, T: SchemaWithPK, S, B> PartialEq for DiffSetBuilder<F, T, S, B>
Custom PartialEq that ignores tables with empty operations.
Tables with no operations are not serialized (skipped in build()), so after
roundtrip they won’t exist. This makes empty tables semantically equivalent
to non-existent tables for comparison purposes.
Verified: SQLite’s session extension does NOT include empty table entries in
changesets/patchsets when all operations cancel out. Our builder keeps them
in memory to preserve table ordering, but they are correctly excluded here
and in build().
Source§impl<T: SchemaWithPK, S: Clone + Debug + Hash + Eq + AsRef<str>, B: Clone + Debug + Hash + Eq + AsRef<[u8]>> Reverse for DiffSetBuilder<ChangesetFormat, T, S, B>
impl<T: SchemaWithPK, S: Clone + Debug + Hash + Eq + AsRef<str>, B: Clone + Debug + Hash + Eq + AsRef<[u8]>> Reverse for DiffSetBuilder<ChangesetFormat, T, S, B>
Source§type Output = DiffSetBuilder<ChangesetFormat, T, S, B>
type Output = DiffSetBuilder<ChangesetFormat, T, S, B>
Auto Trait Implementations§
impl<F, T, S, B> Freeze for DiffSetBuilder<F, T, S, B>
impl<F, T, S, B> RefUnwindSafe for DiffSetBuilder<F, T, S, B>where
T: RefUnwindSafe,
<F as Format<S, B>>::DeleteData: RefUnwindSafe,
S: RefUnwindSafe,
B: RefUnwindSafe,
<F as Format<S, B>>::Old: RefUnwindSafe,
impl<F, T, S, B> Send for DiffSetBuilder<F, T, S, B>
impl<F, T, S, B> Sync for DiffSetBuilder<F, T, S, B>
impl<F, T, S, B> Unpin for DiffSetBuilder<F, T, S, B>
impl<F, T, S, B> UnsafeUnpin for DiffSetBuilder<F, T, S, B>
impl<F, T, S, B> UnwindSafe for DiffSetBuilder<F, T, S, B>where
T: UnwindSafe,
<F as Format<S, B>>::DeleteData: UnwindSafe,
S: UnwindSafe,
B: UnwindSafe,
<F as Format<S, B>>::Old: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.