use std::collections::BTreeMap;
use serde::Deserialize;
use super::{
Column, Constraint, EnumDef, ExtensionDef, ForeignKey, FunctionDef, Index, OpaqueMeta,
PrimaryKey, Schema, Table, TableOptionsMeta, TriggerDef, ViewDef, Volatility,
};
#[derive(Debug, Clone, Default, Deserialize, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct InputSchema {
#[serde(default)]
pub tables: BTreeMap<String, TableInput>,
#[serde(default)]
pub views: BTreeMap<String, ViewInput>,
#[serde(default)]
pub functions: BTreeMap<String, FunctionInput>,
#[serde(default)]
pub extensions: BTreeMap<String, ExtensionInput>,
#[serde(default)]
pub enums: BTreeMap<String, EnumInput>,
}
impl InputSchema {
pub fn into_schema(self) -> Schema {
Schema {
tables: self
.tables
.into_iter()
.map(|(key, table)| (key, table.into_table()))
.collect(),
views: self
.views
.into_iter()
.map(|(key, view)| (key, view.into_view()))
.collect(),
functions: self
.functions
.into_iter()
.map(|(key, function)| (key, function.into_function()))
.collect(),
extensions: self
.extensions
.into_iter()
.map(|(key, extension)| (key, extension.into_extension()))
.collect(),
enums: self
.enums
.into_iter()
.map(|(key, enum_def)| (key, enum_def.into_enum()))
.collect(),
}
}
}
#[derive(Debug, Clone, Deserialize, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct TableInput {
#[serde(default)]
pub name: String,
#[serde(default)]
pub schema: Option<String>,
#[serde(default)]
pub primary_key: Option<PrimaryKey>,
pub columns: Vec<Column>,
#[serde(default)]
pub foreign_keys: Vec<ForeignKey>,
#[serde(default)]
pub indexes: Vec<IndexInput>,
#[serde(default)]
pub constraints: Vec<ConstraintInput>,
#[serde(default)]
pub triggers: Vec<TriggerInput>,
}
impl TableInput {
fn into_table(self) -> Table {
Table {
name: self.name,
schema: self.schema,
primary_key: self.primary_key,
columns: self.columns,
foreign_keys: self.foreign_keys,
indexes: self
.indexes
.into_iter()
.map(IndexInput::into_index)
.collect(),
constraints: self
.constraints
.into_iter()
.map(ConstraintInput::into_constraint)
.collect(),
triggers: self
.triggers
.into_iter()
.map(TriggerInput::into_trigger)
.collect(),
options: TableOptionsMeta::default(),
}
}
}
#[derive(Debug, Clone, Deserialize, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct IndexInput {
#[serde(default)]
pub name: String,
pub columns: Vec<String>,
#[serde(default)]
pub unique: bool,
#[serde(default)]
pub predicate: Option<String>,
}
impl IndexInput {
fn into_index(self) -> Index {
Index {
name: self.name,
columns: self.columns,
unique: self.unique,
predicate: self.predicate,
opaque: OpaqueMeta::default(),
}
}
}
#[derive(Debug, Clone, Deserialize, PartialEq)]
#[serde(tag = "kind", rename_all = "snake_case", deny_unknown_fields)]
pub enum ConstraintInput {
Unique {
#[serde(default)]
name: String,
columns: Vec<String>,
},
Check {
#[serde(default)]
name: String,
expression: String,
},
}
impl ConstraintInput {
fn into_constraint(self) -> Constraint {
match self {
Self::Unique { name, columns } => Constraint::Unique { name, columns },
Self::Check { name, expression } => Constraint::Check { name, expression },
}
}
}
#[derive(Debug, Clone, Deserialize, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct TriggerInput {
#[serde(default)]
pub name: Option<String>,
pub timing: super::TriggerTiming,
pub events: Vec<super::TriggerEvent>,
pub scope: super::TriggerScope,
#[serde(default)]
pub function_name: Option<String>,
#[serde(default)]
pub when: Option<String>,
#[serde(default)]
pub query: Option<String>,
#[serde(default)]
pub language: Option<String>,
}
impl TriggerInput {
fn into_trigger(self) -> TriggerDef {
TriggerDef {
name: self.name,
timing: self.timing,
events: self.events,
scope: self.scope,
function_name: self.function_name,
when: self.when,
query: self.query,
language: self.language,
opaque: OpaqueMeta::default(),
}
}
}
#[derive(Debug, Clone, Deserialize, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct FunctionInput {
pub name: String,
#[serde(default)]
pub schema: Option<String>,
pub arguments: String,
pub returns: String,
pub language: String,
pub body: String,
#[serde(default)]
pub volatility: Volatility,
#[serde(default)]
pub security_definer: bool,
}
impl FunctionInput {
fn into_function(self) -> FunctionDef {
FunctionDef {
name: self.name,
schema: self.schema,
arguments: self.arguments,
returns: self.returns,
language: self.language,
body: self.body,
volatility: self.volatility,
security_definer: self.security_definer,
opaque: OpaqueMeta::default(),
}
}
}
#[derive(Debug, Clone, Deserialize, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct ViewInput {
pub name: String,
#[serde(default)]
pub schema: Option<String>,
pub definition: String,
}
impl ViewInput {
fn into_view(self) -> ViewDef {
ViewDef {
name: self.name,
schema: self.schema,
definition: self.definition,
opaque: OpaqueMeta::default(),
}
}
}
#[derive(Debug, Clone, Deserialize, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct ExtensionInput {
pub name: String,
#[serde(default)]
pub schema: Option<String>,
#[serde(default)]
pub version: Option<String>,
}
impl ExtensionInput {
fn into_extension(self) -> ExtensionDef {
ExtensionDef {
name: self.name,
schema: self.schema,
version: self.version,
opaque: OpaqueMeta::default(),
}
}
}
#[derive(Debug, Clone, Deserialize, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct EnumInput {
pub name: String,
#[serde(default)]
pub schema: Option<String>,
pub values: Vec<String>,
}
impl EnumInput {
fn into_enum(self) -> EnumDef {
EnumDef {
name: self.name,
schema: self.schema,
values: self.values,
opaque: OpaqueMeta::default(),
}
}
}