EasyQtSql_QueryResult.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865
  1. #ifndef EASYQTSQL_QUERYRESULT_H
  2. #define EASYQTSQL_QUERYRESULT_H
  3. /*
  4. * The MIT License (MIT)
  5. * Copyright 2018 Alexey Kramin
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining
  8. * a copy of this software and associated documentation files (the
  9. * "Software"), to deal in the Software without restriction, including
  10. * without limitation the rights to use, copy, modify, merge, publish,
  11. * distribute, sublicense, and/or sell copies of the Software, and to
  12. * permit persons to whom the Software is furnished to do so, subject to
  13. * the following conditions:
  14. *
  15. * The above copyright notice and this permission notice shall be
  16. * included in all copies or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  19. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  21. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  22. * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  23. * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  24. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25. *
  26. */
  27. #ifndef EASY_QT_SQL_MAIN
  28. #include <QtSql>
  29. #include "EasyQtSql_NonQueryResult.h"
  30. #endif
  31. /*!
  32. \brief QSqlQuery wrapper with handy data fetch methods.
  33. */
  34. class QueryResult
  35. {
  36. friend class Database;
  37. friend class Transaction;
  38. friend class PreparedQuery;
  39. public:
  40. /*!
  41. \brief Returns reference on wrapped QSqlQuery.
  42. */
  43. QSqlQuery &unwrappedQuery()
  44. {
  45. return m_query;
  46. }
  47. /*!
  48. \brief Retrieves the next record in the result, if available, and positions the query on the retrieved record.
  49. Wrapper over QSqlQuery::next()
  50. */
  51. bool next()
  52. {
  53. bool res = m_query.next();
  54. if ( ! m_firstRowFetched)
  55. {
  56. m_fieldNames.clear();
  57. QSqlRecord record = m_query.record();
  58. for (int i = 0; i < record.count(); ++i)
  59. {
  60. m_fieldNames.append(record.fieldName(i));
  61. }
  62. m_firstRowFetched = true;
  63. }
  64. return res;
  65. }
  66. /*!
  67. \brief Retrieves the previous record in the result, if available, and positions the query on the retrieved record.
  68. Wrapper over QSqlQuery::previous()
  69. */
  70. bool previous()
  71. {
  72. return m_query.previous();
  73. }
  74. /*!
  75. \brief Discards the current result set and navigates to the next if available (if database is capable of returning multiple result sets)
  76. Wrapper over QSqlQuery::nextResult()
  77. */
  78. bool nextResult()
  79. {
  80. m_firstRowFetched = false;
  81. bool res = m_query.nextResult();
  82. return res;
  83. }
  84. /*!
  85. \brief Retrieves the first record in the result, if available, and positions the query on the retrieved record.
  86. Wrapper over QSqlQuery::first()
  87. */
  88. bool first()
  89. {
  90. return m_query.first();
  91. }
  92. /*!
  93. \brief Retrieves the last record in the result, if available, and positions the query on the retrieved record.
  94. Wrapper over QSqlQuery::last()
  95. */
  96. bool last()
  97. {
  98. return m_query.last();
  99. }
  100. /*!
  101. \brief Retrieves the record at position index, if available, and positions the query on the retrieved record.
  102. Wrapper over QSqlQuery::seek()
  103. */
  104. bool seek(int index, bool relative = false)
  105. {
  106. return m_query.seek(index, relative);
  107. }
  108. /*!
  109. \brief Returns the current internal position of the query. The first record is at position zero.
  110. \return If the position is invalid, the function returns QSql::BeforeFirstRow or QSql::AfterLastRow, which are special negative values.
  111. Wrapper over QSqlQuery::at()
  112. */
  113. int at() const
  114. {
  115. return m_query.at();
  116. }
  117. /*!
  118. \brief Returns true if the query is active. An active QSqlQuery is one that has been exec()'d successfully but not yet finished with.
  119. Wrapper over QSqlQuery::isActive()
  120. */
  121. bool isActive() const
  122. {
  123. return m_query.isActive();
  124. }
  125. /*!
  126. \brief Returns true if the query is currently positioned on a valid record; otherwise returns false.
  127. Wrapper over QSqlQuery::isValid()
  128. */
  129. bool isValid() const
  130. {
  131. return m_query.isValid();
  132. }
  133. /*!
  134. \brief Returns true if you can only scroll forward through a result set; otherwise returns false.
  135. Wrapper over QSqlQuery::isForwardOnly()
  136. */
  137. bool isForwardOnly() const
  138. {
  139. return m_query.isForwardOnly();
  140. }
  141. /*!
  142. \brief Returns the size of the result (number of rows returned), or -1 if the size cannot be determined or if the database does not support reporting information about query sizes.
  143. Wrapper over QSqlQuery::size()
  144. */
  145. int size() const
  146. {
  147. return m_query.size();
  148. }
  149. /*!
  150. \brief Returns the number of rows affected by the result's SQL statement, or -1 if it cannot be determined.
  151. Wrapper over QSqlQuery::numRowsAffected()
  152. */
  153. int numRowsAffected() const
  154. {
  155. return m_query.numRowsAffected();
  156. }
  157. /*!
  158. \brief Returns error information about the last error (if any) that occurred with this query.
  159. Wrapper over QSqlQuery::lastError()
  160. */
  161. QSqlError lastError() const
  162. {
  163. return m_query.lastError();
  164. }
  165. /*!
  166. \brief Returns the text of the current query being used, or an empty string if there is no current query text.
  167. Wrapper over QSqlQuery::lastQuery()
  168. */
  169. QString lastQuery() const
  170. {
  171. return m_query.lastQuery();
  172. }
  173. /*!
  174. \brief Returns the last query that was successfully executed.
  175. Wrapper over QSqlQuery::executedQuery()
  176. */
  177. QString executedQuery() const
  178. {
  179. return m_query.executedQuery();
  180. }
  181. /*!
  182. \brief Returns the value of field index in the current record.
  183. Wrapper over QSqlQuery::value()
  184. */
  185. QVariant value(int column) const
  186. {
  187. return m_query.value(column);
  188. }
  189. /*!
  190. \brief Returns the value of the field called name in the current record. If field name does not exist an invalid variant is returned.
  191. Wrapper over QSqlQuery::value()
  192. */
  193. QVariant value(const QString &colName) const
  194. {
  195. return m_query.value(colName);
  196. }
  197. /*!
  198. \brief Returns the value for the placeholder at position column.
  199. Wrapper over QSqlQuery::boundValue()
  200. */
  201. QVariant boundValue(int column) const
  202. {
  203. return m_query.boundValue(column);
  204. }
  205. /*!
  206. \brief Returns the value for the placeholder with aliasName.
  207. Use subclasses of ParamDirectionWrapper class (::In, ::Out, ::InOut) for aliased/directional parameter binding during PreparedQuery::exec execution
  208. Use Out and InOut wrappers if you need to read Stored Procedures return values (output parameters).
  209. \sa ::In, ::Out, ::InOut, PreparedQuery::exec
  210. */
  211. QVariant boundValue(const QString &aliasName) const
  212. {
  213. const int index = m_bindValueAlias.value(aliasName.trimmed().toLower(), -1);
  214. QVariant res;
  215. if (index >= 0)
  216. {
  217. res = boundValue(index);
  218. }
  219. return res;
  220. }
  221. /*!
  222. \brief Returns list of the bound values (with positional binding)
  223. Wrapper over QSqlQuery::boundValues()
  224. */
  225. QVariantList boundValues() const
  226. {
  227. QList<QVariant> list = m_query.boundValues().values();
  228. return list;
  229. }
  230. /*!
  231. \brief Returns QVariantMap filled with values fetched from current result row. Key is QString (result column name) and value is QVariant value.
  232. \sa QueryResult::fetchMap
  233. */
  234. QVariantMap toMap() const
  235. {
  236. QVariantMap res;
  237. fetchMap(res);
  238. return res;
  239. }
  240. /*!
  241. \brief Returns QVariantList filled with values fetched from current result row.
  242. \sa QueryResult::fetchList
  243. */
  244. QVariantList toList() const
  245. {
  246. QVariantList res;
  247. fetchList(res);
  248. return res;
  249. }
  250. /*!
  251. \brief Returns QStringList filled with values fetched from current result row. SQL values converted to QString with QVariant::toString() method.
  252. \sa QueryResult::fetchStringList()
  253. */
  254. QStringList toStringList() const
  255. {
  256. QStringList res;
  257. fetchStringList(res);
  258. return res;
  259. }
  260. /*!
  261. \brief Returns QVector<QVariant> filled with values fetched from current result row. SQL values not converted: QSqlQuery::value() return value used.
  262. \sa QueryResult::fetchVector
  263. */
  264. QVector<QVariant> toVector() const
  265. {
  266. QVector<QVariant> res;
  267. fetchVector(res);
  268. return res;
  269. }
  270. /*!
  271. \brief Returns QVector<T> filled with values fetched from current result row. SQL values converted with QVariant::value<T>().
  272. QVector::canConvert<T>() method used for convertability check. Non-convertable values skipped.
  273. \param skipNullValues Skip SQL NULL values. Resulting value is default value if skipNullValues = false.
  274. \sa QueryResult::toVector
  275. */
  276. template <typename T>
  277. QVector<T> toVector(bool skipNullValues = false) const
  278. {
  279. QVector<T> res;
  280. res.reserve(m_fieldNames.count());
  281. for (int i = 0; i < m_fieldNames.count(); ++i)
  282. {
  283. const QVariant &value = m_query.value(i);
  284. if (!value.canConvert<T>())
  285. continue;
  286. if (skipNullValues && value.isNull())
  287. continue;
  288. res.append(value.value<T>());
  289. }
  290. return res;
  291. }
  292. /*!
  293. \brief Returns vector of (optionally parsed) integer values from currently active result row.
  294. Parsing with specified base will be performed if type of selected database field is String (varchar/text).
  295. Not successfully parsed string values are ignored.
  296. \param base Number base to parse int values from SQL string values.
  297. \param skipNullValues Skip SQL NULL values. Resulting int value is 0 if skipNullValues = false.
  298. */
  299. QVector<int> parseToIntVector(int base = 10, bool skipNullValues = false) const
  300. {
  301. QVector<int> res;
  302. res.reserve(m_fieldNames.count());
  303. for (int i = 0; i < m_fieldNames.count(); ++i)
  304. {
  305. const QVariant &value = m_query.value(i);
  306. if (!value.canConvert<int>())
  307. continue;
  308. if (skipNullValues && value.isNull())
  309. continue;
  310. bool ok = false;
  311. int iValue = 0;
  312. if ( ((value.type() == QVariant::String) || (value.type() == QVariant::ByteArray)))
  313. {
  314. const QString str = value.toString();
  315. iValue = str.toInt(&ok, base);
  316. }
  317. else
  318. {
  319. iValue = value.toInt(&ok);
  320. }
  321. if (ok)
  322. {
  323. res.append(iValue);
  324. }
  325. }
  326. return res;
  327. }
  328. /*!
  329. \brief Returns scalar value converted to type T (the value of the first column of the current row)
  330. */
  331. template <typename T>
  332. T scalar() const
  333. {
  334. return m_query.value(0).value<T>();
  335. }
  336. /*!
  337. \brief Returns scalar value (the value of the first column of the current row)
  338. */
  339. QVariant scalar() const
  340. {
  341. return m_query.value(0);
  342. }
  343. /*!
  344. \brief Assigns a variable the value from the current record
  345. The method has a variable number of parameters, which allows filling the list of variables with values from the current record in single call.
  346. Overloaded <em>EasyQtSql::fetchVars</em> methods performs the corresponding type conversion with QVariant::to*() methods.
  347. Supported parameter types: <em>int</em>, <em>double</em>, <em>bool</em>, <em>QString</em>, <em>QDate</em>, <em>QDateTime</em>, <em>QTime</em>, <em>QByteArray</em>, <em>QVariant</em>.
  348. Variables of different types can be mixed.
  349. \code
  350. Transaction t;
  351. QueryResult res = t.execQuery("SELECT a, b, c, d FROM table");
  352. while (res.next())
  353. {
  354. int a;
  355. bool b;
  356. QString c;
  357. QDateTime d;
  358. res.fetchVars(a, b, c, d);
  359. }
  360. \endcode
  361. \sa QueryResult::fetchVars(int&) const
  362. , QueryResult::fetchVars(double&) const
  363. , QueryResult::fetchVars(QString&) const
  364. , QueryResult::fetchVars(bool&) const
  365. , QueryResult::fetchVars(QDate&) const
  366. , QueryResult::fetchVars(QDateTime&) const
  367. , QueryResult::fetchVars(QTime&) const
  368. , QueryResult::fetchVars(QByteArray&) const
  369. , QueryResult::fetchVars(QVariant&) const
  370. */
  371. void fetchVars(int &value) const
  372. {
  373. value = m_query.value(m_fetchIndex).toInt();
  374. m_fetchIndex = 0;
  375. }
  376. /*!
  377. \brief Assigns a variable the value from the current record
  378. \sa QueryResult::fetchVars(int&) const
  379. */
  380. void fetchVars(double &value) const
  381. {
  382. value = m_query.value(m_fetchIndex).toInt();
  383. m_fetchIndex = 0;
  384. }
  385. /*!
  386. \brief Assigns a variable the value from the current record
  387. \sa QueryResult::fetchVars(int&) const
  388. */
  389. void fetchVars(QString &value) const
  390. {
  391. value = m_query.value(m_fetchIndex).toString();
  392. m_fetchIndex = 0;
  393. }
  394. /*!
  395. \brief Assigns a variable the value from the current record
  396. \sa QueryResult::fetchVars(int&) const
  397. */
  398. void fetchVars(bool &value) const
  399. {
  400. value = m_query.value(m_fetchIndex).toBool();
  401. m_fetchIndex = 0;
  402. }
  403. /*!
  404. \brief Assigns a variable the value from the current record
  405. \sa QueryResult::fetchVars(int&) const
  406. */
  407. void fetchVars(QDate &value) const
  408. {
  409. value = m_query.value(m_fetchIndex).toDate();
  410. m_fetchIndex = 0;
  411. }
  412. /*!
  413. \brief Assigns a variable the value from the current record
  414. \sa QueryResult::fetchVars(int&) const
  415. */
  416. void fetchVars(QDateTime &value) const
  417. {
  418. value = m_query.value(m_fetchIndex).toDateTime();
  419. m_fetchIndex = 0;
  420. }
  421. /*!
  422. \brief Assigns a variable the value from the current record
  423. \sa QueryResult::fetchVars(int&) const
  424. */
  425. void fetchVars(QTime &value) const
  426. {
  427. value = m_query.value(m_fetchIndex).toTime();
  428. m_fetchIndex = 0;
  429. }
  430. /*!
  431. \brief Assigns a variable the value from the current record
  432. \sa QueryResult::fetchVars(int&) const
  433. */
  434. void fetchVars(QByteArray &value) const
  435. {
  436. value = m_query.value(m_fetchIndex).toByteArray();
  437. m_fetchIndex = 0;
  438. }
  439. /*!
  440. \brief Assigns a variable the value from the current record
  441. \sa QueryResult::fetchVars(int&) const
  442. */
  443. void fetchVars(QVariant &value) const
  444. {
  445. value = m_query.value(m_fetchIndex);
  446. m_fetchIndex = 0;
  447. }
  448. template <typename... Rest> void fetchVars(int &value, Rest&... rest) const
  449. {
  450. value = m_query.value(m_fetchIndex++).toInt();
  451. fetchVars(rest...);
  452. }
  453. template <typename... Rest> void fetchVars(double &value, Rest&... rest) const
  454. {
  455. value = m_query.value(m_fetchIndex++).toDouble();
  456. fetchVars(rest...);
  457. }
  458. template <typename... Rest> void fetchVars(QString &value, Rest&... rest) const
  459. {
  460. value = m_query.value(m_fetchIndex++).toString();
  461. fetchVars(rest...);
  462. }
  463. template <typename... Rest> void fetchVars(bool &value, Rest&... rest) const
  464. {
  465. value = m_query.value(m_fetchIndex++).toBool();
  466. fetchVars(rest...);
  467. }
  468. template <typename... Rest> void fetchVars(QDate &value, Rest&... rest) const
  469. {
  470. value = m_query.value(m_fetchIndex++).toDate();
  471. fetchVars(rest...);
  472. }
  473. template <typename... Rest> void fetchVars(QDateTime &value, Rest&... rest) const
  474. {
  475. value = m_query.value(m_fetchIndex++).toDateTime();
  476. fetchVars(rest...);
  477. }
  478. template <typename... Rest> void fetchVars(QTime &value, Rest&... rest) const
  479. {
  480. value = m_query.value(m_fetchIndex++).toTime();
  481. fetchVars(rest...);
  482. }
  483. template <typename... Rest> void fetchVars(QByteArray &value, Rest&... rest) const
  484. {
  485. value = m_query.value(m_fetchIndex++).toByteArray();
  486. fetchVars(rest...);
  487. }
  488. template <typename... Rest> void fetchVars(QVariant &value, Rest&... rest) const
  489. {
  490. value = m_query.value(m_fetchIndex++);
  491. fetchVars(rest...);
  492. }
  493. /*!
  494. \brief Fills Q_OBJECT object properties with data fetched from current result row.
  495. Qt Meta-Object System used. Only writable properties can be filled.
  496. C++ class fields (properties) will be mapped on SQL result table by Q_PROPERTY member names. For example, if Q_OBJECT class contains Q_PROPERTY named "e" but SELECT query defines no "e" column, object property "e" not affected by the method.
  497. \code
  498. class TestObject : public QObject
  499. {
  500. Q_OBJECT
  501. //property "a" will be filled with "a" column of the Select SQL query result
  502. Q_PROPERTY(int a MEMBER a)
  503. Q_PROPERTY(int b MEMBER b)
  504. Q_PROPERTY(int c MEMBER c)
  505. Q_PROPERTY(QString d MEMBER d)
  506. //property e will be ignored in the example because there is no e field in the Select SQL query result
  507. Q_PROPERTY(int e MEMBER e)
  508. private:
  509. int a;
  510. int b;
  511. int c;
  512. QString d;
  513. int e;
  514. };
  515. void test()
  516. {
  517. Transaction t;
  518. QueryResult res = t.execQuery("SELECT a, b, c, d FROM table");
  519. while (res.next())
  520. {
  521. //TestObject instance (Q_OBJECT class)
  522. TestObject testRow;
  523. res.fetchObject(testRow);
  524. }
  525. }
  526. \endcode
  527. \param object Q_OBJECT object reference
  528. */
  529. void fetchObject(QObject &object) const
  530. {
  531. const QMetaObject *metaobject = object.metaObject();
  532. const int count = metaobject->propertyCount();
  533. const QVariantMap map = toMap();
  534. for (int i = 0; i < count; ++i)
  535. {
  536. QMetaProperty metaproperty = metaobject->property(i);
  537. if (metaproperty.isWritable())
  538. {
  539. QLatin1String sName(metaproperty.name());
  540. if (map.contains(sName))
  541. {
  542. object.setProperty(sName.data(), map.value(sName));
  543. }
  544. }
  545. }
  546. }
  547. /*!
  548. \brief Fills Q_GADGET object properties with data fetched from current result row.
  549. Qt Meta-Object System used. Only writable properties can be filled.
  550. C++ struct fields will be mapped on SQL result table by Q_PROPERTY member names. For example, if Q_GADGET struct contains Q_PROPERTY named "e" but SELECT query defines no "e" column, object property "e" not affected by the method.
  551. \code
  552. struct Row
  553. {
  554. int a;
  555. int b;
  556. int c;
  557. QString d;
  558. int e;
  559. private:
  560. Q_GADGET
  561. //property "a" will be filled with "a" column of the Select SQL query result
  562. Q_PROPERTY(int a MEMBER a)
  563. Q_PROPERTY(int b MEMBER b)
  564. Q_PROPERTY(int c MEMBER c)
  565. Q_PROPERTY(QString d MEMBER d)
  566. //property e will be ignored in the example because there is no e field in the Select SQL query result
  567. Q_PROPERTY(int e MEMBER e)
  568. };
  569. void test()
  570. {
  571. Transaction t;
  572. QueryResult res = t.execQuery("SELECT a, b, c, d FROM table");
  573. while (res.next())
  574. {
  575. //Row instance (Q_GADGET structure)
  576. Row testRow;
  577. //fetch testRow from current result row, properties a, b, c, d will be filled here:
  578. res.fetchGadget(testRow);
  579. }
  580. }
  581. \endcode
  582. \param gadget Q_GADGET reference
  583. */
  584. template<typename T>
  585. void fetchGadget(T &gadget) const
  586. {
  587. const QMetaObject &metaobject = gadget.staticMetaObject;
  588. const int count = metaobject.propertyCount();
  589. const QVariantMap map = toMap();
  590. for (int i = 0; i < count; ++i)
  591. {
  592. QMetaProperty metaproperty = metaobject.property(i);
  593. if (metaproperty.isWritable())
  594. {
  595. QLatin1String sName(metaproperty.name());
  596. if (map.contains(sName))
  597. {
  598. metaproperty.writeOnGadget(&gadget, map.value(sName));
  599. }
  600. }
  601. }
  602. }
  603. /*!
  604. \brief Fills QVariantMap with values fetched from current result row. Key is QString (result column name) and value is QVariant value.
  605. \param[out] map QVariantMap
  606. \sa QueryResult::toMap
  607. */
  608. void fetchMap(QVariantMap &map) const
  609. {
  610. map.clear();
  611. for (int i = 0; i < m_fieldNames.count(); ++i)
  612. {
  613. map.insert(m_fieldNames.at(i), m_query.value(i));
  614. }
  615. }
  616. /*!
  617. \brief Fills QVariantList with values fetched from current result row. SQL values not converted: QSqlQuery::value() return value used.
  618. \param[out] list QVariantList
  619. \sa QueryResult::toList
  620. */
  621. void fetchList(QVariantList &list) const
  622. {
  623. list.clear();
  624. for (int i = 0; i < m_fieldNames.count(); ++i)
  625. {
  626. list.append(m_query.value(i));
  627. }
  628. }
  629. /*!
  630. \brief Fills QVector<QVariant> with values fetched from current result row. SQL values not converted: QSqlQuery::value() return value used.
  631. \param[out] vector QVector<QVariant>
  632. \sa QueryResult::toVector
  633. */
  634. void fetchVector(QVector<QVariant> &vector) const
  635. {
  636. vector.clear();
  637. vector.reserve(m_fieldNames.count());
  638. for (int i = 0; i < m_fieldNames.count(); ++i)
  639. {
  640. vector.append(m_query.value(i));
  641. }
  642. }
  643. /*!
  644. \brief Fills QStringList with values fetched from current result row. SQL values converted to QString with QVariant::toString() method.
  645. \param[out] list QStringList
  646. \sa QueryResult::toStringList
  647. */
  648. void fetchStringList(QStringList &list) const
  649. {
  650. list.clear();
  651. for (int i = 0; i < m_fieldNames.count(); ++i)
  652. {
  653. list.append(m_query.value(i).toString());
  654. }
  655. }
  656. private:
  657. QueryResult()
  658. { }
  659. explicit QueryResult(const QSqlQuery &query)
  660. : m_query(query)
  661. { }
  662. QueryResult(const QSqlQuery &query, const QMap<QString, int> &bindValueAliasMap)
  663. : m_query(query)
  664. , m_bindValueAlias(bindValueAliasMap)
  665. { }
  666. private:
  667. QSqlQuery m_query;
  668. QStringList m_fieldNames;
  669. QMap<QString, int> m_bindValueAlias;
  670. mutable int m_fetchIndex = 0;
  671. bool m_firstRowFetched = false;
  672. };
  673. #endif // EASYQTSQL_QUERYRESULT_H