aboutsummaryrefslogtreecommitdiffstats
path: root/SQLiteStudio3/coreSQLiteStudio/services
diff options
context:
space:
mode:
authorLibravatarUnit 193 <unit193@unit193.net>2021-12-17 07:06:30 -0500
committerLibravatarUnit 193 <unit193@unit193.net>2021-12-17 07:06:30 -0500
commit1fdc150116cad39aae5c5da407c3312b47a59e3a (patch)
tree123c79a4d7ad2d45781ba03ce939f7539fb428d8 /SQLiteStudio3/coreSQLiteStudio/services
parentfeda8a7db8d1d7c5439aa8f8feef7cc0dd2b59a0 (diff)
New upstream version 3.3.3+dfsg1.upstream/3.3.3+dfsg1
Diffstat (limited to 'SQLiteStudio3/coreSQLiteStudio/services')
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/services/codeformatter.cpp3
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/services/config.cpp6
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/services/config.h11
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/services/extralicensemanager.cpp4
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/services/functionmanager.cpp2
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/services/impl/configimpl.cpp145
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/services/impl/configimpl.h5
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/services/impl/dbmanagerimpl.cpp2
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/services/impl/pluginmanagerimpl.cpp18
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/services/importmanager.cpp6
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/services/importmanager.h2
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/services/pluginmanager.h2
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/services/updatemanager.cpp143
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/services/updatemanager.h21
14 files changed, 204 insertions, 166 deletions
diff --git a/SQLiteStudio3/coreSQLiteStudio/services/codeformatter.cpp b/SQLiteStudio3/coreSQLiteStudio/services/codeformatter.cpp
index e02508f..e17032b 100644
--- a/SQLiteStudio3/coreSQLiteStudio/services/codeformatter.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/services/codeformatter.cpp
@@ -2,6 +2,7 @@
#include "parser/parser.h"
#include "plugins/codeformatterplugin.h"
#include "services/pluginmanager.h"
+#include "common/compatibility.h"
#include <QDebug>
void CodeFormatter::setFormatter(const QString& lang, CodeFormatterPlugin *formatterPlugin)
@@ -44,7 +45,7 @@ void CodeFormatter::updateCurrent()
QHash<QString,QVariant> config = CFG_CORE.General.ActiveCodeFormatter.get();
QString name;
QStringList names = availableFormatters.keys();
- qSort(names);
+ sSort(names);
for (const QString& lang : names)
{
name = config[lang].toString();
diff --git a/SQLiteStudio3/coreSQLiteStudio/services/config.cpp b/SQLiteStudio3/coreSQLiteStudio/services/config.cpp
index 60a80d5..c03847a 100644
--- a/SQLiteStudio3/coreSQLiteStudio/services/config.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/services/config.cpp
@@ -4,6 +4,7 @@ CFG_DEFINE(Core)
static const QString DB_FILE_NAME = QStringLiteral("settings3");
static QString MASTER_CONFIG_FILE = QString();
+Config::AskUserForConfigDirFunc Config::askUserForConfigDirFunc;
Config::~Config()
{
@@ -18,3 +19,8 @@ QString Config::getMasterConfigFile()
{
return MASTER_CONFIG_FILE;
}
+
+void Config::setAskUserForConfigDirFunc(const AskUserForConfigDirFunc& value)
+{
+ askUserForConfigDirFunc = value;
+}
diff --git a/SQLiteStudio3/coreSQLiteStudio/services/config.h b/SQLiteStudio3/coreSQLiteStudio/services/config.h
index 202120a..9d1e567 100644
--- a/SQLiteStudio3/coreSQLiteStudio/services/config.h
+++ b/SQLiteStudio3/coreSQLiteStudio/services/config.h
@@ -14,7 +14,7 @@
#include <QSharedPointer>
#include <QDateTime>
-const int SQLITESTUDIO_CONFIG_VERSION = 2;
+const int SQLITESTUDIO_CONFIG_VERSION = 3;
CFG_CATEGORIES(Core,
CFG_CATEGORY(General,
@@ -74,6 +74,7 @@ class API_EXPORT Config : public QObject
QList<DbGroupPtr> childs;
int order;
bool open = false;
+ bool dbExpanded = false;
};
struct SqlHistoryEntry
@@ -107,13 +108,17 @@ class API_EXPORT Config : public QObject
typedef QSharedPointer<ReportHistoryEntry> ReportHistoryEntryPtr;
+ typedef std::function<QString()> AskUserForConfigDirFunc;
+
static void setMasterConfigFile(const QString& path);
static QString getMasterConfigFile();
+ static void setAskUserForConfigDirFunc(const AskUserForConfigDirFunc& value);
virtual void init() = 0;
virtual void cleanUp() = 0;
virtual const QString& getConfigDir() const = 0;
virtual QString getConfigFilePath() const = 0;
+ virtual bool isInMemory() const = 0;
virtual void beginMassSave() = 0;
virtual void commitMassSave() = 0;
@@ -191,6 +196,10 @@ class API_EXPORT Config : public QObject
public slots:
virtual void refreshSqlHistory() = 0;
virtual void refreshDdlHistory() = 0;
+
+ protected:
+ static AskUserForConfigDirFunc askUserForConfigDirFunc;
+
};
#define CFG SQLITESTUDIO->getConfig()
diff --git a/SQLiteStudio3/coreSQLiteStudio/services/extralicensemanager.cpp b/SQLiteStudio3/coreSQLiteStudio/services/extralicensemanager.cpp
index 2bdc712..9710673 100644
--- a/SQLiteStudio3/coreSQLiteStudio/services/extralicensemanager.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/services/extralicensemanager.cpp
@@ -55,7 +55,7 @@ bool ExtraLicenseManager::isViolatedLicense(const QString& title)
QString ExtraLicenseManager::getViolationMessage(const QString& title)
{
if (!licenses.contains(title))
- return QString::null;
+ return QString();
return licenses[title]->violationMessage;
}
@@ -109,7 +109,7 @@ QString ExtraLicenseManager::readLicenseFile(const QString& path) const
if (!file.open(QIODevice::ReadOnly))
{
qCritical() << "Error opening" << file.fileName();
- return QString::null;
+ return QString();
}
QString contents = QString::fromLatin1(file.readAll());
file.close();
diff --git a/SQLiteStudio3/coreSQLiteStudio/services/functionmanager.cpp b/SQLiteStudio3/coreSQLiteStudio/services/functionmanager.cpp
index 10db318..f45e803 100644
--- a/SQLiteStudio3/coreSQLiteStudio/services/functionmanager.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/services/functionmanager.cpp
@@ -24,7 +24,7 @@ QString FunctionManager::FunctionBase::typeString(Type type)
case ScriptFunction::AGGREGATE:
return "AGGREGATE";
}
- return QString::null;
+ return QString();
}
FunctionManager::ScriptFunction::Type FunctionManager::FunctionBase::typeString(const QString& type)
diff --git a/SQLiteStudio3/coreSQLiteStudio/services/impl/configimpl.cpp b/SQLiteStudio3/coreSQLiteStudio/services/impl/configimpl.cpp
index 860e828..570395a 100644
--- a/SQLiteStudio3/coreSQLiteStudio/services/impl/configimpl.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/services/impl/configimpl.cpp
@@ -15,10 +15,15 @@
#include <QDateTime>
#include <QSysInfo>
#include <QCoreApplication>
+#include <QStandardPaths>
+#include <QSettings>
#include <QtConcurrent/QtConcurrentRun>
+#include <QtWidgets/QFileDialog>
static_qstring(DB_FILE_NAME, "settings3");
+static_qstring(CONFIG_DIR_SETTING, "SQLiteStudioConfigDir");
qint64 ConfigImpl::sqlHistoryId = -1;
+QString ConfigImpl::memoryDbName = QStringLiteral(":memory:");
ConfigImpl::~ConfigImpl()
{
@@ -43,7 +48,7 @@ void ConfigImpl::cleanUp()
if (db->isOpen())
db->close();
- safe_delete(db);
+ safe_delete(db)
}
const QString &ConfigImpl::getConfigDir() const
@@ -59,6 +64,11 @@ QString ConfigImpl::getConfigFilePath() const
return db->getPath();
}
+bool ConfigImpl::isInMemory() const
+{
+ return db->getPath() == memoryDbName;
+}
+
void ConfigImpl::beginMassSave()
{
if (isMassSaving())
@@ -243,8 +253,8 @@ void ConfigImpl::storeGroup(const ConfigImpl::DbGroupPtr &group, qint64 parentId
if (parentId > -1)
parent = parentId;
- SqlQueryPtr results = db->exec("INSERT INTO groups (name, [order], parent, open, dbname) VALUES (?, ?, ?, ?, ?)",
- {group->name, group->order, parent, group->open, group->referencedDbName});
+ SqlQueryPtr results = db->exec("INSERT INTO groups (name, [order], parent, open, dbname, db_expanded) VALUES (?, ?, ?, ?, ?, ?)",
+ {group->name, group->order, parent, group->open, group->referencedDbName, group->dbExpanded});
qint64 newParentId = results->getRegularInsertRowId();
for (const DbGroupPtr& childGroup : group->childs)
@@ -261,7 +271,7 @@ QList<ConfigImpl::DbGroupPtr> ConfigImpl::getGroups()
ConfigImpl::DbGroupPtr ConfigImpl::getDbGroup(const QString& dbName)
{
- SqlQueryPtr results = db->exec("SELECT id, name, [order], open, dbname FROM groups WHERE dbname = ? LIMIT 1", {dbName});
+ SqlQueryPtr results = db->exec("SELECT id, name, [order], open, dbname, db_expanded FROM groups WHERE dbname = ? LIMIT 1", {dbName});
DbGroupPtr group = DbGroupPtr::create();
group->referencedDbName = dbName;
@@ -274,6 +284,7 @@ ConfigImpl::DbGroupPtr ConfigImpl::getDbGroup(const QString& dbName)
group->name = row->value("name").toString();
group->order = row->value("order").toInt();
group->open = row->value("open").toBool();
+ group->dbExpanded = row->value("db_expanded").toBool();
return group;
}
@@ -553,9 +564,9 @@ void ConfigImpl::readGroupRecursively(ConfigImpl::DbGroupPtr group)
{
SqlQueryPtr results;
if (group->id < 0)
- results = db->exec("SELECT id, name, [order], open, dbname FROM groups WHERE parent IS NULL ORDER BY [order]");
+ results = db->exec("SELECT id, name, [order], open, dbname, db_expanded FROM groups WHERE parent IS NULL ORDER BY [order]");
else
- results = db->exec("SELECT id, name, [order], open, dbname FROM groups WHERE parent = ? ORDER BY [order]", {group->id});
+ results = db->exec("SELECT id, name, [order], open, dbname, db_expanded FROM groups WHERE parent = ? ORDER BY [order]", {group->id});
DbGroupPtr childGroup;
SqlResultsRowPtr row;
@@ -568,6 +579,7 @@ void ConfigImpl::readGroupRecursively(ConfigImpl::DbGroupPtr group)
childGroup->order = row->value("order").toInt();
childGroup->open = row->value("open").toBool();
childGroup->referencedDbName = row->value("dbname").toString();
+ childGroup->dbExpanded = row->value("db_expanded").toBool();
group->childs += childGroup;
}
@@ -592,6 +604,11 @@ void ConfigImpl::rollback()
QString ConfigImpl::getConfigPath()
{
+ return QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) + "/" + DB_FILE_NAME;
+}
+
+QString ConfigImpl::getLegacyConfigPath()
+{
#ifdef Q_OS_WIN
if (QSysInfo::windowsVersion() & QSysInfo::WV_NT_based)
return SQLITESTUDIO->getEnv("APPDATA")+"/sqlitestudio";
@@ -669,7 +686,7 @@ void ConfigImpl::initTables()
if (!tables.contains("groups"))
db->exec("CREATE TABLE groups (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, parent INTEGER REFERENCES groups(id), "
"[order] INTEGER, open INTEGER DEFAULT 0, dbname TEXT UNIQUE REFERENCES dblist(name) ON UPDATE CASCADE ON DELETE CASCADE, "
- "UNIQUE(name, parent))");
+ "db_expanded INTEGER DEFAULT 0, UNIQUE(name, parent))");
if (!tables.contains("ddl_history"))
db->exec("CREATE TABLE ddl_history (id INTEGER PRIMARY KEY AUTOINCREMENT, dbname TEXT, file TEXT, timestamp INTEGER, "
@@ -712,43 +729,29 @@ void ConfigImpl::initTables()
void ConfigImpl::initDbFile()
{
- // Determinate global config location and portable one
- QString globalPath = getConfigPath();
- QString portablePath = getPortableConfigPath();
-
QList<QPair<QString,bool>> paths;
- if (!globalPath.isNull() && !portablePath.isNull())
- {
- if (QFileInfo(portablePath).exists())
- {
- paths << QPair<QString,bool>(portablePath+"/"+DB_FILE_NAME, false);
- paths << QPair<QString,bool>(globalPath+"/"+DB_FILE_NAME, true);
- }
- else
- {
- paths << QPair<QString,bool>(globalPath+"/"+DB_FILE_NAME, true);
- paths << QPair<QString,bool>(portablePath+"/"+DB_FILE_NAME, false);
- }
- }
- else if (!globalPath.isNull())
+
+ // Do we have path selected by user? (because app was unable to find writable location before)
+ QSettings sett;
+ QString customPath = sett.value(CONFIG_DIR_SETTING).toString();
+ if (!customPath.isEmpty())
{
- paths << QPair<QString,bool>(globalPath+"/"+DB_FILE_NAME, true);
- }
- else if (!portablePath.isNull())
- {
- paths << QPair<QString,bool>(portablePath+"/"+DB_FILE_NAME, false);
+ paths << QPair<QString,bool>(customPath + "/" + DB_FILE_NAME, false);
+ qDebug() << "Using custom configuration directory. The location is stored in" << sett.fileName();
}
+ else
+ paths.append(getStdDbPaths());
// A fallback to in-memory db
- paths << QPair<QString,bool>(":memory:", false);
+ paths << QPair<QString,bool>(memoryDbName, false);
// Go through all candidates and pick one
QDir dir;
for (const QPair<QString,bool>& path : paths)
{
dir = QDir(path.first);
- if (path.first != ":memory:")
- dir.cdUp();
+ if (path.first != memoryDbName)
+ dir = QFileInfo(path.first).dir();
if (tryInitDbFile(path))
{
@@ -757,8 +760,25 @@ void ConfigImpl::initDbFile()
}
}
+ // Failed to use any of predefined directories. Let's ask the user.
+ while (configDir == memoryDbName)
+ {
+ QString path = askUserForConfigDirFunc();
+ if (path.isNull())
+ break;
+
+ dir = QDir(path);
+ if (tryInitDbFile(QPair<QString,bool>(path + "/" + DB_FILE_NAME, false)))
+ {
+ configDir = dir.absolutePath();
+ QSettings sett;
+ sett.setValue(CONFIG_DIR_SETTING, configDir);
+ qDebug() << "Using custom configuration directory. The location is stored in" << sett.fileName();
+ }
+ }
+
// We ended up with in-memory one? That's not good.
- if (configDir == ":memory:")
+ if (configDir == memoryDbName)
{
paths.removeLast();
QStringList pathStrings;
@@ -766,13 +786,38 @@ void ConfigImpl::initDbFile()
pathStrings << path.first;
notifyError(QObject::tr("Could not initialize configuration file. Any configuration changes and queries history will be lost after application restart."
- " Tried to initialize the file at following localizations: %1.").arg(pathStrings.join(", ")));
+ " Unable to create a file at following locations: %1.").arg(pathStrings.join(", ")));
}
qDebug() << "Using configuration directory:" << configDir;
db->exec("PRAGMA foreign_keys = 1;");
}
+QList<QPair<QString,bool>> ConfigImpl::getStdDbPaths()
+{
+ QList<QPair<QString,bool>> paths;
+
+ // Portable dir location has always precedense - comes first
+ QString portablePath = getPortableConfigPath();
+ if (!portablePath.isNull())
+ paths << QPair<QString,bool>(portablePath+"/"+DB_FILE_NAME, false);
+
+ // Determinate global config location
+ QString globalPath = getConfigPath();
+ paths << QPair<QString,bool>(globalPath, true);
+
+ // If needed, migrate configuration from legacy location (pre-3.3) to new location (3.3 and later)
+ QString legacyGlobalPath = getLegacyConfigPath();
+ if (!legacyGlobalPath.isNull())
+ {
+ paths << QPair<QString,bool>(legacyGlobalPath+"/"+DB_FILE_NAME, true);
+ if (!QFile::exists(globalPath))
+ tryToMigrateOldGlobalPath(legacyGlobalPath, globalPath);
+ }
+
+ return paths;
+}
+
bool ConfigImpl::tryInitDbFile(const QPair<QString, bool> &dbPath)
{
// Create global config directory if not existing
@@ -1118,6 +1163,12 @@ void ConfigImpl::updateConfigDb()
// 1->2
db->exec("UPDATE settings SET [key] = 'DataUncommittedError' WHERE [key] = 'DataUncommitedError'");
db->exec("UPDATE settings SET [key] = 'DataUncommitted' WHERE [key] = 'DataUncommited'");
+ __attribute__((__fallthrough__));
+ }
+ case 2:
+ {
+ // 2->3
+ db->exec("ALTER TABLE groups ADD db_expanded INTEGER DEFAULT 0");
}
// Add cases here for next versions,
// without a "break" instruction,
@@ -1129,6 +1180,30 @@ void ConfigImpl::updateConfigDb()
db->commit();
}
+bool ConfigImpl::tryToMigrateOldGlobalPath(const QString& oldPath, const QString& newPath)
+{
+ if (!QFileInfo::exists(oldPath))
+ return false;
+
+ qDebug() << "Attempting to migrate legacy config location" << oldPath << "to new location" << newPath;
+ QDir dir = QFileInfo(newPath).dir();
+ if (!dir.exists())
+ QDir::root().mkpath(dir.absolutePath());
+
+ if (QFile::copy(oldPath, dir.absoluteFilePath(DB_FILE_NAME)))
+ {
+ qDebug() << "Migration successful. Renaming old location file so it has '.old' suffix.";
+ if (QFile::rename(oldPath, oldPath+".old"))
+ qDebug() << "Renaming successful.";
+ else
+ qDebug() << "Renaming did not work, but it's okay. It will just remain with original name there.";
+ }
+ else
+ qDebug() << "Migration (copying) failed.";
+
+ return true;
+}
+
void ConfigImpl::refreshSqlHistory()
{
if (sqlHistoryModel)
diff --git a/SQLiteStudio3/coreSQLiteStudio/services/impl/configimpl.h b/SQLiteStudio3/coreSQLiteStudio/services/impl/configimpl.h
index 561aab4..710fbb3 100644
--- a/SQLiteStudio3/coreSQLiteStudio/services/impl/configimpl.h
+++ b/SQLiteStudio3/coreSQLiteStudio/services/impl/configimpl.h
@@ -22,6 +22,7 @@ class API_EXPORT ConfigImpl : public Config
void cleanUp();
const QString& getConfigDir() const;
QString getConfigFilePath() const;
+ bool isInMemory() const;
void beginMassSave();
void commitMassSave();
@@ -104,6 +105,7 @@ class API_EXPORT ConfigImpl : public Config
QString getPortableConfigPath();
void initTables();
void initDbFile();
+ QList<QPair<QString, bool> > getStdDbPaths();
bool tryInitDbFile(const QPair<QString, bool>& dbPath);
QVariant deserializeValue(const QVariant& value) const;
@@ -131,9 +133,12 @@ class API_EXPORT ConfigImpl : public Config
void mergeMasterConfig();
void updateConfigDb();
+ bool tryToMigrateOldGlobalPath(const QString& oldPath, const QString& newPath);
+ QString getLegacyConfigPath();
static Config* instance;
static qint64 sqlHistoryId;
+ static QString memoryDbName;
Db* db = nullptr;
QString configDir;
diff --git a/SQLiteStudio3/coreSQLiteStudio/services/impl/dbmanagerimpl.cpp b/SQLiteStudio3/coreSQLiteStudio/services/impl/dbmanagerimpl.cpp
index 217c2b7..9086257 100644
--- a/SQLiteStudio3/coreSQLiteStudio/services/impl/dbmanagerimpl.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/services/impl/dbmanagerimpl.cpp
@@ -284,7 +284,7 @@ QString DbManagerImpl::quickAddDb(const QString& path, const QHash<QString, QVar
QString newName = DbManager::generateDbName(path);
newName = generateUniqueName(newName, DBLIST->getDbNames());
if (!DBLIST->addDb(newName, path, options, false))
- return QString::null;
+ return QString();
return newName;
}
diff --git a/SQLiteStudio3/coreSQLiteStudio/services/impl/pluginmanagerimpl.cpp b/SQLiteStudio3/coreSQLiteStudio/services/impl/pluginmanagerimpl.cpp
index c67156c..324f549 100644
--- a/SQLiteStudio3/coreSQLiteStudio/services/impl/pluginmanagerimpl.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/services/impl/pluginmanagerimpl.cpp
@@ -87,7 +87,7 @@ QStringList PluginManagerImpl::getPluginDirs() const
QString PluginManagerImpl::getFilePath(Plugin* plugin) const
{
if (!pluginContainer.contains(plugin->getName()))
- return QString::null;
+ return QString();
return pluginContainer[plugin->getName()]->filePath;
}
@@ -339,7 +339,13 @@ bool PluginManagerImpl::initPlugin(Plugin* plugin)
bool PluginManagerImpl::shouldAutoLoad(const QString& pluginName)
{
- QStringList loadedPlugins = CFG_CORE.General.LoadedPlugins.get().split(",", QString::SkipEmptyParts);
+ QStringList loadedPlugins = CFG_CORE.General.LoadedPlugins.get().split(",",
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
+ Qt::SkipEmptyParts
+#else
+ QString::SkipEmptyParts
+#endif
+ );
QStringList pair;
for (const QString& loadedPlugin : loadedPlugins)
{
@@ -385,7 +391,7 @@ PluginType* PluginManagerImpl::getPluginType(const QString& pluginName) const
QString PluginManagerImpl::getAuthor(const QString& pluginName) const
{
if (!pluginContainer.contains(pluginName))
- return QString::null;
+ return QString();
return pluginContainer[pluginName]->author;
}
@@ -393,7 +399,7 @@ QString PluginManagerImpl::getAuthor(const QString& pluginName) const
QString PluginManagerImpl::getTitle(const QString& pluginName) const
{
if (!pluginContainer.contains(pluginName))
- return QString::null;
+ return QString();
return pluginContainer[pluginName]->title;
}
@@ -401,7 +407,7 @@ QString PluginManagerImpl::getTitle(const QString& pluginName) const
QString PluginManagerImpl::getPrintableVersion(const QString& pluginName) const
{
if (!pluginContainer.contains(pluginName))
- return QString::null;
+ return QString();
return pluginContainer[pluginName]->printableVersion;
}
@@ -417,7 +423,7 @@ int PluginManagerImpl::getVersion(const QString& pluginName) const
QString PluginManagerImpl::getDescription(const QString& pluginName) const
{
if (!pluginContainer.contains(pluginName))
- return QString::null;
+ return QString();
return pluginContainer[pluginName]->description;
}
diff --git a/SQLiteStudio3/coreSQLiteStudio/services/importmanager.cpp b/SQLiteStudio3/coreSQLiteStudio/services/importmanager.cpp
index b9aa947..a06a743 100644
--- a/SQLiteStudio3/coreSQLiteStudio/services/importmanager.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/services/importmanager.cpp
@@ -67,7 +67,7 @@ void ImportManager::importToTable(Db* db, const QString& table, bool async)
importInProgress = true;
ImportWorker* worker = new ImportWorker(plugin, &importConfig, db, table);
- connect(worker, SIGNAL(finished(bool)), this, SLOT(finalizeImport(bool)));
+ connect(worker, SIGNAL(finished(bool, int)), this, SLOT(finalizeImport(bool, int)));
connect(worker, SIGNAL(createdTable(Db*,QString)), this, SLOT(handleTableCreated(Db*,QString)));
connect(this, SIGNAL(orderWorkerToInterrupt()), worker, SLOT(interrupt()));
@@ -87,13 +87,13 @@ bool ImportManager::isAnyPluginAvailable()
return PLUGINS->getLoadedPlugins<ImportPlugin>().size() > 0;
}
-void ImportManager::finalizeImport(bool result)
+void ImportManager::finalizeImport(bool result, int rowCount)
{
importInProgress = false;
emit importFinished();
if (result)
{
- notifyInfo(tr("Imported data to the table '%1' successfully.").arg(table));
+ notifyInfo(tr("Imported data to the table '%1' successfully. Number of imported rows: %2").arg(table, QString::number(rowCount)));
emit importSuccessful();
}
else
diff --git a/SQLiteStudio3/coreSQLiteStudio/services/importmanager.h b/SQLiteStudio3/coreSQLiteStudio/services/importmanager.h
index 5c6a73e..9e9b160 100644
--- a/SQLiteStudio3/coreSQLiteStudio/services/importmanager.h
+++ b/SQLiteStudio3/coreSQLiteStudio/services/importmanager.h
@@ -70,7 +70,7 @@ class API_EXPORT ImportManager : public PluginServiceBase
void interrupt();
private slots:
- void finalizeImport(bool result);
+ void finalizeImport(bool result, int rowCount);
void handleTableCreated(Db* db, const QString& table);
signals:
diff --git a/SQLiteStudio3/coreSQLiteStudio/services/pluginmanager.h b/SQLiteStudio3/coreSQLiteStudio/services/pluginmanager.h
index f771c2c..65aa8fa 100644
--- a/SQLiteStudio3/coreSQLiteStudio/services/pluginmanager.h
+++ b/SQLiteStudio3/coreSQLiteStudio/services/pluginmanager.h
@@ -344,7 +344,7 @@ class API_EXPORT PluginManager : public QObject
* the other one, if the first one is already loaded - and vice versa.
*
* Declaring conflicts for a plugin can be useful for example if somebody wants to proivde an alternative
- * implementation of SQLite2 database plugin, etc. In that case SQLiteStudio won't get confused in
+ * implementation of SQLCipher database plugin, etc. In that case SQLiteStudio won't get confused in
* deciding which plugin to use for supporting such databases.
*/
virtual QStringList getConflicts(const QString& pluginName) const = 0;
diff --git a/SQLiteStudio3/coreSQLiteStudio/services/updatemanager.cpp b/SQLiteStudio3/coreSQLiteStudio/services/updatemanager.cpp
index 87df73b..867ef58 100644
--- a/SQLiteStudio3/coreSQLiteStudio/services/updatemanager.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/services/updatemanager.cpp
@@ -7,29 +7,18 @@
#include <QRegularExpression>
#include <QCoreApplication>
#include <QFileInfo>
+#include <QNetworkRequest>
+#include <QNetworkAccessManager>
+#include <QNetworkReply>
+#include <QJsonDocument>
+#include <QJsonObject>
#include <QtConcurrent/QtConcurrentRun>
UpdateManager::UpdateManager(QObject *parent) :
QObject(parent)
{
- qRegisterMetaType<QList<UpdateManager::UpdateEntry>>();
-
- connect(this, SIGNAL(updatingError(QString)), NOTIFY_MANAGER, SLOT(error(QString)));
-
- QString updateBinary =
-#if defined(Q_OS_WIN)
- "UpdateSQLiteStudio.exe";
-#elif defined(Q_OS_LINUX)
- "UpdateSQLiteStudio";
-#elif defined(Q_OS_OSX)
- "../../UpdateSQLiteStudio.app/Contents/MacOS/UpdateSQLiteStudio";
-#else
- "";
-#endif
-
- if (!updateBinary.isEmpty()) {
- updateBinaryAbsolutePath = QFileInfo(QCoreApplication::applicationDirPath() + "/" + updateBinary).absoluteFilePath();
- }
+ connect(this, SIGNAL(updatingError(QString)), this, SLOT(handleUpdatingError(QString)));
+ netManager = new QNetworkAccessManager(this);
}
UpdateManager::~UpdateManager()
@@ -42,54 +31,14 @@ void UpdateManager::checkForUpdates()
if (!CFG_CORE.General.CheckUpdatesOnStartup.get())
return;
- if (updateBinaryAbsolutePath.isEmpty()) {
- qDebug() << "Updater binary not defined. Skipping updates checking.";
- return;
- }
-
- if (!QFileInfo(updateBinaryAbsolutePath).exists()) {
- QString errorDetails = tr("Updates installer executable is missing.");
- emit updatingError(tr("Unable to check for updates (%1)").arg(errorDetails.trimmed()));
- qWarning() << "Error while checking for updates: " << errorDetails;
- return;
- }
-
- QtConcurrent::run(this, &UpdateManager::checkForUpdatesAsync);
-}
-
-void UpdateManager::checkForUpdatesAsync()
-{
- QProcess proc;
- proc.start(updateBinaryAbsolutePath, {"--checkupdates"});
- if (!waitForProcess(proc))
+ static_qstring(url, "https://sqlitestudio.pl/rest/updates");
+ QNetworkRequest request(url);
+ QNetworkReply* response = netManager->get(request);
+ connect(response, &QNetworkReply::finished, [this, response]()
{
- QString errorDetails = QString::fromLocal8Bit(proc.readAllStandardError());
-
- if (errorDetails.toLower().contains("no updates")) {
- emit noUpdatesAvailable();
- return;
- }
-
- if (errorDetails.isEmpty())
- errorDetails = tr("details are unknown");
-
- emit updatingError(tr("Unable to check for updates (%1)").arg(errorDetails.trimmed()));
- qWarning() << "Error while checking for updates: " << errorDetails;
- return;
- }
-
- processCheckResults(proc.readAllStandardOutput());
-}
-
-void UpdateManager::update()
-{
- bool success = QProcess::startDetached(updateBinaryAbsolutePath, {"--updater"});
- if (!success)
- {
- emit updatingError(tr("Unable to run updater application (%1). Please report this.").arg(updateBinaryAbsolutePath));
- return;
- }
- qApp->exit(0);
+ response->deleteLater();
+ handleUpdatesResponse(response);
+ });
}
bool UpdateManager::isPlatformEligibleForUpdate() const
@@ -97,56 +46,50 @@ bool UpdateManager::isPlatformEligibleForUpdate() const
return getDistributionType() != DistributionType::OS_MANAGED;
}
-bool UpdateManager::waitForProcess(QProcess& proc)
+void UpdateManager::handleUpdatesResponse(QNetworkReply* response)
{
- if (!proc.waitForFinished(-1))
+ if (response->error() != QNetworkReply::NoError)
{
- qDebug() << "Update QProcess timed out.";
- return false;
+ emit updatingError(response->errorString());
+ return;
}
- if (proc.exitStatus() == QProcess::CrashExit)
- {
- qDebug() << "Update QProcess finished by crashing.";
- return false;
- }
+ QJsonParseError parsingError;
+ QJsonDocument json = QJsonDocument::fromJson(response->readAll(), &parsingError);
- if (proc.exitCode() != 0)
+ if (parsingError.error != QJsonParseError::NoError)
{
- qDebug() << "Update QProcess finished with code:" << proc.exitCode();
- return false;
+ emit updatingError(parsingError.errorString());
+ return;
}
- return true;
-}
+ QString version = json["version"].toString();
+ QStringList versionParts = version.split(".");
+ QString alignedVersion = versionParts[0] + versionParts[1].rightJustified(2, '0') + versionParts[2].rightJustified(2, '0');
+ int versionNumber = alignedVersion.toInt();
-void UpdateManager::processCheckResults(const QByteArray &results)
-{
- if (results.trimmed().isEmpty()) {
+ if (SQLITESTUDIO->getVersion() >= versionNumber)
+ {
emit noUpdatesAvailable();
return;
}
- QRegularExpression re(R"(\<update\s+([^\>]+)\>)");
- QRegularExpression versionRe(R"(version\=\"([\d\.]+)\")");
- QRegularExpression nameRe(R"(name\=\"([^\"]+)\")");
+#if defined(Q_OS_WIN)
+ QString url = json["win"].toString();
+#elif defined(Q_OS_LINUX)
+ QString url = json["lin"].toString();
+#elif defined(Q_OS_OSX)
+ QString url = json["mac"].toString();
+#else
+ QString url = jsonQString();
+#endif
- QRegularExpressionMatchIterator reIter = re.globalMatch(results);
- QString updateNode;
- UpdateEntry theUpdate;
- QList<UpdateEntry> updates;
- while (reIter.hasNext())
- {
- updateNode = reIter.next().captured(1);
- theUpdate.version = versionRe.match(updateNode).captured(1);
- theUpdate.compontent = nameRe.match(updateNode).captured(1);
- updates << theUpdate;
- }
+ emit updateAvailable(version, url);
+}
- if (updates.isEmpty())
- emit noUpdatesAvailable();
- else
- emit updatesAvailable(updates);
+void UpdateManager::handleUpdatingError(const QString& errorMessage)
+{
+ NOTIFY_MANAGER->warn(tr("Could not check for updates (%1).").arg(errorMessage));
}
#endif // PORTABLE_CONFIG
diff --git a/SQLiteStudio3/coreSQLiteStudio/services/updatemanager.h b/SQLiteStudio3/coreSQLiteStudio/services/updatemanager.h
index 50f4b6b..d7f59ca 100644
--- a/SQLiteStudio3/coreSQLiteStudio/services/updatemanager.h
+++ b/SQLiteStudio3/coreSQLiteStudio/services/updatemanager.h
@@ -9,8 +9,8 @@
#include <functional>
#include <QProcess>
-class QNetworkAccessManager;
class QNetworkReply;
+class QNetworkAccessManager;
class QTemporaryDir;
class QFile;
@@ -18,34 +18,27 @@ class API_EXPORT UpdateManager : public QObject
{
Q_OBJECT
public:
- struct UpdateEntry
- {
- QString compontent;
- QString version;
- };
-
explicit UpdateManager(QObject *parent = 0);
~UpdateManager();
void checkForUpdates();
- void update();
bool isPlatformEligibleForUpdate() const;
private:
QString updateBinaryAbsolutePath;
+ QNetworkAccessManager *netManager = nullptr;
- void checkForUpdatesAsync();
- bool waitForProcess(QProcess& proc);
- void processCheckResults(const QByteArray& results);
+ void handleUpdatesResponse(QNetworkReply* response);
+
+ private slots:
+ void handleUpdatingError(const QString& errorMessage);
signals:
- void updatesAvailable(const QList<UpdateManager::UpdateEntry>& updates);
+ void updateAvailable(const QString& version, const QString& url);
void noUpdatesAvailable();
void updatingError(const QString& errorMessage);
};
-Q_DECLARE_METATYPE(QList<UpdateManager::UpdateEntry>)
-
#define UPDATES SQLITESTUDIO->getUpdateManager()
#endif // PORTABLE_CONFIG