Kestrel 2 anni fa
parent
commit
5300ea72e6

+ 2 - 2
Cargo.lock

@@ -88,7 +88,7 @@ checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b"
 
 [[package]]
 name = "microrm"
-version = "0.1.0"
+version = "0.1.1"
 dependencies = [
  "base64",
  "microrm-macros",
@@ -101,7 +101,7 @@ dependencies = [
 
 [[package]]
 name = "microrm-macros"
-version = "0.1.0"
+version = "0.1.1"
 dependencies = [
  "convert_case",
  "proc-macro2",

+ 1 - 1
microrm-macros/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = "microrm-macros"
-version = "0.1.0"
+version = "0.1.1"
 edition = "2021"
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

+ 1 - 1
microrm/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = "microrm"
-version = "0.1.0"
+version = "0.1.1"
 edition = "2021"
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

+ 1 - 1
microrm/src/lib.rs

@@ -160,7 +160,7 @@ impl DB {
                     true
                 },
             )
-            .map_err(|e| DBError::EarlyFailure(e))?;
+            .map_err(DBError::EarlyFailure)?;
 
         if mode != CreateMode::MustExist {
             println!("Creating schema!");

+ 2 - 4
microrm/src/model/create.rs

@@ -147,9 +147,7 @@ pub fn sql_for<T: crate::model::Entity>() -> (String, String) {
     // +1 to account for id column that is included in column_count
     assert_eq!(T::column_count(), cd.column_types.len() + 1);
 
-    let mut columns = Vec::new();
-
-    columns.push("id integer primary key".to_owned());
+    let mut columns = vec!["id integer primary key".to_owned()];
 
     for i in 1..T::column_count() {
         let col = <T::Column as std::convert::TryFrom<usize>>::try_from(i).unwrap();
@@ -171,7 +169,7 @@ pub fn sql_for<T: crate::model::Entity>() -> (String, String) {
             "\"{}\" {}{}",
             T::name(col),
             cd.column_types[i - 1],
-            fk.last().unwrap_or("".to_string())
+            fk.last().unwrap_or_else(|| "".to_string())
         ));
     }
 

+ 25 - 20
microrm/src/model/load.rs

@@ -21,31 +21,35 @@ impl<'de, 'a, 'l> serde::de::Deserializer<'de> for &'a mut RowDeserializer<'de,
     }
 
     fn deserialize_bool<V: Visitor<'de>>(self, v: V) -> Result<V::Value, Self::Error> {
-        todo!()
-        /*let res = v.visit_bool(self.row.get(self.col_index)?);
-        self.col_index += 1;
-        res*/
+        let built = Modelable::build_from(self.row, self.col_index)
+            .map_err(|e| Self::Error::LoadError(e.to_string()))?;
+        let res = v.visit_bool(built.0);
+        self.col_index += built.1;
+        res
     }
 
     fn deserialize_i8<V: Visitor<'de>>(self, v: V) -> Result<V::Value, Self::Error> {
-        todo!()
-        /*let res = v.visit_i8(self.row.get(self.col_index)?);
-        self.col_index += 1;
-        res*/
+        let built = Modelable::build_from(self.row, self.col_index)
+            .map_err(|e| Self::Error::LoadError(e.to_string()))?;
+        let res = v.visit_i8(built.0);
+        self.col_index += built.1;
+        res
     }
 
     fn deserialize_i16<V: Visitor<'de>>(self, v: V) -> Result<V::Value, Self::Error> {
-        todo!()
-        /*let res = v.visit_i16(self.row.get(self.col_index)?);
-        self.col_index += 1;
-        res*/
+        let built = Modelable::build_from(self.row, self.col_index)
+            .map_err(|e| Self::Error::LoadError(e.to_string()))?;
+        let res = v.visit_i16(built.0);
+        self.col_index += built.1;
+        res
     }
 
     fn deserialize_i32<V: Visitor<'de>>(self, v: V) -> Result<V::Value, Self::Error> {
-        todo!()
-        /*let res = v.visit_i32(self.row.get(self.col_index)?);
-        self.col_index += 1;
-        res*/
+        let built = Modelable::build_from(self.row, self.col_index)
+            .map_err(|e| Self::Error::LoadError(e.to_string()))?;
+        let res = v.visit_i32(built.0);
+        self.col_index += built.1;
+        res
     }
 
     fn deserialize_i64<V: Visitor<'de>>(self, v: V) -> Result<V::Value, Self::Error> {
@@ -65,10 +69,11 @@ impl<'de, 'a, 'l> serde::de::Deserializer<'de> for &'a mut RowDeserializer<'de,
     }
 
     fn deserialize_byte_buf<V: Visitor<'de>>(self, v: V) -> Result<V::Value, Self::Error> {
-        todo!()
-        /*let res = v.visit_byte_buf(self.row.get(self.col_index)?);
-        self.col_index += 1;
-        res*/
+        let built = Modelable::build_from(self.row, self.col_index)
+            .map_err(|e| Self::Error::LoadError(e.to_string()))?;
+        let res = v.visit_byte_buf(built.0);
+        self.col_index += built.1;
+        res
     }
 
     fn deserialize_struct<V: Visitor<'de>>(

+ 47 - 9
microrm/src/model/modelable.rs

@@ -1,22 +1,60 @@
 use super::Modelable;
 use sqlite::Bindable;
 
