- netboot-base.nix with SSH key auth - Launch scripts for node01/02/03 - Node configuration.nix and disko.nix - Nix modules for first-boot automation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
156 lines
4.5 KiB
Rust
156 lines
4.5 KiB
Rust
use crate::error::{Result, SqlError};
|
|
use crate::metadata::MetadataManager;
|
|
use crate::parser::{SqlStatement, parse_sql};
|
|
use crate::storage::StorageManager;
|
|
use crate::types::QueryResult;
|
|
use flaredb_client::RdbClient;
|
|
use std::sync::Arc;
|
|
use tokio::sync::Mutex;
|
|
|
|
/// SQL execution result
|
|
#[derive(Debug)]
|
|
pub enum ExecutionResult {
|
|
DdlSuccess(String),
|
|
DmlSuccess(u64),
|
|
Query(QueryResult),
|
|
}
|
|
|
|
/// SQL executor
|
|
pub struct SqlExecutor {
|
|
metadata_manager: Arc<MetadataManager>,
|
|
storage_manager: Arc<StorageManager>,
|
|
}
|
|
|
|
impl SqlExecutor {
|
|
pub fn new(client: Arc<Mutex<RdbClient>>) -> Self {
|
|
let metadata_manager = Arc::new(MetadataManager::new(client.clone()));
|
|
let storage_manager = Arc::new(StorageManager::new(client));
|
|
|
|
Self {
|
|
metadata_manager,
|
|
storage_manager,
|
|
}
|
|
}
|
|
|
|
/// Execute a SQL statement
|
|
pub async fn execute(&self, sql: &str) -> Result<ExecutionResult> {
|
|
let statement = parse_sql(sql)?;
|
|
self.execute_statement(&statement).await
|
|
}
|
|
|
|
async fn execute_statement(&self, statement: &SqlStatement) -> Result<ExecutionResult> {
|
|
match statement {
|
|
SqlStatement::CreateTable {
|
|
table_name,
|
|
columns,
|
|
primary_key,
|
|
} => {
|
|
self.metadata_manager
|
|
.create_table(table_name.clone(), columns.clone(), primary_key.clone())
|
|
.await?;
|
|
|
|
Ok(ExecutionResult::DdlSuccess(format!(
|
|
"Table '{}' created",
|
|
table_name
|
|
)))
|
|
}
|
|
|
|
SqlStatement::DropTable { table_name } => {
|
|
self.metadata_manager.drop_table(table_name).await?;
|
|
|
|
Ok(ExecutionResult::DdlSuccess(format!(
|
|
"Table '{}' dropped",
|
|
table_name
|
|
)))
|
|
}
|
|
|
|
SqlStatement::Insert {
|
|
table_name,
|
|
columns,
|
|
values,
|
|
} => {
|
|
let table = self.metadata_manager.get_table_metadata(table_name).await?;
|
|
|
|
self.storage_manager
|
|
.insert_row(&table, columns, values)
|
|
.await?;
|
|
|
|
Ok(ExecutionResult::DmlSuccess(1))
|
|
}
|
|
|
|
SqlStatement::Select {
|
|
table_name,
|
|
columns,
|
|
where_clause,
|
|
} => {
|
|
let table = self.metadata_manager.get_table_metadata(table_name).await?;
|
|
|
|
let result = self
|
|
.storage_manager
|
|
.query_rows(&table, columns, where_clause.as_ref())
|
|
.await?;
|
|
|
|
Ok(ExecutionResult::Query(result))
|
|
}
|
|
|
|
SqlStatement::Update { .. } => {
|
|
Err(SqlError::InvalidOperation("UPDATE not yet implemented".to_string()))
|
|
}
|
|
|
|
SqlStatement::Delete { .. } => {
|
|
Err(SqlError::InvalidOperation("DELETE not yet implemented".to_string()))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[tokio::test]
|
|
#[ignore] // Requires FlareDB server
|
|
async fn test_create_and_query_table() {
|
|
let client = RdbClient::connect_direct("127.0.0.1:8001".to_string(), "sqltest".to_string()).await.unwrap();
|
|
let executor = SqlExecutor::new(Arc::new(Mutex::new(client)));
|
|
|
|
// Create table
|
|
let result = executor
|
|
.execute("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT NOT NULL)")
|
|
.await
|
|
.unwrap();
|
|
|
|
match result {
|
|
ExecutionResult::DdlSuccess(msg) => {
|
|
assert!(msg.contains("created"));
|
|
}
|
|
_ => panic!("Expected DdlSuccess"),
|
|
}
|
|
|
|
// Insert data
|
|
let result = executor
|
|
.execute("INSERT INTO users (id, name) VALUES (1, 'Alice')")
|
|
.await
|
|
.unwrap();
|
|
|
|
match result {
|
|
ExecutionResult::DmlSuccess(count) => {
|
|
assert_eq!(count, 1);
|
|
}
|
|
_ => panic!("Expected DmlSuccess"),
|
|
}
|
|
|
|
// Query data
|
|
let result = executor
|
|
.execute("SELECT * FROM users WHERE id = 1")
|
|
.await
|
|
.unwrap();
|
|
|
|
match result {
|
|
ExecutionResult::Query(query_result) => {
|
|
assert_eq!(query_result.row_count(), 1);
|
|
}
|
|
_ => panic!("Expected Query result"),
|
|
}
|
|
}
|
|
}
|