prgress commit

This commit is contained in:
Timothy Warren 2019-04-22 08:59:40 -04:00
parent 4262b5b1c0
commit 861069abe7
7 changed files with 67 additions and 23 deletions

View File

@ -12,8 +12,7 @@ regex = "1.1.5"
serde_json = "1.0.39" serde_json = "1.0.39"
[dependencies.pg] [dependencies.pg]
version="0.15.2" version="0.16.0-rc.1"
features=["with-serde_json"]
optional=true optional=true
package="postgres" package="postgres"

View File

@ -3,7 +3,8 @@
//! Drivers represent a connection to a specific type of database engine //! Drivers represent a connection to a specific type of database engine
use crate::fns::split_map_join; use crate::fns::split_map_join;
use regex::Regex; use regex::Regex;
use std::fmt; use std::any::Any;
use std::error::Error;
#[cfg(feature = "postgres")] #[cfg(feature = "postgres")]
pub mod postgres; pub mod postgres;
@ -50,7 +51,7 @@ impl DatabaseDriver for DefaultDriver {
/// Database Driver Trait /// Database Driver Trait
/// ///
/// Interface between the database connection library and the query builder /// Interface between the database connection library and the query builder
pub trait DatabaseDriver: fmt::Debug { pub trait DatabaseDriver {
/// Get which characters are used to delimit identifiers /// Get which characters are used to delimit identifiers
/// such as tables, and columns /// such as tables, and columns
fn _quotes(&self) -> (char, char) { fn _quotes(&self) -> (char, char) {
@ -103,7 +104,10 @@ pub trait DatabaseDriver: fmt::Debug {
} }
// Runs a basic sql query on the database // Runs a basic sql query on the database
// fn query(&self, query: &str) -> Result<(), ()>; // fn query(&self, sql: &str) -> Result<impl Any, impl Error>;
// Runs a prepared statement on the database
// fn execute(&self, sql: &str, ?) -> Result<?,?>
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// ! Driver-specific SQL methods // ! Driver-specific SQL methods

View File

@ -1,5 +1,7 @@
//! Database Driver for MySQL //! Database Driver for MySQL
//! //!
//! Use of this driver requires enabling the `mysql` feature.
//!
//! Contains database-specific query data //! Contains database-specific query data
use super::*; use super::*;

View File

@ -1,16 +1,49 @@
//! Database Driver for Postgres //! Database Driver for Postgres
//! //!
//! Contains database-specific query data //! Use of this driver requires enabling the `postgres` feature. The `postgres`
//! feature is enabled by default.
//!
//! Uses the [Postgres](https://crates.io/crates/postgres) crate for
//! interfacing with the database
use super::*; use super::*;
use pg::{Client, Error, NoTls, Row};
use std::any::Any;
use std::cell::RefCell;
/// The struct implementing the `DatabaseDriver` trait /// The struct implementing the `DatabaseDriver` trait
#[derive(Debug)] pub struct PostgresDriver {
pub struct PostgresDriver; connection: RefCell<Option<Client>>,
}
impl PostgresDriver { impl PostgresDriver {
/// Create a PostgresDriver driver /// Create a PostgresDriver driver
pub fn new() -> Self { pub fn new(dsn: &str) -> Self {
PostgresDriver {} let mut driver = PostgresDriver {
connection: RefCell::new(None),
};
driver.connect(dsn);
driver
}
fn connect(&mut self, dsn: &str) {
let connection = Client::connect(dsn, NoTls).unwrap();
self.connection = RefCell::new(Some(connection));
}
pub fn query(&self, sql: &str) -> Result<Vec<Row>, Error> {
if self.connection.borrow().is_none() {
panic!("No database connection.");
}
self.connection
.borrow_mut()
.as_mut()
.unwrap()
.query(sql, &[])
} }
} }

View File

@ -2,11 +2,19 @@
//! //!
//! A query builder using mostly strings, with methods following common SQL syntax //! A query builder using mostly strings, with methods following common SQL syntax
//! //!
//! ``` //!
//! ```no_run
//! use stringqb::prelude::*; //! use stringqb::prelude::*;
//! //!
//! // Create a QueryBuilder object, with the chosen database driver
//! let qb = QueryBuilder::new(PostgresDriver::new("postgresql://user@localhost"));
//! //!
//! ``` //! ```
//!
//! Drivers include:
//! * `PostgresDriver` - for PostgreSQL databases
//! * `MySQLDriver` - for MySQL/MariaDB databases
//! * `SQLiteDriver` - for SQLite databases
#![warn(missing_docs)] #![warn(missing_docs)]
#[macro_use] #[macro_use]

View File

@ -80,7 +80,6 @@ enum QueryType {
} }
/// The struct representing a query builder /// The struct representing a query builder
#[derive(Debug)]
pub struct QueryBuilder { pub struct QueryBuilder {
/// The struct to store the query builder info /// The struct to store the query builder info
state: QueryState, state: QueryState,
@ -207,7 +206,7 @@ impl QueryBuilder {
// ! 'Like' methods // ! 'Like' methods
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
/// Creates a `like` clause in the sql statement /// Creates a `like` clause in the sql
/// ///
/// ```no_run /// ```no_run
/// # use stringqb::prelude::*; /// # use stringqb::prelude::*;
@ -225,12 +224,12 @@ impl QueryBuilder {
self._like(field, value, position, "LIKE", "AND") self._like(field, value, position, "LIKE", "AND")
} }
/// Generates an OR Like clause /// Generates an `or like` clause
pub fn or_like(&mut self, field: &str, value: impl Any, position: LikeWildcard) -> &mut Self { pub fn or_like(&mut self, field: &str, value: impl Any, position: LikeWildcard) -> &mut Self {
self._like(field, value, position, "LIKE", "OR") self._like(field, value, position, "LIKE", "OR")
} }
/// Generates a NOI Like clause /// Generates a `not like` clause
pub fn not_like(&mut self, field: &str, value: impl Any, position: LikeWildcard) -> &mut Self { pub fn not_like(&mut self, field: &str, value: impl Any, position: LikeWildcard) -> &mut Self {
self._like(field, value, position, "NOT LIKE", "AND") self._like(field, value, position, "NOT LIKE", "AND")
} }
@ -255,10 +254,10 @@ impl QueryBuilder {
/// # use stringqb::prelude::*; /// # use stringqb::prelude::*;
/// # let mut qb = QueryBuilder::default(); /// # let mut qb = QueryBuilder::default();
/// // By default, key = value /// // By default, key = value
/// qb.having("key", vec![Box::new("value")]); /// qb.having("key", vec!["value"]);
/// ///
/// // Other operators can be used with a separating space /// // Other operators can be used with a separating space
/// qb.having("clues >=", vec![Box::new(4)]); /// qb.having("clues >=", vec![4]);
/// ``` /// ```
pub fn having(&mut self, key: &str, value: Vec<impl Any>) -> &mut Self { pub fn having(&mut self, key: &str, value: Vec<impl Any>) -> &mut Self {
self._having(key, value, "AND") self._having(key, value, "AND")
@ -281,10 +280,10 @@ impl QueryBuilder {
/// # use stringqb::prelude::*; /// # use stringqb::prelude::*;
/// # let mut qb = QueryBuilder::default(); /// # let mut qb = QueryBuilder::default();
/// // By default, key = value /// // By default, key = value
/// qb.r#where("key", Box::new("value")); /// qb.r#where("key", "value");
/// ///
/// // Other operators can be used with a separating space /// // Other operators can be used with a separating space
/// qb.r#where("key >", Box::new(4)); /// qb.r#where("key >", 4);
/// ``` /// ```
pub fn r#where(&mut self, key: &str, value: impl Any) -> &mut Self { pub fn r#where(&mut self, key: &str, value: impl Any) -> &mut Self {
self._where_string(key, value, "AND") self._where_string(key, value, "AND")
@ -681,7 +680,7 @@ impl QueryBuilder {
match last_item.clause_type { match last_item.clause_type {
QueryClauseType::GroupStart => String::from(""), QueryClauseType::GroupStart => String::from(""),
_ => format!(" {} ", conj) _ => format!(" {} ", conj),
} }
} else { } else {
format!(" {} ", conj) format!(" {} ", conj)
@ -939,7 +938,7 @@ impl QueryState {
pub fn get_query_map_last(&self) -> Option<&QueryClause> { pub fn get_query_map_last(&self) -> Option<&QueryClause> {
if self.query_map.len() == 0 { if self.query_map.len() == 0 {
return None return None;
} }
let index = self.query_map.len() - 1; let index = self.query_map.len() - 1;

View File

@ -51,8 +51,7 @@ fn select_without_from() {
fn select_where() { fn select_where() {
let mut qb = QueryBuilder::default(); let mut qb = QueryBuilder::default();
qb.from("test") qb.from("test").r#where("foo", "bar");
.r#where("foo", "bar");
let sql = qb.get_compiled_select(); let sql = qb.get_compiled_select();
let expected = "SELECT *\nFROM \"test\" WHERE \"foo\"=?"; let expected = "SELECT *\nFROM \"test\" WHERE \"foo\"=?";