parent
1f2e1f32de
commit
9344c69b8e
|
@ -36,6 +36,7 @@ Updating the database schema is slightly complicated, and the following rules mu
|
||||||
* This will create file in the `migrations` folder with the indicated name and a timestamp
|
* This will create file in the `migrations` folder with the indicated name and a timestamp
|
||||||
* This should also add this migration to the qrc file. However, if this is not done, you can do this manually by editing the `rs_migrations.qrc` file.
|
* This should also add this migration to the qrc file. However, if this is not done, you can do this manually by editing the `rs_migrations.qrc` file.
|
||||||
2. Inside the new migration file, add the necessary sql to apply the db change under `-- +migrate Up`
|
2. Inside the new migration file, add the necessary sql to apply the db change under `-- +migrate Up`
|
||||||
|
* This section must come first.
|
||||||
3. Inside the new migration file, add the necessary sql to _undo_ the db change under `-- +migrate Down`
|
3. Inside the new migration file, add the necessary sql to _undo_ the db change under `-- +migrate Down`
|
||||||
4. Only one statement is allowed under each heading. If multiple statements need to be applied, they should done as multiple migration files
|
4. Only one statement is allowed under each heading. If multiple statements need to be applied, they should done as multiple migration files
|
||||||
* This is a sqlite3/Qt limitation.
|
* This is a sqlite3/Qt limitation.
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
|
|
||||||
#include "codeeditor.h"
|
#include "codeeditor.h"
|
||||||
#include "exceptions/fileerror.h"
|
|
||||||
#include "helpers/ui_helpers.h"
|
#include "helpers/ui_helpers.h"
|
||||||
|
|
||||||
CodeBlockView::CodeBlockView(QWidget* parent)
|
CodeBlockView::CodeBlockView(QWidget* parent)
|
||||||
|
|
|
@ -179,32 +179,28 @@ SaveEvidenceResponse EvidenceEditor::saveEvidence() {
|
||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<DeleteEvidenceResponse> EvidenceEditor::deleteEvidence(QList<qint64> evidenceIDs) {
|
QList<DeleteEvidenceResponse> EvidenceEditor::deleteEvidence(QList<qint64> evidenceIDs)
|
||||||
|
{
|
||||||
QList<DeleteEvidenceResponse> responses;
|
QList<DeleteEvidenceResponse> responses;
|
||||||
|
|
||||||
for (qint64 id : evidenceIDs) {
|
for (qint64 id : evidenceIDs) {
|
||||||
model::Evidence evi = db->getEvidenceDetails(id);
|
model::Evidence evi = db->getEvidenceDetails(id);
|
||||||
DeleteEvidenceResponse resp(evi);
|
DeleteEvidenceResponse resp(evi);
|
||||||
|
|
||||||
try{
|
try{
|
||||||
db->deleteEvidence(evi.id);
|
resp.dbDeleteSuccess = db->deleteEvidence(evi.id);
|
||||||
resp.dbDeleteSuccess = true;
|
} catch(QSqlError &e) {
|
||||||
}
|
|
||||||
catch(QSqlError &e) {
|
|
||||||
resp.dbDeleteSuccess = false;
|
|
||||||
resp.errorText = e.text();
|
resp.errorText = e.text();
|
||||||
}
|
}
|
||||||
auto localFile = new QFile(evi.path);
|
|
||||||
if (!localFile->remove()) {
|
auto localFile = QFile(evi.path);
|
||||||
|
if (!localFile.remove()) {
|
||||||
resp.fileDeleteSuccess = false;
|
resp.fileDeleteSuccess = false;
|
||||||
resp.errorText += "\n" + localFile->errorString();
|
resp.errorText.append(QStringLiteral("\n%1").arg(localFile.errorString()));
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
resp.fileDeleteSuccess = true;
|
resp.fileDeleteSuccess = true;
|
||||||
}
|
}
|
||||||
localFile->deleteLater(); // deletes the pointer, not the file
|
|
||||||
resp.errorText = resp.errorText.trimmed();
|
resp.errorText = resp.errorText.trimmed();
|
||||||
responses.append(resp);
|
responses.append(resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
return responses;
|
return responses;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,28 +6,16 @@
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
|
||||||
#include "exceptions/databaseerr.h"
|
|
||||||
#include "exceptions/fileerror.h"
|
#include "exceptions/fileerror.h"
|
||||||
#include "helpers/file_helpers.h"
|
#include "helpers/file_helpers.h"
|
||||||
|
|
||||||
// DatabaseConnection constructs a connection to the database, unsurpringly. Note that the
|
DatabaseConnection::DatabaseConnection(const QString& dbPath, const QString& databaseName)
|
||||||
// constructor can throw a error (see below). Additionally, many methods can throw a QSqlError,
|
: _dbName(databaseName)
|
||||||
// though are not marked as such in their comments. Other errors are listed in throw comments, or
|
, _dbPath(dbPath)
|
||||||
// are marked as noexcept if no error is possible.
|
{
|
||||||
//
|
auto db = QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"), databaseName);
|
||||||
// Throws: DBDriverUnavailable if the required database driver does not exist
|
|
||||||
DatabaseConnection::DatabaseConnection(const QString& dbPath, QString databaseName) {
|
|
||||||
const static QString dbDriver = "QSQLITE";
|
|
||||||
if (QSqlDatabase::isDriverAvailable(dbDriver)) {
|
|
||||||
dbName = std::move(databaseName);
|
|
||||||
auto db = QSqlDatabase::addDatabase(dbDriver, dbName);
|
|
||||||
QDir().mkpath(FileHelpers::getDirname(dbPath));
|
QDir().mkpath(FileHelpers::getDirname(dbPath));
|
||||||
db.setDatabaseName(dbPath);
|
db.setDatabaseName(dbPath);
|
||||||
this->_dbPath = dbPath;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw DBDriverUnavailableError("SQLite");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseConnection::withConnection(const QString& dbPath, const QString &dbName,
|
void DatabaseConnection::withConnection(const QString& dbPath, const QString &dbName,
|
||||||
|
@ -45,12 +33,14 @@ void DatabaseConnection::withConnection(const QString& dbPath, const QString &db
|
||||||
QSqlDatabase::removeDatabase(dbName);
|
QSqlDatabase::removeDatabase(dbName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseConnection::connect() {
|
bool DatabaseConnection::connect()
|
||||||
|
{
|
||||||
auto db = getDB();
|
auto db = getDB();
|
||||||
if (!db.open()) {
|
if (!db.open()) {
|
||||||
|
return false;
|
||||||
throw db.lastError();
|
throw db.lastError();
|
||||||
}
|
}
|
||||||
migrateDB();
|
return migrateDB();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseConnection::close() noexcept { getDB().close(); }
|
void DatabaseConnection::close() noexcept { getDB().close(); }
|
||||||
|
@ -137,8 +127,13 @@ void DatabaseConnection::updateEvidenceDescription(const QString &newDescription
|
||||||
executeQuery(getDB(), "UPDATE evidence SET description=? WHERE id=?", {newDescription, evidenceID});
|
executeQuery(getDB(), "UPDATE evidence SET description=? WHERE id=?", {newDescription, evidenceID});
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseConnection::deleteEvidence(qint64 evidenceID) {
|
bool DatabaseConnection::deleteEvidence(qint64 evidenceID)
|
||||||
executeQuery(getDB(), "DELETE FROM evidence WHERE id=?", {evidenceID});
|
{
|
||||||
|
auto q = executeQuery(getDB(), "DELETE FROM evidence WHERE id=?", {evidenceID});
|
||||||
|
if (q.lastError().type() == QSqlError::NoError)
|
||||||
|
return true;
|
||||||
|
QTextStream(stderr) << "Unable to Delete " << evidenceID << " " << q.lastError().text();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseConnection::updateEvidenceError(const QString &errorText, qint64 evidenceID) {
|
void DatabaseConnection::updateEvidenceError(const QString &errorText, qint64 evidenceID) {
|
||||||
|
@ -339,7 +334,7 @@ QList<model::Evidence> DatabaseConnection::createEvidenceExportView(
|
||||||
// lacking update.
|
// lacking update.
|
||||||
//
|
//
|
||||||
// Throws exceptions/FileError if a migration file cannot be found.
|
// Throws exceptions/FileError if a migration file cannot be found.
|
||||||
void DatabaseConnection::migrateDB() {
|
bool DatabaseConnection::migrateDB() {
|
||||||
auto db = getDB();
|
auto db = getDB();
|
||||||
QTextStream(stdout) << "Checking database state" << Qt::endl;
|
QTextStream(stdout) << "Checking database state" << Qt::endl;
|
||||||
auto migrationsToApply = DatabaseConnection::getUnappliedMigrations(db);
|
auto migrationsToApply = DatabaseConnection::getUnappliedMigrations(db);
|
||||||
|
@ -347,10 +342,8 @@ void DatabaseConnection::migrateDB() {
|
||||||
for (const QString &newMigration : migrationsToApply) {
|
for (const QString &newMigration : migrationsToApply) {
|
||||||
QFile migrationFile(QStringLiteral(":/migrations/%1").arg(newMigration));
|
QFile migrationFile(QStringLiteral(":/migrations/%1").arg(newMigration));
|
||||||
auto ok = migrationFile.open(QFile::ReadOnly);
|
auto ok = migrationFile.open(QFile::ReadOnly);
|
||||||
if (!ok) {
|
if (!ok)
|
||||||
throw FileError::mkError("Error reading migration file",
|
return false;
|
||||||
migrationFile.fileName().toStdString(), migrationFile.error());
|
|
||||||
}
|
|
||||||
auto content = QString(migrationFile.readAll());
|
auto content = QString(migrationFile.readAll());
|
||||||
migrationFile.close();
|
migrationFile.close();
|
||||||
|
|
||||||
|
@ -362,6 +355,7 @@ void DatabaseConnection::migrateDB() {
|
||||||
{newMigration});
|
{newMigration});
|
||||||
}
|
}
|
||||||
QTextStream(stdout) << "All migrations applied" << Qt::endl;
|
QTextStream(stdout) << "All migrations applied" << Qt::endl;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// getUnappliedMigrations retrieves a list of all of the migrations that have not been applied
|
// getUnappliedMigrations retrieves a list of all of the migrations that have not been applied
|
||||||
|
@ -372,10 +366,10 @@ void DatabaseConnection::migrateDB() {
|
||||||
// Throws:
|
// Throws:
|
||||||
// * BadDatabaseStateError if some migrations have been applied that are not known
|
// * BadDatabaseStateError if some migrations have been applied that are not known
|
||||||
// * QSqlError if database queries fail
|
// * QSqlError if database queries fail
|
||||||
QStringList DatabaseConnection::getUnappliedMigrations(const QSqlDatabase &db) {
|
QStringList DatabaseConnection::getUnappliedMigrations(const QSqlDatabase &db)
|
||||||
|
{
|
||||||
QDir migrationsDir(QStringLiteral(":/migrations"));
|
QDir migrationsDir(QStringLiteral(":/migrations"));
|
||||||
|
const auto allMigrations = migrationsDir.entryList(QDir::Files, QDir::Name);
|
||||||
auto allMigrations = migrationsDir.entryList(QDir::Files, QDir::Name);
|
|
||||||
QStringList appliedMigrations;
|
QStringList appliedMigrations;
|
||||||
QStringList migrationsToApply;
|
QStringList migrationsToApply;
|
||||||
|
|
||||||
|
@ -386,19 +380,17 @@ QStringList DatabaseConnection::getUnappliedMigrations(const QSqlDatabase &db) {
|
||||||
}
|
}
|
||||||
// compare the two list to find gaps
|
// compare the two list to find gaps
|
||||||
for (const QString &possibleMigration : allMigrations) {
|
for (const QString &possibleMigration : allMigrations) {
|
||||||
if (!possibleMigration.endsWith(QStringLiteral(".sql"))) {
|
if (!possibleMigration.endsWith(QStringLiteral(".sql")))
|
||||||
continue; // assume non-sql files aren't actual migrations.
|
continue; // assume non-sql files aren't actual migrations.
|
||||||
}
|
|
||||||
auto foundIndex = appliedMigrations.indexOf(possibleMigration);
|
auto foundIndex = appliedMigrations.indexOf(possibleMigration);
|
||||||
if (foundIndex == -1) {
|
if (foundIndex == -1)
|
||||||
migrationsToApply << possibleMigration;
|
migrationsToApply << possibleMigration;
|
||||||
}
|
else
|
||||||
else {
|
|
||||||
appliedMigrations.removeAt(foundIndex);
|
appliedMigrations.removeAt(foundIndex);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (!appliedMigrations.empty()) {
|
if (!appliedMigrations.empty()) {
|
||||||
throw BadDatabaseStateError();
|
QTextStream(stderr) << "Database is in an inconsistent state";
|
||||||
}
|
}
|
||||||
return migrationsToApply;
|
return migrationsToApply;
|
||||||
}
|
}
|
||||||
|
@ -406,21 +398,15 @@ QStringList DatabaseConnection::getUnappliedMigrations(const QSqlDatabase &db) {
|
||||||
// extractMigrateUpContent parses the given migration content and retrieves only
|
// extractMigrateUpContent parses the given migration content and retrieves only
|
||||||
// the portion that applies to the "up" / apply logic. The "down" section is ignored.
|
// the portion that applies to the "up" / apply logic. The "down" section is ignored.
|
||||||
QString DatabaseConnection::extractMigrateUpContent(const QString &allContent) noexcept {
|
QString DatabaseConnection::extractMigrateUpContent(const QString &allContent) noexcept {
|
||||||
auto copying = false;
|
|
||||||
QString upContent;
|
QString upContent;
|
||||||
for (const QString &line : allContent.split("\n")) {
|
const QStringList lines = allContent.split(_newLine);
|
||||||
if (line.trimmed().toLower() == "-- +migrate up") {
|
for (const QString &line : lines) {
|
||||||
copying = true;
|
auto lowerLine = line.trimmed().toLower();
|
||||||
}
|
if (lowerLine == _migrateUp)
|
||||||
else if (line.trimmed().toLower() == "-- +migrate down") {
|
continue;
|
||||||
if (copying) {
|
else if (lowerLine == _migrateDown)
|
||||||
break;
|
break;
|
||||||
}
|
upContent.append(_lineTemplate.arg(line));
|
||||||
copying = false;
|
|
||||||
}
|
|
||||||
else if (copying) {
|
|
||||||
upContent.append(line + "\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return upContent;
|
return upContent;
|
||||||
}
|
}
|
||||||
|
@ -465,14 +451,13 @@ qint64 DatabaseConnection::doInsert(const QSqlDatabase& db, const QString &stmt,
|
||||||
return query.lastInsertId().toLongLong();
|
return query.lastInsertId().toLongLong();
|
||||||
}
|
}
|
||||||
|
|
||||||
QSqlDatabase DatabaseConnection::getDB() {
|
QSqlDatabase DatabaseConnection::getDB()
|
||||||
if (dbName.isEmpty()) {
|
{
|
||||||
return QSqlDatabase::database();
|
return QSqlDatabase::database(_dbName);
|
||||||
}
|
|
||||||
return QSqlDatabase::database(dbName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString DatabaseConnection::getDatabasePath() {
|
QString DatabaseConnection::getDatabasePath()
|
||||||
|
{
|
||||||
return _dbPath;
|
return _dbPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,17 +24,20 @@ class DBQuery {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DBQuery(QString query) : DBQuery(query, {}) {}
|
DBQuery(QString query) : DBQuery(query, {}) {}
|
||||||
DBQuery(QString query, QVariantList values) {
|
DBQuery(QString query, QVariantList values) :_query(query), _values(values) { }
|
||||||
this->_query = query;
|
|
||||||
this->_values = values;
|
|
||||||
}
|
|
||||||
inline QString query() { return _query; }
|
inline QString query() { return _query; }
|
||||||
inline QVariantList values() { return _values; }
|
inline QVariantList values() { return _values; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class DatabaseConnection {
|
class DatabaseConnection {
|
||||||
public:
|
public:
|
||||||
DatabaseConnection(const QString& dbPath, QString databaseName);
|
/**
|
||||||
|
* @brief DatabaseConnection construct a connect to the database,
|
||||||
|
* Uses QSQLite Driver if the driver is missing the app to exit with code 255.
|
||||||
|
* @param dbPath - Path to the database
|
||||||
|
* @param databaseName - Name of the databaseFile or defaultName if none provided
|
||||||
|
*/
|
||||||
|
DatabaseConnection(const QString& dbPath, const QString& databaseName = Constants::defaultDbName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief withConnection acts as a context manager for a single database connection. The goal for
|
* @brief withConnection acts as a context manager for a single database connection. The goal for
|
||||||
|
@ -49,7 +52,7 @@ class DatabaseConnection {
|
||||||
static void withConnection(const QString& dbPath, const QString &dbName,
|
static void withConnection(const QString& dbPath, const QString &dbName,
|
||||||
const std::function<void(DatabaseConnection)> &actions);
|
const std::function<void(DatabaseConnection)> &actions);
|
||||||
|
|
||||||
void connect();
|
bool connect();
|
||||||
void close() noexcept;
|
void close() noexcept;
|
||||||
|
|
||||||
static DBQuery buildGetEvidenceWithFiltersQuery(const EvidenceFilters &filters);
|
static DBQuery buildGetEvidenceWithFiltersQuery(const EvidenceFilters &filters);
|
||||||
|
@ -71,7 +74,12 @@ class DatabaseConnection {
|
||||||
void batchCopyTags(const QList<model::Tag> &allTags);
|
void batchCopyTags(const QList<model::Tag> &allTags);
|
||||||
QList<model::Tag> getFullTagsForEvidenceIDs(const QList<qint64>& evidenceIDs);
|
QList<model::Tag> getFullTagsForEvidenceIDs(const QList<qint64>& evidenceIDs);
|
||||||
|
|
||||||
void deleteEvidence(qint64 evidenceID);
|
/**
|
||||||
|
* @brief deleteEvidence Delete Evidence from the database
|
||||||
|
* @param evidenceID - ID To Delete
|
||||||
|
* @return true if successful
|
||||||
|
*/
|
||||||
|
bool deleteEvidence(qint64 evidenceID);
|
||||||
|
|
||||||
/// createEvidenceExportView duplicates the normal database with only a subset of evidence
|
/// createEvidenceExportView duplicates the normal database with only a subset of evidence
|
||||||
/// present, as well as related data (e.g. tags)
|
/// present, as well as related data (e.g. tags)
|
||||||
|
@ -90,10 +98,14 @@ class DatabaseConnection {
|
||||||
const unsigned long SQLITE_MAX_VARS = 999;
|
const unsigned long SQLITE_MAX_VARS = 999;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString dbName;
|
QString _dbName;
|
||||||
QString _dbPath;
|
QString _dbPath;
|
||||||
|
inline static const auto _migrateUp = QStringLiteral("-- +migrate up");
|
||||||
|
inline static const auto _migrateDown = QStringLiteral("-- +migrate down");
|
||||||
|
inline static const auto _newLine = QStringLiteral("\n");
|
||||||
|
inline static const auto _lineTemplate =QStringLiteral("%1").append(_newLine);
|
||||||
|
|
||||||
void migrateDB();
|
bool migrateDB();
|
||||||
QSqlDatabase getDB();
|
QSqlDatabase getDB();
|
||||||
|
|
||||||
static QStringList getUnappliedMigrations(const QSqlDatabase &db);
|
static QStringList getUnappliedMigrations(const QSqlDatabase &db);
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
|
|
||||||
add_library (EXCEPTIONS STATIC
|
add_library (EXCEPTIONS STATIC fileerror.h)
|
||||||
databaseerr.h
|
|
||||||
fileerror.h
|
|
||||||
)
|
|
||||||
|
|
||||||
add_library(ASHIRT::EXCEPTIONS ALIAS EXCEPTIONS)
|
add_library(ASHIRT::EXCEPTIONS ALIAS EXCEPTIONS)
|
||||||
|
|
||||||
|
@ -12,8 +9,4 @@ target_include_directories (EXCEPTIONS
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries ( EXCEPTIONS PUBLIC
|
target_link_libraries ( EXCEPTIONS PUBLIC Qt::Core)
|
||||||
Qt::Core
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
// Copyright 2020, Verizon Media
|
|
||||||
// Licensed under the terms of MIT. See LICENSE file in project root for terms.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
class BadDatabaseStateError : public std::runtime_error {
|
|
||||||
public:
|
|
||||||
BadDatabaseStateError() : std::runtime_error("Database is in an inconsistent state") {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class DBDriverUnavailableError : public std::runtime_error {
|
|
||||||
public:
|
|
||||||
DBDriverUnavailableError(std::string friendlyDriverName)
|
|
||||||
: std::runtime_error(friendlyDriverName + " driver is unavailable") {}
|
|
||||||
};
|
|
|
@ -118,13 +118,8 @@ void GetInfo::deleteButtonClicked() {
|
||||||
.arg(evi.path));
|
.arg(evi.path));
|
||||||
shouldClose = false;
|
shouldClose = false;
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
db->deleteEvidence(evidenceID);
|
db->deleteEvidence(evidenceID);
|
||||||
}
|
|
||||||
catch (QSqlError& e) {
|
|
||||||
QTextStream(stderr) << "Could not delete evidence from internal database. Error: "
|
|
||||||
<< e.text() << Qt::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_EMIT setActionButtonsEnabled(true);
|
Q_EMIT setActionButtonsEnabled(true);
|
||||||
if (shouldClose) {
|
if (shouldClose) {
|
||||||
|
|
33
src/main.cpp
33
src/main.cpp
|
@ -16,7 +16,6 @@ void handleCLI(std::vector<std::string> args);
|
||||||
#include "appconfig.h"
|
#include "appconfig.h"
|
||||||
#include "appsettings.h"
|
#include "appsettings.h"
|
||||||
#include "db/databaseconnection.h"
|
#include "db/databaseconnection.h"
|
||||||
#include "exceptions/databaseerr.h"
|
|
||||||
#include "exceptions/fileerror.h"
|
#include "exceptions/fileerror.h"
|
||||||
#include "traymanager.h"
|
#include "traymanager.h"
|
||||||
|
|
||||||
|
@ -32,25 +31,10 @@ int main(int argc, char* argv[]) {
|
||||||
QCoreApplication::setOrganizationName("ashirt");
|
QCoreApplication::setOrganizationName("ashirt");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DatabaseConnection* conn;
|
|
||||||
try {
|
DatabaseConnection* conn = new DatabaseConnection(Constants::dbLocation, Constants::defaultDbName);
|
||||||
conn = new DatabaseConnection(Constants::dbLocation, Constants::defaultDbName);
|
if(!conn->connect()) {
|
||||||
conn->connect();
|
QTextStream(stderr) << "Unable to connect to Database" << Qt::endl;
|
||||||
}
|
|
||||||
catch (FileError& err) {
|
|
||||||
QTextStream(stderr) << err.what() << Qt::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
catch (DBDriverUnavailableError& err) {
|
|
||||||
QTextStream(stderr) << err.what() << Qt::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
catch (QSqlError& e) {
|
|
||||||
QTextStream(stderr) << e.text() << Qt::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
catch (std::exception& e) {
|
|
||||||
QTextStream(stderr) << "Unexpected error: " << e.what() << Qt::endl;
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,11 +50,17 @@ int main(int argc, char* argv[]) {
|
||||||
qRegisterMetaType<model::Tag>();
|
qRegisterMetaType<model::Tag>();
|
||||||
|
|
||||||
app.setWindowIcon(getWindowIcon());
|
app.setWindowIcon(getWindowIcon());
|
||||||
|
|
||||||
if (!QSystemTrayIcon::isSystemTrayAvailable()) {
|
if (!QSystemTrayIcon::isSystemTrayAvailable()) {
|
||||||
handleCLI(std::vector<std::string>(argv, argv + argc));
|
handleCLI(std::vector<std::string>(argv, argv + argc));
|
||||||
}
|
}
|
||||||
QApplication::setQuitOnLastWindowClosed(false);
|
QApplication::setQuitOnLastWindowClosed(false);
|
||||||
|
|
||||||
|
QObject::connect(&app, &QApplication::aboutToQuit, [conn] {
|
||||||
|
conn->close();
|
||||||
|
delete conn;
|
||||||
|
});
|
||||||
|
|
||||||
auto window = new TrayManager(nullptr, conn);
|
auto window = new TrayManager(nullptr, conn);
|
||||||
rtn = app.exec();
|
rtn = app.exec();
|
||||||
AppSettings::getInstance().sync();
|
AppSettings::getInstance().sync();
|
||||||
|
@ -82,9 +72,6 @@ int main(int argc, char* argv[]) {
|
||||||
catch (...) {
|
catch (...) {
|
||||||
QTextStream(stderr) << "Unhandled exception while running" << Qt::endl;
|
QTextStream(stderr) << "Unhandled exception while running" << Qt::endl;
|
||||||
}
|
}
|
||||||
conn->close();
|
|
||||||
delete conn;
|
|
||||||
|
|
||||||
return rtn;
|
return rtn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@ class Codeblock {
|
||||||
/**
|
/**
|
||||||
* @brief readCodeblock parses a local codeblock file and returns back the data as a codeblock
|
* @brief readCodeblock parses a local codeblock file and returns back the data as a codeblock
|
||||||
* @param filepath The path to the codeblock file
|
* @param filepath The path to the codeblock file
|
||||||
* @throws a FileError if any issues occur while reading the file
|
|
||||||
* @return a parsed Codeblock object, ready for use.
|
* @return a parsed Codeblock object, ready for use.
|
||||||
*/
|
*/
|
||||||
static Codeblock readCodeblock(const QString& filepath);
|
static Codeblock readCodeblock(const QString& filepath);
|
||||||
|
@ -53,9 +52,7 @@ class Codeblock {
|
||||||
QByteArray encode();
|
QByteArray encode();
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief saveCodeblock encodes the provided codeblock, then writes that codeblock to it's
|
* @brief saveCodeblock encodes the provided codeblock, then writes that codeblock to it's filePath
|
||||||
* filePath
|
|
||||||
* @throws a FileError if any issues occur while writing the file
|
|
||||||
* @param codeblock The codeblock to save
|
* @param codeblock The codeblock to save
|
||||||
*/
|
*/
|
||||||
static bool saveCodeblock(Codeblock codeblock);
|
static bool saveCodeblock(Codeblock codeblock);
|
||||||
|
|
Loading…
Reference in New Issue