Regex and Integration tests
This commit is contained in:
parent
2e793284dd
commit
0b93246cc5
@ -7,6 +7,8 @@ categories = ["database"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
dotenv = "0.13.0"
|
dotenv = "0.13.0"
|
||||||
|
lazy_static = "1.3.0"
|
||||||
|
regex = "1.1.5"
|
||||||
serde_json = "1.0.39"
|
serde_json = "1.0.39"
|
||||||
|
|
||||||
[dependencies.pg]
|
[dependencies.pg]
|
||||||
|
@ -7,6 +7,9 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
#![allow(unused_variables)]
|
#![allow(unused_variables)]
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate lazy_static;
|
||||||
|
|
||||||
pub mod drivers;
|
pub mod drivers;
|
||||||
pub mod enums;
|
pub mod enums;
|
||||||
pub mod query_builder;
|
pub mod query_builder;
|
||||||
|
@ -10,6 +10,7 @@ use crate::enums::*;
|
|||||||
use crate::split_map_join;
|
use crate::split_map_join;
|
||||||
use crate::types::Wild;
|
use crate::types::Wild;
|
||||||
|
|
||||||
|
use regex::Regex;
|
||||||
use query_state::QueryState;
|
use query_state::QueryState;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -52,14 +53,23 @@ impl QueryBuilder {
|
|||||||
|
|
||||||
/// Set the fields to select from the database as a string
|
/// Set the fields to select from the database as a string
|
||||||
pub fn select(&mut self, fields: &str) -> &mut Self {
|
pub fn select(&mut self, fields: &str) -> &mut Self {
|
||||||
let fields = split_map_join(fields, ",", |s| s.trim().to_string());
|
lazy_static! {
|
||||||
|
static ref RE: Regex = Regex::new(r"(?i) as ").unwrap();
|
||||||
|
};
|
||||||
|
|
||||||
// Split identifiers on `As` keyword so they can be quoted properly
|
let fields = split_map_join(fields, ",", |s| {
|
||||||
// @TODO split identifiers on `as` keyword (needs to be case-insensitive)
|
if ! RE.is_match(s) {
|
||||||
|
return self.driver.quote_identifier(s.trim());
|
||||||
|
}
|
||||||
|
|
||||||
// Quote the identifiers (where there was an `as` keyword)
|
// Do a operation similar to split_map_join for the
|
||||||
|
// regex matches, quoting each identifier
|
||||||
// Rejoin those identifiers
|
RE.split(s)
|
||||||
|
.into_iter()
|
||||||
|
.map(|p| self.driver.quote_identifier(p))
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join(" as ")
|
||||||
|
});
|
||||||
|
|
||||||
self.state.append_select_string(&fields);
|
self.state.append_select_string(&fields);
|
||||||
|
|
||||||
@ -175,7 +185,8 @@ impl QueryBuilder {
|
|||||||
/// Set a key and value for an insert or update query
|
/// Set a key and value for an insert or update query
|
||||||
pub fn set(&mut self, key: &str, value: Wild) -> &mut Self {
|
pub fn set(&mut self, key: &str, value: Wild) -> &mut Self {
|
||||||
// @TODO figure a way to make this easier to use
|
// @TODO figure a way to make this easier to use
|
||||||
self.state.append_set_array_keys(key).append_values(value);
|
let key = self.driver.quote_identifier(key);
|
||||||
|
self.state.append_set_array_keys(&key).append_values(value);
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -538,7 +549,7 @@ mod tests {
|
|||||||
|
|
||||||
qb.set("foo", Box::new("bar"));
|
qb.set("foo", Box::new("bar"));
|
||||||
|
|
||||||
assert_eq!(qb.state.get_set_array_keys()[0], "foo");
|
assert_eq!(qb.state.get_set_array_keys()[0], "\"foo\"");
|
||||||
assert!(qb.state.get_values()[0].is::<&str>());
|
assert!(qb.state.get_values()[0].is::<&str>());
|
||||||
|
|
||||||
// @TODO find a way to make this kind of operation much more ergonomic
|
// @TODO find a way to make this kind of operation much more ergonomic
|
||||||
|
59
tests/integration_test.rs
Normal file
59
tests/integration_test.rs
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
use stringqb::query_builder::QueryBuilder;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn minimal_select_query() {
|
||||||
|
let mut qb = QueryBuilder::default();
|
||||||
|
|
||||||
|
let sql = qb.from("foo").get_compiled_select();
|
||||||
|
|
||||||
|
assert_eq!(sql, "SELECT *\nFROM \"foo\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn select_keys_as_query() {
|
||||||
|
let mut qb = QueryBuilder::default();
|
||||||
|
|
||||||
|
let sql = qb.select("foo as bar, baz").from("a").get_compiled_select();
|
||||||
|
|
||||||
|
assert_eq!(sql, "SELECT \"foo\" as \"bar\",\"baz\"\nFROM \"a\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn select_keys_query() {
|
||||||
|
let mut qb = QueryBuilder::default();
|
||||||
|
|
||||||
|
let sql = qb.select("a, b, c").from("foo").get_compiled_select();
|
||||||
|
|
||||||
|
assert_eq!(sql, "SELECT \"a\",\"b\",\"c\"\nFROM \"foo\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn select_vec_keys_query() {
|
||||||
|
let mut qb = QueryBuilder::default();
|
||||||
|
|
||||||
|
let sql = qb
|
||||||
|
.select_vec(vec!["a", "b", "c"])
|
||||||
|
.from("foo")
|
||||||
|
.get_compiled_select();
|
||||||
|
|
||||||
|
assert_eq!(sql, "SELECT \"a\",\"b\",\"c\"\nFROM \"foo\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn select_without_from() {
|
||||||
|
let qb = QueryBuilder::default();
|
||||||
|
|
||||||
|
qb.get_compiled_select();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn basic_insert_query() {
|
||||||
|
let mut qb = QueryBuilder::default();
|
||||||
|
|
||||||
|
qb.set("foo", Box::new("bar"));
|
||||||
|
|
||||||
|
let sql = qb.get_compiled_insert("foobar");
|
||||||
|
|
||||||
|
assert_eq!(sql, "INSERT INTO \"foobar\" (\"foo\")\nVALUES(?)");
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user