Commit c8104762 authored by Karel Slaný's avatar Karel Slaný

Added support for flags into SQLiteDb. Also added virtual methods.

parent e7bbe37b
......@@ -238,8 +238,14 @@ fail:
return false;
}
bool SQLiteDb::copyDb(const QString &newFileName,
const QList<class SQLiteTbl *> &tables)
bool SQLiteDb::assureConsistency(void)
{
logInfoNL("No consistency checks performed in database '%s'.",
fileName().toUtf8().constData());
return true;
}
bool SQLiteDb::copyDb(const QString &newFileName, enum OpenFlag flag)
{
if (Q_UNLIKELY(newFileName.isEmpty())) {
Q_ASSERT(0);
......@@ -256,6 +262,11 @@ bool SQLiteDb::copyDb(const QString &newFileName,
Q_ASSERT(0);
return false;
}
if (Q_UNLIKELY(flag & ~CREATE_MISSING)) {
logErrorNL("Unsupported flag '%d'.", flag);
Q_ASSERT(0);
return false;
}
bool copy_ret, open_ret;
......@@ -284,7 +295,7 @@ bool SQLiteDb::copyDb(const QString &newFileName,
copy_ret = QFile::copy(oldFileName, newFileName);
/* Open database. */
open_ret = openDb(copy_ret ? newFileName : oldFileName, false, tables);
open_ret = openDb(copy_ret ? newFileName : oldFileName, flag);
if (!open_ret) {
Q_ASSERT(0);
logErrorNL("File '%s' could not be opened.",
......@@ -298,8 +309,7 @@ bool SQLiteDb::copyDb(const QString &newFileName,
return copy_ret;
}
bool SQLiteDb::reopenDb(const QString &newFileName,
const QList<class SQLiteTbl *> &tables)
bool SQLiteDb::reopenDb(const QString &newFileName, enum OpenFlag flag)
{
if (Q_UNLIKELY(newFileName.isEmpty())) {
Q_ASSERT(0);
......@@ -316,6 +326,11 @@ bool SQLiteDb::reopenDb(const QString &newFileName,
Q_ASSERT(0);
return false;
}
if (Q_UNLIKELY(flag & ~CREATE_MISSING)) {
logErrorNL("Unsupported flag '%d'.", flag);
Q_ASSERT(0);
return false;
}
bool reopen_ret, open_ret;
......@@ -341,11 +356,11 @@ bool SQLiteDb::reopenDb(const QString &newFileName,
QFile::remove(newFileName);
/* Open new database file. */
reopen_ret = openDb(newFileName, false, tables);
reopen_ret = openDb(newFileName, flag);
/* Open database. */
if (!reopen_ret) {
open_ret = openDb(oldFileName, false, tables);
open_ret = openDb(oldFileName, flag);
if (!open_ret) {
logErrorNL("File '%s' could not be opened.",
oldFileName.toUtf8().constData());
......@@ -357,8 +372,7 @@ bool SQLiteDb::reopenDb(const QString &newFileName,
return reopen_ret;
}
bool SQLiteDb::moveDb(const QString &newFileName,
const QList<class SQLiteTbl *> &tables)
bool SQLiteDb::moveDb(const QString &newFileName, enum OpenFlag flag)
{
if (Q_UNLIKELY(newFileName.isEmpty())) {
Q_ASSERT(0);
......@@ -375,6 +389,11 @@ bool SQLiteDb::moveDb(const QString &newFileName,
Q_ASSERT(0);
return false;
}
if (Q_UNLIKELY(flag & ~CREATE_MISSING)) {
logErrorNL("Unsupported flag '%d'.", flag);
Q_ASSERT(0);
return false;
}
bool move_ret, open_ret;
......@@ -403,7 +422,7 @@ bool SQLiteDb::moveDb(const QString &newFileName,
move_ret = QFile::rename(oldFileName, newFileName);
/* Open database. */
open_ret = openDb(move_ret ? newFileName : oldFileName, false, tables);
open_ret = openDb(move_ret ? newFileName : oldFileName, flag);
if (!open_ret) {
Q_ASSERT(0);
logErrorNL("File '%s' could not be opened.",
......@@ -417,26 +436,34 @@ bool SQLiteDb::moveDb(const QString &newFileName,
return move_ret;
}
bool SQLiteDb::openDb(const QString &fileName, bool forceInMemory,
const QList<class SQLiteTbl *> &tables)
bool SQLiteDb::openDb(const QString &fileName, OpenFlags flags)
{
bool ret;
if (Q_UNLIKELY((!(flags & FORCE_IN_MEMORY)) && fileName.isEmpty())) {
Q_ASSERT(0);
return false;
}
if (m_db.isOpen()) {
m_db.close();
}
if (!forceInMemory) {
if (!(flags & FORCE_IN_MEMORY)) {
m_db.setDatabaseName(QDir::toNativeSeparators(fileName));
} else {
m_db.setDatabaseName(memoryLocation);
}
ret = m_db.open();
bool ret = m_db.open();
if (flags & CREATE_MISSING) {
if (ret) {
/* Ensure database contains all tables. */
ret = createEmptyMissingTables(listOfTables());
}
if (ret) {
/* Ensure database contains all tables. */
ret = createEmptyMissingTables(tables);
if (ret) {
ret = assureConsistency();
}
}
if (!ret) {
......
......@@ -23,6 +23,7 @@
#pragma once
#include <QFlags>
#include <QList>
#include <QSqlDatabase>
#include <QString>
......@@ -35,6 +36,16 @@
class SQLiteDb {
public:
/*!
* @brief Database opening flags.
*/
enum OpenFlag {
NO_OPTIONS = 0x00, /*!< No option specified. */
CREATE_MISSING = 0x01, /*!< Missing tables and entries are going to be created. */
FORCE_IN_MEMORY = 0x02 /*!< Database is going to be opened in memory. */
};
Q_DECLARE_FLAGS(OpenFlags, OpenFlag)
/*!
* @brief Constructor.
*
......@@ -45,6 +56,7 @@ public:
/*!
* @brief Destructor.
*/
virtual
~SQLiteDb(void);
/*!
......@@ -126,55 +138,67 @@ protected:
*/
bool vacuum(void);
/*!
* @brief Returns list of tables encompassed in the database.
*
* @return List of pointers to tables.
*
* @note Override this method in derived classes. This method is
* used to create missing database tables.
*/
virtual
QList<class SQLiteTbl *> listOfTables(void) const = 0;
/*!
* @brief This function is used to make database content consistent
* (e.g. adding missing columns or entries).
*
* @return True on success. If this method returns false, then the
* open procedure must fail. Override this method to implement
* custom checks. This method just returns true.
*/
virtual
bool assureConsistency(void);
/*!
* @brief Copy db.
*
* @param[in] newFileName New file path.
* @param[in] tables List of table prototypes that should be created
* if missing.
* @param[in] flag Can be NO_OPTIONS or CREATE_MISSING.
* @return True on success.
*
* @note The copy is continued to be used. Original is closed.
*/
bool copyDb(const QString &newFileName,
const QList<class SQLiteTbl *> &tables);
bool copyDb(const QString &newFileName, enum OpenFlag flag);
/*!
* @brief Open a new empty database file.
*
* @param[in] newFileName New file path.
* @param[in] tables List of table prototypes that should be created
* if missing.
* @param[in] flag Can be NO_OPTIONS or CREATE_MISSING.
* @return True on success.
*
* @note The old database file is left untouched.
*/
bool reopenDb(const QString &newFileName,
const QList<class SQLiteTbl *> &tables);
bool reopenDb(const QString &newFileName, enum OpenFlag flag);
/*!
* @brief Move db.
*
* @param[in] newFileName New file path.
* @param[in] tables List of table prototypes that should be created
* if missing.
* @param[in] flag Can be NO_OPTIONS or CREATE_MISSING.
* @return True on success.
*/
bool moveDb(const QString &newFileName,
const QList<class SQLiteTbl *> &tables);
bool moveDb(const QString &newFileName, enum OpenFlag flag);
/*!
* @brief Open database file.
*
* @param[in] fileName File name.
* @param[in] forceInMemory True if the message should be stored in
* memory only.
* @param[in] tables List of table prototypes that should be created
* if missing.
* @param[in] flags Database opening flags.
* @return True on success, false on any error.
*/
bool openDb(const QString &fileName, bool forceInMemory,
const QList<class SQLiteTbl *> &tables);
bool openDb(const QString &fileName, OpenFlags flags);
/*!
* @brief Attaches a database file to opened database.
......@@ -208,3 +232,5 @@ private:
*/
bool createEmptyMissingTables(const QList<class SQLiteTbl *> &tables);
};
Q_DECLARE_OPERATORS_FOR_FLAGS(SQLiteDb::OpenFlags)
......@@ -123,9 +123,12 @@ bool AccountDb::openDb(const QString &fileName, bool storeToDisk)
return false;
}
SQLiteDb::OpenFlags flags = SQLiteDb::CREATE_MISSING;
flags |= storeToDisk ? SQLiteDb::NO_OPTIONS : SQLiteDb::FORCE_IN_MEMORY;
return SQLiteDb::openDb(
dirName + QDir::separator() + QDir::toNativeSeparators(fileName),
!storeToDisk, listOfTables());
flags);
}
const QString AccountDb::senderNameGuess(const QString &userName,
......@@ -651,13 +654,11 @@ fail:
return false;
}
QList<class SQLiteTbl *> AccountDb::listOfTables(void)
QList<class SQLiteTbl *> AccountDb::listOfTables(void) const
{
static QList<class SQLiteTbl *> tables;
if (tables.isEmpty()) {
tables.append(&accntinfTbl);
tables.append(&userinfTbl);
}
QList<class SQLiteTbl *> tables;
tables.append(&accntinfTbl);
tables.append(&userinfTbl);
return tables;
}
......
......@@ -36,7 +36,6 @@
class AccountDb : public SQLiteDb {
public:
explicit AccountDb(const QString &connectionName);
/*!
......@@ -108,7 +107,7 @@ public:
/*!
* @brief Open database file.
*
* @param[in] userName Account user name.
* @param[in] fileName File name.
* @param[in] storeToDisk True if db is store on the local storage.
* @return True on success.
*/
......@@ -133,22 +132,22 @@ public:
*/
bool updatePwdExpirInDb(const QString &userName, const QString &date);
private:
protected:
/*!
* @brief Returns list of tables.
*
* @return List of pointers to tables.
*/
virtual
QList<class SQLiteTbl *> listOfTables(void) const Q_DECL_OVERRIDE;
private:
static
const QVector<QString> dsPrintedAttribs;
static
const QVector<QString> ownerPrintedAttribs;
static
const QVector<QString> userPrintedAttribs;
/*!
* @brief Returns list of tables.
*
* @return List of pointers to tables.
*/
static
QList<class SQLiteTbl *> listOfTables(void);
};
/*!
......
......@@ -87,7 +87,7 @@ QStringList FileDb::cleanFilesInDb(int days)
bool FileDb::copyDb(const QString &newFileName)
{
return SQLiteDb::copyDb(newFileName, listOfTables());
return SQLiteDb::copyDb(newFileName, SQLiteDb::CREATE_MISSING);
}
int FileDb::countFilesInDb(void)
......@@ -110,7 +110,7 @@ int FileDb::countFilesInDb(void)
bool FileDb::reopenDb(const QString &newFileName)
{
return SQLiteDb::reopenDb(newFileName, listOfTables());
return SQLiteDb::reopenDb(newFileName, SQLiteDb::CREATE_MISSING);
}
bool FileDb::deleteFilesFromDb(qint64 dmId)
......@@ -294,12 +294,10 @@ fail:
bool FileDb::openDb(const QString &fileName, bool storeToDisk)
{
if (storeToDisk && fileName.isEmpty()) {
Q_ASSERT(0);
return false;
}
SQLiteDb::OpenFlags flags = SQLiteDb::CREATE_MISSING;
flags |= storeToDisk ? SQLiteDb::NO_OPTIONS : SQLiteDb::FORCE_IN_MEMORY;
return SQLiteDb::openDb(fileName, !storeToDisk, listOfTables());
return SQLiteDb::openDb(fileName, flags);
}
bool FileDb::vacuumFileDb(void)
......@@ -314,11 +312,9 @@ bool FileDb::vacuumFileDb(void)
return false;
}
QList<class SQLiteTbl *> FileDb::listOfTables(void)
QList<class SQLiteTbl *> FileDb::listOfTables(void) const
{
static QList<class SQLiteTbl *> tables;
if (tables.isEmpty()) {
tables.append(&flsTbl);
}
QList<class SQLiteTbl *> tables;
tables.append(&flsTbl);
return tables;
}
......@@ -146,14 +146,14 @@ public:
*/
bool vacuumFileDb(void);
private:
protected:
/*!
* @brief Returns list of tables.
*
* @return List of pointers to tables.
*/
static
QList<class SQLiteTbl *> listOfTables(void);
virtual
QList<class SQLiteTbl *> listOfTables(void) const Q_DECL_OVERRIDE;
};
#endif /* _FILE_DB_H_ */
......@@ -58,12 +58,12 @@ MessageDb::MessageDb(const QString &connectionName)
bool MessageDb::copyDb(const QString &newFileName)
{
return SQLiteDb::copyDb(newFileName, listOfTables());
return SQLiteDb::copyDb(newFileName, SQLiteDb::CREATE_MISSING);
}
bool MessageDb::reopenDb(const QString &newFileName)
{
return SQLiteDb::reopenDb(newFileName, listOfTables());
return SQLiteDb::reopenDb(newFileName, SQLiteDb::CREATE_MISSING);
}
bool MessageDb::deleteMsgFromDb(qint64 msgId)
......@@ -711,11 +711,10 @@ bool MessageDb::markMessagesLocallyRead(enum MessageType messageType, bool read)
bool MessageDb::openDb(const QString &fileName, bool storeToDisk)
{
if (storeToDisk && fileName.isEmpty()) {
Q_ASSERT(0);
return false;
}
return SQLiteDb::openDb(fileName, !storeToDisk, listOfTables());
SQLiteDb::OpenFlags flags = SQLiteDb::CREATE_MISSING;
flags |= storeToDisk ? SQLiteDb::NO_OPTIONS : SQLiteDb::FORCE_IN_MEMORY;
return SQLiteDb::openDb(fileName, flags);
}
int MessageDb::searchAndAppendMsgs(MessageListModel *msgModel,
......@@ -915,12 +914,10 @@ fail:
return false;
}
QList<class SQLiteTbl *> MessageDb::listOfTables(void)
QList<class SQLiteTbl *> MessageDb::listOfTables(void) const
{
static QList<class SQLiteTbl *> tables;
if (tables.isEmpty()) {
tables.append(&msgsTbl);
tables.append(&evntsTbl);
}
QList<class SQLiteTbl *> tables;
tables.append(&msgsTbl);
tables.append(&evntsTbl);
return tables;
}
......@@ -256,6 +256,15 @@ public:
*/
bool updateMessageEnvelopeInDb(const MsgEnvelope &msgEnvelopeData);
protected:
/*!
* @brief Returns list of tables.
*
* @return List of pointers to tables.
*/
virtual
QList<class SQLiteTbl *> listOfTables(void) const Q_DECL_OVERRIDE;
private:
static
const QVector<QString> msgPrintedAttribs;
......@@ -263,14 +272,6 @@ private:
const QVector<QString> msgStatus;
static
const QVector<QString> fileItemIds;
/*!
* @brief Returns list of tables.
*
* @return List of pointers to tables.
*/
static
QList<class SQLiteTbl *> listOfTables(void);
};
#endif /* _MESSAGE_DB_H_ */
......@@ -31,6 +31,7 @@
#include <QStandardPaths>
#include "src/io/filesystem.h"
#include "src/log/log.h"
#include "src/sqlite/db_tables.h"
#include "src/sqlite/dbs.h"
#include "src/sqlite/zfo_db.h"
......@@ -50,44 +51,12 @@ bool ZfoDb::openDb(const QString &fileName, bool storeToDisk)
return false;
}
bool ret = SQLiteDb::openDb(
dirName + QDir::separator() + QDir::toNativeSeparators(fileName),
!storeToDisk, listOfTables());
if (!ret) {
return ret;
}
/* Insert zfo size count row into table if not exists */
QSqlQuery query(m_db);
QString queryStr = "SELECT count(*) FROM zfo_size_cnt";
if (!query.prepare(queryStr)) {
qCritical() << "Cannot prepare SQL query:" <<
query.lastError().text().toUtf8().constData();
goto fail;
}
if (query.exec() && query.isActive() && query.first() && query.isValid()) {
if (0 == query.value(0).toInt()) {
queryStr = "INSERT INTO zfo_size_cnt (id,totalSize) "
"VALUES (0,0)";
if (!query.prepare(queryStr)) {
qCritical() << "Cannot prepare SQL query:" <<
query.lastError().text().toUtf8().constData();
goto fail;
}
return query.exec();
}
return true;
} else {
qCritical() <<
"Cannot execute SQL query and/or read SQL data: %s.",
query.lastError().text().toUtf8().constData();
}
SQLiteDb::OpenFlags flags = SQLiteDb::CREATE_MISSING;
flags |= storeToDisk ? SQLiteDb::NO_OPTIONS : SQLiteDb::FORCE_IN_MEMORY;
fail:
return false;
return SQLiteDb::openDb(
dirName + QDir::separator() + QDir::toNativeSeparators(fileName),
flags);
}
void ZfoDb::deleteZfo(qint64 msgId, bool isTestAccount, int zfoSize)
......@@ -350,14 +319,48 @@ fail:
return false;
}
QList<class SQLiteTbl *> ZfoDb::listOfTables(void)
QList<class SQLiteTbl *> ZfoDb::listOfTables(void) const
{
static QList<class SQLiteTbl *> tables;
if (tables.isEmpty()) {
tables.append(&msgZfoTbl);
tables.append(&zfoSizeCntTbl);
}
QList<class SQLiteTbl *> tables;
tables.append(&msgZfoTbl);
tables.append(&zfoSizeCntTbl);
return tables;
}
bool ZfoDb::assureConsistency(void)
{
logInfoNL("Assuring zfo_size_cnt content in database '%s'.",
fileName().toUtf8().constData());
/* Insert ZFO size count row into table if it does not exist. */
QSqlQuery query(m_db);
QString queryStr = "SELECT count(*) FROM zfo_size_cnt";
if (!query.prepare(queryStr)) {
logErrorNL("Cannot prepare SQL query: %s.",
query.lastError().text().toUtf8().constData());
goto fail;
}
if (query.exec() && query.isActive() && query.first() && query.isValid()) {
if (0 == query.value(0).toInt()) {
queryStr = "INSERT INTO zfo_size_cnt (id,totalSize) "
"VALUES (0,0)";
if (!query.prepare(queryStr)) {
logErrorNL("Cannot prepare SQL query: %s.",
query.lastError().text().toUtf8().constData());
goto fail;
}
return query.exec();
}
return true;
} else {
logErrorNL("Cannot execute SQL query and/or read SQL data: %s.",
query.lastError().text().toUtf8().constData());
}
fail:
return false;
}
ZfoDb *globZfoDbPtr = Q_NULLPTR;
......@@ -38,7 +38,6 @@
class ZfoDb : public SQLiteDb {
public:
explicit ZfoDb(const QString &connectionName);
/*!
......@@ -114,14 +113,22 @@ public:
*/
void updateZfoLastAccessTime(qint64 msgId, bool isTestAccount);
private:
protected:
/*!
* @brief Returns list of tables.
*
* @return List of pointers to tables.
*/
static
QList<class SQLiteTbl *> listOfTables(void);
virtual
QList<class SQLiteTbl *> listOfTables(void) const Q_DECL_OVERRIDE;
/*!
* @brief Inserts ZFO size row if it does not exist.
*
* @return True on success.
*/
virtual
bool assureConsistency(void) Q_DECL_OVERRIDE;
};
/*!
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment