Work on database factory.

This commit is contained in:
Martin Rotter 2014-02-07 14:29:53 +01:00
parent 005e6c18a4
commit faf934e7c6
8 changed files with 103 additions and 81 deletions

View File

@ -14,10 +14,11 @@ QPointer<DatabaseFactory> DatabaseFactory::s_instance;
DatabaseFactory::DatabaseFactory(QObject *parent) DatabaseFactory::DatabaseFactory(QObject *parent)
: QObject(parent), : QObject(parent),
m_fileBasedinitialized(false), m_sqliteFileBasedDatabaseinitialized(false),
m_inMemoryInitialized(false) { m_sqliteInMemoryDatabaseInitialized(false) {
setObjectName("DatabaseFactory"); setObjectName("DatabaseFactory");
assemblyDatabaseFilePath(); determineDriver();
sqliteAssemblyDatabaseFilePath();
} }
DatabaseFactory::~DatabaseFactory() { DatabaseFactory::~DatabaseFactory() {
@ -32,21 +33,21 @@ DatabaseFactory *DatabaseFactory::instance() {
return s_instance; return s_instance;
} }
void DatabaseFactory::assemblyDatabaseFilePath() { void DatabaseFactory::sqliteAssemblyDatabaseFilePath() {
if (Settings::instance()->type() == Settings::Portable) { if (Settings::instance()->type() == Settings::Portable) {
m_databaseFilePath = qApp->applicationDirPath() + m_sqliteDatabaseFilePath = qApp->applicationDirPath() +
QDir::separator() + QDir::separator() +
QString(APP_DB_PATH); QString(APP_DB_PATH);
} }
else { else {
m_databaseFilePath = QDir::homePath() + QDir::separator() + m_sqliteDatabaseFilePath = QDir::homePath() + QDir::separator() +
QString(APP_LOW_H_NAME) + QDir::separator() + QString(APP_LOW_H_NAME) + QDir::separator() +
QString(APP_DB_PATH); QString(APP_DB_PATH);
} }
} }
QSqlDatabase DatabaseFactory::initializeInMemoryDatabase() { QSqlDatabase DatabaseFactory::sqliteInitializeInMemoryDatabase() {
QSqlDatabase database = QSqlDatabase::addDatabase(DATABASE_DRIVER); QSqlDatabase database = QSqlDatabase::addDatabase(APP_DB_DRIVER_SQLITE);
database.setDatabaseName(":memory:"); database.setDatabaseName(":memory:");
@ -72,12 +73,12 @@ QSqlDatabase DatabaseFactory::initializeInMemoryDatabase() {
if (query_db.lastError().isValid()) { if (query_db.lastError().isValid()) {
qWarning("Error occurred. In-memory database is not initialized. Initializing now."); qWarning("Error occurred. In-memory database is not initialized. Initializing now.");
QFile file_init(APP_MISC_PATH + QDir::separator() + APP_DB_INIT_MEMORY); QFile file_init(APP_MISC_PATH + QDir::separator() + APP_DB_INIT_SQLITE_MEMORY);
if (!file_init.open(QIODevice::ReadOnly | QIODevice::Text)) { if (!file_init.open(QIODevice::ReadOnly | QIODevice::Text)) {
// Database initialization file not opened. HUGE problem. // Database initialization file not opened. HUGE problem.
qFatal("In-memory database initialization file '%s' from directory '%s' was not found. In-memory database is uninitialized.", qFatal("In-memory database initialization file '%s' from directory '%s' was not found. In-memory database is uninitialized.",
APP_DB_INIT_FILE, APP_DB_INIT_SQLITE,
qPrintable(APP_MISC_PATH)); qPrintable(APP_MISC_PATH));
} }
@ -90,7 +91,7 @@ QSqlDatabase DatabaseFactory::initializeInMemoryDatabase() {
if (query_db.lastError().isValid()) { if (query_db.lastError().isValid()) {
qFatal("In-memory database initialization failed. Initialization script '%s' is not correct.", qFatal("In-memory database initialization failed. Initialization script '%s' is not correct.",
APP_DB_INIT_FILE); APP_DB_INIT_SQLITE);
} }
} }
@ -128,14 +129,14 @@ QSqlDatabase DatabaseFactory::initializeInMemoryDatabase() {
} }
// Everything is initialized now. // Everything is initialized now.
m_inMemoryInitialized = true; m_sqliteInMemoryDatabaseInitialized = true;
return database; return database;
} }
QSqlDatabase DatabaseFactory::initializeFileBasedDatabase(const QString &connection_name) { QSqlDatabase DatabaseFactory::sqliteInitializeFileBasedDatabase(const QString &connection_name) {
// Prepare file paths. // Prepare file paths.
QDir db_path(databaseFilePath()); QDir db_path(m_sqliteDatabaseFilePath);
QFile db_file(db_path.absoluteFilePath(APP_DB_FILE)); QFile db_file(db_path.absoluteFilePath(APP_DB_FILE));
// Check if database directory exists. // Check if database directory exists.
@ -152,7 +153,7 @@ QSqlDatabase DatabaseFactory::initializeFileBasedDatabase(const QString &connect
// Folders are created. Create new QSQLDatabase object. // Folders are created. Create new QSQLDatabase object.
QSqlDatabase database; QSqlDatabase database;
database = QSqlDatabase::addDatabase(DATABASE_DRIVER, database = QSqlDatabase::addDatabase(APP_DB_DRIVER_SQLITE,
connection_name); connection_name);
database.setDatabaseName(db_file.fileName()); database.setDatabaseName(db_file.fileName());
@ -178,12 +179,12 @@ QSqlDatabase DatabaseFactory::initializeFileBasedDatabase(const QString &connect
if (query_db.lastError().isValid()) { if (query_db.lastError().isValid()) {
qWarning("Error occurred. File-based database is not initialized. Initializing now."); qWarning("Error occurred. File-based database is not initialized. Initializing now.");
QFile file_init(APP_MISC_PATH + QDir::separator() + APP_DB_INIT_FILE); QFile file_init(APP_MISC_PATH + QDir::separator() + APP_DB_INIT_SQLITE);
if (!file_init.open(QIODevice::ReadOnly | QIODevice::Text)) { if (!file_init.open(QIODevice::ReadOnly | QIODevice::Text)) {
// Database initialization file not opened. HUGE problem. // Database initialization file not opened. HUGE problem.
qFatal("Database initialization file '%s' from directory '%s' was not found. File-based database is uninitialized.", qFatal("Database initialization file '%s' from directory '%s' was not found. File-based database is uninitialized.",
APP_DB_INIT_FILE, APP_DB_INIT_SQLITE,
qPrintable(APP_MISC_PATH)); qPrintable(APP_MISC_PATH));
} }
@ -196,7 +197,7 @@ QSqlDatabase DatabaseFactory::initializeFileBasedDatabase(const QString &connect
if (query_db.lastError().isValid()) { if (query_db.lastError().isValid()) {
qFatal("File-based database initialization failed. Initialization script '%s' is not correct.", qFatal("File-based database initialization failed. Initialization script '%s' is not correct.",
APP_DB_INIT_FILE); APP_DB_INIT_SQLITE);
} }
} }
@ -216,7 +217,7 @@ QSqlDatabase DatabaseFactory::initializeFileBasedDatabase(const QString &connect
} }
// Everything is initialized now. // Everything is initialized now.
m_fileBasedinitialized = true; m_sqliteFileBasedDatabaseinitialized = true;
return database; return database;
} }
@ -225,12 +226,12 @@ QSqlDatabase DatabaseFactory::initializeFileBasedDatabase(const QString &connect
QSqlDatabase DatabaseFactory::connection(const QString &connection_name, QSqlDatabase DatabaseFactory::connection(const QString &connection_name,
DesiredType desired_type) { DesiredType desired_type) {
if (desired_type == DatabaseFactory::StrictlyInMemory || if (desired_type == DatabaseFactory::StrictlyInMemory ||
(desired_type == DatabaseFactory::FromSettings && m_inMemoryEnabled)) { (desired_type == DatabaseFactory::FromSettings && m_sqliteInMemoryDatabaseEnabled)) {
// We request in-memory database (either user don't care // We request in-memory database (either user don't care
// about the type or user overrided it in the settings). // about the type or user overrided it in the settings).
if (!m_inMemoryInitialized) { if (!m_sqliteInMemoryDatabaseInitialized) {
// It is not initialized yet. // It is not initialized yet.
return initializeInMemoryDatabase(); return sqliteInitializeInMemoryDatabase();
} }
else { else {
QSqlDatabase database = QSqlDatabase::database(); QSqlDatabase database = QSqlDatabase::database();
@ -250,9 +251,9 @@ QSqlDatabase DatabaseFactory::connection(const QString &connection_name,
} }
else { else {
// We request file-based database. // We request file-based database.
if (!m_fileBasedinitialized) { if (!m_sqliteFileBasedDatabaseinitialized) {
// File-based database is not yet initialised. // File-based database is not yet initialised.
return initializeFileBasedDatabase(connection_name); return sqliteInitializeFileBasedDatabase(connection_name);
} }
else { else {
QSqlDatabase database; QSqlDatabase database;
@ -268,9 +269,9 @@ QSqlDatabase DatabaseFactory::connection(const QString &connection_name,
else { else {
// Database connection with this name does not exist // Database connection with this name does not exist
// yet, add it and set it up. // yet, add it and set it up.
database = QSqlDatabase::addDatabase(DATABASE_DRIVER, connection_name); database = QSqlDatabase::addDatabase(APP_DB_DRIVER_SQLITE, connection_name);
QDir db_path(databaseFilePath()); QDir db_path(m_sqliteDatabaseFilePath);
QFile db_file(db_path.absoluteFilePath(APP_DB_FILE)); QFile db_file(db_path.absoluteFilePath(APP_DB_FILE));
// Setup database file path. // Setup database file path.
@ -299,7 +300,7 @@ void DatabaseFactory::removeConnection(const QString &connection_name) {
} }
void DatabaseFactory::saveMemoryDatabase() { void DatabaseFactory::saveMemoryDatabase() {
if (!m_inMemoryEnabled) { if (!m_sqliteInMemoryDatabaseEnabled) {
return; return;
} }
@ -326,11 +327,15 @@ void DatabaseFactory::saveMemoryDatabase() {
copy_contents.finish(); copy_contents.finish();
} }
void DatabaseFactory::determineInMemoryDatabase() { void DatabaseFactory::determineDriver() {
m_inMemoryEnabled = Settings::instance()->value(APP_CFG_GEN, "use_in_memory_db", false).toBool(); m_sqliteInMemoryDatabaseEnabled = Settings::instance()->value(APP_CFG_GEN, "use_in_memory_db", false).toBool();
qDebug("Working database source was determined as %s.", qDebug("Working database source was determined as %s.",
m_inMemoryEnabled ? "in-memory database" : "file-based database"); m_sqliteInMemoryDatabaseEnabled ? "in-memory database" : "file-based database");
}
void DatabaseFactory::saveDatabase() {
saveMemoryDatabase();
} }
bool DatabaseFactory::vacuumDatabase() { bool DatabaseFactory::vacuumDatabase() {

View File

@ -21,6 +21,13 @@ class DatabaseFactory : public QObject {
Q_OBJECT Q_OBJECT
public: public:
// Describes available typos of database backend.
enum UsedDriver {
SQLITE,
SQLITE_MEMORY,
MYSQL
};
// Describes what type of database user wants. // Describes what type of database user wants.
enum DesiredType { enum DesiredType {
StrictlyFileBased, StrictlyFileBased,
@ -28,14 +35,13 @@ class DatabaseFactory : public QObject {
FromSettings FromSettings
}; };
//
// GENERAL stuff.
//
// Destructor. // Destructor.
virtual ~DatabaseFactory(); virtual ~DatabaseFactory();
// Returns absolute file path to database file.
inline QString databaseFilePath() {
return m_databaseFilePath;
}
// If in-memory is true, then :memory: database is returned // If in-memory is true, then :memory: database is returned
// In-memory database is DEFAULT database. // In-memory database is DEFAULT database.
// NOTE: This always returns OPENED database. // NOTE: This always returns OPENED database.
@ -45,51 +51,65 @@ class DatabaseFactory : public QObject {
// Removes connection. // Removes connection.
void removeConnection(const QString &connection_name = QString()); void removeConnection(const QString &connection_name = QString());
// Performs saving of items from in-memory database // Performs any needed database-related operation to be done
// to file-based database. // to gracefully exit the application.
void saveMemoryDatabase(); void saveDatabase();
// Sets m_inMemoryEnabled according to user settings. // Singleton getter.
void determineInMemoryDatabase(); static DatabaseFactory *instance();
//
// SQLITE stuff.
//
// Performs "VACUUM" on the database and // Performs "VACUUM" on the database and
// returns true of operation succeeded. // returns true of operation succeeded.
bool vacuumDatabase(); bool vacuumDatabase();
// Returns whether in-memory database feature is currently
// used.
inline bool usingInMemoryDatabase() const {
return m_inMemoryEnabled;
}
// Singleton getter.
static DatabaseFactory *instance();
private: private:
//
// GENERAL stuff.
//
// Conctructor. // Conctructor.
explicit DatabaseFactory(QObject *parent = 0); explicit DatabaseFactory(QObject *parent = 0);
// Assemblies database file path. // Decides which database backend will be used in this
void assemblyDatabaseFilePath(); // application session.
void determineDriver();
// Creates new connection, initializes database and
// returns opened connections.
QSqlDatabase initializeInMemoryDatabase();
QSqlDatabase initializeFileBasedDatabase(const QString &connection_name);
// Path to database file.
QString m_databaseFilePath;
// Is database file initialized?
bool m_fileBasedinitialized;
bool m_inMemoryInitialized;
// Is true when user selected in-memory database.
// NOTE: This can be changed only on application startup.
bool m_inMemoryEnabled;
// Private singleton value. // Private singleton value.
static QPointer<DatabaseFactory> s_instance; static QPointer<DatabaseFactory> s_instance;
// Holds the type of currently activated database backend.
UsedDriver m_activeDatabaseDriver;
//
// SQLITE stuff.
//
// Performs saving of items from in-memory database
// to file-based database.
void saveMemoryDatabase();
// Assemblies database file path.
void sqliteAssemblyDatabaseFilePath();
// Creates new connection, initializes database and
// returns opened connections.
QSqlDatabase sqliteInitializeInMemoryDatabase();
QSqlDatabase sqliteInitializeFileBasedDatabase(const QString &connection_name);
// Path to database file.
QString m_sqliteDatabaseFilePath;
// Is database file initialized?
bool m_sqliteFileBasedDatabaseinitialized;
bool m_sqliteInMemoryDatabaseInitialized;
// Is true when user selected in-memory database.
// NOTE: This can be changed only on application startup.
bool m_sqliteInMemoryDatabaseEnabled;
}; };
#endif // DATABASEFACTORY_H #endif // DATABASEFACTORY_H

View File

@ -29,8 +29,6 @@
#define TEXT_TITLE_LIMIT 30 #define TEXT_TITLE_LIMIT 30
#define MAX_ZOOM_FACTOR 10.0 #define MAX_ZOOM_FACTOR 10.0
#define ICON_SIZE_SETTINGS 16 #define ICON_SIZE_SETTINGS 16
#define DATABASE_DRIVER "QSQLITE"
#define DATABASE_DRIVER_MYSQL "QMYSQL"
#define NO_PARENT_CATEGORY -1 #define NO_PARENT_CATEGORY -1
#define TRAY_ICON_BUBBLE_TIMEOUT 15000 #define TRAY_ICON_BUBBLE_TIMEOUT 15000
#define KEY_MESSAGES_VIEW "messages_view_column_" #define KEY_MESSAGES_VIEW "messages_view_column_"
@ -44,8 +42,10 @@
#define AUTO_UPDATE_INTERVAL 60000 #define AUTO_UPDATE_INTERVAL 60000
#define STARTUP_UPDATE_DELAY 500 #define STARTUP_UPDATE_DELAY 500
#define APP_DB_INIT_FILE "db_init.sql" #define APP_DB_DRIVER_SQLITE "QSQLITE"
#define APP_DB_INIT_MEMORY "db_init_memory.sql" #define APP_DB_DRIVER_MYSQL "QMYSQL"
#define APP_DB_INIT_SQLITE "db_init_sqlite.sql"
#define APP_DB_INIT_SQLITE_MEMORY "db_init_sqlite_memory.sql"
#define APP_DB_INIT_SPLIT "-- !\n" #define APP_DB_INIT_SPLIT "-- !\n"
#define APP_DB_PATH "data/database/local" #define APP_DB_PATH "data/database/local"
#define APP_DB_FILE "database.db" #define APP_DB_FILE "database.db"

View File

@ -192,7 +192,7 @@ void FormMain::onAboutToQuit() {
m_ui->m_tabWidget->feedMessageViewer()->feedsView()->clearAllReadMessages(); m_ui->m_tabWidget->feedMessageViewer()->feedsView()->clearAllReadMessages();
} }
DatabaseFactory::instance()->saveMemoryDatabase(); DatabaseFactory::instance()->saveDatabase();
saveSize(); saveSize();
if (locked_safely) { if (locked_safely) {

View File

@ -439,14 +439,14 @@ void FormSettings::loadGeneral() {
} }
// Load SQLITE. // Load SQLITE.
m_ui->m_cmbDatabaseDriver->addItem("SQLite", DATABASE_DRIVER); m_ui->m_cmbDatabaseDriver->addItem("SQLite", APP_DB_DRIVER_SQLITE);
// Load in-memory database status. // Load in-memory database status.
m_ui->m_cmbSqliteUseInMemoryDatabase->setChecked(Settings::instance()->value(APP_CFG_GEN, "use_in_memory_db", false).toBool()); m_ui->m_cmbSqliteUseInMemoryDatabase->setChecked(Settings::instance()->value(APP_CFG_GEN, "use_in_memory_db", false).toBool());
if (QSqlDatabase::isDriverAvailable(DATABASE_DRIVER_MYSQL)) { if (QSqlDatabase::isDriverAvailable(APP_DB_DRIVER_MYSQL)) {
// Load MySQL. // Load MySQL.
m_ui->m_cmbDatabaseDriver->addItem("MySQL", DATABASE_DRIVER_MYSQL); m_ui->m_cmbDatabaseDriver->addItem("MySQL", APP_DB_DRIVER_MYSQL);
// TODO: nacist username, password atp. // TODO: nacist username, password atp.
} }
@ -454,7 +454,7 @@ void FormSettings::loadGeneral() {
// TODO: nacist podle nastaveni // TODO: nacist podle nastaveni
m_ui->m_cmbDatabaseDriver->setCurrentIndex(m_ui->m_cmbDatabaseDriver->findData(Settings::instance()->value(APP_CFG_GEN, m_ui->m_cmbDatabaseDriver->setCurrentIndex(m_ui->m_cmbDatabaseDriver->findData(Settings::instance()->value(APP_CFG_GEN,
"database_driver", "database_driver",
DATABASE_DRIVER).toString())); APP_DB_DRIVER_SQLITE).toString()));
} }
void FormSettings::saveGeneral() { void FormSettings::saveGeneral() {
@ -476,13 +476,13 @@ void FormSettings::saveGeneral() {
} }
// Save data storage settings. // Save data storage settings.
QString original_db_driver = Settings::instance()->value(APP_CFG_GEN, "database_driver", DATABASE_DRIVER).toString(); QString original_db_driver = Settings::instance()->value(APP_CFG_GEN, "database_driver", APP_DB_DRIVER_SQLITE).toString();
QString selected_db_driver = m_ui->m_cmbDatabaseDriver->itemData(m_ui->m_cmbDatabaseDriver->currentIndex()).toString(); QString selected_db_driver = m_ui->m_cmbDatabaseDriver->itemData(m_ui->m_cmbDatabaseDriver->currentIndex()).toString();
// Save SQLite. // Save SQLite.
Settings::instance()->setValue(APP_CFG_GEN, "use_in_memory_db", new_inmemory); Settings::instance()->setValue(APP_CFG_GEN, "use_in_memory_db", new_inmemory);
if (QSqlDatabase::isDriverAvailable(DATABASE_DRIVER_MYSQL)) { if (QSqlDatabase::isDriverAvailable(APP_DB_DRIVER_MYSQL)) {
// Save MySQL. // Save MySQL.
// TODO: ulozit username, password atp. // TODO: ulozit username, password atp.
} }

View File

@ -71,9 +71,6 @@ int main(int argc, char *argv[]) {
IconThemeFactory::instance()->loadCurrentIconTheme(); IconThemeFactory::instance()->loadCurrentIconTheme();
SkinFactory::instance()->loadCurrentSkin(); SkinFactory::instance()->loadCurrentSkin();
// Decide whether user decided to use in-memory database or not.
DatabaseFactory::instance()->determineInMemoryDatabase();
// Load localization and setup locale before any widget is constructed. // Load localization and setup locale before any widget is constructed.
LoadLocalization(); LoadLocalization();