mirror of
https://github.com/aljazceru/turso.git
synced 2026-02-23 08:55:40 +01:00
Schema in-memory data structures
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
mod buffer_pool;
|
||||
mod pager;
|
||||
mod schema;
|
||||
mod sqlite3_ondisk;
|
||||
mod vdbe;
|
||||
|
||||
|
||||
114
core/schema.rs
Normal file
114
core/schema.rs
Normal file
@@ -0,0 +1,114 @@
|
||||
use core::fmt;
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub struct Schema {
|
||||
pub tables: HashMap<String, Table>,
|
||||
}
|
||||
|
||||
impl Schema {
|
||||
pub fn new() -> Self {
|
||||
let mut tables: HashMap<String, Table> = HashMap::new();
|
||||
tables.insert("sqlite_schema".to_string(), sqlite_schema_table());
|
||||
Self { tables }
|
||||
}
|
||||
|
||||
pub fn add_table(&mut self, name: String, table: Table) {
|
||||
self.tables.insert(name, table);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Table {
|
||||
root_page: i32,
|
||||
name: String,
|
||||
columns: Vec<Column>,
|
||||
}
|
||||
|
||||
impl Table {
|
||||
pub fn to_sql(&self) -> String {
|
||||
let mut sql = format!("CREATE TABLE {} (\n", self.name);
|
||||
for (i, column) in self.columns.iter().enumerate() {
|
||||
if i > 0 {
|
||||
sql.push_str(",\n");
|
||||
}
|
||||
sql.push_str(" ");
|
||||
sql.push_str(&column.name);
|
||||
sql.push_str(" ");
|
||||
sql.push_str(&column.ty.to_string());
|
||||
}
|
||||
sql.push_str(");\n");
|
||||
sql
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Column {
|
||||
name: String,
|
||||
ty: Type,
|
||||
}
|
||||
|
||||
pub enum Type {
|
||||
Null,
|
||||
Integer,
|
||||
Real,
|
||||
Text,
|
||||
Blob,
|
||||
}
|
||||
|
||||
impl fmt::Display for Type {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let s = match self {
|
||||
Type::Null => "NULL",
|
||||
Type::Integer => "INTEGER",
|
||||
Type::Real => "REAL",
|
||||
Type::Text => "TEXT",
|
||||
Type::Blob => "BLOB",
|
||||
};
|
||||
write!(f, "{}", s)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sqlite_schema_table() -> Table {
|
||||
Table {
|
||||
root_page: 1,
|
||||
name: "sqlite_schema".to_string(),
|
||||
columns: vec![
|
||||
Column {
|
||||
name: "type".to_string(),
|
||||
ty: Type::Text,
|
||||
},
|
||||
Column {
|
||||
name: "name".to_string(),
|
||||
ty: Type::Text,
|
||||
},
|
||||
Column {
|
||||
name: "tbl_name".to_string(),
|
||||
ty: Type::Text,
|
||||
},
|
||||
Column {
|
||||
name: "rootpage".to_string(),
|
||||
ty: Type::Integer,
|
||||
},
|
||||
Column {
|
||||
name: "sql".to_string(),
|
||||
ty: Type::Text,
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
pub fn test_sqlite_schema() {
|
||||
let expected = r#"CREATE TABLE sqlite_schema (
|
||||
type TEXT,
|
||||
name TEXT,
|
||||
tbl_name TEXT,
|
||||
rootpage INTEGER,
|
||||
sql TEXT);
|
||||
"#;
|
||||
let actual = sqlite_schema_table().to_sql();
|
||||
assert_eq!(expected, actual);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
use crate::pager::Pager;
|
||||
use crate::schema::Schema;
|
||||
|
||||
use anyhow::Result;
|
||||
use sqlite3_parser::ast::{Select, Stmt};
|
||||
@@ -31,6 +32,7 @@ pub struct GotoInsn {
|
||||
pub target_pc: usize,
|
||||
}
|
||||
pub struct Program {
|
||||
pub schema: Schema,
|
||||
pub insns: Vec<Insn>,
|
||||
pub pc: usize,
|
||||
}
|
||||
@@ -64,6 +66,7 @@ impl ProgramBuilder {
|
||||
|
||||
pub fn build(self) -> Program {
|
||||
Program {
|
||||
schema: Schema::new(),
|
||||
insns: self.insns,
|
||||
pc: 0,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user