models
This commit is contained in:
parent
d3d0ae2532
commit
3e888c080e
|
|
@ -0,0 +1 @@
|
||||||
|
#include "../src/dbgeography.h"
|
||||||
|
|
@ -2,4 +2,5 @@
|
||||||
#include "../src/table.h"
|
#include "../src/table.h"
|
||||||
#include "../src/database.h"
|
#include "../src/database.h"
|
||||||
#include "../src/tableset.h"
|
#include "../src/tableset.h"
|
||||||
|
#include "../src/dbgeography.h"
|
||||||
#include "../src/query.h"
|
#include "../src/query.h"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
#include "../src/dbgeography.h"
|
||||||
|
|
@ -7,7 +7,7 @@ pattern="\.\.\/src\/([a-z]+)\.h\:class\sNUT_EXPORT\s(\w+)"
|
||||||
echo "" > "Nut"
|
echo "" > "Nut"
|
||||||
echo "" > "nut.h"
|
echo "" > "nut.h"
|
||||||
|
|
||||||
mkdir -p Nut
|
#mkdir -p Nut
|
||||||
|
|
||||||
while read line; do
|
while read line; do
|
||||||
if [[ $line =~ $pattern ]]; then
|
if [[ $line =~ $pattern ]]; then
|
||||||
|
|
|
||||||
|
|
@ -2,4 +2,5 @@
|
||||||
#include "../src/table.h"
|
#include "../src/table.h"
|
||||||
#include "../src/database.h"
|
#include "../src/database.h"
|
||||||
#include "../src/tableset.h"
|
#include "../src/tableset.h"
|
||||||
|
#include "../src/dbgeography.h"
|
||||||
#include "../src/query.h"
|
#include "../src/query.h"
|
||||||
|
|
|
||||||
6
nut.pri
6
nut.pri
|
|
@ -21,7 +21,8 @@ HEADERS += \
|
||||||
$$PWD/src/query_p.h \
|
$$PWD/src/query_p.h \
|
||||||
$$PWD/src/table.h \
|
$$PWD/src/table.h \
|
||||||
$$PWD/src/database.h \
|
$$PWD/src/database.h \
|
||||||
$$PWD/src/database_p.h
|
$$PWD/src/database_p.h \
|
||||||
|
$$PWD/src/dbgeography.h
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
$$PWD/src/tableset.cpp \
|
$$PWD/src/tableset.cpp \
|
||||||
|
|
@ -38,4 +39,5 @@ SOURCES += \
|
||||||
$$PWD/src/sqlservergenerator.cpp \
|
$$PWD/src/sqlservergenerator.cpp \
|
||||||
$$PWD/src/wherephrase.cpp \
|
$$PWD/src/wherephrase.cpp \
|
||||||
$$PWD/src/table.cpp \
|
$$PWD/src/table.cpp \
|
||||||
$$PWD/src/database.cpp
|
$$PWD/src/database.cpp \
|
||||||
|
$$PWD/src/dbgeography.cpp
|
||||||
|
|
|
||||||
199
src/database.cpp
199
src/database.cpp
|
|
@ -58,7 +58,8 @@ bool DatabasePrivate::open()
|
||||||
Q_Q(Database);
|
Q_Q(Database);
|
||||||
getCurrectScheema();
|
getCurrectScheema();
|
||||||
|
|
||||||
connectionName = q->metaObject()->className() + QString::number(DatabasePrivate::lastId);
|
connectionName = q->metaObject()->className()
|
||||||
|
+ QString::number(DatabasePrivate::lastId);
|
||||||
|
|
||||||
db = QSqlDatabase::addDatabase(driver, connectionName);
|
db = QSqlDatabase::addDatabase(driver, connectionName);
|
||||||
db.setHostName(hostName);
|
db.setHostName(hostName);
|
||||||
|
|
@ -67,25 +68,30 @@ bool DatabasePrivate::open()
|
||||||
db.setPassword(password);
|
db.setPassword(password);
|
||||||
bool ok = db.open();
|
bool ok = db.open();
|
||||||
|
|
||||||
if(!ok){
|
if (!ok) {
|
||||||
qWarning("Could not connect to database, error = %s", db.lastError().text().toLocal8Bit().data());
|
qWarning("Could not connect to database, error = %s",
|
||||||
|
db.lastError().text().toLocal8Bit().data());
|
||||||
|
|
||||||
if(db.lastError().text().contains("database \"" + databaseName + "\" does not exist")
|
if (db.lastError().text().contains("database \"" + databaseName
|
||||||
|| db.lastError().text().contains("Cannot open database")
|
+ "\" does not exist")
|
||||||
|| db.lastError().text().contains("Unknown database '" + databaseName + "'")){
|
|| db.lastError().text().contains("Cannot open database")
|
||||||
|
|| db.lastError().text().contains("Unknown database '"
|
||||||
|
+ databaseName + "'")) {
|
||||||
db.setDatabaseName(sqlGenertor->masterDatabaseName(databaseName));
|
db.setDatabaseName(sqlGenertor->masterDatabaseName(databaseName));
|
||||||
ok = db.open();
|
ok = db.open();
|
||||||
qDebug("Creating database");
|
qDebug("Creating database");
|
||||||
if(ok){
|
if (ok) {
|
||||||
db.exec("CREATE DATABASE " + databaseName);
|
db.exec("CREATE DATABASE " + databaseName);
|
||||||
db.close();
|
db.close();
|
||||||
|
|
||||||
if(db.lastError().type() != QSqlError::NoError)
|
if (db.lastError().type() != QSqlError::NoError)
|
||||||
qWarning("Creating database error: %s", db.lastError().text().toLatin1().data());
|
qWarning("Creating database error: %s",
|
||||||
|
db.lastError().text().toLatin1().data());
|
||||||
|
|
||||||
return open();
|
return open();
|
||||||
}else{
|
} else {
|
||||||
qWarning("Unknown error detecting change logs, %s", db.lastError().text().toLatin1().data());
|
qWarning("Unknown error detecting change logs, %s",
|
||||||
|
db.lastError().text().toLatin1().data());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -101,43 +107,48 @@ bool DatabasePrivate::updateDatabase()
|
||||||
DatabaseModel last = getLastScheema();
|
DatabaseModel last = getLastScheema();
|
||||||
DatabaseModel current = currentModel;
|
DatabaseModel current = currentModel;
|
||||||
|
|
||||||
if(last == current){
|
if (last == current) {
|
||||||
qDebug("Databse is up-to-date");
|
qDebug("Databse is up-to-date");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!last.count())
|
if (!last.count())
|
||||||
qDebug("Databse is new");
|
qDebug("Databse is new");
|
||||||
else
|
else
|
||||||
qDebug("Databse is changed");
|
qDebug("Databse is changed");
|
||||||
|
|
||||||
QStringList sql = sqlGenertor->diff(last, current);
|
QStringList sql = sqlGenertor->diff(last, current);
|
||||||
db.transaction();
|
db.transaction();
|
||||||
foreach (QString s, sql){
|
foreach (QString s, sql) {
|
||||||
|
qDebug() <<"cmd="<<s;
|
||||||
db.exec(s);
|
db.exec(s);
|
||||||
|
|
||||||
if(db.lastError().type() != QSqlError::NoError)
|
if (db.lastError().type() != QSqlError::NoError)
|
||||||
qWarning("Error executing sql command, %s", db.lastError().text().toLatin1().data());
|
qWarning("Error executing sql command, %s",
|
||||||
|
db.lastError().text().toLatin1().data());
|
||||||
}
|
}
|
||||||
bool ok = db.commit();
|
bool ok = db.commit();
|
||||||
|
|
||||||
if(ok){
|
if (ok) {
|
||||||
storeScheemaInDB();
|
storeScheemaInDB();
|
||||||
|
|
||||||
q->databaseUpdated(last.versionMajor(), last.versionMinor(), current.versionMajor(), current.versionMinor());
|
q->databaseUpdated(last.versionMajor(), last.versionMinor(),
|
||||||
QString versionText = QString::number(current.versionMajor()) + "_" + QString::number(current.versionMinor());
|
current.versionMajor(), current.versionMinor());
|
||||||
|
QString versionText = QString::number(current.versionMajor()) + "_"
|
||||||
|
+ QString::number(current.versionMinor());
|
||||||
|
|
||||||
for(int i = 0; i < q->metaObject()->methodCount(); i++){
|
for (int i = 0; i < q->metaObject()->methodCount(); i++) {
|
||||||
QMetaMethod m = q->metaObject()->method(i);
|
QMetaMethod m = q->metaObject()->method(i);
|
||||||
if(m.name() == "update" + versionText){
|
if (m.name() == "update" + versionText) {
|
||||||
m.invoke(q, Qt::DirectConnection,
|
m.invoke(q, Qt::DirectConnection,
|
||||||
Q_ARG(int, current.versionMajor()),
|
Q_ARG(int, current.versionMajor()),
|
||||||
Q_ARG(int, current.versionMinor()));
|
Q_ARG(int, current.versionMinor()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{
|
} else {
|
||||||
qWarning("Unable update database, error = %s", db.lastError().text().toLatin1().data());
|
qWarning("Unable update database, error = %s",
|
||||||
|
db.lastError().text().toLatin1().data());
|
||||||
}
|
}
|
||||||
|
|
||||||
return ok;
|
return ok;
|
||||||
|
|
@ -148,41 +159,47 @@ void DatabasePrivate::getCurrectScheema()
|
||||||
Q_Q(Database);
|
Q_Q(Database);
|
||||||
tables.clear();
|
tables.clear();
|
||||||
|
|
||||||
//TODO: change logs must not be in model
|
// TODO: change logs must not be in model
|
||||||
int changeLogTypeId = qRegisterMetaType<ChangeLogTable*>();
|
int changeLogTypeId = qRegisterMetaType<ChangeLogTable *>();
|
||||||
currentModel.append(new TableModel(changeLogTypeId, __CHANGE_LOG_TABLE_NAME));
|
currentModel.append(
|
||||||
tables.insert(ChangeLogTable::staticMetaObject.className(), __CHANGE_LOG_TABLE_NAME);
|
new TableModel(changeLogTypeId, __CHANGE_LOG_TABLE_NAME));
|
||||||
|
tables.insert(ChangeLogTable::staticMetaObject.className(),
|
||||||
|
__CHANGE_LOG_TABLE_NAME);
|
||||||
|
|
||||||
changeLogs = new TableSet<ChangeLogTable>(q);
|
changeLogs = new TableSet<ChangeLogTable>(q);
|
||||||
|
|
||||||
for(int i = 0; i < q->metaObject()->classInfoCount(); i++){
|
for (int i = 0; i < q->metaObject()->classInfoCount(); i++) {
|
||||||
QMetaClassInfo ci = q->metaObject()->classInfo(i);
|
QMetaClassInfo ci = q->metaObject()->classInfo(i);
|
||||||
QString ciName = QString(ci.name()).replace(__nut_NAME_PERFIX, "").replace("\"", "");
|
QString ciName
|
||||||
|
= QString(ci.name()).replace(__nut_NAME_PERFIX, "").replace("\"",
|
||||||
if(ciName.startsWith(__nut_TABLE))
|
"");
|
||||||
|
if (ciName.startsWith(__nut_TABLE))
|
||||||
tables.insert(ciName.split(" ").at(1), ci.value());
|
tables.insert(ciName.split(" ").at(1), ci.value());
|
||||||
|
|
||||||
if(ciName == __nut_DB_VERSION){
|
if (ciName == __nut_DB_VERSION) {
|
||||||
QStringList version = QString(ci.value()).replace("\"", "").split('.');
|
QStringList version
|
||||||
|
= QString(ci.value()).replace("\"", "").split('.');
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
if(version.length() == 1){
|
if (version.length() == 1) {
|
||||||
currentModel.setVersionMajor(version.at(0).toInt(&ok));
|
currentModel.setVersionMajor(version.at(0).toInt(&ok));
|
||||||
} else if(version.length() == 2){
|
} else if (version.length() == 2) {
|
||||||
currentModel.setVersionMajor(version.at(0).toInt(&ok));
|
currentModel.setVersionMajor(version.at(0).toInt(&ok));
|
||||||
currentModel.setVersionMinor(version.at(1).toInt(&ok));
|
currentModel.setVersionMinor(version.at(1).toInt(&ok));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!ok)
|
if (!ok)
|
||||||
qFatal("NUT_DB_VERSION macro accept version in format 'x' or 'x[.y]' only, and x,y must be integer values\n");
|
qFatal("NUT_DB_VERSION macro accept version in format 'x' or "
|
||||||
|
"'x[.y]' only, and x,y must be integer values\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 1; i < q->metaObject()->propertyCount(); i++){
|
for (int i = 1; i < q->metaObject()->propertyCount(); i++) {
|
||||||
QMetaProperty tableProperty = q->metaObject()->property(i);
|
QMetaProperty tableProperty = q->metaObject()->property(i);
|
||||||
int typeId = QMetaType::type(tableProperty.typeName());
|
int typeId = QMetaType::type(tableProperty.typeName());
|
||||||
|
|
||||||
qDebug() << tables.values().contains(tableProperty.name()) << typeId;
|
qDebug() << tables.values().contains(tableProperty.name()) << typeId;
|
||||||
if(tables.values().contains(tableProperty.name()) && typeId >= QVariant::UserType){
|
if (tables.values().contains(tableProperty.name())
|
||||||
|
&& typeId >= QVariant::UserType) {
|
||||||
TableModel *sch = new TableModel(typeId, tableProperty.name());
|
TableModel *sch = new TableModel(typeId, tableProperty.name());
|
||||||
currentModel.append(sch);
|
currentModel.append(sch);
|
||||||
}
|
}
|
||||||
|
|
@ -196,13 +213,17 @@ void DatabasePrivate::getCurrectScheema()
|
||||||
DatabaseModel DatabasePrivate::getLastScheema()
|
DatabaseModel DatabasePrivate::getLastScheema()
|
||||||
{
|
{
|
||||||
Q_Q(Database);
|
Q_Q(Database);
|
||||||
// ChangeLogTable *u = q->_change_logs()->createQuery()->orderBy("id", "desc")->first();
|
// ChangeLogTable *u = q->_change_logs()->createQuery()->orderBy("id",
|
||||||
ChangeLogTable *u = changeLogs->createQuery()->orderBy("id", "desc")->first();
|
// "desc")->first();
|
||||||
|
ChangeLogTable *u
|
||||||
|
= changeLogs->createQuery()->orderBy("id", "desc")->first();
|
||||||
|
|
||||||
DatabaseModel ret;
|
DatabaseModel ret;
|
||||||
|
|
||||||
if(u){
|
if (u) {
|
||||||
QJsonObject json = QJsonDocument::fromJson(QByteArray(u->data().toLocal8Bit().data())).object();
|
QJsonObject json
|
||||||
|
= QJsonDocument::fromJson(
|
||||||
|
QByteArray(u->data().toLocal8Bit().data())).object();
|
||||||
|
|
||||||
foreach (QString key, json.keys()) {
|
foreach (QString key, json.keys()) {
|
||||||
TableModel *sch = new TableModel(json.value(key).toObject(), key);
|
TableModel *sch = new TableModel(json.value(key).toObject(), key);
|
||||||
|
|
@ -213,18 +234,21 @@ DatabaseModel DatabasePrivate::getLastScheema()
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
// QSqlQuery query = q->exec("select * from __change_logs order by id desc limit 1");
|
// QSqlQuery query = q->exec("select * from __change_logs order by id
|
||||||
// DatabaseModel ret;
|
// desc limit 1");
|
||||||
// if(query.next()){
|
// DatabaseModel ret;
|
||||||
// QJsonObject json = QJsonDocument::fromJson(query.value("data").toByteArray()).object();
|
// if(query.next()){
|
||||||
|
// QJsonObject json =
|
||||||
|
// QJsonDocument::fromJson(query.value("data").toByteArray()).object();
|
||||||
|
|
||||||
// foreach (QString key, json.keys()) {
|
// foreach (QString key, json.keys()) {
|
||||||
// TableModel *sch = new TableModel(json.value(key).toObject(), key);
|
// TableModel *sch = new TableModel(json.value(key).toObject(),
|
||||||
// ret.append(sch);
|
// key);
|
||||||
// }
|
// ret.append(sch);
|
||||||
// }
|
// }
|
||||||
//qDebug() << "ret=" <<ret;
|
// }
|
||||||
// return ret;
|
// qDebug() << "ret=" <<ret;
|
||||||
|
// return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DatabasePrivate::storeScheemaInDB()
|
bool DatabasePrivate::storeScheemaInDB()
|
||||||
|
|
@ -243,39 +267,41 @@ bool DatabasePrivate::storeScheemaInDB()
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
// QSqlQuery query(db);
|
||||||
// QSqlQuery query(db);
|
// query.prepare("insert into __change_logs (data) values (:data)");
|
||||||
// query.prepare("insert into __change_logs (data) values (:data)");
|
// query.bindValue(":data",
|
||||||
// query.bindValue(":data", QString(QJsonDocument(currentModel.toJson()).toJson()));
|
// QString(QJsonDocument(currentModel.toJson()).toJson()));
|
||||||
// bool ret = query.exec();
|
// bool ret = query.exec();
|
||||||
// if(query.lastError().type() != QSqlError::NoError)
|
// if(query.lastError().type() != QSqlError::NoError)
|
||||||
// qWarning(QString("storeScheemaInDB" + query.lastError().text()).toLatin1().data());
|
// qWarning(QString("storeScheemaInDB" +
|
||||||
// return ret;
|
// query.lastError().text()).toLatin1().data());
|
||||||
|
// return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabasePrivate::createChangeLogs()
|
void DatabasePrivate::createChangeLogs()
|
||||||
{
|
{
|
||||||
// currentModel.model("change_log")
|
// currentModel.model("change_log")
|
||||||
QString diff = sqlGenertor->diff(0, currentModel.model("__change_log"));
|
QString diff = sqlGenertor->diff(0, currentModel.model("__change_log"));
|
||||||
|
|
||||||
db.exec(diff);
|
db.exec(diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \class Database
|
* \class Database
|
||||||
* \brief Database class
|
* \brief Database class
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Database::Database(QObject *parent) : QObject(parent), d_ptr(new DatabasePrivate(this))
|
Database::Database(QObject *parent)
|
||||||
|
: QObject(parent), d_ptr(new DatabasePrivate(this))
|
||||||
{
|
{
|
||||||
Q_D(Database);
|
Q_D(Database);
|
||||||
//d->changeLogs->sett
|
// d->changeLogs->sett
|
||||||
DatabasePrivate::lastId++;
|
DatabasePrivate::lastId++;
|
||||||
// m__change_logs = new TableSet<ChangeLogTable>(this);
|
// m__change_logs = new TableSet<ChangeLogTable>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Database::Database(const Database &other, QObject *parent) : QObject(parent), d_ptr(new DatabasePrivate(this))
|
Database::Database(const Database &other, QObject *parent)
|
||||||
|
: QObject(parent), d_ptr(new DatabasePrivate(this))
|
||||||
{
|
{
|
||||||
Q_D(Database);
|
Q_D(Database);
|
||||||
|
|
||||||
|
|
@ -287,7 +313,13 @@ Database::Database(const Database &other, QObject *parent) : QObject(parent), d_
|
||||||
setUserName(other.userName());
|
setUserName(other.userName());
|
||||||
setPassword(other.password());
|
setPassword(other.password());
|
||||||
|
|
||||||
// m__change_logs = new TableSet<ChangeLogTable>(this);
|
// m__change_logs = new TableSet<ChangeLogTable>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
Database::~Database()
|
||||||
|
{
|
||||||
|
if (d_ptr)
|
||||||
|
delete d_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Database::databaseName() const
|
QString Database::databaseName() const
|
||||||
|
|
@ -400,7 +432,8 @@ SqlGeneratorBase *Database::sqlGenertor() const
|
||||||
return d->sqlGenertor;
|
return d->sqlGenertor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::databaseUpdated(int oldMajor, int oldMinor, int newMajor, int newMinor)
|
void Database::databaseUpdated(int oldMajor, int oldMinor, int newMajor,
|
||||||
|
int newMinor)
|
||||||
{
|
{
|
||||||
Q_UNUSED(oldMajor);
|
Q_UNUSED(oldMajor);
|
||||||
Q_UNUSED(oldMinor);
|
Q_UNUSED(oldMinor);
|
||||||
|
|
@ -412,28 +445,29 @@ bool Database::open()
|
||||||
{
|
{
|
||||||
Q_D(Database);
|
Q_D(Database);
|
||||||
|
|
||||||
if(d->driver == "QPSQL" || d->driver == "QPSQL7")
|
if (d->driver == "QPSQL" || d->driver == "QPSQL7")
|
||||||
d->sqlGenertor = new PostgreSqlGenerator(this);
|
d->sqlGenertor = new PostgreSqlGenerator(this);
|
||||||
else if (d->driver == "QMYSQL" || d->driver == "QMYSQL3")
|
else if (d->driver == "QMYSQL" || d->driver == "QMYSQL3")
|
||||||
d->sqlGenertor = new MySqlGenerator(this);
|
d->sqlGenertor = new MySqlGenerator(this);
|
||||||
else if (d->driver == "QSQLITE" || d->driver == "QSQLITE3")
|
else if (d->driver == "QSQLITE" || d->driver == "QSQLITE3")
|
||||||
d->sqlGenertor = new SqliteGenerator(this);
|
d->sqlGenertor = new SqliteGenerator(this);
|
||||||
else if(d->driver == "QODBC" || d->driver == "QODBC3"){
|
else if (d->driver == "QODBC" || d->driver == "QODBC3") {
|
||||||
QString driverName = QString::null;
|
QString driverName = QString::null;
|
||||||
QStringList parts = d->databaseName.toLower().split(';');
|
QStringList parts = d->databaseName.toLower().split(';');
|
||||||
foreach (QString p, parts)
|
foreach (QString p, parts)
|
||||||
if(p.trimmed().startsWith("driver="))
|
if (p.trimmed().startsWith("driver="))
|
||||||
driverName = p.split('=').at(1).toLower().trimmed();
|
driverName = p.split('=').at(1).toLower().trimmed();
|
||||||
|
|
||||||
if(driverName == "{sql server}")
|
if (driverName == "{sql server}")
|
||||||
d->sqlGenertor = new SqlServerGenerator(this);
|
d->sqlGenertor = new SqlServerGenerator(this);
|
||||||
//TODO: add ODBC driver for mysql, postgres, ...
|
// TODO: add ODBC driver for mysql, postgres, ...
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!d->sqlGenertor){
|
if (!d->sqlGenertor) {
|
||||||
qWarning("Sql generator for driver %s not found", driver().toLatin1().constData());
|
qWarning("Sql generator for driver %s not found",
|
||||||
|
driver().toLatin1().constData());
|
||||||
return false;
|
return false;
|
||||||
}else{
|
} else {
|
||||||
return d->open();
|
return d->open();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -449,8 +483,9 @@ QSqlQuery Database::exec(QString sql)
|
||||||
Q_D(Database);
|
Q_D(Database);
|
||||||
|
|
||||||
QSqlQuery q = d->db.exec(sql);
|
QSqlQuery q = d->db.exec(sql);
|
||||||
if(d->db.lastError().type() != QSqlError::NoError)
|
if (d->db.lastError().type() != QSqlError::NoError)
|
||||||
qWarning("Error executing sql command: %s", d->db.lastError().text().toLatin1().data());
|
qWarning("Error executing sql command: %s",
|
||||||
|
d->db.lastError().text().toLatin1().data());
|
||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -461,13 +496,13 @@ void Database::add(TableSetBase *t)
|
||||||
|
|
||||||
void Database::saveChanges()
|
void Database::saveChanges()
|
||||||
{
|
{
|
||||||
foreach(TableSetBase *ts, tableSets)
|
foreach (TableSetBase *ts, tableSets)
|
||||||
ts->save(this);
|
ts->save(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::cleanUp()
|
void Database::cleanUp()
|
||||||
{
|
{
|
||||||
foreach(TableSetBase *ts, tableSets)
|
foreach (TableSetBase *ts, tableSets)
|
||||||
ts->clearChilds();
|
ts->clearChilds();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,14 +39,13 @@ class NUT_EXPORT Database : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
// NUT_DECLARE_TABLE(ChangeLogTable, _change_log)
|
|
||||||
|
|
||||||
DatabasePrivate *d_ptr;
|
DatabasePrivate *d_ptr;
|
||||||
Q_DECLARE_PRIVATE(Database)
|
Q_DECLARE_PRIVATE(Database)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Database(QObject *parent = 0);
|
Database(QObject *parent = 0);
|
||||||
Database(const Database &other, QObject *parent = 0);
|
Database(const Database &other, QObject *parent = 0);
|
||||||
|
~Database();
|
||||||
|
|
||||||
bool open();
|
bool open();
|
||||||
void close();
|
void close();
|
||||||
|
|
@ -71,7 +70,8 @@ public:
|
||||||
SqlGeneratorBase *sqlGenertor() const;
|
SqlGeneratorBase *sqlGenertor() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void databaseUpdated(int oldMajor, int oldMinor, int newMajor, int newMinor);
|
virtual void databaseUpdated(int oldMajor, int oldMinor, int newMajor,
|
||||||
|
int newMinor);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setDatabaseName(QString databaseName);
|
void setDatabaseName(QString databaseName);
|
||||||
|
|
@ -83,9 +83,9 @@ public slots:
|
||||||
void setDriver(QString driver);
|
void setDriver(QString driver);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QSet<TableSetBase*> tableSets;
|
QSet<TableSetBase *> tableSets;
|
||||||
};
|
};
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // NUTDATABASE_H
|
#endif // NUTDATABASE_H
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
#include "dbgeography.h"
|
||||||
|
|
||||||
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
DbGeography::DbGeography(QObject *parent) //: QObject(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
DbGeography::DbGeography(const DbGeography &other)
|
||||||
|
{
|
||||||
|
setLatitude(other.latitude());
|
||||||
|
setLongitude(other.longitude());
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal DbGeography::latitude() const
|
||||||
|
{
|
||||||
|
return m_latitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal DbGeography::longitude() const
|
||||||
|
{
|
||||||
|
return m_longitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DbGeography::setLatitude(qreal latitude)
|
||||||
|
{
|
||||||
|
if (qFuzzyCompare(m_latitude, latitude))
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_latitude = latitude;
|
||||||
|
// emit latitudeChanged(latitude);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DbGeography::setLongitude(qreal longitude)
|
||||||
|
{
|
||||||
|
if (qFuzzyCompare(m_longitude, longitude))
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_longitude = longitude;
|
||||||
|
// emit longitudeChanged(longitude);
|
||||||
|
}
|
||||||
|
|
||||||
|
NUT_END_NAMESPACE
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
#ifndef DBGEOGRAPHY_H
|
||||||
|
#define DBGEOGRAPHY_H
|
||||||
|
|
||||||
|
#include "defines.h"
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
#include <QtCore/qglobal.h>
|
||||||
|
|
||||||
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class NUT_EXPORT DbGeography //: public QObject
|
||||||
|
{
|
||||||
|
// Q_PROPERTY(qreal latitude READ latitude WRITE setLatitude NOTIFY
|
||||||
|
// latitudeChanged)
|
||||||
|
// Q_PROPERTY(qreal longitude READ longitude WRITE setLongitude NOTIFY
|
||||||
|
// longitudeChanged)
|
||||||
|
qreal m_latitude;
|
||||||
|
qreal m_longitude;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit DbGeography(QObject *parent = 0);
|
||||||
|
DbGeography(const DbGeography &other);
|
||||||
|
|
||||||
|
qreal latitude() const;
|
||||||
|
qreal longitude() const;
|
||||||
|
|
||||||
|
//signals:
|
||||||
|
// void latitudeChanged(qreal latitude);
|
||||||
|
// void longitudeChanged(qreal longitude);
|
||||||
|
|
||||||
|
//public slots:
|
||||||
|
void setLatitude(qreal latitude);
|
||||||
|
void setLongitude(qreal longitude);
|
||||||
|
};
|
||||||
|
|
||||||
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
#ifdef NUT_NAMESPACE
|
||||||
|
Q_DECLARE_METATYPE(NUT_NAMESPACE::DbGeography)
|
||||||
|
#else
|
||||||
|
Q_DECLARE_METATYPE(DbGeography)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // DBGEOGRAPHY_H
|
||||||
|
|
@ -60,8 +60,8 @@ public: \
|
||||||
Q_CLASSINFO(QT_STRINGIFY(__nut_NAME_PERFIX #name " " __nut_FIELD), #name) \
|
Q_CLASSINFO(QT_STRINGIFY(__nut_NAME_PERFIX #name " " __nut_FIELD), #name) \
|
||||||
type m_##name; \
|
type m_##name; \
|
||||||
public: \
|
public: \
|
||||||
static __NUT_NAMESPACE_PERFIX FieldPhrase name##Field(){ \
|
static __NUT_NAMESPACE_PERFIX FieldPhrase<type> name##Field(){ \
|
||||||
static __NUT_NAMESPACE_PERFIX FieldPhrase f = __NUT_NAMESPACE_PERFIX FieldPhrase(staticMetaObject.className(), #name); \
|
static __NUT_NAMESPACE_PERFIX FieldPhrase<type> f = __NUT_NAMESPACE_PERFIX FieldPhrase<type>(staticMetaObject.className(), #name); \
|
||||||
return f; \
|
return f; \
|
||||||
} \
|
} \
|
||||||
type read() const{ \
|
type read() const{ \
|
||||||
|
|
|
||||||
|
|
@ -64,10 +64,20 @@ QString PostgreSqlGenerator::fieldType(FieldModel *field)
|
||||||
else
|
else
|
||||||
dbType = "text";
|
dbType = "text";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case QVariant::Point:
|
||||||
|
case QVariant::PointF:
|
||||||
|
dbType="point";
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
qDebug() << "Type for " << (int)field->type << field->type << "(" << QMetaType::typeName(field->type) << ")" << "nut supported";
|
||||||
dbType = "";
|
dbType = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(field->type == QMetaType::type("Nut::DbGeography"))
|
||||||
|
dbType = "GEOGRAPHY";
|
||||||
|
|
||||||
return dbType;
|
return dbType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
10
src/query.h
10
src/query.h
|
|
@ -54,9 +54,9 @@ public:
|
||||||
|
|
||||||
int count();
|
int count();
|
||||||
|
|
||||||
QVariant max(FieldPhrase &f);
|
QVariant max(FieldPhrase<int> &f);
|
||||||
QVariant min(FieldPhrase &f);
|
QVariant min(FieldPhrase<int> &f);
|
||||||
QVariant average(FieldPhrase &f){
|
QVariant average(FieldPhrase<int> &f){
|
||||||
//TODO: ...
|
//TODO: ...
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
@ -198,7 +198,7 @@ Q_OUTOFLINE_TEMPLATE int Query<T>::count()
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
Q_OUTOFLINE_TEMPLATE QVariant Query<T>::max(FieldPhrase &f){
|
Q_OUTOFLINE_TEMPLATE QVariant Query<T>::max(FieldPhrase<int> &f){
|
||||||
Q_D(Query);
|
Q_D(Query);
|
||||||
|
|
||||||
QSqlQuery q = d->database->exec(d->database->sqlGenertor()->selectCommand("MAX(" + f.data()->text + ")", d->wheres, d->orders, d->tableName, d->joinClassName));
|
QSqlQuery q = d->database->exec(d->database->sqlGenertor()->selectCommand("MAX(" + f.data()->text + ")", d->wheres, d->orders, d->tableName, d->joinClassName));
|
||||||
|
|
@ -209,7 +209,7 @@ Q_OUTOFLINE_TEMPLATE QVariant Query<T>::max(FieldPhrase &f){
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
Q_OUTOFLINE_TEMPLATE QVariant Query<T>::min(FieldPhrase &f){
|
Q_OUTOFLINE_TEMPLATE QVariant Query<T>::min(FieldPhrase<int> &f){
|
||||||
Q_D(Query);
|
Q_D(Query);
|
||||||
|
|
||||||
QSqlQuery q = d->database->exec(d->database->sqlGenertor()->selectCommand("MIN(" + f.data()->text + ")", d->wheres, d->orders, d->tableName, d->joinClassName));
|
QSqlQuery q = d->database->exec(d->database->sqlGenertor()->selectCommand("MIN(" + f.data()->text + ")", d->wheres, d->orders, d->tableName, d->joinClassName));
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,7 @@ TableModel::TableModel(int typeId, QString tableName)
|
||||||
f = fieldObj;
|
f = fieldObj;
|
||||||
if(!fieldObj)
|
if(!fieldObj)
|
||||||
continue;
|
continue;
|
||||||
|
qDebug() <<"fieldProperty.type()"<<fieldProperty.typeName();
|
||||||
fieldObj->type = fieldProperty.type();
|
fieldObj->type = fieldProperty.type();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -259,6 +259,7 @@ TableModel::TableModel(QJsonObject json, QString tableName)
|
||||||
QJsonObject fieldObject = fields.value(key).toObject();
|
QJsonObject fieldObject = fields.value(key).toObject();
|
||||||
FieldModel *f = new FieldModel;
|
FieldModel *f = new FieldModel;
|
||||||
f->name = fieldObject.value(__NAME).toString();
|
f->name = fieldObject.value(__NAME).toString();
|
||||||
|
qDebug() << "fieldObject.value(__TYPE).toString()"<<fieldObject.value(__TYPE).toString();
|
||||||
f->type = QVariant::nameToType(fieldObject.value(__TYPE).toString().toLatin1().data());
|
f->type = QVariant::nameToType(fieldObject.value(__TYPE).toString().toLatin1().data());
|
||||||
|
|
||||||
if(fieldObject.contains(__nut_NOT_NULL))
|
if(fieldObject.contains(__nut_NOT_NULL))
|
||||||
|
|
|
||||||
|
|
@ -204,16 +204,6 @@ WherePhrase WherePhrase::operator &(const WherePhrase &other)
|
||||||
return WherePhrase(this, PhraseData::Append, (WherePhrase*)&other);
|
return WherePhrase(this, PhraseData::Append, (WherePhrase*)&other);
|
||||||
}
|
}
|
||||||
|
|
||||||
WherePhrase FieldPhrase::operator !()
|
|
||||||
{
|
|
||||||
if(_data->operatorCond < 20)
|
|
||||||
_data->operatorCond = (PhraseData::Condition)((_data->operatorCond + 10) % 20);
|
|
||||||
else
|
|
||||||
qFatal("Operator ! can not aplied to non condition statements");
|
|
||||||
|
|
||||||
return this;//WherePhrase(this, PhraseData::Not);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase WherePhrase::operator ==(const QVariant &other)
|
WherePhrase WherePhrase::operator ==(const QVariant &other)
|
||||||
{
|
{
|
||||||
return WherePhrase(this, PhraseData::Equal, other);
|
return WherePhrase(this, PhraseData::Equal, other);
|
||||||
|
|
@ -244,35 +234,6 @@ WherePhrase WherePhrase::operator >=(const QVariant &other)
|
||||||
return WherePhrase(this, PhraseData::GreaterEqual, other);
|
return WherePhrase(this, PhraseData::GreaterEqual, other);
|
||||||
}
|
}
|
||||||
|
|
||||||
FieldPhrase::FieldPhrase(const char *className, const char *s) : WherePhrase(className, s)
|
|
||||||
{
|
|
||||||
// qDebug() << "(" << this << ")" << "FieldPhrase ctor" << className << s;
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase FieldPhrase::operator =(const QVariant &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Set, other);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase FieldPhrase::isNull(){
|
|
||||||
return WherePhrase(this, PhraseData::Null);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase FieldPhrase::in(QVariantList list)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::In, list);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase FieldPhrase::in(QStringList list)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::In, list);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase FieldPhrase::like(QString pattern)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Like, pattern);
|
|
||||||
}
|
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
#include <QTime>
|
#include <QTime>
|
||||||
#include <QSharedPointer>
|
#include <QSharedPointer>
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
|
#include "dbgeography.h"
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
@ -63,7 +64,10 @@ public:
|
||||||
Add,
|
Add,
|
||||||
Minus,
|
Minus,
|
||||||
Multiple,
|
Multiple,
|
||||||
Divide
|
Divide,
|
||||||
|
|
||||||
|
//special types
|
||||||
|
Distance
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Type{
|
enum Type{
|
||||||
|
|
@ -136,6 +140,7 @@ public:
|
||||||
PhraseData *data() const;
|
PhraseData *data() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
class FieldPhrase: public WherePhrase{
|
class FieldPhrase: public WherePhrase{
|
||||||
public:
|
public:
|
||||||
FieldPhrase(const char *className, const char* s);
|
FieldPhrase(const char *className, const char* s);
|
||||||
|
|
@ -156,6 +161,66 @@ public:
|
||||||
|
|
||||||
//};
|
//};
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Q_OUTOFLINE_TEMPLATE FieldPhrase<T>::FieldPhrase(const char *className, const char *s) : WherePhrase(className, s)
|
||||||
|
{
|
||||||
|
// qDebug() << "(" << this << ")" << "FieldPhrase ctor" << className << s;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase<T>::operator =(const QVariant &other)
|
||||||
|
{
|
||||||
|
return WherePhrase(this, PhraseData::Set, other);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase<T>::operator !()
|
||||||
|
{
|
||||||
|
if(_data->operatorCond < 20)
|
||||||
|
_data->operatorCond = (PhraseData::Condition)((_data->operatorCond + 10) % 20);
|
||||||
|
else
|
||||||
|
qFatal("Operator ! can not aplied to non condition statements");
|
||||||
|
|
||||||
|
return this;//WherePhrase(this, PhraseData::Not);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase<T>::isNull(){
|
||||||
|
return WherePhrase(this, PhraseData::Null);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase<T>::in(QVariantList list)
|
||||||
|
{
|
||||||
|
return WherePhrase(this, PhraseData::In, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase<T>::in(QStringList list)
|
||||||
|
{
|
||||||
|
return WherePhrase(this, PhraseData::In, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase<T>::like(QString pattern)
|
||||||
|
{
|
||||||
|
return WherePhrase(this, PhraseData::Like, pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
class FieldPhrase<DbGeography>: public WherePhrase {
|
||||||
|
public:
|
||||||
|
FieldPhrase(const char *className, const char* s) : WherePhrase(className, s){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
WherePhrase distance(const DbGeography &geo) {
|
||||||
|
return WherePhrase(this, PhraseData::Distance, QVariant::fromValue(geo));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // PHRASE_H
|
#endif // PHRASE_H
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue