From 3e888c080e2199dc7d9f6a6aa2150a68c2204f51 Mon Sep 17 00:00:00 2001 From: blackdal Date: Thu, 25 May 2017 20:16:54 +0430 Subject: [PATCH] models --- include/DbGeography | 1 + include/Nut | 1 + include/dbgeography.h | 1 + include/header_copier | 2 +- include/nut.h | 1 + nut.pri | 6 +- src/database.cpp | 199 +++++++++++++++++++++--------------- src/database.h | 10 +- src/dbgeography.cpp | 44 ++++++++ src/dbgeography.h | 43 ++++++++ src/defines.h | 4 +- src/postgresqlgenerator.cpp | 10 ++ src/query.h | 10 +- src/tablemodel.cpp | 3 +- src/wherephrase.cpp | 39 ------- src/wherephrase.h | 67 +++++++++++- 16 files changed, 303 insertions(+), 138 deletions(-) create mode 100644 include/DbGeography create mode 100644 include/dbgeography.h mode change 100644 => 100755 include/header_copier create mode 100644 src/dbgeography.cpp create mode 100644 src/dbgeography.h diff --git a/include/DbGeography b/include/DbGeography new file mode 100644 index 0000000..7e8c4fa --- /dev/null +++ b/include/DbGeography @@ -0,0 +1 @@ +#include "../src/dbgeography.h" diff --git a/include/Nut b/include/Nut index 5b89c95..2dfb0b9 100644 --- a/include/Nut +++ b/include/Nut @@ -2,4 +2,5 @@ #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 new file mode 100644 index 0000000..7e8c4fa --- /dev/null +++ b/include/dbgeography.h @@ -0,0 +1 @@ +#include "../src/dbgeography.h" diff --git a/include/header_copier b/include/header_copier old mode 100644 new mode 100755 index b0394f7..6265d12 --- a/include/header_copier +++ b/include/header_copier @@ -7,7 +7,7 @@ pattern="\.\.\/src\/([a-z]+)\.h\:class\sNUT_EXPORT\s(\w+)" echo "" > "Nut" echo "" > "nut.h" -mkdir -p Nut +#mkdir -p Nut while read line; do if [[ $line =~ $pattern ]]; then diff --git a/include/nut.h b/include/nut.h index 5b89c95..2dfb0b9 100644 --- a/include/nut.h +++ b/include/nut.h @@ -2,4 +2,5 @@ #include "../src/table.h" #include "../src/database.h" #include "../src/tableset.h" +#include "../src/dbgeography.h" #include "../src/query.h" diff --git a/nut.pri b/nut.pri index a3355e3..b596e78 100644 --- a/nut.pri +++ b/nut.pri @@ -21,7 +21,8 @@ HEADERS += \ $$PWD/src/query_p.h \ $$PWD/src/table.h \ $$PWD/src/database.h \ - $$PWD/src/database_p.h + $$PWD/src/database_p.h \ + $$PWD/src/dbgeography.h SOURCES += \ $$PWD/src/tableset.cpp \ @@ -38,4 +39,5 @@ SOURCES += \ $$PWD/src/sqlservergenerator.cpp \ $$PWD/src/wherephrase.cpp \ $$PWD/src/table.cpp \ - $$PWD/src/database.cpp + $$PWD/src/database.cpp \ + $$PWD/src/dbgeography.cpp diff --git a/src/database.cpp b/src/database.cpp index b3672dd..c2c078c 100644 --- a/src/database.cpp +++ b/src/database.cpp @@ -58,7 +58,8 @@ bool DatabasePrivate::open() Q_Q(Database); getCurrectScheema(); - connectionName = q->metaObject()->className() + QString::number(DatabasePrivate::lastId); + connectionName = q->metaObject()->className() + + QString::number(DatabasePrivate::lastId); db = QSqlDatabase::addDatabase(driver, connectionName); db.setHostName(hostName); @@ -67,25 +68,30 @@ bool DatabasePrivate::open() db.setPassword(password); bool ok = db.open(); - if(!ok){ - qWarning("Could not connect to database, error = %s", db.lastError().text().toLocal8Bit().data()); + if (!ok) { + qWarning("Could not connect to database, error = %s", + db.lastError().text().toLocal8Bit().data()); - if(db.lastError().text().contains("database \"" + databaseName + "\" does not exist") - || db.lastError().text().contains("Cannot open database") - || db.lastError().text().contains("Unknown database '" + databaseName + "'")){ + if (db.lastError().text().contains("database \"" + databaseName + + "\" does not exist") + || db.lastError().text().contains("Cannot open database") + || db.lastError().text().contains("Unknown database '" + + databaseName + "'")) { db.setDatabaseName(sqlGenertor->masterDatabaseName(databaseName)); ok = db.open(); qDebug("Creating database"); - if(ok){ + if (ok) { db.exec("CREATE DATABASE " + databaseName); db.close(); - if(db.lastError().type() != QSqlError::NoError) - qWarning("Creating database error: %s", db.lastError().text().toLatin1().data()); + if (db.lastError().type() != QSqlError::NoError) + qWarning("Creating database error: %s", + db.lastError().text().toLatin1().data()); return open(); - }else{ - qWarning("Unknown error detecting change logs, %s", db.lastError().text().toLatin1().data()); + } else { + qWarning("Unknown error detecting change logs, %s", + db.lastError().text().toLatin1().data()); } } return false; @@ -101,43 +107,48 @@ bool DatabasePrivate::updateDatabase() DatabaseModel last = getLastScheema(); DatabaseModel current = currentModel; - if(last == current){ + if (last == current) { qDebug("Databse is up-to-date"); return true; } - if(!last.count()) + if (!last.count()) qDebug("Databse is new"); else qDebug("Databse is changed"); QStringList sql = sqlGenertor->diff(last, current); db.transaction(); - foreach (QString s, sql){ + foreach (QString s, sql) { + qDebug() <<"cmd="<databaseUpdated(last.versionMajor(), last.versionMinor(), current.versionMajor(), current.versionMinor()); - QString versionText = QString::number(current.versionMajor()) + "_" + QString::number(current.versionMinor()); + q->databaseUpdated(last.versionMajor(), last.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); - if(m.name() == "update" + versionText){ + if (m.name() == "update" + versionText) { m.invoke(q, Qt::DirectConnection, Q_ARG(int, current.versionMajor()), Q_ARG(int, current.versionMinor())); break; } } - }else{ - qWarning("Unable update database, error = %s", db.lastError().text().toLatin1().data()); + } else { + qWarning("Unable update database, error = %s", + db.lastError().text().toLatin1().data()); } return ok; @@ -148,41 +159,47 @@ void DatabasePrivate::getCurrectScheema() Q_Q(Database); tables.clear(); - //TODO: change logs must not be in model - int changeLogTypeId = qRegisterMetaType(); - currentModel.append(new TableModel(changeLogTypeId, __CHANGE_LOG_TABLE_NAME)); - tables.insert(ChangeLogTable::staticMetaObject.className(), __CHANGE_LOG_TABLE_NAME); + // TODO: change logs must not be in model + int changeLogTypeId = qRegisterMetaType(); + currentModel.append( + new TableModel(changeLogTypeId, __CHANGE_LOG_TABLE_NAME)); + tables.insert(ChangeLogTable::staticMetaObject.className(), + __CHANGE_LOG_TABLE_NAME); changeLogs = new TableSet(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); - QString ciName = QString(ci.name()).replace(__nut_NAME_PERFIX, "").replace("\"", ""); - - if(ciName.startsWith(__nut_TABLE)) + QString ciName + = QString(ci.name()).replace(__nut_NAME_PERFIX, "").replace("\"", + ""); + if (ciName.startsWith(__nut_TABLE)) tables.insert(ciName.split(" ").at(1), ci.value()); - if(ciName == __nut_DB_VERSION){ - QStringList version = QString(ci.value()).replace("\"", "").split('.'); + if (ciName == __nut_DB_VERSION) { + QStringList version + = QString(ci.value()).replace("\"", "").split('.'); bool ok = false; - if(version.length() == 1){ + if (version.length() == 1) { 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.setVersionMinor(version.at(1).toInt(&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"); + if (!ok) + 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); int typeId = QMetaType::type(tableProperty.typeName()); 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()); currentModel.append(sch); } @@ -196,13 +213,17 @@ void DatabasePrivate::getCurrectScheema() DatabaseModel DatabasePrivate::getLastScheema() { Q_Q(Database); -// ChangeLogTable *u = q->_change_logs()->createQuery()->orderBy("id", "desc")->first(); - ChangeLogTable *u = changeLogs->createQuery()->orderBy("id", "desc")->first(); + // ChangeLogTable *u = q->_change_logs()->createQuery()->orderBy("id", + // "desc")->first(); + ChangeLogTable *u + = changeLogs->createQuery()->orderBy("id", "desc")->first(); DatabaseModel ret; - if(u){ - QJsonObject json = QJsonDocument::fromJson(QByteArray(u->data().toLocal8Bit().data())).object(); + if (u) { + QJsonObject json + = QJsonDocument::fromJson( + QByteArray(u->data().toLocal8Bit().data())).object(); foreach (QString key, json.keys()) { TableModel *sch = new TableModel(json.value(key).toObject(), key); @@ -213,18 +234,21 @@ DatabaseModel DatabasePrivate::getLastScheema() } return ret; -// QSqlQuery query = q->exec("select * from __change_logs order by id desc limit 1"); -// DatabaseModel ret; -// if(query.next()){ -// QJsonObject json = QJsonDocument::fromJson(query.value("data").toByteArray()).object(); + // QSqlQuery query = q->exec("select * from __change_logs order by id + // desc limit 1"); + // DatabaseModel ret; + // if(query.next()){ + // QJsonObject json = + // QJsonDocument::fromJson(query.value("data").toByteArray()).object(); -// foreach (QString key, json.keys()) { -// TableModel *sch = new TableModel(json.value(key).toObject(), key); -// ret.append(sch); -// } -// } -//qDebug() << "ret=" <diff(0, currentModel.model("__change_log")); db.exec(diff); } - /*! * \class Database * \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); - //d->changeLogs->sett + // d->changeLogs->sett DatabasePrivate::lastId++; -// m__change_logs = new TableSet(this); + // m__change_logs = new TableSet(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); @@ -287,7 +313,13 @@ Database::Database(const Database &other, QObject *parent) : QObject(parent), d_ setUserName(other.userName()); setPassword(other.password()); -// m__change_logs = new TableSet(this); + // m__change_logs = new TableSet(this); +} + +Database::~Database() +{ + if (d_ptr) + delete d_ptr; } QString Database::databaseName() const @@ -400,7 +432,8 @@ SqlGeneratorBase *Database::sqlGenertor() const 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(oldMinor); @@ -412,28 +445,29 @@ bool Database::open() { Q_D(Database); - if(d->driver == "QPSQL" || d->driver == "QPSQL7") + if (d->driver == "QPSQL" || d->driver == "QPSQL7") d->sqlGenertor = new PostgreSqlGenerator(this); else if (d->driver == "QMYSQL" || d->driver == "QMYSQL3") d->sqlGenertor = new MySqlGenerator(this); else if (d->driver == "QSQLITE" || d->driver == "QSQLITE3") 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; QStringList parts = d->databaseName.toLower().split(';'); foreach (QString p, parts) - if(p.trimmed().startsWith("driver=")) + if (p.trimmed().startsWith("driver=")) driverName = p.split('=').at(1).toLower().trimmed(); - if(driverName == "{sql server}") + if (driverName == "{sql server}") d->sqlGenertor = new SqlServerGenerator(this); - //TODO: add ODBC driver for mysql, postgres, ... + // TODO: add ODBC driver for mysql, postgres, ... } - if(!d->sqlGenertor){ - qWarning("Sql generator for driver %s not found", driver().toLatin1().constData()); + if (!d->sqlGenertor) { + qWarning("Sql generator for driver %s not found", + driver().toLatin1().constData()); return false; - }else{ + } else { return d->open(); } } @@ -449,8 +483,9 @@ QSqlQuery Database::exec(QString sql) Q_D(Database); QSqlQuery q = d->db.exec(sql); - if(d->db.lastError().type() != QSqlError::NoError) - qWarning("Error executing sql command: %s", d->db.lastError().text().toLatin1().data()); + if (d->db.lastError().type() != QSqlError::NoError) + qWarning("Error executing sql command: %s", + d->db.lastError().text().toLatin1().data()); return q; } @@ -461,13 +496,13 @@ void Database::add(TableSetBase *t) void Database::saveChanges() { - foreach(TableSetBase *ts, tableSets) + foreach (TableSetBase *ts, tableSets) ts->save(this); } void Database::cleanUp() { - foreach(TableSetBase *ts, tableSets) + foreach (TableSetBase *ts, tableSets) ts->clearChilds(); } diff --git a/src/database.h b/src/database.h index 5d520b6..c2df6d8 100644 --- a/src/database.h +++ b/src/database.h @@ -39,14 +39,13 @@ class NUT_EXPORT Database : public QObject { Q_OBJECT -// NUT_DECLARE_TABLE(ChangeLogTable, _change_log) - DatabasePrivate *d_ptr; Q_DECLARE_PRIVATE(Database) public: Database(QObject *parent = 0); Database(const Database &other, QObject *parent = 0); + ~Database(); bool open(); void close(); @@ -71,7 +70,8 @@ public: SqlGeneratorBase *sqlGenertor() const; 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: void setDatabaseName(QString databaseName); @@ -83,9 +83,9 @@ public slots: void setDriver(QString driver); private: - QSet tableSets; + QSet tableSets; }; NUT_END_NAMESPACE -#endif // NUTDATABASE_H +#endif // NUTDATABASE_H diff --git a/src/dbgeography.cpp b/src/dbgeography.cpp new file mode 100644 index 0000000..3ca73f0 --- /dev/null +++ b/src/dbgeography.cpp @@ -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 diff --git a/src/dbgeography.h b/src/dbgeography.h new file mode 100644 index 0000000..09481fd --- /dev/null +++ b/src/dbgeography.h @@ -0,0 +1,43 @@ +#ifndef DBGEOGRAPHY_H +#define DBGEOGRAPHY_H + +#include "defines.h" +#include +#include + +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 diff --git a/src/defines.h b/src/defines.h index e7910e0..257e394 100644 --- a/src/defines.h +++ b/src/defines.h @@ -60,8 +60,8 @@ public: \ Q_CLASSINFO(QT_STRINGIFY(__nut_NAME_PERFIX #name " " __nut_FIELD), #name) \ type m_##name; \ public: \ - static __NUT_NAMESPACE_PERFIX FieldPhrase name##Field(){ \ - static __NUT_NAMESPACE_PERFIX FieldPhrase f = __NUT_NAMESPACE_PERFIX FieldPhrase(staticMetaObject.className(), #name); \ + static __NUT_NAMESPACE_PERFIX FieldPhrase name##Field(){ \ + static __NUT_NAMESPACE_PERFIX FieldPhrase f = __NUT_NAMESPACE_PERFIX FieldPhrase(staticMetaObject.className(), #name); \ return f; \ } \ type read() const{ \ diff --git a/src/postgresqlgenerator.cpp b/src/postgresqlgenerator.cpp index 598a406..0d78d31 100644 --- a/src/postgresqlgenerator.cpp +++ b/src/postgresqlgenerator.cpp @@ -64,10 +64,20 @@ QString PostgreSqlGenerator::fieldType(FieldModel *field) else dbType = "text"; break; + + case QVariant::Point: + case QVariant::PointF: + dbType="point"; + break; + default: + qDebug() << "Type for " << (int)field->type << field->type << "(" << QMetaType::typeName(field->type) << ")" << "nut supported"; dbType = ""; } + if(field->type == QMetaType::type("Nut::DbGeography")) + dbType = "GEOGRAPHY"; + return dbType; } diff --git a/src/query.h b/src/query.h index 1c06431..583bc12 100644 --- a/src/query.h +++ b/src/query.h @@ -54,9 +54,9 @@ public: int count(); - QVariant max(FieldPhrase &f); - QVariant min(FieldPhrase &f); - QVariant average(FieldPhrase &f){ + QVariant max(FieldPhrase &f); + QVariant min(FieldPhrase &f); + QVariant average(FieldPhrase &f){ //TODO: ... return QVariant(); } @@ -198,7 +198,7 @@ Q_OUTOFLINE_TEMPLATE int Query::count() } template -Q_OUTOFLINE_TEMPLATE QVariant Query::max(FieldPhrase &f){ +Q_OUTOFLINE_TEMPLATE QVariant Query::max(FieldPhrase &f){ Q_D(Query); 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::max(FieldPhrase &f){ } template -Q_OUTOFLINE_TEMPLATE QVariant Query::min(FieldPhrase &f){ +Q_OUTOFLINE_TEMPLATE QVariant Query::min(FieldPhrase &f){ Q_D(Query); QSqlQuery q = d->database->exec(d->database->sqlGenertor()->selectCommand("MIN(" + f.data()->text + ")", d->wheres, d->orders, d->tableName, d->joinClassName)); diff --git a/src/tablemodel.cpp b/src/tablemodel.cpp index 25e291c..9abe7df 100644 --- a/src/tablemodel.cpp +++ b/src/tablemodel.cpp @@ -181,7 +181,7 @@ TableModel::TableModel(int typeId, QString tableName) f = fieldObj; if(!fieldObj) continue; - +qDebug() <<"fieldProperty.type()"<type = fieldProperty.type(); } @@ -259,6 +259,7 @@ TableModel::TableModel(QJsonObject json, QString tableName) QJsonObject fieldObject = fields.value(key).toObject(); FieldModel *f = new FieldModel; f->name = fieldObject.value(__NAME).toString(); + qDebug() << "fieldObject.value(__TYPE).toString()"<type = QVariant::nameToType(fieldObject.value(__TYPE).toString().toLatin1().data()); if(fieldObject.contains(__nut_NOT_NULL)) diff --git a/src/wherephrase.cpp b/src/wherephrase.cpp index 38ee2a7..82e9ad0 100644 --- a/src/wherephrase.cpp +++ b/src/wherephrase.cpp @@ -204,16 +204,6 @@ WherePhrase WherePhrase::operator &(const 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) { return WherePhrase(this, PhraseData::Equal, other); @@ -244,35 +234,6 @@ WherePhrase WherePhrase::operator >=(const QVariant &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 diff --git a/src/wherephrase.h b/src/wherephrase.h index 48a14ca..931c67e 100644 --- a/src/wherephrase.h +++ b/src/wherephrase.h @@ -29,6 +29,7 @@ #include #include #include "defines.h" +#include "dbgeography.h" NUT_BEGIN_NAMESPACE @@ -63,7 +64,10 @@ public: Add, Minus, Multiple, - Divide + Divide, + + //special types + Distance }; enum Type{ @@ -136,6 +140,7 @@ public: PhraseData *data() const; }; +template class FieldPhrase: public WherePhrase{ public: FieldPhrase(const char *className, const char* s); @@ -156,6 +161,66 @@ public: //}; + +template +Q_OUTOFLINE_TEMPLATE FieldPhrase::FieldPhrase(const char *className, const char *s) : WherePhrase(className, s) +{ +// qDebug() << "(" << this << ")" << "FieldPhrase ctor" << className << s; +} + +template +Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase::operator =(const QVariant &other) +{ + return WherePhrase(this, PhraseData::Set, other); +} + +template +Q_OUTOFLINE_TEMPLATE 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); +} + +template +Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase::isNull(){ + return WherePhrase(this, PhraseData::Null); +} + +template +Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase::in(QVariantList list) +{ + return WherePhrase(this, PhraseData::In, list); +} + +template +Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase::in(QStringList list) +{ + return WherePhrase(this, PhraseData::In, list); +} + +template +Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase::like(QString pattern) +{ + return WherePhrase(this, PhraseData::Like, pattern); +} + +template<> +class FieldPhrase: 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 #endif // PHRASE_H