Skip to content

Commit

Permalink
change over to new API (cleanup still needed - this branch is still a…
Browse files Browse the repository at this point in the history
… WIP)
  • Loading branch information
lmcmicu committed Jan 23, 2024
1 parent 2dc13cc commit 4145315
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 450 deletions.
188 changes: 47 additions & 141 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,21 @@
use indexmap::map::IndexMap;
use ontodev_valve::{
get_compiled_datatype_conditions, get_compiled_rule_conditions,
get_parsed_structure_conditions, valve_grammar::StartParser, valve_old, ColumnRule,
CompiledCondition, ParsedStructure, ValveCommandOld,
Valve,
};
use ontodev_valve::Valve;
use serde::{Deserialize, Serialize};
use serde_json::Value as SerdeValue;
use sqlx::{
any::{AnyConnectOptions, AnyKind, AnyPool, AnyPoolOptions},
query as sqlx_query,
};
use std::{collections::HashMap, fmt, fs, path::Path, str::FromStr};
use sqlx::any::AnyPool;
use std::{fmt, fs, path::Path};
use toml;

#[derive(Clone, Debug)]
pub struct Config {
pub config_version: u16,
pub port: u16,
pub logging_level: LoggingLevel,
pub connection: String,
pub pool: Option<AnyPool>,
pub valve_old: Option<ValveConfigOld>,
pub valve: Option<Valve>,
pub valve: Valve,
pub valve_path: String,
pub valve_create_only: bool,
pub connection: String,
pub pool: AnyPool,
pub asset_path: Option<String>,
pub template_path: Option<String>,
pub actions: IndexMap<String, ActionConfig>,
Expand All @@ -43,28 +35,6 @@ impl Default for LoggingLevel {
}
}

#[derive(Clone, Debug)]
pub struct ValveConfigOld {
pub config: SerdeMap,
pub datatype_conditions: HashMap<String, CompiledCondition>,
pub rule_conditions: HashMap<String, HashMap<String, Vec<ColumnRule>>>,
pub structure_conditions: HashMap<String, ParsedStructure>,
}

impl ValveConfigOld {
pub fn get_path(&self) -> String {
self.config
.get("table")
.and_then(|t| t.as_object())
.and_then(|t| t.get("table"))
.and_then(|t| t.as_object())
.and_then(|t| t.get("path"))
.and_then(|p| p.as_str())
.unwrap()
.to_string()
}
}

#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct TomlConfig {
pub nanobot: NanobotConfig,
Expand Down Expand Up @@ -149,39 +119,59 @@ pub struct InputConfig {
pub test: Option<String>,
}

#[derive(Debug)]
pub enum NanobotError {
GeneralError(String),
ValveError(ontodev_valve::ValveError),
TomlError(toml::de::Error),
}

impl From<ontodev_valve::ValveError> for NanobotError {
fn from(e: ontodev_valve::ValveError) -> Self {
Self::ValveError(e)
}
}

impl From<toml::de::Error> for NanobotError {
fn from(e: toml::de::Error) -> Self {
Self::TomlError(e)
}
}

pub type SerdeMap = serde_json::Map<String, SerdeValue>;

pub const DEFAULT_TOML: &str = "[nanobot]
config_version = 1";

