Add a rudimentary SQL builder, based on parts of Diesel. (#273) r=nalexander
https://github.com/diesel-rs/diesel/
This commit is contained in:
parent
bc2b2ec4c8
commit
f890995202
4 changed files with 92 additions and 0 deletions
|
@ -35,6 +35,9 @@ path = "parser-utils"
|
|||
[dependencies.mentat_core]
|
||||
path = "core"
|
||||
|
||||
[dependencies.mentat_sql]
|
||||
path = "sql"
|
||||
|
||||
[dependencies.mentat_db]
|
||||
path = "db"
|
||||
|
||||
|
|
3
sql/Cargo.toml
Normal file
3
sql/Cargo.toml
Normal file
|
@ -0,0 +1,3 @@
|
|||
[package]
|
||||
name = "mentat_sql"
|
||||
version = "0.0.1"
|
7
sql/README.md
Normal file
7
sql/README.md
Normal file
|
@ -0,0 +1,7 @@
|
|||
This is a tiny SQL query builder.
|
||||
|
||||
The majority of this code was distilled from QueryBuilder in Diesel:
|
||||
|
||||
https://github.com/diesel-rs/diesel/
|
||||
|
||||
used under the Apache 2.0 license.
|
79
sql/src/lib.rs
Normal file
79
sql/src/lib.rs
Normal file
|
@ -0,0 +1,79 @@
|
|||
// Copyright 2016 Mozilla
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
||||
// this file except in compliance with the License. You may obtain a copy of the
|
||||
// License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software distributed
|
||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
use std::error::Error;
|
||||
|
||||
pub type BuildQueryError = Box<Error + Send + Sync>;
|
||||
pub type BuildQueryResult = Result<(), BuildQueryError>;
|
||||
|
||||
/// Gratefully based on Diesel's QueryBuilder trait:
|
||||
/// https://github.com/diesel-rs/diesel/blob/4885f61b8205f7f3c2cfa03837ed6714831abe6b/diesel/src/query_builder/mod.rs#L56
|
||||
pub trait QueryBuilder {
|
||||
fn push_sql(&mut self, sql: &str);
|
||||
fn push_identifier(&mut self, identifier: &str) -> BuildQueryResult;
|
||||
fn push_bind_param(&mut self);
|
||||
fn finish(self) -> String;
|
||||
}
|
||||
|
||||
pub trait QueryFragment {
|
||||
fn push_sql(&self, out: &mut QueryBuilder) -> BuildQueryResult;
|
||||
}
|
||||
|
||||
impl QueryFragment for Box<QueryFragment> {
|
||||
fn push_sql(&self, out: &mut QueryBuilder) -> BuildQueryResult {
|
||||
QueryFragment::push_sql(&**self, out)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> QueryFragment for &'a QueryFragment {
|
||||
fn push_sql(&self, out: &mut QueryBuilder) -> BuildQueryResult {
|
||||
QueryFragment::push_sql(&**self, out)
|
||||
}
|
||||
}
|
||||
|
||||
impl QueryFragment for () {
|
||||
fn push_sql(&self, _out: &mut QueryBuilder) -> BuildQueryResult {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// A QueryBuilder that implements SQLite's specific escaping rules.
|
||||
pub struct SQLiteQueryBuilder {
|
||||
pub sql: String,
|
||||
}
|
||||
|
||||
impl SQLiteQueryBuilder {
|
||||
pub fn new() -> Self {
|
||||
SQLiteQueryBuilder {
|
||||
sql: String::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl QueryBuilder for SQLiteQueryBuilder {
|
||||
fn push_sql(&mut self, sql: &str) {
|
||||
self.sql.push_str(sql);
|
||||
}
|
||||
|
||||
fn push_identifier(&mut self, identifier: &str) -> BuildQueryResult {
|
||||
self.push_sql("`");
|
||||
self.push_sql(&identifier.replace("`", "``"));
|
||||
self.push_sql("`");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn push_bind_param(&mut self) {
|
||||
self.push_sql("?");
|
||||
}
|
||||
|
||||
fn finish(self) -> String {
|
||||
self.sql
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue