in core/src/services/persy/backend.rs [79:137]
fn build(&mut self) -> Result<Self::Accessor> {
let datafile_path = self.datafile.take().ok_or_else(|| {
Error::new(ErrorKind::ConfigInvalid, "datafile is required but not set")
.with_context("service", Scheme::Persy)
})?;
let segment_name = self.segment.take().ok_or_else(|| {
Error::new(ErrorKind::ConfigInvalid, "segment is required but not set")
.with_context("service", Scheme::Persy)
})?;
let segment = segment_name.clone();
let index_name = self.index.take().ok_or_else(|| {
Error::new(ErrorKind::ConfigInvalid, "index is required but not set")
.with_context("service", Scheme::Persy)
})?;
let index = index_name.clone();
let persy = persy::OpenOptions::new()
.create(true)
.prepare_with(move |p| init(p, &segment_name, &index_name))
.open(&datafile_path)
.map_err(|e| {
Error::new(ErrorKind::ConfigInvalid, "open db")
.with_context("service", Scheme::Persy)
.with_context("datafile", datafile_path.clone())
.set_source(e)
})?;
// This function will only be called on database creation
fn init(
persy: &persy::Persy,
segment_name: &str,
index_name: &str,
) -> std::result::Result<(), Box<dyn std::error::Error>> {
let mut tx = persy.begin()?;
if !tx.exists_segment(segment_name)? {
tx.create_segment(segment_name)?;
}
if !tx.exists_index(index_name)? {
tx.create_index::<String, persy::PersyId>(index_name, persy::ValueMode::Replace)?;
}
let prepared = tx.prepare()?;
prepared.commit()?;
Ok(())
}
Ok(PersyBackend::new(Adapter {
datafile: datafile_path,
segment,
index,
persy,
}))
}