diff --git a/src/drivers.rs b/src/drivers.rs index de41b0c..f88eefe 100644 --- a/src/drivers.rs +++ b/src/drivers.rs @@ -79,7 +79,7 @@ pub trait DatabaseDriver { if identifier.contains(",") { // This was the only way I could figure to get // around mutable string reference scope hell - let func = |part| self.quote_identifier(part.trim()); + let func = |part: &str| self.quote_identifier(part.trim()); identifier.replace_range(.., &split_map_join(identifier, ",", func)); } @@ -110,7 +110,10 @@ pub trait DatabaseDriver { } // Runs a prepared statement on the database - // fn execute(&self, sql: &str, ?) -> Result + // fn execute(&self, sql: &str, ?) -> Result; + + // Prepares and executes an sql query + // fn prepare_execute(&self, sql: &str, params: &[?]) -> Result; // ------------------------------------------------------------------------ // ! Driver-specific SQL methods @@ -124,7 +127,7 @@ pub trait DatabaseDriver { sql += &format!("\nLIMIT {}", limit.unwrap()); } - if offset.is_some() { + if limit.is_some() && offset.is_some() { sql += &format!(" OFFSET {}", offset.unwrap()); } diff --git a/src/lib.rs b/src/lib.rs index 69204d5..fe6f954 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,7 +7,7 @@ //! use stringqb::prelude::*; //! //! // Create a QueryBuilder object, with the chosen database driver -//! let qb = QueryBuilder::new(PostgresDriver::new("postgresql://user@localhost")); +//! let mut qb = QueryBuilder::new(PostgresDriver::new("postgresql://user@localhost")); //! //! ``` //! diff --git a/src/query_builder.rs b/src/query_builder.rs index 488e8f6..af6284a 100644 --- a/src/query_builder.rs +++ b/src/query_builder.rs @@ -329,7 +329,6 @@ impl QueryBuilder { /// Set a key and value for an insert or update query pub fn set(&mut self, key: &str, value: impl Any) -> &mut Self { - // @TODO figure a way to make this easier to use let key = self.driver.quote_identifier(key); self.state .append_set_array_keys(&key) diff --git a/src/types.rs b/src/types.rs index b3fadae..573695c 100644 --- a/src/types.rs +++ b/src/types.rs @@ -42,6 +42,7 @@ //! use std::any::Any; use std::borrow::Cow; +use std::error::Error; /// Empty struct to represent Null values #[derive(Copy, Clone)] @@ -77,15 +78,58 @@ pub enum ValueRef<'a> { } #[derive(Clone, Debug, PartialEq)] -pub enum ToSqlOutput<'a> { +pub enum ToDriverOutput<'a> { Borrowed(ValueRef<'a>), Owned(Value), } -/// Types that can be converted to SQL -//pub trait ToSql { -// fn to_sql(&self) -> Result>; -//} +// Generically allow any type that can be converted into a ValueRef +// to be converted into a ToSqlOutput as well. +impl<'a, T: ?Sized> From<&'a T> for ToDriverOutput<'a> + where + &'a T: Into>, +{ + fn from(t: &'a T) -> Self { + ToDriverOutput::Borrowed(t.into()) + } +} + +// We cannot also generically allow any type that can be converted +// into a Value to be converted into a ToDriverOutput because of +// coherence rules (https://github.com/rust-lang/rust/pull/46192), +// so we'll manually implement it for all the types we know can +// be converted into Values. +//macro_rules! from_value( +// ($t:ty) => ( +// impl From<$t> for ToDriverOutput<'_> { +// fn from(t: $t) -> Self { ToDriverOutput::Owned(t.into())} +// } +// ) +//); +//from_value!(String); +//from_value!(Null); +//from_value!(bool); +//from_value!(i8); +//from_value!(i16); +//from_value!(i32); +//from_value!(i64); +//from_value!(isize); +//from_value!(u8); +//from_value!(u16); +//from_value!(u32); +//from_value!(f64); +//from_value!(Vec); + + +/// Types that can be converted to a type that the driver understands +pub trait ToDriver { + fn to_driver(&self) -> Result, ()>; +} + +/// A trait for types that can be created from the result of a query on the driver +pub trait FromDriver: Sized { + +} /// Enum struct for mapping between database and Rust types #[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]