source: src/orm/ormrecord.h @ dcefa71

qt5
Last change on this file since dcefa71 was 68b2df2, checked in by gregor herrmann <gregoa@…>, 11 years ago

Add copyright to source.

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