use std::sync::Arc;
use crate::error::Result;
use crate::ffi::cstring;
use crate::library::{Library, columns_of};
use crate::schema::{Schema, settings_json};
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
#[repr(i32)]
pub enum CompileMode {
#[default]
Declared = 0,
}
impl CompileMode {
pub fn code(self) -> i32 {
self as i32
}
}
pub struct CompileRequest<'a> {
pub(crate) lib: &'a Arc<Library>,
pub(crate) columns_sql: String,
pub(crate) settings: Vec<(String, String)>,
pub(crate) mode: CompileMode,
}
impl<'a> CompileRequest<'a> {
pub fn settings<I, K, V>(mut self, settings: I) -> Self
where
I: IntoIterator<Item = (K, V)>,
K: Into<String>,
V: Into<String>,
{
self.settings = settings
.into_iter()
.map(|(k, v)| (k.into(), v.into()))
.collect();
self
}
pub fn mode(mut self, mode: CompileMode) -> Self {
self.mode = mode;
self
}
pub fn compile(self) -> Result<Schema> {
let ddl = cstring(&self.columns_sql, "column list")?;
let json = settings_json(&self.settings)?;
let (handle, columns) = {
let _guard = self.lib.lock();
let handle = self.lib.api().compile(&ddl, &json, self.mode.code())?;
let columns = unsafe { self.lib.api().columns(handle) };
(handle, columns)
};
Ok(Schema::new(
Arc::clone(self.lib),
handle,
columns_of(columns),
))
}
}