impl Config {
pub async fn new() -> Result<Config, String> {
pub async fn new() -> Result<Config, NanobotError> {
let user_config_file = match fs::read_to_string("nanobot.toml") {
Ok(x) => x,
Err(_) => DEFAULT_TOML.into(),
};
let user: TomlConfig = match toml::from_str(user_config_file.as_str()) {
Ok(d) => d,
Err(e) => return Err(e.to_string()),
};
let user: TomlConfig = toml::from_str(user_config_file.as_str())?;
let connection = user
.database
.unwrap_or_default()
.connection
.unwrap_or(".nanobot.db".into());
let valve_path = user
.valve
.unwrap_or_default()
.path
.unwrap_or("src/schema/table.tsv".into());
let valve = Valve::build(&valve_path, &connection, false, false).await?;
let pool = valve.pool.clone();

let config = Config {
config_version: user.nanobot.config_version,
port: user.nanobot.port.unwrap_or(3000),
logging_level: user.logging.unwrap_or_default().level.unwrap_or_default(),
connection: user
.database
.unwrap_or_default()
.connection
.unwrap_or(".nanobot.db".into()),
pool: None,
valve_old: None,
valve: None,
valve_path: user
.valve
.unwrap_or_default()
.path
.unwrap_or("src/schema/table.tsv".into()),
valve: valve,
valve_path: valve_path,
valve_create_only: false,
connection: connection,
pool: pool,
asset_path: {
match user.assets.unwrap_or_default().path {
Some(p) => {
Expand Down Expand Up @@ -222,102 +212,18 @@ impl Config {
Ok(config)
}

pub async fn init(&mut self) -> Result<&mut Config, String> {
self.start_pool().await?.load_valve_config().await?;
Ok(self)
}

pub async fn start_pool(&mut self) -> Result<&mut Config, String> {
let connection_options;
if self.connection.starts_with("postgresql://") {
connection_options = match AnyConnectOptions::from_str(&self.connection) {
Ok(o) => o,
Err(e) => return Err(e.to_string()),
};
} else {
let connection_string;
if !self.connection.starts_with("sqlite://") {
connection_string = format!("sqlite://{}?mode=rwc", self.connection);
} else {
connection_string = self.connection.to_string();
}
connection_options = match AnyConnectOptions::from_str(connection_string.as_str()) {
Ok(o) => o,
Err(e) => return Err(e.to_string()),
};
}

let pool = match AnyPoolOptions::new()
.max_connections(5)
.connect_with(connection_options)
.await
{
Ok(o) => o,
Err(e) => return Err(e.to_string()),
};
if pool.any_kind() == AnyKind::Sqlite {
if let Err(e) = sqlx_query("PRAGMA foreign_keys = ON").execute(&pool).await {
return Err(e.to_string());
}
}
self.pool = Some(pool);
Ok(self)
}

pub async fn load_valve_config(&mut self) -> Result<&mut Config, String> {
let verbose = false;
let initial_load = false;
match valve_old(
&self.valve_path,
&self.connection,
&ValveCommandOld::Config,
verbose,
initial_load,
"table",
)
.await
{
Err(e) => {
return Err(format!(
"VALVE error while initializing from {}: {:?}",
&self.valve_path,
e
))
}
Ok(v) => {
let v: SerdeMap = serde_json::from_str(&v).unwrap();
let parser = StartParser::new();
let d = get_compiled_datatype_conditions(&v, &parser);
let r = get_compiled_rule_conditions(&v, d.clone(), &parser);
let p = get_parsed_structure_conditions(&v, &parser);
self.valve_old = Some(ValveConfigOld {
config: v,
datatype_conditions: d,
rule_conditions: r,
structure_conditions: p,
});
}
};

Ok(self)
}

pub fn connection<S: Into<String>>(&mut self, connection: S) -> &mut Config {
self.connection = connection.into();
self
}

pub fn create_only(&mut self, value: bool) -> &mut Config {
// TODO: Reach into self.valve and set it there instead.
//self.valve_create_only = value;
todo!();
self.valve_create_only = value;
self
}

pub fn initial_load(&mut self, value: bool) -> &mut Config {
// TODO: Reach into self.valve and set it there instead.
//self.valve_initial_load = value;
todo!();
self.valve.initial_load = value;
self
}
}
Expand Down
41 changes: 13 additions & 28 deletions src/get.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,12 +126,7 @@ pub async fn get_rows(
format: &str,
) -> Result<String, GetError> {
// Get all the tables
let table_map = match config
.valve_old
.as_ref()
.and_then(|v| v.config.get("table"))
.and_then(|t| t.as_object())
{
let table_map = match config.valve.config.get("table").and_then(|t| t.as_object()) {
Some(table_map) => table_map,
None => {
return Err(GetError::new(format!(
Expand All @@ -150,9 +145,9 @@ pub async fn get_rows(

// Get the columns for the selected table
let column_config = match config
.valve_old
.as_ref()
.and_then(|v| v.config.get("table"))
.valve
.config
.get("table")
.and_then(|t| t.as_object())
.and_then(|t| t.get(&unquoted_table))
.and_then(|t| t.as_object())
Expand Down Expand Up @@ -188,15 +183,7 @@ pub async fn get_rows(
_ => select.limit(LIMIT_DEFAULT),
};

let pool = match config.pool.as_ref() {
Some(p) => p,
_ => {
return Err(GetError::new(format!(
"Could not connect to database using pool {:?}",
config.pool
)))
}
};
let pool = &config.pool;

match shape {
"value_rows" => {
Expand Down Expand Up @@ -252,7 +239,7 @@ async fn get_page(
table_map: &Map<String, Value>,
column_rows: &Vec<Map<String, Value>>,
) -> Result<Value, GetError> {
let pool = &config.pool.as_ref().unwrap();
let pool = &config.pool;
let filter_messages = {
let m = select
.select
Expand Down Expand Up @@ -282,10 +269,10 @@ async fn get_page(
}

let sql_type = valve::get_sql_type_from_global_config(
&config.valve_old.as_ref().unwrap().config,
&config.valve.config,
&unquote(&select.table).unwrap(),
&key,
&config.pool.as_ref().unwrap(),
&config.pool,
)
.unwrap_or_default();
r.insert("sql_type".into(), json!(sql_type));
Expand Down Expand Up @@ -439,9 +426,9 @@ async fn get_page(

// convert value_rows to cell_rows
let table_type = config
.valve_old
.as_ref()
.and_then(|v| v.config.get("table"))
.valve
.config
.get("table")
.and_then(|v| v.as_object())
.and_then(|o| o.get(&unquoted_table))
.and_then(|v| v.as_object())
Expand Down Expand Up @@ -840,16 +827,14 @@ pub fn get_change_message(record: &AnyRow) -> Option<String> {

// Get the undo message, or None.
pub fn get_undo_message(config: &Config) -> Option<String> {
let pool = config.pool.as_ref()?;
let record = block_on(valve::get_record_to_undo_old(pool)).ok()??;
let record = block_on(config.valve.get_record_to_undo()).ok()??;
let message = get_change_message(&record)?;
Some(String::from(format!("Undo {message}")))
}

// Get the redo message, or None.
pub fn get_redo_message(config: &Config) -> Option<String> {
let pool = config.pool.as_ref()?;
let record = block_on(valve::get_record_to_redo_old(pool)).ok()??;
let record = block_on(config.valve.get_record_to_redo()).ok()??;
let message = get_change_message(&record)?;
Some(String::from(format!("Redo {message}")))
}
Expand Down
Loading

0 comments on commit 4145315

Please sign in to comment.