1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
|
#ifndef DBMANAGER_H
#define DBMANAGER_H
#include "db/db.h"
#include "coreSQLiteStudio_global.h"
#include "common/global.h"
#include "sqlitestudio.h"
#include <QObject>
#include <QList>
#include <QHash>
/** @file */
class DbPlugin;
class Config;
class Plugin;
class PluginType;
/**
* @brief Database registry manager.
*
* Manages list of databases in SQLiteStudio core.
*
* It's a singleton asseccible with DBLIST macro.
*/
class API_EXPORT DbManager : public QObject
{
Q_OBJECT
public:
/**
* @brief Creates database manager.
* @param parent Parent object passed to QObject constructor.
*/
explicit DbManager(QObject *parent = 0);
/**
* @brief Default destructor.
*/
~DbManager();
/**
* @brief Adds database to the manager.
* @param name Symbolic name of the database, as it will be presented in the application.
* @param path Path to the database file.
* @param options Key-value custom options for database, that can be used in the DbPlugin implementation, like connection password, etc.
* @param permanent If true, then the database will be remembered in configuration, otherwise it will be disappear after application restart.
* @return true if the database has been successfully added, or false otherwise.
*
* The method can return false if given database file exists, but is not supported SQLite version (including invalid files,
* that are not SQLite database). It basicly returns false if DbPlugin#getInstance() returned null for given database parameters.
*/
virtual bool addDb(const QString &name, const QString &path, const QHash<QString, QVariant> &options, bool permanent = true) = 0;
/**
* @overload
*/
virtual bool addDb(const QString &name, const QString &path, bool permanent = true) = 0;
/**
* @brief Adds database as temporary, with generated name.
* @param path Path to database.
* @param options Key-value custom options for database.
* @return Added database name, if the database has been successfully added, or null string otherwise.
*
* This method is used for example when database was passed as argument to application command line arguments.
*/
virtual QString quickAddDb(const QString &path, const QHash<QString, QVariant> &options) = 0;
/**
* @brief Updates registered database with new data.
* @param db Registered database.
* @param name New symbolic name for the database.
* @param path New database file path.
* @param options New database options. See addDb() for details.
* @param permanent True to make the database stored in configuration, false to make it disappear after application restart.
* @return true if the database was successfully updated, or false otherwise.
*/
virtual bool updateDb(Db* db, const QString &name, const QString &path, const QHash<QString, QVariant> &options, bool permanent) = 0;
/**
* @brief Removes database from application.
* @param name Symbolic name of the database.
* @param cs Should the name be compare with case sensitivity?
*/
virtual void removeDbByName(const QString& name, Qt::CaseSensitivity cs = Qt::CaseSensitive) = 0;
/**
* @brief Removes database from application.
* @param path Database file path as it was passed to addDb() or updateDb().
*/
virtual void removeDbByPath(const QString& path) = 0;
/**
* @brief Removes database from application.
* @param db Database to be removed.
*/
virtual void removeDb(Db* db) = 0;
/**
* @brief Gives list of databases registered in the application.
* @return List of databases, no matter if database is open or not.
*
* The results list includes invalid databases (not supported by driver plugin, or with no read access, etc).
*/
virtual QList<Db*> getDbList() = 0;
/**
* @brief Gives list of valid databases.
* @return List of open databases.
*/
virtual QList<Db*> getValidDbList() = 0;
/**
* @brief Gives list of currently open databases.
* @return List of open databases.
*/
virtual QList<Db*> getConnectedDbList() = 0;
/**
* @brief Gives list of database names.
* @return List of database names that are registered in the application.
*/
virtual QStringList getDbNames() = 0;
/**
* @brief Gives database object by its name.
* @param name Symbolic name of the database.
* @param cs Should the \p name be compared with case sensitivity?
* @return Database object, or null pointer if the database could not be found.
*
* This method is fast, as it uses hash table lookup.
*/
virtual Db* getByName(const QString& name, Qt::CaseSensitivity cs = Qt::CaseInsensitive) = 0;
/**
* @brief Gives database object by its file path.
* @param path Database file path as it was passed to addDb() or updateDb().
* @return Database matched by file path, or null if no database was found.
*
* This method is fast, as it uses hash table lookup.
*/
virtual Db* getByPath(const QString& path) = 0;
/**
* @brief Creates in-memory SQLite3 database.
* @return Created database.
*
* Created database can be used for any purpose. Note that DbManager doesn't own created
* database and it's up to the caller to delete the database when it's no longer needed.
*/
virtual Db* createInMemDb() = 0;
/**
* @brief Tells if given database is temporary.
* @param db Database to check.
* @return true if database is temporary, or false if it's stored in the configuration.
*
* Temporary databases are databases that are not stored in configuration and will not be restored
* upon next SQLiteStudio start. This can be decided by user on UI when he edits database registration info
* (there is a checkbox for that).
*/
virtual bool isTemporary(Db* db) = 0;
virtual DbPlugin* getPluginForDbFile(const QString& filePath) = 0;
virtual QString generateUniqueDbName(const QString& filePath) = 0;
virtual QString generateUniqueDbName(DbPlugin* plugin, const QString& filePath) = 0;
/**
* @brief Generates database name.
* @param filePath Database file path.
* @return A name, using database file name as a hint for a name.
*
* This method doesn't care about uniqueness of the name. It just gets the file name from provided path
* and uses it as a name.
*/
static QString generateDbName(const QString& filePath);
public slots:
/**
* @brief Rescans configuration for new database entries.
*
* Looks into the configuration for new databases. If there are any, adds them to list of managed databases.
*/
virtual void scanForNewDatabasesInConfig() = 0;
/**
* @brief Sends signal to all interested entities, that databases are loaded.
*
* This is called by the managing entity (the SQLiteStudio instance) to let all know,
* that all db-related plugins and configuration related to databases are now loaded
* and list of databases in the manager is complete.
*/
virtual void notifyDatabasesAreLoaded() = 0;
virtual void rescanInvalidDatabasesForPlugin(DbPlugin* dbPlugin) = 0;
signals:
/**
* @brief Application just connected to the database.
* @param db Database object that the connection was made to.
*
* Emitted just after application has connected to the database.
*/
void dbConnected(Db* db);
/**
* @brief Application just disconnected from the database.
* @param db Database object that the connection was closed with.
*/
void dbDisconnected(Db* db);
/**
* @brief The database is about to be disconnected and user can still deny it.
* @param db Database to be closed.
* @param deny If set to true, then disconnecting will be aborted.
*/
void dbAboutToBeDisconnected(Db* db, bool& deny);
/**
* @brief A database has been added to the application.
* @param db Database added.
* Emitted from addDb() methods in case of success.
*/
void dbAdded(Db* db);
/**
* @brief A database has been removed from the application.
* @param db Database object that was removed. The object still exists, but will be removed soon after this signal is handled.
*
* Emitted from removeDb(). As the argument is a smart pointer, the object will be deleted after last reference to the pointer
* is deleted, which is very likely that the pointer instance in this signal is the last one.
*/
void dbRemoved(Db* db);
/**
* @brief A database registration data has been updated.
* @param oldName The name of the database before the update - in case the name was updated.
* @param db Database object that was updated.
*
* Emitted from updateDb() after successful update.
*
* The name of the database is a key for tables related to the databases, so if it changed, we dbUpdated() provides
* the original name before update, so any tables can be updated basing on the old name.
*/
void dbUpdated(const QString& oldName, Db* db);
/**
* @brief Loaded plugin to support the database.
* @param db Database object handled by the plugin.
*
* Emitted after a plugin was loaded and it turned out to handle the database that was already registered in the application,
* but wasn't managed by database manager, because no handler plugin was loaded earlier.
*
* Also emitted when database details were edited and saved, which fixes database configuration (for example path).
*/
void dbLoaded(Db* db);
/**
* @brief Plugin supporting the database is about to be unloaded.
* @param db Database object to be removed from the manager.
* @param plugin Plugin that handles the database.
*
* Emitted when PluginManager is about to unload the plugin which is handling the database.
* All classes using this database object should stop using it immediately, or the application may crash.
*
* The plugin itself should not use this signal. Instead it should implement Plugin::deinit() method
* to perform deinitialization before unloading. The Plugin::deinit() method is called before this signal is emitted.
*/
void dbAboutToBeUnloaded(Db* db, DbPlugin* plugin);
/**
* @brief Plugins supporting the database was just unloaded.
* @param db The new database object (InvalidDb) that replaced the previous one.
*
* This is emitted after the plugin for the database was unloaded. The \p db object is now a different object.
* It is of InvalidDb class and it represents a database in an invalid state. It still has name, path and connection options,
* but no operation can be performed on the database.
*/
void dbUnloaded(Db* db);
/**
* @brief Emited when the initial database list has been loaded.
*/
void dbListLoaded();
};
/**
* @brief Database manager.
* Provides direct access to the database manager.
*/
#define DBLIST SQLITESTUDIO->getDbManager()
#endif // DBMANAGER_H
|