diff --git a/db/src/lib.rs b/db/src/lib.rs index c1e3225c..463e5bd0 100644 --- a/db/src/lib.rs +++ b/db/src/lib.rs @@ -35,8 +35,11 @@ mod schema; mod types; mod values; +pub use types::DB; + use edn::symbols; +// TODO: replace with sqlite3_limit. #288. pub const SQLITE_MAX_VARIABLE_NUMBER: usize = 999; pub fn to_namespaced_keyword(s: &str) -> Option { diff --git a/query-parser/src/find.rs b/query-parser/src/find.rs index 3f5c6667..5a35f7f9 100644 --- a/query-parser/src/find.rs +++ b/query-parser/src/find.rs @@ -158,6 +158,17 @@ fn parse_find_edn_map(map: BTreeMap) -> QueryParseResult parse_find_map(m) } +impl From for QueryParseError { + fn from(err: edn::parse::ParseError) -> QueryParseError { + QueryParseError::EdnParseError(err) + } +} + +pub fn parse_find_string(string: &str) -> QueryParseResult { + let expr = edn::parse::value(string)?; + parse_find(expr) +} + pub fn parse_find(expr: edn::Value) -> QueryParseResult { // No `match` because scoping and use of `expr` in error handling is nuts. if let edn::Value::Map(m) = expr { diff --git a/query-parser/src/lib.rs b/query-parser/src/lib.rs index fcf24ba3..ed0ee048 100644 --- a/query-parser/src/lib.rs +++ b/query-parser/src/lib.rs @@ -17,3 +17,16 @@ extern crate mentat_parser_utils; mod util; mod parse; pub mod find; + +pub use find::{ + parse_find, + parse_find_string, +}; + +pub use parse::{ + QueryParseResult, + QueryParseError, + FindParseError, + WhereParseError, + NotAVariableError, +}; diff --git a/query-parser/src/parse.rs b/query-parser/src/parse.rs index 78b789e2..7312b306 100644 --- a/query-parser/src/parse.rs +++ b/query-parser/src/parse.rs @@ -54,12 +54,6 @@ pub enum QueryParseError { WithParseError(NotAVariableError), } -impl From for QueryParseError { - fn from(err: edn::parse::ParseError) -> QueryParseError { - QueryParseError::EdnParseError(err) - } -} - impl From for QueryParseError { fn from(err: WhereParseError) -> QueryParseError { QueryParseError::WhereParseError(err) diff --git a/src/lib.rs b/src/lib.rs index 449b4ce5..643adf6c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,14 +13,18 @@ extern crate slog; #[macro_use] extern crate slog_scope; +extern crate rusqlite; + extern crate edn; +extern crate mentat_core; +extern crate mentat_db; extern crate mentat_query; extern crate mentat_query_parser; -extern crate rusqlite; use rusqlite::Connection; pub mod ident; +pub mod query; pub fn get_name() -> String { info!("Called into mentat library"; "fn" => "get_name"); diff --git a/src/query.rs b/src/query.rs new file mode 100644 index 00000000..bccc3134 --- /dev/null +++ b/src/query.rs @@ -0,0 +1,60 @@ +// 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::collections::HashMap; + +use mentat_core::{ + TypedValue, +}; + +use mentat_db::DB; + +use mentat_query_parser::{ + parse_find_string, + QueryParseError, +}; + +// TODO +pub type SQLiteConnection = (); + +pub enum QueryResults { + Scalar(Option), + Tuple(Vec), + Coll(Vec), + Rel(Vec>), +} + +pub enum QueryExecutionError { + ParseError(QueryParseError), + InvalidArgumentName(String), +} + +impl From for QueryExecutionError { + fn from(err: QueryParseError) -> QueryExecutionError { + QueryExecutionError::ParseError(err) + } +} + +pub type QueryExecutionResult = Result; + +/// Take an EDN query string, a reference to a open SQLite connection, a Mentat DB, and an optional +/// collection of input bindings (which should be keyed by `"?varname"`), and execute the query +/// immediately, blocking the current thread. +/// Returns a structure that corresponds to the kind of input query, populated with `TypedValue` +/// instances. +#[allow(unused_variables)] +pub fn q_once(sqlite: SQLiteConnection, + db: DB, + query: &str, + inputs: Option>) -> QueryExecutionResult { + // TODO: validate inputs. + let parsed = parse_find_string(query)?; + Ok(QueryResults::Scalar(Some(TypedValue::Boolean(true)))) +}