dbmigrate_lib/drivers/
mysql.rs

1use mysql_client::{from_row, Pool};
2
3use super::Driver;
4use errors::{Result, ResultExt};
5
6
7/// The MySQL driver
8#[derive(Debug)]
9pub struct Mysql {
10    pool: Pool
11}
12
13impl Mysql {
14    /// Create MySQL driver
15    pub fn new(url: &str) -> Result<Mysql> {
16        let pool = Pool::new(url)?;
17        let mut mysql = Mysql { pool: pool };
18        mysql.ensure_migration_table_exists();
19
20        Ok(mysql)
21    }
22}
23
24
25impl Driver for Mysql {
26    fn ensure_migration_table_exists(&mut self) {
27        let mut conn = self.pool.get_conn().unwrap();
28        conn.query("
29            CREATE TABLE IF NOT EXISTS __dbmigrate_table(id INTEGER, current INTEGER);
30            INSERT INTO __dbmigrate_table (id, current)
31            SELECT 1, 0 FROM DUAL
32            WHERE NOT EXISTS(SELECT * FROM __dbmigrate_table WHERE id = 1);
33        ").unwrap();
34    }
35
36    fn remove_migration_table(&mut self) {
37        self.pool.prep_exec("DROP TABLE __dbmigrate_table;", ()).unwrap();
38    }
39
40    fn get_current_number(&mut self) -> i32 {
41        let mut result = self.pool.prep_exec("
42            SELECT current FROM __dbmigrate_table WHERE id = 1;
43        ", ()).unwrap();
44        // That is quite ugly
45        let row = result.next().unwrap();
46        from_row::<i32>(row.unwrap())
47    }
48
49    fn set_current_number(&mut self, number: i32) {
50        self.pool.prep_exec(
51            "UPDATE __dbmigrate_table SET current = ? WHERE id = 1;",
52            (&number, )
53        ).unwrap();
54    }
55
56    fn migrate(&mut self, migration: String, number: i32) -> Result<()> {
57        let mut conn = self.pool.get_conn()?;
58        conn.query(migration).chain_err(|| "Migration failed")?;
59        self.set_current_number(number);
60
61        Ok(())
62    }
63}