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

qt5
Last change on this file since 6a807e7 was 7d7659d, checked in by pavelpa <pavelpa@…>, 12 years ago

combined EVENT and VIRTUAL_EVENT => 'EVENT' now

  • Maemo sqlite doesn't support Full-Text-Search
  • Property mode set to 100644
File size: 4.8 KB
Line 
1#ifndef ORMRECORD_H
2#define ORMRECORD_H
3
4#include <QSqlQuery>
5#include <QSqlRecord>
6#include <QSqlField>
7#include <QSqlError>
8#include <QStringList>
9#include <QDateTime>
10#include <QDebug>
11
12class OrmException
13{
14};
15
16class OrmNoObjectException : OrmException
17{
18};
19
20class OrmSqlException : OrmException
21{
22public:
23    OrmSqlException(const QString& text) : mText(text) {}
24    QString text() const { return mText; }
25
26private:
27    QString mText;
28};
29
30template <typename T>
31class OrmRecord : protected QSqlRecord
32{
33public:
34    OrmRecord();
35    static T hydrate(const QSqlRecord& record);
36    void update(QString col, QVariant value = QVariant()); // updates specified column 'col'
37
38protected:
39    QVariant value(QString col) const;
40    void setValue(QString col, QVariant value);
41
42    static T loadOne(QSqlQuery query);
43    static QList<T> load(QSqlQuery query);
44
45    // auxiliary methods
46    static QSqlRecord toRecord(const QList<QSqlField> & columnList);
47    // all record items/columns are in one table
48    static QString columnsForSelect(const QString& prefix = QString());
49    static QString selectQuery();
50    static QString updateQuery();
51
52    static QVariant convertToC(QVariant value, QVariant::Type colType);
53    static QVariant convertToDb(QVariant value, QVariant::Type colType);
54};
55
56template <typename T>
57OrmRecord<T>::OrmRecord()
58{
59    QSqlRecord::operator=(T::sColumns);
60}
61
62template <typename T>
63T OrmRecord<T>::hydrate(const QSqlRecord& record)
64{
65    T object;
66    object.QSqlRecord::operator=(record);
67    return object;
68}
69
70// updates specified column 'col'
71// if the value is not specified  as an argument,
72// it's taken from the reford itself
73// see also: setValue() method for more details
74template <typename T>
75void OrmRecord<T>::update(QString col, QVariant value)
76{
77    QSqlQuery query;
78    query.prepare(QString(updateQuery() + "SET %1 = :col WHERE id = :id").arg(col));
79    if(value.isValid()) // take 'col' value from the method's arguments
80        query.bindValue(":col", value);
81    else // take 'col' value from the record; see setValue()
82        query.bindValue(":col", convertToDb(this->value(col), this->value(col).type()));
83    query.bindValue(":id", this->value("id"));
84    //query.bindValue(":id", convertToDb(value("id"), QVariant::Int));
85    query.exec();
86}
87
88template <typename T>
89QVariant OrmRecord<T>::value(QString col) const
90{
91    return convertToC(QSqlRecord::value(col), T::sColumns.field(col).type());
92}
93
94template <typename T>
95void OrmRecord<T>::setValue(QString col, QVariant value)
96{
97    QSqlRecord::setValue(col, convertToDb(value, T::sColumns.field(col).type()));
98}
99
100template <typename T>
101T OrmRecord<T>::loadOne(QSqlQuery query)
102{
103    if (!query.isActive())
104    {
105        if (!query.exec())
106        {
107            throw OrmSqlException(query.lastError().text());
108        }
109    }
110
111    if (!query.next())
112    {
113        throw OrmNoObjectException();
114    }
115
116    return hydrate(query.record());
117}
118
119template <typename T>
120QList<T> OrmRecord<T>::load(QSqlQuery query)
121{
122    if (!query.isActive())
123    {
124        if (!query.exec())
125        {
126            qDebug() << "Error: " << query.lastError().driverText() << "; Type: " << query.lastError().type();
127            throw OrmSqlException(query.lastError().text());
128        }
129        else
130        {
131            qDebug() << "SQL OK";
132        }
133    }
134
135    QList<T> objects;
136    while (query.next())
137    {
138        objects << hydrate(query.record());
139    }
140    qDebug() << "Fetch done";
141    return objects;
142}
143
144template <typename T>
145QString OrmRecord<T>::columnsForSelect(const QString& prefix)
146{
147    QStringList prefixedColumns;
148    for (int i=0; i<T::sColumns.count(); i++)
149    {
150        prefixedColumns.append(prefix.isEmpty() ?
151            T::sColumns.field(i).name() :
152            QString("%1.%2").arg(prefix, T::sColumns.field(i).name()));
153    }
154    return prefixedColumns.join(",");
155}
156
157template <typename T>
158QString OrmRecord<T>::selectQuery()
159{
160    return QString("SELECT %1 FROM %2 ").arg(columnsForSelect(), T::sTableName);
161}
162
163template <typename T>
164QString OrmRecord<T>::updateQuery()
165{
166    return QString("UPDATE %1 ").arg(T::sTableName);
167}
168
169template <typename T>
170QSqlRecord OrmRecord<T>::toRecord(const QList<QSqlField> & columnList)
171{
172    QSqlRecord record;
173    foreach (const QSqlField & col, columnList)
174    {
175        record.append(col);
176    }
177    return record;
178}
179
180template <typename T>
181QVariant OrmRecord<T>::convertToC(QVariant value, QVariant::Type colType)
182{
183    if (colType == QVariant::DateTime && value.canConvert<uint>())
184    {
185        QDateTime date;
186        date.setTimeSpec(Qt::UTC);
187        date.setTime_t(value.toUInt());
188        return date;
189    }
190
191    return value;
192}
193
194template <typename T>
195QVariant OrmRecord<T>::convertToDb(QVariant value, QVariant::Type colType)
196{
197    if (colType == QVariant::DateTime && value.canConvert<QDateTime>())
198    {
199        return value.toDateTime().toTime_t();
200    }
201
202    return value;
203}
204
205#endif // ORMRECORD_H
206
Note: See TracBrowser for help on using the repository browser.