photoncloud-monorepo/flaredb/crates/flaredb-sql/src/executor.rs
centra 5c6eb04a46 T036: Add VM cluster deployment configs for nixos-anywhere
- 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>
2025-12-11 09:59:19 +09:00

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"),
}
}
}