use crate::utils::{deserialize, serialize_to_bytevec, normalize_type_name};
use crate::decl::types::*;
use crate::prelude::*;
use crate::mem::{Memory, OwnedMemoryRecord};
use crate::fio::FileIO;
use crate::slice;
use crate::types::record::Record;
enum DbType {
InMemory,
File,
}
pub struct Db {
file_name: String,
f_io: Option<FileIO>,
memory: Memory,
r#type: DbType,
}
impl Db {
pub fn create<S: AsRef<str>>(file_name: S) -> std::io::Result<Self> {
let f = std::fs::OpenOptions::new()
.write(true)
.create(true)
.read(true)
.open(file_name.as_ref())?;
let f_io = FileIO::new(f);
let mut memory = Memory::new();
f_io.read_to(&mut memory)?;
memory.generate_lu_maps();
Ok(Db {
file_name: file_name.as_ref().to_string(),
f_io: Some(f_io),
memory: memory,
r#type: DbType::File,
})
}
pub fn read<S: AsRef<str>>(file_name: S) -> std::io::Result<Self> {
let f = std::fs::OpenOptions::new()
.write(true)
.read(true)
.open(file_name.as_ref())?;
let f_io = FileIO::new(f);
let mut memory = Memory::new();
f_io.read_to(&mut memory)?;
memory.generate_lu_maps();
Ok(Db {
file_name: file_name.as_ref().to_string(),
f_io: Some(f_io),
memory: memory,
r#type: DbType::File,
})
}
pub fn read_to_mem<S: AsRef<str>>(file_name: S) -> std::io::Result<Self> {
let f = std::fs::OpenOptions::new()
.read(true)
.open(file_name.as_ref())?;
let f_io = FileIO::new(f);
let mut memory = Memory::new();
f_io.read_to(&mut memory)?;
memory.generate_lu_maps();
Ok(Db {
file_name: file_name.as_ref().to_string(),
f_io: Some(f_io),
memory: memory,
r#type: DbType::InMemory,
})
}
pub fn mem() -> std::io::Result<Self> {
Ok(Db {
file_name: String::new(),
f_io: None,
memory: Memory::new(),
r#type: DbType::InMemory,
})
}
pub fn file_name(&self) -> &str {
self.file_name.as_str()
}
pub fn memory(&self) -> &Memory {
&self.memory
}
pub fn memory_mut(&mut self) -> &mut Memory {
&mut self.memory
}
pub fn len(&self) -> usize {
self.memory.len()
}
pub fn declarations(&self) -> &DeclarationMap {
&self.memory.declaration_map()
}
pub fn kv_records(&self) -> &Vec<OwnedMemoryRecord> {
&self.memory.kv_records()
}
pub fn decl_records(&self) -> &DeclarationRecords {
&self.memory.decl_records()
}
pub fn field_map<S: AsRef<str>>(&self, key: S) -> &FieldMap {
&self.memory.declaration_map()[key.as_ref().as_bytes()]
}
pub fn has_key<S: AsRef<str>>(&self, key: S) -> bool {
self.memory.has_key(key.as_ref().as_bytes())
}
pub fn store<S: AsRef<str>, T: Sized + serde::ser::Serialize>(&mut self, k: S, v: T) {
let (k, t, ser_v) = (k.as_ref().as_bytes(), normalize_type_name(std::any::type_name::<T>().as_bytes()), serialize_to_bytevec(&v));
assert!(k.len() > 0 && t.len() > 0);
self.memory.push_record((k.into(), t.into(), ser_v));
}
pub fn store_as<S: AsRef<str>, T: Sized + serde::ser::Serialize>(&mut self, k: S, t: S, v: T) {
let (k, t, v) = (k.as_ref().as_bytes(), normalize_type_name(t.as_ref().as_bytes()), serialize_to_bytevec(&v));
assert!(k.len() > 0 && t.len() > 0);
self.memory.push_record((k.into(), t.into(), v));
}
pub fn store_raw<S: AsRef<str>>(&mut self, k: S, t: S, v: &[u8]) {
let (k, t, v) = (k.as_ref().as_bytes(), normalize_type_name(t.as_ref().as_bytes()), v);
assert!(k.len() > 0 && t.len() > 0);
self.memory.push_record((k.into(), t.into(), v.into()));
}
pub fn store_many<S: AsRef<str>, T: Sized + serde::ser::Serialize>(&mut self, values: &Vec<(S, T)>) {
for (k, v) in values {
let (k, t, v) = (k.as_ref().as_bytes(), std::any::type_name::<T>().as_bytes(), serialize_to_bytevec(v));
assert!(k.len() > 0 && t.len() > 0);
self.memory.push_record((k.into(), slice::strip_ref_symbols(t).into(), v));
}
}
pub fn store_many_as<S: AsRef<str>, T: Sized + serde::ser::Serialize>(&mut self, values: &Vec<(S, S, T)>) {
for (k, t, v) in values {
let (k, t, v) = (k.as_ref().as_bytes(), t.as_ref().as_bytes(), serialize_to_bytevec(&v));
assert!(k.len() > 0 && t.len() > 0);
self.memory.push_record((k.into(), t.into(), v));
}
}
pub fn fetch<S: AsRef<str>>(&self, key: S) -> Record {
let (k, t, v) = &self.memory[key];
Record::new(k, t, v)
}
pub fn fetch_value<T: serde::de::DeserializeOwned>(&self, key: &str) -> T {
deserialize(&self.memory[key].2.inner())
}
pub fn fetch_raw<S: AsRef<str>>(&self, key: S) -> &OwnedMemoryRecord {
&self.memory[key]
}
pub fn update<S: AsRef<str>, T: serde::ser::Serialize>(&mut self, k: S, v: T) {
self.memory.delete_record(self.memory.index_of_key(k.as_ref().as_bytes()));
self.store(k, v);
}
pub fn update_record(&mut self, record: impl RecordRead) {
self.memory.delete_record(self.memory.index_of_key(record.key().as_slice()));
self.memory.push_record(record.to_tuple());
}
pub fn update_many(&mut self, records: &Vec<impl RecordRead>) {
for record in records {
self.memory.delete_record(self.memory.index_of_key(record.key().as_slice()));
self.memory.push_record(record.to_tuple());
}
}
pub fn remove<S: AsRef<str>>(&mut self, key: S) {
self.memory.delete_record(self.memory.index_of_key(key.as_ref().as_bytes()));
}
pub fn remove_record(&mut self, record: impl RecordRead) {
self.memory.delete_record(self.memory.index_of_key(record.key().as_slice()));
}
pub fn remove_many(&mut self, records: &Vec<impl RecordRead>) {
for record in records {
self.memory.delete_record(self.memory.index_of_key(record.key().as_slice()));
}
}
pub fn commit(&mut self) -> std::io::Result<()> {
if !self.file_name.is_empty() {
let f = std::fs::OpenOptions::new()
.write(true)
.read(true)
.create(true)
.truncate(true)
.open(&self.file_name)?;
self.f_io = Some(FileIO::new(f));
self.r#type = DbType::File;
self.f_io.as_mut().unwrap().dump_mem(&self.memory).unwrap()
}
Err(std::io::Error::new(std::io::ErrorKind::Other, "File name not set, are you using a memory database?"))
}
pub fn has_decl<S: AsRef<str>>(&self, name: S) -> bool {
self.memory.declaration_map().contains_key(name.as_ref().as_bytes())
}
pub fn declare<'a, S: AsRef<str>>(&mut self, name: S) -> Declare {
Declare::new(name)
}
pub fn insert_decl(&mut self, dg: &Declare) {
self.memory.insert_decl(dg);
}
pub fn remove_decl<S: AsRef<str>>(&mut self, name: S) {
self.memory.remove_decl(name);
}
pub fn decl_insert_row<S: AsRef<str>>(&mut self, name: S, row: DeclarationRecord) {
self.memory.decl_insert_row(name.as_ref(), row);
}
pub fn decl_insert_many<S: AsRef<str>>(&mut self, name: S, rows: Vec<DeclarationRecord>) {
self.memory.decl_insert_rows(name.as_ref(), rows);
}
pub fn query<S: AsRef<str>>(&self, name: S) -> QueryBuilder {
let field_map = self.memory.get_field_map(&name);
let records = self.memory.get_decl_records(&name);
QueryBuilder::new(field_map, records)
}
}
impl BytesFilter for Db {
fn filter<F>(&self, cb: F) -> Vec<Record> where F: Fn(&Record) -> bool {
self.memory.iter()
.filter_map(|r| {
let r: Record = r.into();
if cb(&r) { return Some(r) }
None
})
.collect()
}
}
impl BytesSearch for Db {
fn starts_with<S: AsRef<str>>(&self, key_part: S) -> Vec<Record> {
let k_part = key_part.as_ref().as_bytes();
self.memory.char_search(k_part[0]).iter().filter_map(|(k, t, v)| {
if k.starts_with(k_part) {
return Some(Record::new(k, t, v))
}
None
})
.collect::<Vec<_>>()
}
fn ends_with<S: AsRef<str>>(&self, key_part: S) -> Vec<Record> {
self.memory.iter().filter_map(|(k, t, v)| {
if k.ends_with(key_part.as_ref().as_bytes()) {
return Some(Record::new(k, t, v))
}
None
})
.collect::<Vec<_>>()
}
fn contains<S: AsRef<str>>(&self, key_part: S) -> Vec<Record> {
self.memory.iter().filter_map(|(k, t, v)| {
if k.contains(key_part.as_ref()) {
return Some(Record::new(k, t, v))
}
None
})
.collect::<Vec<_>>()
}
}