pub mod daemon_registry;
pub mod paths;
pub mod sandbox;
pub mod sqlite;
use crate::ayb_db::models::DBType;
use crate::error::AybError;
use crate::formatting::TabularFormatter;
use crate::from_str;
use crate::hosted_db::sqlite::run_sqlite_query;
use crate::try_from_i16;
use prettytable::{Cell, Row, Table};
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use std::str::FromStr;
use std::vec::Vec;
#[derive(Serialize, Debug, Deserialize, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
#[repr(i16)]
pub enum QueryMode {
ReadOnly = 0,
ReadWrite = 1,
}
try_from_i16!(QueryMode, {
0 => QueryMode::ReadOnly,
1 => QueryMode::ReadWrite
});
from_str!(QueryMode, {
"read-only" => QueryMode::ReadOnly,
"read-write" => QueryMode::ReadWrite
});
impl QueryMode {
pub fn to_str(&self) -> &str {
match self {
QueryMode::ReadOnly => "read-only",
QueryMode::ReadWrite => "read-write",
}
}
pub fn permits(&self, requested: QueryMode) -> bool {
*self >= requested
}
}
#[derive(Serialize, Debug, Deserialize)]
pub struct QueryResult {
pub fields: Vec<String>,
pub rows: Vec<Vec<Option<String>>>,
}
impl TabularFormatter for QueryResult {
fn to_table(&self) -> Table {
let mut table = Table::new();
table.set_titles(Row::new(
self.fields
.iter()
.map(|cell| Cell::new(cell))
.collect::<Vec<_>>(),
));
for row in &self.rows {
let cells = row
.iter()
.map(|cell| {
Cell::new(match cell {
Some(s) => s,
None => "NULL",
})
})
.collect::<Vec<_>>();
table.add_row(Row::new(cells));
}
table
}
}
pub async fn run_query(
daemon_registry: &daemon_registry::DaemonRegistry,
path: &PathBuf,
query: &str,
db_type: &DBType,
query_mode: QueryMode,
) -> Result<QueryResult, AybError> {
match db_type {
DBType::Sqlite => Ok(run_sqlite_query(daemon_registry, path, query, query_mode).await?),
_ => Err(AybError::Other {
message: "Unsupported DB type".to_string(),
}),
}
}