File indexing completed on 2024-05-05 10:11:55
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"