shared: Begin db migration logic

Issue: #26
This commit is contained in:
Albert S. 2022-02-27 23:37:22 +01:00
parent 294455b861
commit 3d8b086f53
6 changed files with 121 additions and 6 deletions

View File

@ -1,5 +0,0 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>create.sql</file>
</qresource>
</RCC>

85
shared/dbmigrator.cpp Normal file
View File

@ -0,0 +1,85 @@
#include <QDirIterator>
#include <QSqlQuery>
#include <QSqlError>
#include <QTextStream>
#include <QDebug>
#include "dbmigrator.h"
#include "looqsgeneralexception.h"
DBMigrator::DBMigrator(QSqlDatabase &db)
{
Q_INIT_RESOURCE(migrations);
this->db = &db;
}
DBMigrator::~DBMigrator()
{
Q_CLEANUP_RESOURCE(migrations);
}
QStringList DBMigrator::getMigrationFilenames()
{
QStringList result;
QDirIterator it(":/looqs-migrations/");
while(it.hasNext())
{
result.append(it.next());
}
return result;
}
uint32_t DBMigrator::currentRevision()
{
QSqlQuery dbquery(*db);
dbquery.exec("PRAGMA user_version;");
if(!dbquery.next())
{
throw new LooqsGeneralException("Failed to query current db revision");
}
uint32_t result = dbquery.value(0).toUInt();
return result;
}
bool DBMigrator::migrationNeeded()
{
QStringList migrations = getMigrationFilenames();
uint32_t currentRev = currentRevision();
return currentRev < static_cast<uint32_t>(migrations.size());
}
void DBMigrator::performMigrations()
{
QStringList migrations = getMigrationFilenames();
uint32_t currentRev = currentRevision();
uint32_t targetRev = (migrations.size());
for(uint32_t i = currentRev + 1; i <= targetRev; i++)
{
QString fileName = QString(":/looqs-migrations/%1.sql").arg(i);
QFile file{fileName};
if(!file.open(QIODevice::ReadOnly))
{
throw LooqsGeneralException("Migration: Failed to find required revision file");
}
QTextStream stream(&file);
db->transaction();
while(!stream.atEnd())
{
QString sql = stream.readLine();
QSqlQuery sqlQuery{*db};
if(!sqlQuery.exec(sql))
{
db->rollback();
throw LooqsGeneralException("Failed to execute sql statement while initializing database: " +
sqlQuery.lastError().text());
}
}
QSqlQuery updateVersion{*db};
updateVersion.exec(QString("PRAGMA user_version=%1;").arg(i));
db->commit();
emit migrationDone(i);
}
emit done();
}

24
shared/dbmigrator.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef DBMIGRATOR_H
#define DBMIGRATOR_H
#include <QStringList>
#include <QSqlDatabase>
#include <QObject>
class DBMigrator : public QObject
{
Q_OBJECT
private:
QSqlDatabase *db;
public:
DBMigrator(QSqlDatabase &db);
~DBMigrator();
uint32_t currentRevision();
void performMigrations();
QStringList getMigrationFilenames();
bool migrationNeeded();
signals:
void migrationDone(uint32_t);
void done();
};
#endif // DBMIGRATOR_H

View File

@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/looqs-migrations">
<file>1.sql</file>
</qresource>
</RCC>

View File

@ -27,12 +27,18 @@ DEFINES += QT_DEPRECATED_WARNINGS
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += sqlitesearch.cpp \
databasefactory.cpp \
dbmigrator.cpp \
logger.cpp \
looqsgeneralexception.cpp \
common.cpp \
looqsquery.cpp
HEADERS += sqlitesearch.h \
databasefactory.h \
dbmigrator.h \
filedata.h \
logger.h \
looqsgeneralexception.h \
looqsquery.h \
searchresult.h \
@ -42,4 +48,4 @@ unix {
target.path = /usr/lib
INSTALLS += target
}
RESOURCES = create.qrc
RESOURCES = migrations/migrations.qrc