source: src/orm/ormrecord.h @ 680a4da

qt5
Last change on this file since 680a4da was 680a4da, checked in by pavelpa <pavelpa@…>, 12 years ago

work on favourite

  • created 'favourite' column in EVENT table
  • modified 'ormrecord' for setting record's elements
  • favourities view not implemented
  • Property mode set to 100644
File size: 4.6 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 QString columnsForSelect(const QString& prefix = QString());
47    static QString selectQuery();
48    static QString updateQuery();
49    static QSqlRecord toRecord(const QList<QSqlField> & columnList);
50
51    static QVariant convertToC(QVariant value, QVariant::Type colType);
52    static QVariant convertToDb(QVariant value, QVariant::Type colType);
53};
54
55template <typename T>
56OrmRecord<T>::OrmRecord()
57{
58    QSqlRecord::operator=(T::sColumns);
59}
60
61template <typename T>
62T OrmRecord<T>::hydrate(const QSqlRecord& record)
63{
64    T object;
65    object.QSqlRecord::operator=(record);
66    return object;
67}
68
69// updates specified column 'col'
70// if the value is not specified  as an argument,
71// it's taken from the reford itself
72// see also: setValue() method for more details
73template <typename T>
74void OrmRecord<T>::update(QString col, QVariant value)
75{
76    QSqlQuery query;
77    query.prepare(QString(updateQuery() + "SET %1 = :col WHERE id = :id").arg(col));
78    if(value.isValid()) // take 'col' value from the method's arguments
79        query.bindValue(":col", value);
80    else // take 'col' value from the record; see setValue()
81        query.bindValue(":col", convertToDb(this->value(col), this->value(col).type()));
82    query.bindValue(":id", this->value("id"));
83    //query.bindValue(":id", convertToDb(value("id"), QVariant::Int));
84    query.exec();
85}
86
87template <typename T>
88QVariant OrmRecord<T>::value(QString col) const
89{
90    return convertToC(QSqlRecord::value(col), T::sColumns.field(col).type());
91}
92
93template <typename T>
94void OrmRecord<T>::setValue(QString col, QVariant value)
95{
96    QSqlRecord::setValue(col, convertToDb(value, T::sColumns.field(col).type()));
97}
98
99template <typename T>
100T OrmRecord<T>::loadOne(QSqlQuery query)
101{
102    if (!query.isActive())
103    {
104        if (!query.exec())
105        {
106            throw new OrmSqlException(query.lastError().text());
107        }
108    }
109
110    if (!query.next())
111    {
112        throw new OrmNoObjectException();
113    }
114
115    return hydrate(query.record());
116}
117
118template <typename T>
119QList<T> OrmRecord<T>::load(QSqlQuery query)
120{
121    if (!query.isActive())
122    {
123        if (!query.exec())
124        {
125            throw new OrmSqlException(query.lastError().text());
126        }
127    }
128
129    QList<T> objects;
130    while (query.next())
131    {
132        objects << hydrate(query.record());
133    }
134
135    return objects;
136}
137
138template <typename T>
139QString OrmRecord<T>::columnsForSelect(const QString& prefix)
140{
141    QStringList prefixedColumns;
142    for (int i=0; i<T::sColumns.count(); i++)
143    {
144        prefixedColumns.append(prefix.isEmpty() ?
145            T::sColumns.field(i).name() :
146            QString("%1.%2").arg(prefix, T::sColumns.field(i).name()));
147    }
148    return prefixedColumns.join(",");
149}
150
151template <typename T>
152QString OrmRecord<T>::selectQuery()
153{
154    return QString("SELECT %1 FROM %2 ").arg(columnsForSelect(), T::sTableName);
155}
156
157template <typename T>
158QString OrmRecord<T>::updateQuery()
159{
160    return QString("UPDATE %1 ").arg(T::sTableName);
161}
162
163template <typename T>
164QSqlRecord OrmRecord<T>::toRecord(const QList<QSqlField> & columnList)
165{
166    QSqlRecord record;
167    foreach (const QSqlField & col, columnList)
168    {
169        record.append(col);
170    }
171    return record;
172}
173
174template <typename T>
175QVariant OrmRecord<T>::convertToC(QVariant value, QVariant::Type colType)
176{
177    if (colType == QVariant::DateTime && value.canConvert<uint>())
178    {
179        QDateTime date;
180        date.setTimeSpec(Qt::UTC);
181        date.setTime_t(value.toUInt());
182        return date;
183    }
184
185    return value;
186}
187
188template <typename T>
189QVariant OrmRecord<T>::convertToDb(QVariant value, QVariant::Type colType)
190{
191    if (colType == QVariant::DateTime && value.canConvert<QDateTime>())
192    {
193        return value.toDateTime().toTime_t();
194    }
195
196    return value;
197}
198
199#endif // ORMRECORD_H
Note: See TracBrowser for help on using the repository browser.