use ayb::hosted_db::sandbox::apply_sandbox;
use ayb::hosted_db::sqlite::query_sqlite;
use ayb::hosted_db::QueryMode;
use serde::{Deserialize, Serialize};
use std::env;
use std::io::{self, BufRead, Write};
use std::path::PathBuf;
#[derive(Serialize, Deserialize, Debug)]
struct QueryRequest {
query: String,
query_mode: i16,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let args: Vec<String> = env::args().collect();
let db_file = parse_args(&args)?;
apply_sandbox(&db_file)?;
run(db_file)
}
fn parse_args(args: &[String]) -> Result<PathBuf, Box<dyn std::error::Error>> {
match args.len() {
2 => Ok(PathBuf::from(&args[1])),
_ => {
eprintln!("Usage: ayb_query_daemon <database.sqlite>");
std::process::exit(1);
}
}
}
fn run(db_file: PathBuf) -> Result<(), Box<dyn std::error::Error>> {
let stdin = io::stdin();
let mut stdout = io::stdout();
for line in stdin.lock().lines() {
let line = line?;
let request: QueryRequest = match serde_json::from_str(&line) {
Ok(req) => req,
Err(e) => {
let error_response = serde_json::json!({
"error": format!("Failed to parse request: {}", e)
});
writeln!(stdout, "{error_response}")?;
stdout.flush()?;
continue;
}
};
let query_mode = match QueryMode::try_from(request.query_mode) {
Ok(mode) => mode,
Err(_) => {
let error_response = serde_json::json!({
"error": "Invalid query_mode, must be 0 or 1"
});
writeln!(stdout, "{error_response}")?;
stdout.flush()?;
continue;
}
};
let result = query_sqlite(&db_file, &request.query, false, query_mode);
match result {
Ok(result) => {
writeln!(stdout, "{}", serde_json::to_string(&result)?)?;
}
Err(error) => {
writeln!(stdout, "{}", serde_json::to_string(&error)?)?;
}
}
stdout.flush()?;
}
Ok(())
}