File indexing completed on 2024-04-21 05:48:59

0001 /*
0002 SPDX-FileCopyrightText: 2010 Marco Mentasti <marcomentasti@gmail.com>
0003 
0004 SPDX-License-Identifier: LGPL-2.0-only
0005 */
0006 
0007 #include "cachedsqlquerymodel.h"
0008 
0009 #include <QDebug>
0010 
0011 CachedSqlQueryModel::CachedSqlQueryModel(QObject *parent, int cacheCapacity)
0012     : QSqlQueryModel(parent)
0013     , cache(cacheCapacity)
0014 {
0015 }
0016 
0017 QVariant CachedSqlQueryModel::data(const QModelIndex &item, int role) const
0018 {
0019     if (!item.isValid()) {
0020         return QVariant();
0021     }
0022 
0023     if (role == Qt::EditRole) {
0024         return QSqlQueryModel::data(item, role);
0025     }
0026 
0027     if (role != Qt::DisplayRole) {
0028         return QVariant();
0029     }
0030 
0031     const int row = item.row();
0032 
0033     return record(row).value(item.column());
0034 }
0035 
0036 QSqlRecord CachedSqlQueryModel::record(int row) const
0037 {
0038     // if cache capacity is set to 0, don't use cache
0039     if (cacheCapacity() == 0) {
0040         return QSqlQueryModel::record(row);
0041     }
0042 
0043     const int lookAhead = cacheCapacity() / 5;
0044     const int halfLookAhead = lookAhead / 2;
0045 
0046     if (row > cache.lastIndex()) {
0047         if (row - cache.lastIndex() > lookAhead) {
0048             cacheRecords(row - halfLookAhead, qMin(rowCount(), row + halfLookAhead));
0049         } else {
0050             int until = qMin(rowCount(), cache.lastIndex() + lookAhead);
0051 
0052             while (cache.lastIndex() < until) {
0053                 cache.append(QSqlQueryModel::record(cache.lastIndex() + 1));
0054             }
0055         }
0056     } else if (row < cache.firstIndex()) {
0057         if (cache.firstIndex() - row > lookAhead) {
0058             cacheRecords(qMax(0, row - halfLookAhead), row + halfLookAhead);
0059         } else {
0060             int until = qMax(0, cache.firstIndex() - lookAhead);
0061 
0062             while (cache.firstIndex() > until) {
0063                 cache.prepend(QSqlQueryModel::record(cache.firstIndex() - 1));
0064             }
0065         }
0066     }
0067 
0068     return cache.at(row);
0069 }
0070 
0071 void CachedSqlQueryModel::clear()
0072 {
0073     clearCache();
0074 
0075     QSqlQueryModel::clear();
0076 }
0077 
0078 void CachedSqlQueryModel::cacheRecords(int from, int to) const
0079 {
0080     qDebug() << "caching records from" << from << "to" << to;
0081 
0082     for (int i = from; i <= to; ++i) {
0083         cache.insert(i, QSqlQueryModel::record(i));
0084     }
0085 }
0086 
0087 void CachedSqlQueryModel::clearCache()
0088 {
0089     cache.clear();
0090 }
0091 
0092 int CachedSqlQueryModel::cacheCapacity() const
0093 {
0094     return cache.capacity();
0095 }
0096 
0097 void CachedSqlQueryModel::setCacheCapacity(int capacity)
0098 {
0099     qDebug() << "cache capacity set to" << capacity;
0100 
0101     cache.setCapacity(capacity);
0102 }
0103 
0104 void CachedSqlQueryModel::queryChange()
0105 {
0106     clearCache();
0107 }
0108 
0109 #include "moc_cachedsqlquerymodel.cpp"