File indexing completed on 2024-05-12 04:45:55

0001 /***
0002 Pix  Copyright (C) 2018  Camilo Higuita
0003 This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
0004 This is free software, and you are welcome to redistribute it
0005 under certain conditions; type `show c' for details.
0006 
0007  This program is free software: you can redistribute it and/or modify
0008 it under the terms of the GNU General Public License as published by
0009 the Free Software Foundation, either version 3 of the License, or
0010 (at your option) any later version.
0011 
0012 This program is distributed in the hope that it will be useful,
0013 but WITHOUT ANY WARRANTY; without even the implied warranty of
0014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0015 GNU General Public License for more details.
0016 
0017 You should have received a copy of the GNU General Public License
0018 along with this program.  If not, see <http://www.gnu.org/licenses/>.
0019 ***/
0020 
0021 #include "db.h"
0022 #include <QCoreApplication>
0023 #include <QSqlQuery>
0024 #include <QString>
0025 #include <QStringList>
0026 #include <QUuid>
0027 
0028 DB::DB()
0029     : QObject(nullptr)
0030 {
0031     QDir collectionDBPath_dir(OWL::CollectionDBPath.toLocalFile());
0032     if (!collectionDBPath_dir.exists())
0033         collectionDBPath_dir.mkpath(".");
0034 
0035     this->name = QUuid::createUuid().toString();
0036     if (!FMH::fileExists(OWL::CollectionDBPath.toString() + OWL::DBName)) {
0037         this->openDB(this->name);
0038         qDebug() << "Collection doesn't exists, trying to create it" << OWL::CollectionDBPath.toString() + OWL::DBName;
0039         this->prepareCollectionDB();
0040     } else
0041         this->openDB(this->name);
0042 }
0043 
0044 DB::~DB()
0045 {
0046     qDebug() << "DELETING LOCAL DB";
0047     this->m_db.close();
0048 }
0049 
0050 void DB::openDB(const QString &name)
0051 {
0052     if (!QSqlDatabase::contains(name)) {
0053         this->m_db = QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"), name);
0054         this->m_db.setDatabaseName(OWL::CollectionDBPath.toLocalFile() + OWL::DBName);
0055     }
0056 
0057     if (!this->m_db.isOpen()) {
0058         if (!this->m_db.open())
0059             qDebug() << "ERROR OPENING DB" << this->m_db.lastError().text() << m_db.connectionName();
0060     }
0061     auto query = this->getQuery("PRAGMA synchronous=OFF");
0062     query.exec();
0063 }
0064 
0065 void DB::prepareCollectionDB() const
0066 {
0067     QSqlQuery query(this->m_db);
0068 
0069     QFile file(":/db/script.sql");
0070 
0071     if (!file.exists()) {
0072         QString log = QStringLiteral("Fatal error on build database. The file '");
0073         log.append(file.fileName() + QStringLiteral("' for database and tables creation query cannot be not found!"));
0074         qDebug() << log;
0075         return;
0076     }
0077 
0078     if (!file.open(QIODevice::ReadOnly)) {
0079         qDebug() << QStringLiteral("Fatal error on try to create database! The file with sql queries for database creation cannot be opened!");
0080         return;
0081     }
0082 
0083     bool hasText;
0084     QString line;
0085     QByteArray readLine;
0086     QString cleanedLine;
0087     QStringList strings;
0088 
0089     while (!file.atEnd()) {
0090         hasText = false;
0091         line = "";
0092         readLine = "";
0093         cleanedLine = "";
0094         strings.clear();
0095         while (!hasText) {
0096             readLine = file.readLine();
0097             cleanedLine = readLine.trimmed();
0098             strings = cleanedLine.split("--");
0099             cleanedLine = strings.at(0);
0100             if (!cleanedLine.startsWith("--") && !cleanedLine.startsWith("DROP") && !cleanedLine.isEmpty())
0101                 line += cleanedLine;
0102             if (cleanedLine.endsWith(";"))
0103                 break;
0104             if (cleanedLine.startsWith("COMMIT"))
0105                 hasText = true;
0106         }
0107         if (!line.isEmpty()) {
0108             if (!query.exec(line)) {
0109                 qDebug() << "exec failed" << query.lastQuery() << query.lastError();
0110             }
0111 
0112         } else
0113             qDebug() << "exec wrong" << query.lastError();
0114     }
0115     file.close();
0116 }
0117 
0118 bool DB::checkExistance(const QString &tableName, const QString &searchId, const QString &search)
0119 {
0120     auto queryStr = QString("SELECT %1 FROM %2 WHERE %3 = \"%4\"").arg(searchId, tableName, searchId, search);
0121     auto query = this->getQuery(queryStr);
0122 
0123     if (query.exec()) {
0124         if (query.next())
0125             return true;
0126     } else
0127         qDebug() << query.lastError().text();
0128 
0129     return false;
0130 }
0131 
0132 const FMH::MODEL_LIST DB::getDBData(const QString &queryTxt)
0133 {
0134     FMH::MODEL_LIST mapList;
0135 
0136     auto query = this->getQuery(queryTxt);
0137 
0138     if (query.exec()) {
0139         const auto keys = FMH::MODEL_NAME.keys();
0140         while (query.next()) {
0141             FMH::MODEL data;
0142 
0143             for (const auto &key : keys)
0144             {
0145                 if (query.record().indexOf(FMH::MODEL_NAME[key]) > -1)
0146                 {
0147                     data.insert(key, query.value(FMH::MODEL_NAME[key]).toString());
0148                 }
0149             }
0150 
0151             mapList << data;
0152         }
0153 
0154     } else
0155         qDebug() << query.lastError() << query.lastQuery();
0156 
0157     return mapList;
0158 }
0159 
0160 QSqlQuery DB::getQuery(const QString &queryTxt)
0161 {
0162     QSqlQuery query(queryTxt, this->m_db);
0163     return query;
0164 }
0165 
0166 bool DB::insert(const QString &tableName, const QVariantMap &insertData)
0167 {
0168     qDebug() << "TRY TO ISNERT NOTE TO DB" << insertData;
0169     if (tableName.isEmpty()) {
0170         qDebug() << QStringLiteral("Fatal error on insert! The table name is empty!");
0171         return false;
0172 
0173     } else if (insertData.isEmpty()) {
0174         qDebug() << QStringLiteral("Fatal error on insert! The insertData is empty!");
0175         return false;
0176     }
0177 
0178     QStringList strValues;
0179     QStringList fields = insertData.keys();
0180     QVariantList values = insertData.values();
0181     int totalFields = fields.size();
0182     for (int i = 0; i < totalFields; ++i)
0183         strValues.append("?");
0184 
0185     QString sqlQueryString = "INSERT INTO " + tableName + " (" + QString(fields.join(",")) + ") VALUES(" + QString(strValues.join(",")) + ")";
0186     QSqlQuery query(this->m_db);
0187     query.prepare(sqlQueryString);
0188 
0189     int k = 0;
0190     foreach (const QVariant &value, values)
0191         query.bindValue(k++, value);
0192 
0193     return query.exec();
0194 }
0195 
0196 bool DB::update(const QString &tableName, const QVariantMap &updateData, const QVariantMap &where)
0197 {
0198     if (tableName.isEmpty()) {
0199         qDebug() << QStringLiteral("Fatal error on insert! The table name is empty!");
0200         return false;
0201     } else if (updateData.isEmpty()) {
0202         qDebug() << QStringLiteral("Fatal error on insert! The insertData is empty!");
0203         return false;
0204     }
0205 
0206     QStringList set;
0207     const auto updateKeys = updateData.keys();
0208     for (const auto &key : updateKeys)
0209     {
0210         set.append(key + " = ?");
0211     }
0212 
0213     QStringList condition;
0214     const auto whereKeys = where.keys();
0215     for (const auto &key : whereKeys)
0216     {
0217         condition.append(key + " = '" + where[key].toString() + "'");
0218     }
0219 
0220     QString sqlQueryString = "UPDATE " + tableName + " SET " + QString(set.join(",")) + " WHERE " + QString(condition.join(" AND "));
0221     auto query = this->getQuery(sqlQueryString);
0222 
0223     QVariantList values = updateData.values();
0224     int k = 0;
0225     foreach (const QVariant &value, values)
0226     {
0227         query.bindValue(k++, value);
0228     }
0229 
0230     qDebug() << query.lastQuery();
0231     return query.exec();
0232 }
0233 
0234 bool DB::update(const QString &table, const QString &column, const QVariant &newValue, const QVariant &op, const QString &id)
0235 {
0236     auto queryStr = QString("UPDATE %1 SET %2 = \"%3\" WHERE %4 = \"%5\"").arg(table, column, newValue.toString().replace("\"", "\"\""), op.toString(), id);
0237     auto query = this->getQuery(queryStr);
0238     return query.exec();
0239 }
0240 
0241 bool DB::remove(const QString &tableName, const QVariantMap &removeData)
0242 {
0243     if (tableName.isEmpty()) {
0244         qDebug() << QStringLiteral("Fatal error on removing! The table name is empty!");
0245         return false;
0246 
0247     } else if (removeData.isEmpty()) {
0248         qDebug() << QStringLiteral("Fatal error on insert! The removeData is empty!");
0249         return false;
0250     }
0251 
0252     QStringList set;
0253     const auto removeKeys = removeData.keys();
0254     for (const auto &key : removeKeys)
0255     {
0256         set.append(key + " = ?");
0257     }
0258 
0259     QString sqlQueryString = "DELETE FROM " + tableName + " WHERE " + QString(set.join(" AND "));
0260     qDebug() << sqlQueryString;
0261 
0262     auto query = this->getQuery(sqlQueryString);
0263 
0264     QVariantList values = removeData.values();
0265 
0266     int k = 0;
0267     foreach (const QVariant &value, values)
0268         query.bindValue(k++, value);
0269 
0270     return query.exec();
0271 }