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
qsqlcachedresult.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 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 "private/qsqlcachedresult_p.h"
5
6#include <qvariant.h>
7#include <QtSql/private/qsqldriver_p.h>
8
10
11/*
12 QSqlCachedResult is a convenience class for databases that only allow
13 forward only fetching. It will cache all the results so we can iterate
14 backwards over the results again.
15
16 All you need to do is to inherit from QSqlCachedResult and reimplement
17 gotoNext(). gotoNext() will have a reference to the internal cache and
18 will give you an index where you can start filling in your data. Special
19 case: If the user actually wants a forward-only query, idx will be -1
20 to indicate that we are not interested in the actual values.
21*/
22
23static constexpr qsizetype initial_cache_size = 128;
24
26{
27 cache.clear();
28 atEnd = false;
29 colCount = 0;
30 rowCacheEnd = 0;
31}
32
34{
36 cleanup();
37 forwardOnly = fo;
39 if (fo) {
42 } else {
44 }
45}
46
48{
49 if (forwardOnly)
50 return 0;
51 int newIdx = rowCacheEnd;
52 if (newIdx + colCount > cache.size())
53 cache.resize(qMin(cache.size() * 2, cache.size() + 10000));
55
56 return newIdx;
57}
58
60{
61 if (forwardOnly || i < 0)
62 return false;
63 return rowCacheEnd >= (i + 1) * colCount;
64}
65
72
79
81
86
87void QSqlCachedResult::init(int colCount)
88{
90 d->init(colCount, isForwardOnly());
91}
92
94{
96 if ((!isActive()) || (i < 0))
97 return false;
98 if (at() == i)
99 return true;
100 if (d->forwardOnly) {
101 // speed hack - do not copy values if not needed
102 if (at() > i || at() == QSql::AfterLastRow)
103 return false;
104 while(at() < i - 1) {
105 if (!gotoNext(d->cache, -1))
106 return false;
107 setAt(at() + 1);
108 }
109 if (!gotoNext(d->cache, 0))
110 return false;
111 setAt(at() + 1);
112 return true;
113 }
114 if (d->canSeek(i)) {
115 setAt(i);
116 return true;
117 }
118 if (d->rowCacheEnd > 0)
119 setAt(d->cacheCount());
120 while (at() < i + 1) {
121 if (!cacheNext()) {
122 if (d->canSeek(i))
123 break;
124 return false;
125 }
126 }
127 setAt(i);
128
129 return true;
130}
131
133{
134 Q_D(QSqlCachedResult);
135 if (d->canSeek(at() + 1)) {
136 setAt(at() + 1);
137 return true;
138 }
139 return cacheNext();
140}
141
143{
144 return fetch(at() - 1);
145}
146
148{
149 Q_D(QSqlCachedResult);
150 if (d->forwardOnly && at() != QSql::BeforeFirstRow) {
151 return false;
152 }
153 if (d->canSeek(0)) {
154 setAt(0);
155 return true;
156 }
157 return cacheNext();
158}
159
161{
162 Q_D(QSqlCachedResult);
163 if (d->atEnd) {
164 if (d->forwardOnly)
165 return false;
166 else
167 return fetch(d->cacheCount() - 1);
168 }
169
170 int i = at();
171 while (fetchNext())
172 ++i; /* brute force */
173 if (d->forwardOnly && at() == QSql::AfterLastRow) {
174 setAt(i);
175 return true;
176 } else {
177 return fetch(i);
178 }
179}
180
182{
183 Q_D(const QSqlCachedResult);
184 int idx = d->forwardOnly ? i : at() * d->colCount + i;
185 if (i >= d->colCount || i < 0 || at() < 0 || idx >= d->rowCacheEnd)
186 return QVariant();
187
188 return d->cache.at(idx);
189}
190
192{
193 Q_D(const QSqlCachedResult);
194 int idx = d->forwardOnly ? i : at() * d->colCount + i;
195 if (i >= d->colCount || i < 0 || at() < 0 || idx >= d->rowCacheEnd)
196 return true;
197
198 return d->cache.at(idx).isNull();
199}
200
202{
203 Q_D(QSqlCachedResult);
205 setActive(false);
206 d->cleanup();
207}
208
210{
211 Q_D(QSqlCachedResult);
213 d->rowCacheEnd = 0;
214 d->atEnd = false;
215}
216
217bool QSqlCachedResult::cacheNext()
218{
219 Q_D(QSqlCachedResult);
220 if (d->atEnd)
221 return false;
222
223 if (isForwardOnly()) {
224 d->cache.resize(d->colCount);
225 }
226
227 if (!gotoNext(d->cache, d->nextIndex())) {
228 d->revertLast();
229 d->atEnd = true;
230 return false;
231 }
232 setAt(at() + 1);
233 return true;
234}
235
237{
238 Q_D(const QSqlCachedResult);
239 return d->colCount;
240}
241
247
249{
251}
252
257
263
264
qsizetype size() const noexcept
Definition qlist.h:397
void resize(qsizetype size)
Definition qlist.h:403
void clear()
Definition qlist.h:434
void init(int count, bool fo)
QSqlCachedResult::ValueCache cache
QVariant data(int i) override
Returns the data for field index in the current row as a QVariant.
bool fetchLast() override
Positions the result to the last record (last row) in the result.
bool fetchFirst() override
Positions the result to the first record (row 0) in the result.
bool fetchPrevious() override
Positions the result to the previous record (row) in the result.
void virtual_hook(int id, void *data) override
bool isNull(int i) override
Returns true if the field at position index in the current row is null; otherwise returns false.
virtual bool gotoNext(ValueCache &values, int index)=0
bool fetch(int i) override
Positions the result to an arbitrary (zero-based) row index.
QSqlCachedResult(QSqlCachedResultPrivate &d)
void init(int colCount)
bool fetchNext() override
Positions the result to the next available record (row) in the result.
void setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy policy) override
void detachFromResultSet() override
The QSqlResult class provides an abstract interface for accessing data from specific SQL databases.
Definition qsqlresult.h:22
bool isForwardOnly() const
Returns true if you can only scroll forward through the result set; otherwise returns false.
virtual void virtual_hook(int id, void *data)
virtual void setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy policy)
int at() const
Returns the current (zero-based) row position of the result.
virtual void setAt(int at)
This function is provided for derived classes to set the internal (zero-based) row position to index.
virtual void setActive(bool a)
This function is provided for derived classes to set the internal active state to active.
bool isActive() const
Returns true if the result has records to be retrieved; otherwise returns false.
\inmodule QtCore
Definition qvariant.h:65
@ AfterLastRow
Definition qtsqlglobal.h:22
@ BeforeFirstRow
Definition qtsqlglobal.h:21
NumericalPrecisionPolicy
Definition qtsqlglobal.h:43
Combined button and popup list for selecting options.
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
GLenum GLenum GLsizei count
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
static QT_BEGIN_NAMESPACE constexpr qsizetype initial_cache_size
ptrdiff_t qsizetype
Definition qtypes.h:165
QSizePolicy policy