starfish_core/schema/
entity.rs

1//! Define entity schema
2
3use super::Schema;
4use crate::{
5    entities::{
6        entity,
7        entity_attribute::{self, Datatype},
8    },
9    lang::EntityJson,
10};
11use sea_orm::{ActiveModelTrait, ConnectionTrait, DbConn, DbErr, DeriveIden, Set};
12use sea_query::{Alias, ColumnDef, Index, Table};
13
14impl Schema {
15    /// Insert entity metadata into database and create a corresponding node table
16    pub async fn create_entity(db: &DbConn, entity_json: EntityJson) -> Result<(), DbErr> {
17        let entity_json_bak = entity_json.clone();
18
19        let entity = entity::ActiveModel {
20            name: Set(entity_json.name),
21            ..Default::default()
22        }
23        .insert(db)
24        .await?;
25
26        for attribute in entity_json.attributes.into_iter() {
27            entity_attribute::ActiveModel {
28                entity_id: Set(entity.id),
29                name: Set(attribute.name),
30                datatype: Set(attribute.datatype),
31                ..Default::default()
32            }
33            .insert(db)
34            .await?;
35        }
36
37        Self::create_node_table(db, entity_json_bak).await
38    }
39
40    async fn create_node_table(db: &DbConn, entity_json: EntityJson) -> Result<(), DbErr> {
41        let table = Alias::new(entity_json.get_table_name().as_str());
42        let mut stmt = Table::create();
43        stmt.table(table.clone())
44            .col(
45                ColumnDef::new(Alias::new("id"))
46                    .integer()
47                    .not_null()
48                    .auto_increment()
49                    .primary_key(),
50            )
51            .col(
52                ColumnDef::new(Alias::new("name"))
53                    .string()
54                    .not_null()
55                    .unique_key(),
56            )
57            .index(
58                Index::create()
59                    .name(&format!("idx-{}-{}", table.to_string(), "name"))
60                    .table(table.clone())
61                    .col(Alias::new("name")),
62            );
63
64        for attribute in entity_json.attributes.into_iter() {
65            let mut column_def = ColumnDef::new(Alias::new(attribute.get_column_name().as_str()));
66            match attribute.datatype {
67                Datatype::Int => column_def.integer(),
68                Datatype::String => column_def.string(),
69            };
70            stmt.col(&mut column_def);
71        }
72
73        let builder = db.get_database_backend();
74        db.execute(builder.build(&stmt)).await?;
75
76        Ok(())
77    }
78}