1 | /* |
2 | This file is part of the KDE libraries |
3 | SPDX-FileCopyrightText: 1999-2000 Waldo Bastian <bastian@kde.org> |
4 | SPDX-FileCopyrightText: 2005-2009 David Faure <faure@kde.org> |
5 | SPDX-FileCopyrightText: 2008 Hamish Rodda <rodda@kde.org> |
6 | SPDX-FileCopyrightText: 2020 Harald Sitter <sitter@kde.org> |
7 | |
8 | SPDX-License-Identifier: LGPL-2.0-only |
9 | */ |
10 | |
11 | #ifndef KSYCOCA_P_H |
12 | #define KSYCOCA_P_H |
13 | |
14 | #include "ksycocafactory_p.h" |
15 | #include <KDirWatch> |
16 | #include <QDateTime> |
17 | #include <QElapsedTimer> |
18 | #include <QStringList> |
19 | |
20 | #include <memory> |
21 | |
22 | class QFile; |
23 | class QDataStream; |
24 | class KSycocaAbstractDevice; |
25 | class KMimeTypeFactory; |
26 | class KServiceFactory; |
27 | class KServiceGroupFactory; |
28 | |
29 | // This is for the part of the global header that we don't need to store, |
30 | // i.e. it's just a struct for returning temp data from readSycocaHeader(). |
31 | struct { |
32 | () |
33 | : timeStamp(0) |
34 | , updateSignature(0) |
35 | { |
36 | } |
37 | QString ; |
38 | QString ; |
39 | qint64 ; // in ms |
40 | quint32 ; |
41 | }; |
42 | |
43 | QDataStream &(QDataStream &in, KSycocaHeader &h); |
44 | |
45 | /** |
46 | * \internal |
47 | * Exported for unittests |
48 | */ |
49 | class KSERVICE_EXPORT KSycocaPrivate |
50 | { |
51 | public: |
52 | explicit KSycocaPrivate(KSycoca *qq); |
53 | |
54 | // per-thread "singleton" |
55 | static KSycocaPrivate *self() |
56 | { |
57 | return KSycoca::self()->d; |
58 | } |
59 | |
60 | bool checkVersion(); |
61 | bool openDatabase(); |
62 | enum BehaviorIfNotFound { |
63 | IfNotFoundDoNothing = 0, |
64 | IfNotFoundRecreate = 1, |
65 | }; |
66 | Q_DECLARE_FLAGS(BehaviorsIfNotFound, BehaviorIfNotFound) |
67 | bool checkDatabase(BehaviorsIfNotFound ifNotFound); |
68 | void closeDatabase(); |
69 | void setStrategyFromString(const QString &strategy); |
70 | bool tryMmap(); |
71 | |
72 | /** |
73 | * Check if the on-disk cache needs to be rebuilt, and do it then. |
74 | */ |
75 | void checkDirectories(); |
76 | |
77 | /** |
78 | * Check if the on-disk cache needs to be rebuilt, and return true |
79 | */ |
80 | bool needsRebuild(); |
81 | |
82 | /** |
83 | * Recreate the cache and reopen the database |
84 | */ |
85 | bool buildSycoca(); |
86 | |
87 | KSycocaHeader (); |
88 | |
89 | KSycocaAbstractDevice *device(); |
90 | QDataStream *&stream(); |
91 | |
92 | QString findDatabase(); |
93 | void slotDatabaseChanged(); |
94 | |
95 | KMimeTypeFactory *mimeTypeFactory(); |
96 | KServiceFactory *serviceFactory(); |
97 | KServiceGroupFactory *serviceGroupFactory(); |
98 | |
99 | enum { |
100 | DatabaseNotOpen, // openDatabase must be called |
101 | BadVersion, // it's opened, but it's not usable |
102 | DatabaseOK, |
103 | } databaseStatus; |
104 | bool readError; |
105 | |
106 | qint64 timeStamp; // in ms since epoch |
107 | enum { StrategyMmap, StrategyMemFile, StrategyFile } m_sycocaStrategy; |
108 | QString m_databasePath; |
109 | QString language; |
110 | quint32 updateSig; |
111 | QMap<QString, qint64> allResourceDirs; // path, modification time in "ms since epoch" |
112 | QMap<QString, qint64> ; // path, modification time in "ms since epoch" |
113 | |
114 | void addFactory(KSycocaFactory *factory) |
115 | { |
116 | m_factories.append(t: factory); |
117 | } |
118 | KSycocaFactoryList *factories() |
119 | { |
120 | return &m_factories; |
121 | } |
122 | |
123 | QElapsedTimer m_lastCheck; |
124 | QDateTime m_dbLastModified; |
125 | |
126 | // Using KDirWatch because it will reliably tell us every time ksycoca is recreated. |
127 | // QFileSystemWatcher's inotify implementation easily gets confused between "removed" and "changed", |
128 | // and fails to re-add an inotify watch after the file was replaced at some point (KServiceTest::testThreads), |
129 | // thinking it only got changed and not removed+recreated. |
130 | // NOTE: this may be nullptr when file watching is disabled on the current thread |
131 | std::unique_ptr<KDirWatch> m_fileWatcher; |
132 | bool m_haveListeners; |
133 | |
134 | KSycoca *q; |
135 | |
136 | private: |
137 | KSycocaFactoryList m_factories; |
138 | size_t sycoca_size; |
139 | const char *sycoca_mmap; |
140 | QFile *m_mmapFile; |
141 | KSycocaAbstractDevice *m_device; |
142 | |
143 | public: |
144 | KMimeTypeFactory *m_mimeTypeFactory; |
145 | KServiceFactory *m_serviceFactory; |
146 | KServiceGroupFactory *m_serviceGroupFactory; |
147 | }; |
148 | |
149 | #endif /* KSYCOCA_P_H */ |
150 | |