Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qsqltablemodel.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qsqltablemodel.h"
5
6#include "qsqldriver.h"
7#include "qsqlerror.h"
8#include "qsqlfield.h"
9#include "qsqlindex.h"
10#include "qsqlquery.h"
11#include "qsqlrecord.h"
12#include "qsqlresult.h"
13
14#include "qsqltablemodel_p.h"
15
16#include <qdebug.h>
17
19
20using namespace Qt::StringLiterals;
21
23
28
32QSqlRecord QSqlTableModelPrivate::record(const QList<QVariant> &values) const
33{
35 for (int i = 0; i < r.count() && i < values.size(); ++i)
36 r.setValue(i, values.at(i));
37 return r;
38}
39
44
46{
47 QString fieldname = name;
49 fieldname = db.driver()->stripDelimiters(fieldname, QSqlDriver::FieldName);
50 return fieldname;
51}
52
54{
55 int cnt = 0;
58 for ( ; i != e && (maxRow < 0 || i.key() <= maxRow); ++i)
59 if (i.value().insert())
60 ++cnt;
61
62 return cnt;
63}
64
71
83
88
90{
91 Q_Q(QSqlTableModel);
93
94 switch (r.op()) {
96 Q_ASSERT_X(false, "QSqlTableModelPrivate::revertCachedRow()", "Invalid entry in cache map");
97 return;
100 if (!r.submitted()) {
101 cache[row].revert();
102 emit q->dataChanged(q->createIndex(row, 0),
103 q->createIndex(row, q->columnCount() - 1));
104 }
105 break;
108 if (it == cache.end())
109 return;
110 q->beginRemoveRows(QModelIndex(), row, row);
111 it = cache.erase(it);
112 while (it != cache.end()) {
113 int oldKey = it.key();
114 const QSqlTableModelPrivate::ModifiedRow oldValue = it.value();
115 cache.erase(it);
116 it = cache.insert(oldKey - 1, oldValue);
117 ++it;
118 }
119 q->endRemoveRows();
120 break; }
121 }
122}
123
124bool QSqlTableModelPrivate::exec(const QString &stmt, bool prepStatement,
125 const QSqlRecord &rec, const QSqlRecord &whereValues)
126{
127 if (stmt.isEmpty())
128 return false;
129
130 // lazy initialization of editQuery
131 if (editQuery.driver() != db.driver())
133
134 // workaround for In-Process databases - remove all read locks
135 // from the table to make sure the editQuery succeeds
137 const_cast<QSqlResult *>(query.result())->detachFromResultSet();
138
139 if (prepStatement) {
140 if (editQuery.lastQuery() != stmt) {
141 if (!editQuery.prepare(stmt)) {
143 return false;
144 }
145 }
146 int i;
147 for (i = 0; i < rec.count(); ++i)
148 if (rec.isGenerated(i))
150 for (i = 0; i < whereValues.count(); ++i)
151 if (whereValues.isGenerated(i) && !whereValues.isNull(i))
152 editQuery.addBindValue(whereValues.value(i));
153
154 if (!editQuery.exec()) {
156 return false;
157 }
158 } else {
159 if (!editQuery.exec(stmt)) {
161 return false;
162 }
163 }
164 return true;
165}
166
262{
263 Q_D(QSqlTableModel);
264 d->db = db.isValid() ? db : QSqlDatabase::database();
265}
266
270 : QSqlQueryModel(dd, parent)
271{
272 Q_D(QSqlTableModel);
273 d->db = db.isValid() ? db : QSqlDatabase::database();
274}
275
282
294void QSqlTableModel::setTable(const QString &tableName)
295{
296 Q_D(QSqlTableModel);
297 clear();
298 d->tableName = tableName;
299 d->initRecordAndPrimaryIndex();
300
301 if (d->rec.count() == 0)
302 d->error = QSqlError("Unable to find table "_L1 + d->tableName, QString(),
304
305 // Remember the auto index column if there is one now.
306 // The record that will be obtained from the query after select lacks this feature.
307 d->autoColumn.clear();
308 for (int c = 0; c < d->rec.count(); ++c) {
309 if (d->rec.field(c).isAutoValue()) {
310 d->autoColumn = d->rec.fieldName(c);
311 break;
312 }
313 }
314}
315
320{
321 Q_D(const QSqlTableModel);
322 return d->tableName;
323}
324
335{
336 Q_D(QSqlTableModel);
337 const QString query = selectStatement();
338 if (query.isEmpty())
339 return false;
340
342
343 d->clearCache();
344
345 this->QSqlQueryModel::setQuery(query, d->db);
346
347 if (!d->query.isActive() || lastError().isValid()) {
348 // something went wrong - revert to non-select state
349 d->initRecordAndPrimaryIndex();
351 return false;
352 }
354 return true;
355}
356
369{
370 Q_D(QSqlTableModel);
371
372 if (row < 0 || row >= rowCount())
373 return false;
374
375 const int table_sort_col = d->sortColumn;
376 d->sortColumn = -1;
377 const QString table_filter = d->filter;
378 d->filter = d->db.driver()->sqlStatement(QSqlDriver::WhereStatement,
379 d->tableName,
381 false);
382 static const QString wh = SqlTm::where() + SqlTm::sp();
383 if (d->filter.startsWith(wh, Qt::CaseInsensitive))
384 d->filter.remove(0, wh.size());
385
386 QString stmt;
387
388 if (!d->filter.isEmpty())
389 stmt = selectStatement();
390
391 d->sortColumn = table_sort_col;
392 d->filter = table_filter;
393
394 if (stmt.isEmpty())
395 return false;
396
397 bool exists;
398 QSqlRecord newValues;
399
400 {
401 QSqlQuery q(d->db);
402 q.setForwardOnly(true);
403 if (!q.exec(stmt))
404 return false;
405
406 exists = q.next();
407 newValues = q.record();
408 }
409
410 bool needsAddingToCache = !exists || d->cache.contains(row);
411
412 if (!needsAddingToCache) {
413 const QSqlRecord curValues = record(row);
414 needsAddingToCache = curValues.count() != newValues.count();
415 if (!needsAddingToCache) {
416 // Look for changed values. Primary key fields are customarily first
417 // and probably change less often than other fields, so start at the end.
418 for (int f = curValues.count() - 1; f >= 0; --f) {
419 if (curValues.value(f) != newValues.value(f)) {
420 needsAddingToCache = true;
421 break;
422 }
423 }
424 }
425 }
426
427 if (needsAddingToCache) {
428 d->cache[row].refresh(exists, newValues);
431 }
432
433 return true;
434}
435
440{
441 Q_D(const QSqlTableModel);
442 if (!index.isValid() || (role != Qt::DisplayRole && role != Qt::EditRole))
443 return QVariant();
444
445 const auto it = d->cache.constFind(index.row());
446 if (it != d->cache.constEnd() && it->op() != QSqlTableModelPrivate::None)
447 return it->rec().value(index.column());
448
449 return QSqlQueryModel::data(index, role);
450}
451
455QVariant QSqlTableModel::headerData(int section, Qt::Orientation orientation, int role) const
456{
457 Q_D(const QSqlTableModel);
458 if (orientation == Qt::Vertical && role == Qt::DisplayRole) {
459 const QSqlTableModelPrivate::Op op = d->cache.value(section).op();
461 return "*"_L1;
462 else if (op == QSqlTableModelPrivate::Delete)
463 return "!"_L1;
464 }
465 return QSqlQueryModel::headerData(section, orientation, role);
466}
467
476{
477 Q_D(const QSqlTableModel);
479 const QSqlTableModelPrivate::CacheMap::ConstIterator e = d->cache.constEnd();
480 for (; i != e; ++i) {
481 if (!i.value().submitted())
482 return true;
483 }
484 return false;
485}
486
495{
496 Q_D(const QSqlTableModel);
497 if (!index.isValid())
498 return false;
499
500 const auto it = d->cache.constFind(index.row());
501 if (it == d->cache.constEnd())
502 return false;
504 if (row.submitted())
505 return false;
506
510 && row.rec().isGenerated(index.column()));
511}
512
540{
541 Q_D(QSqlTableModel);
542 if (d->busyInsertingRows)
543 return false;
544
545 if (role != Qt::EditRole)
546 return QSqlQueryModel::setData(index, value, role);
547
548 if (!index.isValid() || index.column() >= d->rec.count() || index.row() >= rowCount())
549 return false;
550
552 return false;
553
554 const QVariant oldValue = QSqlTableModel::data(index, role);
555 if (value == oldValue
556 && value.isNull() == oldValue.isNull()
557 && d->cache.value(index.row()).op() != QSqlTableModelPrivate::Insert)
558 return true;
559
561
565
566 row.setValue(index.column(), value);
568
569 if (d->strategy == OnFieldChange && row.op() != QSqlTableModelPrivate::Insert)
570 return submit();
571
572 return true;
573}
574
582
600{
601 Q_D(QSqlTableModel);
602 QSqlRecord rec(values);
603 emit beforeUpdate(row, rec);
604
605 const QSqlRecord whereValues = primaryValues(row);
606 const bool prepStatement = d->db.driver()->hasFeature(QSqlDriver::PreparedQueries);
607 const QString stmt = d->db.driver()->sqlStatement(QSqlDriver::UpdateStatement, d->tableName,
608 rec, prepStatement);
609 const QString where = d->db.driver()->sqlStatement(QSqlDriver::WhereStatement, d->tableName,
610 whereValues, prepStatement);
611
612 if (stmt.isEmpty() || where.isEmpty() || row < 0 || row >= rowCount()) {
613 d->error = QSqlError("No Fields to update"_L1, QString(), QSqlError::StatementError);
614 return false;
615 }
616
617 return d->exec(SqlTm::concat(stmt, where), prepStatement, rec, whereValues);
618}
619
620
635{
636 Q_D(QSqlTableModel);
637 QSqlRecord rec = values;
638 emit beforeInsert(rec);
639
640 const bool prepStatement = d->db.driver()->hasFeature(QSqlDriver::PreparedQueries);
641 const QString stmt = d->db.driver()->sqlStatement(QSqlDriver::InsertStatement, d->tableName,
642 rec, prepStatement);
643
644 if (stmt.isEmpty()) {
645 d->error = QSqlError("No Fields to update"_L1, QString(), QSqlError::StatementError);
646 return false;
647 }
648
649 return d->exec(stmt, prepStatement, rec, QSqlRecord() /* no where values */);
650}
651
665{
666 Q_D(QSqlTableModel);
668
669 const QSqlRecord whereValues = primaryValues(row);
670 const bool prepStatement = d->db.driver()->hasFeature(QSqlDriver::PreparedQueries);
671 const QString stmt = d->db.driver()->sqlStatement(QSqlDriver::DeleteStatement,
672 d->tableName,
673 QSqlRecord(),
674 prepStatement);
675 const QString where = d->db.driver()->sqlStatement(QSqlDriver::WhereStatement,
676 d->tableName,
677 whereValues,
678 prepStatement);
679
680 if (stmt.isEmpty() || where.isEmpty()) {
681 d->error = QSqlError("Unable to delete row"_L1, QString(), QSqlError::StatementError);
682 return false;
683 }
684
685 return d->exec(SqlTm::concat(stmt, where), prepStatement, QSqlRecord() /* no new values */, whereValues);
686}
687
704{
705 Q_D(QSqlTableModel);
706
707 bool success = true;
708
709 const auto cachedKeys = d->cache.keys();
710 for (int row : cachedKeys) {
711 // be sure cache *still* contains the row since overridden selectRow() could have called select()
712 QSqlTableModelPrivate::CacheMap::iterator it = d->cache.find(row);
713 if (it == d->cache.end())
714 continue;
715
717 if (mrow.submitted())
718 continue;
719
720 switch (mrow.op()) {
722 success = insertRowIntoTable(mrow.rec());
723 break;
725 success = updateRowInTable(row, mrow.rec());
726 break;
728 success = deleteRowFromTable(row);
729 break;
731 Q_ASSERT_X(false, "QSqlTableModel::submitAll()", "Invalid cache operation");
732 break;
733 }
734
735 if (success) {
736 if (d->strategy != OnManualSubmit && mrow.op() == QSqlTableModelPrivate::Insert) {
737 int c = mrow.rec().indexOf(d->autoColumn);
738 if (c != -1 && !mrow.rec().isGenerated(c))
739 mrow.setValue(c, d->editQuery.lastInsertId());
740 }
741 mrow.setSubmitted();
742 if (d->strategy != OnManualSubmit)
743 success = selectRow(row);
744 }
745
746 if (!success)
747 break;
748 }
749
750 if (success) {
751 if (d->strategy == OnManualSubmit)
752 success = select();
753 }
754
755 return success;
756}
757
778{
779 Q_D(QSqlTableModel);
780 if (d->strategy == OnRowChange || d->strategy == OnFieldChange)
781 return submitAll();
782 return true;
783}
784
799{
800 Q_D(QSqlTableModel);
801 if (d->strategy == OnRowChange || d->strategy == OnFieldChange)
802 revertAll();
803}
804
831{
832 Q_D(QSqlTableModel);
833 revertAll();
834 d->strategy = strategy;
835}
836
843{
844 Q_D(const QSqlTableModel);
845 return d->strategy;
846}
847
854{
855 Q_D(QSqlTableModel);
856
857 const QList<int> rows(d->cache.keys());
858 for (int i = rows.size() - 1; i >= 0; --i)
859 revertRow(rows.value(i));
860}
861
868{
869 if (row < 0)
870 return;
871
872 Q_D(QSqlTableModel);
873 d->revertCachedRow(row);
874}
875
883{
884 Q_D(const QSqlTableModel);
885 return d->primaryIndex;
886}
887
898{
899 Q_D(QSqlTableModel);
900 d->primaryIndex = key;
901}
902
907{
908 Q_D(const QSqlTableModel);
909 return d->db;
910}
911
924
933{
934 Q_D(QSqlTableModel);
935 d->sortColumn = column;
936 d->sortOrder = order;
937}
938
946{
947 Q_D(const QSqlTableModel);
948 QSqlField f = d->rec.field(d->sortColumn);
949 if (!f.isValid())
950 return QString();
951
952 //we can safely escape the field because it would have been obtained from the database
953 //and have the correct case
954 QString field = d->db.driver()->escapeIdentifier(d->tableName, QSqlDriver::TableName)
955 + u'.'
956 + d->db.driver()->escapeIdentifier(f.name(), QSqlDriver::FieldName);
957 field = d->sortOrder == Qt::AscendingOrder ? SqlTm::asc(field) : SqlTm::desc(field);
958 return SqlTm::orderBy(field);
959}
960
965int QSqlTableModel::fieldIndex(const QString &fieldName) const
966{
967 Q_D(const QSqlTableModel);
968 return d->rec.indexOf(fieldName);
969}
970
979{
980 Q_D(const QSqlTableModel);
981 if (d->tableName.isEmpty()) {
982 d->error = QSqlError("No table name given"_L1, QString(), QSqlError::StatementError);
983 return QString();
984 }
985 if (d->rec.isEmpty()) {
986 d->error = QSqlError("Unable to find table "_L1 + d->tableName, QString(),
988 return QString();
989 }
990
991 const QString stmt = d->db.driver()->sqlStatement(QSqlDriver::SelectStatement,
992 d->tableName,
993 d->rec,
994 false);
995 if (stmt.isEmpty()) {
996 d->error = QSqlError("Unable to select fields from table "_L1 + d->tableName,
998 return stmt;
999 }
1000 return SqlTm::concat(SqlTm::concat(stmt, SqlTm::where(d->filter)), orderByClause());
1001}
1002
1013{
1014 Q_D(QSqlTableModel);
1015 if (parent.isValid() || column < 0 || column + count > d->rec.count())
1016 return false;
1017 for (int i = 0; i < count; ++i)
1018 d->rec.remove(column);
1019 if (d->query.isActive())
1020 return select();
1021 return true;
1022}
1023
1054{
1055 Q_D(QSqlTableModel);
1056 if (parent.isValid() || row < 0 || count <= 0 || row + count > rowCount())
1057 return false;
1058
1059 if (d->strategy != OnManualSubmit)
1060 if (count > 1 || (d->cache.value(row).submitted() && isDirty()))
1061 return false;
1062
1063 // Iterate backwards so we don't have to worry about removed rows causing
1064 // higher cache entries to shift downwards.
1065 for (int idx = row + count - 1; idx >= row; --idx) {
1066 QSqlTableModelPrivate::ModifiedRow& mrow = d->cache[idx];
1067 if (mrow.op() == QSqlTableModelPrivate::Insert) {
1068 revertRow(idx);
1069 } else {
1070 if (mrow.op() == QSqlTableModelPrivate::None)
1073 else
1075 if (d->strategy == OnManualSubmit)
1077 }
1078 }
1079
1080 if (d->strategy != OnManualSubmit)
1081 return submit();
1082
1083 return true;
1084}
1085
1107{
1108 Q_D(QSqlTableModel);
1109 if (row < 0 || count <= 0 || row > rowCount() || parent.isValid())
1110 return false;
1111
1112 if (d->strategy != OnManualSubmit)
1113 if (count != 1 || isDirty())
1114 return false;
1115
1116 d->busyInsertingRows = true;
1118
1119 if (d->strategy != OnManualSubmit)
1120 d->cache.empty();
1121
1122 if (!d->cache.isEmpty()) {
1124 while (it != d->cache.begin() && (--it).key() >= row) {
1125 int oldKey = it.key();
1126 const QSqlTableModelPrivate::ModifiedRow oldValue = it.value();
1127 d->cache.erase(it);
1128 it = d->cache.insert(oldKey + count, oldValue);
1129 }
1130 }
1131
1132 for (int i = 0; i < count; ++i) {
1134 d->rec);
1135 emit primeInsert(row + i, d->cache[row + i].recRef());
1136 }
1137
1138 endInsertRows();
1139 d->busyInsertingRows = false;
1140 return true;
1141}
1142
1156{
1157 if (row < 0)
1158 row = rowCount();
1159 if (!insertRow(row, QModelIndex()))
1160 return false;
1161 if (!setRecord(row, record)) {
1162 revertRow(row);
1163 return false;
1164 }
1165 return true;
1166}
1167
1171{
1172 Q_D(const QSqlTableModel);
1173
1174 if (parent.isValid())
1175 return 0;
1176
1177 return QSqlQueryModel::rowCount() + d->insertCount();
1178}
1179
1193{
1194 Q_D(const QSqlTableModel);
1195 const auto it = d->cache.constFind(item.row());
1196 if (it != d->cache.constEnd() && it->insert())
1197 return QModelIndex();
1198
1199 const int rowOffset = d->insertCount(item.row());
1200 return QSqlQueryModel::indexInQuery(createIndex(item.row() - rowOffset, item.column(), item.internalPointer()));
1201}
1202
1209{
1210 Q_D(const QSqlTableModel);
1211 return d->filter;
1212}
1213
1227{
1228 Q_D(QSqlTableModel);
1229 d->filter = filter;
1230 if (d->query.isActive())
1231 select();
1232}
1233
1237{
1238 Q_D(QSqlTableModel);
1240 d->clear();
1242 endResetModel();
1243}
1244
1247Qt::ItemFlags QSqlTableModel::flags(const QModelIndex &index) const
1248{
1249 Q_D(const QSqlTableModel);
1250 if (index.internalPointer() || index.column() < 0 || index.column() >= d->rec.count()
1251 || index.row() < 0)
1252 return { };
1253
1254 bool editable = true;
1255
1256 if (d->rec.field(index.column()).isReadOnly()) {
1257 editable = false;
1258 }
1259 else {
1260 const QSqlTableModelPrivate::ModifiedRow mrow = d->cache.value(index.row());
1261 if (mrow.op() == QSqlTableModelPrivate::Delete) {
1262 editable = false;
1263 }
1264 else if (d->strategy == OnFieldChange) {
1265 if (mrow.op() != QSqlTableModelPrivate::Insert)
1266 if (!isDirty(index) && isDirty())
1267 editable = false;
1268 }
1269 else if (d->strategy == OnRowChange) {
1270 if (mrow.submitted() && isDirty())
1271 editable = false;
1272 }
1273 }
1274
1275 if (!editable)
1277 else
1279}
1280
1293
1307{
1308 Q_D(const QSqlTableModel);
1309
1310 // the query gets the values from virtual data()
1312
1313 // get generated flags from the cache
1314 const QSqlTableModelPrivate::ModifiedRow mrow = d->cache.value(row);
1315 if (mrow.op() != QSqlTableModelPrivate::None) {
1316 const QSqlRecord &crec = mrow.rec();
1317 for (int i = 0, cnt = rec.count(); i < cnt; ++i)
1318 rec.setGenerated(i, crec.isGenerated(i));
1319 }
1320
1321 return rec;
1322}
1323
1347{
1348 Q_D(QSqlTableModel);
1349 Q_ASSERT_X(row >= 0, "QSqlTableModel::setRecord()", "Cannot set a record to a row less than 0");
1350 if (d->busyInsertingRows)
1351 return false;
1352
1353 if (row >= rowCount())
1354 return false;
1355
1356 if (d->cache.value(row).op() == QSqlTableModelPrivate::Delete)
1357 return false;
1358
1359 if (d->strategy != OnManualSubmit && d->cache.value(row).submitted() && isDirty())
1360 return false;
1361
1362 // Check field names and remember mapping
1363 typedef QMap<int, int> Map;
1364 Map map;
1365 for (int i = 0; i < values.count(); ++i) {
1366 int idx = d->nameToIndex(values.fieldName(i));
1367 if (idx == -1)
1368 return false;
1369 map[i] = idx;
1370 }
1371
1373 if (mrow.op() == QSqlTableModelPrivate::None)
1376
1377 Map::const_iterator i = map.constBegin();
1378 const Map::const_iterator e = map.constEnd();
1379 for ( ; i != e; ++i) {
1380 // have to use virtual setData() here rather than mrow.setValue()
1381 EditStrategy strategy = d->strategy;
1382 d->strategy = OnManualSubmit;
1383 QModelIndex cIndex = createIndex(row, i.value());
1384 setData(cIndex, values.value(i.key()));
1385 d->strategy = strategy;
1386 // setData() sets generated to TRUE, but source record should prevail.
1387 if (!values.isGenerated(i.key()))
1388 mrow.recRef().setGenerated(i.value(), false);
1389 }
1390
1391 if (d->strategy != OnManualSubmit)
1392 return submit();
1393
1394 return true;
1395}
1396
1405{
1406 Q_D(const QSqlTableModel);
1407
1408 const QSqlRecord &pIndex = d->primaryIndex.isEmpty() ? d->rec : d->primaryIndex;
1409
1410 QSqlTableModelPrivate::ModifiedRow mr = d->cache.value(row);
1411 if (mr.op() != QSqlTableModelPrivate::None)
1412 return mr.primaryValues(pIndex);
1413 else
1414 return QSqlQueryModel::record(row).keyValues(pIndex);
1415}
1416
1418
1419#include "moc_qsqltablemodel.cpp"
virtual Q_INVOKABLE Qt::ItemFlags flags(const QModelIndex &index) const
Returns the item flags for the given index.
Q_INVOKABLE Qt::SortOrder order
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QList< int > &roles=QList< int >())
This signal is emitted whenever the data in an existing item changes.
virtual Q_INVOKABLE bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole)
Sets the role data for the item at index to value.
void headerDataChanged(Qt::Orientation orientation, int first, int last)
This signal is emitted whenever a header is changed.
QModelIndex createIndex(int row, int column, const void *data=nullptr) const
Creates a model index for the given row and column with the internal pointer ptr.
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:346
iterator insert(const Key &key, const T &value)
Definition qmap.h:688
T value(const Key &key, const T &defaultValue=T()) const
Definition qmap.h:357
iterator erase(const_iterator it)
Definition qmap.h:619
void clear()
Definition qmap.h:289
iterator find(const Key &key)
Definition qmap.h:641
const_iterator ConstIterator
Definition qmap.h:639
iterator end()
Definition qmap.h:602
const_iterator constBegin() const
Definition qmap.h:600
const_iterator constEnd() const
Definition qmap.h:604
\inmodule QtCore
\inmodule QtCore
Definition qobject.h:103
iterator begin()
Definition qset.h:136
iterator end()
Definition qset.h:140
const_iterator constEnd() const noexcept
Definition qset.h:143
iterator erase(const_iterator i)
Definition qset.h:145
const_iterator constFind(const T &value) const
Definition qset.h:161
iterator find(const T &value)
Definition qset.h:159
iterator insert(const T &value)
Definition qset.h:155
The QSqlDatabase class handles a connection to a database.
QSqlIndex primaryIndex(const QString &tablename) const
Returns the primary index for table tablename.
QSqlDriver * driver() const
Returns the database driver used to access the database connection.
QSqlRecord record(const QString &tablename) const
Returns a QSqlRecord populated with the names of all the fields in the table (or view) called tablena...
static QSqlDatabase database(const QString &connectionName=QLatin1StringView(defaultConnection), bool open=true)
\threadsafe
@ DeleteStatement
Definition qsqldriver.h:39
@ UpdateStatement
Definition qsqldriver.h:38
@ InsertStatement
Definition qsqldriver.h:39
@ SelectStatement
Definition qsqldriver.h:38
virtual QString stripDelimiters(const QString &identifier, IdentifierType type) const
Returns the identifier with the leading and trailing delimiters removed, identifier can either be a t...
@ PreparedQueries
Definition qsqldriver.h:33
virtual bool isIdentifierEscaped(const QString &identifier, IdentifierType type) const
Returns whether identifier is escaped according to the database rules.
virtual bool hasFeature(DriverFeature f) const =0
Returns true if the driver supports feature feature; otherwise returns false.
The QSqlError class provides SQL database error information.
Definition qsqlerror.h:17
@ StatementError
Definition qsqlerror.h:22
The QSqlField class manipulates the fields in SQL database tables and views.
Definition qsqlfield.h:19
The QSqlIndex class provides functions to manipulate and describe database indexes.
Definition qsqlindex.h:18
void initColOffsets(int size)
static const QLatin1StringView orderBy()
static const QLatin1StringView asc()
static const QLatin1StringView sp()
static const QLatin1StringView desc()
static const QString concat(const QString &a, const QString &b)
static const QLatin1StringView where()
The QSqlQueryModel class provides a read-only data model for SQL result sets.
void beginInsertRows(const QModelIndex &parent, int first, int last)
virtual QModelIndex indexInQuery(const QModelIndex &item) const
Returns the index of the value in the database result set for the given item in the model.
QVariant data(const QModelIndex &item, int role=Qt::DisplayRole) const override
Returns the value for the specified item and role.
int rowCount(const QModelIndex &parent=QModelIndex()) const override
If the database supports returning the size of a query (see QSqlDriver::hasFeature()),...
void setQuery(QSqlQuery &&query)
Resets the model and sets the data provider to be the given query.
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
Returns the header data for the given role in the section of the header with the specified orientatio...
QSqlError lastError() const
Returns information about the last error that occurred on the database.
int columnCount(const QModelIndex &parent=QModelIndex()) const override
\reimp
QSqlRecord record() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
virtual void clear()
Clears the model and releases any acquired resource.
The QSqlQuery class provides a means of executing and manipulating SQL statements.
Definition qsqlquery.h:24
const QSqlDriver * driver() const
Returns the database driver associated with the query.
bool prepare(const QString &query)
Prepares the SQL query query for execution.
void clear()
Clears the result set and releases any resources held by the query.
QSqlError lastError() const
Returns error information about the last error (if any) that occurred with this query.
QString lastQuery() const
Returns the text of the current query being used, or an empty string if there is no current query tex...
bool exec(const QString &query)
Executes the SQL in query.
void addBindValue(const QVariant &val, QSql::ParamType type=QSql::In)
Adds the value val to the list of values when using positional value binding.
The QSqlRecord class encapsulates a database record.
Definition qsqlrecord.h:20
void clear()
Removes all the record's fields.
QVariant value(int i) const
Returns the value of the field located at position index in the record.
bool isEmpty() const
Returns true if there are no fields in the record; otherwise returns false.
int count() const
Returns the number of fields in the record.
QSqlRecord keyValues(const QSqlRecord &keyFields) const
void setValue(int i, const QVariant &val)
Sets the value of the field at position index to val.
bool isGenerated(int i) const
Returns true if the record has a field at position index and this field is to be generated (the defau...
void setGenerated(const QString &name, bool generated)
This is an overloaded member function, provided for convenience. It differs from the above function o...
int indexOf(const QString &name) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
The QSqlResult class provides an abstract interface for accessing data from specific SQL databases.
Definition qsqlresult.h:22
QSqlRecord primaryValues(const QSqlRecord &pi) const
virtual int nameToIndex(const QString &name) const
virtual void clearCache()
int insertCount(int maxRow=-1) const
bool exec(const QString &stmt, bool prepStatement, const QSqlRecord &rec, const QSqlRecord &whereValues)
QSqlRecord record(const QList< QVariant > &values) const
virtual void revertCachedRow(int row)
QString strippedFieldName(const QString &name) const
The QSqlTableModel class provides an editable data model for a single database table.
EditStrategy
This enum type describes which strategy to choose when editing values in the database.
void primeInsert(int row, QSqlRecord &record)
This signal is emitted by insertRows(), when an insertion is initiated in the given row of the curren...
virtual void setFilter(const QString &filter)
Sets the current filter to filter.
virtual QString orderByClause() const
Returns an SQL {ORDER BY} clause based on the currently set sort order.
bool removeColumns(int column, int count, const QModelIndex &parent=QModelIndex()) override
Removes count columns from the parent model, starting at index column.
void setPrimaryKey(const QSqlIndex &key)
Protected method that allows subclasses to set the primary key to key.
bool insertRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
Inserts count empty rows at position row.
void sort(int column, Qt::SortOrder order) override
Sorts the data by column with the sort order order.
QVariant data(const QModelIndex &idx, int role=Qt::DisplayRole) const override
\reimp
void beforeInsert(QSqlRecord &record)
This signal is emitted by insertRowIntoTable() before a new row is inserted into the currently active...
QSqlRecord record() const
This is an overloaded function.
QSqlTableModel(QObject *parent=nullptr, const QSqlDatabase &db=QSqlDatabase())
Creates an empty QSqlTableModel and sets the parent to parent and the database connection to db.
bool isDirty() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
QSqlRecord primaryValues(int row) const
virtual bool selectRow(int row)
QString filter() const
Returns the currently set filter.
QSqlIndex primaryKey() const
Returns the primary key for the current table, or an empty QSqlIndex if the table is not set or has n...
virtual void setSort(int column, Qt::SortOrder order)
Sets the sort order for column to order.
EditStrategy editStrategy() const
Returns the current edit strategy.
virtual bool updateRowInTable(int row, const QSqlRecord &values)
Updates the given row in the currently active database table with the specified values.
void revert() override
This reimplemented slot is called by the item delegates when the user canceled editing the current ro...
bool clearItemData(const QModelIndex &index) override
\reimp
virtual bool insertRowIntoTable(const QSqlRecord &values)
Inserts the values values into the currently active database table.
void clear() override
\reimp
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override
Sets the data for the item index for the role role to value.
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
\reimp
QString tableName() const
Returns the name of the currently selected table.
void revertAll()
Reverts all pending changes.
bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
Removes count rows starting at row.
bool submitAll()
Submits all pending changes and returns true on success.
virtual void setTable(const QString &tableName)
Sets the database table on which the model operates to tableName.
void beforeDelete(int row)
This signal is emitted by deleteRowFromTable() before the row is deleted from the currently active da...
QModelIndex indexInQuery(const QModelIndex &item) const override
Returns the index of the value in the database result set for the given item in the model.
virtual QString selectStatement() const
Returns the SQL SELECT statement used internally to populate the model.
virtual bool select()
Populates the model with data from the table that was set via setTable(), using the specified filter ...
bool submit() override
This reimplemented slot is called by the item delegates when the user stopped editing the current row...
virtual void setEditStrategy(EditStrategy strategy)
Sets the strategy for editing values in the database to strategy.
QSqlDatabase database() const
Returns the model's database connection.
virtual bool deleteRowFromTable(int row)
Deletes the given row from the currently active database table.
bool insertRecord(int row, const QSqlRecord &record)
Inserts the record at position row.
int fieldIndex(const QString &fieldName) const
Returns the index of the field fieldName, or -1 if no corresponding field exists in the model.
bool setRecord(int row, const QSqlRecord &record)
Applies values to the row in the model.
int rowCount(const QModelIndex &parent=QModelIndex()) const override
\reimp
Qt::ItemFlags flags(const QModelIndex &index) const override
\reimp
virtual ~QSqlTableModel()
Destroys the object and frees any allocated resources.
void beforeUpdate(int row, QSqlRecord &record)
This signal is emitted by updateRowInTable() before the row is updated in the currently active databa...
virtual void revertRow(int row)
Reverts all changes for the specified row.
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
void clear()
Clears the contents of the string and makes it null.
Definition qstring.h:1252
qsizetype size() const noexcept
Returns the number of characters in this string.
Definition qstring.h:186
\inmodule QtCore
Definition qvariant.h:65
bool isNull() const
Returns true if this is a null variant, false otherwise.
QMap< QString, QString > map
[6]
QSet< QString >::iterator it
Combined button and popup list for selecting options.
Orientation
Definition qnamespace.h:98
@ Vertical
Definition qnamespace.h:100
@ EditRole
@ DisplayRole
SortOrder
Definition qnamespace.h:121
@ AscendingOrder
Definition qnamespace.h:122
@ CaseInsensitive
@ ItemIsEditable
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
GLenum GLsizei GLsizei GLint * values
[15]
GLuint64 key
GLuint index
[2]
GLboolean r
[2]
GLenum GLenum GLsizei count
GLfloat GLfloat f
GLbitfield flags
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLuint name
GLenum GLenum GLsizei void GLsizei void * column
GLenum query
const GLubyte * c
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLenum GLenum GLsizei void * row
GLfixed GLfixed GLint GLint order
#define Q_ASSERT_X(cond, x, msg)
Definition qrandom.cpp:48
#define emit
QList< std::pair< QString, QString > > Map
QMimeDatabase db
[0]
MyRecord record(int row) const
[0]
QGraphicsItem * item
flay insertRow(2, "User:", le)