source: src/orm/ormrecord.h @ 9d8946b

qt5
Last change on this file since 9d8946b was 9d8946b, checked in by timkoma <timkoma@…>, 12 years ago

update for the search

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