use std::{cell::RefMut, collections::HashMap, str};
use bson::Bson;
use crate::db::{collection::{Collection, _SYSTEM_MASTER}, operation_context::OperationContext, ops::insert::insert, recovery_unit::RecoveryUnit};
pub struct CollectionCatalog {
pub collection_metadata: HashMap<String, Collection>
}
#[derive(Debug)]
pub struct RawDocument {
pub next_document: u64,
pub content_length: u64,
pub content: Vec<u8>,
}
impl CollectionCatalog {
pub fn new() -> Self {
Self {
collection_metadata: HashMap::new(),
}
}
pub fn lookup_collection(&self, op_ctx: &OperationContext, colname: &str) -> Collection {
let mut next_document = _SYSTEM_MASTER.next_document;
println!("Colname: {}", colname);
let rc_unit = op_ctx.rc_unit();
while next_document != 0 {
let name = Collection::parse_name(&rc_unit.borrow(),
next_document + DOCUMENT_CONTENT_OFFSET);
if let Ok(text) = std::str::from_utf8(&name) {
let text = text.trim_matches('\0');
println!("text: '{}', colname: '{}'", text, colname);
if text.eq(colname) {
println!("equals");
let next_d = rc_unit.borrow().effective_view(next_document + DOCUMENT_CONTENT_OFFSET, 40);
println!("NextD: {:?} ({})", next_d, next_document);
let col_next_document = Collection::parse_next_document(&rc_unit.borrow(),
next_document + DOCUMENT_CONTENT_OFFSET);
let collection = Collection {
name,
next_document: col_next_document,
offset: next_document,
};
println!("Col: {:?}", collection);
return collection;
}
}
next_document = RawDocument::parse_next_document(&rc_unit.borrow(), next_document) as usize
}
let col = Collection::new(colname, 0);
println!("Col: {:?}", col);
col
}
pub fn acquire_collection_or_create(&mut self, colname: &str, op_ctx: &mut OperationContext) -> Collection {
let mut next_document = _SYSTEM_MASTER.next_document;
println!("Colname: {}", colname);
let rc_unit = op_ctx.rc_unit();
while next_document != 0 {
let name = Collection::parse_name(&rc_unit.borrow(),
next_document + DOCUMENT_CONTENT_OFFSET);
if let Ok(text) = std::str::from_utf8(&name) {
let text = text.trim_matches('\0');
println!("text: '{}', colname: '{}'", text, colname);
if text.eq(colname) {
println!("equals");
let col_next_document = Collection::parse_next_document(&rc_unit.borrow(),
next_document + DOCUMENT_CONTENT_OFFSET);
let collection = Collection {
name,
next_document: col_next_document,
offset: next_document,
};
println!("Col aq: {:?}", collection);
return collection;
}
}
next_document = RawDocument::parse_next_document(&rc_unit.borrow(), next_document) as usize
}
let mut collection = Collection::new(colname, 0);
let col_offset = insert(op_ctx, _SYSTEM_MASTER,
&collection.to_bytes());
collection.offset = col_offset;
println!("Col aq: {:?}", collection);
collection
}
}
const DOCUMENT_NEXT_DOCUMENT_OFFSET: usize = 0;
pub const DOCUMENT_CONTENT_LENGHT_OFFSET: usize = 8;
pub const DOCUMENT_CONTENT_OFFSET: usize = 16;
impl RawDocument {
pub fn len(&self) -> usize {
self.content.len() + 8 + 8
}
pub fn parse(ss: &RecoveryUnit, offset: usize) -> RawDocument {
let content_length = Self::parse_content_length(ss, offset);
RawDocument {
next_document: Self::parse_next_document(ss, offset),
content_length,
content: Self::parse_content(ss, offset, content_length as usize),
}
}
pub fn parse_next_document(ss: &RecoveryUnit, offset: usize) -> u64 {
let mut bytes = [0u8; 8];
bytes.copy_from_slice(
&ss.effective_view(offset+DOCUMENT_NEXT_DOCUMENT_OFFSET, 8)
);
u64::from_le_bytes(bytes)
}
pub fn parse_content_length(ss: &RecoveryUnit, offset: usize) -> u64 {
let mut bytes = [0u8; 8];
bytes.copy_from_slice(
&ss.effective_view(offset+DOCUMENT_CONTENT_LENGHT_OFFSET, 8)
);
u64::from_le_bytes(bytes)
}
pub fn parse_content(ss: &RecoveryUnit, offset: usize, content_length: usize) -> Vec<u8> {
ss.effective_view(offset+DOCUMENT_CONTENT_OFFSET, content_length)
.to_vec()
}
pub fn write_next_document(mut rc_unit: RefMut<'_, RecoveryUnit>, offset: usize, next_offset: usize) {
rc_unit.write(offset+DOCUMENT_NEXT_DOCUMENT_OFFSET, &next_offset.to_le_bytes());
}
pub fn write_content_length(mut rc_unit: RefMut<'_, RecoveryUnit>, offset: usize, content_length: usize) {
rc_unit.write(offset+DOCUMENT_CONTENT_LENGHT_OFFSET, &content_length.to_le_bytes());
}
pub fn write_content(mut rc_unit: RefMut<'_, RecoveryUnit>, offset: usize, content: &[u8]) {
rc_unit.write(offset+DOCUMENT_CONTENT_OFFSET, content);
}
}
impl From<&Collection> for RawDocument {
fn from(value: &Collection) -> Self {
Self {
next_document: 0,
content_length: Collection::len(),
content: value.to_bytes(),
}
}
}
impl From<Bson> for RawDocument {
fn from(value: Bson) -> Self {
todo!()
}
}