16 class OrmNoObjectException : OrmException
20 class OrmSqlException : OrmException
23 OrmSqlException(const QString& text) : mText(text) {}
24 QString text() const { return mText; }
31 class OrmRecord : protected QSqlRecord
35 static T hydrate(const QSqlRecord& record);
36 void update(QString col, QVariant value = QVariant()); // updates specified column 'col'
39 QVariant value(QString col) const;
40 void setValue(QString col, QVariant value);
42 static T loadOne(QSqlQuery query);
43 static QList<T> load(QSqlQuery query);
46 static QString columnsForSelect(const QString& prefix = QString());
47 static QString selectQuery();
48 static QString updateQuery();
49 static QSqlRecord toRecord(const QList<QSqlField> & columnList);
51 static QVariant convertToC(QVariant value, QVariant::Type colType);
52 static QVariant convertToDb(QVariant value, QVariant::Type colType);
56 OrmRecord<T>::OrmRecord()
58 QSqlRecord::operator=(T::sColumns);
62 T OrmRecord<T>::hydrate(const QSqlRecord& record)
65 object.QSqlRecord::operator=(record);
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
74 void OrmRecord<T>::update(QString col, QVariant value)
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));
88 QVariant OrmRecord<T>::value(QString col) const
90 return convertToC(QSqlRecord::value(col), T::sColumns.field(col).type());
94 void OrmRecord<T>::setValue(QString col, QVariant value)
96 QSqlRecord::setValue(col, convertToDb(value, T::sColumns.field(col).type()));
100 T OrmRecord<T>::loadOne(QSqlQuery query)
102 if (!query.isActive())
106 throw new OrmSqlException(query.lastError().text());
112 throw new OrmNoObjectException();
115 return hydrate(query.record());
118 template <typename T>
119 QList<T> OrmRecord<T>::load(QSqlQuery query)
121 if (!query.isActive())
125 throw new OrmSqlException(query.lastError().text());
132 objects << hydrate(query.record());
138 template <typename T>
139 QString OrmRecord<T>::columnsForSelect(const QString& prefix)
141 QStringList prefixedColumns;
142 for (int i=0; i<T::sColumns.count(); i++)
144 prefixedColumns.append(prefix.isEmpty() ?
145 T::sColumns.field(i).name() :
146 QString("%1.%2").arg(prefix, T::sColumns.field(i).name()));
148 return prefixedColumns.join(",");
151 template <typename T>
152 QString OrmRecord<T>::selectQuery()
154 return QString("SELECT %1 FROM %2 ").arg(columnsForSelect(), T::sTableName);
157 template <typename T>
158 QString OrmRecord<T>::updateQuery()
160 return QString("UPDATE %1 ").arg(T::sTableName);
163 template <typename T>
164 QSqlRecord OrmRecord<T>::toRecord(const QList<QSqlField> & columnList)
167 foreach (const QSqlField & col, columnList)
174 template <typename T>
175 QVariant OrmRecord<T>::convertToC(QVariant value, QVariant::Type colType)
177 if (colType == QVariant::DateTime && value.canConvert<uint>())
180 date.setTimeSpec(Qt::UTC);
181 date.setTime_t(value.toUInt());
188 template <typename T>
189 QVariant OrmRecord<T>::convertToDb(QVariant value, QVariant::Type colType)
191 if (colType == QVariant::DateTime && value.canConvert<QDateTime>())
193 return value.toDateTime().toTime_t();
199 #endif // ORMRECORD_H