source: src/orm/ormrecord.h @ 92995da

qt5
Last change on this file since 92995da was 5034a83, checked in by korrco <korrco@…>, 13 years ago

TODO for exception handling added

  • Property mode set to 100644
File size: 3.9 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
37protected:
38    QVariant value(QString col) const;
39    void setValue(QString col, QVariant value);
40
41    static T loadOne(QSqlQuery query);
42    static QList<T> load(QSqlQuery query);
43
44    // auxiliary methods
45    static QString columnsForSelect(const QString& prefix = QString());
46    static QString selectQuery();
47    static QSqlRecord toRecord(const QList<QSqlField> & columnList);
48
49    static QVariant convertToC(QVariant value, QVariant::Type colType);
50    static QVariant convertToDb(QVariant value, QVariant::Type colType);
51};
52
53template <typename T>
54OrmRecord<T>::OrmRecord()
55{
56    QSqlRecord::operator=(T::sColumns);
57}
58
59template <typename T>
60T OrmRecord<T>::hydrate(const QSqlRecord& record)
61{
62    T object;
63    object.QSqlRecord::operator=(record);
64    return object;
65}
66
67template <typename T>
68QVariant OrmRecord<T>::value(QString col) const
69{
70    return convertToC(QSqlRecord::value(col), T::sColumns.field(col).type());
71}
72
73template <typename T>
74void OrmRecord<T>::setValue(QString col, QVariant value)
75{
76    QSqlRecord::setValue(col, convertToDb(value, T::sColumns.field(col).type()));
77}
78
79template <typename T>
80T OrmRecord<T>::loadOne(QSqlQuery query)
81{
82    if (!query.isActive())
83    {
84        if (!query.exec())
85        {
86            throw new OrmSqlException(query.lastError().text());
87        }
88    }
89
90    if (!query.next())
91    {
92        throw new OrmNoObjectException();
93    }
94
95    return hydrate(query.record());
96}
97
98template <typename T>
99QList<T> OrmRecord<T>::load(QSqlQuery query)
100{
101    if (!query.isActive())
102    {
103        if (!query.exec())
104        {
105            //TODO Palo: exception handling !
106                QString start = "START\n";
107                QString end = "\nEND\n";
108                QString message = start + query.lastError().text() + end;
109                const char *data = message.toLatin1().data();
110                qDebug(data);
111            throw new OrmSqlException(query.lastError().text());
112        }
113    }
114
115    QList<T> objects;
116    while (query.next())
117    {
118        objects << hydrate(query.record());
119    }
120
121    return objects;
122}
123
124template <typename T>
125QString OrmRecord<T>::columnsForSelect(const QString& prefix)
126{
127    QStringList prefixedColumns;
128    for (int i=0; i<T::sColumns.count(); i++)
129    {
130        prefixedColumns.append(prefix.isEmpty() ?
131            T::sColumns.field(i).name() :
132            QString("%1.%2").arg(prefix, T::sColumns.field(i).name()));
133    }
134    return prefixedColumns.join(",");
135}
136
137template <typename T>
138QString OrmRecord<T>::selectQuery()
139{
140    return QString("SELECT %1 FROM %2 ").arg(columnsForSelect(), T::sTableName);
141}
142
143template <typename T>
144QSqlRecord OrmRecord<T>::toRecord(const QList<QSqlField> & columnList)
145{
146    QSqlRecord record;
147    foreach (const QSqlField & col, columnList)
148    {
149        record.append(col);
150    }
151    return record;
152}
153
154template <typename T>
155QVariant OrmRecord<T>::convertToC(QVariant value, QVariant::Type colType)
156{
157    if (colType == QVariant::DateTime && value.canConvert<uint>())
158    {
159        QDateTime date;
160        date.setTimeSpec(Qt::UTC);
161        date.setTime_t(value.toUInt());
162        return date;
163    }
164
165    return value;
166}
167
168template <typename T>
169QVariant OrmRecord<T>::convertToDb(QVariant value, QVariant::Type colType)
170{
171    if (colType == QVariant::DateTime && value.canConvert<QDateTime>())
172    {
173        return value.toDateTime().toTime_t();
174    }
175
176    return value;
177}
178
179#endif // ORMRECORD_H
Note: See TracBrowser for help on using the repository browser.