Change the way how the database is exported to file

The export of internal database to file is now do by sqlite3 native
function instead of a dirty home made function.
For the moment, the export to file function is unavailable on macOSX (we
need some help to add sqlite3 lib on macOSX)
This commit is contained in:
Claveau Joshua 2020-09-16 21:28:47 +02:00
parent 8e82dee8f0
commit 139241e773
4 changed files with 130 additions and 105 deletions

View File

@ -212,6 +212,7 @@ TARGET = qelectrotech
# Ajustement des bibliotheques utilisees lors de l'edition des liens
unix:QMAKE_LIBS_THREAD -= -lpthread
unix|win32: LIBS += -lsqlite3
# Enable C++11
QMAKE_CXXFLAGS += -std=c++11

View File

@ -25,6 +25,11 @@
#include <QSqlError>
#if defined(Q_OS_LINUX) || defined(Q_OS_WINDOWS)
#include <QSqlDriver>
#include <sqlite3.h>
#endif
/**
@brief projectDataBase::projectDataBase
Default constructor
@ -38,13 +43,6 @@ projectDataBase::projectDataBase(QETProject *project, QObject *parent) :
createDataBase();
}
projectDataBase::projectDataBase(QETProject *project, const QString &connection_name, const QString &path, QObject *parent) :
QObject(parent),
m_project(project)
{
createDataBase(connection_name, path);
}
/**
@brief projectDataBase::~projectDataBase
Destructor
@ -193,95 +191,81 @@ void projectDataBase::removeDiagram(Diagram *diagram)
Create the data base
@return : true if the data base was successfully created.
*/
bool projectDataBase::createDataBase(const QString &connection_name, const QString &name)
bool projectDataBase::createDataBase()
{
m_data_base = QSqlDatabase::addDatabase("QSQLITE", "qet_project_db_" + m_project->uuid().toString());
if(!m_data_base.open()) {
m_data_base.close();
return false;
}
QString connect_name = connection_name;
if (connect_name.isEmpty()) {
connect_name = "qet_project_db_" + m_project->uuid().toString();
m_data_base.exec("PRAGMA temp_store = MEMORY");
m_data_base.exec("PRAGMA journal_mode = MEMORY");
m_data_base.exec("PRAGMA synchronous = OFF");
QSqlQuery query_(m_data_base);
bool first_ = true;
//Create diagram table
QString diagram_table("CREATE TABLE diagram ("
"uuid VARCHAR(50) PRIMARY KEY NOT NULL,"
"pos INTEGER)");
if (!query_.exec(diagram_table)) {
qDebug() << "diagram_table query : "<< query_.lastError();
}
if (m_data_base.connectionNames().contains(connect_name)) {
m_data_base = QSqlDatabase::database(connect_name);
//Create the table element
QString element_table("CREATE TABLE element"
"( "
"uuid VARCHAR(50) PRIMARY KEY NOT NULL, "
"diagram_uuid VARCHAR(50) NOT NULL,"
"pos VARCHAR(6) NOT NULL,"
"type VARCHAR(50),"
"sub_type VARCHAR(50),"
"FOREIGN KEY (diagram_uuid) REFERENCES diagram (uuid)"
")");
if (!query_.exec(element_table)) {
qDebug() <<" element_table query : "<< query_.lastError();
}
else
//Create the diagram info table
QString diagram_info_table("CREATE TABLE diagram_info (diagram_uuid VARCHAR(50) PRIMARY KEY NOT NULL, ");
first_ = true;
for (auto string : QETApp::diagramInfoKeys())
{
m_data_base = QSqlDatabase::addDatabase("QSQLITE", connect_name);
m_data_base.setDatabaseName(name);
if(!m_data_base.open()) {
m_data_base.close();
return false;
if (first_) {
first_ = false;
} else {
diagram_info_table += ", ";
}
m_data_base.exec("PRAGMA temp_store = MEMORY");
m_data_base.exec("PRAGMA journal_mode = MEMORY");
m_data_base.exec("PRAGMA synchronous = OFF");
m_data_base.exec("PRAGMA foreign_keys = ON");
QSqlQuery query_(m_data_base);
bool first_ = true;
//Create diagram table
QString diagram_table("CREATE TABLE diagram ("
"uuid VARCHAR(50) PRIMARY KEY NOT NULL,"
"pos INTEGER)");
if (!query_.exec(diagram_table)) {
qDebug() << "diagram_table query : "<< query_.lastError();
}
//Create the table element
QString element_table("CREATE TABLE element"
"( "
"uuid VARCHAR(50) PRIMARY KEY NOT NULL, "
"diagram_uuid VARCHAR(50) NOT NULL,"
"pos VARCHAR(6) NOT NULL,"
"type VARCHAR(50),"
"sub_type VARCHAR(50),"
"FOREIGN KEY (diagram_uuid) REFERENCES diagram (uuid) ON DELETE CASCADE"
")");
if (!query_.exec(element_table)) {
qDebug() <<" element_table query : "<< query_.lastError();
}
//Create the diagram info table
QString diagram_info_table("CREATE TABLE diagram_info (diagram_uuid VARCHAR(50) PRIMARY KEY NOT NULL, ");
first_ = true;
for (auto string : QETApp::diagramInfoKeys())
{
if (first_) {
first_ = false;
} else {
diagram_info_table += ", ";
}
diagram_info_table += string += string=="date" ? " DATE" : " VARCHAR(100)";
}
diagram_info_table += ", FOREIGN KEY (diagram_uuid) REFERENCES diagram (uuid) ON DELETE CASCADE)";
if (!query_.exec(diagram_info_table)) {
qDebug() << "diagram_info_table query : " << query_.lastError();
}
//Create the element info table
QString element_info_table("CREATE TABLE element_info(element_uuid VARCHAR(50) PRIMARY KEY NOT NULL,");
first_=true;
for (auto string : QETApp::elementInfoKeys())
{
if (first_) {
first_ = false;
} else {
element_info_table += ",";
}
element_info_table += string += " VARCHAR(100)";
}
element_info_table += ", FOREIGN KEY (element_uuid) REFERENCES element (uuid) ON DELETE CASCADE);";
if (!query_.exec(element_info_table)) {
qDebug() << " element_info_table query : " << query_.lastError();
}
createElementNomenclatureView();
createSummaryView();
diagram_info_table += string += string=="date" ? " DATE" : " VARCHAR(100)";
}
diagram_info_table += ", FOREIGN KEY (diagram_uuid) REFERENCES diagram (uuid))";
if (!query_.exec(diagram_info_table)) {
qDebug() << "diagram_info_table query : " << query_.lastError();
}
//Create the element info table
QString element_info_table("CREATE TABLE element_info(element_uuid VARCHAR(50) PRIMARY KEY NOT NULL,");
first_=true;
for (auto string : QETApp::elementInfoKeys())
{
if (first_) {
first_ = false;
} else {
element_info_table += ",";
}
element_info_table += string += " VARCHAR(100)";
}
element_info_table += ", FOREIGN KEY (element_uuid) REFERENCES element (uuid));";
if (!query_.exec(element_info_table)) {
qDebug() << " element_info_table query : " << query_.lastError();
}
createElementNomenclatureView();
createSummaryView();
prepareQuery();
updateDB();
return true;
@ -529,12 +513,37 @@ QHash<QString, QString> projectDataBase::elementInfoToString(Element *elmt)
}
/**
@brief projectDataBase::exportDb
@param db
@param parent
@param caption
@param dir
*/
* @brief projectDataBase::sqliteHandle
* @param db
* @return the sqlite3 handler class used internally by @db
*/
sqlite3 *projectDataBase::sqliteHandle(QSqlDatabase *db)
{
//sqlite 3 lib isn't availlable for the moment on macosx
//need some help to add sqlite3 lib on macosx compilation
#if Q_OS_MACOS
return nullptr;
#else
sqlite3 *handle = nullptr;
QVariant v = db->driver()->handle();
if (v.isValid() && qstrcmp(v.typeName(), "sqlite3*") == 0) {
handle = *static_cast<sqlite3 **>(v.data());
}
return handle;
#endif
}
/**
* @brief projectDataBase::exportDb
* Export the @db, to a file.
* @param db : database to export
* @param parent : parent widget of a QDialog used in this function
* @param caption : Title of the QDialog used in this function
* @param dir : Default directory where the database must be saved.
*/
void projectDataBase::exportDb(projectDataBase *db,
QWidget *parent,
const QString &caption,
@ -562,8 +571,26 @@ void projectDataBase::exportDb(projectDataBase *db,
return;
}
//Database is filled at creation, work is done.
QString connection_name("export_project_db_" + db->project()->uuid().toString());
projectDataBase file_db(db->project(), connection_name, path_);
if (true) //Enter in a scope only to nicely use QSqlDatabase::removeDatabase just after the end of the scope
{
auto file_db = QSqlDatabase::addDatabase("QSQLITE", connection_name);
file_db.setDatabaseName(path_);
if (!file_db.open()) {
return;
}
auto memory_db_handle = sqliteHandle(&db->m_data_base);
auto file_db_handle = sqliteHandle(&file_db);
auto sqlite_backup = sqlite3_backup_init(file_db_handle, "main", memory_db_handle, "main");
if (sqlite_backup)
{
sqlite3_backup_step(sqlite_backup, -1);
sqlite3_backup_finish(sqlite_backup);
}
file_db.close();
}
QSqlDatabase::removeDatabase(connection_name);
}

View File

@ -1,4 +1,4 @@
/*
/*
Copyright 2006-2020 QElectroTech Team
This file is part of QElectroTech.
@ -27,6 +27,7 @@
class Element;
class QETProject;
class Diagram;
class sqlite3;
/**
@brief The projectDataBase class
@ -41,12 +42,6 @@ class projectDataBase : public QObject
public:
projectDataBase(QETProject *project, QObject *parent = nullptr);
private:
projectDataBase(QETProject *project,
const QString &connection_name,
const QString &path,
QObject *parent = nullptr);
public:
virtual ~projectDataBase() override;
void updateDB();
@ -62,8 +57,7 @@ class projectDataBase : public QObject
void dataBaseUpdated();
private:
bool createDataBase(const QString &connection_name= QString(),
const QString &name = QString());
bool createDataBase();
void createElementNomenclatureView();
void createSummaryView();
void populateDiagramTable();
@ -86,6 +80,7 @@ class projectDataBase : public QObject
m_insert_diagram_info_query;
public:
static sqlite3 *sqliteHandle(QSqlDatabase *db);
static void exportDb(projectDataBase *db,
QWidget *parent = nullptr,
const QString &caption = QString(),

View File

@ -782,8 +782,10 @@ void QETDiagramEditor::setUpMenu()
menu_project -> addAction(m_csv_export);
menu_project -> addAction(m_project_export_conductor_num);
menu_project -> addAction(m_project_terminalBloc);
#if defined(Q_OS_LINUX) || defined(Q_OS_WINDOWS)
menu_project -> addSeparator();
menu_project -> addAction(m_export_project_db);
#endif
main_tool_bar -> toggleViewAction() -> setStatusTip(tr("Affiche ou non la barre d'outils principale"));
view_tool_bar -> toggleViewAction() -> setStatusTip(tr("Affiche ou non la barre d'outils Affichage"));