use crate::core::failed;
use crate::event::Event;
use crate::failure::FailureCode;
use crate::port::DriverCapabilities;
impl crate::core::Core {
pub(crate) fn create_database_from_template(
&mut self,
path: std::path::PathBuf,
template: String,
) -> Vec<Event> {
if self.state.database.is_some() {
return failed(
FailureCode::Lifecycle,
"close the open database before creating a database from a template",
);
}
if !self.port.capabilities().create_database {
return failed(
FailureCode::Capability(crate::availability::DisabledReason::CreateDatabase),
DriverCapabilities::unsupported(&self.port.driver_id(), "create database files"),
);
}
let Some(template) = crate::templates::find_template(&template) else {
let available: Vec<&str> = crate::templates::templates()
.iter()
.map(|entry| entry.name)
.collect();
return failed(
FailureCode::NotFound,
format!(
"unknown template {template:?} — available: {}",
available.join(", ")
),
);
};
let format = template.format;
if let Some(foreign) = format.creation_suffix_conflict(&path) {
return failed(
FailureCode::InvalidInput,
format!(
"the path {} ends in .{foreign}, which does not match the template's \
format {format} — rename the file or choose another template",
path.display()
),
);
}
if let Err(e) = self.port.create_database(&path, format) {
return failed(FailureCode::Port, e.to_string());
}
if let Err(e) = self.materialize_template_tables(&path, &template.tables) {
let _ = std::fs::remove_file(&path);
return failed(FailureCode::Port, e);
}
vec![Event::DatabaseCreated { path, format }]
}
fn materialize_template_tables(
&mut self,
path: &std::path::Path,
tables: &[crate::templates::TemplateTable],
) -> Result<(), String> {
if tables.is_empty() {
return Ok(());
}
if let Err(e) = self.port.open(path, None) {
return Err(e.to_string());
}
for table in tables {
if let Err(e) = self.port.create_table(&table.definition) {
self.port.close();
return Err(e.to_string());
}
for row in &table.rows {
if let Err(e) = self.port.insert_row(&table.definition.name, row) {
self.port.close();
return Err(e.to_string());
}
}
}
self.port.close();
Ok(())
}
}