Huge step forward in MySQL feature.

This commit is contained in:
Martin Rotter 2014-02-07 20:15:05 +01:00
parent 000226df21
commit 9f09d57514
7 changed files with 138 additions and 12 deletions

View File

@ -43,10 +43,10 @@ DROP TABLE IF EXISTS FeedsData;
-- !
CREATE TABLE IF NOT EXISTS FeedsData (
feed_id INTEGER NOT NULL,
key TEXT NOT NULL,
value TEXT,
feed_key TEXT NOT NULL,
feed_value TEXT,
PRIMARY KEY (feed_id, key),
PRIMARY KEY (feed_id, feed_key),
FOREIGN KEY (feed_id) REFERENCES Feeds (id)
);
-- !

View File

@ -43,10 +43,10 @@ DROP TABLE IF EXISTS FeedsData;
-- !
CREATE TABLE IF NOT EXISTS FeedsData (
feed_id INTEGER NOT NULL,
key TEXT NOT NULL,
value TEXT,
feed_key TEXT NOT NULL,
feed_value TEXT,
PRIMARY KEY (feed_id, key),
PRIMARY KEY (feed_id, feed_key),
FOREIGN KEY (feed_id) REFERENCES Feeds (id)
);
-- !

View File

@ -14,6 +14,7 @@ QPointer<DatabaseFactory> DatabaseFactory::s_instance;
DatabaseFactory::DatabaseFactory(QObject *parent)
: QObject(parent),
m_mysqlDatabaseInitialized(false),
m_sqliteFileBasedDatabaseinitialized(false),
m_sqliteInMemoryDatabaseInitialized(false) {
setObjectName("DatabaseFactory");
@ -226,7 +227,7 @@ QSqlDatabase DatabaseFactory::connection(const QString &connection_name,
DesiredType desired_type) {
switch (m_activeDatabaseDriver) {
case MYSQL:
return QSqlDatabase();
return mysqlConnection(connection_name);
case SQLITE:
case SQLITE_MEMORY:
@ -295,6 +296,116 @@ void DatabaseFactory::determineDriver() {
}
}
QSqlDatabase DatabaseFactory::mysqlConnection(const QString &connection_name) {
if (!m_mysqlDatabaseInitialized) {
// Return initialized database.
return mysqlInitializeDatabase(connection_name);
}
else {
QSqlDatabase database;
if (QSqlDatabase::contains(connection_name)) {
qDebug("MySQL connection '%s' is already active.",
qPrintable(connection_name));
// This database connection was added previously, no need to
// 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(APP_DB_DRIVER_MYSQL, connection_name);
database.setHostName("localhost");
database.setPort(3306);
database.setUserName("root");
database.setDatabaseName("rssguard");
//database.setPassword("password");
}
if (!database.isOpen() && !database.open()) {
qFatal("MySQL database was NOT opened. Delivered error message: '%s'.",
qPrintable(database.lastError().text()));
}
else {
qDebug("MySQL database connection '%s' to file '%s' seems to be established.",
qPrintable(connection_name),
qPrintable(QDir::toNativeSeparators(database.databaseName())));
}
return database;
}
}
QSqlDatabase DatabaseFactory::mysqlInitializeDatabase(const QString &connection_name) {
// Folders are created. Create new QSQLDatabase object.
QSqlDatabase database = QSqlDatabase::addDatabase(APP_DB_DRIVER_MYSQL,
connection_name);
database.setHostName("localhost");
database.setPort(3306);
database.setUserName("root");
//database.setPassword("password");
if (!database.open()) {
qFatal("MySQL database was NOT opened. Delivered error message: '%s'",
qPrintable(database.lastError().text()));
}
else {
QSqlQuery query_db(database);
query_db.setForwardOnly(true);
if (!query_db.exec("USE rssguard") ||
!query_db.exec("SELECT inf_value FROM Information WHERE inf_key = 'schema_version'")) {
// If no "rssguard" database exists
// or schema version is wrong, then initialize it.
qWarning("Error occurred. MySQL database is not initialized. Initializing now.");
QFile file_init(APP_MISC_PATH + QDir::separator() + APP_DB_INIT_MYSQL);
if (!file_init.open(QIODevice::ReadOnly | QIODevice::Text)) {
// Database initialization file not opened. HUGE problem.
qFatal("MySQL database initialization file '%s' from directory '%s' was not found. File-based database is uninitialized.",
APP_DB_INIT_MYSQL,
qPrintable(APP_MISC_PATH));
}
QStringList statements = QString(file_init.readAll()).split(APP_DB_INIT_SPLIT,
QString::SkipEmptyParts);
database.transaction();
foreach(const QString &statement, statements) {
query_db.exec(statement);
if (query_db.lastError().isValid()) {
qFatal("MySQL database initialization failed. Initialization script '%s' is not correct.",
APP_DB_INIT_MYSQL);
}
}
database.commit();
qDebug("MySQL database backend should be ready now.");
}
else {
query_db.next();
qDebug("MySQL database connection '%s' seems to be established.",
qPrintable(connection_name),
qPrintable(QDir::toNativeSeparators(database.databaseName())));
qDebug("MySQL database has version '%s'.", qPrintable(query_db.value(0).toString()));
}
query_db.finish();
}
// Everything is initialized now.
m_mysqlDatabaseInitialized = true;
return database;
}
QSqlDatabase DatabaseFactory::sqliteConnection(const QString &connection_name,
DatabaseFactory::DesiredType desired_type) {
if (desired_type == DatabaseFactory::StrictlyInMemory ||

View File

@ -79,6 +79,20 @@ class DatabaseFactory : public QObject {
// Holds the type of currently activated database backend.
UsedDriver m_activeDatabaseDriver;
//
// MYSQL stuff.
//
// Returns (always OPENED) MySQL database connection.
QSqlDatabase mysqlConnection(const QString &connection_name);
// Initializes MySQL database.
QSqlDatabase mysqlInitializeDatabase(const QString &connection_name);
// True if MySQL database is fully initialized for use,
// otherwise false.
bool m_mysqlDatabaseInitialized;
//
// SQLITE stuff.
//

View File

@ -44,8 +44,9 @@
#define APP_DB_DRIVER_SQLITE "QSQLITE"
#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_MYSQL "db_init_mysql.sql"
#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_PATH "data/database/local"
#define APP_DB_FILE "database.db"

View File

@ -53,7 +53,7 @@ void FeedsModelFeed::updateCounts(bool including_total_count) {
query_all.setForwardOnly(true);
if (including_total_count) {
if (query_all.exec(QString("SELECT count() FROM Messages "
if (query_all.exec(QString("SELECT count(*) FROM Messages "
"WHERE feed = %1 AND is_deleted = 0;").arg(id())) &&
query_all.next()) {
m_totalCount = query_all.value(0).toInt();
@ -61,7 +61,7 @@ void FeedsModelFeed::updateCounts(bool including_total_count) {
}
// Obtain count of unread messages.
if (query_all.exec(QString("SELECT count() FROM Messages "
if (query_all.exec(QString("SELECT count(*) FROM Messages "
"WHERE feed = %1 AND is_deleted = 0 AND is_read = 0;").arg(id())) &&
query_all.next()) {
m_unreadCount = query_all.value(0).toInt();

View File

@ -92,7 +92,7 @@ class FeedsModelStandardFeed : public FeedsModelFeed {
// Persistently stores given messages into the database
// and updates existing messages if newer version is
// available.
void updateMessages(const QList<Message> &messages);
void updateMessages(const QList<Message> &messages);
private:
AutoUpdateType m_autoUpdateType;