models/qsqlquerymodel.cpp

Source codeSwitch to Preprocessed file
LineSource CodeCoverage
1/****************************************************************************-
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtSql module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/****************************************************************************
2** -
3** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -
4** Contact: http://www.qt-project.org/legal -
5** -
6** This file is part of the QtSql module of the Qt Toolkit. -
7** -
8** $QT_BEGIN_LICENSE:LGPL$ -
9** Commercial License Usage -
10** Licensees holding valid commercial Qt licenses may use this file in -
11** accordance with the commercial license agreement provided with the -
12** Software or, alternatively, in accordance with the terms contained in -
13** a written agreement between you and Digia. For licensing terms and -
14** conditions see http://qt.digia.com/licensing. For further information -
15** use the contact form at http://qt.digia.com/contact-us. -
16** -
17** GNU Lesser General Public License Usage -
18** Alternatively, this file may be used under the terms of the GNU Lesser -
19** General Public License version 2.1 as published by the Free Software -
20** Foundation and appearing in the file LICENSE.LGPL included in the -
21** packaging of this file. Please review the following information to -
22** ensure the GNU Lesser General Public License version 2.1 requirements -
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -
24** -
25** In addition, as a special exception, Digia gives you certain additional -
26** rights. These rights are described in the Digia Qt LGPL Exception -
27** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -
28** -
29** GNU General Public License Usage -
30** Alternatively, this file may be used under the terms of the GNU -
31** General Public License version 3.0 as published by the Free Software -
32** Foundation and appearing in the file LICENSE.GPL included in the -
33** packaging of this file. Please review the following information to -
34** ensure the GNU General Public License version 3.0 requirements will be -
35** met: http://www.gnu.org/copyleft/gpl.html. -
36** -
37** -
38** $QT_END_LICENSE$ -
39** -
40****************************************************************************/ -
41 -
42#include "qsqlquerymodel.h" -
43#include "qsqlquerymodel_p.h" -
44 -
45#include <qdebug.h> -
46#include <qsqldriver.h> -
47#include <qsqlfield.h> -
48 -
49QT_BEGIN_NAMESPACE -
50 -
51#define QSQL_PREFETCH 255 -
52 -
53void QSqlQueryModelPrivate::prefetch(int limit) -
54{ -
55 Q_Q(QSqlQueryModel); -
56 -
57 if (atEnd || limit <= bottom.row() || bottom.column() == -1) -
58 return; -
59 -
60 QModelIndex newBottom; -
61 const int oldBottomRow = qMax(bottom.row(), 0); -
62 -
63 // try to seek directly -
64 if (query.seek(limit)) { -
65 newBottom = q->createIndex(limit, bottom.column()); -
66 } else { -
67 // have to seek back to our old position for MS Access -
68 int i = oldBottomRow; -
69 if (query.seek(i)) { -
70 while (query.next()) -
71 ++i; -
72 newBottom = q->createIndex(i, bottom.column()); -
73 } else { -
74 // empty or invalid query -
75 newBottom = q->createIndex(-1, bottom.column()); -
76 } -
77 atEnd = true; // this is the end. -
78 } -
79 if (newBottom.row() >= 0 && newBottom.row() > bottom.row()) { -
80 q->beginInsertRows(QModelIndex(), bottom.row() + 1, newBottom.row()); -
81 bottom = newBottom; -
82 q->endInsertRows(); -
83 } else { -
84 bottom = newBottom; -
85 } -
86} -
87 -
88QSqlQueryModelPrivate::~QSqlQueryModelPrivate() -
89{ -
90} -
91 -
92void QSqlQueryModelPrivate::initColOffsets(int size) -
93{ -
94 colOffsets.resize(size); -
95 memset(colOffsets.data(), 0, colOffsets.size() * sizeof(int)); -
96} -
97 -
98int QSqlQueryModelPrivate::columnInQuery(int modelColumn) const -
99{ -
100 if (modelColumn < 0 || modelColumn >= rec.count() || !rec.isGenerated(modelColumn) || modelColumn >= colOffsets.size())
evaluated: modelColumn < 0
TRUEFALSE
yes
Evaluation Count:15
yes
Evaluation Count:3254
partially evaluated: modelColumn >= rec.count()
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:3254
evaluated: !rec.isGenerated(modelColumn)
TRUEFALSE
yes
Evaluation Count:12
yes
Evaluation Count:3242
partially evaluated: modelColumn >= colOffsets.size()
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:3242
0-3254
101 return -1;
executed: return -1;
Execution Count:27
27
102 return modelColumn - colOffsets[modelColumn];
executed: return modelColumn - colOffsets[modelColumn];
Execution Count:3242
3242
103} -
104 -
105/*! -
106 \class QSqlQueryModel -
107 \brief The QSqlQueryModel class provides a read-only data model for SQL -
108 result sets. -
109 -
110 \ingroup database -
111 \inmodule QtSql -
112 -
113 QSqlQueryModel is a high-level interface for executing SQL -
114 statements and traversing the result set. It is built on top of -
115 the lower-level QSqlQuery and can be used to provide data to -
116 view classes such as QTableView. For example: -
117 -
118 \snippet sqldatabase/sqldatabase.cpp 16 -
119 -
120 We set the model's query, then we set up the labels displayed in -
121 the view header. -
122 -
123 QSqlQueryModel can also be used to access a database -
124 programmatically, without binding it to a view: -
125 -
126 \snippet sqldatabase/sqldatabase.cpp 21 -
127 -
128 The code snippet above extracts the \c salary field from record 4 in -
129 the result set of the query \c{SELECT * from employee}. Assuming -
130 that \c salary is column 2, we can rewrite the last line as follows: -
131 -
132 \snippet sqldatabase/sqldatabase.cpp 22 -
133 -
134 The model is read-only by default. To make it read-write, you -
135 must subclass it and reimplement setData() and flags(). Another -
136 option is to use QSqlTableModel, which provides a read-write -
137 model based on a single database table. -
138 -
139 The \l{querymodel} example illustrates how to use -
140 QSqlQueryModel to display the result of a query. It also shows -
141 how to subclass QSqlQueryModel to customize the contents of the -
142 data before showing it to the user, and how to create a -
143 read-write model based on QSqlQueryModel. -
144 -
145 If the database doesn't return the number of selected rows in -
146 a query, the model will fetch rows incrementally. -
147 See fetchMore() for more information. -
148 -
149 \sa QSqlTableModel, QSqlRelationalTableModel, QSqlQuery, -
150 {Model/View Programming}, {Query Model Example} -
151*/ -
152 -
153/*! -
154 Creates an empty QSqlQueryModel with the given \a parent. -
155 */ -
156QSqlQueryModel::QSqlQueryModel(QObject *parent) -
157 : QAbstractTableModel(*new QSqlQueryModelPrivate, parent) -
158{ -
159} -
160 -
161/*! \internal -
162 */ -
163QSqlQueryModel::QSqlQueryModel(QSqlQueryModelPrivate &dd, QObject *parent) -
164 : QAbstractTableModel(dd, parent) -
165{ -
166} -
167 -
168/*! -
169 Destroys the object and frees any allocated resources. -
170 -
171 \sa clear() -
172*/ -
173QSqlQueryModel::~QSqlQueryModel() -
174{ -
175} -
176 -
177/*! -
178 \since 4.1 -
179 -
180 Fetches more rows from a database. -
181 This only affects databases that don't report back the size of a query -
182 (see QSqlDriver::hasFeature()). -
183 -
184 To force fetching of the entire result set, you can use the following: -
185 -
186 \snippet code/src_sql_models_qsqlquerymodel.cpp 0 -
187 -
188 \a parent should always be an invalid QModelIndex. -
189 -
190 \sa canFetchMore() -
191*/ -
192void QSqlQueryModel::fetchMore(const QModelIndex &parent) -
193{ -
194 Q_D(QSqlQueryModel); -
195 if (parent.isValid()) -
196 return; -
197 d->prefetch(qMax(d->bottom.row(), 0) + QSQL_PREFETCH); -
198} -
199 -
200/*! -
201 \since 4.1 -
202 -
203 Returns true if it is possible to read more rows from the database. -
204 This only affects databases that don't report back the size of a query -
205 (see QSqlDriver::hasFeature()). -
206 -
207 \a parent should always be an invalid QModelIndex. -
208 -
209 \sa fetchMore() -
210 */ -
211bool QSqlQueryModel::canFetchMore(const QModelIndex &parent) const -
212{ -
213 Q_D(const QSqlQueryModel); -
214 return (!parent.isValid() && !d->atEnd); -
215} -
216 -
217/*! \internal -
218 */ -
219void QSqlQueryModel::beginInsertRows(const QModelIndex &parent, int first, int last) -
220{ -
221 Q_D(QSqlQueryModel); -
222 if (!d->nestedResetLevel) -
223 QAbstractTableModel::beginInsertRows(parent, first, last); -
224} -
225 -
226/*! \internal -
227 */ -
228void QSqlQueryModel::endInsertRows() -
229{ -
230 Q_D(QSqlQueryModel); -
231 if (!d->nestedResetLevel) -
232 QAbstractTableModel::endInsertRows(); -
233} -
234 -
235/*! \internal -
236 */ -
237void QSqlQueryModel::beginRemoveRows(const QModelIndex &parent, int first, int last) -
238{ -
239 Q_D(QSqlQueryModel); -
240 if (!d->nestedResetLevel) -
241 QAbstractTableModel::beginRemoveRows(parent, first, last); -
242} -
243 -
244/*! \internal -
245 */ -
246void QSqlQueryModel::endRemoveRows() -
247{ -
248 Q_D(QSqlQueryModel); -
249 if (!d->nestedResetLevel) -
250 QAbstractTableModel::endRemoveRows(); -
251} -
252 -
253/*! \internal -
254 */ -
255void QSqlQueryModel::beginInsertColumns(const QModelIndex &parent, int first, int last) -
256{ -
257 Q_D(QSqlQueryModel); -
258 if (!d->nestedResetLevel) -
259 QAbstractTableModel::beginInsertColumns(parent, first, last); -
260} -
261 -
262/*! \internal -
263 */ -
264void QSqlQueryModel::endInsertColumns() -
265{ -
266 Q_D(QSqlQueryModel); -
267 if (!d->nestedResetLevel) -
268 QAbstractTableModel::endInsertColumns(); -
269} -
270 -
271/*! \internal -
272 */ -
273void QSqlQueryModel::beginRemoveColumns(const QModelIndex &parent, int first, int last) -
274{ -
275 Q_D(QSqlQueryModel); -
276 if (!d->nestedResetLevel) -
277 QAbstractTableModel::beginRemoveColumns(parent, first, last); -
278} -
279 -
280/*! \internal -
281 */ -
282void QSqlQueryModel::endRemoveColumns() -
283{ -
284 Q_D(QSqlQueryModel); -
285 if (!d->nestedResetLevel) -
286 QAbstractTableModel::endRemoveColumns(); -
287} -
288 -
289/*! \internal -
290 */ -
291void QSqlQueryModel::beginResetModel() -
292{ -
293 Q_D(QSqlQueryModel); -
294 if (!d->nestedResetLevel) -
295 QAbstractTableModel::beginResetModel(); -
296 ++d->nestedResetLevel; -
297} -
298 -
299/*! \internal -
300 */ -
301void QSqlQueryModel::endResetModel() -
302{ -
303 Q_D(QSqlQueryModel); -
304 --d->nestedResetLevel; -
305 if (!d->nestedResetLevel) -
306 QAbstractTableModel::endResetModel(); -
307} -
308 -
309/*! \fn int QSqlQueryModel::rowCount(const QModelIndex &parent) const -
310 \since 4.1 -
311 -
312 If the database supports returning the size of a query -
313 (see QSqlDriver::hasFeature()), the number of rows of the current -
314 query is returned. Otherwise, returns the number of rows -
315 currently cached on the client. -
316 -
317 \a parent should always be an invalid QModelIndex. -
318 -
319 \sa canFetchMore(), QSqlDriver::hasFeature() -
320 */ -
321int QSqlQueryModel::rowCount(const QModelIndex &index) const -
322{ -
323 Q_D(const QSqlQueryModel); -
324 return index.isValid() ? 0 : d->bottom.row() + 1; -
325} -
326 -
327/*! \reimp -
328 */ -
329int QSqlQueryModel::columnCount(const QModelIndex &index) const -
330{ -
331 Q_D(const QSqlQueryModel); -
332 return index.isValid() ? 0 : d->rec.count(); -
333} -
334 -
335/*! -
336 Returns the value for the specified \a item and \a role. -
337 -
338 If \a item is out of bounds or if an error occurred, an invalid -
339 QVariant is returned. -
340 -
341 \sa lastError() -
342*/ -
343QVariant QSqlQueryModel::data(const QModelIndex &item, int role) const -
344{ -
345 Q_D(const QSqlQueryModel); -
346 if (!item.isValid()) -
347 return QVariant(); -
348 -
349 QVariant v; -
350 if (role & ~(Qt::DisplayRole | Qt::EditRole)) -
351 return v; -
352 -
353 if (!d->rec.isGenerated(item.column())) -
354 return v; -
355 QModelIndex dItem = indexInQuery(item); -
356 if (dItem.row() > d->bottom.row()) -
357 const_cast<QSqlQueryModelPrivate *>(d)->prefetch(dItem.row()); -
358 -
359 if (!d->query.seek(dItem.row())) { -
360 d->error = d->query.lastError(); -
361 return v; -
362 } -
363 -
364 return d->query.value(dItem.column()); -
365} -
366 -
367/*! -
368 Returns the header data for the given \a role in the \a section -
369 of the header with the specified \a orientation. -
370*/ -
371QVariant QSqlQueryModel::headerData(int section, Qt::Orientation orientation, int role) const -
372{ -
373 Q_D(const QSqlQueryModel);
executed (the execution status of this line is deduced): const QSqlQueryModelPrivate * const d = d_func();
-
374 if (orientation == Qt::Horizontal) {
evaluated: orientation == Qt::Horizontal
TRUEFALSE
yes
Evaluation Count:32
yes
Evaluation Count:1601
32-1601
375 QVariant val = d->headers.value(section).value(role);
executed (the execution status of this line is deduced): QVariant val = d->headers.value(section).value(role);
-
376 if (role == Qt::DisplayRole && !val.isValid())
evaluated: role == Qt::DisplayRole
TRUEFALSE
yes
Evaluation Count:27
yes
Evaluation Count:5
partially evaluated: !val.isValid()
TRUEFALSE
yes
Evaluation Count:27
no
Evaluation Count:0
0-27
377 val = d->headers.value(section).value(Qt::EditRole);
executed: val = d->headers.value(section).value(Qt::EditRole);
Execution Count:27
27
378 if (val.isValid())
evaluated: val.isValid()
TRUEFALSE
yes
Evaluation Count:2
yes
Evaluation Count:30
2-30
379 return val;
executed: return val;
Execution Count:2
2
380 / See if it's an inserted column (iiq.column() != -1)4-25
QModelIndex dItem = indexInQuery(createIndex(0, section));if (role == Qt::DisplayRole && d->rec.count() > section && dItem.column()d->columnInQuery(section) != -1)
evaluated: role == Qt::DisplayRole
TRUEFALSE
yes
Evaluation Count:25
yes
Evaluation Count:5
evaluated: d->rec.count() > section
TRUEFALSE
yes
Evaluation Count:20
yes
Evaluation Count:5
evaluated: d->columnInQuery(section) != -1
TRUEFALSE
yes
Evaluation Count:16
yes
Evaluation Count:4
381 return d->rec.fieldName(section);
executed: return d->rec.fieldName(section);
Execution Count:16
16
382 }
executed: }
Execution Count:14
14
383 return QAbstractItemModel::headerData(section, orientation, role);
executed: return QAbstractItemModel::headerData(section, orientation, role);
Execution Count:1615
1615
384} -
385 -
386/*! -
387 This virtual function is called whenever the query changes. The -
388 default implementation does nothing. -
389 -
390 query() returns the new query. -
391 -
392 \sa query(), setQuery() -
393 */ -
394void QSqlQueryModel::queryChange() -
395{ -
396 // do nothing -
397} -
398 -
399/*! -
400 Resets the model and sets the data provider to be the given \a -
401 query. Note that the query must be active and must not be -
402 isForwardOnly(). -
403 -
404 lastError() can be used to retrieve verbose information if there -
405 was an error setting the query. -
406 -
407 \note Calling setQuery() will remove any inserted columns. -
408 -
409 \sa query(), QSqlQuery::isActive(), QSqlQuery::setForwardOnly(), lastError() -
410*/ -
411void QSqlQueryModel::setQuery(const QSqlQuery &query) -
412{ -
413 Q_D(QSqlQueryModel); -
414 beginResetModel(); -
415 -
416 QSqlRecord newRec = query.record(); -
417 bool columnsChanged = (newRec != d->rec); -
418 -
419 if (d->colOffsets.size() != newRec.count() || columnsChanged) -
420 d->initColOffsets(newRec.count()); -
421 -
422 d->bottom = QModelIndex(); -
423 d->error = QSqlError(); -
424 d->query = query; -
425 d->rec = newRec; -
426 d->atEnd = true; -
427 -
428 if (query.isForwardOnly()) { -
429 d->error = QSqlError(QLatin1String("Forward-only queries " -
430 "cannot be used in a data model"), -
431 QString(), QSqlError::ConnectionError); -
432 endResetModel(); -
433 return; -
434 } -
435 -
436 if (!query.isActive()) { -
437 d->error = query.lastError(); -
438 endResetModel(); -
439 return; -
440 } -
441 -
442 if (query.driver()->hasFeature(QSqlDriver::QuerySize) && d->query.size() > 0) { -
443 d->bottom = createIndex(d->query.size() - 1, d->rec.count() - 1); -
444 } else { -
445 d->bottom = createIndex(-1, d->rec.count() - 1); -
446 d->atEnd = false; -
447 } -
448 -
449 -
450 // fetchMore does the rowsInserted stuff for incremental models -
451 fetchMore(); -
452 -
453 endResetModel(); -
454 queryChange(); -
455} -
456 -
457/*! \overload -
458 -
459 Executes the query \a query for the given database connection \a -
460 db. If no database (or an invalid database) is specified, the -
461 default connection is used. -
462 -
463 lastError() can be used to retrieve verbose information if there -
464 was an error setting the query. -
465 -
466 Example: -
467 \snippet code/src_sql_models_qsqlquerymodel.cpp 1 -
468 -
469 \sa query(), queryChange(), lastError() -
470*/ -
471void QSqlQueryModel::setQuery(const QString &query, const QSqlDatabase &db) -
472{ -
473 setQuery(QSqlQuery(query, db)); -
474} -
475 -
476/*! -
477 Clears the model and releases any acquired resource. -
478*/ -
479void QSqlQueryModel::clear() -
480{ -
481 Q_D(QSqlQueryModel); -
482 d->error = QSqlError(); -
483 d->atEnd = true; -
484 d->query.clear(); -
485 d->rec.clear(); -
486 d->colOffsets.clear(); -
487 d->bottom = QModelIndex(); -
488 d->headers.clear(); -
489} -
490 -
491/*! -
492 Sets the caption for a horizontal header for the specified \a role to -
493 \a value. This is useful if the model is used to -
494 display data in a view (e.g., QTableView). -
495 -
496 Returns true if \a orientation is Qt::Horizontal and -
497 the \a section refers to a valid section; otherwise returns -
498 false. -
499 -
500 Note that this function cannot be used to modify values in the -
501 database since the model is read-only. -
502 -
503 \sa data() -
504 */ -
505bool QSqlQueryModel::setHeaderData(int section, Qt::Orientation orientation, -
506 const QVariant &value, int role) -
507{ -
508 Q_D(QSqlQueryModel); -
509 if (orientation != Qt::Horizontal || section < 0 || columnCount() <= section) -
510 return false; -
511 -
512 if (d->headers.size() <= section) -
513 d->headers.resize(qMax(section + 1, 16)); -
514 d->headers[section][role] = value; -
515 emit headerDataChanged(orientation, section, section); -
516 return true; -
517} -
518 -
519/*! -
520 Returns the QSqlQuery associated with this model. -
521 -
522 \sa setQuery() -
523*/ -
524QSqlQuery QSqlQueryModel::query() const -
525{ -
526 Q_D(const QSqlQueryModel); -
527 return d->query; -
528} -
529 -
530/*! -
531 Returns information about the last error that occurred on the -
532 database. -
533 -
534 \sa query() -
535*/ -
536QSqlError QSqlQueryModel::lastError() const -
537{ -
538 Q_D(const QSqlQueryModel); -
539 return d->error; -
540} -
541 -
542/*! -
543 Protected function which allows derived classes to set the value of -
544 the last error that occurred on the database to \a error. -
545 -
546 \sa lastError() -
547*/ -
548void QSqlQueryModel::setLastError(const QSqlError &error) -
549{ -
550 Q_D(QSqlQueryModel); -
551 d->error = error; -
552} -
553 -
554/*! -
555 Returns the record containing information about the fields of the -
556 current query. If \a row is the index of a valid row, the record -
557 will be populated with values from that row. -
558 -
559 If the model is not initialized, an empty record will be -
560 returned. -
561 -
562 \sa QSqlRecord::isEmpty() -
563*/ -
564QSqlRecord QSqlQueryModel::record(int row) const -
565{ -
566 Q_D(const QSqlQueryModel); -
567 if (row < 0) -
568 return d->rec; -
569 -
570 QSqlRecord rec = d->rec; -
571 for (int i = 0; i < rec.count(); ++i) -
572 rec.setValue(i, data(createIndex(row, i), Qt::EditRole)); -
573 return rec; -
574} -
575 -
576/*! \overload -
577 -
578 Returns an empty record containing information about the fields -
579 of the current query. -
580 -
581 If the model is not initialized, an empty record will be -
582 returned. -
583 -
584 \sa QSqlRecord::isEmpty() -
585 */ -
586QSqlRecord QSqlQueryModel::record() const -
587{ -
588 Q_D(const QSqlQueryModel); -
589 return d->rec; -
590} -
591 -
592/*! -
593 Inserts \a count columns into the model at position \a column. The -
594 \a parent parameter must always be an invalid QModelIndex, since -
595 the model does not support parent-child relationships. -
596 -
597 Returns true if \a column is within bounds; otherwise returns false. -
598 -
599 By default, inserted columns are empty. To fill them with data, -
600 reimplement data() and handle any inserted column separately: -
601 -
602 \snippet sqldatabase/sqldatabase.cpp 23 -
603 -
604 \sa removeColumns() -
605*/ -
606bool QSqlQueryModel::insertColumns(int column, int count, const QModelIndex &parent) -
607{ -
608 Q_D(QSqlQueryModel); -
609 if (count <= 0 || parent.isValid() || column < 0 || column > d->rec.count()) -
610 return false; -
611 -
612 beginInsertColumns(parent, column, column + count - 1); -
613 for (int c = 0; c < count; ++c) { -
614 QSqlField field; -
615 field.setReadOnly(true); -
616 field.setGenerated(false); -
617 d->rec.insert(column, field); -
618 if (d->colOffsets.size() < d->rec.count()) { -
619 int nVal = d->colOffsets.isEmpty() ? 0 : d->colOffsets[d->colOffsets.size() - 1]; -
620 d->colOffsets.append(nVal); -
621 Q_ASSERT(d->colOffsets.size() >= d->rec.count()); -
622 } -
623 for (int i = column + 1; i < d->colOffsets.count(); ++i) -
624 ++d->colOffsets[i]; -
625 } -
626 endInsertColumns(); -
627 return true; -
628} -
629 -
630/*! -
631 Removes \a count columns from the model starting from position \a -
632 column. The \a parent parameter must always be an invalid -
633 QModelIndex, since the model does not support parent-child -
634 relationships. -
635 -
636 Removing columns effectively hides them. It does not affect the -
637 underlying QSqlQuery. -
638 -
639 Returns true if the columns were removed; otherwise returns false. -
640 */ -
641bool QSqlQueryModel::removeColumns(int column, int count, const QModelIndex &parent) -
642{ -
643 Q_D(QSqlQueryModel); -
644 if (count <= 0 || parent.isValid() || column < 0 || column >= d->rec.count()) -
645 return false; -
646 -
647 beginRemoveColumns(parent, column, column + count - 1); -
648 -
649 int i; -
650 for (i = 0; i < count; ++i) -
651 d->rec.remove(column); -
652 for (i = column; i < d->colOffsets.count(); ++i) -
653 d->colOffsets[i] -= count; -
654 -
655 endRemoveColumns(); -
656 return true; -
657} -
658 -
659/*! -
660 Returns the index of the value in the database result set for the -
661 given \a item in the model. -
662 -
663 The return value is identical to \a item if no columns or rows -
664 have been inserted, removed, or moved around. -
665 -
666 Returns an invalid model index if \a item is out of bounds or if -
667 \a item does not point to a value in the result set. -
668 -
669 \sa QSqlTableModel::indexInQuery(), insertColumns(), removeColumns() -
670*/ -
671QModelIndex QSqlQueryModel::indexInQuery(const QModelIndex &item) const -
672{ -
673 Q_D(const QSqlQueryModel);
executed (the execution status of this line is deduced): const QSqlQueryModelPrivate * const d = d_func();
-
674 if (item.column() < 0 || item.column() >= d->rec.count()-
|| !int modelColumn = d->rec.isGeneratedcolumnInQuery(item.column())
||item.column() >= d->colOffsets.size())());
executed (the execution status of this line is deduced): int modelColumn = d->columnInQuery(item.column());
675 if (modelColumn < 0)
evaluated: modelColumn < 0
TRUEFALSE
yes
Evaluation Count:23
yes
Evaluation Count:3226
23-3226
676 return QModelIndex();
executed: return QModelIndex();
Execution Count:23
23
677 return createIndex(item.row(), item.column() - d->colOffsets[item.column()],modelColumn, item.internalPointer());
executed: return createIndex(item.row(), modelColumn, item.internalPointer());
Execution Count:3226
3226
678} -
679 -
680QT_END_NAMESPACE -
681 -
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial