|
@@ -19,6 +19,13 @@ impl<'r, 'q, T: Entity> Update<'r, 'q, T> {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // pub fn entire(&self, to: &T) -> Entire<'r, 'q, T>impl Filterable<'r, 'q, Table = T> {
|
|
|
+ pub fn to(self, to: &'r T) -> Entire<'r, 'q, T> {
|
|
|
+ Entire {
|
|
|
+ wrap: self,
|
|
|
+ to,
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
impl<'r, 'q, T: Entity> Settable<'r, 'q> for Update<'r, 'q, T>
|
|
@@ -45,7 +52,7 @@ impl<'r, 'q, T: Entity> QueryComponent for Update<'r, 'q, T> {
|
|
|
std::any::TypeId::of::<T>().hash(hasher);
|
|
|
}
|
|
|
|
|
|
- // next binding point is the first
|
|
|
+ // next binding point is the first, we do nothing here
|
|
|
fn bind(&self, _stmt: &mut sqlite::Statement<'_>) -> Result<usize, Error> {
|
|
|
Ok(1)
|
|
|
}
|
|
@@ -61,6 +68,58 @@ impl<'r, 'q, T: Entity> Resolvable<'r, 'q, T> for Update<'r, 'q, T> {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+pub struct Entire<'r, 'q, T: Entity> {
|
|
|
+ wrap: Update<'r, 'q, T>,
|
|
|
+ to: &'r T
|
|
|
+}
|
|
|
+
|
|
|
+impl<'r, 'q, T: Entity> StaticVersion for Entire<'r, 'q, T> {
|
|
|
+ type Is = Entire<'static, 'static, T>;
|
|
|
+}
|
|
|
+
|
|
|
+impl<'r, 'q, T: Entity> QueryComponent for Entire<'r, 'q, T> {
|
|
|
+ fn derive(&self) -> DerivedQuery {
|
|
|
+ let mut dq = self.wrap.derive();
|
|
|
+
|
|
|
+ // skip ID column
|
|
|
+ let cols = T::columns();
|
|
|
+ for column in &cols[1..] {
|
|
|
+ dq = dq.add(QueryPart::Set, format!("{} = ?", column.name()));
|
|
|
+ }
|
|
|
+ dq
|
|
|
+ }
|
|
|
+
|
|
|
+ fn contribute<H: Hasher>(&self, hasher: &mut H) {
|
|
|
+ self.wrap.contribute(hasher);
|
|
|
+ std::any::TypeId::of::<Self::Is>().hash(hasher);
|
|
|
+ }
|
|
|
+
|
|
|
+ fn bind(&self, stmt: &mut sqlite::Statement<'_>) -> Result<usize, Error> {
|
|
|
+ let ind = self.wrap.bind(stmt)?;
|
|
|
+
|
|
|
+ let values = self.to.values();
|
|
|
+
|
|
|
+ // skip ID
|
|
|
+ for col in 0..T::column_count()-1 {
|
|
|
+ println!("col: {}", col);
|
|
|
+ values[col].bind_to(stmt, ind + col)?;
|
|
|
+ }
|
|
|
+
|
|
|
+ println!("bound!");
|
|
|
+ Ok(ind + T::column_count() - 1)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl<'r, 'q, T: Entity> Resolvable<'r, 'q, T> for Entire<'r, 'q, T> {
|
|
|
+ fn qi(&self) -> &'r QueryInterface<'q> {
|
|
|
+ self.wrap.qi
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl<'r, 'q, T: Entity> Filterable<'r, 'q> for Entire<'r, 'q, T> {
|
|
|
+ type Table = T;
|
|
|
+}
|
|
|
+
|
|
|
pub trait Settable<'r, 'q>: Resolvable<'r, 'q, Self::Table>
|
|
|
where
|
|
|
'q: 'r,
|
|
@@ -84,7 +143,6 @@ where
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/// A concrete SET clause
|
|
|
pub struct Set<'r, 'q, S: Settable<'r, 'q>, C: EntityColumn, G: Modelable + ?Sized>
|
|
|
where
|
|
@@ -164,6 +222,7 @@ where
|
|
|
mod test {
|
|
|
use crate::prelude::*;
|
|
|
use crate::test_support::KVStore;
|
|
|
+ use crate::query::Resolvable;
|
|
|
|
|
|
#[test]
|
|
|
fn simple_update() {
|
|
@@ -180,4 +239,24 @@ mod test {
|
|
|
qi.update().update(KVStore::Value, "newvalue").by(KVStore::Key, "key").exec().unwrap();
|
|
|
assert_eq!(qi.get().by(KVStore::Key, "key").one().unwrap().unwrap().value, "newvalue");
|
|
|
}
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn swapout() {
|
|
|
+ let db = crate::DB::new_in_memory(crate::Schema::new().entity::<KVStore>()).unwrap();
|
|
|
+ let qi = db.query_interface();
|
|
|
+
|
|
|
+ let id = qi.add(&KVStore { key: "a".into(), value: "b".into() }).unwrap();
|
|
|
+
|
|
|
+ let check = qi.get().by(KVStore::ID, &id).all().unwrap();
|
|
|
+ assert_eq!(check.len(), 1);
|
|
|
+ assert_eq!(check[0].key, "a");
|
|
|
+ assert_eq!(check[0].value, "b");
|
|
|
+
|
|
|
+ qi.update().to(&KVStore { key: "c".into(), value: "d".into() }).by(KVStore::ID, &id).exec().unwrap();
|
|
|
+
|
|
|
+ let check = qi.get().by(KVStore::ID, &id).all().unwrap();
|
|
|
+ assert_eq!(check.len(), 1);
|
|
|
+ assert_eq!(check[0].key, "c");
|
|
|
+ assert_eq!(check[0].value, "d");
|
|
|
+ }
|
|
|
}
|