TreeFrogFramework  1.18
tsqlormapper.h
Go to the documentation of this file.
1 #ifndef TSQLORMAPPER_H
2 #define TSQLORMAPPER_H
3 
4 #include <QtSql>
5 #include <QList>
6 #include <QMap>
7 #include <TGlobal>
8 #include <TSqlObject>
9 #include <TCriteria>
10 #include <TCriteriaConverter>
11 #include <TSqlQuery>
12 #include <TSqlJoin>
13 #include "tsystemglobal.h"
14 
25 template <class T>
26 class TSqlORMapper : public QSqlTableModel
27 {
28 public:
29  TSqlORMapper();
30  virtual ~TSqlORMapper();
31 
32  // Method chaining
36  TSqlORMapper<T> &orderBy(const QString &column, Tf::SortOrder order = Tf::AscendingOrder);
37  template <class C> TSqlORMapper<T> &join(int column, const TSqlJoin<C> &join);
38 
39  void setLimit(int limit);
40  void setOffset(int offset);
41  void setSortOrder(int column, Tf::SortOrder order = Tf::AscendingOrder);
42  void setSortOrder(const QString &column, Tf::SortOrder order = Tf::AscendingOrder);
43  template <class C> void setJoin(int column, const TSqlJoin<C> &join);
44  void reset();
45 
46  T findFirst(const TCriteria &cri = TCriteria());
47  T findFirstBy(int column, QVariant value);
48  T findByPrimaryKey(QVariant pk);
49  int find(const TCriteria &cri = TCriteria());
50  int findBy(int column, QVariant value);
51  int findIn(int column, const QVariantList &values);
52  int rowCount() const;
53  T first() const;
54  T last() const;
55  T value(int i) const;
56 
57  int findCount(const TCriteria &cri = TCriteria());
58  int findCountBy(int column, QVariant value);
59  int updateAll(const TCriteria &cri, int column, QVariant value);
60  int updateAll(const TCriteria &cri, const QMap<int, QVariant> &values);
61  int removeAll(const TCriteria &cri = TCriteria());
62 
63  class ConstIterator;
64  inline ConstIterator begin() const { return ConstIterator(this, 0); }
65  inline ConstIterator end() const { return ConstIterator(this, rowCount()); }
66 
70  class ConstIterator {
71  public:
72  const TSqlORMapper<T> *m {nullptr};
73  int it {0};
74 
75  inline ConstIterator() {}
76  inline ConstIterator(const ConstIterator &o) : m(o.m), it(o.it) {}
77  inline ConstIterator &operator=(const ConstIterator &o) { m = o.m; it = o.it; return *this; }
78  inline const T operator*() const { return m->value(it); }
79  inline bool operator==(const ConstIterator &o) const { return m == o.m && it == o.it; }
80  inline bool operator!=(const ConstIterator &o) const { return m != o.m || it != o.it; }
81  inline ConstIterator &operator++() { it = qMin(it + 1, m->rowCount()); return *this; }
82  inline ConstIterator operator++(int) { int i = it; it = qMin(it + 1, m->rowCount()); return ConstIterator(m, i); }
83  inline ConstIterator &operator--() { --it; return *this; }
84  inline ConstIterator operator--(int) { int i = it++; return ConstIterator(m, i); }
85 
86  private:
87  inline ConstIterator(const TSqlORMapper<T> *mapper, int i) : m(mapper), it(i) {}
88  friend class TSqlORMapper;
89  };
90 
91 protected:
92  void setFilter(const QString &filter);
93  QString orderBy() const;
94  virtual QString orderByClause() const { return QString(); }
95  virtual void clear();
96  virtual QString selectStatement() const;
97  virtual int rowCount(const QModelIndex &parent) const;
98 
99 private:
100  QString queryFilter;
101  QList<QPair<QString, Tf::SortOrder>> sortColumns;
102  int queryLimit {0};
103  int queryOffset {0};
104  int joinCount {0};
105  QStringList joinClauses;
106  QStringList joinWhereClauses;
107 
110 };
111 
115 template <class T>
117  : QSqlTableModel(0, Tf::currentSqlDatabase(T().databaseId()))
118 {
119  setTable(T().tableName());
120 }
121 
125 template <class T>
127 { }
128 
133 template <class T>
135 {
136  if (!cri.isEmpty()) {
137  TCriteriaConverter<T> conv(cri, database(), "t0");
138  setFilter(conv.toString());
139  } else {
140  setFilter(QString());
141  }
142 
143  int oldLimit = queryLimit;
144  queryLimit = 1;
145  bool ret = select();
146  Tf::writeQueryLog(query().lastQuery(), ret, lastError());
147  queryLimit = oldLimit;
148 
149  tSystemDebug("rowCount: %d", rowCount());
150  return first();
151 }
152 
157 template <class T>
158 inline T TSqlORMapper<T>::findFirstBy(int column, QVariant value)
159 {
160  return findFirst(TCriteria(column, value));
161 }
162 
167 template <class T>
169 {
170  int idx = T().primaryKeyIndex();
171  if (idx < 0) {
172  tSystemDebug("Primary key not found, table name: %s", qPrintable(T().tableName()));
173  return T();
174  }
175 
176  return findFirst(TCriteria(idx, pk));
177 }
178 
185 template <class T>
186 inline int TSqlORMapper<T>::find(const TCriteria &cri)
187 {
188  if (!cri.isEmpty()) {
189  TCriteriaConverter<T> conv(cri, database(), "t0");
190  setFilter(conv.toString());
191  } else {
192  setFilter(QString());
193  }
194 
195  bool ret = select();
196  while (canFetchMore()) { // For SQLite, not report back the size of a query
197  fetchMore();
198  }
199  Tf::writeQueryLog(query().lastQuery(), ret, lastError());
200  tSystemDebug("rowCount: %d", rowCount());
201  return ret ? rowCount() : -1;
202 }
203 
210 template <class T>
211 inline int TSqlORMapper<T>::findBy(int column, QVariant value)
212 {
213  return find(TCriteria(column, value));
214 }
215 
222 template <class T>
223 inline int TSqlORMapper<T>::findIn(int column, const QVariantList &values)
224 {
225  return find(TCriteria(column, TSql::In, values));
226 }
227 
231 template <class T>
232 inline int TSqlORMapper<T>::rowCount() const
233 {
234  return QSqlTableModel::rowCount();
235 }
236 
240 template <class T>
241 inline int TSqlORMapper<T>::rowCount(const QModelIndex &parent) const
242 {
243  return QSqlTableModel::rowCount(parent);
244 }
245 
250 template <class T>
251 inline T TSqlORMapper<T>::first() const
252 {
253  return value(0);
254 }
255 
260 template <class T>
261 inline T TSqlORMapper<T>::last() const
262 {
263  return value(rowCount() - 1);
264 }
265 
271 template <class T>
272 inline T TSqlORMapper<T>::value(int i) const
273 {
274  T rec;
275  if (i >= 0 && i < rowCount()) {
276  rec.setRecord(record(i), QSqlError());
277  } else {
278  tSystemDebug("no such record, index: %d rowCount:%d", i, rowCount());
279  }
280  return rec;
281 }
282 
287 template <class T>
289 {
290  queryLimit = limit;
291 }
292 
297 template <class T>
299 {
300  queryOffset = offset;
301 }
302 
306 template <class T>
307 inline void TSqlORMapper<T>::setSortOrder(int column, Tf::SortOrder order)
308 {
309  if (column >= 0) {
310  QString columnName = TCriteriaConverter<T>::getPropertyName(column, database().driver());
311  sortColumns << qMakePair(columnName, order);
312  }
313 }
314 
318 template <class T>
319 inline void TSqlORMapper<T>::setSortOrder(const QString &column, Tf::SortOrder order)
320 {
321  if (!column.isEmpty()) {
322  T obj;
323  if (obj.propertyNames().contains(column, Qt::CaseInsensitive)) {
324  sortColumns << qMakePair(column, order);
325  } else {
326  tWarn("Unable to set sort order : '%s' column not found in '%s' table",
327  qPrintable(column), qPrintable(obj.tableName()));
328  }
329  }
330 }
331 
336 template <class T>
338 {
339  setLimit(l);
340  return *this;
341 }
342 
347 template <class T>
349 {
350  setOffset(o);
351  return *this;
352 }
353 
357 template <class T>
359 {
360  setSortOrder(column, order);
361  return *this;
362 }
363 
367 template <class T>
368 inline TSqlORMapper<T> &TSqlORMapper<T>::orderBy(const QString &column, Tf::SortOrder order)
369 {
370  setSortOrder(column, order);
371  return *this;
372 }
373 
380 template <class T>
381 inline void TSqlORMapper<T>::setFilter(const QString &filter)
382 {
383  queryFilter = filter;
384 }
385 
390 template <class T>
391 inline QString TSqlORMapper<T>::selectStatement() const
392 {
393  QString query;
394  query.reserve(256);
395  bool joinFlag = !joinClauses.isEmpty();
396 
397  auto rec = record();
398  for (int i = 0; i < rec.count(); ++i) {
399  if (rec.isGenerated(i)) {
400  if (joinFlag) {
401  query += QLatin1String("t0.");
402  }
403  query += TSqlQuery::escapeIdentifier(rec.fieldName(i), QSqlDriver::FieldName, database().driver());
404  query += QLatin1Char(',');
405  }
406  }
407 
408  if (Q_UNLIKELY(query.isEmpty())) {
409  return query;
410  } else {
411  query.chop(1);
412  }
413 
414  if (joinFlag) {
415  query.prepend(QLatin1String("SELECT DISTINCT "));
416  } else {
417  query.prepend(QLatin1String("SELECT "));
418  }
419  query += QLatin1String(" FROM ");
420  query += TSqlQuery::escapeIdentifier(tableName(), QSqlDriver::TableName, database().driver());
421  query += QLatin1String(" t0"); // alias needed
422 
423  if (joinFlag) {
424  for (auto &join : (const QStringList&)joinClauses) {
425  query += join;
426  }
427  }
428 
429  QString filter = queryFilter;
430  if (!joinWhereClauses.isEmpty()) {
431  for (auto &wh : (const QStringList&)joinWhereClauses) {
432  if (!filter.isEmpty()) {
433  filter += QLatin1String(" AND ");
434  }
435  filter += wh;
436  }
437  }
438 
439  if (Q_LIKELY(!filter.isEmpty())) {
440  query.append(QLatin1String(" WHERE ")).append(filter);
441  }
442 
443  QString orderby = orderBy();
444  if (!orderby.isEmpty()) {
445  query.append(orderby);
446  }
447 
448  if (queryLimit > 0) {
449  query.append(QLatin1String(" LIMIT ")).append(QString::number(queryLimit));
450  }
451  if (queryOffset > 0) {
452  query.append(QLatin1String(" OFFSET ")).append(QString::number(queryOffset));
453  }
454 
455  return query;
456 }
457 
462 template <class T>
463 inline int TSqlORMapper<T>::findCount(const TCriteria &cri)
464 {
465  if (!cri.isEmpty()) {
466  TCriteriaConverter<T> conv(cri, database(), "t0");
467  setFilter(conv.toString());
468  } else {
469  setFilter(QString());
470  }
471 
472  QString query;
473  query += QLatin1String("SELECT COUNT(*) FROM (");
474  query += selectStatement();
475  query += QLatin1String(") t");
476 
477  int cnt = -1;
478  TSqlQuery q(database());
479  bool res = q.exec(query);
480  if (res) {
481  q.next();
482  cnt = q.value(0).toInt();
483  }
484  return cnt;
485 }
486 
491 template <class T>
492 inline int TSqlORMapper<T>::findCountBy(int column, QVariant value)
493 {
494  return findCount(TCriteria(column, value));
495 }
496 
502 template <class T>
503 int TSqlORMapper<T>::updateAll(const TCriteria &cri, const QMap<int, QVariant> &values)
504 {
505  const QByteArray UpdatedAt("updated_at");
506  const QByteArray ModifiedAt("modified_at");
507 
508  QString upd; // UPDATE Statement
509  upd.reserve(256);
510  upd.append(QLatin1String("UPDATE ")).append(tableName()).append(QLatin1String(" SET "));
511 
512  QSqlDatabase db = database();
513  TCriteriaConverter<T> conv(cri, db);
514  QString where = conv.toString();
515 
516  if (values.isEmpty()) {
517  tSystemError("Update Parameter Error");
518  return -1;
519  }
520 
521  T obj;
522  for (int i = obj.metaObject()->propertyOffset(); i < obj.metaObject()->propertyCount(); ++i) {
523  const char *propName = obj.metaObject()->property(i).name();
524  QByteArray prop = QByteArray(propName).toLower();
525  if (prop == UpdatedAt || prop == ModifiedAt) {
526  upd += propName;
527  upd += '=';
528  upd += TSqlQuery::formatValue(QDateTime::currentDateTime(), QVariant::DateTime, db);
529  upd += QLatin1Char(',');
530  break;
531  }
532  }
533 
534  QMapIterator<int, QVariant> it(values);
535  for (;;) {
536  it.next();
537  upd += conv.propertyName(it.key(), db.driver());
538  upd += '=';
539  upd += TSqlQuery::formatValue(it.value(), conv.variantType(it.key()), db);
540 
541  if (!it.hasNext())
542  break;
543 
544  upd += QLatin1Char(',');
545  }
546 
547  if (!where.isEmpty()) {
548  upd.append(QLatin1String(" WHERE ")).append(where);
549  }
550 
551  TSqlQuery sqlQuery(db);
552  bool res = sqlQuery.exec(upd);
553  return res ? sqlQuery.numRowsAffected() : -1;
554 }
555 
560 template <class T>
561 inline int TSqlORMapper<T>::updateAll(const TCriteria &cri, int column, QVariant value)
562 {
563  QMap<int, QVariant> map;
564  map.insert(column, value);
565  return updateAll(cri, map);
566 }
567 
572 template <class T>
573 inline int TSqlORMapper<T>::removeAll(const TCriteria &cri)
574 {
575  QSqlDatabase db = database();
576  QString del = db.driver()->sqlStatement(QSqlDriver::DeleteStatement,
577  T().tableName(), QSqlRecord(), false);
578  TCriteriaConverter<T> conv(cri, db);
579  QString where = conv.toString();
580 
581  if (del.isEmpty()) {
582  tSystemError("Statement Error");
583  return -1;
584  }
585  if (!where.isEmpty()) {
586  del.append(QLatin1String(" WHERE ")).append(where);
587  }
588 
589  TSqlQuery sqlQuery(db);
590  bool res = sqlQuery.exec(del);
591  return res ? sqlQuery.numRowsAffected() : -1;
592 }
593 
597 template <class T>
598 template <class C> inline void TSqlORMapper<T>::setJoin(int column, const TSqlJoin<C> &join)
599 {
600  if (column < 0 || join.joinColumn() < 0) {
601  return;
602  }
603 
604  QString clause;
605 
606  switch (join.joinMode()) {
607  case TSql::InnerJoin:
608  clause = QLatin1String(" INNER JOIN ");
609  break;
610 
611  case TSql::LeftJoin:
612  clause = QLatin1String(" LEFT OUTER JOIN ");
613  break;
614 
615  case TSql::RightJoin:
616  clause = QLatin1String(" RIGHT OUTER JOIN ");
617  break;
618 
619  default:
620  break;
621  }
622 
623  int joinCount = joinClauses.count();
624  QString alias = QLatin1Char('t') + QString::number(joinCount + 1);
625  QSqlDatabase db = database();
626 
627  clause += C().tableName();
628  clause += QLatin1Char(' ');
629  clause += alias;
630  clause += QLatin1String(" ON ");
631  clause += TCriteriaConverter<T>::getPropertyName(column, db.driver(), "t0");
632  clause += QLatin1Char('=');
633  clause += TCriteriaConverter<C>::getPropertyName(join.joinColumn(), db.driver(), alias);
634  joinClauses << clause;
635 
636  if (!join.criteria().isEmpty()) {
637  TCriteriaConverter<C> conv(join.criteria(), db, alias);
638  joinWhereClauses << conv.toString();
639  }
640 }
641 
642 template <class T>
643 template <class C> inline TSqlORMapper<T> &TSqlORMapper<T>::join(int column, const TSqlJoin<C> &j)
644 {
645  setJoin(column, j);
646  return *this;
647 }
648 
652 template <class T>
654 {
655  setTable(tableName());
656 }
657 
661 template <class T>
663 {
664  QSqlTableModel::clear();
665  queryFilter.clear();
666  sortColumns.clear();
667  queryLimit = 0;
668  queryOffset = 0;
669  joinCount = 0;
670  joinClauses.clear();
671  joinWhereClauses.clear();
672 
673  // Don't call the setTable() here,
674  // or it causes a segmentation fault.
675 }
676 
680 template <class T>
681 inline QString TSqlORMapper<T>::orderBy() const
682 {
683  QString str;
684 
685  if (!sortColumns.isEmpty()) {
686  str += QLatin1String(" ORDER BY ");
687  for (auto &p : sortColumns) {
688  str += QLatin1String("t0.");
689  str += TSqlQuery::escapeIdentifier(p.first, QSqlDriver::FieldName, database().driver());
690  str += (p.second == Tf::AscendingOrder) ? QLatin1String(" ASC,") : QLatin1String(" DESC,");
691  }
692  str.chop(1);
693  }
694  return str;
695 }
696 
697 #endif // TSQLORMAPPER_H
TSqlORMapper< T > & limit(int limit)
Sets the limit to limit, which is the limited number of rows for execution of SELECT statement...
Definition: tsqlormapper.h:337
T_CORE_EXPORT QSqlDatabase & currentSqlDatabase(int id)
Definition: tglobal.cpp:229
QVariant value(int index) const
Returns the value of field index in the current record.
Definition: tsqlquery.cpp:207
QString orderBy() const
Returns a SQL WHERE clause generated from a criteria.
Definition: tsqlormapper.h:681
TSqlORMapper< T > & offset(int offset)
Sets the offset to offset, which is the number of rows to skip for execution of SELECT statement...
Definition: tsqlormapper.h:348
ConstIterator & operator--()
Definition: tsqlormapper.h:83
const T operator*() const
Definition: tsqlormapper.h:78
T findFirst(const TCriteria &cri=TCriteria())
Returns the first ORM object retrieved with the criteria cri from the table.
Definition: tsqlormapper.h:134
static QString escapeIdentifier(const QString &identifier, QSqlDriver::IdentifierType type=QSqlDriver::FieldName, int databaseId=0)
Returns the identifier escaped according to the rules of the database databaseId. ...
Definition: tsqlquery.cpp:95
virtual QString selectStatement() const
Returns a SELECT statement generated from the specified parameters.
Definition: tsqlormapper.h:391
void reset()
Reset the internal state of the mapper object.
Definition: tsqlormapper.h:653
void tSystemError(const char *msg,...)
Definition: tsystemglobal.cpp:118
TCriteria criteria() const
Definition: tsqljoin.h:26
ConstIterator()
Definition: tsqlormapper.h:75
The TSqlQuery class provides a means of executing and manipulating SQL statements.
Definition: tsqlquery.h:8
int findIn(int column, const QVariantList &values)
Retrieves with the criteria that the column is within the list of values values returns the number of...
Definition: tsqlormapper.h:223
T findByPrimaryKey(QVariant pk)
Returns the ORM object retrieved with the primary key pk from the table.
Definition: tsqlormapper.h:168
int find(const TCriteria &cri=TCriteria())
Retrieves with the criteria cri from the table and returns the number of the ORM objects.
Definition: tsqlormapper.h:186
T findFirstBy(int column, QVariant value)
Returns the first ORM object retrieved with the criteria for the column as the value in the table...
Definition: tsqlormapper.h:158
void setOffset(int offset)
Sets the offset to offset, which is the number of rows to skip for execution of SELECT statement...
Definition: tsqlormapper.h:298
void setJoin(int column, const TSqlJoin< C > &join)
Sets a JOIN clause for column to join.
Definition: tsqlormapper.h:598
TSqlORMapper< T > & join(int column, const TSqlJoin< C > &join)
Definition: tsqlormapper.h:643
#define T_DISABLE_COPY(Class)
Definition: tglobal.h:137
int findCountBy(int column, QVariant value)
Returns the number of records retrieved with the criteria for the column as the value from the table...
Definition: tsqlormapper.h:492
#define T_DISABLE_MOVE(Class)
Definition: tglobal.h:141
T first() const
Returns the first ORM object in the results retrieved by find() function.
Definition: tsqlormapper.h:251
bool operator!=(const ConstIterator &o) const
Definition: tsqlormapper.h:80
Definition: tfnamespace.h:268
bool operator==(const ConstIterator &o) const
Definition: tsqlormapper.h:79
TSql::JoinMode joinMode() const
Definition: tsqljoin.h:24
The TSqlORMapper class is a template class that provides concise functionality to object-relational m...
Definition: tsqlormapper.h:26
The Tf namespace contains miscellaneous identifiers used throughout the library of TreeFrog Framework...
Definition: tdebug.h:8
ConstIterator(const ConstIterator &o)
Definition: tsqlormapper.h:76
Definition: tfnamespace.h:121
void setSortOrder(int column, Tf::SortOrder order=Tf::AscendingOrder)
Sets the sort order for column to order.
Definition: tsqlormapper.h:307
void tSystemDebug(const char *msg,...)
Definition: tsystemglobal.cpp:146
int findBy(int column, QVariant value)
Retrieves with the criteria for the column as the value in the table and returns the number of the OR...
Definition: tsqlormapper.h:211
Definition: tfnamespace.h:269
ConstIterator end() const
Definition: tsqlormapper.h:65
const QByteArray UpdatedAt("updatedAt")
ConstIterator & operator=(const ConstIterator &o)
Definition: tsqlormapper.h:77
Definition: tfnamespace.h:267
Const iterator.
Definition: tsqlormapper.h:70
static QString formatValue(const QVariant &val, QVariant::Type type=QVariant::Invalid, int databaseId=0)
Returns a string representation of the value val for the database databaseId.
Definition: tsqlquery.cpp:118
bool next()
Retrieves the next record in the result, if available, and positions the query on the retrieved recor...
Definition: tsqlquery.cpp:199
ConstIterator operator++(int)
Definition: tsqlormapper.h:82
void setLimit(int limit)
Sets the limit to limit, which is the limited number of rows for execution of SELECT statement...
Definition: tsqlormapper.h:288
ConstIterator & operator++()
Definition: tsqlormapper.h:81
virtual ~TSqlORMapper()
Destructor.
Definition: tsqlormapper.h:126
const QByteArray ModifiedAt("modifiedAt")
Definition: tfnamespace.h:19
int rowCount() const
Returns the number of rows of the current query.
Definition: tsqlormapper.h:232
virtual QString orderByClause() const
Definition: tsqlormapper.h:94
void setFilter(const QString &filter)
Sets the current filter to filter.
Definition: tsqlormapper.h:381
ConstIterator begin() const
Definition: tsqlormapper.h:64
T last() const
Returns the last ORM object in the results retrieved by find() function.
Definition: tsqlormapper.h:261
Definition: tfnamespace.h:136
int joinColumn() const
Definition: tsqljoin.h:25
ConstIterator operator--(int)
Definition: tsqlormapper.h:84
const TSqlORMapper< T > * m
Definition: tsqlormapper.h:72
TSqlORMapper()
Constructor.
Definition: tsqlormapper.h:116
int removeAll(const TCriteria &cri=TCriteria())
Removes all rows based on the criteria cri from the table and returns the number of the rows affected...
Definition: tsqlormapper.h:573
int updateAll(const TCriteria &cri, int column, QVariant value)
Updates the value of the specified column in all rows that satisfy the criteria cri and returns the n...
Definition: tsqlormapper.h:561
Definition: tfnamespace.h:258
bool exec(const QString &query)
Executes the SQL in query.
Definition: tsqlquery.cpp:151
int numRowsAffected() const
Returns the number of rows affected by the result&#39;s SQL statement, or -1 if it cannot be determined...
Definition: tsqlquery.cpp:174
T_CORE_EXPORT void writeQueryLog(const QString &query, bool success, const QSqlError &error)
Definition: tsystemglobal.cpp:184
int it
Definition: tsqlormapper.h:73
#define tWarn
Definition: tglobal.h:148
int findCount(const TCriteria &cri=TCriteria())
Returns the number of records retrieved with the criteria cri from the table.
Definition: tsqlormapper.h:463
The TSqlJoin class represents JOIN clause for combination to a record of other table.
Definition: tsqljoin.h:15
The TCriteria class represents a WHERE clause without SQL for the sake of database abstraction...
Definition: tcriteria.h:8
virtual void clear()
Clears and releases any acquired resource.
Definition: tsqlormapper.h:662
SortOrder
Definition: tfnamespace.h:135
bool isEmpty() const
Returns true if the criteria has no data; otherwise returns false.
Definition: tcriteria.cpp:341
const char * prop(const QJSValue &val, const QString &name=QString())
Definition: tjsmodule.cpp:21
T value(int i) const
Returns the ORM object in the results retrieved by find() function.
Definition: tsqlormapper.h:272