feat: implements table, columns serialization
This commit is contained in:
107
Cargo.lock
generated
Normal file
107
Cargo.lock
generated
Normal file
@@ -0,0 +1,107 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "db_builder"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.106"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_core"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.149"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
"serde",
|
||||
"serde_core",
|
||||
"zmij",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.117"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
||||
|
||||
[[package]]
|
||||
name = "zmij"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
|
||||
8
Cargo.toml
Normal file
8
Cargo.toml
Normal file
@@ -0,0 +1,8 @@
|
||||
[package]
|
||||
name = "db_builder"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
serde_json = "1.0.149"
|
||||
serde = { version = "1.0.228", features = ["derive"] }
|
||||
3
src/lib.rs
Normal file
3
src/lib.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
mod mappings;
|
||||
mod schemas;
|
||||
mod query_builders;
|
||||
66
src/mappings/mod.rs
Normal file
66
src/mappings/mod.rs
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
This module is used to make mapping between Rust and SQLite
|
||||
*/
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, Deserialize, Serialize, Default)]
|
||||
pub enum SQLiteDatatypes {
|
||||
Integer,
|
||||
Real,
|
||||
#[default]
|
||||
Text,
|
||||
Blob,
|
||||
Null,
|
||||
Numeric,
|
||||
Any,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, Deserialize, Default)]
|
||||
pub enum SupportedTypes {
|
||||
I32,
|
||||
I64,
|
||||
F64,
|
||||
#[default]
|
||||
String,
|
||||
VecU8,
|
||||
Bool,
|
||||
Option,
|
||||
}
|
||||
|
||||
impl From<SupportedTypes> for SQLiteDatatypes {
|
||||
fn from(t: SupportedTypes) -> Self {
|
||||
match t {
|
||||
SupportedTypes::I32 | SupportedTypes::I64 | SupportedTypes::Bool => SQLiteDatatypes::Integer,
|
||||
SupportedTypes::F64 => SQLiteDatatypes::Real,
|
||||
SupportedTypes::String => SQLiteDatatypes::Text,
|
||||
SupportedTypes::VecU8 => SQLiteDatatypes::Blob,
|
||||
SupportedTypes::Option => SQLiteDatatypes::Any,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SQLiteDatatypes> for SupportedTypes {
|
||||
fn from(t: SQLiteDatatypes) -> Self {
|
||||
match t {
|
||||
SQLiteDatatypes::Integer => SupportedTypes::I64,
|
||||
SQLiteDatatypes::Real | SQLiteDatatypes::Numeric => SupportedTypes::F64,
|
||||
SQLiteDatatypes::Text => SupportedTypes::String,
|
||||
SQLiteDatatypes::Blob => SupportedTypes::VecU8,
|
||||
SQLiteDatatypes::Null | SQLiteDatatypes::Any => SupportedTypes::Option,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SQLiteDatatypes> for String {
|
||||
fn from(t: SQLiteDatatypes) -> Self {
|
||||
match t {
|
||||
SQLiteDatatypes::Integer => String::from("INTEGER"),
|
||||
SQLiteDatatypes::Real => String::from("REAL"),
|
||||
SQLiteDatatypes::Text => String::from("TEXT"),
|
||||
SQLiteDatatypes::Blob => String::from("BLOB"),
|
||||
SQLiteDatatypes::Any => String::from("ANY"),
|
||||
SQLiteDatatypes::Null => String::from("NULL"),
|
||||
SQLiteDatatypes::Numeric => String::from("NUMERIC")
|
||||
}
|
||||
}
|
||||
}
|
||||
109
src/query_builders/column_sql_serializer.rs
Normal file
109
src/query_builders/column_sql_serializer.rs
Normal file
@@ -0,0 +1,109 @@
|
||||
use crate::mappings::SQLiteDatatypes;
|
||||
use crate::schemas::entities::Column;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct ColumnSqlSerializer {}
|
||||
|
||||
impl ColumnSqlSerializer {
|
||||
pub fn new() -> Self {
|
||||
ColumnSqlSerializer {}
|
||||
}
|
||||
|
||||
pub fn serialize(self, column: Column) -> Result<String, String> {
|
||||
let mut query = String::from(column.name);
|
||||
query.push(' ');
|
||||
|
||||
query += &*String::from(column.datatype);
|
||||
query.push(' ');
|
||||
|
||||
if !column.nullable {
|
||||
query += "NOT NULL " // Notice the space at the end
|
||||
}
|
||||
|
||||
if column.unique {
|
||||
query += "UNIQUE " // Notice the space at the end
|
||||
}
|
||||
|
||||
if column.auto_increment {
|
||||
query += "AUTO_INCREMENT " // Notice the space at the end
|
||||
}
|
||||
|
||||
if let Some(default) = column.default {
|
||||
match column.datatype {
|
||||
SQLiteDatatypes::Text | SQLiteDatatypes::Blob => {
|
||||
query += &format!("DEFAULT '{}' ", default);
|
||||
},
|
||||
SQLiteDatatypes::Numeric | SQLiteDatatypes::Integer | SQLiteDatatypes::Real => {
|
||||
query += &format!("DEFAULT {} ", default);
|
||||
},
|
||||
SQLiteDatatypes::Any | SQLiteDatatypes::Null => {
|
||||
return Err("No default value can be set with Any and Null".to_string())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(check_constraint) = column.check_constraint {
|
||||
query += &format!("CHECK {} ", check_constraint);
|
||||
}
|
||||
|
||||
if column.primary_key {
|
||||
query += "PRIMARY KEY ";
|
||||
}
|
||||
|
||||
query.push(',');
|
||||
Ok(query)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::super::super::schemas::builders::ColumnBuilder;
|
||||
use crate::mappings::SQLiteDatatypes;
|
||||
use crate::query_builders::column_sql_serializer::ColumnSqlSerializer;
|
||||
|
||||
#[test]
|
||||
pub fn test_column_sql_serializer() {
|
||||
let column = ColumnBuilder::new()
|
||||
.with_name("id".to_string())
|
||||
.with_datatype(SQLiteDatatypes::Integer)
|
||||
.with_auto_increment()
|
||||
.with_primary_key()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let serializer = ColumnSqlSerializer::new();
|
||||
let result = serializer.serialize(column).unwrap();
|
||||
|
||||
assert_eq!(result, "id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY ,".to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_column_sql_serializer_with_text_default() {
|
||||
let column = ColumnBuilder::new()
|
||||
.with_name("name".to_string())
|
||||
.with_datatype(SQLiteDatatypes::Text)
|
||||
.with_default("None".to_string())
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let serializer = ColumnSqlSerializer::new();
|
||||
let result = serializer.serialize(column).unwrap();
|
||||
|
||||
assert_eq!(result, "name TEXT NOT NULL DEFAULT 'None' ,".to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_column_sql_serializer_with_integer_default() {
|
||||
let column = ColumnBuilder::new()
|
||||
.with_name("age".to_string())
|
||||
.with_datatype(SQLiteDatatypes::Integer)
|
||||
.with_default("18".to_string())
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let serializer = ColumnSqlSerializer::new();
|
||||
let result = serializer.serialize(column).unwrap();
|
||||
|
||||
assert_eq!(result, "age INTEGER NOT NULL DEFAULT 18 ,".to_string());
|
||||
}
|
||||
}
|
||||
2
src/query_builders/mod.rs
Normal file
2
src/query_builders/mod.rs
Normal file
@@ -0,0 +1,2 @@
|
||||
mod column_sql_serializer;
|
||||
mod table_sql_serializer;
|
||||
52
src/query_builders/table_sql_serializer.rs
Normal file
52
src/query_builders/table_sql_serializer.rs
Normal file
@@ -0,0 +1,52 @@
|
||||
use crate::query_builders::column_sql_serializer::ColumnSqlSerializer;
|
||||
use crate::schemas::entities::Table;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct TableSqlSerializer {}
|
||||
|
||||
impl TableSqlSerializer {
|
||||
pub fn new() -> Self {
|
||||
TableSqlSerializer{}
|
||||
}
|
||||
|
||||
pub fn serialize(self, table: Table) -> String {
|
||||
let mut query = String::from("CREATE TABLE ");
|
||||
query += &format!("{} (\n", table.name);
|
||||
|
||||
let column_serializer = ColumnSqlSerializer::new();
|
||||
for column in table.columns {
|
||||
query += &column_serializer.serialize(column).unwrap();
|
||||
}
|
||||
|
||||
query += ");";
|
||||
query
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::mappings::SQLiteDatatypes;
|
||||
use crate::query_builders::table_sql_serializer::TableSqlSerializer;
|
||||
use crate::schemas::builders::{ColumnBuilder, TableBuilder};
|
||||
|
||||
#[test]
|
||||
pub fn test_table_sql_serializer() {
|
||||
let column = ColumnBuilder::new()
|
||||
.with_name("id".to_string())
|
||||
.with_datatype(SQLiteDatatypes::Integer)
|
||||
.with_auto_increment()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let table = TableBuilder::new()
|
||||
.with_name("test".to_string())
|
||||
.with_column(column)
|
||||
.build();
|
||||
|
||||
let serializer = TableSqlSerializer::new();
|
||||
|
||||
let result = serializer.serialize(table);
|
||||
|
||||
assert_eq!(result, "CREATE TABLE test (\nid INTEGER NOT NULL AUTO_INCREMENT ,);".to_string());
|
||||
}
|
||||
}
|
||||
182
src/schemas/builders.rs
Normal file
182
src/schemas/builders.rs
Normal file
@@ -0,0 +1,182 @@
|
||||
use crate::mappings::SQLiteDatatypes;
|
||||
use crate::schemas::entities::{Column, Table};
|
||||
|
||||
pub struct ColumnBuilder {
|
||||
name: String,
|
||||
datatype: SQLiteDatatypes,
|
||||
nullable: bool,
|
||||
default: Option<String>,
|
||||
auto_increment: bool,
|
||||
unique: bool,
|
||||
check_constraint: Option<String>,
|
||||
primary_key: bool,
|
||||
}
|
||||
|
||||
impl ColumnBuilder {
|
||||
pub fn new() -> ColumnBuilder {
|
||||
ColumnBuilder {
|
||||
name: String::new(),
|
||||
datatype: SQLiteDatatypes::Text,
|
||||
nullable: false,
|
||||
default: None,
|
||||
auto_increment: false,
|
||||
unique: false,
|
||||
check_constraint: None,
|
||||
primary_key: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_name(mut self, name: String) -> Self {
|
||||
self.name = name;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_datatype(mut self, datatype: SQLiteDatatypes) -> Self {
|
||||
self.datatype = datatype;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_nullable(mut self) -> Self {
|
||||
self.nullable = true;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_default(mut self, default: String) -> Self {
|
||||
self.default = Some(default);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_auto_increment(mut self) -> Self {
|
||||
self.auto_increment = true;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_unique(mut self) -> Self {
|
||||
self.unique = true;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_check_constraint(mut self, constraint: String) -> Self {
|
||||
self.check_constraint = Some(constraint);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_primary_key(mut self) -> Self {
|
||||
self.primary_key = true;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> Result<Column, String> {
|
||||
if self.auto_increment && self.datatype != SQLiteDatatypes::Integer {
|
||||
return Err("Cannot set AUTO_INCREMENT on non-INTEGER column".to_string());
|
||||
}
|
||||
|
||||
Ok(Column::new(
|
||||
self.name,
|
||||
self.datatype,
|
||||
self.nullable,
|
||||
self.default,
|
||||
self.auto_increment,
|
||||
self.unique,
|
||||
self.check_constraint,
|
||||
self.primary_key,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TableBuilder {
|
||||
name: String,
|
||||
columns: Vec<Column>,
|
||||
strict: bool
|
||||
}
|
||||
|
||||
impl TableBuilder {
|
||||
pub fn new() -> TableBuilder {
|
||||
TableBuilder {
|
||||
name: String::new(),
|
||||
columns: Vec::new(),
|
||||
strict: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_name(mut self, name: String) -> Self {
|
||||
self.name = name;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_strict(mut self) -> Self {
|
||||
self.strict = true;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_column(mut self, column: Column) -> Self {
|
||||
self.columns.push(column);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> Table {
|
||||
Table::new(self.name, self.columns, self.strict)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::mappings::SQLiteDatatypes;
|
||||
use crate::schemas::builders::{ColumnBuilder, TableBuilder};
|
||||
|
||||
#[test]
|
||||
fn test_column_builder() {
|
||||
let result = ColumnBuilder::new()
|
||||
.with_name("name".to_string())
|
||||
.with_datatype(SQLiteDatatypes::Text)
|
||||
.with_nullable()
|
||||
.build();
|
||||
|
||||
match result {
|
||||
Ok(column) => {
|
||||
assert_eq!(column.name, String::from("name"));
|
||||
assert_eq!(column.datatype, SQLiteDatatypes::Text);
|
||||
assert_eq!(column.nullable, true);
|
||||
},
|
||||
Err(_) => {
|
||||
assert!(false, "should not fail");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_column_builder_should_fail() {
|
||||
let result = ColumnBuilder::new()
|
||||
.with_name("name".to_string())
|
||||
.with_datatype(SQLiteDatatypes::Blob)
|
||||
.with_auto_increment()
|
||||
.build();
|
||||
|
||||
match result {
|
||||
Ok(_) => {
|
||||
assert!(false, "Should not make auto increment with another type than integer")
|
||||
},
|
||||
Err(_) => {
|
||||
assert!(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_table_builder() {
|
||||
let column = ColumnBuilder::new()
|
||||
.with_name("id".to_string())
|
||||
.with_datatype(SQLiteDatatypes::Integer)
|
||||
.with_auto_increment()
|
||||
.build()
|
||||
.expect("Failed to create id column");
|
||||
|
||||
let table = TableBuilder::new()
|
||||
.with_name("my_table".to_string())
|
||||
.with_column(column.clone())
|
||||
.build();
|
||||
|
||||
assert_eq!(table.name, String::from("my_table"));
|
||||
assert_eq!(*table.columns.first().unwrap(), column);
|
||||
}
|
||||
}
|
||||
46
src/schemas/entities.rs
Normal file
46
src/schemas/entities.rs
Normal file
@@ -0,0 +1,46 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use crate::mappings::SQLiteDatatypes;
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Default, Clone)]
|
||||
pub struct Table {
|
||||
pub name: String,
|
||||
pub columns: Vec<Column>,
|
||||
pub strict: bool
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Default, Clone, PartialEq)]
|
||||
pub struct Column {
|
||||
pub name: String,
|
||||
pub datatype: SQLiteDatatypes,
|
||||
pub nullable: bool,
|
||||
pub default: Option<String>,
|
||||
pub auto_increment: bool,
|
||||
pub unique: bool,
|
||||
pub check_constraint: Option<String>, // raw check constraint
|
||||
pub primary_key: bool
|
||||
}
|
||||
|
||||
impl Table {
|
||||
pub fn new(name: String, columns: Vec<Column>, strict: bool) -> Table {
|
||||
Table {
|
||||
name,
|
||||
columns,
|
||||
strict
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Column {
|
||||
pub fn new(name: String, datatype: SQLiteDatatypes, nullable: bool, default: Option<String>, auto_increment: bool, unique: bool, check_constraint: Option<String>, primary_key: bool) -> Column {
|
||||
Column {
|
||||
name,
|
||||
datatype,
|
||||
nullable,
|
||||
default,
|
||||
auto_increment,
|
||||
unique,
|
||||
check_constraint,
|
||||
primary_key
|
||||
}
|
||||
}
|
||||
}
|
||||
4
src/schemas/mod.rs
Normal file
4
src/schemas/mod.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
pub(crate) mod reader;
|
||||
pub(crate) mod entities;
|
||||
pub(crate) mod builders;
|
||||
mod writer;
|
||||
23
src/schemas/reader.rs
Normal file
23
src/schemas/reader.rs
Normal file
@@ -0,0 +1,23 @@
|
||||
use std::fs;
|
||||
use crate::schemas::entities::Table;
|
||||
|
||||
pub struct SchemaParsingFacade {}
|
||||
|
||||
impl SchemaParsingFacade {
|
||||
pub fn new() -> SchemaParsingFacade {
|
||||
SchemaParsingFacade{}
|
||||
}
|
||||
|
||||
pub fn parse(&self, path: String) -> Vec<Table> {
|
||||
let json_schema = self.read_schema_file(path);
|
||||
self.parse_schema_file(json_schema)
|
||||
}
|
||||
|
||||
fn read_schema_file(&self, path: String) -> String {
|
||||
fs::read_to_string(path).expect("Error reading schema files")
|
||||
}
|
||||
|
||||
fn parse_schema_file(&self, json_schema: String) -> Vec<Table> {
|
||||
serde_json::from_str(&json_schema).expect("Error parsing JSON schema")
|
||||
}
|
||||
}
|
||||
32
src/schemas/writer.rs
Normal file
32
src/schemas/writer.rs
Normal file
@@ -0,0 +1,32 @@
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use crate::schemas::entities::Table;
|
||||
|
||||
pub struct SchemaWriter {
|
||||
tables: Vec<Table>
|
||||
}
|
||||
|
||||
impl SchemaWriter {
|
||||
pub fn new() -> Self {
|
||||
SchemaWriter{
|
||||
tables: Vec::new()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_table(mut self, table: Table) -> Self {
|
||||
self.tables.push(table);
|
||||
self
|
||||
}
|
||||
|
||||
// create_schemas create the schema as a JSON file. the name doesn't need to have the ".json"
|
||||
pub fn create_schemas(self, schema_name: String) -> Result<(), String> {
|
||||
let schema_file_path = format!("{}.json", schema_name);
|
||||
|
||||
let content_result = serde_json::to_string(self.tables.as_slice()).expect("Error serializing tables");
|
||||
|
||||
let mut schema_file = File::create(schema_file_path).expect("Failed to create schema file");
|
||||
schema_file.write_all(content_result.as_bytes()).expect("Error writing in schema file");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user