use crate::database::SchemaRecord;
use crate::values::{integer, string, Value};
use crate::varint;
pub struct Record {
pub rowid: u64,
values: Vec<Value>,
}
impl Record {
pub fn new(rowid: u64) -> Self {
Self {
rowid,
values: vec![],
}
}
pub fn add_value(&mut self, value: Value) {
self.values.push(value);
}
pub fn bytes_len(&self) -> u16 {
let record_length: u16 = self.values.iter().map(Value::len).sum();
record_length + 1
}
}
impl From<Record> for Vec<u8> {
fn from(mut record: Record) -> Vec<u8> {
let record_length = record.bytes_len();
let mut length_bytes = varint::write(u64::from(record_length));
let mut rowid_bytes = varint::write(record.rowid);
let mut buffer =
Vec::with_capacity(length_bytes.len() + rowid_bytes.len() + record_length as usize);
buffer.append(&mut length_bytes);
buffer.append(&mut rowid_bytes);
let length_of_encoded_column_types: usize =
record.values.iter().map(|v| v.datatype.len()).sum();
buffer.append(&mut varint::write(
(length_of_encoded_column_types + 1) as u64,
));
for v in &mut record.values {
buffer.append(&mut v.datatype);
}
for v in &mut record.values {
buffer.append(&mut v.data);
}
buffer
}
}
impl From<SchemaRecord> for Record {
fn from(s: SchemaRecord) -> Self {
let mut record = Record::new(s.rowid);
record.add_value(string("table"));
record.add_value(string(&s.table_name.to_ascii_lowercase()));
record.add_value(string(&s.table_name.to_ascii_lowercase()));
record.add_value(integer(i64::from(s.root_page)));
record.add_value(string(&s.sql));
record
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test() {
let mut record = Record::new(1);
record.add_value(string("hello"));
let bytes: Vec<u8> = record.into();
assert_eq!(bytes, vec![7, 1, 2, 23, 104, 101, 108, 108, 111]);
}
}