Line data Source code
1 1 : int database_initialize(LOGGER log, DATABASE* database){
2 1 : char* QUERY_AUTHENTICATION_DATA = "SELECT user_authdata, user_alias FROM main.users WHERE user_name = ?;";
3 1 : char* QUERY_USER_DATABASE = "SELECT user_database FROM main.users WHERE user_name = ? AND user_database NOT NULL;";
4 1 : char* UPDATE_POP_LOCK = "UPDATE OR FAIL main.popd SET pop_lock=? WHERE pop_user = ? AND pop_lock = ?;";
5 :
6 1 : char* LIST_MAILS_MASTER = "SELECT mail_id, length(mail_data) AS length, mail_ident FROM main.mailbox WHERE mail_user = ? ORDER BY mail_submission ASC;";
7 1 : char* FETCH_MAIL_MASTER = "SELECT mail_data FROM main.mailbox WHERE mail_id = ?;";
8 :
9 1 : char* MARK_DELETION = "INSERT INTO temp.deletions (user, mail) VALUES (?, ?);";
10 1 : char* UNMARK_DELETIONS = "DELETE FROM temp.deletions WHERE user = ?;";
11 1 : char* DELETE_MAIL_MASTER = "DELETE FROM main.mailbox WHERE mail_id IN (SELECT mail FROM temp.deletions WHERE user = ?);";
12 :
13 1 : char* CREATE_DELETION_TABLE = "CREATE TEMPORARY TABLE temp.deletions (user TEXT NOT NULL, mail INTEGER NOT NULL);";
14 :
15 1 : char* err_str = NULL;
16 :
17 : //check the database schema version
18 1 : if(database_schema_version(log, database->conn) != CMAIL_CURRENT_SCHEMA_VERSION){
19 0 : logprintf(log, LOG_ERROR, "The database schema is at another version than required for this build\n");
20 0 : return -1;
21 : }
22 :
23 : //create the temp table to store deletions
24 1 : switch(sqlite3_exec(database->conn, CREATE_DELETION_TABLE, NULL, NULL, &err_str)){
25 : case SQLITE_OK:
26 : case SQLITE_DONE:
27 1 : break;
28 : default:
29 0 : logprintf(log, LOG_WARNING, "Non-completion response to temp table create statement\n");
30 : }
31 :
32 1 : if(err_str){
33 0 : logprintf(log, LOG_ERROR, "Failed to create temporary deletion table: %s\n", err_str);
34 0 : sqlite3_free(err_str);
35 0 : return -1;
36 : }
37 :
38 1 : database->query_authdata = database_prepare(log, database->conn, QUERY_AUTHENTICATION_DATA);
39 1 : database->query_userdatabase = database_prepare(log, database->conn, QUERY_USER_DATABASE);
40 1 : database->update_lock = database_prepare(log, database->conn, UPDATE_POP_LOCK);
41 1 : database->list_master = database_prepare(log, database->conn, LIST_MAILS_MASTER);
42 1 : database->fetch_master = database_prepare(log, database->conn, FETCH_MAIL_MASTER);
43 :
44 1 : database->mark_deletion = database_prepare(log, database->conn, MARK_DELETION);
45 1 : database->unmark_deletions = database_prepare(log, database->conn, UNMARK_DELETIONS);
46 1 : database->delete_master = database_prepare(log, database->conn, DELETE_MAIL_MASTER);
47 :
48 1 : if(!database->query_authdata || !database->query_userdatabase){
49 0 : logprintf(log, LOG_ERROR, "Failed to prepare user data query\n");
50 0 : return -1;
51 : }
52 :
53 1 : if(!database->update_lock){
54 0 : logprintf(log, LOG_ERROR, "Failed to prepare lock modification statement\n");
55 0 : return -1;
56 : }
57 :
58 1 : if(!database->list_master || !database->fetch_master){
59 0 : logprintf(log, LOG_ERROR, "Failed to prepare mail data query\n");
60 0 : return -1;
61 : }
62 :
63 1 : if(!database->mark_deletion || !database->unmark_deletions || !database->delete_master){
64 0 : logprintf(log, LOG_ERROR, "Failed to prepare some deletion statements\n");
65 0 : return -1;
66 : }
67 :
68 1 : return 0;
69 : }
70 :
71 2 : void database_free(LOGGER log, DATABASE* database){
72 : //FIXME check for SQLITE_BUSY here
73 :
74 2 : if(database->conn){
75 2 : sqlite3_finalize(database->query_authdata);
76 2 : sqlite3_finalize(database->query_userdatabase);
77 2 : sqlite3_finalize(database->update_lock);
78 2 : sqlite3_finalize(database->list_master);
79 2 : sqlite3_finalize(database->fetch_master);
80 :
81 2 : sqlite3_finalize(database->mark_deletion);
82 2 : sqlite3_finalize(database->unmark_deletions);
83 2 : sqlite3_finalize(database->delete_master);
84 :
85 2 : sqlite3_close(database->conn);
86 2 : database->conn = NULL;
87 : }
88 2 : }
|