177 QMap<
int, QString> attributeIds;
178 m_query->exec(
"SELECT DISTINCT Id, Name FROM FilterAttributeTable ORDER BY Id"_L1);
179 while (m_query->next())
180 attributeIds.insert(m_query->value(0).toInt(), m_query->value(1).toString());
184 QList<
int> usedAttributeIds;
185 for (
auto it = attributeIds.cbegin(), end = attributeIds.cend(); it != end; ++it) {
186 const int attributeId = it.key();
187 if (isAttributeUsed(m_query.get(),
"IndexFilterTable"_L1, attributeId)
188 || isAttributeUsed(m_query.get(),
"ContentsFilterTable"_L1, attributeId)
189 || isAttributeUsed(m_query.get(),
"FileFilterTable"_L1, attributeId)) {
190 usedAttributeIds.append(attributeId);
195 m_query->exec(
"SELECT * FROM pragma_table_info('IndexTable') WHERE name='ContextName'"_L1);
199 const QString identifierColumnName = legacy ?
"ContextName"_L1 :
"Identifier"_L1;
200 const int usedAttributeCount = usedAttributeIds.size();
202 QMap<
int, IndexItem> idToIndexItem;
203 m_query->exec(QString::fromLatin1(
"SELECT Name, %1, FileId, Anchor, Id "
205 "ORDER BY Id").arg(identifierColumnName));
206 while (m_query->next()) {
208 indexItem.name = m_query->value(0).toString();
209 indexItem.identifier = m_query->value(1).toString();
210 indexItem.fileId = m_query->value(2).toInt();
211 indexItem.anchor = m_query->value(3).toString();
212 const int indexId = m_query->value(4).toInt();
214 idToIndexItem.insert(indexId, indexItem);
217 QMap<
int, FileItem> idToFileItem;
218 QMap<
int,
int> originalFileIdToNewFileId;
223 "FileNameTable.FileId, "
224 "FileNameTable.Name, "
225 "FileNameTable.Title "
226 "FROM FileNameTable, FolderTable "
227 "WHERE FileNameTable.FolderId = FolderTable.Id "
228 "ORDER BY FileId"_L1);
229 while (m_query->next()) {
230 const int fileId = m_query->value(0).toInt();
232 fileItem.name = m_query->value(1).toString();
233 fileItem.title = m_query->value(2).toString();
235 idToFileItem.insert(fileId, fileItem);
236 originalFileIdToNewFileId.insert(fileId, filesCount);
240 QMap<
int, ContentsItem> idToContentsItem;
242 m_query->exec(
"SELECT Data, Id FROM ContentsTable ORDER BY Id"_L1);
243 while (m_query->next()) {
245 contentsItem.data = m_query->value(0).toByteArray();
246 const int contentsId = m_query->value(1).toInt();
248 idToContentsItem.insert(contentsId, contentsItem);
251 bool optimized =
true;
253 if (usedAttributeCount) {
262 const bool mayOptimizeIndexTable = filterDataCount(m_query.get(),
"IndexFilterTable"_L1)
263 == idToIndexItem.size() * usedAttributeCount;
264 const bool mayOptimizeFileTable = filterDataCount(m_query.get(),
"FileFilterTable"_L1)
265 == idToFileItem.size() * usedAttributeCount;
266 const bool mayOptimizeContentsTable =
267 filterDataCount(m_query.get(),
"ContentsFilterTable"_L1)
268 == idToContentsItem.size() * usedAttributeCount;
269 optimized = mayOptimizeIndexTable && mayOptimizeFileTable && mayOptimizeContentsTable;
274 "IndexFilterTable.IndexId, "
275 "FilterAttributeTable.Name "
278 "FilterAttributeTable "
280 "IndexFilterTable.FilterAttributeId = FilterAttributeTable.Id"_L1);
281 while (m_query->next()) {
282 const int indexId = m_query->value(0).toInt();
283 auto it = idToIndexItem.find(indexId);
284 if (it != idToIndexItem.end())
285 it.value().filterAttributes.append(m_query->value(1).toString());
290 "FileFilterTable.FileId, "
291 "FilterAttributeTable.Name "
294 "FilterAttributeTable "
296 "FileFilterTable.FilterAttributeId = FilterAttributeTable.Id"_L1);
297 while (m_query->next()) {
298 const int fileId = m_query->value(0).toInt();
299 auto it = idToFileItem.find(fileId);
300 if (it != idToFileItem.end())
301 it.value().filterAttributes.append(m_query->value(1).toString());
306 "ContentsFilterTable.ContentsId, "
307 "FilterAttributeTable.Name "
309 "ContentsFilterTable, "
310 "FilterAttributeTable "
312 "ContentsFilterTable.FilterAttributeId = FilterAttributeTable.Id"_L1);
313 while (m_query->next()) {
314 const int contentsId = m_query->value(0).toInt();
315 auto it = idToContentsItem.find(contentsId);
316 if (it != idToContentsItem.end())
317 it.value().filterAttributes.append(m_query->value(1).toString());
323 for (
auto it = idToIndexItem.cbegin(), end = idToIndexItem.cend(); it != end; ++it) {
324 IndexItem item = it.value();
325 item.fileId = originalFileIdToNewFileId.value(item.fileId);
326 table.indexItems.append(item);
329 table.fileItems = idToFileItem.values();
330 table.contentsItems = idToContentsItem.values();
333 for (
int attributeId : std::as_const(usedAttributeIds))
334 table.usedFilterAttributes.append(attributeIds.value(attributeId));
434QMultiMap<QString, QByteArray>
QHelpDBReader::filesData(
const QStringList &filterAttributes,
435 const QString &extensionFilter)
const
442 if (!extensionFilter.isEmpty())
443 extension =
"AND FileNameTable.Name LIKE \'%.%1\'"_L1.arg(extensionFilter);
445 if (filterAttributes.isEmpty()) {
448 "FileNameTable.Name, "
449 "FileDataTable.Data "
454 "WHERE FileDataTable.Id = FileNameTable.FileId "
455 "AND FileNameTable.FolderId = FolderTable.Id %1"_L1.arg(extension);
457 for (
int i = 0; i < filterAttributes.size(); ++i) {
459 query.append(
" INTERSECT "_L1);
462 "FileNameTable.Name, "
463 "FileDataTable.Data "
469 "FilterAttributeTable "
470 "WHERE FileDataTable.Id = FileNameTable.FileId "
471 "AND FileNameTable.FolderId = FolderTable.Id "
472 "AND FileNameTable.FileId = FileFilterTable.FileId "
473 "AND FileFilterTable.FilterAttributeId = FilterAttributeTable.Id "
474 "AND FilterAttributeTable.Name = \'%1\' %2"_L1
475 .arg(quote(filterAttributes.at(i)), extension));
478 m_query->exec(query);
479 QMultiMap<QString, QByteArray> result;
480 while (m_query->next())
481 result.insert(m_query->value(0).toString(), qUncompress(m_query->value(1).toByteArray()));