2 * Copyright (C) 2010 Ixonos Plc.
3 * Copyright (C) 2011 Philipp Spitzer, gregor herrmann
5 * This file is part of ConfClerk.
7 * ConfClerk is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation, either version 2 of the License, or (at your option)
12 * ConfClerk is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * You should have received a copy of the GNU General Public License along with
18 * ConfClerk. If not, see <http://www.gnu.org/licenses/>.
27 #include <QStringList>
34 OrmException(const QString& text) : mText(text) {}
35 virtual ~OrmException(){}
36 virtual const QString& text() const { return mText; }
41 class OrmNoObjectException : public OrmException
44 OrmNoObjectException() : OrmException("No object exception"){}
45 ~OrmNoObjectException(){}
48 class OrmSqlException : public OrmException
51 OrmSqlException(const QString& text) : OrmException( QString("Sql error: ") + text ) {}
56 class OrmRecord : protected QSqlRecord
60 static T hydrate(const QSqlRecord& record);
61 void update(QString col, QVariant value = QVariant()); // updates specified column 'col'
64 QVariant value(QString col) const;
65 void setValue(QString col, QVariant value);
67 static T loadOne(QSqlQuery query);
68 static QList<T> load(QSqlQuery query);
71 static QSqlRecord toRecord(const QList<QSqlField> & columnList);
72 // all record items/columns are in one table
73 static QString columnsForSelect(const QString& prefix = QString());
74 static QString selectQuery();
75 static QString updateQuery();
77 static QVariant convertToC(QVariant value, QVariant::Type colType);
78 static QVariant convertToDb(QVariant value, QVariant::Type colType);
82 OrmRecord<T>::OrmRecord()
84 QSqlRecord::operator=(T::sColumns);
88 T OrmRecord<T>::hydrate(const QSqlRecord& record)
91 object.QSqlRecord::operator=(record);
95 // updates specified column 'col'
96 // if the value is not specified as an argument,
97 // it's taken from the reford itself
98 // see also: setValue() method for more details
100 void OrmRecord<T>::update(QString col, QVariant value)
103 query.prepare(QString(updateQuery() + "SET %1 = :col WHERE id = :id").arg(col));
104 if(value.isValid()) // take 'col' value from the method's arguments
105 query.bindValue(":col", value);
106 else // take 'col' value from the record; see setValue()
107 query.bindValue(":col", convertToDb(this->value(col), this->value(col).type()));
108 query.bindValue(":id", this->value("id"));
109 //query.bindValue(":id", convertToDb(value("id"), QVariant::Int));
113 template <typename T>
114 QVariant OrmRecord<T>::value(QString col) const
116 return convertToC(QSqlRecord::value(col), T::sColumns.field(col).type());
119 template <typename T>
120 void OrmRecord<T>::setValue(QString col, QVariant value)
122 QSqlRecord::setValue(col, convertToDb(value, T::sColumns.field(col).type()));
125 template <typename T>
126 T OrmRecord<T>::loadOne(QSqlQuery query)
128 if (!query.isActive())
132 throw OrmSqlException(query.lastError().text());
138 throw OrmNoObjectException();
141 return hydrate(query.record());
144 template <typename T>
145 QList<T> OrmRecord<T>::load(QSqlQuery query)
147 if (!query.isActive())
151 qDebug() << "Error: " << query.lastError().driverText() << "; Type: " << query.lastError().type();
152 throw OrmSqlException(query.lastError().text());
156 /*qDebug() << "SQL OK";*/
163 objects << hydrate(query.record());
165 /*qDebug() << "Fetch done";*/
169 template <typename T>
170 QString OrmRecord<T>::columnsForSelect(const QString& prefix)
172 QStringList prefixedColumns;
173 for (int i=0; i<T::sColumns.count(); i++)
175 prefixedColumns.append(prefix.isEmpty() ?
176 T::sColumns.field(i).name() :
177 QString("%1.%2").arg(prefix, T::sColumns.field(i).name()));
179 return prefixedColumns.join(",");
182 template <typename T>
183 QString OrmRecord<T>::selectQuery()
185 return QString("SELECT %1 FROM %2 ").arg(columnsForSelect(), T::sTableName);
188 template <typename T>
189 QString OrmRecord<T>::updateQuery()
191 return QString("UPDATE %1 ").arg(T::sTableName);
194 template <typename T>
195 QSqlRecord OrmRecord<T>::toRecord(const QList<QSqlField> & columnList)
198 for(int i=0; i< columnList.count(); i++)
200 record.append(columnList[i]);
205 template <typename T>
206 QVariant OrmRecord<T>::convertToC(QVariant value, QVariant::Type colType)
208 if (colType == QVariant::DateTime && value.canConvert<uint>())
211 date.setTimeSpec(Qt::UTC);
212 date.setTime_t(value.toUInt());
219 template <typename T>
220 QVariant OrmRecord<T>::convertToDb(QVariant value, QVariant::Type colType)
222 if (colType == QVariant::DateTime && value.canConvert<QDateTime>())
224 return value.toDateTime().toTime_t();
230 #endif // ORMRECORD_H