-impl Modelable for i32 {
+macro_rules! integral {
+    ($i:ty) => {
+        impl Modelable for $i {
+            fn bind_to(&self, stmt: &mut sqlite::Statement, col: usize) -> sqlite::Result<()> {
+                (*self as i64).bind(stmt, col)
+            }
+            fn build_from(stmt: &sqlite::Statement, col_offset: usize) -> sqlite::Result<(Self, usize)>
+            where
+                Self: Sized,
+            {
+                stmt.read::<i64>(col_offset).map(|x| (x as Self, 1))
+            }
+        }
+    }
+}
+
+integral!(i8);
+integral!(u8);
+integral!(i16);
+integral!(u16);
+integral!(i32);
+integral!(u32);
+integral!(i64);
+integral!(u64);
+
+impl Modelable for bool {
     fn bind_to(&self, stmt: &mut sqlite::Statement, col: usize) -> sqlite::Result<()> {
-        (*self as i64).bind(stmt, col)
+        let val = if self == &true { 1i64 } else { 0i64 };
+        val.bind(stmt, col)
     }
-    fn build_from(stmt: &sqlite::Statement, col_offset: usize) -> sqlite::Result<(Self, usize)>
+    fn build_from(_stmt: &sqlite::Statement, _col_offset: usize) -> sqlite::Result<(Self, usize)>
     where
         Self: Sized,
     {
-        stmt.read::<i64>(col_offset).map(|x| (x as i32, 1))
+        unreachable!("sqlite only gives Strings back, not &strs!");
     }
 }
 
-impl Modelable for i64 {
+impl<'a> Modelable for &'a str {
     fn bind_to(&self, stmt: &mut sqlite::Statement, col: usize) -> sqlite::Result<()> {
         self.bind(stmt, col)
     }
+    fn build_from(_stmt: &sqlite::Statement, _col_offset: usize) -> sqlite::Result<(Self, usize)>
+    where
+        Self: Sized,
+    {
+        unreachable!("sqlite only gives Strings back, not &strs!");
+    }
+}
+
+impl Modelable for std::string::String {
+    fn bind_to(&self, stmt: &mut sqlite::Statement, col: usize) -> sqlite::Result<()> {
+        self.as_str().bind(stmt, col)
+    }
     fn build_from(stmt: &sqlite::Statement, col_offset: usize) -> sqlite::Result<(Self, usize)>
     where
         Self: Sized,
@@ -25,7 +63,7 @@ impl Modelable for i64 {
     }
 }
 
-impl<'a> Modelable for &'a str {
+impl<'a> Modelable for &'a [u8] {
     fn bind_to(&self, stmt: &mut sqlite::Statement, col: usize) -> sqlite::Result<()> {
         self.bind(stmt, col)
     }
@@ -33,13 +71,13 @@ impl<'a> Modelable for &'a str {
     where
         Self: Sized,
     {
-        unreachable!("sqlite only gives Strings back, not &strs!");
+        unreachable!("sqlite only gives Vec<u8> back, not &[u8]!");
     }
 }
 
-impl Modelable for std::string::String {
+impl Modelable for Vec<u8> {
     fn bind_to(&self, stmt: &mut sqlite::Statement, col: usize) -> sqlite::Result<()> {
-        self.as_str().bind(stmt, col)
+        self.bind(stmt, col)
     }
     fn build_from(stmt: &sqlite::Statement, col_offset: usize) -> sqlite::Result<(Self, usize)>
     where

+ 8 - 44
microrm/src/query.rs

@@ -1,5 +1,4 @@
 use crate::model::{Entity, EntityColumns, EntityID};
-use crate::DB;
 
 // pub mod condition;
 
@@ -101,11 +100,11 @@ impl<'l> QueryInterface<'l> {
 
         val.bind_to(&mut prepared, 1).ok()?;
 
-        return self.expect_one_result(&mut prepared, &mut |stmt| {
+        self.expect_one_result(&mut prepared, &mut |stmt| {
             let id: i64 = stmt.read(0).ok()?;
-            let mut rd = crate::model::load::RowDeserializer::from_row(&stmt);
-            return Some(WithID::wrap(T::deserialize(&mut rd).ok()?, id));
-        });
+            let mut rd = crate::model::load::RowDeserializer::from_row(stmt);
+            Some(WithID::wrap(T::deserialize(&mut rd).ok()?, id))
+        })
     }
 
     /// Search for an entity by ID
@@ -119,11 +118,11 @@ impl<'l> QueryInterface<'l> {
 
         id.bind_to(&mut prepared, 1).ok()?;
 
-        return self.expect_one_result(&mut prepared, &mut |stmt| {
+        self.expect_one_result(&mut prepared, &mut |stmt| {
             let id: i64 = stmt.read(0).ok()?;
-            let mut rd = crate::model::load::RowDeserializer::from_row(&stmt);
+            let mut rd = crate::model::load::RowDeserializer::from_row(stmt);
             return Some(WithID::wrap(T::deserialize(&mut rd).ok()?, id));
-        });
+        })
     }
 
     /// Search for all entities matching a property
@@ -168,7 +167,7 @@ impl<'l> QueryInterface<'l> {
     /// Add an entity to its table
     pub fn add<T: Entity + serde::Serialize>(&self, m: &T) -> Option<<T as Entity>::ID> {
         let placeholders = (0..(<T as Entity>::column_count() - 1))
-            .map(|n| "?".to_string())
+            .map(|_| "?".to_string())
             .collect::<Vec<_>>()
             .join(",");
 
@@ -211,38 +210,3 @@ impl<'l> QueryInterface<'l> {
         Some(<T as Entity>::ID::from_raw_id(id))*/
     }
 }
-
-/// Search for all entities matching a property
-pub fn get_all_by<T: Entity<Column = C>, C: EntityColumns<Entity = T>, V: sqlite::Bindable>(
-    db: &DB,
-    c: C,
-    val: V,
-) -> Option<Vec<WithID<T>>> {
-    let table_name = <T as Entity>::table_name();
-    let column_name = <T as Entity>::name(c);
-
-    todo!();
-
-    /*
-
-    let mut prepared = db
-        .conn
-        .prepare(&format!(
-            "SELECT * FROM \"{}\" WHERE \"{}\" = ?1",
-            table_name, column_name
-        ))
-        .ok()?;
-
-    let rows = prepared
-        .query_map([&val], |row| {
-            let mut deser = crate::model::load::RowDeserializer::from_row(row);
-            Ok(WithID::wrap(
-                T::deserialize(&mut deser)?,
-                row.get(0).expect("can get rowid"),
-            ))
-        })
-        .ok()?;
-
-    Some(rows.map(|x| x.unwrap()).collect())
-    */
-}