Ugly progress commit

This commit is contained in:
Timothy Warren 2019-04-10 14:03:28 -04:00
parent b16cb8b8e4
commit 1776233a93
8 changed files with 61 additions and 34 deletions

View File

@ -30,6 +30,7 @@ struct QueryResult;
pub struct DefaultDriver;
impl DefaultDriver {
/// Create a `DefaultDriver`
pub fn new() -> Self {
DefaultDriver {}
}
@ -61,7 +62,7 @@ pub trait DatabaseDriver: fmt::Debug {
/// Quote the identifiers passed, so the database does not
/// normalize the identifiers (eg, table, column, etc.)
fn quote_identifier(&self, identifier: &str) -> String {
let mut identifier = &mut String::from(identifier);
let identifier = &mut String::from(identifier);
// If the identifier is actually a comma-separated list,
// recurse to quote each identifier in the list
@ -78,13 +79,12 @@ pub trait DatabaseDriver: fmt::Debug {
let trimmed_tiers = split_map_join(identifier, ".", |tier| {
let tier = tier.trim();
// Here where the quoting actually happens. Everything
// else is breaking down the identifier list for this.
if tier.starts_with(open_char) && tier.ends_with(close_char) {
return tier.to_string();
}
// Here where the quoting actually happens. Everything
// else is breaking down the identifier list for this.
format!("{}{}{}", &open_char, tier, &close_char)
});

View File

@ -8,6 +8,7 @@ use super::*;
pub struct MSSQL;
impl MSSQL {
/// Create a MSSQL Driver
pub fn new() -> Self {
MSSQL {}
}

View File

@ -8,6 +8,7 @@ use super::*;
pub struct MySQL;
impl MySQL {
/// Create a MySQL driver
pub fn new() -> Self {
MySQL {}
}

View File

@ -8,6 +8,7 @@ use super::*;
pub struct Postgres;
impl Postgres {
/// Create a Postgres driver
pub fn new() -> Self {
Postgres {}
}

View File

@ -8,6 +8,7 @@ use super::*;
pub struct SQLite;
impl SQLite {
/// Create an SQLite driver
pub fn new() -> Self {
SQLite {}
}

View File

@ -1,11 +1,11 @@
//! # StringQB
//!
//! A query builder using mostly strings, with methods following common SQL syntax
// #![warn(missing_docs)]
#![warn(missing_docs)]
#![allow(dead_code)]
pub mod drivers;
pub mod query_builder;
pub mod types;
/// Split a string, apply a closure to each substring,
/// then join the string back together

View File

@ -1,7 +1,7 @@
//! This main file is just for temparary testing
use stringqb::drivers::postgres::Postgres;
use stringqb::query_builder::QueryBuilder;
use stringqb::types::{SQLType, Type};
// use stringqb::types::{SQLType, Type};
fn main() {
let mut qb = QueryBuilder::new(Postgres::new());
@ -17,6 +17,6 @@ fn main() {
println!("QueryBuilder object: {:#?}", &qb);
println!("SQLType mapping: {:#?}", SQLType::SmallInt(32));
println!("Type: {:#?}", Type(Box::new(1234567890)));
// println!("SQLType mapping: {:#?}", SQLType::SmallInt(32));
// println!("Type: {:#?}", Type(Box::new(1234567890)));
}

View File

@ -5,6 +5,7 @@ use std::any::Any;
use std::collections::HashMap;
use crate::drivers::{DatabaseDriver, DefaultDriver};
use crate::split_map_join;
/// The position of the wildcard(s)
/// for a `like` clause
@ -26,18 +27,16 @@ pub enum LikeWildcard {
/// The type of SQL join
#[derive(Debug)]
pub enum JoinType {
/// A `CROSS` join
Cross,
/// An `INNER` join
Inner,
/// An `OUTER` join
Outer,
/// A `LEFT` join
/// A `LEFT (OUTER)` join
Left,
/// A `RIGHT` join
/// A `RIGHT (OUTER)` join
Right,
/// A `LEFT OUTER` join
LeftOuter,
/// A `RIGHT OUTER` join
RightOuter,
}
/// The sort direction
@ -47,7 +46,7 @@ pub enum OrderDirection {
Asc,
/// Sort Descending
Desc,
/// Random Sort
/// Random Sort (Not yet implemented!)
Rand,
}
@ -61,6 +60,14 @@ enum QueryClauseType {
WhereIn,
}
#[derive(Debug)]
enum QueryType {
Select,
Insert,
Update,
Delete,
}
#[derive(Debug)]
struct QueryClause {
clause_type: QueryClauseType,
@ -197,7 +204,18 @@ impl QueryBuilder {
/// Set the fields to select from the database as a string
pub fn select(&mut self, fields: &str) -> &mut Self {
unimplemented!();
let fields = split_map_join(fields, ",", |s| s.trim().to_string());
// Split identifiers on `As` keyword so they can be quoted properly
// @TODO split identifiers on `as` keyword (needs to be case-insensitive)
// Quote the identifiers (where there was an `as` keyword)
// Rejoin those identifiers
self.state.append_select_string(&fields);
self
}
/// Set the fields to select from the database as a Vector
@ -284,7 +302,7 @@ impl QueryBuilder {
self
}
// Specify a condition for a `where` clause where a column has a value
/// Specify a condition for a `where` clause where a column has a value
pub fn where_eq(&mut self, key: &str, value: Box<dyn Any>) -> &mut Self {
self.r#where(key, "=", value)
}
@ -360,12 +378,11 @@ impl QueryBuilder {
let condition = table + " ON " + &col + op + value;
let join_type = match join_type {
JoinType::Cross => "CROSS ",
JoinType::Left => "LEFT ",
JoinType::Inner => "INNER ",
JoinType::LeftOuter => "LEFT OUTER ",
JoinType::Outer => "OUTER ",
JoinType::Right => "RIGHT ",
JoinType::RightOuter => "RIGHT OUTER",
};
let conjunction = "\n".to_string() + join_type + "JOIN ";
@ -438,26 +455,28 @@ impl QueryBuilder {
/// Start a logical grouping in the current query
pub fn group_start(&mut self) -> &mut Self {
if self.state.query_map.len() == 0 {
self.state
.append_query_map(QueryClauseType::GroupStart, " ", "(");
let conj = if self.state.query_map.len() == 0 {
" WHERE "
} else {
self.state
.append_query_map(QueryClauseType::GroupStart, " WHERE ", "(");
}
" "
};
self.state
.append_query_map(QueryClauseType::GroupStart, conj, "(");
self
}
/// Start a logical grouping, prefixed with `not`
pub fn not_group_start(&mut self) -> &mut Self {
if self.state.query_map.len() == 0 {
self.state
.append_query_map(QueryClauseType::GroupStart, " WHERE NOT ", "(");
let conj = if self.state.query_map.len() == 0 {
" WHERE "
} else {
self.state
.append_query_map(QueryClauseType::GroupStart, " AND NOT ", "(");
}
" AND "
};
self.state
.append_query_map(QueryClauseType::GroupStart, conj, "NOT (");
self
}
@ -491,7 +510,7 @@ impl QueryBuilder {
// --------------------------------------------------------------------------
/// Execute the built query
pub fn get(self) -> Box<dyn Any> {
pub fn get(self) {
unimplemented!();
}
@ -556,7 +575,11 @@ impl QueryBuilder {
// ! Implementation Details
// --------------------------------------------------------------------------
fn compile() -> String {
fn compile(&self, query_type: QueryType, table: &str) -> String {
unimplemented!();
}
fn compile_type(&self, query_type: QueryType, table: &str) -> String {
unimplemented!();
}
}