More implementation
This commit is contained in:
parent
4cc6f079c3
commit
f7efadeb66
@ -28,14 +28,9 @@ version="15.1.0"
|
||||
optional=true
|
||||
package="mysql"
|
||||
|
||||
[dependencies.ms]
|
||||
version="0.3.2"
|
||||
optional=true
|
||||
package="tiberius"
|
||||
|
||||
[features]
|
||||
default=['postgres']
|
||||
postgres=['pg']
|
||||
sqlite=['slite']
|
||||
mysql=['my']
|
||||
mssql=['ms']
|
||||
mssql=[]
|
||||
|
@ -37,7 +37,15 @@ impl DefaultDriver {
|
||||
}
|
||||
}
|
||||
|
||||
impl DatabaseDriver for DefaultDriver {}
|
||||
impl DatabaseDriver for DefaultDriver {
|
||||
fn explain(&self, sql: &str) -> String {
|
||||
return format!("EXPLAIN {}", sql)
|
||||
}
|
||||
|
||||
fn random(&self) -> String {
|
||||
String::from(" RANDOM")
|
||||
}
|
||||
}
|
||||
|
||||
/// Database Driver Trait
|
||||
///
|
||||
@ -96,6 +104,32 @@ pub trait DatabaseDriver: fmt::Debug {
|
||||
|
||||
// Runs a basic sql query on the database
|
||||
// fn query(&self, query: &str) -> Result<(), ()>;
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// ! Driver-specific SQL methods
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/// Take an existing sql query and add a limit and/or offset
|
||||
fn limit(&self, sql: &str, limit: Option<usize>, offset: Option<usize>) -> String {
|
||||
let mut sql = sql.to_string();
|
||||
|
||||
if limit.is_some() {
|
||||
sql += &format!("\nLIMIT {}", limit.unwrap());
|
||||
}
|
||||
|
||||
if offset.is_some() {
|
||||
sql += &format!(" OFFSET {}", offset.unwrap());
|
||||
}
|
||||
|
||||
sql
|
||||
}
|
||||
|
||||
/// Get the query plan for the existing sql
|
||||
fn explain(&self, sql: &str) -> String;
|
||||
|
||||
/// Get the database's keyword for sorting randomly
|
||||
fn random(&self) -> String;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -1,5 +1,8 @@
|
||||
//! Database Driver for MSSQL
|
||||
//!
|
||||
//! Note:
|
||||
//! **This driver will probably never be fully implemented**
|
||||
//!
|
||||
//! Contains database-specific query data
|
||||
use super::*;
|
||||
|
||||
@ -20,6 +23,14 @@ impl DatabaseDriver for MSSQL {
|
||||
fn _quotes(&self) -> (char, char) {
|
||||
('[', ']')
|
||||
}
|
||||
|
||||
fn explain(&self, sql: &str) -> String {
|
||||
sql.to_string()
|
||||
}
|
||||
|
||||
fn random(&self) -> String {
|
||||
String::from(" RANDOM")
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -5,21 +5,43 @@ use super::*;
|
||||
|
||||
/// The struct implementing the `DatabaseDriver` trait
|
||||
#[derive(Debug)]
|
||||
pub struct MySQL;
|
||||
pub struct MySQLDriver;
|
||||
|
||||
impl MySQL {
|
||||
/// Create a MySQL driver
|
||||
impl MySQLDriver {
|
||||
/// Create a MySQLDriver driver
|
||||
pub fn new() -> Self {
|
||||
MySQL {}
|
||||
MySQLDriver {}
|
||||
}
|
||||
}
|
||||
|
||||
impl DatabaseDriver for MySQL {
|
||||
impl DatabaseDriver for MySQLDriver {
|
||||
/// Get which characters are used to delimit identifiers
|
||||
/// such as tables, and columns
|
||||
fn _quotes(&self) -> (char, char) {
|
||||
('`', '`')
|
||||
}
|
||||
|
||||
fn limit(&self, sql: &str, limit: Option<usize>, offset: Option<usize>) -> String {
|
||||
if limit.is_none() {
|
||||
return sql.to_string();
|
||||
}
|
||||
|
||||
// Limit and Offset are defined
|
||||
if offset.is_some() {
|
||||
return format!("{} LIMIT {}.{}", sql, offset.unwrap(), limit.unwrap());
|
||||
}
|
||||
|
||||
// Limit is defined
|
||||
format!("{} LIMIT {}", sql, limit.unwrap())
|
||||
}
|
||||
|
||||
fn explain(&self, sql: &str) -> String {
|
||||
return format!("EXPLAIN EXTENDED {}", sql)
|
||||
}
|
||||
|
||||
fn random(&self) -> String {
|
||||
String::from(" RAND() DESC")
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -28,7 +50,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_quote_identifier_backtick_quote() {
|
||||
let driver = MySQL::new();
|
||||
let driver = MySQLDriver::new();
|
||||
|
||||
assert_eq!(
|
||||
driver.quote_identifier("foo, bar, baz"),
|
||||
@ -42,7 +64,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_quote_identifiers_backtick_quote() {
|
||||
let driver = MySQL::new();
|
||||
let driver = MySQLDriver::new();
|
||||
|
||||
assert_eq!(
|
||||
driver.quote_identifiers(vec![
|
||||
|
@ -5,13 +5,21 @@ use super::*;
|
||||
|
||||
/// The struct implementing the `DatabaseDriver` trait
|
||||
#[derive(Debug)]
|
||||
pub struct Postgres;
|
||||
pub struct PostgresDriver;
|
||||
|
||||
impl Postgres {
|
||||
/// Create a Postgres driver
|
||||
impl PostgresDriver {
|
||||
/// Create a PostgresDriver driver
|
||||
pub fn new() -> Self {
|
||||
Postgres {}
|
||||
PostgresDriver {}
|
||||
}
|
||||
}
|
||||
|
||||
impl DatabaseDriver for Postgres {}
|
||||
impl DatabaseDriver for PostgresDriver {
|
||||
fn explain(&self, sql: &str) -> String {
|
||||
return format!("EXPLAIN VERBOSE {}", sql)
|
||||
}
|
||||
|
||||
fn random(&self) -> String {
|
||||
String::from(" RANDOM()")
|
||||
}
|
||||
}
|
||||
|
@ -5,13 +5,22 @@ use super::*;
|
||||
|
||||
/// The struct implementing the `DatabaseDriver` trait
|
||||
#[derive(Debug)]
|
||||
pub struct SQLite;
|
||||
pub struct SQLiteDriver;
|
||||
|
||||
impl SQLite {
|
||||
/// Create an SQLite driver
|
||||
impl SQLiteDriver {
|
||||
/// Create an SQLiteDriver driver
|
||||
pub fn new() -> Self {
|
||||
SQLite {}
|
||||
SQLiteDriver {}
|
||||
}
|
||||
}
|
||||
|
||||
impl DatabaseDriver for SQLiteDriver {
|
||||
fn explain(&self, sql: &str) -> String {
|
||||
return format!("EXPLAIN QUERY PLAN {}", sql)
|
||||
}
|
||||
|
||||
fn random(&self) -> String {
|
||||
String::from(" RANDOM()")
|
||||
}
|
||||
}
|
||||
|
||||
impl DatabaseDriver for SQLite {}
|
||||
|
16
src/lib.rs
16
src/lib.rs
@ -17,7 +17,21 @@ pub mod query_builder;
|
||||
|
||||
pub mod prelude {
|
||||
//! Re-exports important traits and types.
|
||||
//!
|
||||
//! This includes enum types, traits,
|
||||
//! the Query Builder, and individual database drivers.
|
||||
pub use crate::enums::*;
|
||||
pub use crate::drivers::{DatabaseDriver, DefaultDriver};
|
||||
pub use crate::drivers::DatabaseDriver;
|
||||
pub use crate::query_builder::QueryBuilder;
|
||||
|
||||
#[cfg(feature = "postgres")]
|
||||
pub use crate::drivers::postgres::PostgresDriver;
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
pub use crate::drivers::sqlite::SQLiteDriver;
|
||||
|
||||
#[cfg(feature = "mysql")]
|
||||
pub use crate::drivers::mysql::MySQLDriver;
|
||||
|
||||
// MSSQL is missing on purpose, as it is not a real priority to actually implement
|
||||
}
|
||||
|
@ -1,10 +1,8 @@
|
||||
//! 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::prelude::*;
|
||||
|
||||
fn main() {
|
||||
let mut qb = QueryBuilder::new(Postgres::new());
|
||||
let mut qb = QueryBuilder::new(PostgresDriver::new());
|
||||
|
||||
qb.set("foo", Box::new("bar"))
|
||||
.set("bar", Box::new(12))
|
||||
|
@ -53,6 +53,13 @@ impl QueryBuilder {
|
||||
///
|
||||
/// // The query builder must be mutable to be useful
|
||||
/// let mut qb = QueryBuilder::new(DefaultDriver::new());
|
||||
///
|
||||
/// // Each builder method returns a mutable reference to itself so
|
||||
/// // the methods are chainable
|
||||
/// qb.select("field f").from("table");
|
||||
///
|
||||
/// // Since they are references, you do not have to chain.
|
||||
/// let sql = qb.get_compiled_select();
|
||||
/// ```
|
||||
pub fn new(driver: impl DatabaseDriver + 'static) -> Self {
|
||||
QueryBuilder {
|
||||
|
@ -1,4 +1,4 @@
|
||||
use stringqb::query_builder::QueryBuilder;
|
||||
use stringqb::prelude::*;
|
||||
|
||||
#[test]
|
||||
fn minimal_select_query() {
|
||||
@ -47,6 +47,26 @@ fn select_without_from() {
|
||||
qb.get_compiled_select();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn select_where_in() {
|
||||
let mut qb = QueryBuilder::default();
|
||||
|
||||
qb.from("test")
|
||||
.where_in("foo", vec![
|
||||
Box::new(0),
|
||||
Box::new(1),
|
||||
Box::new(2),
|
||||
Box::new(3),
|
||||
Box::new(4),
|
||||
Box::new(5)
|
||||
]);
|
||||
|
||||
let sql = qb.get_compiled_select();
|
||||
let expected = "SELECT *\nFROM \"test\" WHERE \"foo\" IN (?,?,?,?,?,?) ";
|
||||
|
||||
assert_eq!(sql, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn basic_insert_query() {
|
||||
let mut qb = QueryBuilder::default();
|
||||
|
Loading…
Reference in New Issue
Block a user