1use crate::sql::{DBObject, TypeWriter};
2use crate::type_writers::Postgresql;
3use crate::util::*;
4use std::error::Error;
5use std::fs::File;
6use std::io::prelude::*;
7
8type BxTypeWriter = Box<dyn TypeWriter>;
9type BxObject<'a> = &'a Box<&'a dyn DBObject>;
10type Objects = Vec<Box<dyn DBObject>>;
11
12pub struct Processor<'a> {
17 objs: Vec<Box<&'a dyn DBObject>>,
18 type_writer:BxTypeWriter,
19}
20
21impl <'a> Processor<'a> {
22 pub fn new(type_writer:Option<BxTypeWriter>) -> Self {
24 let type_writer = if let Some(tr) = type_writer {
25 tr
26 } else {
27 Box::new(Postgresql{})
28 };
29 Processor {
30 objs: Vec::new(),
31 type_writer,
32 }
33 }
34 pub fn new_with_objects(objects:&'a Objects, type_writer:Option<BxTypeWriter>) -> Self {
36 let mut me = Processor::new(type_writer);
37 for obj in objects.iter() {
38 me.objs.push(Box::new(obj.as_ref()))
39 }
40 me
41 }
42 pub fn add(&mut self, object:&'a dyn DBObject) -> &Self {
44 self.objs.push(Box::new(object));
45 self
46 }
47 fn add_to_toplevel(&self, obj:&mut BxObject, out:&mut Vec<String>, delayed:&mut Vec<&Box<&dyn DBObject>>) {
48 let sql;
49 if delayed.is_empty() {
50 sql = obj.to_sql(self.type_writer.as_ref())
52 } else {
53 sql = obj.top_level_to_sql(self.type_writer.as_ref(), &delayed);
55 delayed.clear()
56 };
57 if ! sql.is_empty() {
58 out.push(sql);
59 }
60 }
61 pub fn sql_statements(&self) -> Vec<String> {
63 let mut out = Vec::new();
64 let mut delayed = Vec::new();
65 let mut top : Option<BxObject> = None;
66 for obj in &self.objs {
67 if ! obj.is_top_level() {
68 delayed.push(obj)
69 } else {
70 if let Some(mut tl) = top {
71 self.add_to_toplevel(&mut tl, &mut out, &mut delayed);
72 }
73 top = Some(obj)
74 }
75 }
76 if let Some(mut tl) = top {
77 self.add_to_toplevel(&mut tl, &mut out, &mut delayed)
78 }
79 out
80 }
81 pub fn join_sql_statements(&self) -> String {
83 self.sql_statements().join("\n")
84 }
85 pub fn serialize_to_yaml_file(&self, file_name:&str) -> Result<(), Box<dyn Error>> {
87 Ok(write_yaml_to_file(file_name, &self.objs)?)
88 }
89 pub fn write_to_sql_file(&self, file_name:&str) -> Result<(), Box<dyn Error>> {
91 let sqls = self.join_sql_statements();
92 let mut fh = File::create(file_name)?;
93 Ok(fh.write_all(&sqls.as_bytes())?)
94 }
95 pub fn objects(&self) -> &Vec<Box<&'a dyn DBObject>> {
97 &self.objs
98 }
99}
100
101
102pub struct Loader {
107 objs: Objects,
108}
109
110impl Loader {
111 pub fn new(data:&str) -> Result<Self, Box<dyn Error>> {
113 Ok(Loader {
114 objs: read_yaml_from_string(data).expect(format!("To load objects from string '{data}'").as_str())
115 })
116 }
117 pub fn new_from_file(file_name:&str) -> Result<Self, Box<dyn Error>> {
119 Ok(Loader {
120 objs: read_yaml_from_file(file_name).expect(format!("To load objects from '{file_name}'").as_str())
121 })
122 }
123 pub fn objects(&self) -> &Objects {
124 &self.objs
125 }
126}