From 3865fd56b2ff285c93a32c38d2dcfb16a9d47b43 Mon Sep 17 00:00:00 2001 From: Timothy Warren Date: Thu, 4 Apr 2019 16:39:05 -0400 Subject: [PATCH] Another progress commit --- src/drivers/mod.rs | 12 +++-- src/drivers/postgres.rs | 3 +- src/drivers/sqlite.rs | 2 +- src/lib.rs | 3 +- src/main.rs | 31 ++++++----- src/query_builder.rs | 110 +++++++++++++++++++++++----------------- src/types.rs | 14 ++--- 7 files changed, 96 insertions(+), 79 deletions(-) diff --git a/src/drivers/mod.rs b/src/drivers/mod.rs index 1ec9448..b3446c0 100644 --- a/src/drivers/mod.rs +++ b/src/drivers/mod.rs @@ -3,16 +3,15 @@ //! Drivers represent a connection to a specific type of database engine use std::fmt; -#[cfg(feature="postgres")] +#[cfg(feature = "postgres")] mod postgres; -#[cfg(feature="sqlite")] +#[cfg(feature = "sqlite")] mod sqlite; -#[cfg(feature="mysql")] +#[cfg(feature = "mysql")] mod mysql; - #[derive(Debug)] struct Connection; @@ -20,6 +19,11 @@ struct Connection; #[derive(Debug)] struct QueryResult; +struct DriverBase { + escape_char_open: char, + escape_char_close: char, + has_truncate: bool, +} /// Database Driver Trait /// diff --git a/src/drivers/postgres.rs b/src/drivers/postgres.rs index 354d21b..7e54f2a 100644 --- a/src/drivers/postgres.rs +++ b/src/drivers/postgres.rs @@ -3,7 +3,6 @@ use super::*; #[derive(Debug)] pub struct Postgres; -#[cfg(feature="pg")] impl DatabaseDriver for Postgres { fn quote_identifier(&self, identifier: &str) -> String { String::from(identifier) @@ -12,4 +11,4 @@ impl DatabaseDriver for Postgres { fn query(&self, _query: &str) -> Result<(), ()> { Ok(()) } -} \ No newline at end of file +} diff --git a/src/drivers/sqlite.rs b/src/drivers/sqlite.rs index 47b7a47..27de3a9 100644 --- a/src/drivers/sqlite.rs +++ b/src/drivers/sqlite.rs @@ -11,4 +11,4 @@ impl DatabaseDriver for SQLite { fn query(&self, _query: &str) -> Result<(), ()> { Ok(()) } -} \ No newline at end of file +} diff --git a/src/lib.rs b/src/lib.rs index 3c34dff..d807fee 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,9 +1,8 @@ //! # StringQB //! //! A query builder using mostly strings, with methods following common SQL syntax -#![warn(missing_docs)] +// #![warn(missing_docs)] pub mod drivers; pub mod query_builder; pub mod types; - diff --git a/src/main.rs b/src/main.rs index 5dc93e2..c2958fd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,20 +3,19 @@ use stringqb::query_builder::QueryBuilder; use stringqb::types::{SQLType, Type}; fn main() { - let qb = QueryBuilder::new() - .set("foo", Box::new("bar")) - .set("bar", Box::new(12)) - .set("baz", Box::new(false)) - .set("fizz", Box::new(12.38)) - .set("buzz", Box::new((1, 2.0, true, 'q'))); - - - - // This just makes me sad - let qb = qb.r#where("foo", Box::new(2)); - - println!("QueryBuilder object: {:#?}", &qb); - - println!("SQLType mapping: {:#?}", SQLType::SmallInt(32)); - println!("Type: {:#?}", Type(Box::new(1234567890))); + let mut qb = QueryBuilder::new(); + + qb.set("foo", Box::new("bar")) + .set("bar", Box::new(12)) + .set("baz", Box::new(false)) + .set("fizz", Box::new(12.38)) + .set("buzz", Box::new((1, 2.0, true, 'q'))); + + // This just makes me sad + qb.r#where("foo", Box::new(2)); + + println!("QueryBuilder object: {:#?}", &qb); + + println!("SQLType mapping: {:#?}", SQLType::SmallInt(32)); + println!("Type: {:#?}", Type(Box::new(1234567890))); } diff --git a/src/query_builder.rs b/src/query_builder.rs index 6fc0f53..8ea89d9 100644 --- a/src/query_builder.rs +++ b/src/query_builder.rs @@ -94,9 +94,9 @@ struct QueryState { // Values to apply to where clauses in prepared statements where_values: Vec>, - limit: Option, + limit: Option, - offset: Option, + offset: Option, // Query components for complex selects query_map: Vec, @@ -130,7 +130,7 @@ impl Default for QueryState { } impl QueryState { - pub fn new() -> QueryState { + pub fn new() -> Self { QueryState::default() } } @@ -156,17 +156,17 @@ impl QueryBuilder { // -------------------------------------------------------------------------- /// Set the fields to select from the database - pub fn select(mut self, fields: &str) -> Self { - unimplemented!(); + pub fn select(&mut self, fields: &str) -> &mut Self { + unimplemented!(); } /// Adds the `distinct` keyword to a query - pub fn distinct(mut self) -> Self { + pub fn distinct(&mut self) -> &mut Self { unimplemented!(); } /// Specify the database table to select from - pub fn from(mut self, table_name: &str) -> Self { + pub fn from(&mut self, table_name: &str) -> &mut Self { // @TODO properly escape the table name self.state.from_string = table_name.to_string(); @@ -178,22 +178,37 @@ impl QueryBuilder { // -------------------------------------------------------------------------- /// Creates a `like` clause in the sql statement - pub fn like(mut self, field: &str, value: Box, position: LikeWildcard) -> Self { + pub fn like(&mut self, field: &str, value: Box, position: LikeWildcard) -> &mut Self { unimplemented!(); } /// Generates an OR Like clause - pub fn or_like(mut self, field: &str, value: Box, position: LikeWildcard) -> Self { + pub fn or_like( + &mut self, + field: &str, + value: Box, + position: LikeWildcard, + ) -> &mut Self { unimplemented!(); } /// Generates a NOI Like clause - pub fn not_like(mut self, field: &str, value: Box, position: LikeWildcard) -> Self { + pub fn not_like( + &mut self, + field: &str, + value: Box, + position: LikeWildcard, + ) -> &mut Self { unimplemented!(); } /// Generates an OR NOT Like clause - pub fn or_not_like(mut self, field: &str, value: Box, position: LikeWildcard) -> Self { + pub fn or_not_like( + &mut self, + field: &str, + value: Box, + position: LikeWildcard, + ) -> &mut Self { unimplemented!(); } @@ -202,12 +217,12 @@ impl QueryBuilder { // -------------------------------------------------------------------------- /// Add a `having` clause to the query - pub fn having(mut self, key:&str, value: Box) -> Self { + pub fn having(&mut self, key: &str, value: Box) -> &mut Self { unimplemented!(); } /// Add a `having` clause to the query, prefixed with an `or` - pub fn or_having(mut self, key:&str, value: Box) -> Self { + pub fn or_having(&mut self, key: &str, value: Box) -> &mut Self { unimplemented!(); } @@ -216,35 +231,35 @@ impl QueryBuilder { // -------------------------------------------------------------------------- /// Specify a condition for the `where` clause of the query - pub fn r#where(mut self, key: &str, value: Box) -> Self { + pub fn r#where(&mut self, key: &str, value: Box) -> &mut Self { // @TODO actually implement setting the keys for the where self.state.where_values.push(value); - + self } /// Specify a condition for the `where` clause of the query, prefixed with `or` - pub fn or_where(mut self, key: &str, value: Box) -> Self { + pub fn or_where(&mut self, key: &str, value: Box) -> &mut Self { unimplemented!(); } /// Specify a `where in` clause for the query - pub fn where_in(mut self, key: &str, value: Vec>) -> Self { + pub fn where_in(&mut self, key: &str, value: Vec>) -> &mut Self { unimplemented!(); } /// Specify a `where in` clause for the query, prefixed with `or` - pub fn or_where_in(mut self, key: &str, value: Vec>) -> Self { + pub fn or_where_in(&mut self, key: &str, value: Vec>) -> &mut Self { unimplemented!(); } /// Specify a `where not in` clause for the query - pub fn where_not_in(mut self, key: &str, value: Vec>) -> Self { + pub fn where_not_in(&mut self, key: &str, value: Vec>) -> &mut Self { unimplemented!(); } /// Specify a `where not in` clause for the query, prefixed with `or` - pub fn or_where_not_in(mut self, key: &str, value: Vec>) -> Self { + pub fn or_where_not_in(&mut self, key: &str, value: Vec>) -> &mut Self { unimplemented!(); } @@ -253,7 +268,7 @@ impl QueryBuilder { // -------------------------------------------------------------------------- /// Set a key and value for an insert or update query - pub fn set(mut self, key: &str, value: Box) -> Self { + pub fn set(&mut self, key: &str, value: Box) -> &mut Self { // @TODO figure a way to make this easier to use self.state.set_array_keys.push(key.to_string()); self.state.values.push(value); @@ -262,38 +277,38 @@ impl QueryBuilder { } /// Set a map of data for an insert or update query - pub fn set_map(mut self, data: HashMap>) -> Self { + pub fn set_map(&mut self, data: HashMap>) -> &mut Self { for (key, value) in data { - self = self.set(&key, value); + self.set(&key, value); } self } /// Add a table join to the query - pub fn join(mut self, table: &str, condition: &str, join_type: JoinType) -> Self { + pub fn join(&mut self, table: &str, condition: &str, join_type: JoinType) -> &mut Self { unimplemented!(); } /// Add a group by clause to the query - pub fn group_by(mut self, field: &str) -> Self { + pub fn group_by(&mut self, field: &str) -> &mut Self { unimplemented!(); } /// Add an order by clause to the query - pub fn order_by(mut self, field: &str, direction: OrderDirection) -> Self { + pub fn order_by(&mut self, field: &str, direction: OrderDirection) -> &mut Self { unimplemented!(); } /// Add a limit to the query - pub fn limit(mut self, limit: u32) -> Self { + pub fn limit(&mut self, limit: usize) -> &mut Self { self.state.limit = Some(limit); self } /// Add an offset to the query - pub fn offset(mut self, offset: u32) -> Self { + pub fn offset(&mut self, offset: usize) -> &mut Self { self.state.offset = Some(offset); self @@ -304,27 +319,27 @@ impl QueryBuilder { // -------------------------------------------------------------------------- /// Start a logical grouping in the current query - pub fn group_start(mut self) -> Self { + pub fn group_start(&mut self) -> &mut Self { unimplemented!(); } /// Start a logical grouping, prefixed with `not` - pub fn not_group_start(mut self) -> Self { + pub fn not_group_start(&mut self) -> &mut Self { unimplemented!(); } /// Start a logical grouping, prefixed with `or` - pub fn or_group_start(mut self) -> Self { + pub fn or_group_start(&mut self) -> &mut Self { unimplemented!(); } /// Start a logical grouping, prefixed with `or not` - pub fn or_not_group_start(mut self) -> Self { + pub fn or_not_group_start(&mut self) -> &mut Self { unimplemented!(); } /// End the current logical grouping - pub fn group_end(mut self) -> Self { + pub fn group_end(&mut self) -> &mut Self { unimplemented!(); } @@ -338,24 +353,24 @@ impl QueryBuilder { } /// Count all the rows in the specified database table - pub fn count_all(self, table: &str) -> u32 { + pub fn count_all(self, table: &str) -> usize { unimplemented!(); } /// Execute the generated insert query - pub fn insert(mut self, table: &str) { + pub fn insert(&mut self, table: &str) { // @TODO determine query result type unimplemented!(); } /// Execute the generated update query - pub fn update(mut self, table: &str) { + pub fn update(&mut self, table: &str) { // @TODO determine query result type unimplemented!(); } /// Execute the generated delete query - pub fn delete(mut self, table: &str) { + pub fn delete(&mut self, table: &str) { unimplemented!(); } @@ -388,7 +403,7 @@ impl QueryBuilder { // -------------------------------------------------------------------------- /// Get a new instance of the query builder - pub fn reset_query(mut self) -> Self { + pub fn reset_query(&mut self) -> Self { QueryBuilder::new() } } @@ -399,8 +414,9 @@ mod tests { #[test] fn set_key_value() { - let qb = QueryBuilder::new() - .set("foo", Box::new("bar")); + let mut qb = QueryBuilder::new(); + + qb.set("foo", Box::new("bar")); assert_eq!(qb.state.set_array_keys[0], "foo"); assert!(qb.state.values[0].is::<&str>()); @@ -411,20 +427,20 @@ mod tests { #[test] fn set_hashmap() { - let qb = QueryBuilder::new(); + let mut qb = QueryBuilder::new(); let mut authors: HashMap> = HashMap::new(); authors.insert( String::from("Chinua Achebe"), - Box::new(String::from("Nigeria"))); + Box::new(String::from("Nigeria")), + ); authors.insert( String::from("Rabindranath Tagore"), - Box::new(String::from("India"))); - authors.insert( - String::from("Anita Nair"), - Box::new(String::from("India"))); + Box::new(String::from("India")), + ); + authors.insert(String::from("Anita Nair"), Box::new(String::from("India"))); - let qb = qb.set_map(authors); + qb.set_map(authors); // assert_eq!(qb.state.set_array_keys[0], "Chinua Achebe"); assert_eq!(qb.state.set_array_keys.len(), 3); diff --git a/src/types.rs b/src/types.rs index 69d266c..87ebf70 100644 --- a/src/types.rs +++ b/src/types.rs @@ -7,21 +7,21 @@ pub struct Type(pub Box); /// Enum struct for mapping between database and Rust types #[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)] pub enum SQLType { - Boolean(T), - SmallInt(T), - BigInt(T), - Text(T), - None, + Boolean(T), + SmallInt(T), + BigInt(T), + Text(T), + None, } impl SQLType { - pub fn is_some(&self) -> bool { + pub fn is_some(&self) -> bool { match *self { SQLType::None => false, _ => true, } } - + pub fn is_none(&self) -> bool { !self.is_some() }