}
}
+struct integrity_check_cb_arg {
+ int rows;
+ int ok;
+};
+
+/* pragma integrity_check returns a single row with the value "ok" if no errors are found */
+static int integrity_check_cb(void *pArg, int argc, char **argv, char **columnNames)
+{
+ struct integrity_check_cb_arg *cb_arg = (struct integrity_check_cb_arg *)pArg;
+ cb_arg->rows++;
+ cb_arg->ok = (0 == strcasecmp(argv[0], "ok"));
+ return 0;
+}
+
SWITCH_DECLARE(int) switch_core_db_open(const char *filename, switch_core_db_t **ppDb)
{
return sqlite3_open(filename, ppDb);
SWITCH_DECLARE(switch_core_db_t *) switch_core_db_open_file(const char *filename)
{
- switch_core_db_t *db;
+ switch_core_db_t *db = NULL;
char path[1024];
int db_ret;
+ struct integrity_check_cb_arg cb_arg;
+ int i;
+
db_pick_path(filename, path, sizeof(path));
- if ((db_ret = switch_core_db_open(path, &db)) != SQLITE_OK) {
- goto end;
+
+ for (i = 0; i < 2; i++) {
+ if ((db_ret = switch_core_db_open(path, &db)) != SQLITE_OK) {
+ goto end;
+ }
+
+ memset(&cb_arg, 0, sizeof(cb_arg));
+ if ((db_ret = switch_core_db_exec(db, "PRAGMA integrity_check;", integrity_check_cb, &cb_arg, NULL) != SQLITE_OK)) {
+ goto end;
+ }
+
+ if (cb_arg.ok && (1 == cb_arg.rows)) {
+ break;
+ } else if (0 == i) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQLite integrity_check failed for [%s]. Deleting file and retrying\n", path);
+ switch_core_db_close(db);
+ remove(path);
+ continue;
+
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQLite integrity_check failed second time for [%s]\n", path);
+ switch_core_db_close(db);
+ db = NULL;
+ goto end;
+ }
}
+
if ((db_ret = switch_core_db_exec(db, "PRAGMA synchronous=OFF;", NULL, NULL, NULL) != SQLITE_OK)) {
goto end;
}