source: src/orm/ormrecord.h @ 6df32f2

qt5
Last change on this file since 6df32f2 was 6df32f2, checked in by gregor herrmann <gregoa@…>, 10 years ago

Update GPL blurb in source files.

  • Property mode set to 100644
File size: 5.8 KB
RevLine 
[ca90cb1]1/*
2 * Copyright (C) 2010 Ixonos Plc.
3 *
[6df32f2]4 * This file is part of ConfClerk.
[ca90cb1]5 *
[6df32f2]6 * ConfClerk is free software: you can redistribute it and/or modify it
[ca90cb1]7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation, either version 2 of the License, or (at your option)
9 * any later version.
10 *
[6df32f2]11 * ConfClerk is distributed in the hope that it will be useful, but
[ca90cb1]12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
[6df32f2]17 * ConfClerk.  If not, see <http://www.gnu.org/licenses/>.
[ca90cb1]18 */
[20a6010]19#ifndef ORMRECORD_H
20#define ORMRECORD_H
21
22#include <QSqlQuery>
[5a73d27]23#include <QSqlRecord>
24#include <QSqlField>
[20a6010]25#include <QSqlError>
26#include <QStringList>
27#include <QDateTime>
28#include <QDebug>
29
30class OrmException
31{
[9d8946b]32public:
[a0f3e32]33    OrmException(const QString& text) : mText(text) {}
34    virtual ~OrmException(){}
[9d8946b]35    virtual const QString& text() const { return mText; }
36private:
37    QString mText;
[20a6010]38};
39
[0d4ecc2]40class OrmNoObjectException : public OrmException
[20a6010]41{
[9d8946b]42public:
[a0f3e32]43    OrmNoObjectException() : OrmException("No object exception"){}
44    ~OrmNoObjectException(){}
[20a6010]45};
46
[0d4ecc2]47class OrmSqlException : public OrmException
[20a6010]48{
49public:
[a0f3e32]50    OrmSqlException(const QString& text) : OrmException( QString("Sql error: ") + text ) {}
51    ~OrmSqlException(){}
[20a6010]52};
[5a73d27]53
54template <typename T>
55class OrmRecord : protected QSqlRecord
56{
57public:
[20a6010]58    OrmRecord();
59    static T hydrate(const QSqlRecord& record);
[680a4da]60    void update(QString col, QVariant value = QVariant()); // updates specified column 'col'
[5a73d27]61
62protected:
[20a6010]63    QVariant value(QString col) const;
64    void setValue(QString col, QVariant value);
65
66    static T loadOne(QSqlQuery query);
67    static QList<T> load(QSqlQuery query);
68
69    // auxiliary methods
[c790268]70    static QSqlRecord toRecord(const QList<QSqlField> & columnList);
71    // all record items/columns are in one table
[20a6010]72    static QString columnsForSelect(const QString& prefix = QString());
73    static QString selectQuery();
[680a4da]74    static QString updateQuery();
[20a6010]75
76    static QVariant convertToC(QVariant value, QVariant::Type colType);
77    static QVariant convertToDb(QVariant value, QVariant::Type colType);
[5a73d27]78};
79
80template <typename T>
[20a6010]81OrmRecord<T>::OrmRecord()
82{
83    QSqlRecord::operator=(T::sColumns);
84}
85
86template <typename T>
87T OrmRecord<T>::hydrate(const QSqlRecord& record)
88{
89    T object;
90    object.QSqlRecord::operator=(record);
91    return object;
92}
93
[680a4da]94// updates specified column 'col'
95// if the value is not specified  as an argument,
96// it's taken from the reford itself
97// see also: setValue() method for more details
98template <typename T>
99void OrmRecord<T>::update(QString col, QVariant value)
100{
101    QSqlQuery query;
102    query.prepare(QString(updateQuery() + "SET %1 = :col WHERE id = :id").arg(col));
103    if(value.isValid()) // take 'col' value from the method's arguments
104        query.bindValue(":col", value);
105    else // take 'col' value from the record; see setValue()
106        query.bindValue(":col", convertToDb(this->value(col), this->value(col).type()));
107    query.bindValue(":id", this->value("id"));
108    //query.bindValue(":id", convertToDb(value("id"), QVariant::Int));
109    query.exec();
110}
111
[20a6010]112template <typename T>
113QVariant OrmRecord<T>::value(QString col) const
114{
115    return convertToC(QSqlRecord::value(col), T::sColumns.field(col).type());
116}
117
118template <typename T>
119void OrmRecord<T>::setValue(QString col, QVariant value)
120{
121    QSqlRecord::setValue(col, convertToDb(value, T::sColumns.field(col).type()));
122}
123
124template <typename T>
125T OrmRecord<T>::loadOne(QSqlQuery query)
126{
127    if (!query.isActive())
128    {
129        if (!query.exec())
130        {
[72cd3af]131            throw OrmSqlException(query.lastError().text());
[20a6010]132        }
133    }
134
135    if (!query.next())
136    {
[72cd3af]137        throw OrmNoObjectException();
[20a6010]138    }
139
140    return hydrate(query.record());
141}
142
143template <typename T>
144QList<T> OrmRecord<T>::load(QSqlQuery query)
145{
146    if (!query.isActive())
147    {
148        if (!query.exec())
149        {
[fbc1646]150            qDebug() << "Error: " << query.lastError().driverText() << "; Type: " << query.lastError().type();
[72cd3af]151            throw OrmSqlException(query.lastError().text());
[20a6010]152        }
[e662750]153        else
154        {
[ea638ef]155            /*qDebug() << "SQL OK";*/
[e662750]156        }
[20a6010]157    }
158
159    QList<T> objects;
160    while (query.next())
161    {
162        objects << hydrate(query.record());
163    }
[ea638ef]164    /*qDebug() << "Fetch done";*/
[20a6010]165    return objects;
166}
167
168template <typename T>
169QString OrmRecord<T>::columnsForSelect(const QString& prefix)
[5a73d27]170{
[20a6010]171    QStringList prefixedColumns;
172    for (int i=0; i<T::sColumns.count(); i++)
173    {
174        prefixedColumns.append(prefix.isEmpty() ?
175            T::sColumns.field(i).name() :
176            QString("%1.%2").arg(prefix, T::sColumns.field(i).name()));
177    }
178    return prefixedColumns.join(",");
[5a73d27]179}
180
181template <typename T>
[20a6010]182QString OrmRecord<T>::selectQuery()
[5a73d27]183{
[20a6010]184    return QString("SELECT %1 FROM %2 ").arg(columnsForSelect(), T::sTableName);
185}
[5a73d27]186
[680a4da]187template <typename T>
188QString OrmRecord<T>::updateQuery()
189{
[7d7659d]190    return QString("UPDATE %1 ").arg(T::sTableName);
[680a4da]191}
192
[20a6010]193template <typename T>
194QSqlRecord OrmRecord<T>::toRecord(const QList<QSqlField> & columnList)
195{
196    QSqlRecord record;
[5d22816]197    for(int i=0; i< columnList.count(); i++)
[20a6010]198    {
[5d22816]199        record.append(columnList[i]);
[20a6010]200    }
201    return record;
[5a73d27]202}
203
204template <typename T>
[20a6010]205QVariant OrmRecord<T>::convertToC(QVariant value, QVariant::Type colType)
[5a73d27]206{
[489f262]207    if (colType == QVariant::DateTime && value.canConvert<uint>())
[20a6010]208    {
209        QDateTime date;
[489f262]210        date.setTimeSpec(Qt::UTC);
[20a6010]211        date.setTime_t(value.toUInt());
212        return date;
213    }
[5a73d27]214
[20a6010]215    return value;
216}
[5a73d27]217
[20a6010]218template <typename T>
219QVariant OrmRecord<T>::convertToDb(QVariant value, QVariant::Type colType)
220{
[d0d0a66]221    if (colType == QVariant::DateTime && value.canConvert<QDateTime>())
[5a73d27]222    {
[20a6010]223        return value.toDateTime().toTime_t();
[5a73d27]224    }
225
[20a6010]226    return value;
[5a73d27]227}
[20a6010]228
229#endif // ORMRECORD_H
[c790268]230
Note: See TracBrowser for help on using the repository browser.