summaryrefslogtreecommitdiffstats
path: root/src/sql/drivers/cache/qsqlcachedresult.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/sql/drivers/cache/qsqlcachedresult.cpp')
-rw-r--r--src/sql/drivers/cache/qsqlcachedresult.cpp259
1 files changed, 259 insertions, 0 deletions
diff --git a/src/sql/drivers/cache/qsqlcachedresult.cpp b/src/sql/drivers/cache/qsqlcachedresult.cpp
new file mode 100644
index 0000000..4891b97
--- /dev/null
+++ b/src/sql/drivers/cache/qsqlcachedresult.cpp
@@ -0,0 +1,259 @@
+/****************************************************************************
+**
+** Implementation of cached Qt SQL result classes
+**
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the Qt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.QPL
+** included in the packaging of this file. Licensees holding valid Qt
+** Commercial licenses may use this file in accordance with the Qt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "qsqlcachedresult.h"
+#include <qdatetime.h>
+
+#ifndef QT_NO_SQL
+static const uint initial_cache_size = 128;
+
+class QtSqlCachedResultPrivate
+{
+public:
+ QtSqlCachedResultPrivate();
+ bool seek(int i);
+ void init(int count, bool fo);
+ void cleanup();
+ QtSqlCachedResult::RowCache* next();
+ void revertLast();
+
+ QtSqlCachedResult::RowsetCache *cache;
+ QtSqlCachedResult::RowCache *current;
+ int rowCacheEnd;
+ int colCount;
+ bool forwardOnly;
+};
+
+QtSqlCachedResultPrivate::QtSqlCachedResultPrivate():
+ cache(0), current(0), rowCacheEnd(0), colCount(0), forwardOnly(FALSE)
+{
+}
+
+void QtSqlCachedResultPrivate::cleanup()
+{
+ if (cache) {
+ for (int i = 0; i < rowCacheEnd; ++i)
+ delete (*cache)[i];
+ delete cache;
+ cache = 0;
+ }
+ if (forwardOnly)
+ delete current;
+ current = 0;
+ forwardOnly = FALSE;
+ colCount = 0;
+ rowCacheEnd = 0;
+}
+
+void QtSqlCachedResultPrivate::init(int count, bool fo)
+{
+ cleanup();
+ forwardOnly = fo;
+ colCount = count;
+ if (fo)
+ current = new QtSqlCachedResult::RowCache(count);
+ else
+ cache = new QtSqlCachedResult::RowsetCache(initial_cache_size);
+}
+
+QtSqlCachedResult::RowCache *QtSqlCachedResultPrivate::next()
+{
+ if (forwardOnly)
+ return current;
+
+ Q_ASSERT(cache);
+ current = new QtSqlCachedResult::RowCache(colCount);
+ if (rowCacheEnd == (int)cache->size())
+ cache->resize(cache->size() * 2);
+ cache->insert(rowCacheEnd++, current);
+ return current;
+}
+
+bool QtSqlCachedResultPrivate::seek(int i)
+{
+ if (forwardOnly || i < 0)
+ return FALSE;
+ if (i >= rowCacheEnd)
+ return FALSE;
+ current = (*cache)[i];
+ return TRUE;
+}
+
+void QtSqlCachedResultPrivate::revertLast()
+{
+ if (forwardOnly)
+ return;
+ --rowCacheEnd;
+ delete current;
+ current = 0;
+}
+
+//////////////
+
+QtSqlCachedResult::QtSqlCachedResult(const QSqlDriver * db ): QSqlResult ( db )
+{
+ d = new QtSqlCachedResultPrivate();
+}
+
+QtSqlCachedResult::~QtSqlCachedResult()
+{
+ delete d;
+}
+
+void QtSqlCachedResult::init(int colCount)
+{
+ d->init(colCount, isForwardOnly());
+}
+
+bool QtSqlCachedResult::fetch(int i)
+{
+ if ((!isActive()) || (i < 0))
+ return FALSE;
+ if (at() == i)
+ return TRUE;
+ if (d->forwardOnly) {
+ // speed hack - do not copy values if not needed
+ if (at() > i || at() == QSql::AfterLast)
+ return FALSE;
+ while(at() < i - 1) {
+ if (!gotoNext(0))
+ return FALSE;
+ setAt(at() + 1);
+ }
+ if (!gotoNext(d->current))
+ return FALSE;
+ setAt(at() + 1);
+ return TRUE;
+ }
+ if (d->seek(i)) {
+ setAt(i);
+ return TRUE;
+ }
+ setAt(d->rowCacheEnd - 1);
+ while (at() < i) {
+ if (!cacheNext())
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool QtSqlCachedResult::fetchNext()
+{
+ if (d->seek(at() + 1)) {
+ setAt(at() + 1);
+ return TRUE;
+ }
+ return cacheNext();
+}
+
+bool QtSqlCachedResult::fetchPrev()
+{
+ return fetch(at() - 1);
+}
+
+bool QtSqlCachedResult::fetchFirst()
+{
+ if (d->forwardOnly && at() != QSql::BeforeFirst) {
+ return FALSE;
+ }
+ if (d->seek(0)) {
+ setAt(0);
+ return TRUE;
+ }
+ return cacheNext();
+}
+
+bool QtSqlCachedResult::fetchLast()
+{
+ if (at() == QSql::AfterLast) {
+ if (d->forwardOnly)
+ return FALSE;
+ else
+ return fetch(d->rowCacheEnd - 1);
+ }
+
+ int i = at();
+ while (fetchNext())
+ i++; /* brute force */
+ if (d->forwardOnly && at() == QSql::AfterLast) {
+ setAt(i);
+ return TRUE;
+ } else {
+ return fetch(d->rowCacheEnd - 1);
+ }
+}
+
+QVariant QtSqlCachedResult::data(int i)
+{
+ if (!d->current || i >= (int)d->current->size() || i < 0)
+ return QVariant();
+
+ return (*d->current)[i];
+}
+
+bool QtSqlCachedResult::isNull(int i)
+{
+ if (!d->current || i >= (int)d->current->size() || i < 0)
+ return TRUE;
+
+ return (*d->current)[i].isNull();
+}
+
+void QtSqlCachedResult::cleanup()
+{
+ setAt(QSql::BeforeFirst);
+ setActive(FALSE);
+ d->cleanup();
+}
+
+bool QtSqlCachedResult::cacheNext()
+{
+ if (!gotoNext(d->next())) {
+ d->revertLast();
+ return FALSE;
+ }
+ setAt(at() + 1);
+ return TRUE;
+}
+
+int QtSqlCachedResult::colCount() const
+{
+ return d->colCount;
+}
+#endif // QT_NO_SQL