111 if (!nameSpace.startsWith(
"org.qt-project."_L1))
116 const QChar dot(u'.');
117 QString &tail = result.tail;
118 for (
int i = nameSpace.size(); i > 0; --i) {
119 const QChar c = nameSpace.at(i - 1);
120 if (c.isDigit() || c == dot)
127 if (!tail.startsWith(dot) && tail.count(dot) == 1) {
130 const int dotIndex = tail.indexOf(dot);
132 tail = tail.mid(dotIndex);
136 while (tail.startsWith(dot))
140 while (tail.endsWith(dot))
143 if (tail.size() >= 3 && tail.size() <= 5 && tail.count(dot) == 0) {
147 QStringView tail{result.tail};
148 result
.major = tail.left(1).toInt();
149 result
.minor = tail.size() == 3 ? tail.mid(1, 1).toInt() : tail.mid(1, 2).toInt();
150 result
.patch = tail.size() == 5 ? tail.right(2).toInt() : tail.right(1).toInt();
195 QMap<
int, QString> attributeIds;
196 m_query->exec(
"SELECT DISTINCT Id, Name FROM FilterAttributeTable ORDER BY Id"_L1);
197 while (m_query->next())
198 attributeIds.insert(m_query->value(0).toInt(), m_query->value(1).toString());
202 QList<
int> usedAttributeIds;
203 for (
auto it = attributeIds.cbegin(), end = attributeIds.cend(); it != end; ++it) {
204 const int attributeId = it.key();
205 if (isAttributeUsed(m_query.get(),
"IndexFilterTable"_L1, attributeId)
206 || isAttributeUsed(m_query.get(),
"ContentsFilterTable"_L1, attributeId)
207 || isAttributeUsed(m_query.get(),
"FileFilterTable"_L1, attributeId)) {
208 usedAttributeIds.append(attributeId);
213 m_query->exec(
"SELECT * FROM pragma_table_info('IndexTable') WHERE name='ContextName'"_L1);
217 const QString identifierColumnName = legacy ?
"ContextName"_L1 :
"Identifier"_L1;
218 const int usedAttributeCount = usedAttributeIds.size();
220 QMap<
int, IndexItem> idToIndexItem;
221 m_query->exec(QString::fromLatin1(
"SELECT Name, %1, FileId, Anchor, Id "
223 "ORDER BY Id").arg(identifierColumnName));
224 while (m_query->next()) {
226 indexItem.name = m_query->value(0).toString();
227 indexItem.identifier = m_query->value(1).toString();
228 indexItem.fileId = m_query->value(2).toInt();
229 indexItem.anchor = m_query->value(3).toString();
230 const int indexId = m_query->value(4).toInt();
232 idToIndexItem.insert(indexId, indexItem);
235 QMap<
int, FileItem> idToFileItem;
236 QMap<
int,
int> originalFileIdToNewFileId;
241 "FileNameTable.FileId, "
242 "FileNameTable.Name, "
243 "FileNameTable.Title "
244 "FROM FileNameTable, FolderTable "
245 "WHERE FileNameTable.FolderId = FolderTable.Id "
246 "ORDER BY FileId"_L1);
247 while (m_query->next()) {
248 const int fileId = m_query->value(0).toInt();
250 fileItem.name = m_query->value(1).toString();
251 fileItem.title = m_query->value(2).toString();
253 idToFileItem.insert(fileId, fileItem);
254 originalFileIdToNewFileId.insert(fileId, filesCount);
258 QMap<
int, ContentsItem> idToContentsItem;
260 m_query->exec(
"SELECT Data, Id FROM ContentsTable ORDER BY Id"_L1);
261 while (m_query->next()) {
263 contentsItem.data = m_query->value(0).toByteArray();
264 const int contentsId = m_query->value(1).toInt();
266 idToContentsItem.insert(contentsId, contentsItem);
269 bool optimized =
true;
271 if (usedAttributeCount) {
280 const bool mayOptimizeIndexTable = filterDataCount(m_query.get(),
"IndexFilterTable"_L1)
281 == idToIndexItem.size() * usedAttributeCount;
282 const bool mayOptimizeFileTable = filterDataCount(m_query.get(),
"FileFilterTable"_L1)
283 == idToFileItem.size() * usedAttributeCount;
284 const bool mayOptimizeContentsTable =
285 filterDataCount(m_query.get(),
"ContentsFilterTable"_L1)
286 == idToContentsItem.size() * usedAttributeCount;
287 optimized = mayOptimizeIndexTable && mayOptimizeFileTable && mayOptimizeContentsTable;
292 "IndexFilterTable.IndexId, "
293 "FilterAttributeTable.Name "
296 "FilterAttributeTable "
298 "IndexFilterTable.FilterAttributeId = FilterAttributeTable.Id"_L1);
299 while (m_query->next()) {
300 const int indexId = m_query->value(0).toInt();
301 auto it = idToIndexItem.find(indexId);
302 if (it != idToIndexItem.end())
303 it.value().filterAttributes.append(m_query->value(1).toString());
308 "FileFilterTable.FileId, "
309 "FilterAttributeTable.Name "
312 "FilterAttributeTable "
314 "FileFilterTable.FilterAttributeId = FilterAttributeTable.Id"_L1);
315 while (m_query->next()) {
316 const int fileId = m_query->value(0).toInt();
317 auto it = idToFileItem.find(fileId);
318 if (it != idToFileItem.end())
319 it.value().filterAttributes.append(m_query->value(1).toString());
324 "ContentsFilterTable.ContentsId, "
325 "FilterAttributeTable.Name "
327 "ContentsFilterTable, "
328 "FilterAttributeTable "
330 "ContentsFilterTable.FilterAttributeId = FilterAttributeTable.Id"_L1);
331 while (m_query->next()) {
332 const int contentsId = m_query->value(0).toInt();
333 auto it = idToContentsItem.find(contentsId);
334 if (it != idToContentsItem.end())
335 it.value().filterAttributes.append(m_query->value(1).toString());
341 for (
auto it = idToIndexItem.cbegin(), end = idToIndexItem.cend(); it != end; ++it) {
342 IndexItem item = it.value();
343 item.fileId = originalFileIdToNewFileId.value(item.fileId);
344 table.indexItems.append(item);
347 table.fileItems = idToFileItem.values();
348 table.contentsItems = idToContentsItem.values();
351 for (
int attributeId : std::as_const(usedAttributeIds))
352 table.usedFilterAttributes.append(attributeIds.value(attributeId));
452QMultiMap<QString, QByteArray>
QHelpDBReader::filesData(
const QStringList &filterAttributes,
453 const QString &extensionFilter)
const
460 if (!extensionFilter.isEmpty())
461 extension =
"AND FileNameTable.Name LIKE \'%.%1\'"_L1.arg(extensionFilter);
463 if (filterAttributes.isEmpty()) {
466 "FileNameTable.Name, "
467 "FileDataTable.Data "
472 "WHERE FileDataTable.Id = FileNameTable.FileId "
473 "AND FileNameTable.FolderId = FolderTable.Id %1"_L1.arg(extension);
475 for (
int i = 0; i < filterAttributes.size(); ++i) {
477 query.append(
" INTERSECT "_L1);
480 "FileNameTable.Name, "
481 "FileDataTable.Data "
487 "FilterAttributeTable "
488 "WHERE FileDataTable.Id = FileNameTable.FileId "
489 "AND FileNameTable.FolderId = FolderTable.Id "
490 "AND FileNameTable.FileId = FileFilterTable.FileId "
491 "AND FileFilterTable.FilterAttributeId = FilterAttributeTable.Id "
492 "AND FilterAttributeTable.Name = \'%1\' %2"_L1
493 .arg(quote(filterAttributes.at(i)), extension));
496 m_query->exec(query);
497 QMultiMap<QString, QByteArray> result;
498 while (m_query->next())
499 result.insert(m_query->value(0).toString(), qUncompress(m_query->value(1).toByteArray()));