Added Schema::json_schema_from_entity
This commit is contained in:
parent
1e496a25ad
commit
e896e0c7d8
@ -70,7 +70,7 @@ pub trait EntityTrait: EntityName {
|
|||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
type PrimaryKey: PrimaryKeyTrait + PrimaryKeyToColumn<Column = Self::Column>;
|
type PrimaryKey: PrimaryKeyTrait + PrimaryKeyToColumn<Column = Self::Column>;
|
||||||
|
|
||||||
/// Check if the relation belongs to an Entity
|
/// Construct a belongs to relation
|
||||||
fn belongs_to<R>(related: R) -> RelationBuilder<Self, R>
|
fn belongs_to<R>(related: R) -> RelationBuilder<Self, R>
|
||||||
where
|
where
|
||||||
R: EntityTrait,
|
R: EntityTrait,
|
||||||
@ -78,7 +78,7 @@ pub trait EntityTrait: EntityName {
|
|||||||
RelationBuilder::new(RelationType::HasOne, Self::default(), related, false)
|
RelationBuilder::new(RelationType::HasOne, Self::default(), related, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if the entity has at least one relation
|
/// Construct a has one relation
|
||||||
fn has_one<R>(_: R) -> RelationBuilder<Self, R>
|
fn has_one<R>(_: R) -> RelationBuilder<Self, R>
|
||||||
where
|
where
|
||||||
R: EntityTrait + Related<Self>,
|
R: EntityTrait + Related<Self>,
|
||||||
@ -86,7 +86,7 @@ pub trait EntityTrait: EntityName {
|
|||||||
RelationBuilder::from_rel(RelationType::HasOne, R::to().rev(), true)
|
RelationBuilder::from_rel(RelationType::HasOne, R::to().rev(), true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if the Entity has many relations
|
/// Construct a has many relation
|
||||||
fn has_many<R>(_: R) -> RelationBuilder<Self, R>
|
fn has_many<R>(_: R) -> RelationBuilder<Self, R>
|
||||||
where
|
where
|
||||||
R: EntityTrait + Related<Self>,
|
R: EntityTrait + Related<Self>,
|
||||||
|
@ -192,11 +192,8 @@ where
|
|||||||
E: EntityTrait,
|
E: EntityTrait,
|
||||||
{
|
{
|
||||||
let orm_column_def = column.def();
|
let orm_column_def = column.def();
|
||||||
let types = match orm_column_def.col_type {
|
let types = match &orm_column_def.col_type {
|
||||||
ColumnType::Enum {
|
ColumnType::Enum { name, variants } => match backend {
|
||||||
ref name,
|
|
||||||
ref variants,
|
|
||||||
} => match backend {
|
|
||||||
DbBackend::MySql => {
|
DbBackend::MySql => {
|
||||||
let variants: Vec<String> = variants.iter().map(|v| v.to_string()).collect();
|
let variants: Vec<String> = variants.iter().map(|v| v.to_string()).collect();
|
||||||
ColumnType::custom(format!("ENUM('{}')", variants.join("', '")).as_str())
|
ColumnType::custom(format!("ENUM('{}')", variants.join("', '")).as_str())
|
||||||
|
184
src/schema/json.rs
Normal file
184
src/schema/json.rs
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
use crate::{ColumnTrait, ColumnType, EntityTrait, Iden, Iterable, Schema};
|
||||||
|
use serde_json::{Map, Value};
|
||||||
|
|
||||||
|
impl Schema {
|
||||||
|
/// Construct a schema description in json for the given Entity.
|
||||||
|
pub fn json_schema_from_entity<E>(&self, entity: E) -> Value
|
||||||
|
where
|
||||||
|
E: EntityTrait,
|
||||||
|
{
|
||||||
|
json_schema_from_entity(entity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn json_schema_from_entity<E>(entity: E) -> Value
|
||||||
|
where
|
||||||
|
E: EntityTrait,
|
||||||
|
{
|
||||||
|
let mut obj = Map::new();
|
||||||
|
let mut cols = Vec::new();
|
||||||
|
|
||||||
|
if let Some(comment) = entity.comment() {
|
||||||
|
obj.insert("comment".to_owned(), Value::String(comment.to_owned()));
|
||||||
|
}
|
||||||
|
|
||||||
|
for column in E::Column::iter() {
|
||||||
|
let col = json_schema_from_entity_column::<E>(column);
|
||||||
|
cols.push(col);
|
||||||
|
}
|
||||||
|
obj.insert("columns".to_owned(), Value::Array(cols));
|
||||||
|
|
||||||
|
let mut pk = Vec::new();
|
||||||
|
for col in E::PrimaryKey::iter() {
|
||||||
|
pk.push(Value::String(col.to_string()));
|
||||||
|
}
|
||||||
|
obj.insert("primary_key".to_owned(), Value::Array(pk));
|
||||||
|
|
||||||
|
Value::Object(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn json_schema_from_entity_column<E>(column: E::Column) -> Value
|
||||||
|
where
|
||||||
|
E: EntityTrait,
|
||||||
|
{
|
||||||
|
let mut obj = Map::new();
|
||||||
|
|
||||||
|
let column_def = column.def();
|
||||||
|
obj.insert("name".to_owned(), Value::String(column.to_string()));
|
||||||
|
obj.insert(
|
||||||
|
"type".to_owned(),
|
||||||
|
type_def_from_column_def(&column_def.col_type),
|
||||||
|
);
|
||||||
|
obj.insert("nullable".to_owned(), Value::Bool(column_def.null));
|
||||||
|
if column_def.unique {
|
||||||
|
obj.insert("unique".to_owned(), Value::Bool(true));
|
||||||
|
}
|
||||||
|
if let Some(comment) = column_def.comment {
|
||||||
|
obj.insert("comment".to_owned(), Value::String(comment));
|
||||||
|
}
|
||||||
|
|
||||||
|
Value::Object(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn type_def_from_column_def(column_type: &ColumnType) -> Value {
|
||||||
|
match column_type {
|
||||||
|
ColumnType::Char(_) | ColumnType::String(_) | ColumnType::Text => {
|
||||||
|
Value::String("string".to_owned())
|
||||||
|
}
|
||||||
|
ColumnType::TinyInteger
|
||||||
|
| ColumnType::SmallInteger
|
||||||
|
| ColumnType::Integer
|
||||||
|
| ColumnType::BigInteger
|
||||||
|
| ColumnType::TinyUnsigned
|
||||||
|
| ColumnType::SmallUnsigned
|
||||||
|
| ColumnType::Unsigned
|
||||||
|
| ColumnType::BigUnsigned => Value::String("integer".to_owned()),
|
||||||
|
ColumnType::Float | ColumnType::Double => Value::String("real".to_owned()),
|
||||||
|
ColumnType::Decimal(_) | ColumnType::Money(_) => Value::String("decimal".to_owned()),
|
||||||
|
ColumnType::DateTime | ColumnType::Timestamp | ColumnType::TimestampWithTimeZone => {
|
||||||
|
Value::String("datetime".to_owned())
|
||||||
|
}
|
||||||
|
ColumnType::Time => Value::String("time".to_owned()),
|
||||||
|
ColumnType::Date => Value::String("date".to_owned()),
|
||||||
|
ColumnType::Year => Value::String("year".to_owned()),
|
||||||
|
ColumnType::Binary(_)
|
||||||
|
| ColumnType::VarBinary(_)
|
||||||
|
| ColumnType::Bit(_)
|
||||||
|
| ColumnType::VarBit(_) => Value::String("binary".to_owned()),
|
||||||
|
ColumnType::Boolean => Value::String("bool".to_owned()),
|
||||||
|
ColumnType::Json | ColumnType::JsonBinary => Value::String("json".to_owned()),
|
||||||
|
ColumnType::Uuid => Value::String("uuid".to_owned()),
|
||||||
|
ColumnType::Custom(typename) => Value::String(typename.to_string()),
|
||||||
|
ColumnType::Enum { name, variants } => {
|
||||||
|
let mut enum_def = Map::new();
|
||||||
|
enum_def.insert("name".to_owned(), Value::String(name.to_string()));
|
||||||
|
let variants: Vec<Value> = variants
|
||||||
|
.iter()
|
||||||
|
.map(|v| Value::String(v.to_string()))
|
||||||
|
.collect();
|
||||||
|
enum_def.insert("variants".to_owned(), Value::Array(variants));
|
||||||
|
Value::Object(enum_def)
|
||||||
|
}
|
||||||
|
ColumnType::Array(inner) => {
|
||||||
|
let mut obj = Map::new();
|
||||||
|
obj.insert("array".to_owned(), type_def_from_column_def(inner));
|
||||||
|
Value::Object(obj)
|
||||||
|
}
|
||||||
|
_ => Value::String("other".to_owned()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
use crate::{
|
||||||
|
tests_cfg::{cake, lunch_set},
|
||||||
|
DbBackend,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_json_schema_from_entity() {
|
||||||
|
let json = Schema::new(DbBackend::MySql).json_schema_from_entity(cake::Entity);
|
||||||
|
println!("{}", serde_json::to_string_pretty(&json).unwrap());
|
||||||
|
assert_eq!(
|
||||||
|
json,
|
||||||
|
serde_json::from_str::<Value>(
|
||||||
|
r#"{
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"nullable": false,
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "name",
|
||||||
|
"nullable": false,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"primary_key": [
|
||||||
|
"id"
|
||||||
|
]
|
||||||
|
}"#
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
|
let json = Schema::new(DbBackend::MySql).json_schema_from_entity(lunch_set::Entity);
|
||||||
|
println!("{}", serde_json::to_string_pretty(&json).unwrap());
|
||||||
|
assert_eq!(
|
||||||
|
json,
|
||||||
|
serde_json::from_str::<Value>(
|
||||||
|
r#"{
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"nullable": false,
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "name",
|
||||||
|
"nullable": false,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "tea",
|
||||||
|
"nullable": false,
|
||||||
|
"type": {
|
||||||
|
"name": "tea",
|
||||||
|
"variants": [
|
||||||
|
"EverydayTea",
|
||||||
|
"BreakfastTea"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"primary_key": [
|
||||||
|
"id"
|
||||||
|
]
|
||||||
|
}"#
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,8 @@
|
|||||||
use crate::DbBackend;
|
use crate::DbBackend;
|
||||||
|
|
||||||
mod entity;
|
mod entity;
|
||||||
|
#[cfg(feature = "serde_json")]
|
||||||
|
mod json;
|
||||||
|
|
||||||
/// This is a helper struct to convert [`EntityTrait`](crate::EntityTrait)
|
/// This is a helper struct to convert [`EntityTrait`](crate::EntityTrait)
|
||||||
/// into different [`sea_query`](crate::sea_query) statements.
|
/// into different [`sea_query`](crate::sea_query) statements.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user