|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the Qt Assistant of the Qt Toolkit. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 #include "qhelpdbreader_p.h" |
|
43 #include "qhelp_global.h" |
|
44 |
|
45 #include <QtCore/QVariant> |
|
46 #include <QtCore/QFile> |
|
47 #include <QtSql/QSqlError> |
|
48 #include <QtSql/QSqlQuery> |
|
49 |
|
50 QT_BEGIN_NAMESPACE |
|
51 |
|
52 QHelpDBReader::QHelpDBReader(const QString &dbName) |
|
53 : QObject(0) |
|
54 { |
|
55 initObject(dbName, |
|
56 QHelpGlobal::uniquifyConnectionName(QLatin1String("QHelpDBReader"), |
|
57 this)); |
|
58 } |
|
59 |
|
60 QHelpDBReader::QHelpDBReader(const QString &dbName, const QString &uniqueId, |
|
61 QObject *parent) |
|
62 : QObject(parent) |
|
63 { |
|
64 initObject(dbName, uniqueId); |
|
65 } |
|
66 |
|
67 void QHelpDBReader::initObject(const QString &dbName, const QString &uniqueId) |
|
68 { |
|
69 m_dbName = dbName; |
|
70 m_uniqueId = uniqueId; |
|
71 m_initDone = false; |
|
72 m_query = 0; |
|
73 m_useAttributesCache = false; |
|
74 } |
|
75 |
|
76 QHelpDBReader::~QHelpDBReader() |
|
77 { |
|
78 if (m_initDone) { |
|
79 delete m_query; |
|
80 QSqlDatabase::removeDatabase(m_uniqueId); |
|
81 } |
|
82 } |
|
83 |
|
84 bool QHelpDBReader::init() |
|
85 { |
|
86 if (m_initDone) |
|
87 return true; |
|
88 |
|
89 if (!QFile::exists(m_dbName)) |
|
90 return false; |
|
91 |
|
92 QSqlDatabase db = QSqlDatabase::addDatabase(QLatin1String("QSQLITE"), m_uniqueId); |
|
93 db.setDatabaseName(m_dbName); |
|
94 if (!db.open()) { |
|
95 /*: The placeholders are: %1 - The name of the database which cannot be opened |
|
96 %2 - The unique id for the connection |
|
97 %3 - The actual error string */ |
|
98 m_error = tr("Cannot open database '%1' '%2': %3").arg(m_dbName, m_uniqueId, db.lastError().text()); |
|
99 QSqlDatabase::removeDatabase(m_uniqueId); |
|
100 return false; |
|
101 } |
|
102 |
|
103 m_initDone = true; |
|
104 m_query = new QSqlQuery(db); |
|
105 |
|
106 return true; |
|
107 } |
|
108 |
|
109 QString QHelpDBReader::databaseName() const |
|
110 { |
|
111 return m_dbName; |
|
112 } |
|
113 |
|
114 QString QHelpDBReader::errorMessage() const |
|
115 { |
|
116 return m_error; |
|
117 } |
|
118 |
|
119 QString QHelpDBReader::namespaceName() const |
|
120 { |
|
121 if (!m_namespace.isEmpty()) |
|
122 return m_namespace; |
|
123 if (m_query) { |
|
124 m_query->exec(QLatin1String("SELECT Name FROM NamespaceTable")); |
|
125 if (m_query->next()) |
|
126 m_namespace = m_query->value(0).toString(); |
|
127 } |
|
128 return m_namespace; |
|
129 } |
|
130 |
|
131 QString QHelpDBReader::virtualFolder() const |
|
132 { |
|
133 if (m_query) { |
|
134 m_query->exec(QLatin1String("SELECT Name FROM FolderTable WHERE Id=1")); |
|
135 if (m_query->next()) |
|
136 return m_query->value(0).toString(); |
|
137 } |
|
138 return QString(); |
|
139 } |
|
140 |
|
141 QList<QStringList> QHelpDBReader::filterAttributeSets() const |
|
142 { |
|
143 QList<QStringList> result; |
|
144 if (m_query) { |
|
145 m_query->exec(QLatin1String("SELECT a.Id, b.Name FROM FileAttributeSetTable a, " |
|
146 "FilterAttributeTable b WHERE a.FilterAttributeId=b.Id ORDER BY a.Id")); |
|
147 int oldId = -1; |
|
148 while (m_query->next()) { |
|
149 int id = m_query->value(0).toInt(); |
|
150 if (id != oldId) { |
|
151 result.append(QStringList()); |
|
152 oldId = id; |
|
153 } |
|
154 result.last().append(m_query->value(1).toString()); |
|
155 } |
|
156 } |
|
157 return result; |
|
158 } |
|
159 |
|
160 bool QHelpDBReader::fileExists(const QString &virtualFolder, |
|
161 const QString &filePath, |
|
162 const QStringList &filterAttributes) const |
|
163 { |
|
164 if (virtualFolder.isEmpty() || filePath.isEmpty() || !m_query) |
|
165 return false; |
|
166 |
|
167 //SELECT COUNT(a.Name) FROM FileNameTable a, FolderTable b, FileFilterTable c, FilterAttributeTable d WHERE a.FolderId=b.Id AND b.Name='qtdoc' AND a.Name='qstring.html' AND a.FileId=c.FileId AND c.FilterAttributeId=d.Id AND d.Name='qtrefdoc' |
|
168 |
|
169 QString query; |
|
170 namespaceName(); |
|
171 if (filterAttributes.isEmpty()) { |
|
172 query = QString(QLatin1String("SELECT COUNT(a.Name) FROM FileNameTable a, FolderTable b " |
|
173 "WHERE a.FolderId=b.Id AND b.Name=\'%1\' AND a.Name=\'%2\'")).arg(quote(virtualFolder)).arg(quote(filePath)); |
|
174 } else { |
|
175 query = QString(QLatin1String("SELECT COUNT(a.Name) FROM FileNameTable a, FolderTable b, " |
|
176 "FileFilterTable c, FilterAttributeTable d WHERE a.FolderId=b.Id " |
|
177 "AND b.Name=\'%1\' AND a.Name=\'%2\' AND a.FileId=c.FileId AND " |
|
178 "c.FilterAttributeId=d.Id AND d.Name=\'%3\'")) |
|
179 .arg(quote(virtualFolder)).arg(quote(filePath)) |
|
180 .arg(quote(filterAttributes.first())); |
|
181 for (int i=1; i<filterAttributes.count(); ++i) { |
|
182 query.append(QString(QLatin1String(" INTERSECT SELECT COUNT(a.Name) FROM FileNameTable a, " |
|
183 "FolderTable b, FileFilterTable c, FilterAttributeTable d WHERE a.FolderId=b.Id " |
|
184 "AND b.Name=\'%1\' AND a.Name=\'%2\' AND a.FileId=c.FileId AND " |
|
185 "c.FilterAttributeId=d.Id AND d.Name=\'%3\'")) |
|
186 .arg(quote(virtualFolder)).arg(quote(filePath)) |
|
187 .arg(quote(filterAttributes.at(i)))); |
|
188 } |
|
189 } |
|
190 m_query->exec(query); |
|
191 if (m_query->next() && m_query->isValid() && m_query->value(0).toInt()) |
|
192 return true; |
|
193 return false; |
|
194 } |
|
195 |
|
196 QByteArray QHelpDBReader::fileData(const QString &virtualFolder, |
|
197 const QString &filePath) const |
|
198 { |
|
199 QByteArray ba; |
|
200 if (virtualFolder.isEmpty() || filePath.isEmpty() || !m_query) |
|
201 return ba; |
|
202 |
|
203 namespaceName(); |
|
204 m_query->prepare(QLatin1String("SELECT a.Data FROM FileDataTable a, FileNameTable b, FolderTable c, " |
|
205 "NamespaceTable d WHERE a.Id=b.FileId AND (b.Name=? OR b.Name=?) AND b.FolderId=c.Id " |
|
206 "AND c.Name=? AND c.NamespaceId=d.Id AND d.Name=?")); |
|
207 m_query->bindValue(0, filePath); |
|
208 m_query->bindValue(1, QLatin1String("./") + filePath); |
|
209 m_query->bindValue(2, virtualFolder); |
|
210 m_query->bindValue(3, m_namespace); |
|
211 m_query->exec(); |
|
212 if (m_query->next() && m_query->isValid()) |
|
213 ba = qUncompress(m_query->value(0).toByteArray()); |
|
214 return ba; |
|
215 } |
|
216 |
|
217 QStringList QHelpDBReader::customFilters() const |
|
218 { |
|
219 QStringList lst; |
|
220 if (m_query) { |
|
221 m_query->exec(QLatin1String("SELECT Name FROM FilterNameTable")); |
|
222 while (m_query->next()) |
|
223 lst.append(m_query->value(0).toString()); |
|
224 } |
|
225 return lst; |
|
226 } |
|
227 |
|
228 QStringList QHelpDBReader::filterAttributes(const QString &filterName) const |
|
229 { |
|
230 QStringList lst; |
|
231 if (m_query) { |
|
232 if (filterName.isEmpty()) { |
|
233 m_query->prepare(QLatin1String("SELECT Name FROM FilterAttributeTable")); |
|
234 } else { |
|
235 m_query->prepare(QLatin1String("SELECT a.Name FROM FilterAttributeTable a, " |
|
236 "FilterTable b, FilterNameTable c WHERE c.Name=? " |
|
237 "AND c.Id=b.NameId AND b.FilterAttributeId=a.Id")); |
|
238 m_query->bindValue(0, filterName); |
|
239 } |
|
240 m_query->exec(); |
|
241 while (m_query->next()) |
|
242 lst.append(m_query->value(0).toString()); |
|
243 } |
|
244 return lst; |
|
245 } |
|
246 |
|
247 QStringList QHelpDBReader::indicesForFilter(const QStringList &filterAttributes) const |
|
248 { |
|
249 QStringList indices; |
|
250 if (!m_query) |
|
251 return indices; |
|
252 |
|
253 //SELECT DISTINCT a.Name FROM IndexTable a, IndexFilterTable b, FilterAttributeTable c WHERE a.Id=b.IndexId AND b.FilterAttributeId=c.Id AND c.Name in ('4.2.3', 'qt') |
|
254 |
|
255 QString query; |
|
256 if (filterAttributes.isEmpty()) { |
|
257 query = QLatin1String("SELECT DISTINCT Name FROM IndexTable"); |
|
258 } else { |
|
259 query = QString(QLatin1String("SELECT DISTINCT a.Name FROM IndexTable a, " |
|
260 "IndexFilterTable b, FilterAttributeTable c WHERE a.Id=b.IndexId " |
|
261 "AND b.FilterAttributeId=c.Id AND c.Name='%1'")).arg(quote(filterAttributes.first())); |
|
262 for (int i=1; i<filterAttributes.count(); ++i) { |
|
263 query.append(QString(QLatin1String(" INTERSECT SELECT DISTINCT a.Name FROM IndexTable a, " |
|
264 "IndexFilterTable b, FilterAttributeTable c WHERE a.Id=b.IndexId " |
|
265 "AND b.FilterAttributeId=c.Id AND c.Name='%1'")) |
|
266 .arg(quote(filterAttributes.at(i)))); |
|
267 } |
|
268 } |
|
269 |
|
270 m_query->exec(query); |
|
271 while (m_query->next()) { |
|
272 if (!m_query->value(0).toString().isEmpty()) |
|
273 indices.append(m_query->value(0).toString()); |
|
274 } |
|
275 return indices; |
|
276 } |
|
277 |
|
278 void QHelpDBReader::linksForKeyword(const QString &keyword, const QStringList &filterAttributes, |
|
279 QMap<QString, QUrl> &linkMap) const |
|
280 { |
|
281 if (!m_query) |
|
282 return; |
|
283 |
|
284 QString query; |
|
285 if (filterAttributes.isEmpty()) { |
|
286 query = QString(QLatin1String("SELECT d.Title, f.Name, e.Name, d.Name, a.Anchor " |
|
287 "FROM IndexTable a, FileNameTable d, " |
|
288 "FolderTable e, NamespaceTable f WHERE " |
|
289 "a.FileId=d.FileId AND d.FolderId=e.Id AND a.NamespaceId=f.Id " |
|
290 "AND a.Name='%1'")).arg(quote(keyword)); |
|
291 } else if (m_useAttributesCache) { |
|
292 query = QString(QLatin1String("SELECT d.Title, f.Name, e.Name, d.Name, a.Anchor, a.Id " |
|
293 "FROM IndexTable a, " |
|
294 "FileNameTable d, FolderTable e, NamespaceTable f WHERE " |
|
295 "a.FileId=d.FileId AND d.FolderId=e.Id " |
|
296 "AND a.NamespaceId=f.Id AND a.Name='%1'")) |
|
297 .arg(quote(keyword)); |
|
298 m_query->exec(query); |
|
299 while (m_query->next()) { |
|
300 if (m_indicesCache.contains(m_query->value(5).toInt())) { |
|
301 linkMap.insertMulti(m_query->value(0).toString(), buildQUrl(m_query->value(1).toString(), |
|
302 m_query->value(2).toString(), m_query->value(3).toString(), |
|
303 m_query->value(4).toString())); |
|
304 } |
|
305 } |
|
306 return; |
|
307 } else { |
|
308 query = QString(QLatin1String("SELECT d.Title, f.Name, e.Name, d.Name, a.Anchor " |
|
309 "FROM IndexTable a, IndexFilterTable b, FilterAttributeTable c, " |
|
310 "FileNameTable d, FolderTable e, NamespaceTable f " |
|
311 "WHERE a.FileId=d.FileId AND d.FolderId=e.Id " |
|
312 "AND a.NamespaceId=f.Id AND b.IndexId=a.Id AND b.FilterAttributeId=c.Id " |
|
313 "AND a.Name='%1' AND c.Name='%2'")).arg(quote(keyword)) |
|
314 .arg(quote(filterAttributes.first())); |
|
315 for (int i=1; i<filterAttributes.count(); ++i) { |
|
316 query.append(QString(QLatin1String(" INTERSECT SELECT d.Title, f.Name, e.Name, d.Name, a.Anchor " |
|
317 "FROM IndexTable a, IndexFilterTable b, FilterAttributeTable c, " |
|
318 "FileNameTable d, FolderTable e, NamespaceTable f " |
|
319 "WHERE a.FileId=d.FileId AND d.FolderId=e.Id " |
|
320 "AND a.NamespaceId=f.Id AND b.IndexId=a.Id AND b.FilterAttributeId=c.Id " |
|
321 "AND a.Name='%1' AND c.Name='%2'")).arg(quote(keyword)) |
|
322 .arg(quote(filterAttributes.at(i)))); |
|
323 } |
|
324 } |
|
325 |
|
326 QString title; |
|
327 m_query->exec(query); |
|
328 while (m_query->next()) { |
|
329 title = m_query->value(0).toString(); |
|
330 if (title.isEmpty()) // generate a title + corresponding path |
|
331 title = keyword + QLatin1String(" : ") + m_query->value(3).toString(); |
|
332 linkMap.insertMulti(title, buildQUrl(m_query->value(1).toString(), |
|
333 m_query->value(2).toString(), m_query->value(3).toString(), |
|
334 m_query->value(4).toString())); |
|
335 } |
|
336 } |
|
337 |
|
338 void QHelpDBReader::linksForIdentifier(const QString &id, |
|
339 const QStringList &filterAttributes, |
|
340 QMap<QString, QUrl> &linkMap) const |
|
341 { |
|
342 if (!m_query) |
|
343 return; |
|
344 |
|
345 QString query; |
|
346 if (filterAttributes.isEmpty()) { |
|
347 query = QString(QLatin1String("SELECT d.Title, f.Name, e.Name, d.Name, a.Anchor " |
|
348 "FROM IndexTable a, FileNameTable d, FolderTable e, " |
|
349 "NamespaceTable f WHERE a.FileId=d.FileId AND " |
|
350 "d.FolderId=e.Id AND a.NamespaceId=f.Id AND a.Identifier='%1'")) |
|
351 .arg(quote(id)); |
|
352 } else if (m_useAttributesCache) { |
|
353 query = QString(QLatin1String("SELECT d.Title, f.Name, e.Name, d.Name, a.Anchor, a.Id " |
|
354 "FROM IndexTable a," |
|
355 "FileNameTable d, FolderTable e, NamespaceTable f WHERE " |
|
356 "a.FileId=d.FileId AND d.FolderId=e.Id " |
|
357 "AND a.NamespaceId=f.Id AND a.Identifier='%1'")) |
|
358 .arg(quote(id)); |
|
359 m_query->exec(query); |
|
360 while (m_query->next()) { |
|
361 if (m_indicesCache.contains(m_query->value(5).toInt())) { |
|
362 linkMap.insertMulti(m_query->value(0).toString(), buildQUrl(m_query->value(1).toString(), |
|
363 m_query->value(2).toString(), m_query->value(3).toString(), |
|
364 m_query->value(4).toString())); |
|
365 } |
|
366 } |
|
367 return; |
|
368 } else { |
|
369 query = QString(QLatin1String("SELECT d.Title, f.Name, e.Name, d.Name, a.Anchor " |
|
370 "FROM IndexTable a, IndexFilterTable b, FilterAttributeTable c, " |
|
371 "FileNameTable d, FolderTable e, NamespaceTable f " |
|
372 "WHERE a.FileId=d.FileId AND d.FolderId=e.Id " |
|
373 "AND a.NamespaceId=f.Id AND b.IndexId=a.Id AND b.FilterAttributeId=c.Id " |
|
374 "AND a.Identifier='%1' AND c.Name='%2'")).arg(quote(id)) |
|
375 .arg(quote(filterAttributes.first())); |
|
376 for (int i=0; i<filterAttributes.count(); ++i) { |
|
377 query.append(QString(QLatin1String(" INTERSECT SELECT d.Title, f.Name, e.Name, " |
|
378 "d.Name, a.Anchor FROM IndexTable a, IndexFilterTable b, " |
|
379 "FilterAttributeTable c, FileNameTable d, " |
|
380 "FolderTable e, NamespaceTable f WHERE " |
|
381 "a.FileId=d.FileId AND d.FolderId=e.Id AND a.NamespaceId=f.Id " |
|
382 "AND b.IndexId=a.Id AND b.FilterAttributeId=c.Id AND " |
|
383 "a.Identifier='%1' AND c.Name='%2'")).arg(quote(id)) |
|
384 .arg(quote(filterAttributes.at(i)))); |
|
385 } |
|
386 } |
|
387 |
|
388 m_query->exec(query); |
|
389 while (m_query->next()) { |
|
390 linkMap.insertMulti(m_query->value(0).toString(), buildQUrl(m_query->value(1).toString(), |
|
391 m_query->value(2).toString(), m_query->value(3).toString(), |
|
392 m_query->value(4).toString())); |
|
393 } |
|
394 } |
|
395 |
|
396 QUrl QHelpDBReader::buildQUrl(const QString &ns, const QString &folder, |
|
397 const QString &relFileName, const QString &anchor) const |
|
398 { |
|
399 QUrl url; |
|
400 url.setScheme(QLatin1String("qthelp")); |
|
401 url.setAuthority(ns); |
|
402 url.setPath(folder + QLatin1Char('/') + relFileName); |
|
403 url.setFragment(anchor); |
|
404 return url; |
|
405 } |
|
406 |
|
407 QList<QByteArray> QHelpDBReader::contentsForFilter(const QStringList &filterAttributes) const |
|
408 { |
|
409 QList<QByteArray> contents; |
|
410 if (!m_query) |
|
411 return contents; |
|
412 |
|
413 //SELECT DISTINCT a.Data FROM ContentsTable a, ContentsFilterTable b, FilterAttributeTable c WHERE a.Id=b.ContentsId AND b.FilterAttributeId=c.Id AND c.Name='qt' INTERSECT SELECT DISTINCT a.Data FROM ContentsTable a, ContentsFilterTable b, FilterAttributeTable c WHERE a.Id=b.ContentsId AND b.FilterAttributeId=c.Id AND c.Name='3.3.8'; |
|
414 |
|
415 QString query; |
|
416 if (filterAttributes.isEmpty()) { |
|
417 query = QLatin1String("SELECT Data from ContentsTable"); |
|
418 } else { |
|
419 query = QString(QLatin1String("SELECT a.Data FROM ContentsTable a, " |
|
420 "ContentsFilterTable b, FilterAttributeTable c " |
|
421 "WHERE a.Id=b.ContentsId AND b.FilterAttributeId=c.Id " |
|
422 "AND c.Name='%1'")).arg(quote(filterAttributes.first())); |
|
423 for (int i=1; i<filterAttributes.count(); ++i) { |
|
424 query.append(QString(QLatin1String(" INTERSECT SELECT a.Data FROM ContentsTable a, " |
|
425 "ContentsFilterTable b, FilterAttributeTable c " |
|
426 "WHERE a.Id=b.ContentsId AND b.FilterAttributeId=c.Id " |
|
427 "AND c.Name='%1'")).arg(quote(filterAttributes.at(i)))); |
|
428 } |
|
429 } |
|
430 |
|
431 m_query->exec(query); |
|
432 while (m_query->next()) { |
|
433 contents.append(m_query->value(0).toByteArray()); |
|
434 } |
|
435 return contents; |
|
436 } |
|
437 |
|
438 QUrl QHelpDBReader::urlOfPath(const QString &relativePath) const |
|
439 { |
|
440 QUrl url; |
|
441 if (!m_query) |
|
442 return url; |
|
443 |
|
444 m_query->exec(QLatin1String("SELECT a.Name, b.Name FROM NamespaceTable a, " |
|
445 "FolderTable b WHERE a.id=b.NamespaceId and a.Id=1")); |
|
446 if (m_query->next()) { |
|
447 QString rp = relativePath; |
|
448 QString anchor; |
|
449 int i = rp.indexOf(QLatin1Char('#')); |
|
450 if (i > -1) { |
|
451 rp = relativePath.left(i); |
|
452 anchor = relativePath.mid(i+1); |
|
453 } |
|
454 url = buildQUrl(m_query->value(0).toString(), |
|
455 m_query->value(1).toString(), rp, anchor); |
|
456 } |
|
457 return url; |
|
458 } |
|
459 |
|
460 QStringList QHelpDBReader::files(const QStringList &filterAttributes, |
|
461 const QString &extensionFilter) const |
|
462 { |
|
463 QStringList lst; |
|
464 if (!m_query) |
|
465 return lst; |
|
466 |
|
467 QString query; |
|
468 QString extension; |
|
469 if (!extensionFilter.isEmpty()) |
|
470 extension = QString(QLatin1String("AND b.Name like \'%.%1\'")).arg(extensionFilter); |
|
471 |
|
472 if (filterAttributes.isEmpty()) { |
|
473 query = QString(QLatin1String("SELECT a.Name, b.Name FROM FolderTable a, " |
|
474 "FileNameTable b WHERE b.FolderId=a.Id %1")) |
|
475 .arg(extension); |
|
476 } else { |
|
477 query = QString(QLatin1String("SELECT a.Name, b.Name FROM FolderTable a, " |
|
478 "FileNameTable b, FileFilterTable c, FilterAttributeTable d " |
|
479 "WHERE b.FolderId=a.Id AND b.FileId=c.FileId " |
|
480 "AND c.FilterAttributeId=d.Id AND d.Name=\'%1\' %2")) |
|
481 .arg(quote(filterAttributes.first())).arg(extension); |
|
482 for (int i=1; i<filterAttributes.count(); ++i) { |
|
483 query.append(QString(QLatin1String(" INTERSECT SELECT a.Name, b.Name FROM " |
|
484 "FolderTable a, FileNameTable b, FileFilterTable c, " |
|
485 "FilterAttributeTable d WHERE b.FolderId=a.Id AND " |
|
486 "b.FileId=c.FileId AND c.FilterAttributeId=d.Id AND " |
|
487 "d.Name=\'%1\' %2")).arg(quote(filterAttributes.at(i))) |
|
488 .arg(extension)); |
|
489 } |
|
490 } |
|
491 m_query->exec(query); |
|
492 while (m_query->next()) { |
|
493 lst.append(m_query->value(0).toString() + QLatin1Char('/') |
|
494 + m_query->value(1).toString()); |
|
495 } |
|
496 |
|
497 return lst; |
|
498 } |
|
499 |
|
500 QVariant QHelpDBReader::metaData(const QString &name) const |
|
501 { |
|
502 QVariant v; |
|
503 if (!m_query) |
|
504 return v; |
|
505 |
|
506 m_query->prepare(QLatin1String("SELECT COUNT(Value), Value FROM MetaDataTable " |
|
507 "WHERE Name=?")); |
|
508 m_query->bindValue(0, name); |
|
509 if (m_query->exec() && m_query->next() |
|
510 && m_query->value(0).toInt() == 1) |
|
511 v = m_query->value(1); |
|
512 return v; |
|
513 } |
|
514 |
|
515 QString QHelpDBReader::mergeList(const QStringList &list) const |
|
516 { |
|
517 QString str; |
|
518 foreach (QString s, list) |
|
519 str.append(QLatin1Char('\'') + quote(s) + QLatin1String("\', ")); |
|
520 if (str.endsWith(QLatin1String(", "))) |
|
521 str = str.left(str.length()-2); |
|
522 return str; |
|
523 } |
|
524 |
|
525 QString QHelpDBReader::quote(const QString &string) const |
|
526 { |
|
527 QString s = string; |
|
528 s.replace(QLatin1Char('\''), QLatin1String("\'\'")); |
|
529 return s; |
|
530 } |
|
531 |
|
532 QSet<int> QHelpDBReader::indexIds(const QStringList &attributes) const |
|
533 { |
|
534 QSet<int> ids; |
|
535 |
|
536 if (attributes.isEmpty()) |
|
537 return ids; |
|
538 |
|
539 QString query = QString(QLatin1String("SELECT a.IndexId FROM IndexFilterTable a, " |
|
540 "FilterAttributeTable b WHERE a.FilterAttributeId=b.Id " |
|
541 "AND b.Name='%1'")).arg(attributes.first()); |
|
542 for (int i=0; i<attributes.count(); ++i) { |
|
543 query.append(QString(QLatin1String(" INTERSECT SELECT a.IndexId FROM " |
|
544 "IndexFilterTable a, FilterAttributeTable b WHERE " |
|
545 "a.FilterAttributeId=b.Id AND b.Name='%1'")) |
|
546 .arg(attributes.at(i))); |
|
547 } |
|
548 |
|
549 if (!m_query->exec(query)) |
|
550 return ids; |
|
551 |
|
552 while (m_query->next()) |
|
553 ids.insert(m_query->value(0).toInt()); |
|
554 |
|
555 return ids; |
|
556 } |
|
557 |
|
558 bool QHelpDBReader::createAttributesCache(const QStringList &attributes, |
|
559 const QSet<int> &indexIds) |
|
560 { |
|
561 m_useAttributesCache = false; |
|
562 |
|
563 if (attributes.count() < 2) { |
|
564 m_viewAttributes.clear(); |
|
565 return true; |
|
566 } |
|
567 |
|
568 bool needUpdate = !m_viewAttributes.count(); |
|
569 |
|
570 foreach (QString s, attributes) |
|
571 m_viewAttributes.remove(s); |
|
572 |
|
573 if (m_viewAttributes.count() || needUpdate) { |
|
574 m_viewAttributes.clear(); |
|
575 m_indicesCache = indexIds; |
|
576 } |
|
577 foreach (QString s, attributes) |
|
578 m_viewAttributes.insert(s); |
|
579 m_useAttributesCache = true; |
|
580 return true; |
|
581 } |
|
582 |
|
583 QT_END_NAMESPACE |