diff options
author | Christian Kamm <kamm@incasoftware.de> | 2014-12-04 15:55:58 +0300 |
---|---|---|
committer | Christian Kamm <kamm@incasoftware.de> | 2014-12-04 17:35:55 +0300 |
commit | 40f44c23890dd5fca86928b0f7c0d3f4218b7fc4 (patch) | |
tree | f28f9211fd867773f66c66f5cfece9781728fc67 /src/mirall | |
parent | 441b5bd1dc3e862aec98161c8ea780bc7e846828 (diff) |
DB: Delete corrupt database. #2547
* Also use readonly DB access for SocketAPI.
Diffstat (limited to 'src/mirall')
-rw-r--r-- | src/mirall/ownsql.cpp | 81 | ||||
-rw-r--r-- | src/mirall/ownsql.h | 6 | ||||
-rw-r--r-- | src/mirall/socketapi.cpp | 4 | ||||
-rw-r--r-- | src/mirall/syncjournaldb.cpp | 2 |
4 files changed, 81 insertions, 12 deletions
diff --git a/src/mirall/ownsql.cpp b/src/mirall/ownsql.cpp index 157b00c85..19c9f88b2 100644 --- a/src/mirall/ownsql.cpp +++ b/src/mirall/ownsql.cpp @@ -15,6 +15,7 @@ #include <QDateTime> #include <QString> #include <QDebug> +#include <QFile> #include "ownsql.h" #include "utility.h" @@ -40,26 +41,88 @@ bool SqlDatabase::isOpen() return _db != 0; } -bool SqlDatabase::open( const QString& filename ) +bool SqlDatabase::openHelper( const QString& filename, int sqliteFlags ) { - if(isOpen()) { + if( isOpen() ) { return true; } - int flag = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_NOMUTEX; - SQLITE_DO( sqlite3_open_v2(filename.toUtf8().constData(), &_db, flag, 0) ); + sqliteFlags |= SQLITE_OPEN_NOMUTEX; + + SQLITE_DO( sqlite3_open_v2(filename.toUtf8().constData(), &_db, sqliteFlags, 0) ); if( _errId != SQLITE_OK ) { - qDebug() << Q_FUNC_INFO << "Error:" << _error << "for" << filename; + qDebug() << "Error:" << _error << "for" << filename; close(); - _db = 0; + return false; + } + + if( !_db ) { + qDebug() << "Error: no database for" << filename; + return false; + } + + sqlite3_busy_timeout(_db, 5000); + + return true; +} + +bool SqlDatabase::checkDb() +{ + SqlQuery quick_check("PRAGMA quick_check;", *this); + if( !quick_check.exec() ) { + qDebug() << "Error running quick_check on database"; + return false; + } + + quick_check.next(); + QString result = quick_check.stringValue(0); + if( result != "ok" ) { + qDebug() << "quick_check returned failure:" << result; + return false; + } + + return true; +} + +bool SqlDatabase::openOrCreateReadWrite( const QString& filename ) +{ + if( isOpen() ) { + return true; + } + + if( !openHelper(filename, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE) ) { + return false; + } + + if( !checkDb() ) { + qDebug() << "Consistency check failed, removing broken db" << filename; + close(); + QFile::remove(filename); + + return openHelper(filename, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE); + } + + return true; +} + +bool SqlDatabase::openReadOnly( const QString& filename ) +{ + if( isOpen() ) { + return true; } - if (_db) { - sqlite3_busy_timeout(_db, 5000); + if( !openHelper(filename, SQLITE_OPEN_READONLY) ) { + return false; } - return isOpen(); + if( !checkDb() ) { + qDebug() << "Consistency check failed in readonly mode, giving up" << filename; + close(); + return false; + } + + return true; } QString SqlDatabase::error() const diff --git a/src/mirall/ownsql.h b/src/mirall/ownsql.h index 055be3372..863800861 100644 --- a/src/mirall/ownsql.h +++ b/src/mirall/ownsql.h @@ -30,7 +30,8 @@ public: explicit SqlDatabase(); bool isOpen(); - bool open( const QString& filename ); + bool openOrCreateReadWrite( const QString& filename ); + bool openReadOnly( const QString& filename ); bool transaction(); bool commit(); void close(); @@ -38,6 +39,9 @@ public: sqlite3* sqliteDb(); private: + bool openHelper( const QString& filename, int sqliteFlags ); + bool checkDb(); + sqlite3 *_db; QString _error; // last error string int _errId; diff --git a/src/mirall/socketapi.cpp b/src/mirall/socketapi.cpp index 1b382e3e0..b8d5da268 100644 --- a/src/mirall/socketapi.cpp +++ b/src/mirall/socketapi.cpp @@ -422,7 +422,7 @@ SqlQuery* SocketApi::getSqlQuery( Folder *folder ) if( fi.exists() ) { SqlDatabase *db = new SqlDatabase; - if( db && db->open(dbFileName) ) { + if( db && db->openReadOnly(dbFileName) ) { _openDbs.insert(folder, db); SqlQuery *query = new SqlQuery(*db); @@ -435,6 +435,8 @@ SqlQuery* SocketApi::getSqlQuery( Folder *folder ) } _dbQueries.insert( folder, query); return query; + } else { + qDebug() << "Unable to open db" << dbFileName; } } else { qDebug() << Q_FUNC_INFO << "Journal to query does not yet exist."; diff --git a/src/mirall/syncjournaldb.cpp b/src/mirall/syncjournaldb.cpp index 579bf575e..4d2b3f86e 100644 --- a/src/mirall/syncjournaldb.cpp +++ b/src/mirall/syncjournaldb.cpp @@ -120,7 +120,7 @@ bool SyncJournalDb::checkConnect() bool isNewDb = !QFile::exists(_dbFile); // The database file is created by this call (SQLITE_OPEN_CREATE) - if( !_db.open(_dbFile) ) { + if( !_db.openOrCreateReadWrite(_dbFile) ) { QString error = _db.error(); qDebug() << "Error opening the db: " << error; return false; |