diff --git a/include/DbGeography b/include/DbGeography index 7e8c4fa..66d3f2d 100644 --- a/include/DbGeography +++ b/include/DbGeography @@ -1 +1 @@ -#include "../src/dbgeography.h" +#include "../src/types/dbgeography.h" diff --git a/include/Nut b/include/Nut index 2dfb0b9..5b89c95 100644 --- a/include/Nut +++ b/include/Nut @@ -2,5 +2,4 @@ #include "../src/table.h" #include "../src/database.h" #include "../src/tableset.h" -#include "../src/dbgeography.h" #include "../src/query.h" diff --git a/include/dbgeography.h b/include/dbgeography.h index 7e8c4fa..66d3f2d 100644 --- a/include/dbgeography.h +++ b/include/dbgeography.h @@ -1 +1 @@ -#include "../src/dbgeography.h" +#include "../src/types/dbgeography.h" diff --git a/nut.pri b/nut.pri index 92c44de..4932d79 100644 --- a/nut.pri +++ b/nut.pri @@ -8,6 +8,7 @@ HEADERS += \ $$PWD/src/generators/mysqlgenerator.h \ $$PWD/src/generators/sqlitegenerator.h \ $$PWD/src/generators/sqlservergenerator.h \ + $$PWD/src/types/dbgeography.h \ $$PWD/src/tableset.h \ $$PWD/src/defines_p.h \ $$PWD/src/defines.h \ @@ -22,7 +23,6 @@ HEADERS += \ $$PWD/src/table.h \ $$PWD/src/database.h \ $$PWD/src/database_p.h \ - $$PWD/src/dbgeography.h \ $$PWD/src/serializableobject.h SOURCES += \ @@ -31,6 +31,7 @@ SOURCES += \ $$PWD/src/generators/mysqlgenerator.cpp \ $$PWD/src/generators/sqlitegenerator.cpp \ $$PWD/src/generators/sqlservergenerator.cpp \ + $$PWD/src/types/dbgeography.cpp \ $$PWD/src/tableset.cpp \ $$PWD/src/query.cpp \ $$PWD/src/databasemodel.cpp \ @@ -41,5 +42,4 @@ SOURCES += \ $$PWD/src/wherephrase.cpp \ $$PWD/src/table.cpp \ $$PWD/src/database.cpp \ - $$PWD/src/dbgeography.cpp \ $$PWD/src/serializableobject.cpp diff --git a/src/database.cpp b/src/database.cpp index fc4e1a0..c2e1149 100644 --- a/src/database.cpp +++ b/src/database.cpp @@ -47,7 +47,7 @@ NUT_BEGIN_NAMESPACE -int DatabasePrivate::lastId = 0; +qulonglong DatabasePrivate::lastId = 0; QMap DatabasePrivate::allTableMaps; DatabasePrivate::DatabasePrivate(Database *parent) : q_ptr(parent) @@ -58,8 +58,6 @@ bool DatabasePrivate::open(bool update) { Q_Q(Database); // if (update) - bool isNew = getCurrectScheema(); - connectionName = q->metaObject()->className() + QString::number(DatabasePrivate::lastId); @@ -79,6 +77,8 @@ bool DatabasePrivate::open(bool update) || db.lastError().text().contains("Cannot open database") || db.lastError().text().contains("Unknown database '" + databaseName + "'")) { + + db.close(); db.setDatabaseName(sqlGenertor->masterDatabaseName(databaseName)); ok = db.open(); qDebug("Creating database"); @@ -86,10 +86,13 @@ bool DatabasePrivate::open(bool update) db.exec("CREATE DATABASE " + databaseName); db.close(); - if (db.lastError().type() != QSqlError::NoError) + if (db.lastError().type() != QSqlError::NoError) { qWarning("Creating database error: %s", db.lastError().text().toLatin1().data()); + return false; + } + _databaseStatus = New; return open(update); } else { qWarning("Unknown error detecting change logs, %s", @@ -99,7 +102,7 @@ bool DatabasePrivate::open(bool update) return false; } - if(isNew) + if(update) return updateDatabase(); else return true; @@ -109,7 +112,10 @@ bool DatabasePrivate::updateDatabase() { Q_Q(Database); - DatabaseModel last = getLastScheema(); + if (!getCurrectScheema()) + return true; + + DatabaseModel last = _databaseStatus == New ? DatabaseModel() : getLastScheema(); DatabaseModel current = currentModel; if (last == current) { @@ -123,15 +129,17 @@ bool DatabasePrivate::updateDatabase() qDebug("Databse is changed"); QStringList sql = sqlGenertor->diff(last, current); + db.transaction(); foreach (QString s, sql) { db.exec(s); if (db.lastError().type() != QSqlError::NoError) - qWarning("Error executing sql command, %s", + qWarning("Error executing sql command `%s`, %s", + qPrintable(s), db.lastError().text().toLatin1().data()); } - storeScheemaInDB(); + putModelToDatabase(); bool ok = db.commit(); if (db.lastError().type() == QSqlError::NoError) { @@ -160,6 +168,7 @@ bool DatabasePrivate::getCurrectScheema() if (allTableMaps.contains(q->metaObject()->className())) { currentModel = allTableMaps[q->metaObject()->className()]; + qDebug() << "******************"; return false; } @@ -229,21 +238,22 @@ DatabaseModel DatabasePrivate::getLastScheema() ->orderBy(!ChangeLogTable::idField()) ->first(); - DatabaseModel ret(q->metaObject()->className()); +// DatabaseModel ret(q->metaObject()->className()); if (u) { QJsonObject json = QJsonDocument::fromJson( QByteArray(u->data().toLocal8Bit().data())).object(); + DatabaseModel ret = json; + return ret; + /* foreach (QString key, json.keys()) { TableModel *sch = new TableModel(json.value(key).toObject(), key); ret.append(sch); - } - - u->deleteLater(); + }*/ } - return ret; + return DatabaseModel(); // QSqlQuery query = q->exec("select * from __change_logs order by id // desc limit 1"); @@ -261,7 +271,7 @@ DatabaseModel DatabasePrivate::getLastScheema() // return ret; } -bool DatabasePrivate::storeScheemaInDB() +bool DatabasePrivate::putModelToDatabase() { Q_Q(Database); DatabaseModel current = currentModel; diff --git a/src/database_p.h b/src/database_p.h index 33c4b05..605864b 100644 --- a/src/database_p.h +++ b/src/database_p.h @@ -41,7 +41,7 @@ public: bool updateDatabase(); void createChangeLogs(); - bool storeScheemaInDB(); + bool putModelToDatabase(); DatabaseModel getLastScheema(); bool getCurrectScheema(); @@ -63,9 +63,17 @@ public: QT_DEPRECATED QHash tables; static QMap allTableMaps; - static int lastId; + static qulonglong lastId; QSet tableSets; + + + enum DatabaseStatus{ + New, + Modified, + NotChanged + }; + DatabaseStatus _databaseStatus; }; NUT_END_NAMESPACE diff --git a/src/databasemodel.cpp b/src/databasemodel.cpp index 71b4531..36f682e 100644 --- a/src/databasemodel.cpp +++ b/src/databasemodel.cpp @@ -21,12 +21,15 @@ #include "databasemodel.h" #include "tablemodel.h" +#include #include NUT_BEGIN_NAMESPACE QMap DatabaseModel::_models; +#define NODE_VERSION "version" +#define NODE_TABLES "tables" DatabaseModel::DatabaseModel(const QString &name) : QList(), _databaseClassName(name), _version(QString::null) { _models.insert(name, this); @@ -39,13 +42,14 @@ DatabaseModel::DatabaseModel(const DatabaseModel &other) : QList(ot DatabaseModel::DatabaseModel(const QJsonObject &json) : QList() { - setVersion(json.value(QT_STRINGIFY(version)).toString()); + setVersion(json.value(NODE_VERSION).toString()); - foreach (QString key, json.keys()) { - if(!json.value(key).isObject()) + QJsonObject tables = json.value(NODE_TABLES).toObject(); + foreach (QString key, tables.keys()) { + if(!tables.value(key).isObject()) continue; - TableModel *sch = new TableModel(json.value(key).toObject(), key); + TableModel *sch = new TableModel(tables.value(key).toObject(), key); append(sch); } } @@ -98,17 +102,33 @@ bool DatabaseModel::operator ==(const DatabaseModel &other) const return true; } +DatabaseModel DatabaseModel::operator +(const DatabaseModel &other) +{ + DatabaseModel model; + DatabaseModel::const_iterator i; + + for (i = constBegin(); i != constEnd(); ++i) + model.append(*i); + + for (i = other.constBegin(); i != other.constEnd(); ++i) + model.append(*i); + + return model; +} + QJsonObject DatabaseModel::toJson() const { QJsonObject obj; obj.insert(QT_STRINGIFY(version), QJsonValue(_version)); - + QJsonObject tables; for(int i = 0; i < size(); i++){ TableModel *s = at(i); - obj.insert(s->name(), s->toJson()); + tables.insert(s->name(), s->toJson()); } + obj.insert(NODE_TABLES, tables); + return obj; } @@ -149,10 +169,10 @@ DatabaseModel DatabaseModel::fromJson(QJsonObject &json) { DatabaseModel model(QString::null); -// model.setVersionMajor(json.value(QT_STRINGIFY(versionMajor)).toInt()); -// model.setVersionMinor(json.value(QT_STRINGIFY(versionMinor)).toInt()); + model.setVersion(json.value(NODE_VERSION).toString()); - foreach (QString key, json.keys()) { + QJsonObject tables = json.value(NODE_TABLES).toObject(); + foreach (QString key, tables.keys()) { if(!json.value(key).isObject()) continue; diff --git a/src/databasemodel.h b/src/databasemodel.h index 6e575d6..40d5373 100644 --- a/src/databasemodel.h +++ b/src/databasemodel.h @@ -50,6 +50,7 @@ public: const QString &childClassName); bool operator==(const DatabaseModel &other) const; + DatabaseModel operator +(const DatabaseModel &other); Q_DECL_DEPRECATED static DatabaseModel fromJson(QJsonObject &json); diff --git a/src/defines.h b/src/defines.h index 1184a11..c386a17 100644 --- a/src/defines.h +++ b/src/defines.h @@ -26,7 +26,6 @@ #include "defines_p.h" #include "qglobal.h" - #ifdef NUT_COMPILE_STATIC # define NUT_EXPORT #else @@ -36,7 +35,7 @@ // Database //TODO: remove minor version #define NUT_DB_VERSION(version) \ - Q_CLASSINFO(QT_STRINGIFY(__nut_NAME_PERFIX __nut_DB_VERSION), #version)) + Q_CLASSINFO(QT_STRINGIFY(__nut_NAME_PERFIX __nut_DB_VERSION), #version) #define NUT_DECLARE_TABLE(type, name) \ Q_CLASSINFO(QT_STRINGIFY(__nut_NAME_PERFIX __nut_TABLE " " #type), #name) \ @@ -90,7 +89,6 @@ public: \ return m_##n; \ } - #define NUT_INDEX(name, field, order) #define NUT_PRIMARY_KEY(x) Q_CLASSINFO(QT_STRINGIFY(__nut_NAME_PERFIX #x " " __nut_PRIMARY_KEY), #x) #define NUT_AUTO_INCREMENT(x) Q_CLASSINFO(QT_STRINGIFY(__nut_NAME_PERFIX #x " " __nut_AUTO_INCREMENT), #x) @@ -114,6 +112,4 @@ public: \ # define FIRST() ->first() #endif // NUT_NO_KEYWORDS - - #endif // SYNTAX_DEFINES_H diff --git a/src/generators/sqlgeneratorbase.cpp b/src/generators/sqlgeneratorbase.cpp index f845d4f..d186d4c 100644 --- a/src/generators/sqlgeneratorbase.cpp +++ b/src/generators/sqlgeneratorbase.cpp @@ -81,18 +81,15 @@ QStringList SqlGeneratorBase::diff(DatabaseModel lastModel, { QStringList ret; - QSet tableNames; - foreach (TableModel *table, lastModel) - tableNames.insert(table->name()); + DatabaseModel unionModel = lastModel + newModel; - foreach (TableModel *table, newModel) - tableNames.insert(table->name()); - - foreach (QString tableName, tableNames) { - TableModel *oldTable = lastModel.tableByName(tableName); - TableModel *newTable = newModel.tableByName(tableName); + foreach (TableModel *table, unionModel) { + TableModel *oldTable = lastModel.tableByName(table->name()); + TableModel *newTable = newModel.tableByName(table->name()); QString sql = diff(oldTable, newTable); - ret << sql; + + if (!sql.isEmpty()) + ret << sql; } return ret; diff --git a/src/query.h b/src/query.h index f70d7dc..62e298f 100644 --- a/src/query.h +++ b/src/query.h @@ -109,7 +109,6 @@ template Q_OUTOFLINE_TEMPLATE Query::~Query() { Q_D(Query); - delete d; } diff --git a/src/types/dbgeography.cpp b/src/types/dbgeography.cpp new file mode 100644 index 0000000..11d4407 --- /dev/null +++ b/src/types/dbgeography.cpp @@ -0,0 +1,81 @@ +/************************************************************************** +** +** This file is part of Nut project. +** https://github.com/HamedMasafi/Nut +** +** Nut is free software: you can redistribute it and/or modify +** it under the terms of the GNU Lesser General Public License as published by +** the Free Software Foundation, either version 3 of the License, or +** (at your option) any later version. +** +** Nut is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU Lesser General Public License for more details. +** +** You should have received a copy of the GNU Lesser General Public License +** along with Nut. If not, see . +** +**************************************************************************/ + +#include "dbgeography.h" + +NUT_BEGIN_NAMESPACE + +DbGeography::DbGeography() : m_longitude(0), m_latitude(0) +{ + +} + +DbGeography::DbGeography(const DbGeography &other) +{ + setLongitude(other.longitude()); + setLatitude(other.latitude()); +} + +DbGeography::DbGeography(const QVariant &value) +{ + QStringList parts = value.toString().split(','); + if (parts.count() == 2) { + setLongitude(parts[0].toDouble()); + setLatitude(parts[1].toDouble()); + } else { + qWarning("Input value for DbGeography is invalid: %s", + qPrintable(value.toString())); + setLongitude(0); + setLatitude(0); + } +} + +qreal DbGeography::longitude() const +{ + return m_longitude; +} + +qreal DbGeography::latitude() const +{ + return m_latitude; +} + +void DbGeography::setLongitude(qreal longitude) + +{ + if (qFuzzyCompare(m_longitude, longitude)) + return; + + m_longitude = longitude; +} + +void DbGeography::setLatitude(qreal latitude) +{ + if (qFuzzyCompare(m_latitude, latitude)) + return; + + m_latitude = latitude; +} +DbGeography::operator QVariant() +{ + return QVariant::fromValue(QString("%1,%2").arg(longitude()).arg(latitude())); +} + +NUT_END_NAMESPACE diff --git a/src/types/dbgeography.h b/src/types/dbgeography.h new file mode 100644 index 0000000..9a7dfd0 --- /dev/null +++ b/src/types/dbgeography.h @@ -0,0 +1,54 @@ +/************************************************************************** +** +** This file is part of Nut project. +** https://github.com/HamedMasafi/Nut +** +** Nut is free software: you can redistribute it and/or modify +** it under the terms of the GNU Lesser General Public License as published by +** the Free Software Foundation, either version 3 of the License, or +** (at your option) any later version. +** +** Nut is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU Lesser General Public License for more details. +** +** You should have received a copy of the GNU Lesser General Public License +** along with Nut. If not, see . +** +**************************************************************************/ + +#ifndef DBGEOGRAPHY_H +#define DBGEOGRAPHY_H + +#include "../defines.h" +#include +#include +#include + +NUT_BEGIN_NAMESPACE + +class NUT_EXPORT DbGeography +{ + qreal m_longitude; + qreal m_latitude; + +public: + explicit DbGeography(); + DbGeography(const DbGeography &other); + DbGeography(const QVariant &value); + + qreal longitude() const; + qreal latitude() const; + + void setLongitude(qreal longitude); + void setLatitude(qreal latitude); + + operator QVariant(); +}; + +NUT_END_NAMESPACE + +Q_DECLARE_METATYPE(NUT_WRAP_NAMESPACE(DbGeography)) + +#endif // DBGEOGRAPHY_H diff --git a/src/wherephrase.h b/src/wherephrase.h index f7eada9..233e493 100644 --- a/src/wherephrase.h +++ b/src/wherephrase.h @@ -30,7 +30,7 @@ #include #include #include "defines.h" -#include "dbgeography.h" +#include "types/dbgeography.h" #include