Ugly progress commit
This commit is contained in:
parent
b16cb8b8e4
commit
1776233a93
@ -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)
|
||||
});
|
||||
|
||||
|
@ -8,6 +8,7 @@ use super::*;
|
||||
pub struct MSSQL;
|
||||
|
||||
impl MSSQL {
|
||||
/// Create a MSSQL Driver
|
||||
pub fn new() -> Self {
|
||||
MSSQL {}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ use super::*;
|
||||
pub struct MySQL;
|
||||
|
||||
impl MySQL {
|
||||
/// Create a MySQL driver
|
||||
pub fn new() -> Self {
|
||||
MySQL {}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ use super::*;
|
||||
pub struct Postgres;
|
||||
|
||||
impl Postgres {
|
||||
/// Create a Postgres driver
|
||||
pub fn new() -> Self {
|
||||
Postgres {}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ use super::*;
|
||||
pub struct SQLite;
|
||||
|
||||
impl SQLite {
|
||||
/// Create an SQLite driver
|
||||
pub fn new() -> Self {
|
||||
SQLite {}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)));
|
||||
}
|
||||
|
@ -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 ", "(");
|
||||
}
|
||||
.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 {
|
||||
" AND "
|
||||
};
|
||||
|
||||
self.state
|
||||
.append_query_map(QueryClauseType::GroupStart, " AND NOT ", "(");
|
||||
}
|
||||
.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!();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user