1 #include "sqlitestudio.h"
2 #include "plugins/plugin.h"
3 #include "services/pluginmanager.h"
4 #include "common/utils.h"
5 #include "common/utils_sql.h"
6 #include "completionhelper.h"
7 #include "parser/keywords.h"
8 #include "parser/lexer.h"
9 #include "services/notifymanager.h"
10 #include "plugins/codeformatterplugin.h"
11 #include "services/codeformatter.h"
12 #include "plugins/generalpurposeplugin.h"
13 #include "plugins/dbplugin.h"
14 #include "common/unused.h"
15 #include "services/functionmanager.h"
16 #include "plugins/scriptingplugin.h"
17 #include "plugins/exportplugin.h"
18 #include "plugins/scriptingqt.h"
19 #include "plugins/dbpluginsqlite3.h"
20 #include "services/impl/configimpl.h"
21 #include "services/impl/dbmanagerimpl.h"
22 #include "services/impl/functionmanagerimpl.h"
23 #include "services/impl/collationmanagerimpl.h"
24 #include "services/impl/pluginmanagerimpl.h"
25 #include "services/impl/sqliteextensionmanagerimpl.h"
26 #include "services/updatemanager.h"
27 #include "impl/dbattacherimpl.h"
28 #include "services/exportmanager.h"
29 #include "services/importmanager.h"
30 #include "services/populatemanager.h"
31 #include "plugins/scriptingsql.h"
32 #include "plugins/importplugin.h"
33 #include "plugins/populateplugin.h"
34 #include "services/extralicensemanager.h"
35 #include "services/sqliteextensionmanager.h"
36 #include "translations.h"
37 #include <QProcessEnvironment>
38 #include <QThreadPool>
39 #include <QCoreApplication>
40
41 DEFINE_SINGLETON(SQLiteStudio)
42
43 static const int sqlitestudioVersion = 30303;
44
SQLiteStudio()45 SQLiteStudio::SQLiteStudio()
46 {
47 if (qApp) // qApp is null in unit tests
48 connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(cleanUp()));
49 }
50
~SQLiteStudio()51 SQLiteStudio::~SQLiteStudio()
52 {
53 }
getInitialTranslationFiles() const54 QStringList SQLiteStudio::getInitialTranslationFiles() const
55 {
56 return initialTranslationFiles;
57 }
58
setInitialTranslationFiles(const QStringList & value)59 void SQLiteStudio::setInitialTranslationFiles(const QStringList& value)
60 {
61 initialTranslationFiles = value;
62 }
63
64
getCurrentLang() const65 QString SQLiteStudio::getCurrentLang() const
66 {
67 return currentLang;
68 }
69
getExtraLicenseManager() const70 ExtraLicenseManager* SQLiteStudio::getExtraLicenseManager() const
71 {
72 return extraLicenseManager;
73 }
74
setExtraLicenseManager(ExtraLicenseManager * value)75 void SQLiteStudio::setExtraLicenseManager(ExtraLicenseManager* value)
76 {
77 extraLicenseManager = value;
78 }
79
80
getImmediateQuit() const81 bool SQLiteStudio::getImmediateQuit() const
82 {
83 return immediateQuit;
84 }
85
setImmediateQuit(bool value)86 void SQLiteStudio::setImmediateQuit(bool value)
87 {
88 immediateQuit = value;
89 }
90
91 #ifdef PORTABLE_CONFIG
getUpdateManager() const92 UpdateManager* SQLiteStudio::getUpdateManager() const
93 {
94 return updateManager;
95 }
96
setUpdateManager(UpdateManager * value)97 void SQLiteStudio::setUpdateManager(UpdateManager* value)
98 {
99 updateManager = value;
100 }
101 #endif
102
getPopulateManager() const103 PopulateManager* SQLiteStudio::getPopulateManager() const
104 {
105 return populateManager;
106 }
107
setPopulateManager(PopulateManager * value)108 void SQLiteStudio::setPopulateManager(PopulateManager* value)
109 {
110 populateManager = value;
111 }
112
getCodeFormatter() const113 CodeFormatter* SQLiteStudio::getCodeFormatter() const
114 {
115 return codeFormatter;
116 }
117
setCodeFormatter(CodeFormatter * codeFormatter)118 void SQLiteStudio::setCodeFormatter(CodeFormatter* codeFormatter)
119 {
120 this->codeFormatter = codeFormatter;
121 }
122
getHomePage() const123 QString SQLiteStudio::getHomePage() const
124 {
125 static_qstring(url, "https://sqlitestudio.pl");
126 return url;
127 }
128
getGitHubReleases() const129 QString SQLiteStudio::getGitHubReleases() const
130 {
131 static_qstring(url, "https://github.com/pawelsalawa/sqlitestudio/releases");
132 return url;
133 }
134
getUserManualPage() const135 QString SQLiteStudio::getUserManualPage() const
136 {
137 static_qstring(url, "https://github.com/pawelsalawa/sqlitestudio/wiki/User_Manual");
138 return url;
139 }
140
getSqliteDocsPage() const141 QString SQLiteStudio::getSqliteDocsPage() const
142 {
143 static_qstring(url, "http://sqlite.org/lang.html");
144 return url;
145 }
146
getIssuesPage() const147 QString SQLiteStudio::getIssuesPage() const
148 {
149 static_qstring(url, "https://github.com/pawelsalawa/sqlitestudio/issues");
150 return url;
151 }
152
getDonatePage() const153 QString SQLiteStudio::getDonatePage() const
154 {
155 static_qstring(url, "https://sqlitestudio.pl/donate/");
156 return url;
157 }
158
getNewIssuePage() const159 QString SQLiteStudio::getNewIssuePage() const
160 {
161 static_qstring(url, "https://github.com/pawelsalawa/sqlitestudio/issues/new");
162 return url;
163 }
164
getImportManager() const165 ImportManager* SQLiteStudio::getImportManager() const
166 {
167 return importManager;
168 }
169
setImportManager(ImportManager * value)170 void SQLiteStudio::setImportManager(ImportManager* value)
171 {
172 importManager = value;
173 }
174
getExportManager() const175 ExportManager* SQLiteStudio::getExportManager() const
176 {
177 return exportManager;
178 }
179
setExportManager(ExportManager * value)180 void SQLiteStudio::setExportManager(ExportManager* value)
181 {
182 exportManager = value;
183 }
184
getVersion() const185 int SQLiteStudio::getVersion() const
186 {
187 return sqlitestudioVersion;
188 }
189
getVersionString() const190 QString SQLiteStudio::getVersionString() const
191 {
192 int ver = getVersion();
193 int majorVer = ver / 10000;
194 int minorVer = ver % 10000 / 100;
195 int patchVer = ver % 100;
196 return QString::number(majorVer) + "." + QString::number(minorVer) + "." + QString::number(patchVer);
197 }
198
getCollationManager() const199 CollationManager* SQLiteStudio::getCollationManager() const
200 {
201 return collationManager;
202 }
203
setCollationManager(CollationManager * value)204 void SQLiteStudio::setCollationManager(CollationManager* value)
205 {
206 safe_delete(collationManager);
207 collationManager = value;
208 }
209
getSqliteExtensionManager() const210 SqliteExtensionManager* SQLiteStudio::getSqliteExtensionManager() const
211 {
212 return extensionManager;
213 }
214
setSqliteExtensionManager(SqliteExtensionManager * value)215 void SQLiteStudio::setSqliteExtensionManager(SqliteExtensionManager* value)
216 {
217 safe_delete(extensionManager);
218 extensionManager = value;
219 }
220
getDbAttacherFactory() const221 DbAttacherFactory* SQLiteStudio::getDbAttacherFactory() const
222 {
223 return dbAttacherFactory;
224 }
225
setDbAttacherFactory(DbAttacherFactory * value)226 void SQLiteStudio::setDbAttacherFactory(DbAttacherFactory* value)
227 {
228 safe_delete(dbAttacherFactory);
229 dbAttacherFactory = value;
230 }
231
getPluginManager() const232 PluginManager* SQLiteStudio::getPluginManager() const
233 {
234 return pluginManager;
235 }
236
setPluginManager(PluginManager * value)237 void SQLiteStudio::setPluginManager(PluginManager* value)
238 {
239 safe_delete(pluginManager);
240 pluginManager = value;
241 }
242
getFunctionManager() const243 FunctionManager* SQLiteStudio::getFunctionManager() const
244 {
245 return functionManager;
246 }
247
setFunctionManager(FunctionManager * value)248 void SQLiteStudio::setFunctionManager(FunctionManager* value)
249 {
250 safe_delete(functionManager);
251 functionManager = value;
252 }
253
getDbManager() const254 DbManager* SQLiteStudio::getDbManager() const
255 {
256 return dbManager;
257 }
258
setDbManager(DbManager * value)259 void SQLiteStudio::setDbManager(DbManager* value)
260 {
261 safe_delete(dbManager);
262 dbManager = value;
263 }
264
getConfig() const265 Config* SQLiteStudio::getConfig() const
266 {
267 return config;
268 }
269
setConfig(Config * value)270 void SQLiteStudio::setConfig(Config* value)
271 {
272 safe_delete(config);
273 config = value;
274 }
275
init(const QStringList & cmdListArguments,bool guiAvailable)276 void SQLiteStudio::init(const QStringList& cmdListArguments, bool guiAvailable)
277 {
278 env = new QProcessEnvironment(QProcessEnvironment::systemEnvironment());
279 this->guiAvailable = guiAvailable;
280
281 QThreadPool::globalInstance()->setMaxThreadCount(10);
282
283 Q_INIT_RESOURCE(coreSQLiteStudio);
284
285 CfgLazyInitializer::init();
286
287 initUtils();
288 CfgMain::staticInit();
289 Db::metaInit();
290 initUtilsSql();
291 SchemaResolver::staticInit();
292 initKeywords();
293 Lexer::staticInit();
294 CompletionHelper::init();
295
296 qRegisterMetaType<ScriptingPlugin::Context*>();
297
298 NotifyManager::getInstance();
299
300 dbAttacherFactory = new DbAttacherDefaultFactory();
301
302 config = new ConfigImpl();
303 config->init();
304
305 currentLang = CFG_CORE.General.Language.get();
306 loadTranslations(initialTranslationFiles);
307
308 pluginManager = new PluginManagerImpl();
309 dbManager = new DbManagerImpl();
310
311 pluginManager->registerPluginType<GeneralPurposePlugin>(QObject::tr("General purpose", "plugin category name"));
312 pluginManager->registerPluginType<DbPlugin>(QObject::tr("Database support", "plugin category name"));
313 pluginManager->registerPluginType<CodeFormatterPlugin>(QObject::tr("Code formatter", "plugin category name"), "formatterPluginsPage");
314 pluginManager->registerPluginType<ScriptingPlugin>(QObject::tr("Scripting languages", "plugin category name"));
315 pluginManager->registerPluginType<ExportPlugin>(QObject::tr("Exporting", "plugin category name"));
316 pluginManager->registerPluginType<ImportPlugin>(QObject::tr("Importing", "plugin category name"));
317 pluginManager->registerPluginType<PopulatePlugin>(QObject::tr("Table populating", "plugin category name"));
318
319 codeFormatter = new CodeFormatter();
320 connect(CFG_CORE.General.ActiveCodeFormatter, SIGNAL(changed(QVariant)), this, SLOT(updateCurrentCodeFormatter()));
321 connect(pluginManager, SIGNAL(pluginsInitiallyLoaded()), this, SLOT(updateCodeFormatter()));
322
323 // FunctionManager needs to be set up before DbManager, cause when DbManager starts up, databases make their
324 // connections and register functions.
325 functionManager = new FunctionManagerImpl();
326
327 collationManager = new CollationManagerImpl();
328 extensionManager = new SqliteExtensionManagerImpl();
329
330 cmdLineArgs = cmdListArguments;
331
332 connect(pluginManager, SIGNAL(pluginsInitiallyLoaded()), DBLIST, SLOT(notifyDatabasesAreLoaded()));
333
334 DbPluginSqlite3* sqlite3plugin = new DbPluginSqlite3;
335 dynamic_cast<DbManagerImpl*>(dbManager)->setInMemDbCreatorPlugin(sqlite3plugin);
336
337 pluginManager->loadBuiltInPlugin(new ScriptingQt);
338 pluginManager->loadBuiltInPlugin(new ScriptingSql);
339 pluginManager->loadBuiltInPlugin(sqlite3plugin);
340
341 exportManager = new ExportManager();
342 importManager = new ImportManager();
343 populateManager = new PopulateManager();
344 #ifdef PORTABLE_CONFIG
345 updateManager = new UpdateManager();
346 #endif
347 extraLicenseManager = new ExtraLicenseManager();
348
349 extraLicenseManager->addLicense("SQLiteStudio license (GPL v3)", ":/docs/licenses/sqlitestudio_license.txt");
350 extraLicenseManager->addLicense("Fugue icons", ":/docs/licenses/fugue_icons.txt");
351 extraLicenseManager->addLicense("Qt, QHexEdit (LGPL v2.1)", ":/docs/licenses/lgpl.txt");
352 extraLicenseManager->addLicense("diff_match (Apache License v2.0)", ":/docs/licenses/diff_match.txt");
353 extraLicenseManager->addLicense("RSA library (GPL v3)", ":/docs/licenses/gpl.txt");
354 extraLicenseManager->addLicense("SingleApplication (The MIT License)", ":/docs/licenses/mit.txt");
355 }
356
initPlugins()357 void SQLiteStudio::initPlugins()
358 {
359 pluginManager->init();
360
361 connect(pluginManager, SIGNAL(loaded(Plugin*,PluginType*)), this, SLOT(pluginLoaded(Plugin*,PluginType*)));
362 connect(pluginManager, SIGNAL(aboutToUnload(Plugin*,PluginType*)), this, SLOT(pluginToBeUnloaded(Plugin*,PluginType*)));
363 connect(pluginManager, SIGNAL(unloaded(QString,PluginType*)), this, SLOT(pluginUnloaded(QString,PluginType*)));
364 }
365
cleanUp()366 void SQLiteStudio::cleanUp()
367 {
368 emit aboutToQuit();
369 disconnect(pluginManager, SIGNAL(aboutToUnload(Plugin*,PluginType*)), this, SLOT(pluginToBeUnloaded(Plugin*,PluginType*)));
370 disconnect(pluginManager, SIGNAL(unloaded(QString,PluginType*)), this, SLOT(pluginUnloaded(QString,PluginType*)));
371 if (!immediateQuit)
372 {
373 if (pluginManager)
374 pluginManager->deinit();
375
376 safe_delete(pluginManager); // PluginManager before DbManager, so Db objects are deleted while DbManager still exists
377 #ifdef PORTABLE_CONFIG
378 safe_delete(updateManager);
379 #endif
380 safe_delete(populateManager);
381 safe_delete(importManager);
382 safe_delete(exportManager);
383 safe_delete(functionManager);
384 safe_delete(extraLicenseManager);
385 safe_delete(dbManager);
386 safe_delete(config);
387 safe_delete(codeFormatter);
388 safe_delete(dbAttacherFactory);
389 safe_delete(env);
390 NotifyManager::destroy();
391 }
392 Q_CLEANUP_RESOURCE(coreSQLiteStudio);
393 }
394
updateCodeFormatter()395 void SQLiteStudio::updateCodeFormatter()
396 {
397 codeFormatter->fullUpdate();
398 }
399
updateCurrentCodeFormatter()400 void SQLiteStudio::updateCurrentCodeFormatter()
401 {
402 codeFormatter->updateCurrent();
403 }
404
pluginLoaded(Plugin * plugin,PluginType * pluginType)405 void SQLiteStudio::pluginLoaded(Plugin* plugin, PluginType* pluginType)
406 {
407 UNUSED(plugin);
408 if (pluginType->isForPluginType<CodeFormatterPlugin>()) // TODO move this to slot of CodeFormatter
409 updateCodeFormatter();
410 }
411
pluginToBeUnloaded(Plugin * plugin,PluginType * pluginType)412 void SQLiteStudio::pluginToBeUnloaded(Plugin* plugin, PluginType* pluginType)
413 {
414 UNUSED(plugin);
415 UNUSED(pluginType);
416 }
417
pluginUnloaded(const QString & pluginName,PluginType * pluginType)418 void SQLiteStudio::pluginUnloaded(const QString& pluginName, PluginType* pluginType)
419 {
420 UNUSED(pluginName);
421 if (pluginType->isForPluginType<CodeFormatterPlugin>()) // TODO move this to slot of CodeFormatter
422 updateCodeFormatter();
423 }
424
getEnv(const QString & name,const QString & defaultValue)425 QString SQLiteStudio::getEnv(const QString &name, const QString &defaultValue)
426 {
427 return env->value(name, defaultValue);
428 }
429
createDbAttacher(Db * db)430 DbAttacher* SQLiteStudio::createDbAttacher(Db* db)
431 {
432 return dbAttacherFactory->create(db);
433 }
434
isGuiAvailable() const435 bool SQLiteStudio::isGuiAvailable() const
436 {
437 return guiAvailable;
438 }
439