зеркало из https://github.com/nextcloud/desktop.git
DB: Delete corrupt database. #2547
* Also use readonly DB access for SocketAPI.
This commit is contained in:
Родитель
441b5bd1dc
Коммит
40f44c2389
|
@ -15,6 +15,7 @@
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QFile>
|
||||||
|
|
||||||
#include "ownsql.h"
|
#include "ownsql.h"
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
|
@ -40,26 +41,88 @@ bool SqlDatabase::isOpen()
|
||||||
return _db != 0;
|
return _db != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SqlDatabase::open( const QString& filename )
|
bool SqlDatabase::openHelper( const QString& filename, int sqliteFlags )
|
||||||
{
|
{
|
||||||
if(isOpen()) {
|
if( isOpen() ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int flag = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_NOMUTEX;
|
sqliteFlags |= SQLITE_OPEN_NOMUTEX;
|
||||||
SQLITE_DO( sqlite3_open_v2(filename.toUtf8().constData(), &_db, flag, 0) );
|
|
||||||
|
SQLITE_DO( sqlite3_open_v2(filename.toUtf8().constData(), &_db, sqliteFlags, 0) );
|
||||||
|
|
||||||
if( _errId != SQLITE_OK ) {
|
if( _errId != SQLITE_OK ) {
|
||||||
qDebug() << Q_FUNC_INFO << "Error:" << _error << "for" << filename;
|
qDebug() << "Error:" << _error << "for" << filename;
|
||||||
close();
|
close();
|
||||||
_db = 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_db) {
|
if( !_db ) {
|
||||||
sqlite3_busy_timeout(_db, 5000);
|
qDebug() << "Error: no database for" << filename;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return isOpen();
|
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( !openHelper(filename, SQLITE_OPEN_READONLY) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !checkDb() ) {
|
||||||
|
qDebug() << "Consistency check failed in readonly mode, giving up" << filename;
|
||||||
|
close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SqlDatabase::error() const
|
QString SqlDatabase::error() const
|
||||||
|
|
|
@ -30,7 +30,8 @@ public:
|
||||||
explicit SqlDatabase();
|
explicit SqlDatabase();
|
||||||
|
|
||||||
bool isOpen();
|
bool isOpen();
|
||||||
bool open( const QString& filename );
|
bool openOrCreateReadWrite( const QString& filename );
|
||||||
|
bool openReadOnly( const QString& filename );
|
||||||
bool transaction();
|
bool transaction();
|
||||||
bool commit();
|
bool commit();
|
||||||
void close();
|
void close();
|
||||||
|
@ -38,6 +39,9 @@ public:
|
||||||
sqlite3* sqliteDb();
|
sqlite3* sqliteDb();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool openHelper( const QString& filename, int sqliteFlags );
|
||||||
|
bool checkDb();
|
||||||
|
|
||||||
sqlite3 *_db;
|
sqlite3 *_db;
|
||||||
QString _error; // last error string
|
QString _error; // last error string
|
||||||
int _errId;
|
int _errId;
|
||||||
|
|
|
@ -422,7 +422,7 @@ SqlQuery* SocketApi::getSqlQuery( Folder *folder )
|
||||||
if( fi.exists() ) {
|
if( fi.exists() ) {
|
||||||
SqlDatabase *db = new SqlDatabase;
|
SqlDatabase *db = new SqlDatabase;
|
||||||
|
|
||||||
if( db && db->open(dbFileName) ) {
|
if( db && db->openReadOnly(dbFileName) ) {
|
||||||
_openDbs.insert(folder, db);
|
_openDbs.insert(folder, db);
|
||||||
|
|
||||||
SqlQuery *query = new SqlQuery(*db);
|
SqlQuery *query = new SqlQuery(*db);
|
||||||
|
@ -435,6 +435,8 @@ SqlQuery* SocketApi::getSqlQuery( Folder *folder )
|
||||||
}
|
}
|
||||||
_dbQueries.insert( folder, query);
|
_dbQueries.insert( folder, query);
|
||||||
return query;
|
return query;
|
||||||
|
} else {
|
||||||
|
qDebug() << "Unable to open db" << dbFileName;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
qDebug() << Q_FUNC_INFO << "Journal to query does not yet exist.";
|
qDebug() << Q_FUNC_INFO << "Journal to query does not yet exist.";
|
||||||
|
|
|
@ -120,7 +120,7 @@ bool SyncJournalDb::checkConnect()
|
||||||
bool isNewDb = !QFile::exists(_dbFile);
|
bool isNewDb = !QFile::exists(_dbFile);
|
||||||
|
|
||||||
// The database file is created by this call (SQLITE_OPEN_CREATE)
|
// The database file is created by this call (SQLITE_OPEN_CREATE)
|
||||||
if( !_db.open(_dbFile) ) {
|
if( !_db.openOrCreateReadWrite(_dbFile) ) {
|
||||||
QString error = _db.error();
|
QString error = _db.error();
|
||||||
qDebug() << "Error opening the db: " << error;
|
qDebug() << "Error opening the db: " << error;
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -42,7 +42,7 @@ private slots:
|
||||||
void testOpenDb() {
|
void testOpenDb() {
|
||||||
QFileInfo fi( testdbC );
|
QFileInfo fi( testdbC );
|
||||||
QVERIFY( !fi.exists() ); // must not exist
|
QVERIFY( !fi.exists() ); // must not exist
|
||||||
_db.open(testdbC);
|
_db.openOrCreateReadWrite(testdbC);
|
||||||
fi.refresh();
|
fi.refresh();
|
||||||
QVERIFY(fi.exists());
|
QVERIFY(fi.exists());
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче