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
22class QFile;
23class QDataStream;
24class KSycocaAbstractDevice;
25class KMimeTypeFactory;
26class KServiceFactory;
27class 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().
31struct KSycocaHeader {
32 KSycocaHeader()
33 : timeStamp(0)
34 , updateSignature(0)
35 {
36 }
37 QString prefixes;
38 QString language;
39 qint64 timeStamp; // in ms
40 quint32 updateSignature;
41};
42
43QDataStream &operator>>(QDataStream &in, KSycocaHeader &h);
44
45/**
46 * \internal
47 * Exported for unittests
48 */
49class KSERVICE_EXPORT KSycocaPrivate
50{
51public:
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 readSycocaHeader();
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> extraFiles; // 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
136private:
137 KSycocaFactoryList m_factories;
138 size_t sycoca_size;
139 const char *sycoca_mmap;
140 QFile *m_mmapFile;
141 KSycocaAbstractDevice *m_device;
142
143public:
144 KMimeTypeFactory *m_mimeTypeFactory;
145 KServiceFactory *m_serviceFactory;
146 KServiceGroupFactory *m_serviceGroupFactory;
147};
148
149#endif /* KSYCOCA_P_H */
150

source code of kservice/src/sycoca/ksycoca_p.h