1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
use diesel::Connection;
use crate::db::backend::Connectable;
use crate::db::models::Field;
pub enum DatabaseChange {
CreateModel {
name: &'static str,
fields: &'static [Field],
options: &'static [CreateModelOption]
},
}
impl DatabaseChange {
pub fn apply<C: Connectable>(&self, app_name: &str, connection: &C::Connection) {
use barrel::{Migration, Table, types};
match self {
DatabaseChange::CreateModel { name, fields, options } => {
let mut m = Migration::new();
let columns: Vec<(&'static str, _)> = fields.iter().map(|field| match field {
Field::CharField { name, max_length } => {
let name = *name;
let _type = match max_length {
None => types::text(),
Some(max_length) => types::varchar(*max_length),
};
(name, _type)
}
Field::DateTimeField { name } => {
(*name, types::text()) // TODO do smart things on non-sqlite
}
Field::IntField { name } => {
(*name, types::integer())
}
}).collect();
let callback = move |t: &mut Table| {
for (name, _type) in &columns {
t.add_column(*name, _type.clone());
}
};
let table_name = format!("{}-{}", app_name, name);
if options.contains(&CreateModelOption::IfNotExist) {
m.create_table_if_not_exists(table_name, callback);
} else {
m.create_table(table_name, callback);
}
connection.execute(&m.make::<C::SqlGenerator>()).unwrap();
}
}
}
}
#[derive(PartialEq)]
pub enum CreateModelOption {
IfNotExist,
}
|