More implementation
This commit is contained in:
parent
4cc6f079c3
commit
f7efadeb66
@ -28,14 +28,9 @@ version="15.1.0"
|
|||||||
optional=true
|
optional=true
|
||||||
package="mysql"
|
package="mysql"
|
||||||
|
|
||||||
[dependencies.ms]
|
|
||||||
version="0.3.2"
|
|
||||||
optional=true
|
|
||||||
package="tiberius"
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default=['postgres']
|
default=['postgres']
|
||||||
postgres=['pg']
|
postgres=['pg']
|
||||||
sqlite=['slite']
|
sqlite=['slite']
|
||||||
mysql=['my']
|
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
|
/// Database Driver Trait
|
||||||
///
|
///
|
||||||
@ -96,6 +104,32 @@ 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, 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)]
|
#[cfg(test)]
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
//! Database Driver for MSSQL
|
//! Database Driver for MSSQL
|
||||||
//!
|
//!
|
||||||
|
//! Note:
|
||||||
|
//! **This driver will probably never be fully implemented**
|
||||||
|
//!
|
||||||
//! Contains database-specific query data
|
//! Contains database-specific query data
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
@ -20,6 +23,14 @@ impl DatabaseDriver for MSSQL {
|
|||||||
fn _quotes(&self) -> (char, char) {
|
fn _quotes(&self) -> (char, char) {
|
||||||
('[', ']')
|
('[', ']')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn explain(&self, sql: &str) -> String {
|
||||||
|
sql.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn random(&self) -> String {
|
||||||
|
String::from(" RANDOM")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -5,21 +5,43 @@ use super::*;
|
|||||||
|
|
||||||
/// The struct implementing the `DatabaseDriver` trait
|
/// The struct implementing the `DatabaseDriver` trait
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct MySQL;
|
pub struct MySQLDriver;
|
||||||
|
|
||||||
impl MySQL {
|
impl MySQLDriver {
|
||||||
/// Create a MySQL driver
|
/// Create a MySQLDriver driver
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
MySQL {}
|
MySQLDriver {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DatabaseDriver for MySQL {
|
impl DatabaseDriver for MySQLDriver {
|
||||||
/// 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) {
|
||||||
('`', '`')
|
('`', '`')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)]
|
#[cfg(test)]
|
||||||
@ -28,7 +50,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_quote_identifier_backtick_quote() {
|
fn test_quote_identifier_backtick_quote() {
|
||||||
let driver = MySQL::new();
|
let driver = MySQLDriver::new();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
driver.quote_identifier("foo, bar, baz"),
|
driver.quote_identifier("foo, bar, baz"),
|
||||||
@ -42,7 +64,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_quote_identifiers_backtick_quote() {
|
fn test_quote_identifiers_backtick_quote() {
|
||||||
let driver = MySQL::new();
|
let driver = MySQLDriver::new();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
driver.quote_identifiers(vec![
|
driver.quote_identifiers(vec![
|
||||||
|
@ -5,13 +5,21 @@ use super::*;
|
|||||||
|
|
||||||
/// The struct implementing the `DatabaseDriver` trait
|
/// The struct implementing the `DatabaseDriver` trait
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Postgres;
|
pub struct PostgresDriver;
|
||||||
|
|
||||||
impl Postgres {
|
impl PostgresDriver {
|
||||||
/// Create a Postgres driver
|
/// Create a PostgresDriver driver
|
||||||
pub fn new() -> Self {
|
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
|
/// The struct implementing the `DatabaseDriver` trait
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SQLite;
|
pub struct SQLiteDriver;
|
||||||
|
|
||||||
impl SQLite {
|
impl SQLiteDriver {
|
||||||
/// Create an SQLite driver
|
/// Create an SQLiteDriver driver
|
||||||
pub fn new() -> Self {
|
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 {
|
pub mod prelude {
|
||||||
//! Re-exports important traits and types.
|
//! 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::enums::*;
|
||||||
pub use crate::drivers::{DatabaseDriver, DefaultDriver};
|
pub use crate::drivers::DatabaseDriver;
|
||||||
pub use crate::query_builder::QueryBuilder;
|
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
|
//! This main file is just for temparary testing
|
||||||
use stringqb::drivers::postgres::Postgres;
|
use stringqb::prelude::*;
|
||||||
use stringqb::query_builder::QueryBuilder;
|
|
||||||
// use stringqb::types::{SQLType, Type};
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut qb = QueryBuilder::new(Postgres::new());
|
let mut qb = QueryBuilder::new(PostgresDriver::new());
|
||||||
|
|
||||||
qb.set("foo", Box::new("bar"))
|
qb.set("foo", Box::new("bar"))
|
||||||
.set("bar", Box::new(12))
|
.set("bar", Box::new(12))
|
||||||
|
@ -53,6 +53,13 @@ impl QueryBuilder {
|
|||||||
///
|
///
|
||||||
/// // The query builder must be mutable to be useful
|
/// // The query builder must be mutable to be useful
|
||||||
/// let mut qb = QueryBuilder::new(DefaultDriver::new());
|
/// 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 {
|
pub fn new(driver: impl DatabaseDriver + 'static) -> Self {
|
||||||
QueryBuilder {
|
QueryBuilder {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use stringqb::query_builder::QueryBuilder;
|
use stringqb::prelude::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn minimal_select_query() {
|
fn minimal_select_query() {
|
||||||
@ -47,6 +47,26 @@ fn select_without_from() {
|
|||||||
qb.get_compiled_select();
|
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]
|
#[test]
|
||||||
fn basic_insert_query() {
|
fn basic_insert_query() {
|
||||||
let mut qb = QueryBuilder::default();
|
let mut qb = QueryBuilder::default();
|
||||||
|
Loading…
Reference in New Issue
Block a user