New database stuff.

This commit is contained in:
Martin Rotter 2013-10-12 17:00:25 +02:00
parent 27e78b6b20
commit db554557bf
7 changed files with 221 additions and 11 deletions

View File

@ -204,6 +204,7 @@ set(APP_SOURCES
src/core/basewebpage.cpp
src/core/webbrowsernetworkaccessmanager.cpp
src/core/textfactory.cpp
src/core/databasefactory.cpp
# Basic application sources.
src/main.cpp
@ -244,6 +245,7 @@ set(APP_HEADERS
src/core/basenetworkaccessmanager.h
src/core/webbrowsernetworkaccessmanager.h
src/core/basewebpage.h
src/core/databasefactory.h
)
# Add form files.

View File

@ -0,0 +1,122 @@
#include <QApplication>
#include <QDir>
#include <QSqlQuery>
#include <QSqlError>
#include <QVariant>
#include "core/databasefactory.h"
QPointer<DatabaseFactory> DatabaseFactory::s_instance;
DatabaseFactory::DatabaseFactory(QObject *parent) : QObject(parent) {
assemblyDatabaseFilePath();
}
DatabaseFactory::~DatabaseFactory() {
qDebug("Destroying DatabaseFactory object.");
}
DatabaseFactory *DatabaseFactory::getInstance() {
if (s_instance.isNull()) {
s_instance = new DatabaseFactory(qApp);
}
return s_instance;
}
void DatabaseFactory::assemblyDatabaseFilePath() {
// TODO: Fill m_databasePath with correct path (portable or non-portable).
}
QString DatabaseFactory::getDatabasePath() {
return m_databasePath;
}
QSqlDatabase DatabaseFactory::initialize(const QString &connection_name) {
// Prepare file paths.
QDir db_path(getDatabasePath());
QFile db_file(db_path.absoluteFilePath("database.db"));
// Check if database directory exists.
if (!db_path.exists()) {
if (!db_path.mkpath(db_path.absolutePath())) {
// Failure when create database file path.
qFatal("Directory for database file '%s' was NOT created."
"This is HUGE problem.",
qPrintable(db_file.symLinkTarget()));
}
}
// Folders are created. Create new QSQLDatabase object.
QSqlDatabase database = QSqlDatabase::addDatabase("QSQLITE", connection_name);
// Setup database file path.
database.setDatabaseName(db_file.symLinkTarget());
if (!database.open()) {
qFatal("Database was NOT opened. Delivered error message: '%s'",
qPrintable(database.lastError().databaseText()));
}
else {
database.exec("PRAGMA synchronous = OFF");
database.exec("PRAGMA journal_mode = MEMORY");
database.exec("PRAGMA count_changes = OFF");
database.exec("PRAGMA temp_store = MEMORY");
//database.exec("PRAGMA foreign_keys = ON");
QSqlQuery q = database.exec("SELECT value FROM rssg_information WHERE key = 'schema_version'");
if (q.lastError().isValid()) {
qWarning("Error occurred. Database is not initialized. Initializing now.");
QFile file_init(":/database/init.sql");
file_init.open(QIODevice::ReadOnly | QIODevice::Text);
QStringList statements = QString(file_init.readAll()).split("-- !\n");//--\n");
database.exec("begin transaction");
foreach(QString i, statements) {
q = database.exec(i);
if (q.lastError().isValid()) {
if (q.lastError().number() != -1) {
break;
}
}
}
database.exec("commit");
qWarning("Database backend should be ready now.");
}
else {
q.next();
qDebug("Database connection '%s' to file %s seems to be loaded.",
qPrintable(connection_name),
qPrintable(QDir::toNativeSeparators(database.databaseName())));
qDebug("Database has version %s.", qPrintable(q.value(0).toString()));
}
q.finish();
}
return database;
}
QSqlDatabase DatabaseFactory::addConnection(const QString &connection_name) {
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", connection_name);
if (!m_initialized) {
return initialize(connection_name);
}
else {
return QSqlDatabase::addDatabase("QSQLITE", connection_name);
}
}
QSqlDatabase DatabaseFactory::getConnection(const QString &connection_name) {
return QSqlDatabase::database(connection_name);
}
void DatabaseFactory::removeConnection(const QString &connection_name) {
qDebug("Removing database connection '%s'.", qPrintable(connection_name));
QSqlDatabase::removeDatabase(connection_name);
}

View File

@ -0,0 +1,47 @@
#ifndef DATABASEFACTORY_H
#define DATABASEFACTORY_H
#include <QObject>
#include <QPointer>
#include <QSqlDatabase>
class DatabaseFactory : public QObject {
Q_OBJECT
private:
// Conctructor.
explicit DatabaseFactory(QObject *parent = 0);
// Assemblies database file path.
void assemblyDatabaseFilePath();
// Returns true if database was initialized, otherwise false.
QSqlDatabase initialize(const QString &connection_name);
// Path to database file.
QString m_databasePath;
// True if database file is initialized, otherwise false.
bool m_initialized;
// Private singleton value.
static QPointer<DatabaseFactory> s_instance;
public:
// Destructor.
virtual ~DatabaseFactory();
// Returns absolute file path to database file.
QString getDatabasePath();
// Database manipulators.
QSqlDatabase addConnection(const QString &connection_name);
QSqlDatabase getConnection(const QString &connection_name);
void removeConnection(const QString &connection_name);
// Singleton getter.
static DatabaseFactory *getInstance();
};
#endif // DATABASEFACTORY_H

View File

@ -9,14 +9,20 @@ class Settings : public QSettings {
Q_OBJECT
private:
// Constructor.
Settings(const QString & file_name, Format format, QObject * parent = 0);
// Creates settings file in correct location.
static QSettings::Status setupSettings();
// Private singleton value.
static QPointer<Settings> s_instance;
public:
// Singleton getter.
static Settings *getInstance();
// Constructor and destructor.
Settings(const QString & file_name, Format format, QObject * parent = 0);
// Destructor.
virtual ~Settings();
// Getter/setter for settings values.
@ -30,10 +36,6 @@ class Settings : public QSettings {
// Synchronises settings.
QSettings::Status checkSettings();
protected:
// Creates settings file in correct location.
static QSettings::Status setupSettings();
};
#endif // SETTINGS_H

View File

@ -1,4 +1,8 @@
#include <QString>
#include <QStringList>
#include <QDateTime>
#include <QLocale>
#include <QRegExp>
#include "core/defs.h"
#include "core/textfactory.h"
@ -10,9 +14,35 @@ TextFactory::TextFactory() {
TextFactory::~TextFactory() {
}
QString TextFactory::shorten(const QString &input) {
if (input.size() > TEXT_TITLE_LIMIT) {
return input.left(TEXT_TITLE_LIMIT - 3) + QString(3, '.');
QDateTime TextFactory::parseDateTime(const QString &date_time) {
QString date = date_time.simplified();
QDateTime dt;
QString temp;
QLocale locale(QLocale::C);
QStringList date_patterns;
date_patterns << "yyyy-MM-ddTHH:mm:ss" << "MMM dd yyyy hh:mm:ss" <<
"MMM hd yyyy hh:mm:ss" << "ddd, dd MMM yyyy HH:mm:ss" <<
"dd MMM yyyy" << "yyyy-MM-dd HH:mm:ss.z" << "yyyy-MM-dd" <<
"YYYY" << "YYYY-MM" << "YYYY-MM-DD" << "YYYY-MM-DDThh:mmTZD" <<
"YYYY-MM-DDThh:mm:ssTZD";
// Iterate over patterns and check if input date/time matches the pattern.
foreach (QString pattern, date_patterns) {
temp = date.left(pattern.size());
dt = locale.toDateTime(temp, pattern);
if (dt.isValid()) {
return dt;
}
}
qWarning("Problem with parsing date '%s', returning invalid QDateTime instance.",
qPrintable(date));
return QDateTime();
}
QString TextFactory::shorten(const QString &input, int text_length_limit) {
if (input.size() > text_length_limit) {
return input.left(text_length_limit - 3) + QString(3, '.');
}
else {
return input;

View File

@ -1,6 +1,8 @@
#ifndef TEXTFACTORY_H
#define TEXTFACTORY_H
#include "core/defs.h"
class TextFactory {
private:
@ -9,7 +11,12 @@ class TextFactory {
public:
virtual ~TextFactory();
static QString shorten(const QString &input);
// Tries to parse input textual date/time representation.
// Returns invalid date/time if processing fails.
static QDateTime parseDateTime(const QString &date_time);
// Shortens input string according to given length limit.
static QString shorten(const QString &input, int text_length_limit = TEXT_TITLE_LIMIT);
};
#endif // TEXTFACTORY_H

View File

@ -40,7 +40,7 @@ class WebBrowser : public TabContent {
WebBrowser *webBrowser();
// Returns global menu for this web browser.
QList<QAction*> globalMenu();
virtual QList<QAction*> globalMenu();
// Returns pointer to global network access manager
// for web browsers.