EasyQtSql
Easy SQL data access helper for QtSql
EasyQtSql_QueryResult.h
Go to the documentation of this file.
1 #ifndef EASYQTSQL_QUERYRESULT_H
2 #define EASYQTSQL_QUERYRESULT_H
3 
4 /*
5  * The MIT License (MIT)
6  * Copyright 2018 Alexey Kramin
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining
9  * a copy of this software and associated documentation files (the
10  * "Software"), to deal in the Software without restriction, including
11  * without limitation the rights to use, copy, modify, merge, publish,
12  * distribute, sublicense, and/or sell copies of the Software, and to
13  * permit persons to whom the Software is furnished to do so, subject to
14  * the following conditions:
15  *
16  * The above copyright notice and this permission notice shall be
17  * included in all copies or substantial portions of the Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26  *
27 */
28 
29 #ifndef EASY_QT_SQL_MAIN
30 
31 #include <QtSql>
33 
34 #endif
35 
40 {
41  friend class Database;
42  friend class Transaction;
43  friend class PreparedQuery;
44 
45 public:
46 
50  QSqlQuery &unwrappedQuery()
51  {
52  return m_query;
53  }
54 
60  bool next()
61  {
62  bool res = m_query.next();
63 
64  if ( ! m_firstRowFetched)
65  {
66  m_fieldNames.clear();
67 
68  QSqlRecord record = m_query.record();
69 
70  for (int i = 0; i < record.count(); ++i)
71  {
72  m_fieldNames.append(record.fieldName(i));
73  }
74 
75  m_firstRowFetched = true;
76  }
77 
78  return res;
79  }
80 
86  bool previous()
87  {
88  return m_query.previous();
89  }
90 
96  bool nextResult()
97  {
98  m_firstRowFetched = false;
99 
100  bool res = m_query.nextResult();
101 
102  return res;
103  }
104 
110  bool first()
111  {
112  return m_query.first();
113  }
114 
120  bool last()
121  {
122  return m_query.last();
123  }
124 
130  bool seek(int index, bool relative = false)
131  {
132  return m_query.seek(index, relative);
133  }
134 
141  int at() const
142  {
143  return m_query.at();
144  }
145 
151  bool isActive() const
152  {
153  return m_query.isActive();
154  }
155 
161  bool isValid() const
162  {
163  return m_query.isValid();
164  }
165 
171  bool isForwardOnly() const
172  {
173  return m_query.isForwardOnly();
174  }
175 
181  int size() const
182  {
183  return m_query.size();
184  }
185 
191  int numRowsAffected() const
192  {
193  return m_query.numRowsAffected();
194  }
195 
201  QSqlError lastError() const
202  {
203  return m_query.lastError();
204  }
205 
211  QString lastQuery() const
212  {
213  return m_query.lastQuery();
214  }
215 
221  QString executedQuery() const
222  {
223  return m_query.executedQuery();
224  }
225 
231  QVariant value(int column) const
232  {
233  return m_query.value(column);
234  }
235 
241  QVariant value(const QString &colName) const
242  {
243  return m_query.value(colName);
244  }
245 
251  QVariant boundValue(int column) const
252  {
253  return m_query.boundValue(column);
254  }
255 
265  QVariant boundValue(const QString &aliasName) const
266  {
267  const int index = m_bindValueAlias.value(aliasName.trimmed().toLower(), -1);
268 
269  QVariant res;
270 
271  if (index >= 0)
272  {
273  res = boundValue(index);
274  }
275 
276  return res;
277  }
278 
284  QVariantList boundValues() const
285  {
286  QList<QVariant> list = m_query.boundValues().values();
287 
288  return list;
289  }
290 
295  QVariantMap toMap() const
296  {
297  QVariantMap res;
298 
299  fetchMap(res);
300 
301  return res;
302  }
303 
308  QVariantList toList() const
309  {
310  QVariantList res;
311 
312  fetchList(res);
313 
314  return res;
315  }
316 
321  QStringList toStringList() const
322  {
323  QStringList res;
324 
325  fetchStringList(res);
326 
327  return res;
328  }
329 
334  QVector<QVariant> toVector() const
335  {
336  QVector<QVariant> res;
337 
338  fetchVector(res);
339 
340  return res;
341  }
342 
349  template <typename T>
350  QVector<T> toVector(bool skipNullValues = false) const
351  {
352  QVector<T> res;
353 
354  res.reserve(m_fieldNames.count());
355 
356  for (int i = 0; i < m_fieldNames.count(); ++i)
357  {
358  const QVariant &value = m_query.value(i);
359 
360  if (!value.canConvert<T>())
361  continue;
362 
363  if (skipNullValues && value.isNull())
364  continue;
365 
366  res.append(value.value<T>());
367  }
368 
369  return res;
370  }
371 
381  QVector<int> parseToIntVector(int base = 10, bool skipNullValues = false) const
382  {
383  QVector<int> res;
384 
385  res.reserve(m_fieldNames.count());
386 
387  for (int i = 0; i < m_fieldNames.count(); ++i)
388  {
389  const QVariant &value = m_query.value(i);
390 
391  if (!value.canConvert<int>())
392  continue;
393 
394  if (skipNullValues && value.isNull())
395  continue;
396 
397  bool ok = false;
398  int iValue = 0;
399 
400  if ( ((value.type() == QVariant::String) || (value.type() == QVariant::ByteArray)))
401  {
402  const QString str = value.toString();
403 
404  iValue = str.toInt(&ok, base);
405  }
406  else
407  {
408  iValue = value.toInt(&ok);
409  }
410 
411  if (ok)
412  {
413  res.append(iValue);
414  }
415  }
416 
417  return res;
418  }
419 
423  template <typename T>
424  T scalar() const
425  {
426  return m_query.value(0).value<T>();
427  }
428 
432  QVariant scalar() const
433  {
434  return m_query.value(0);
435  }
436 
473  void fetchVars(int &value) const
474  {
475  value = m_query.value(m_fetchIndex).toInt();
476 
477  m_fetchIndex = 0;
478  }
479 
485  void fetchVars(double &value) const
486  {
487  value = m_query.value(m_fetchIndex).toInt();
488 
489  m_fetchIndex = 0;
490  }
491 
497  void fetchVars(QString &value) const
498  {
499  value = m_query.value(m_fetchIndex).toString();
500 
501  m_fetchIndex = 0;
502  }
503 
509  void fetchVars(bool &value) const
510  {
511  value = m_query.value(m_fetchIndex).toBool();
512 
513  m_fetchIndex = 0;
514  }
515 
521  void fetchVars(QDate &value) const
522  {
523  value = m_query.value(m_fetchIndex).toDate();
524 
525  m_fetchIndex = 0;
526  }
527 
533  void fetchVars(QDateTime &value) const
534  {
535  value = m_query.value(m_fetchIndex).toDateTime();
536 
537  m_fetchIndex = 0;
538  }
539 
545  void fetchVars(QTime &value) const
546  {
547  value = m_query.value(m_fetchIndex).toTime();
548 
549  m_fetchIndex = 0;
550  }
551 
557  void fetchVars(QByteArray &value) const
558  {
559  value = m_query.value(m_fetchIndex).toByteArray();
560 
561  m_fetchIndex = 0;
562  }
563 
569  void fetchVars(QVariant &value) const
570  {
571  value = m_query.value(m_fetchIndex);
572 
573  m_fetchIndex = 0;
574  }
575 
576  template <typename... Rest> void fetchVars(int &value, Rest&... rest) const
577  {
578  value = m_query.value(m_fetchIndex++).toInt();
579 
580  fetchVars(rest...);
581  }
582 
583  template <typename... Rest> void fetchVars(double &value, Rest&... rest) const
584  {
585  value = m_query.value(m_fetchIndex++).toDouble();
586 
587  fetchVars(rest...);
588  }
589 
590  template <typename... Rest> void fetchVars(QString &value, Rest&... rest) const
591  {
592  value = m_query.value(m_fetchIndex++).toString();
593 
594  fetchVars(rest...);
595  }
596 
597  template <typename... Rest> void fetchVars(bool &value, Rest&... rest) const
598  {
599  value = m_query.value(m_fetchIndex++).toBool();
600 
601  fetchVars(rest...);
602  }
603 
604  template <typename... Rest> void fetchVars(QDate &value, Rest&... rest) const
605  {
606  value = m_query.value(m_fetchIndex++).toDate();
607 
608  fetchVars(rest...);
609  }
610 
611  template <typename... Rest> void fetchVars(QDateTime &value, Rest&... rest) const
612  {
613  value = m_query.value(m_fetchIndex++).toDateTime();
614 
615  fetchVars(rest...);
616  }
617 
618  template <typename... Rest> void fetchVars(QTime &value, Rest&... rest) const
619  {
620  value = m_query.value(m_fetchIndex++).toTime();
621 
622  fetchVars(rest...);
623  }
624 
625  template <typename... Rest> void fetchVars(QByteArray &value, Rest&... rest) const
626  {
627  value = m_query.value(m_fetchIndex++).toByteArray();
628 
629  fetchVars(rest...);
630  }
631 
632  template <typename... Rest> void fetchVars(QVariant &value, Rest&... rest) const
633  {
634  value = m_query.value(m_fetchIndex++);
635 
636  fetchVars(rest...);
637  }
638 
686  void fetchObject(QObject &object) const
687  {
688  const QMetaObject *metaobject = object.metaObject();
689  const int count = metaobject->propertyCount();
690 
691  const QVariantMap map = toMap();
692 
693  for (int i = 0; i < count; ++i)
694  {
695  QMetaProperty metaproperty = metaobject->property(i);
696 
697  if (metaproperty.isWritable())
698  {
699  QLatin1String sName(metaproperty.name());
700 
701  if (map.contains(sName))
702  {
703  object.setProperty(sName.data(), map.value(sName));
704  }
705  }
706  }
707  }
708 
757  template<typename T>
758  void fetchGadget(T &gadget) const
759  {
760  const QMetaObject &metaobject = gadget.staticMetaObject;
761 
762  const int count = metaobject.propertyCount();
763 
764  const QVariantMap map = toMap();
765 
766  for (int i = 0; i < count; ++i)
767  {
768  QMetaProperty metaproperty = metaobject.property(i);
769 
770  if (metaproperty.isWritable())
771  {
772  QLatin1String sName(metaproperty.name());
773 
774  if (map.contains(sName))
775  {
776  metaproperty.writeOnGadget(&gadget, map.value(sName));
777  }
778  }
779  }
780  }
781 
787  void fetchMap(QVariantMap &map) const
788  {
789  map.clear();
790 
791  for (int i = 0; i < m_fieldNames.count(); ++i)
792  {
793  map.insert(m_fieldNames.at(i), m_query.value(i));
794  }
795  }
796 
802  void fetchList(QVariantList &list) const
803  {
804  list.clear();
805 
806  for (int i = 0; i < m_fieldNames.count(); ++i)
807  {
808  list.append(m_query.value(i));
809  }
810  }
811 
817  void fetchVector(QVector<QVariant> &vector) const
818  {
819  vector.clear();
820  vector.reserve(m_fieldNames.count());
821 
822  for (int i = 0; i < m_fieldNames.count(); ++i)
823  {
824  vector.append(m_query.value(i));
825  }
826  }
827 
833  void fetchStringList(QStringList &list) const
834  {
835  list.clear();
836 
837  for (int i = 0; i < m_fieldNames.count(); ++i)
838  {
839  list.append(m_query.value(i).toString());
840  }
841  }
842 
843 private:
844 
845  QueryResult()
846  { }
847 
848  explicit QueryResult(const QSqlQuery &query)
849  : m_query(query)
850  { }
851 
852  QueryResult(const QSqlQuery &query, const QMap<QString, int> &bindValueAliasMap)
853  : m_query(query)
854  , m_bindValueAlias(bindValueAliasMap)
855  { }
856 
857 private:
858  QSqlQuery m_query;
859  QStringList m_fieldNames;
860  QMap<QString, int> m_bindValueAlias;
861  mutable int m_fetchIndex = 0;
862  bool m_firstRowFetched = false;
863 };
864 
865 #endif // EASYQTSQL_QUERYRESULT_H
bool previous()
Retrieves the previous record in the result, if available, and positions the query on the retrieved r...
Definition: EasyQtSql_QueryResult.h:86
void fetchVars(double &value) const
Assigns a variable the value from the current record.
Definition: EasyQtSql_QueryResult.h:485
QSqlError lastError() const
Returns error information about the last error (if any) that occurred with this query.
Definition: EasyQtSql_QueryResult.h:201
QVector< QVariant > toVector() const
Returns QVector<QVariant> filled with values fetched from current result row. SQL values not converte...
Definition: EasyQtSql_QueryResult.h:334
void fetchVector(QVector< QVariant > &vector) const
Fills QVector<QVariant> with values fetched from current result row. SQL values not converted: QSqlQu...
Definition: EasyQtSql_QueryResult.h:817
Class for query preparation and execution.
Definition: EasyQtSql_PreparedQuery.h:63
QVariant scalar() const
Returns scalar value (the value of the first column of the current row)
Definition: EasyQtSql_QueryResult.h:432
void fetchVars(QVariant &value) const
Assigns a variable the value from the current record.
Definition: EasyQtSql_QueryResult.h:569
bool isValid() const
Returns true if the query is currently positioned on a valid record; otherwise returns false...
Definition: EasyQtSql_QueryResult.h:161
T scalar() const
Returns scalar value converted to type T (the value of the first column of the current row) ...
Definition: EasyQtSql_QueryResult.h:424
QVector< int > parseToIntVector(int base=10, bool skipNullValues=false) const
Returns vector of (optionally parsed) integer values from currently active result row...
Definition: EasyQtSql_QueryResult.h:381
QVariant boundValue(const QString &aliasName) const
Returns the value for the placeholder with aliasName.
Definition: EasyQtSql_QueryResult.h:265
QSqlQuery & unwrappedQuery()
Returns reference on wrapped QSqlQuery.
Definition: EasyQtSql_QueryResult.h:50
void fetchVars(QByteArray &value) const
Assigns a variable the value from the current record.
Definition: EasyQtSql_QueryResult.h:557
void fetchVars(QDateTime &value) const
Assigns a variable the value from the current record.
Definition: EasyQtSql_QueryResult.h:533
void fetchGadget(T &gadget) const
Fills Q_GADGET object properties with data fetched from current result row.
Definition: EasyQtSql_QueryResult.h:758
QVariant value(const QString &colName) const
Returns the value of the field called name in the current record. If field name does not exist an inv...
Definition: EasyQtSql_QueryResult.h:241
void fetchVars(bool &value, Rest &... rest) const
Definition: EasyQtSql_QueryResult.h:597
void fetchVars(QByteArray &value, Rest &... rest) const
Definition: EasyQtSql_QueryResult.h:625
void fetchVars(int &value) const
Assigns a variable the value from the current record.
Definition: EasyQtSql_QueryResult.h:473
QVariant boundValue(int column) const
Returns the value for the placeholder at position column.
Definition: EasyQtSql_QueryResult.h:251
void fetchVars(QDate &value, Rest &... rest) const
Definition: EasyQtSql_QueryResult.h:604
bool isForwardOnly() const
Returns true if you can only scroll forward through a result set; otherwise returns false...
Definition: EasyQtSql_QueryResult.h:171
void fetchVars(QString &value, Rest &... rest) const
Definition: EasyQtSql_QueryResult.h:590
int at() const
Returns the current internal position of the query. The first record is at position zero...
Definition: EasyQtSql_QueryResult.h:141
int size() const
Returns the size of the result (number of rows returned), or -1 if the size cannot be determined or i...
Definition: EasyQtSql_QueryResult.h:181
void fetchMap(QVariantMap &map) const
Fills QVariantMap with values fetched from current result row. Key is QString (result column name) an...
Definition: EasyQtSql_QueryResult.h:787
QVariantList toList() const
Returns QVariantList filled with values fetched from current result row.
Definition: EasyQtSql_QueryResult.h:308
void fetchVars(QDateTime &value, Rest &... rest) const
Definition: EasyQtSql_QueryResult.h:611
QVector< T > toVector(bool skipNullValues=false) const
Returns QVector<T> filled with values fetched from current result row. SQL values converted with QVar...
Definition: EasyQtSql_QueryResult.h:350
void fetchVars(QTime &value) const
Assigns a variable the value from the current record.
Definition: EasyQtSql_QueryResult.h:545
bool last()
Retrieves the last record in the result, if available, and positions the query on the retrieved recor...
Definition: EasyQtSql_QueryResult.h:120
QVariantList boundValues() const
Returns list of the bound values (with positional binding)
Definition: EasyQtSql_QueryResult.h:284
QSqlDatabase wrapper.
Definition: EasyQtSql_Transaction.h:67
bool isActive() const
Returns true if the query is active. An active QSqlQuery is one that has been exec()&#39;d successfully b...
Definition: EasyQtSql_QueryResult.h:151
void fetchVars(QDate &value) const
Assigns a variable the value from the current record.
Definition: EasyQtSql_QueryResult.h:521
void fetchVars(QVariant &value, Rest &... rest) const
Definition: EasyQtSql_QueryResult.h:632
int numRowsAffected() const
Returns the number of rows affected by the result&#39;s SQL statement, or -1 if it cannot be determined...
Definition: EasyQtSql_QueryResult.h:191
QVariant value(int column) const
Returns the value of field index in the current record.
Definition: EasyQtSql_QueryResult.h:231
void fetchVars(double &value, Rest &... rest) const
Definition: EasyQtSql_QueryResult.h:583
QVariantMap toMap() const
Returns QVariantMap filled with values fetched from current result row. Key is QString (result column...
Definition: EasyQtSql_QueryResult.h:295
void fetchVars(bool &value) const
Assigns a variable the value from the current record.
Definition: EasyQtSql_QueryResult.h:509
bool nextResult()
Discards the current result set and navigates to the next if available (if database is capable of ret...
Definition: EasyQtSql_QueryResult.h:96
bool seek(int index, bool relative=false)
Retrieves the record at position index, if available, and positions the query on the retrieved record...
Definition: EasyQtSql_QueryResult.h:130
void fetchObject(QObject &object) const
Fills Q_OBJECT object properties with data fetched from current result row.
Definition: EasyQtSql_QueryResult.h:686
QSqlQuery wrapper with handy data fetch methods.
Definition: EasyQtSql_QueryResult.h:39
QSqlDatabase transaction wrapper.
Definition: EasyQtSql_Transaction.h:398
void fetchStringList(QStringList &list) const
Fills QStringList with values fetched from current result row. SQL values converted to QString with Q...
Definition: EasyQtSql_QueryResult.h:833
bool next()
Retrieves the next record in the result, if available, and positions the query on the retrieved recor...
Definition: EasyQtSql_QueryResult.h:60
void fetchVars(QString &value) const
Assigns a variable the value from the current record.
Definition: EasyQtSql_QueryResult.h:497
QStringList toStringList() const
Returns QStringList filled with values fetched from current result row. SQL values converted to QStri...
Definition: EasyQtSql_QueryResult.h:321
bool first()
Retrieves the first record in the result, if available, and positions the query on the retrieved reco...
Definition: EasyQtSql_QueryResult.h:110
void fetchVars(QTime &value, Rest &... rest) const
Definition: EasyQtSql_QueryResult.h:618
QString lastQuery() const
Returns the text of the current query being used, or an empty string if there is no current query tex...
Definition: EasyQtSql_QueryResult.h:211
void fetchList(QVariantList &list) const
Fills QVariantList with values fetched from current result row. SQL values not converted: QSqlQuery::...
Definition: EasyQtSql_QueryResult.h:802
QString executedQuery() const
Returns the last query that was successfully executed.
Definition: EasyQtSql_QueryResult.h:221
void fetchVars(int &value, Rest &... rest) const
Definition: EasyQtSql_QueryResult.h:576