10#include <QRegularExpression>
11#include <QSqlDatabase>
16#include <QJsonDocument>
21#include <QStandardPaths>
22#include <QCoreApplication>
27bool SqlDBWriter::exec(QSqlQuery *sq,
const QString& sqlFile)
const {
30 if (f.open(QIODevice::ReadOnly)) {
32 QString temp, delimiter =
";";
33 QTextStream stream(&f);
34#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
35 stream.setCodec(
"UTF8");
38 while(!stream.atEnd()) {
39 QString line = stream.readLine();
41 int linedelimiterIndex = line.lastIndexOf(delimiter, -1, Qt::CaseInsensitive);
42 int delimiterIndex = temp.size() + linedelimiterIndex;
44 if (line.contains(
"--"))
49 if (linedelimiterIndex > -1) {
50 result = result && sq->exec(temp.left(delimiterIndex));
51 temp = temp.remove(0, delimiterIndex + 1);
54 QuasarAppUtils::Params::log(QString(
"Exec database error. File: %0. Line:%1: %2").
55 arg(sqlFile).arg(lineNumber).arg(sq->lastError().text()),
56 QuasarAppUtils::Error);
67 QuasarAppUtils::Params::log(
"sql source file is not open: " + sqlFile,
68 QuasarAppUtils::Error);
73bool SqlDBWriter::initDbPrivate(
const QVariantMap ¶ms) {
80 _config[
"DBFilePath"].toString()));
82 if (_config.contains(
"DBFilePath")) {
84 auto path = QFileInfo(_config[
"DBFilePath"].toString());
85 if (!QDir(
"").mkpath(path.absolutePath())) {
89 _db->setDatabaseName(path.absoluteFilePath());
92 if (_config.contains(
"DBLogin")) {
93 _db->setPassword(_config[
"DBLogin"].toString());
96 if (_config.contains(
"DBPass")) {
97 _db->setPassword(_config[
"DBPass"].toString());
100 if (_config.contains(
"DBHost")) {
101 _db->setHostName(_config[
"DBHost"].toString());
104 if (_config.contains(
"DBPort")) {
105 _db->setPort(_config[
"DBPort"].toInt());
109 QuasarAppUtils::Params::log(_db->lastError().text(),
110 QuasarAppUtils::Error);
114 for (
const QString& sqlFile : std::as_const(_SQLSources)) {
115 QSqlQuery query(*_db);
116 if (!exec(&query, sqlFile)) {
121 if (_config.contains(
"DBInitFile")) {
122 auto path = QFileInfo(_config[
"DBInitFile"].toString()).absoluteFilePath();
124 QSqlQuery query(*_db);
125 if (!exec(&query, path)) {
130 initSuccessful = _db->isValid();
131 return initSuccessful;
134bool SqlDBWriter::doQueryPrivate(
const QString &query,
const QVariantMap &bindValues, QSqlQuery* result)
const {
141 if (bindValues.size()) {
142 if (!q.prepare(query)) {
143 QuasarAppUtils::Params::log(
"request error : " + q.lastError().text(),
144 QuasarAppUtils::Error);
148 for (
auto it = bindValues.begin(); it != bindValues.end(); ++it) {
149 q.bindValue(it.key(), it.value());
153 QuasarAppUtils::Params::log(
"request error : " + q.lastError().text(),
154 QuasarAppUtils::Error);
158 if (!q.exec(query)) {
159 QuasarAppUtils::Params::log(
"request error : " + q.lastError().text(),
160 QuasarAppUtils::Error);
166 *result = std::move(q);
173bool SqlDBWriter::doSqlPrivate(
const QString &sqlFile)
const {
174 QSqlQuery query(*_db);
175 if (!exec(&query, sqlFile)) {
187 QSqlQuery query(*
db());
188 QString request = QString(
"PRAGMA foreign_keys = ON");
189 if (!query.exec(request)) {
190 QuasarAppUtils::Params::log(
"request error : " + query.lastError().text());
203 QSqlQuery query(*
db());
204 QString request = QString(
"PRAGMA foreign_keys = OFF");
205 if (!query.exec(request)) {
206 QuasarAppUtils::Params::log(
"request error : " + query.lastError().text());
215 QFile file(initFile);
218 if (file.open(QIODevice::ReadOnly)) {
219 QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
222 if (!doc.isObject()) {
226 QJsonObject obj = doc.object();
227 return obj.toVariantMap();
238 params[
"DBDriver"] =
"QSQLITE";
244 const QString& name) {
246 return QSqlDatabase::addDatabase(driverName,
247 QFileInfo(name).fileName());
265 if (initDbParams.isEmpty()) {
275 auto handleInitDb = [¶ms,
this]() {
276 return initDbPrivate(params);
283 return db() &&
db()->isValid() &&
db()->isOpen() && initSuccessful;
287 QList<QSharedPointer<DBObject>> &result) {
289 auto getAll = [&templateObject, &result,
this]() {
316 const QWeakPointer<unsigned int>& autoincrementIdResult) {
319 auto resultId = QSharedPointer<int>::create();
320 Async::Job job = [
this, ptr, autoincrementIdResult]() {
350 return db()->databaseName();
357 QString connectionName = _db->connectionName();
362 QSqlDatabase::removeDatabase(connectionName);
368 const QWeakPointer<unsigned int>& autoincrementIdResult)
const {
378 auto prepare = [ptr](QSqlQuery&q) {
379 return ptr->prepareInsertQuery(q,
false);
382 auto cb = [&q, autoincrementIdResult]() {
384 if (
auto&& ptr = autoincrementIdResult.lock()) {
385 *ptr = q.lastInsertId().toInt();
391 return workWithQuery(q, prepare, cb);
404 auto prepare = [ptr](QSqlQuery&q) {
405 return ptr->prepareInsertQuery(q,
true);
408 auto cb = [](){
return true;};
410 return workWithQuery(q, prepare, cb);
414 bool wait, QSqlQuery* result)
const {
416 wait = result || wait;
418 Async::Job job = [
this, query, bindValues, result]() {
419 return doQueryPrivate(query, bindValues, result);
428 return doSqlPrivate(sqlFile);
436 QList<QSharedPointer<QH::PKG::DBObject>> &result) {
443 auto prepare = [&requestObject](QSqlQuery&q) {
447 auto cb = [&q, &requestObject, &result]() ->
bool {
450 auto newObject = QSharedPointer<QH::PKG::DBObject>(requestObject.
createDBObject());
456 if (!newObject->fromSqlRecord(q.record())) {
457 QuasarAppUtils::Params::log(
"Select query finished successful but, "
458 "the fromSqlRecord method return false." +
459 newObject->toString(),
460 QuasarAppUtils::Error);
465 result.push_back(newObject);
469 auto newObject = QSharedPointer<QH::PKG::DBObject>(requestObject.
createDBObject());
474 if (!newObject->fromSqlRecord(q.record())) {
475 QuasarAppUtils::Params::log(
"Init sql object error.",
476 QuasarAppUtils::Error);
479 result.push_back(newObject);
485 return result.size();
488 return workWithQuery(q, prepare, cb);
501 auto cb = []() ->
bool {
506 return workWithQuery(q, prepare, cb);
515 auto prepare = [ptr](QSqlQuery&q) {
516 return ptr->prepareUpdateQuery(q);
519 auto cb = [](){
return true;};
521 return workWithQuery(q, prepare, cb);
524bool SqlDBWriter::workWithQuery(QSqlQuery &q,
525 const std::function<
PrepareResult (QSqlQuery &)> &prepareFunc,
526 const std::function<
bool ()> &cb)
const {
528 auto printError = [](
const QSqlQuery &q) {
530 QuasarAppUtils::Params::log(
"prepare sql error: " + q.executedQuery(),
531 QuasarAppUtils::Debug);
533 QuasarAppUtils::Params::log(
"exec sql error: " + q.lastError().text(),
534 QuasarAppUtils::Error);
539 switch (prepareFunc(q)) {
540 case PrepareResult::Success: {
547#ifdef HEART_PRINT_SQL_QUERIES
548 QuasarAppUtils::Params::log(QString(
"Query executed successfull into %0\n"
550 arg(_db->databaseName(), q.executedQuery()),
551 QuasarAppUtils::Debug);
556 case PrepareResult::Disabled: {
557 QuasarAppUtils::Params::log(
"call disabled operator! ",
558 QuasarAppUtils::Warning);
562 case PrepareResult::Fail: {
The Async class This is bundle of async templates and async wrappers.
std::function< bool()> Job
bool asyncLauncher(const Job &job, bool await=false, bool freaze=true) const
asyncLauncher This method invoke a job on the thread (using the asyncHandler method) of this object.
The DBObject class- main class for work with data base.
virtual PrepareResult prepareSelectQuery(QSqlQuery &q) const
prepareSelectQuery This method should be prepare a query for selected data. Override this method for ...
virtual bool isBundle() const
isBundle This method definef determines whether the object will be abstract (composite objects) or si...
virtual DBObject * createDBObject() const =0
createDBObject This method should be create a object with the some type as the object called this met...
bool disableFK()
disableFK This method disable foreign key for the sqlite database.
bool deleteObject(const QSharedPointer< PKG::DBObject > &ptr, bool wait=false) override
deleteObject This method execute a delete method of obj and remove current object from database.
virtual bool updateQuery(const QSharedPointer< QH::PKG::DBObject > &ptr) const
updateQuery This method execute update query of object. For more Information see DBObject::prepareUpd...
QString databaseLocation() const
databaseLocation This method return location of database. If it is sqlite then return path to db file...
bool updateObject(const QSharedPointer< PKG::DBObject > &ptr, bool wait=false) override
updateObject This method execute a update method of the saveObject and save all changes into database...
bool doSql(const QString &sqlFile, bool wait) const override
doSql This method execute a query in this database.
QSqlDatabase * db()
db This method return db connection. If SqlDBWriter in not inited then return nullptr....
bool enableFK()
enableFK This method enable foreign key for the sqlite database.
virtual bool replaceQuery(const QSharedPointer< QH::PKG::DBObject > &insertObject) const
replaceQuery This method prepare the replce object query.
virtual QSqlDatabase initSqlDataBasse(const QString &driverName, const QString &name)
initSqlDataBasse This method create ad database connection. Without configuration....
SqlDBWriter(QThread *thread, QObject *ptr=nullptr)
bool doQuery(const QString &query, const QVariantMap &bindValues={}, bool wait=false, QSqlQuery *result=nullptr) const override
doQuery This method execute a query in this database.
bool replaceObject(const QSharedPointer< PKG::DBObject > &ptr, bool wait=false) override
replaceObject This method execute a replace method of the saveObject and insert or save if not exists...
virtual bool selectQuery(const QH::PKG::DBObject &requestObject, QList< QSharedPointer< QH::PKG::DBObject > > &result)
selectQuery generate select query to database from parameters.
void setSQLSources(const QStringList &list) override
setSQLSources This method set sql sources for deployed database.
virtual bool isValid() const
isValid This method return true if database is successful inited and working correctly.
virtual bool deleteQuery(const QSharedPointer< QH::PKG::DBObject > &deleteObject) const
deleteQuery This method prepare the delete object query.
virtual bool initDb(const QString &initDbParams=DEFAULT_DB_PATH)
initDb This method is wraper of the initDb(const QVariantMap ¶ms) method. This implementation rea...
virtual QVariantMap getInitParams(const QString &initFile) const
getInitPararm This method read parameters of database.
virtual ~SqlDBWriter() override
bool getAllObjects(const PKG::DBObject &templateObject, QList< QSharedPointer< PKG::DBObject > > &result) override
getAllObjects This method execute a select method of the templateObject and return list of all select...
virtual bool insertQuery(const QSharedPointer< QH::PKG::DBObject > &insertObject, const QWeakPointer< unsigned int > &autoIncrementID={}) const
insertQuery This method prepare the insert object query.
virtual QVariantMap defaultInitPararm() const
defaultInitPararm This method return default parameters of the database.
bool insertObject(const QSharedPointer< PKG::DBObject > &ptr, bool wait=false, const QWeakPointer< unsigned int > &autoincrementIdResult={}) override
insertObject This method execute a insert method of the saveObject and insert it into database.
PrepareResult
The PrepareResult enum is result of work prepare sql query of dbobjects.
The QH namespace - QuasarApp Heart namespace. This namespace contains all classes of the Heart librar...