Line data Source code
1 : /**
2 : * @file db_migrate_from_2_to_3.c
3 : * @brief Migration to database version 3
4 : */
5 :
6 : #include "precizer.h"
7 :
8 : /**
9 : * @brief Migrates database from version 2 to version 3
10 : * @details Forces journal_mode to DELETE to disable WAL and cleans up WAL files.
11 : * No schema changes are applied; this migration only switches journaling mode.
12 : * @param db_file_path Path to the SQLite database file
13 : * @return Return status code
14 : */
15 14 : Return db_migrate_from_2_to_3(const char *db_file_path)
16 : {
17 14 : Return status = SUCCESS;
18 14 : sqlite3 *db = NULL;
19 14 : char *err_msg = NULL;
20 :
21 14 : if(config->dry_run == true)
22 : {
23 0 : slog(TRACE,"Dry Run mode is enabled. Database migration is not required\n");
24 0 : provide(status);
25 : }
26 :
27 14 : int rc = sqlite3_open_v2(db_file_path,&db,SQLITE_OPEN_READWRITE|SQLITE_OPEN_FULLMUTEX,NULL);
28 :
29 14 : if(SQLITE_OK != rc)
30 : {
31 0 : log_sqlite_error(db,rc,NULL,"Failed to open database");
32 0 : status = FAILURE;
33 : }
34 :
35 14 : if(SUCCESS == status)
36 : {
37 14 : const char *pragmas =
38 : "PRAGMA locking_mode=EXCLUSIVE;"
39 : "PRAGMA strict=ON;"
40 : "PRAGMA fsync=ON;"
41 : "PRAGMA synchronous=EXTRA;";
42 :
43 14 : rc = sqlite3_exec(db,pragmas,NULL,NULL,&err_msg);
44 :
45 14 : if(SQLITE_OK != rc)
46 : {
47 0 : log_sqlite_error(db,rc,err_msg,"Failed to set pragmas");
48 0 : status = FAILURE;
49 : }
50 : }
51 :
52 14 : if(SUCCESS == status)
53 : {
54 14 : sqlite3_stmt *stmt = NULL;
55 :
56 14 : rc = sqlite3_prepare_v2(db,"PRAGMA journal_mode=DELETE;",-1,&stmt,NULL);
57 :
58 14 : if(SQLITE_OK != rc)
59 : {
60 0 : log_sqlite_error(db,rc,NULL,"Failed to prepare journal_mode switch");
61 0 : status = FAILURE;
62 : }
63 :
64 14 : if(SUCCESS == status)
65 : {
66 14 : rc = sqlite3_step(stmt);
67 :
68 14 : if(SQLITE_ROW == rc)
69 : {
70 14 : const unsigned char *mode = sqlite3_column_text(stmt,0);
71 :
72 14 : if(mode == NULL || strcmp((const char *)mode,"delete") != 0)
73 : {
74 0 : slog(ERROR,"journal_mode switch failed, current mode: %s\n",mode ? (const char *)mode : "(null)");
75 0 : status = FAILURE;
76 : }
77 : } else {
78 0 : log_sqlite_error(db,rc,NULL,"journal_mode switch did not return a row");
79 0 : status = FAILURE;
80 : }
81 : }
82 :
83 14 : if(stmt != NULL)
84 : {
85 14 : sqlite3_finalize(stmt);
86 : }
87 : }
88 :
89 14 : if(SUCCESS == status)
90 : {
91 14 : rc = sqlite3_exec(db,"PRAGMA wal_checkpoint(TRUNCATE);",NULL,NULL,NULL);
92 :
93 14 : if(SQLITE_OK != rc)
94 : {
95 0 : log_sqlite_error(db,rc,NULL,"Failed to checkpoint WAL");
96 0 : status = FAILURE;
97 : }
98 : }
99 :
100 14 : if(SUCCESS == status)
101 : {
102 14 : if(strcmp(db_file_path,config->db_primary_file_path) == 0)
103 : {
104 8 : config->db_primary_file_modified = true;
105 : }
106 : }
107 :
108 14 : call(db_close(db,&config->db_primary_file_modified));
109 :
110 14 : provide(status);
111 : }
|