Q3DataBrowser::Boundary Q3DataBrowser::boundary() { Q3SqlCursor* cur = d->cur.cursor(); if (!cur || !cur->isActive()) return Unknown; if (!cur->isValid()) { if (cur->at() == QSql::BeforeFirst) return BeforeBeginning; if (cur->at() == QSql::AfterLast) return AfterEnd; return Unknown; } if (cur->at() == 0) return Beginning; int currentAt = cur->at(); Boundary b = None; if (!cur->previous()) b = Beginning; else cur->seek(currentAt); if (b == None && !cur->next()) b = End; cur->seek(currentAt); return b; }
bool Q3DataBrowser::deleteCurrent() { if (isReadOnly()) return false; QSqlRecord* buf = d->frm.record(); Q3SqlCursor* cur = d->cur.cursor(); if (!buf || !cur) return false; writeFields(); int n = cur->at(); emit beforeDelete(buf); int ar = cur->del(); if (ar) { refresh(); updateBoundary(); cursorChanged(Q3SqlCursor::Delete); if (!cur->seek(n)) last(); if (cur->isValid()) { cur->editBuffer(true); readFields(); } else { clearValues(); } return true; } else { if (!cur->isActive()) { handleError(cur->lastError()); refresh(); updateBoundary(); } } return false; }
//## possibly add sizeHint parameter bool Q3SqlCursorManager::findBuffer(const QSqlIndex& idx, int atHint) { #ifdef QT_DEBUG_DATAMANAGER qDebug("Q3SqlCursorManager::findBuffer:"); #endif Q3SqlCursor* cur = cursor(); if (!cur) return false; if (!cur->isActive()) return false; if (!idx.count()) { if (cur->at() == QSql::BeforeFirst) cur->next(); return false; } QSqlRecord* buf = cur->editBuffer(); bool indexEquals = false; #ifdef QT_DEBUG_DATAMANAGER qDebug(" Checking hint..."); #endif /* check the hint */ if (cur->seek(atHint)) indexEquals = index_matches(cur, buf, idx); if (!indexEquals) { #ifdef QT_DEBUG_DATAMANAGER qDebug(" Checking current page..."); #endif /* check current page */ int pageSize = 20; int startIdx = qMax(atHint - pageSize, 0); int endIdx = atHint + pageSize; for (int j = startIdx; j <= endIdx; ++j) { if (cur->seek(j)) { indexEquals = index_matches(cur, buf, idx); if (indexEquals) break; } } } if (!indexEquals && cur->driver()->hasFeature(QSqlDriver::QuerySize) && cur->sort().count()) { #ifdef QT_DEBUG_DATAMANAGER qDebug(" Using binary search..."); #endif // binary search based on record buffer and current sort fields int lo = 0; int hi = cur->size(); int mid; if (compare_recs(buf, cur, cur->sort()) >= 0) lo = cur->at(); while (lo != hi) { mid = lo + (hi - lo) / 2; if (!cur->seek(mid)) break; if (index_matches(cur, buf, idx)) { indexEquals = true; break; } int c = compare_recs(buf, cur, cur->sort()); if (c < 0) { hi = mid; } else if (c == 0) { // found it, but there may be duplicates int at = mid; do { mid--; if (!cur->seek(mid)) break; if (index_matches(cur, buf, idx)) { indexEquals = true; break; } } while (compare_recs(buf, cur, cur->sort()) == 0); if (!indexEquals) { mid = at; do { mid++; if (!cur->seek(mid)) break; if (index_matches(cur, buf, idx)) { indexEquals = true; break; } } while (compare_recs(buf, cur, cur->sort()) == 0); } break; } else if (c > 0) { lo = mid + 1; } } } if (!indexEquals) { #ifdef QT_DEBUG_DATAMANAGER qDebug(" Using brute search..."); #endif #ifndef QT_NO_CURSOR QApplication::setOverrideCursor(Qt::WaitCursor); #endif /* give up, use brute force */ int startIdx = 0; if (cur->at() != startIdx) { cur->seek(startIdx); } for (;;) { indexEquals = false; indexEquals = index_matches(cur, buf, idx); if (indexEquals) break; if (!cur->next()) break; } #ifndef QT_NO_CURSOR QApplication::restoreOverrideCursor(); #endif } #ifdef QT_DEBUG_DATAMANAGER qDebug(" Done, result:" + QString::number(indexEquals)); #endif return indexEquals; }