Some database optimizing.

This commit is contained in:
Martin Rotter 2014-01-13 13:56:10 +01:00
parent 16e2df6575
commit 5667b905b8
2 changed files with 50 additions and 52 deletions

View file

@ -45,7 +45,7 @@ void DatabaseFactory::assemblyDatabaseFilePath() {
} }
} }
QSqlDatabase DatabaseFactory::initializeInMemory() { QSqlDatabase DatabaseFactory::initializeInMemoryDatabase() {
QSqlDatabase database = QSqlDatabase::addDatabase(DATABASE_DRIVER); QSqlDatabase database = QSqlDatabase::addDatabase(DATABASE_DRIVER);
database.setDatabaseName(":memory:"); database.setDatabaseName(":memory:");
@ -124,8 +124,6 @@ QSqlDatabase DatabaseFactory::initializeInMemory() {
copy_contents.exec("DETACH 'storage'"); copy_contents.exec("DETACH 'storage'");
copy_contents.finish(); copy_contents.finish();
// DB is attached.
query_db.finish(); query_db.finish();
} }
@ -135,10 +133,6 @@ QSqlDatabase DatabaseFactory::initializeInMemory() {
return database; return database;
} }
QString DatabaseFactory::getDatabasePath() {
return m_databasePath;
}
// TODO: :memory: database je rychllejsi, overit // TODO: :memory: database je rychllejsi, overit
// na windows, a udelat to takto: // na windows, a udelat to takto:
// vsechny connectiony v aplikaci budou defaultní (bez connection_name) // vsechny connectiony v aplikaci budou defaultní (bez connection_name)
@ -148,7 +142,7 @@ QString DatabaseFactory::getDatabasePath() {
// a pri vypinani se zase :memory: presype do // a pri vypinani se zase :memory: presype do
// souborove databaze // souborove databaze
QSqlDatabase DatabaseFactory::initializeFileBased(const QString &connection_name) { QSqlDatabase DatabaseFactory::initializeFileBasedDatabase(const QString &connection_name) {
// Prepare file paths. // Prepare file paths.
QDir db_path(getDatabasePath()); QDir db_path(getDatabasePath());
QFile db_file(db_path.absoluteFilePath(APP_DB_FILE)); QFile db_file(db_path.absoluteFilePath(APP_DB_FILE));
@ -182,7 +176,6 @@ QSqlDatabase DatabaseFactory::initializeFileBased(const QString &connection_name
query_db.exec("PRAGMA encoding = \"UTF-8\""); query_db.exec("PRAGMA encoding = \"UTF-8\"");
query_db.exec("PRAGMA synchronous = OFF"); query_db.exec("PRAGMA synchronous = OFF");
query_db.exec("PRAGMA journal_mode = MEMORY"); query_db.exec("PRAGMA journal_mode = MEMORY");
// TODO: prozkoumat cache a page size a lockingmode co to je
query_db.exec("PRAGMA page_size = 4096"); query_db.exec("PRAGMA page_size = 4096");
query_db.exec("PRAGMA cache_size = 16384"); query_db.exec("PRAGMA cache_size = 16384");
query_db.exec("PRAGMA count_changes = OFF"); query_db.exec("PRAGMA count_changes = OFF");
@ -243,7 +236,7 @@ QSqlDatabase DatabaseFactory::connection(const QString &connection_name,
// We request in-memory database. // We request in-memory database.
if (!m_inMemoryInitialized) { if (!m_inMemoryInitialized) {
// It is not initialized yet. // It is not initialized yet.
return initializeInMemory(); return initializeInMemoryDatabase();
} }
else { else {
QSqlDatabase database = QSqlDatabase::database(); QSqlDatabase database = QSqlDatabase::database();
@ -261,43 +254,47 @@ QSqlDatabase DatabaseFactory::connection(const QString &connection_name,
return database; return database;
} }
} }
if (!m_fileBasedinitialized) {
// File-based database is not yet initialised.
return initializeFileBased(connection_name);
}
else { else {
QSqlDatabase database; // We request file-based database.
if (!m_fileBasedinitialized) {
if (QSqlDatabase::contains(connection_name)) { // File-based database is not yet initialised.
qDebug("Connection '%s' is already active.", return initializeFileBasedDatabase(connection_name);
qPrintable(connection_name));
// This database connection was added previously, no need to
// setup its properties.
database = QSqlDatabase::database(connection_name);
} }
else { else {
database = QSqlDatabase::addDatabase(DATABASE_DRIVER, connection_name); QSqlDatabase database;
QDir db_path(getDatabasePath()); if (QSqlDatabase::contains(connection_name)) {
QFile db_file(db_path.absoluteFilePath(APP_DB_FILE)); qDebug("Connection '%s' is already active.",
qPrintable(connection_name));
// Setup database file path. // This database connection was added previously, no need to
database.setDatabaseName(db_file.fileName()); // setup its properties.
database = QSqlDatabase::database(connection_name);
}
else {
// Database connection with this name does not exist
// yet, add it and set it up.
database = QSqlDatabase::addDatabase(DATABASE_DRIVER, connection_name);
QDir db_path(getDatabasePath());
QFile db_file(db_path.absoluteFilePath(APP_DB_FILE));
// Setup database file path.
database.setDatabaseName(db_file.fileName());
}
if (!database.isOpen() && !database.open()) {
qFatal("File-based database was NOT opened. Delivered error message: '%s'.",
qPrintable(database.lastError().text()));
}
else {
qDebug("File-based database connection '%s' to file '%s' seems to be established.",
qPrintable(connection_name),
qPrintable(QDir::toNativeSeparators(database.databaseName())));
}
return database;
} }
if (!database.isOpen() && !database.open()) {
qFatal("File-based database was NOT opened. Delivered error message: '%s'.",
qPrintable(database.lastError().text()));
}
else {
qDebug("File-based database connection '%s' to file '%s' seems to be established.",
qPrintable(connection_name),
qPrintable(QDir::toNativeSeparators(database.databaseName())));
}
return database;
} }
} }
@ -309,22 +306,21 @@ void DatabaseFactory::removeConnection(const QString &connection_name) {
void DatabaseFactory::saveMemoryDatabase() { void DatabaseFactory::saveMemoryDatabase() {
QSqlDatabase database = connection(); QSqlDatabase database = connection();
QSqlDatabase file_database = connection(objectName(), false); QSqlDatabase file_database = connection(objectName(), false);
QSqlQuery copy_contents(database);
QSqlQuery copy_msgs(database);
// Attach database. // Attach database.
copy_msgs.exec(QString("ATTACH DATABASE '%1' AS 'storage';").arg(file_database.databaseName())); copy_contents.exec(QString("ATTACH DATABASE '%1' AS 'storage';").arg(file_database.databaseName()));
// Copy all stuff. // Copy all stuff.
QStringList tables; tables << "Categories" << "Feeds" << "FeedsData" << QStringList tables; tables << "Categories" << "Feeds" << "FeedsData" <<
"Messages"; "Messages";
foreach (const QString &table, tables) { foreach (const QString &table, tables) {
copy_msgs.exec(QString("DELETE FROM storage.%1;").arg(table)); copy_contents.exec(QString("DELETE FROM storage.%1;").arg(table));
copy_msgs.exec(QString("INSERT INTO storage.%1 SELECT * FROM main.%1;").arg(table)); copy_contents.exec(QString("INSERT INTO storage.%1 SELECT * FROM main.%1;").arg(table));
} }
// Detach database and finish. // Detach database and finish.
copy_msgs.exec("DETACH 'storage'"); copy_contents.exec("DETACH 'storage'");
copy_msgs.finish(); copy_contents.finish();
} }

View file

@ -14,7 +14,9 @@ class DatabaseFactory : public QObject {
virtual ~DatabaseFactory(); virtual ~DatabaseFactory();
// Returns absolute file path to database file. // Returns absolute file path to database file.
QString getDatabasePath(); inline QString getDatabasePath() {
return m_databasePath;
}
// 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.
@ -40,9 +42,9 @@ class DatabaseFactory : public QObject {
void assemblyDatabaseFilePath(); void assemblyDatabaseFilePath();
// Creates new connection, initializes database and // Creates new connection, initializes database and
// returns opened connection. // returns opened connections.
QSqlDatabase initializeInMemory(); QSqlDatabase initializeInMemoryDatabase();
QSqlDatabase initializeFileBased(const QString &connection_name); QSqlDatabase initializeFileBasedDatabase(const QString &connection_name);
// Path to database file. // Path to database file.
QString m_databasePath; QString m_databasePath;