can read and write
This commit is contained in:
parent
8bcedcc032
commit
518622947d
5 changed files with 40 additions and 33 deletions
|
|
@ -3,6 +3,6 @@ use csv::table::Table;
|
||||||
fn main() {
|
fn main() {
|
||||||
let csv = include_str!("data/test.csv");
|
let csv = include_str!("data/test.csv");
|
||||||
let table = Table::from_csv(csv, None);
|
let table = Table::from_csv(csv, None);
|
||||||
println!("{:?}",table);
|
// println!("{:?}",table);
|
||||||
table.select("*");
|
table.select("*");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
10
src/page.rs
10
src/page.rs
|
|
@ -62,14 +62,14 @@ impl Page {
|
||||||
self.data.splice(start..self.index_pos as usize, bytes);
|
self.data.splice(start..self.index_pos as usize, bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self, index: usize) -> Option<Record> {
|
pub fn get(&self, row_index: usize) -> Option<Record> {
|
||||||
if index < self.n_records {
|
if row_index < self.n_records {
|
||||||
let index = BigEndian::read_u16(&self.data[index * 2..=index * 2 + 1]);
|
let physical_index = BigEndian::read_u16(&self.data[row_index * 2..=row_index * 2 + 1]);
|
||||||
let (nbytes, len) = varint::read(&self.data[index as usize..]);
|
let (bytes_read, len) = varint::read(&self.data[physical_index as usize..]);
|
||||||
Some(
|
Some(
|
||||||
(
|
(
|
||||||
len,
|
len,
|
||||||
&self.data[nbytes + index as usize..nbytes + index as usize + len as usize],
|
&self.data[bytes_read + physical_index as usize..=bytes_read + physical_index as usize + len as usize],
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -88,15 +88,17 @@ impl From<Record> for Vec<u8> {
|
||||||
// needs improving, for clarity get rid of the tuple
|
// needs improving, for clarity get rid of the tuple
|
||||||
impl Into<Record> for (u64, &[u8]) {
|
impl Into<Record> for (u64, &[u8]) {
|
||||||
fn into(self) -> Record {
|
fn into(self) -> Record {
|
||||||
let (len, data) = self;
|
let (_, data) = self;
|
||||||
let len = len as usize; //meh
|
let mut offset = 0;
|
||||||
let (mut offset, rowid) = varint::read(data);
|
let (inc, rowid) = varint::read(data);
|
||||||
|
offset += inc;
|
||||||
let mut datatypes = vec![];
|
let mut datatypes = vec![];
|
||||||
|
let (inc, dt_len) = varint::read(&data[offset..]);
|
||||||
|
offset += inc;
|
||||||
|
let end_of_dt = offset + dt_len as usize - 1; // why -1?
|
||||||
|
//read n of fields
|
||||||
|
|
||||||
//read n of fields
|
while offset < end_of_dt {
|
||||||
|
|
||||||
while offset < len {
|
|
||||||
//WRONG, read this len first from the buffer
|
//WRONG, read this len first from the buffer
|
||||||
let (inc, datatype) = varint::read(&data[offset..]);
|
let (inc, datatype) = varint::read(&data[offset..]);
|
||||||
datatypes.push(datatype);
|
datatypes.push(datatype);
|
||||||
|
|
@ -107,27 +109,24 @@ impl Into<Record> for (u64, &[u8]) {
|
||||||
let mut values: Vec<Value> = vec![];
|
let mut values: Vec<Value> = vec![];
|
||||||
for dt in datatypes {
|
for dt in datatypes {
|
||||||
match dt {
|
match dt {
|
||||||
13.. if dt % 2 == 0 => {
|
13.. if dt % 2 == 1 => {
|
||||||
let len = ((dt >> 1) - 13) as usize;
|
let len = ((dt - 13) >> 1) as usize;
|
||||||
if let Ok(text) = String::from_utf8(data[offset..len].to_vec()) {
|
values.push(Value::new(dt, data[offset..offset + len].to_vec()));
|
||||||
values.push(text.into());
|
|
||||||
}
|
|
||||||
offset += len;
|
offset += len;
|
||||||
}
|
}
|
||||||
12.. if dt % 2 == 0 => {
|
12.. if dt % 2 == 0 => {
|
||||||
let len = ((dt >> 1) - 12) as usize;
|
let len = ((dt >> 1) - 12) as usize;
|
||||||
// no blobs yet
|
values.push(Value::new(dt, data[offset..offset + len].to_vec()));
|
||||||
offset += len;
|
offset += len;
|
||||||
}
|
}
|
||||||
9 => values.push(1.into()),
|
8 | 9 => values.push(Value::new(dt, vec![])),
|
||||||
8 => values.push(0.into()),
|
|
||||||
7 => {
|
7 => {
|
||||||
values.push(BigEndian::read_f64(&data[offset..offset + 8]).into());
|
values.push(Value::new(dt, data[offset..offset + 8].to_vec()));
|
||||||
offset += 8;
|
offset += 8;
|
||||||
}
|
}
|
||||||
1..=6 => {
|
1..=6 => {
|
||||||
let (inc, v) = read_int(&data[offset..], dt);
|
let inc = read_int_len(dt);
|
||||||
values.push(v.into());
|
values.push(Value::new(dt, data[offset..offset + inc].to_vec()));
|
||||||
offset += inc;
|
offset += inc;
|
||||||
}
|
}
|
||||||
0 => {
|
0 => {
|
||||||
|
|
@ -141,13 +140,12 @@ impl Into<Record> for (u64, &[u8]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_int(buf: &[u8], datatype: u64) -> (usize, i64) {
|
fn read_int_len(datatype: u64) -> usize {
|
||||||
let nb = match datatype {
|
match datatype {
|
||||||
6 => 8,
|
6 => 8,
|
||||||
5 => 6,
|
5 => 6,
|
||||||
_ => datatype as usize,
|
_ => datatype as usize,
|
||||||
};
|
}
|
||||||
(nb, BigEndian::read_i64(&buf[..nb]))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Record {
|
impl Default for Record {
|
||||||
|
|
|
||||||
|
|
@ -153,7 +153,8 @@ impl Iterator for TableIter {
|
||||||
type Item = Record;
|
type Item = Record;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
self.root_page.borrow().get(self.index)
|
self.index += 1;
|
||||||
|
self.root_page.borrow().get(self.index - 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
16
src/value.rs
16
src/value.rs
|
|
@ -61,7 +61,7 @@ pub enum Datatype {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Value {
|
impl Value {
|
||||||
fn new(datatype: u64, data: Vec<u8>) -> Self {
|
pub(crate) fn new(datatype: u64, data: Vec<u8>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
datatype,
|
datatype,
|
||||||
data,
|
data,
|
||||||
|
|
@ -69,6 +69,14 @@ impl Value {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn from_raw(datatype_bytes: Vec<u8>, data: Vec<u8>) -> Self {
|
||||||
|
Self{
|
||||||
|
datatype: varint::read(&datatype_bytes).1,
|
||||||
|
datatype_bytes,
|
||||||
|
data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// get the length of the encoding of the value
|
/// get the length of the encoding of the value
|
||||||
pub fn bytes_len(&self) -> u16 {
|
pub fn bytes_len(&self) -> u16 {
|
||||||
(self.datatype_bytes.len() + self.data.len()) as u16
|
(self.datatype_bytes.len() + self.data.len()) as u16
|
||||||
|
|
@ -188,10 +196,10 @@ impl Into<Value> for &str {
|
||||||
|
|
||||||
impl Into<Value> for String {
|
impl Into<Value> for String {
|
||||||
fn into(self) -> Value {
|
fn into(self) -> Value {
|
||||||
if let Ok(f) = self.parse::<f64>() {
|
if let Ok(i) = self.parse::<i64>() {
|
||||||
Value::from_f64(f)
|
|
||||||
} else if let Ok(i) = self.parse::<i64>() {
|
|
||||||
Value::from_i64(i)
|
Value::from_i64(i)
|
||||||
|
} else if let Ok(f) = self.parse::<f64>() {
|
||||||
|
Value::from_f64(f)
|
||||||
} else {
|
} else {
|
||||||
Value::from_text(strip_quotes(self))
|
Value::from_text(strip_quotes(self))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue