1use crate::args::Args;
2use crate::model::data::ModelData;
3use crate::model::{ModelMigration, ModelType};
4use colored::Colorize;
5use scylla::client::session::Session;
6
7use charybdis_parser::schema::code_schema::CodeSchema;
8use charybdis_parser::schema::db_schema::DbSchema;
9use charybdis_parser::schema::SchemaObject;
10
11pub struct Migration<'a> {
12 current_db_schema: DbSchema,
13 current_code_schema: CodeSchema,
14 session: &'a Session,
15 args: Args,
16}
17
18impl<'a> Migration<'a> {
19 pub fn new(current_db_schema: DbSchema, current_code_schema: CodeSchema, session: &'a Session, args: Args) -> Self {
20 Migration {
21 current_db_schema,
22 current_code_schema,
23 session,
24 args,
25 }
26 }
27
28 pub async fn run(&self) {
29 self.run_udts().await;
30 self.run_tables().await;
31 self.run_materialized_views().await;
32
33 println!("\n{}", "Migration plan ran successfully!".bright_green());
34 }
35
36 pub async fn write_schema_to_json(&self) {
37 DbSchema::new(self.session, self.args.keyspace.clone())
38 .await
39 .write_schema_to_json(&self.args.current_dir);
40 }
41
42 pub fn get_code_schema(&self) -> &CodeSchema {
43 &self.current_code_schema
44 }
45
46 pub fn get_db_schema(&self) -> &DbSchema {
47 &self.current_db_schema
48 }
49
50 async fn run_udts(&self) {
51 let empty_udt = SchemaObject::default();
52
53 for (name, code_udt_schema) in self.current_code_schema.udts.iter() {
54 let model_data = ModelData::new(
55 name,
56 ModelType::Udt,
57 code_udt_schema,
58 self.current_db_schema.udts.get(name).unwrap_or(&empty_udt),
59 );
60
61 let migration = ModelMigration::new(&model_data, self.session, &self.args);
62
63 migration.run().await;
64 }
65 }
66
67 async fn run_tables(&self) {
68 let empty_table = SchemaObject::default();
69
70 for (name, code_table_schema) in self.current_code_schema.tables.iter() {
71 let model_data = ModelData::new(
72 name,
73 ModelType::Table,
74 code_table_schema,
75 self.current_db_schema.tables.get(name).unwrap_or(&empty_table),
76 );
77
78 let migration = ModelMigration::new(&model_data, self.session, &self.args);
79
80 migration.run().await;
81 }
82 }
83
84 async fn run_materialized_views(&self) {
85 let empty_mv = SchemaObject::default();
86
87 for (name, code_mv_schema) in self.current_code_schema.materialized_views.iter() {
88 let model_data = ModelData::new(
89 name,
90 ModelType::MaterializedView,
91 code_mv_schema,
92 self.current_db_schema.materialized_views.get(name).unwrap_or(&empty_mv),
93 );
94
95 let migration = ModelMigration::new(&model_data, self.session, &self.args);
96
97 migration.run().await;
98 }
99 }
100}