1d38a454f03091e1d1020f1a19001919494aef8b
1 use crate::consts
::SQL_FILENAME
;
5 use std
::{fs
::{self, File
}, path
::Path
, io
::Read
};
7 //use rusqlite::types::ToSql;
8 //use rusqlite::{Connection, Result, NO_PARAMS};
10 use r2d2_sqlite
::SqliteConnectionManager
;
12 const CURRENT_DB_VERSION
: u32 = 1;
16 SqliteError(rusqlite
::Error
),
17 R2d2Error(r2d2
::Error
),
18 UnsupportedVersion(u32),
22 pub struct Connection
{
23 //con: rusqlite::Connection
24 pool
: Pool
<SqliteConnectionManager
>
32 impl std
::convert
::From
<rusqlite
::Error
> for DBError
{
33 fn from(error
: rusqlite
::Error
) -> Self {
34 DBError
::SqliteError(error
)
38 impl std
::convert
::From
<r2d2
::Error
> for DBError
{
39 fn from(error
: r2d2
::Error
) -> Self {
40 DBError
::R2d2Error(error
)
45 pub fn new() -> Result
<Connection
, DBError
> {
47 let data_dir
= Path
::new(consts
::DB_DIRECTORY
);
49 if !data_dir
.exists() {
50 fs
::DirBuilder
::new().create(data_dir
).unwrap();
53 let manager
= SqliteConnectionManager
::file(consts
::DB_FILENAME
);
54 let pool
= r2d2
::Pool
::new(manager
).unwrap();
56 let connection
= Connection
{ pool
};
57 connection
.create_or_update()?
;
62 * Called after the connection has been established for creating or updating the database.
63 * The 'Version' table tracks the current state of the database.
65 fn create_or_update(self: &Self) -> Result
<(), DBError
> {
66 // let connection = Connection::new();
67 // let mut stmt = connection.sqlite_con.prepare("SELECT * FROM versions ORDER BY date").unwrap();
68 // let mut stmt = connection.sqlite_con.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='versions'").unwrap();
70 // Check the Database version.
71 let mut con
= self.pool
.get()?
;
72 let tx
= con
.transaction()?
;
74 // Version 0 corresponds to an empty database.
77 "SELECT [name] FROM [sqlite_master] WHERE [type] = 'table' AND [name] = 'Version'",
79 |row
| row
.get
::<usize, String
>(0)
81 Ok(_
) => tx
.query_row("SELECT [version] FROM [Version]", [], |row
| row
.get(0)).unwrap_or_default(),
86 while Connection
::update_to_next_version(version
, &tx
)?
{
95 fn update_to_next_version(current_version
: u32, tx
: &rusqlite
::Transaction
) -> Result
<bool
, DBError
> {
96 let next_version
= current_version
+ 1;
98 if next_version
<= CURRENT_DB_VERSION
{
99 println!("Update to version {}...", next_version
);
102 fn ok(updated
: bool
) -> Result
<bool
, DBError
> {
104 println!("Version updated");
111 tx
.execute_batch(&load_sql_file(next_version
)?
)?
;
116 // Version 1 doesn't exist yet.
121 Err(DBError
::UnsupportedVersion(v
)),
125 pub fn get_all_recipes() {
130 fn load_sql_file(version
: u32) -> Result
<String
, DBError
> {
131 let sql_file
= SQL_FILENAME
.replace("{VERSION}", &version
.to_string());
132 let mut file
= File
::open(&sql_file
).map_err(|err
| DBError
::Other(format!("Cannot open SQL file ({}): {}", &sql_file
, err
.to_string())))?
;
133 let mut sql
= String
::new();
134 file
.read_to_string(&mut sql
).map_err(|err
| DBError
::Other(format!("Cannot read SQL file ({}) : {}", &sql_file
, err
.to_string())))?
;