/*! Resets the model and sets the data provider to be the given \a query. Note that the query must be active and must not be isForwardOnly(). lastError() can be used to retrieve verbose information if there was an error setting the query. \sa query(), QSqlQuery::isActive(), QSqlQuery::setForwardOnly(), lastError() */ void QSqlQueryModel::setQuery(const QSqlQuery &query) { Q_D(QSqlQueryModel); QSqlRecord newRec = query.record(); bool columnsChanged = (newRec != d->rec); bool hasQuerySize = query.driver()->hasFeature(QSqlDriver::QuerySize); bool hasNewData = (newRec != QSqlRecord()) || !query.lastError().isValid(); if (d->colOffsets.size() != newRec.count() || columnsChanged) d->initColOffsets(newRec.count()); bool mustClearModel = d->bottom.isValid(); if (mustClearModel) { d->atEnd = true; beginRemoveRows(QModelIndex(), 0, qMax(d->bottom.row(), 0)); d->bottom = QModelIndex(); } d->error = QSqlError(); d->query = query; d->rec = newRec; if (mustClearModel) endRemoveRows(); d->atEnd = false; if (columnsChanged && hasNewData) reset(); if (!query.isActive() || query.isForwardOnly()) { d->atEnd = true; d->bottom = QModelIndex(); if (query.isForwardOnly()) d->error = QSqlError(QLatin1String("Forward-only queries " "cannot be used in a data model"), QString(), QSqlError::ConnectionError); else d->error = query.lastError(); return; } QModelIndex newBottom; if (hasQuerySize && d->query.size() > 0) { newBottom = createIndex(d->query.size() - 1, d->rec.count() - 1); beginInsertRows(QModelIndex(), 0, qMax(0, newBottom.row())); d->bottom = createIndex(d->query.size() - 1, columnsChanged ? 0 : d->rec.count() - 1); d->atEnd = true; endInsertRows(); } else { newBottom = createIndex(-1, d->rec.count() - 1); } d->bottom = newBottom; queryChange(); // fetchMore does the rowsInserted stuff for incremental models fetchMore(); }
bool DbFunc::execQuery(QSqlQuery& query, const QString& sql, const ArgList& args) { // Executes an existing query (in place) with the supplied SQL/args. // THIS IS THE MAIN POINT THROUGH WHICH ALL QUERIES SHOULD BE EXECUTED. query.prepare(sql); addArgs(query, args); #ifdef DEBUG_SQL_QUERY { qDebug() << "Executing:" << qUtf8Printable(sql); QDebug debug = qDebug().nospace(); debug << "... args: "; DebugFunc::debugConcisely(debug, args); } // endl on destruction #endif bool success = query.exec(); #ifdef DEBUG_QUERY_END qDebug() << "... query finished"; #endif if (!success) { qCritical() << "Query failed; error was:" << query.lastError(); } #ifdef DEBUG_SQL_RESULT if (success && query.isSelect() && !query.isForwardOnly()) { qDebug() << "Resultset preview:"; int row = 0; while (query.next()) { QDebug debug = qDebug().nospace(); QSqlRecord rec = query.record(); int ncols = rec.count(); debug << "... row " << row << ": "; for (int col = 0; col < ncols; ++col) { if (col > 0) { debug << "; "; } debug << rec.fieldName(col) << "="; DebugFunc::debugConcisely(debug, query.value(col)); } ++row; } // endl on destruction if (row == 0) { qDebug() << "<no rows>"; } query.seek(QSql::BeforeFirstRow); // the original starting position } #endif return success; // The return value is boolean (success?). // Use query.next() to iterate through a result set; see // http://doc.qt.io/qt-4.8/sql-sqlstatements.html }
QScriptValue property(const QScriptValue &object, const QScriptString &name, uint) { QSqlQuery query = qscriptvalue_cast<QSqlQuery>(object.data()); if (name == str_length) { int s = query.size(); if (s<0) { // Inefficient. if (query.last()) { return query.at()+1; } else { return 0; } } else { return s; } } else if (name == str_forwardOnly) { return query.isForwardOnly(); } return engine()->undefinedValue(); }