Use sqlite C api.

This commit is contained in:
Klaas Freitag 2014-10-13 14:14:43 +02:00
parent a452a05e52
commit d08c2de619
3 changed files with 74 additions and 8 deletions

View file

@ -35,6 +35,9 @@
#include <QApplication> #include <QApplication>
#include <QLocalSocket> #include <QLocalSocket>
#include <sqlite3.h>
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
#include <QStandardPaths> #include <QStandardPaths>
#endif #endif
@ -112,12 +115,66 @@ SyncFileStatus recursiveFolderStatus(Folder *folder, const QString& fileName, c_
return result; return result;
} }
SyncJournalFileRecord dbFileRecord( Folder *folder, QString fileName ) SyncJournalFileRecord dbFileRecord_capi( Folder *folder, QString fileName )
{ {
QFileInfo fi(fileName);
// FIXME: Check if this stat is really needed, or is it done in the caller?
if( !folder ) { if( !folder ) {
return SyncJournalFileRecord(); return SyncJournalFileRecord();
} }
QFileInfo fi(fileName);
if( fi.isAbsolute() ) {
fileName.remove(0, folder->path().length());
}
QString dbFileName = SyncJournalDb::databaseFilePath();
sqlite3 *db = NULL;
sqlite3_stmt *stmt = NULL;
SyncJournalFileRecord rec;
int rc;
const char* query = "SELECT inode, mode, modtime, type, md5, fileid, remotePerm FROM "
"metadata WHERE phash=:ph";
if( sqlite3_open_v2(dbFileName.toUtf8().constData(), &db,
SQLITE_OPEN_READONLY+SQLITE_OPEN_NOMUTEX, NULL) == SQLITE_OK ) {
rc = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
if( rc != SQLITE_OK ) {
qDebug() << "Unable to prepare the query statement.";
return rec;
}
qlonglong phash = SyncJournalDb::getPHash( fileName );
sqlite3_bind_int64(stmt, 1, (long long signed int)phash);
// int column_count = sqlite3_column_count(stmt);
rc = sqlite3_step(stmt);
if (rc == SQLITE_ROW ) {
rec._path = fileName;
rec._inode = sqlite3_column_int64(stmt,0);;
rec._mode = sqlite3_column_int(stmt, 1);
rec._modtime = Utility::qDateTimeFromTime_t( strtoul((char*)sqlite3_column_text(stmt, 2), NULL, 10));
rec._type = sqlite3_column_int(stmt, 3);;
rec._etag = QByteArray((char*)sqlite3_column_text(stmt, 4));
rec._fileId = QByteArray((char*)sqlite3_column_text(stmt, 5));
rec._remotePerm = QByteArray((char*)sqlite3_column_text(stmt, 6));
}
sqlite3_finalize(stmt);
sqlite3_close(db);
}
return rec;
}
SyncJournalFileRecord dbFileRecord( Folder *folder, QString fileName )
{
if( !folder ) {
return SyncJournalFileRecord();
}
QFileInfo fi(fileName);
if( fi.isAbsolute() ) { if( fi.isAbsolute() ) {
fileName.remove(0, folder->path().length()); fileName.remove(0, folder->path().length());
} }
@ -169,18 +226,18 @@ SyncFileStatus fileStatus(Folder *folder, const QString& systemFileName, c_strli
// Problem: for the sync dir itself we do not have a record in the sync journal // Problem: for the sync dir itself we do not have a record in the sync journal
// so the next check must not be used for the sync root folder. // so the next check must not be used for the sync root folder.
SyncJournalFileRecord rec = dbFileRecord(folder, unixFileName ); SyncJournalFileRecord rec = dbFileRecord_capi(folder, unixFileName );
if( !isSyncRootFolder && !rec.isValid() ) { if( !isSyncRootFolder && !rec.isValid() ) {
// check the parent folder if it is shared and if it is allowed to create a file/dir within // check the parent folder if it is shared and if it is allowed to create a file/dir within
QDir d( fi.path() ); QDir d( fi.path() );
QString parentPath = d.path(); QString parentPath = d.path();
SyncJournalFileRecord dirRec = dbFileRecord(folder, parentPath); SyncJournalFileRecord dirRec = dbFileRecord_capi(folder, parentPath);
while( !d.isRoot() && !(d.exists() && dirRec.isValid()) ) { while( !d.isRoot() && !(d.exists() && dirRec.isValid()) ) {
d.cdUp(); // returns true if the dir exists. d.cdUp(); // returns true if the dir exists.
parentPath = d.path(); parentPath = d.path();
// cut the folder path // cut the folder path
dirRec = dbFileRecord(folder, parentPath); dirRec = dbFileRecord_capi(folder, parentPath);
} }
if( dirRec.isValid() ) { if( dirRec.isValid() ) {
if( dirRec._type == CSYNC_FTW_TYPE_DIR ) { if( dirRec._type == CSYNC_FTW_TYPE_DIR ) {

View file

@ -30,6 +30,8 @@
namespace Mirall { namespace Mirall {
QString SyncJournalDb::_dbFile;
SyncJournalDb::SyncJournalDb(const QString& path, QObject *parent) : SyncJournalDb::SyncJournalDb(const QString& path, QObject *parent) :
QObject(parent), _transaction(0), _possibleUpgradeFromMirall_1_5(false) QObject(parent), _transaction(0), _possibleUpgradeFromMirall_1_5(false)
{ {
@ -49,6 +51,11 @@ bool SyncJournalDb::exists()
return (!_dbFile.isEmpty() && QFile::exists(_dbFile)); return (!_dbFile.isEmpty() && QFile::exists(_dbFile));
} }
QString SyncJournalDb::databaseFilePath()
{
return _dbFile;
}
void SyncJournalDb::startTransaction() void SyncJournalDb::startTransaction()
{ {
if( _transaction == 0 ) { if( _transaction == 0 ) {
@ -405,7 +412,7 @@ QStringList SyncJournalDb::tableColumns( const QString& table )
return columns; return columns;
} }
qint64 SyncJournalDb::getPHash(const QString& file) const qint64 SyncJournalDb::getPHash(const QString& file)
{ {
QByteArray utf8File = file.toUtf8(); QByteArray utf8File = file.toUtf8();
int64_t h; int64_t h;

View file

@ -44,6 +44,9 @@ public:
int getFileRecordCount(); int getFileRecordCount();
bool exists(); bool exists();
static QString databaseFilePath();
static qint64 getPHash(const QString& );
void updateBlacklistEntry( const SyncJournalBlacklistRecord& item ); void updateBlacklistEntry( const SyncJournalBlacklistRecord& item );
void wipeBlacklistEntry(const QString& file); void wipeBlacklistEntry(const QString& file);
int wipeBlacklist(); int wipeBlacklist();
@ -106,7 +109,6 @@ public:
bool isUpdateFrom_1_5(); bool isUpdateFrom_1_5();
private: private:
qint64 getPHash(const QString& ) const;
bool updateDatabaseStructure(); bool updateDatabaseStructure();
bool sqlFail(const QString& log, const QSqlQuery &query ); bool sqlFail(const QString& log, const QSqlQuery &query );
void commitInternal(const QString &context, bool startTrans = true); void commitInternal(const QString &context, bool startTrans = true);
@ -116,7 +118,7 @@ private:
bool checkConnect(); bool checkConnect();
QSqlDatabase _db; QSqlDatabase _db;
QString _dbFile; static QString _dbFile;
QMutex _mutex; // Public functions are protected with the mutex. QMutex _mutex; // Public functions are protected with the mutex.
int _transaction; int _transaction;
bool _possibleUpgradeFromMirall_1_5; bool _possibleUpgradeFromMirall_1_5;