Compare commits

..

No commits in common. "fe5ae0de75983135aa9e9bc7f1cf0326f53ea612" and "b93f037017e768150d109bdc08f53f3c6918256f" have entirely different histories.

7 changed files with 35 additions and 157 deletions

View file

@ -1,7 +1,5 @@
set dotenv-load := true set dotenv-load := true
dev: dev:
cargo run --bin cli -- query "SELECT * FROM sources;" # cargo run --bin cli -- query "SELECT * FROM sources;"
cargo run --bin cli -- discover
build-schema:
cargo run --bin cli -- discover -c examples/schema.toml -o examples/schema.toml

21
example/schema.toml Normal file
View file

@ -0,0 +1,21 @@
[public]
[public.entries]
name = "entries"
display_name = "entries"
columns = [
{ name = "id", col_type = "Integer", default = false, not_null = true, reference = { table = "", identity = "", label = "" } },
]
[public.sources]
name = "sources"
display_name = "Sources"
[[public.sources.columns]]
name = "id"
col_type = "Integer"
default = false
not_null = true
reference = { table = "", identity = "", label = "" }

View file

@ -1,110 +0,0 @@
[public.entry_categories]
display_name = "Entry Categories"
[[public.entry_categories.columns]]
name = "entry_id"
type = "Integer"
not_null = true
reference = { table = "entries", identity = "id", label = "Entry Id" }
[[public.entry_categories.columns]]
name = "entry_date"
type = "Date"
not_null = true
reference = { table = "entries", identity = "id", label = "Entry Id" }
[[public.entry_categories.columns]]
name = "category_id"
type = "Integer"
not_null = true
reference = { table = "categories", identity = "id", label = "Category Id" }
[public.entries]
display_name = "Entries"
[[public.entries.columns]]
name = "id"
type = "Integer"
default = "nextval('entries_id_seq'::regclass)"
not_null = true
[[public.entries.columns]]
name = "date"
type = "Date"
default = "CURRENT_TIMESTAMP"
not_null = true
[[public.entries.columns]]
name = "source_id"
type = "Integer"
not_null = true
reference = { table = "sources", identity = "id", label = "Source Id" }
[[public.entries.columns]]
name = "uid"
not_null = true
type = { Varchar = {} }
[[public.entries.columns]]
name = "text"
type = "Text"
not_null = false
[public.categories]
display_name = "Categories"
[[public.categories.columns]]
name = "id"
type = "Integer"
default = "nextval('category_id_seq'::regclass)"
not_null = true
[[public.categories.columns]]
name = "name"
not_null = true
type = { Varchar = { length = 20 } }
[[public.categories.columns]]
name = "uid"
not_null = false
type = { Varchar = { length = 8 } }
[public.sources]
display_name = "Sources"
[[public.sources.columns]]
name = "id"
type = "Integer"
default = "nextval('sources_id_seq'::regclass)"
not_null = true
[[public.sources.columns]]
name = "name"
not_null = true
type = { Varchar = { length = 20 } }
[[public.sources.columns]]
name = "uid"
not_null = true
type = { Varchar = { length = 8 } }
[[public.sources.columns]]
name = "uri"
not_null = true
type = { Varchar = {} }
[[public.sources.columns]]
name = "created_at"
default = "CURRENT_TIMESTAMP"
not_null = true
type = { TimestampWithTimeZone = { precision = 6 } }
[[public.sources.columns]]
name = "updated_at"
not_null = false
type = { TimestampWithTimeZone = { precision = 6 } }
[[public.sources.columns]]
name = "deleted_at"
not_null = false
type = { TimestampWithTimeZone = { precision = 6 } }

View file

@ -1,8 +1,6 @@
#![allow(unused)] #![allow(unused)]
#![allow(dead_code)] #![allow(dead_code)]
use std::path::PathBuf;
use clap::{Parser, Subcommand}; use clap::{Parser, Subcommand};
use simple_crud::error::Error; use simple_crud::error::Error;
use simple_crud::error::Result; use simple_crud::error::Result;
@ -19,9 +17,6 @@ struct Cli {
#[arg(short = 'u', long, global = true, env = "CLI_DB_URL")] #[arg(short = 'u', long, global = true, env = "CLI_DB_URL")]
db_url: Option<String>, db_url: Option<String>,
#[arg(short, long, global = true, env = "CLI_CONFIG")]
config_file: Option<PathBuf>,
} }
#[derive(Subcommand)] #[derive(Subcommand)]
@ -57,7 +52,7 @@ async fn main() -> Result<()> {
let result = match &cli.command { let result = match &cli.command {
Commands::Query { sql } => sql::handle_query(url, sql).await, Commands::Query { sql } => sql::handle_query(url, sql).await,
Commands::Discover { schema, output } => { Commands::Discover { schema, output } => {
sql::discover_scheme(url, cli.config_file, schema.to_owned(), output.to_owned()).await sql::discover_scheme(url, schema.to_owned(), output.to_owned()).await
} }
}; };

View file

@ -17,9 +17,6 @@ pub enum Error {
#[error(transparent)] #[error(transparent)]
TomlEncoding(#[from] toml::ser::Error), TomlEncoding(#[from] toml::ser::Error),
#[error(transparent)]
TomlDecodign(#[from] toml::de::Error),
#[error(transparent)] #[error(transparent)]
ParseError(#[from] url::ParseError), ParseError(#[from] url::ParseError),

View file

@ -1,6 +1,6 @@
use std::fs::File; use std::fs::File;
use std::io; use std::io;
use std::path::{Path, PathBuf}; use std::path::Path;
use clap::ValueEnum; use clap::ValueEnum;
use sea_schema::postgres::discovery::SchemaDiscovery; use sea_schema::postgres::discovery::SchemaDiscovery;
@ -49,7 +49,6 @@ pub async fn handle_query(url: String, query: &String) -> Result<()> {
pub async fn discover_scheme( pub async fn discover_scheme(
url: String, url: String,
config_file: Option<PathBuf>,
schema: Option<String>, schema: Option<String>,
output: Option<String>, output: Option<String>,
) -> Result<()> { ) -> Result<()> {
@ -69,23 +68,15 @@ pub async fn discover_scheme(
} }
}; };
let mut data_model = DataModel::new(config_file)?;
println!("{:?}", data_model);
let schema = schema_discovery.discover().await?; let schema = schema_discovery.discover().await?;
data_model.insert_schema(schema.schema.to_owned(), Schema::from(schema)); let mut data_model = DataModel::new();
data_model
.schemas
.insert(schema.schema.to_owned(), Schema::from(schema));
let mut buffer: Box<dyn io::Write> = match output { let mut buffer: Box<dyn io::Write> = match output {
Some(path) => { Some(path) => Box::new(File::create(Path::new(&path))?),
let path = Path::new(&path);
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent)?;
}
Box::new(File::create(path)?)
}
None => Box::new(io::stdout()), None => Box::new(io::stdout()),
}; };

View file

@ -2,14 +2,12 @@ use heck::ToTitleCase;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::collections::HashMap; use std::collections::HashMap;
use std::fmt; use std::fmt;
use std::fs::read_to_string;
use std::io::Write; use std::io::Write;
use std::path::PathBuf;
use toml_edit::visit_mut::VisitMut; use toml_edit::visit_mut::VisitMut;
use sea_schema::postgres::def as sea_schema_def; use sea_schema::postgres::def as sea_schema_def;
use crate::error::{self, Result}; use crate::error;
struct InlineTableFix; struct InlineTableFix;
@ -38,27 +36,15 @@ impl VisitMut for InlineTableFix {
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct DataModel { pub struct DataModel {
#[serde(flatten)] #[serde(flatten)]
schemas: HashMap<String, Schema>, pub schemas: HashMap<String, Schema>,
} }
impl DataModel { impl DataModel {
pub fn new(path: Option<PathBuf>) -> Result<Self> { pub fn new() -> Self {
match path { Self {
Some(path) => { schemas: HashMap::new(),
let content = read_to_string(&path)?;
let data_model: Self = toml::from_str(&content)?;
Ok(data_model)
}
None => Ok(Self {
schemas: HashMap::new(),
}),
} }
} }
pub fn insert_schema(&mut self, name: String, schema: Schema) {
self.schemas.insert(name, schema);
}
} }
impl DataModel { impl DataModel {