This commit is contained in:
blackdal 2017-05-25 20:16:54 +04:30
parent d3d0ae2532
commit 3e888c080e
16 changed files with 303 additions and 138 deletions

1
include/DbGeography Normal file
View File

@ -0,0 +1 @@
#include "../src/dbgeography.h"

View File

@ -2,4 +2,5 @@
#include "../src/table.h"
#include "../src/database.h"
#include "../src/tableset.h"
#include "../src/dbgeography.h"
#include "../src/query.h"

1
include/dbgeography.h Normal file
View File

@ -0,0 +1 @@
#include "../src/dbgeography.h"

2
include/header_copier Normal file → Executable file
View File

@ -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

View File

@ -2,4 +2,5 @@
#include "../src/table.h"
#include "../src/database.h"
#include "../src/tableset.h"
#include "../src/dbgeography.h"
#include "../src/query.h"

View File

@ -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

View File

@ -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="<<s;
db.exec(s);
if(db.lastError().type() != QSqlError::NoError)
qWarning("Error executing sql command, %s", db.lastError().text().toLatin1().data());
if (db.lastError().type() != QSqlError::NoError)
qWarning("Error executing sql command, %s",
db.lastError().text().toLatin1().data());
}
bool ok = db.commit();
if(ok){
if (ok) {
storeScheemaInDB();
q->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<ChangeLogTable*>();
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<ChangeLogTable *>();
currentModel.append(
new TableModel(changeLogTypeId, __CHANGE_LOG_TABLE_NAME));
tables.insert(ChangeLogTable::staticMetaObject.className(),
__CHANGE_LOG_TABLE_NAME);
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);
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=" <<ret;
// return ret;
// foreach (QString key, json.keys()) {
// TableModel *sch = new TableModel(json.value(key).toObject(),
// key);
// ret.append(sch);
// }
// }
// qDebug() << "ret=" <<ret;
// return ret;
}
bool DatabasePrivate::storeScheemaInDB()
@ -243,39 +267,41 @@ bool DatabasePrivate::storeScheemaInDB()
return true;
// QSqlQuery query(db);
// query.prepare("insert into __change_logs (data) values (:data)");
// query.bindValue(":data", QString(QJsonDocument(currentModel.toJson()).toJson()));
// bool ret = query.exec();
// if(query.lastError().type() != QSqlError::NoError)
// qWarning(QString("storeScheemaInDB" + query.lastError().text()).toLatin1().data());
// return ret;
// QSqlQuery query(db);
// query.prepare("insert into __change_logs (data) values (:data)");
// query.bindValue(":data",
// QString(QJsonDocument(currentModel.toJson()).toJson()));
// bool ret = query.exec();
// if(query.lastError().type() != QSqlError::NoError)
// qWarning(QString("storeScheemaInDB" +
// query.lastError().text()).toLatin1().data());
// return ret;
}
void DatabasePrivate::createChangeLogs()
{
// currentModel.model("change_log")
// currentModel.model("change_log")
QString diff = sqlGenertor->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<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);
@ -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<ChangeLogTable>(this);
// m__change_logs = new TableSet<ChangeLogTable>(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();
}

View File

@ -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<TableSetBase*> tableSets;
QSet<TableSetBase *> tableSets;
};
NUT_END_NAMESPACE
#endif // NUTDATABASE_H
#endif // NUTDATABASE_H

44
src/dbgeography.cpp Normal file
View File

@ -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

43
src/dbgeography.h Normal file
View File

@ -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

View File

@ -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<type> name##Field(){ \
static __NUT_NAMESPACE_PERFIX FieldPhrase<type> f = __NUT_NAMESPACE_PERFIX FieldPhrase<type>(staticMetaObject.className(), #name); \
return f; \
} \
type read() const{ \

View File

@ -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;
}

View File

@ -54,9 +54,9 @@ public:
int count();
QVariant max(FieldPhrase &f);
QVariant min(FieldPhrase &f);
QVariant average(FieldPhrase &f){
QVariant max(FieldPhrase<int> &f);
QVariant min(FieldPhrase<int> &f);
QVariant average(FieldPhrase<int> &f){
//TODO: ...
return QVariant();
}
@ -198,7 +198,7 @@ Q_OUTOFLINE_TEMPLATE int Query<T>::count()
}
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);
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>
Q_OUTOFLINE_TEMPLATE QVariant Query<T>::min(FieldPhrase &f){
Q_OUTOFLINE_TEMPLATE QVariant Query<T>::min(FieldPhrase<int> &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));

View File

@ -181,7 +181,7 @@ TableModel::TableModel(int typeId, QString tableName)
f = fieldObj;
if(!fieldObj)
continue;
qDebug() <<"fieldProperty.type()"<<fieldProperty.typeName();
fieldObj->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()"<<fieldObject.value(__TYPE).toString();
f->type = QVariant::nameToType(fieldObject.value(__TYPE).toString().toLatin1().data());
if(fieldObject.contains(__nut_NOT_NULL))

View File

@ -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

View File

@ -29,6 +29,7 @@
#include <QTime>
#include <QSharedPointer>
#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<typename T>
class FieldPhrase: public WherePhrase{
public:
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
#endif // PHRASE_H