Commit ce1274a0 authored by Andreas Cord-Landwehr's avatar Andreas Cord-Landwehr
Browse files

Store new profiles in sqlite storage.

parent 2e5d9543
......@@ -27,12 +27,13 @@ set( learnerprofile_LIB_SRCS
learner.cpp
learninggoal.cpp
profilemanager.cpp
storage.cpp
)
kde4_add_library( learnerprofile SHARED ${learnerprofile_LIB_SRCS} )
target_link_libraries( learnerprofile
${KDE4_KDECORE_LIBS}
${KDE4_KDECORE_LIBS} ${QT_QTSQL_LIBRARY}
)
set_target_properties( learnerprofile
......
......@@ -50,12 +50,12 @@ void Learner::setName(const QString &name)
emit nameChanged();
}
QString Learner::identifier() const
int Learner::identifier() const
{
return d->identifier;
}
void Learner::setIdentifier(const QString& identifier)
void Learner::setIdentifier(int identifier)
{
if (identifier == d->identifier) {
return;
......
......@@ -36,7 +36,7 @@ class LIBLEARNERPROFILE_EXPORT Learner : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(QString id READ identifier WRITE setIdentifier NOTIFY identifierChanged)
Q_PROPERTY(int id READ identifier WRITE setIdentifier NOTIFY identifierChanged)
public:
explicit Learner(QObject *parent = 0);
......@@ -44,8 +44,8 @@ public:
QString name() const;
void setName(const QString &name);
QString identifier() const;
void setIdentifier(const QString &identifier);
int identifier() const;
void setIdentifier(int identifier);
Q_SIGNALS:
void nameChanged();
......
......@@ -32,7 +32,7 @@ public:
~LearnerPrivate() {}
QString name;
QString identifier;
int identifier;
QList<LearningGoal*> goals;
};
}
......@@ -24,7 +24,6 @@
#include <QObject>
#include <QList>
#include <QUuid>
#include <KDebug>
using namespace LearnerProfile;
......@@ -51,21 +50,17 @@ Learner * ProfileManager::addProfile(const QString &name)
Learner *learner = new Learner(this);
learner->setName(name);
//compare that profile id is unique
bool unique;
do {
learner->setIdentifier(QUuid::createUuid());
unique = true;
foreach (Learner *cpLearner, profiles()) {
if (learner->identifier() == cpLearner->identifier()) {
unique = false;
kWarning() << "Learner id already use, computing new one.";
}
// set id
int maxUsedId = 0;
foreach (Learner *cpLearner, d->m_profiles) {
if (cpLearner->identifier() >= maxUsedId) {
maxUsedId = cpLearner->identifier();
}
} while (!unique);
}
learner->setIdentifier(maxUsedId + 1);
d->m_profiles.append(learner);
d->m_storage.storeProfile(learner);
return learner;
}
......
......@@ -19,14 +19,19 @@
*/
#include "learner.h"
#include "storage.h"
#include <QString>
#include <QList>
#include <KDebug>
#include <KConfig>
#include <KConfigGroup>
#include <KStandardDirs>
#include <QString>
#include <QList>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
namespace LearnerProfile
{
class Learner;
......@@ -42,6 +47,7 @@ public:
QList<Learner*> m_profiles;
Learner *m_activeProfile;
KConfig *m_config;
Storage m_storage;
};
ProfileManagerPrivate::ProfileManagerPrivate()
......
/*
* Copyright 2013 Andreas Cord-Landwehr <cordlandwehr@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) version 3, or any
* later version accepted by the membership of KDE e.V. (or its
* successor approved by the membership of KDE e.V.), which shall
* act as a proxy defined in Section 6 of version 3 of the license.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "storage.h"
#include "learner.h"
#include <KStandardDirs>
#include <KDebug>
#include <KLocale>
#include <QSqlError>
#include <QSqlDatabase>
#include <QSqlQuery>
using namespace LearnerProfile;
Storage::Storage(QObject* parent)
: QObject(parent)
, m_errorMessage(QString())
{
}
QString Storage::errorMessage() const
{
return m_errorMessage;
}
void Storage::raiseError(const QSqlError &error)
{
m_errorMessage = QString("%1 : %2").arg(error.driverText()).arg(error.databaseText());
emit errorMessageChanged();
}
bool Storage::storeProfile(Learner *learner)
{
QSqlDatabase db = database();
// test whether ID is present
QSqlQuery idExistsQuery = db.exec(QString("SELECT value FROM profiles WHERE id = '%1'").arg(learner->identifier()));
if (db.lastError().isValid()) {
kError() << db.lastError().text();
raiseError(db.lastError());
return false;
}
if (idExistsQuery.size() < 1) {
// in case learner ID is not found in database
QSqlQuery insertCourseQuery(db);
insertCourseQuery.prepare("INSERT INTO profiles (id, name) VALUES (?, ?)");
insertCourseQuery.bindValue(0, learner->identifier());
insertCourseQuery.bindValue(1, learner->name());
insertCourseQuery.exec();
if (insertCourseQuery.lastError().isValid()) {
kError() << insertCourseQuery.lastError().text();
raiseError(insertCourseQuery.lastError());
db.rollback();
return false;
}
return true;
} else {
//FIXME
kError() << "Update not supported";
return false;
}
}
QSqlDatabase Storage::database()
{
if (QSqlDatabase::contains(QSqlDatabase::defaultConnection)) {
return QSqlDatabase::database(QSqlDatabase::defaultConnection);
}
QString path = KGlobal::dirs()->locateLocal("appdata", "learnerdata.db");
kDebug() << "Database path: " << path;
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(path);
if (!db.open()) {
kError() << "Could not open database: " << db.lastError().text();
raiseError(db.lastError());
return db;
}
if (!updateSchema()) {
kError() << "Database scheme not correct.";
return db;
}
// return correctly set up database
return db;
}
bool Storage::updateSchema()
{
QSqlDatabase db = database();
// check database version format
db.exec("CREATE TABLE IF NOT EXISTS metadata ("
"key TEXT PRIMARY KEY, "
"value TEXT"
")");
if (db.lastError().isValid()) {
kError() << db.lastError().text();
raiseError(db.lastError());
return false;
}
QSqlQuery versionQuery = db.exec("SELECT value FROM metadata WHERE key = 'version'");
if (db.lastError().isValid()) {
kError() << db.lastError().text();
raiseError(db.lastError());
return false;
}
if (versionQuery.next()) {
QString version = versionQuery.value(0).toString();
if (version != "1") {
m_errorMessage = i18n("Invalid database version '%1'.", version);
emit errorMessageChanged();
return false;
}
}
else
{
if (!db.transaction())
{
kWarning() << db.lastError().text();
raiseError(db.lastError());
return false;
}
db.exec("INSERT INTO metadata (key, value) VALUES ('version', '1')");
if (db.lastError().isValid()) {
kError() << db.lastError().text();
raiseError(db.lastError());
return false;
}
if (!db.commit()) {
kError() << db.lastError().text();
raiseError(db.lastError());
return false;
}
}
db.exec("CREATE TABLE IF NOT EXISTS profiles ("
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT"
")");
if (db.lastError().isValid()) {
kError() << db.lastError().text();
raiseError(db.lastError());
return false;
}
return true;
}
/*
* Copyright 2013 Andreas Cord-Landwehr <cordlandwehr@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) version 3, or any
* later version accepted by the membership of KDE e.V. (or its
* successor approved by the membership of KDE e.V.), which shall
* act as a proxy defined in Section 6 of version 3 of the license.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef STORAGE_H
#define STORAGE_H
#include <QObject>
class QSqlError;
class QSqlDatabase;
namespace LearnerProfile
{
class Learner;
class Storage : public QObject
{
Q_OBJECT
Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorMessageChanged)
public:
explicit Storage(QObject* parent = 0);
QString errorMessage() const;
/**
* Store profile in database. This can either be a new or an existing profile.
* If it is an existing profile, the corresponding values are updated.
*/
bool storeProfile(Learner *learner);
Q_SIGNALS:
void errorMessageChanged();
protected:
QSqlDatabase database();
void raiseError(const QSqlError &error);
private:
bool updateSchema();
QString m_errorMessage;
};
}
#endif // STORAGE_H
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