Integrate Query Parser
Integrate the query parser to allow filters to be provided to collection end points. Refactor the shared state to better encapsulate the model.
This commit is contained in:
1872
Cargo.lock
generated
1872
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -20,7 +20,7 @@ include = ["Cargo.toml", "README.md", "LICENSE", "ACKNOWLEDGEMENTS", "src/**/*.r
|
||||
|
||||
[dependencies]
|
||||
mercator_db = "^0.1"
|
||||
#mercator_parser = "^0.1"
|
||||
mercator_parser = "^0.1"
|
||||
|
||||
actix = "^0.7"
|
||||
actix-web = "^0.7"
|
||||
|
||||
@@ -70,8 +70,8 @@ paths:
|
||||
summary: >
|
||||
Retrieve a list of space definition names.
|
||||
operationId: post_spaces
|
||||
# parameters:
|
||||
# - $ref: '#/parameters/Filters'
|
||||
parameters:
|
||||
- $ref: '#/parameters/Filters'
|
||||
responses:
|
||||
'200':
|
||||
$ref: '#/responses/ArrayOfStrings'
|
||||
@@ -204,8 +204,8 @@ paths:
|
||||
summary: >
|
||||
Retrieve a list of core names.
|
||||
operationId: post_cores
|
||||
# parameters:
|
||||
# - $ref: '#/parameters/Filters'
|
||||
parameters:
|
||||
- $ref: '#/parameters/Filters'
|
||||
responses:
|
||||
'200':
|
||||
$ref: '#/responses/ArrayOfStrings'
|
||||
@@ -356,8 +356,8 @@ paths:
|
||||
summary: >
|
||||
Retrieve a list of spatial object.
|
||||
operationId: post_spatial_objects
|
||||
# parameters:
|
||||
# - $ref: '#/parameters/Filters'
|
||||
parameters:
|
||||
- $ref: '#/parameters/Filters'
|
||||
responses:
|
||||
'200':
|
||||
$ref: '#/responses/ArrayOfStrings'
|
||||
@@ -667,6 +667,7 @@ parameters:
|
||||
Filters:
|
||||
name: filters
|
||||
in: body
|
||||
required: false
|
||||
description: >
|
||||
Filter string to use to select the data.
|
||||
|
||||
|
||||
35
src/main.rs
35
src/main.rs
@@ -5,6 +5,7 @@ extern crate measure_time;
|
||||
extern crate serde_derive;
|
||||
|
||||
mod rest_api;
|
||||
mod shared_state;
|
||||
|
||||
use std::process::exit;
|
||||
use std::sync::Arc;
|
||||
@@ -14,7 +15,7 @@ use mercator_db::json::model;
|
||||
use mercator_db::json::storage;
|
||||
use mercator_db::DataBase;
|
||||
|
||||
pub type SharedState = DataBase;
|
||||
use shared_state::SharedState;
|
||||
|
||||
/*
|
||||
fn into_bool(string: &str) -> bool {
|
||||
@@ -126,48 +127,20 @@ fn main() {
|
||||
}
|
||||
};
|
||||
|
||||
// Convert to binary the JSON data:
|
||||
if true {
|
||||
info_time!("Converting to binary JSON data");
|
||||
storage::convert(&import);
|
||||
}
|
||||
|
||||
// Build a Database Index:
|
||||
if true {
|
||||
info_time!("Building database index");
|
||||
storage::build(&import);
|
||||
}
|
||||
|
||||
// Load a Database:
|
||||
{
|
||||
info_time!("Loading database index");
|
||||
db = DataBase::load(&import).unwrap();
|
||||
}
|
||||
/*
|
||||
let core = db.core(&import).unwrap();
|
||||
|
||||
let space = db.space("std").unwrap();
|
||||
let lower = space.encode(&[0.2, 0.2, 0.2]).unwrap();
|
||||
let higher = space.encode(&[0.8, 0.8, 0.8]).unwrap();
|
||||
|
||||
let shape = Shape::BoundingBox(lower.clone(), higher.clone());
|
||||
let r;
|
||||
{
|
||||
info_time!("Query by box {:?} - {:?}", lower, higher);
|
||||
r = core.get_by_shape(&shape, 0.0).unwrap();
|
||||
}
|
||||
|
||||
println!("get_by_shape {:?}: {}", shape, r.len());
|
||||
println!("{:?}: {:?}\n", shape, r[0]);
|
||||
*/
|
||||
// END of Temporary bloc
|
||||
}
|
||||
let state = SharedState::new(db);
|
||||
|
||||
rest_api::run(
|
||||
hostname,
|
||||
port,
|
||||
base,
|
||||
allowed_origins,
|
||||
Arc::new(RwLock::new(db)),
|
||||
Arc::new(RwLock::new(state)),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
use actix_web::HttpRequest;
|
||||
use actix_web::HttpResponse;
|
||||
use actix_web::Json;
|
||||
|
||||
use super::error_400;
|
||||
use super::AppState;
|
||||
use super::Filters;
|
||||
use super::StringOrStaticFileResult;
|
||||
|
||||
pub fn health(_req: &HttpRequest<AppState>) -> HttpResponse {
|
||||
HttpResponse::Ok().finish()
|
||||
}
|
||||
|
||||
pub fn query(_req: &HttpRequest<AppState>) -> StringOrStaticFileResult {
|
||||
pub fn query(
|
||||
(_parameters, _state): (Option<Json<Filters>>, HttpRequest<AppState>),
|
||||
) -> StringOrStaticFileResult {
|
||||
trace!("query Triggered!");
|
||||
error_400()
|
||||
}
|
||||
|
||||
@@ -1,27 +1,23 @@
|
||||
use actix_web::HttpRequest;
|
||||
use actix_web::Json;
|
||||
use actix_web::Path;
|
||||
|
||||
use super::error_400;
|
||||
use super::error_404;
|
||||
use super::ok_200;
|
||||
use super::AppState;
|
||||
use super::StringOrStaticFileResult;
|
||||
|
||||
use actix_web::HttpRequest;
|
||||
use actix_web::Path;
|
||||
|
||||
/*
|
||||
pub fn post(_req: &HttpRequest<AppState>) -> StringOrStaticFileResult {
|
||||
trace!("POST Triggered!");
|
||||
error_400()
|
||||
}
|
||||
*/
|
||||
|
||||
#[derive(Clone, Deserialize, Serialize)]
|
||||
struct Core {
|
||||
pub struct Core {
|
||||
name: String,
|
||||
version: String,
|
||||
scales: Vec<Vec<i32>>,
|
||||
}
|
||||
|
||||
pub fn put((_path, _state): (Path<String>, HttpRequest<AppState>)) -> StringOrStaticFileResult {
|
||||
pub fn put(
|
||||
(_path, _core, _state): (Path<String>, Json<Core>, HttpRequest<AppState>),
|
||||
) -> StringOrStaticFileResult {
|
||||
trace!("PUT Triggered!");
|
||||
error_400()
|
||||
}
|
||||
@@ -29,9 +25,9 @@ pub fn put((_path, _state): (Path<String>, HttpRequest<AppState>)) -> StringOrSt
|
||||
pub fn get((core, state): (Path<String>, HttpRequest<AppState>)) -> StringOrStaticFileResult {
|
||||
trace!("GET Triggered!");
|
||||
let core = core.to_string();
|
||||
let db = state.state().shared.read().unwrap();
|
||||
let context = state.state().shared.read().unwrap();
|
||||
|
||||
match db.core(core) {
|
||||
match context.db().core(core) {
|
||||
Ok(core) => ok_200(&Core {
|
||||
name: core.name().clone(),
|
||||
version: core.version().clone(),
|
||||
@@ -43,7 +39,9 @@ pub fn get((core, state): (Path<String>, HttpRequest<AppState>)) -> StringOrStat
|
||||
}
|
||||
}
|
||||
|
||||
pub fn patch((_path, _state): (Path<String>, HttpRequest<AppState>)) -> StringOrStaticFileResult {
|
||||
pub fn patch(
|
||||
(_path, _core, _state): (Path<String>, Json<Core>, HttpRequest<AppState>),
|
||||
) -> StringOrStaticFileResult {
|
||||
trace!("PATCH Triggered!");
|
||||
error_400()
|
||||
}
|
||||
|
||||
@@ -1,34 +1,55 @@
|
||||
use actix_web::HttpRequest;
|
||||
use actix_web::Json;
|
||||
|
||||
use super::error_400;
|
||||
use super::ok_200;
|
||||
use super::AppState;
|
||||
use super::Filters;
|
||||
use super::StringOrStaticFileResult;
|
||||
|
||||
pub fn post(state: &HttpRequest<AppState>) -> StringOrStaticFileResult {
|
||||
pub fn post(
|
||||
(parameters, state): (Option<Json<Filters>>, HttpRequest<AppState>),
|
||||
) -> StringOrStaticFileResult {
|
||||
trace!("POST Triggered!");
|
||||
let db = state.state().shared.read().unwrap();
|
||||
let context = state.state().shared.read().unwrap();
|
||||
let parameters = Filters::get(parameters);
|
||||
|
||||
ok_200(db.core_keys())
|
||||
let mut results = match parameters.filters {
|
||||
None => context.db().core_keys().clone(),
|
||||
Some(filter) => context
|
||||
.db()
|
||||
.core_keys()
|
||||
.iter()
|
||||
.filter_map(|core| match context.filter(&filter, core, None, None) {
|
||||
Err(_) => None, //FIXME: Return errors here instead!!
|
||||
Ok(_) => Some(core.to_string()),
|
||||
})
|
||||
.collect(),
|
||||
};
|
||||
|
||||
results.sort_unstable();
|
||||
results.dedup();
|
||||
|
||||
ok_200(&results)
|
||||
}
|
||||
|
||||
pub fn put(_state: &HttpRequest<AppState>) -> StringOrStaticFileResult {
|
||||
pub fn put(
|
||||
(_parameters, _state): (Option<Json<Filters>>, HttpRequest<AppState>),
|
||||
) -> StringOrStaticFileResult {
|
||||
trace!("PUT Triggered!");
|
||||
error_400()
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn get(_state: &HttpRequest<AppState>) -> StringOrStaticFileResult {
|
||||
trace!("GET Triggered!");
|
||||
error400()
|
||||
}*/
|
||||
|
||||
pub fn patch(_state: &HttpRequest<AppState>) -> StringOrStaticFileResult {
|
||||
pub fn patch(
|
||||
(_parameters, _state): (Option<Json<Filters>>, HttpRequest<AppState>),
|
||||
) -> StringOrStaticFileResult {
|
||||
trace!("PATCH Triggered!");
|
||||
error_400()
|
||||
}
|
||||
|
||||
pub fn delete(_state: &HttpRequest<AppState>) -> StringOrStaticFileResult {
|
||||
pub fn delete(
|
||||
(_parameters, _state): (Option<Json<Filters>>, HttpRequest<AppState>),
|
||||
) -> StringOrStaticFileResult {
|
||||
trace!("DELETE Triggered!");
|
||||
error_400()
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ use actix_web::fs;
|
||||
use actix_web::http;
|
||||
use actix_web::http::Method;
|
||||
use actix_web::http::StatusCode;
|
||||
use actix_web::middleware;
|
||||
use actix_web::middleware::cors::Cors;
|
||||
use actix_web::pred;
|
||||
use actix_web::server;
|
||||
@@ -25,6 +26,7 @@ use actix_web::server::HttpHandler;
|
||||
use actix_web::server::HttpHandlerTask;
|
||||
use actix_web::App;
|
||||
use actix_web::Either;
|
||||
use actix_web::Json;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::SharedState;
|
||||
@@ -34,21 +36,25 @@ pub struct AppState {
|
||||
shared: Arc<RwLock<SharedState>>,
|
||||
}
|
||||
|
||||
/* EXAMPLE FOR STATE USAGE
|
||||
// simple handle
|
||||
fn index(req: &HttpRequest<AppState>) -> HttpResponse {
|
||||
println!("{:?}", req);
|
||||
{
|
||||
// So that we release ASAP the exclusive lock.
|
||||
*(req.state().shared.write().unwrap()) += 1;
|
||||
}
|
||||
|
||||
HttpResponse::BadRequest().body(format!(
|
||||
"Num of requests: {}",
|
||||
req.state().shared.read().unwrap()
|
||||
))
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct Filters {
|
||||
filters: Option<String>,
|
||||
ids_only: Option<bool>,
|
||||
}
|
||||
|
||||
impl Filters {
|
||||
pub fn get(parameters: Option<Json<Filters>>) -> Self {
|
||||
trace!("PARAMETERS {:#?}", parameters);
|
||||
|
||||
match parameters {
|
||||
None => Filters {
|
||||
filters: None,
|
||||
ids_only: Some(true),
|
||||
},
|
||||
Some(p) => p.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
type StringOrStaticFileResult = Either<String, fs::NamedFile>;
|
||||
|
||||
@@ -120,19 +126,19 @@ where
|
||||
cors.allowed_methods(vec!["GET", "POST", "UPDATE", "PATCH", "DELETE", "OPTIONS"])
|
||||
.allowed_headers(vec![http::header::AUTHORIZATION, http::header::ACCEPT])
|
||||
.allowed_header(http::header::CONTENT_TYPE)
|
||||
.max_age(60)
|
||||
.max_age(600)
|
||||
.resource("/queries", |r| {
|
||||
r.method(Method::POST).f(actions::query);
|
||||
r.method(Method::POST).with(actions::query);
|
||||
r.route()
|
||||
.filter(pred::Not(pred::Post()))
|
||||
.f(default::page_400);
|
||||
})
|
||||
// SPACES -------------------------------------------------------------------
|
||||
.resource("/spaces", |r| {
|
||||
r.method(Method::POST).f(spaces::post);
|
||||
r.method(Method::PUT).f(spaces::put);
|
||||
r.method(Method::PATCH).f(spaces::patch);
|
||||
r.method(Method::DELETE).f(spaces::delete);
|
||||
r.method(Method::POST).with(spaces::post);
|
||||
r.method(Method::PUT).with(spaces::put);
|
||||
r.method(Method::PATCH).with(spaces::patch);
|
||||
r.method(Method::DELETE).with(spaces::delete);
|
||||
})
|
||||
.resource("/spaces/{name}", |r| {
|
||||
r.method(Method::PUT).with(space::put);
|
||||
@@ -142,10 +148,10 @@ where
|
||||
})
|
||||
// DATASETS -------------------------------------------------------------------
|
||||
.resource("/cores", |r| {
|
||||
r.method(Method::POST).f(&cores::post);
|
||||
r.method(Method::PUT).f(&cores::put);
|
||||
r.method(Method::PATCH).f(&cores::patch);
|
||||
r.method(Method::DELETE).f(&cores::delete);
|
||||
r.method(Method::POST).with(&cores::post);
|
||||
r.method(Method::PUT).with(&cores::put);
|
||||
r.method(Method::PATCH).with(&cores::patch);
|
||||
r.method(Method::DELETE).with(&cores::delete);
|
||||
})
|
||||
.resource("/cores/{name}", |r| {
|
||||
r.method(Method::PUT).with(core::put);
|
||||
|
||||
@@ -9,13 +9,6 @@ use super::ok_200;
|
||||
use super::AppState;
|
||||
use super::StringOrStaticFileResult;
|
||||
|
||||
/*
|
||||
pub fn post(_req: &HttpRequest<AppState>) ->StringOrStaticFileResult {
|
||||
info!("POST Triggered!");
|
||||
error_400()
|
||||
}
|
||||
*/
|
||||
|
||||
pub fn put((path, _state): (Path<String>, HttpRequest<AppState>)) -> StringOrStaticFileResult {
|
||||
trace!("PUT Triggered on {}", path);
|
||||
error_400()
|
||||
@@ -24,9 +17,9 @@ pub fn put((path, _state): (Path<String>, HttpRequest<AppState>)) -> StringOrSta
|
||||
pub fn get((path, state): (Path<String>, HttpRequest<AppState>)) -> StringOrStaticFileResult {
|
||||
trace!("GET Triggered on '{}'", path);
|
||||
let name = path.to_string();
|
||||
let db = state.state().shared.read().unwrap();
|
||||
let context = state.state().shared.read().unwrap();
|
||||
|
||||
match db.space(name) {
|
||||
match context.db().space(name) {
|
||||
Ok(space) => {
|
||||
let space: model::Space = space.into();
|
||||
ok_200(&space)
|
||||
|
||||
@@ -1,34 +1,59 @@
|
||||
use actix_web::HttpRequest;
|
||||
use actix_web::Json;
|
||||
|
||||
use super::error_400;
|
||||
use super::ok_200;
|
||||
use super::AppState;
|
||||
use super::Filters;
|
||||
use super::StringOrStaticFileResult;
|
||||
|
||||
pub fn post(state: &HttpRequest<AppState>) -> StringOrStaticFileResult {
|
||||
pub fn post(
|
||||
(parameters, state): (Option<Json<Filters>>, HttpRequest<AppState>),
|
||||
) -> StringOrStaticFileResult {
|
||||
trace!("POST Triggered!");
|
||||
let db = state.state().shared.read().unwrap();
|
||||
let context = state.state().shared.read().unwrap();
|
||||
let parameters = Filters::get(parameters);
|
||||
|
||||
ok_200(db.space_keys())
|
||||
let mut results = match parameters.filters {
|
||||
None => context.db().space_keys().clone(),
|
||||
Some(filter) => context
|
||||
.db()
|
||||
.core_keys()
|
||||
.iter()
|
||||
.flat_map(|core| match context.filter(&filter, core, None, None) {
|
||||
Err(_) => vec![], //FIXME: Return errors here instead!!
|
||||
Ok(r) => {
|
||||
let mut r = r.into_iter().map(|o| o.space_id).collect::<Vec<_>>();
|
||||
r.sort_unstable();
|
||||
r.dedup();
|
||||
r
|
||||
}
|
||||
})
|
||||
.collect(),
|
||||
};
|
||||
results.sort_unstable();
|
||||
results.dedup();
|
||||
|
||||
ok_200(&results)
|
||||
}
|
||||
|
||||
pub fn put(_state: &HttpRequest<AppState>) -> StringOrStaticFileResult {
|
||||
pub fn put(
|
||||
(_parameters, _state): (Option<Json<Filters>>, HttpRequest<AppState>),
|
||||
) -> StringOrStaticFileResult {
|
||||
trace!("PUT Triggered!");
|
||||
error_400()
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn get(_state: &HttpRequest<AppState>) -> StringOrStaticFileResult {
|
||||
trace!("GET Triggered!");
|
||||
error_400()
|
||||
}*/
|
||||
|
||||
pub fn patch(_state: &HttpRequest<AppState>) -> StringOrStaticFileResult {
|
||||
pub fn patch(
|
||||
(_parameters, _state): (Option<Json<Filters>>, HttpRequest<AppState>),
|
||||
) -> StringOrStaticFileResult {
|
||||
trace!("PATCH Triggered!");
|
||||
error_400()
|
||||
}
|
||||
|
||||
pub fn delete(_state: &HttpRequest<AppState>) -> StringOrStaticFileResult {
|
||||
pub fn delete(
|
||||
(_parameters, _state): (Option<Json<Filters>>, HttpRequest<AppState>),
|
||||
) -> StringOrStaticFileResult {
|
||||
trace!("DELETE Triggered!");
|
||||
error_400()
|
||||
}
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
use actix_web::HttpRequest;
|
||||
use actix_web::Json;
|
||||
use actix_web::Path;
|
||||
|
||||
use super::error_400;
|
||||
use super::error_404;
|
||||
use super::ok_200;
|
||||
@@ -5,16 +9,6 @@ use super::AppState;
|
||||
use super::StringOrStaticFileResult;
|
||||
use crate::model::to_spatial_objects;
|
||||
|
||||
use actix_web::HttpRequest;
|
||||
use actix_web::Path;
|
||||
|
||||
/*
|
||||
pub fn post((_path, _state): (Path<String>, HttpRequest<AppState>)) -> StringOrStaticFileResult {
|
||||
info!("POST Triggered!");
|
||||
error_400()
|
||||
}
|
||||
*/
|
||||
|
||||
pub fn put(
|
||||
(core, id, state): (Path<String>, Path<String>, HttpRequest<AppState>),
|
||||
) -> StringOrStaticFileResult {
|
||||
@@ -29,11 +23,12 @@ pub fn get(
|
||||
let (core, id) = path.into_inner();
|
||||
let core = core.to_string();
|
||||
let id = id.to_string();
|
||||
let db = state.state().shared.read().unwrap();
|
||||
let context = state.state().shared.read().unwrap();
|
||||
let db = context.db();
|
||||
|
||||
match db.core(core) {
|
||||
Ok(core) => match core.get_by_id(&db, &id, None, 0.0) {
|
||||
Ok(objects) => ok_200(&to_spatial_objects(&db, objects)),
|
||||
Ok(core) => match core.get_by_id(db, &id, None, 0.0) {
|
||||
Ok(objects) => ok_200(&to_spatial_objects(db, objects)),
|
||||
Err(_) => error_404(),
|
||||
},
|
||||
Err(_) => error_404(),
|
||||
|
||||
@@ -1,23 +1,37 @@
|
||||
use actix_web::HttpRequest;
|
||||
use actix_web::Json;
|
||||
use actix_web::Path;
|
||||
|
||||
use super::error_400;
|
||||
use super::error_404;
|
||||
use super::ok_200;
|
||||
use super::AppState;
|
||||
use super::Filters;
|
||||
use super::StringOrStaticFileResult;
|
||||
|
||||
pub fn post((core, state): (Path<String>, HttpRequest<AppState>)) -> StringOrStaticFileResult {
|
||||
pub fn post(
|
||||
(core_id, parameters, state): (Path<String>, Option<Json<Filters>>, HttpRequest<AppState>),
|
||||
) -> StringOrStaticFileResult {
|
||||
trace!("POST Triggered!");
|
||||
let core = core.to_string();
|
||||
let db = state.state().shared.read().unwrap();
|
||||
let core = core_id.to_string();
|
||||
let context = state.state().shared.read().unwrap();
|
||||
|
||||
match db.core(core) {
|
||||
match context.db().core(core) {
|
||||
Ok(core) => {
|
||||
// Generate a list of oid.
|
||||
let v: Vec<&String> = core.keys().iter().map(|o| o.id()).collect();
|
||||
let parameters = Filters::get(parameters);
|
||||
|
||||
ok_200(&v)
|
||||
// Generate a list of oid.
|
||||
let mut results = match parameters.filters {
|
||||
None => core.keys().iter().map(|o| o.id().clone()).collect(),
|
||||
Some(filter) => match context.filter(&filter, &core_id, None, None) {
|
||||
Err(_) => vec![], //FIXME: Return errors here instead!!
|
||||
Ok(objects) => objects.iter().map(|o| o.value.id().clone()).collect(),
|
||||
},
|
||||
};
|
||||
results.sort_unstable();
|
||||
results.dedup();
|
||||
|
||||
ok_200(&results)
|
||||
}
|
||||
Err(_) => error_404(),
|
||||
}
|
||||
@@ -28,12 +42,6 @@ pub fn put((_path, _state): (Path<String>, HttpRequest<AppState>)) -> StringOrSt
|
||||
error_400()
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn get((_path, _state): (Path<String>, HttpRequest<AppState>)) -> StringOrStaticFileResult {
|
||||
trace!("GET Triggered!");
|
||||
error400()
|
||||
*/
|
||||
|
||||
pub fn patch((_path, _state): (Path<String>, HttpRequest<AppState>)) -> StringOrStaticFileResult {
|
||||
trace!("PATCH Triggered!");
|
||||
error_400()
|
||||
|
||||
134
src/shared_state.rs
Normal file
134
src/shared_state.rs
Normal file
@@ -0,0 +1,134 @@
|
||||
use mercator_db::DataBase;
|
||||
use parser::Executor;
|
||||
use parser::FiltersParser;
|
||||
use parser::QueryParser;
|
||||
use parser::Validator;
|
||||
|
||||
pub struct SharedState {
|
||||
db: DataBase,
|
||||
query_parser: QueryParser,
|
||||
filter_parser: FiltersParser,
|
||||
}
|
||||
|
||||
impl SharedState {
|
||||
pub fn new(db: DataBase) -> Self {
|
||||
SharedState {
|
||||
db,
|
||||
query_parser: QueryParser::new(),
|
||||
filter_parser: FiltersParser::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn db(&self) -> &DataBase {
|
||||
&self.db
|
||||
}
|
||||
|
||||
pub fn filter_parser(&self) -> &FiltersParser {
|
||||
&self.filter_parser
|
||||
}
|
||||
|
||||
pub fn query_parser(&self) -> &QueryParser {
|
||||
&self.query_parser
|
||||
}
|
||||
|
||||
pub fn filter(
|
||||
&self,
|
||||
input: &str,
|
||||
core: &str,
|
||||
output_space: Option<&str>,
|
||||
threshold_volume: Option<f64>,
|
||||
) -> mercator_db::ResultSet {
|
||||
let parser = self.filter_parser();
|
||||
let parse;
|
||||
|
||||
// Parse Input
|
||||
{
|
||||
info_time!("Parsing");
|
||||
parse = parser.parse(input);
|
||||
}
|
||||
match parse {
|
||||
Err(e) => {
|
||||
debug!("Parsing failed: \n{:?}", e);
|
||||
Err(format!("{}", e))
|
||||
}
|
||||
Ok(tree) => {
|
||||
let validation;
|
||||
let execution;
|
||||
|
||||
// Check type coherence & validate tree
|
||||
{
|
||||
info_time!("Type check");
|
||||
validation = tree.validate();
|
||||
}
|
||||
if validation.is_err() {
|
||||
debug!("Type check failed");
|
||||
return Err("Type check failed".to_string());
|
||||
}
|
||||
|
||||
// Execute filter.
|
||||
{
|
||||
info_time!("Execution");
|
||||
execution = tree.execute(self.db(), core, output_space, threshold_volume);
|
||||
}
|
||||
match execution {
|
||||
Err(e) => {
|
||||
debug!("Parsing failed: \n{:?}", e);
|
||||
Err(e.to_string())
|
||||
}
|
||||
results @ Ok(_) => results,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn query(
|
||||
&self,
|
||||
input: &str,
|
||||
core: &str,
|
||||
output_space: Option<&str>,
|
||||
threshold_volume: Option<f64>,
|
||||
) -> mercator_db::ResultSet {
|
||||
let parser = self.query_parser();
|
||||
let parse;
|
||||
|
||||
// Parse Input
|
||||
{
|
||||
info_time!("Parsing");
|
||||
parse = parser.parse(input);
|
||||
}
|
||||
match parse {
|
||||
Err(e) => {
|
||||
debug!("Parsing failed: \n{:?}", e);
|
||||
Err(e.to_string())
|
||||
}
|
||||
Ok(None) => Ok(vec![]),
|
||||
Ok(Some(tree)) => {
|
||||
let validation;
|
||||
let execution;
|
||||
|
||||
// Check type coherence & validate tree
|
||||
{
|
||||
info_time!("Type check");
|
||||
validation = tree.validate();
|
||||
}
|
||||
if validation.is_err() {
|
||||
debug!("Type check failed");
|
||||
return Err("Type check failed".to_string());
|
||||
}
|
||||
|
||||
// Execute filter.
|
||||
{
|
||||
info_time!("Execution");
|
||||
execution = tree.execute(self.db(), core, output_space, threshold_volume);
|
||||
}
|
||||
match execution {
|
||||
Err(e) => {
|
||||
debug!("Parsing failed: \n{:?}", e);
|
||||
Err(e.to_string())
|
||||
}
|
||||
results @ Ok(_) => results,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user