commit
d75305aba2
82
.travis.yml
82
.travis.yml
|
|
@ -1,9 +1,79 @@
|
||||||
|
#Based on https://github.com/pcolby/libqtaws/blob/master/.travis.yml
|
||||||
|
language: cpp
|
||||||
|
|
||||||
|
os:
|
||||||
|
- linux
|
||||||
|
- osx
|
||||||
|
|
||||||
|
dist: trusty
|
||||||
|
|
||||||
|
compiler:
|
||||||
|
- clang
|
||||||
|
- gcc
|
||||||
|
|
||||||
|
env:
|
||||||
|
matrix:
|
||||||
|
- QT=5 BREW=
|
||||||
|
- QT=5 BREW=ex PPA=ubuntu-sdk-team/ppa
|
||||||
|
- QT=51 BREW=ex PPA=beineri/opt-qt511-trusty
|
||||||
|
- QT=52 BREW=ex PPA=beineri/opt-qt521-trusty
|
||||||
|
- QT=53 BREW=ex PPA=beineri/opt-qt532-trusty
|
||||||
|
- QT=54 BREW=ex PPA=beineri/opt-qt542-trusty
|
||||||
|
- QT=55 BREW=@5.5 PPA=beineri/opt-qt551-trusty
|
||||||
|
- QT=56 BREW=ex PPA=beineri/opt-qt562-trusty
|
||||||
|
- QT=56 BREW=ex PPA=beineri/opt-qt563-trusty
|
||||||
|
- QT=57 BREW=@5.7 PPA=beineri/opt-qt571-trusty
|
||||||
|
- QT=58 BREW=ex PPA=beineri/opt-qt58-trusty
|
||||||
|
- QT=59 BREW=@5.9 PPA=beineri/opt-qt591-trusty
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
exclude:
|
||||||
|
- { os: osx, env: QT=5 BREW=ex PPA=ubuntu-sdk-team/ppa }
|
||||||
|
- { os: osx, env: QT=51 BREW=ex PPA=beineri/opt-qt511-trusty }
|
||||||
|
- { os: osx, env: QT=52 BREW=ex PPA=beineri/opt-qt521-trusty }
|
||||||
|
- { os: osx, env: QT=53 BREW=ex PPA=beineri/opt-qt532-trusty }
|
||||||
|
- { os: osx, env: QT=54 BREW=ex PPA=beineri/opt-qt542-trusty }
|
||||||
|
- { os: osx, env: QT=56 BREW=ex PPA=beineri/opt-qt562-trusty }
|
||||||
|
- { os: osx, env: QT=56 BREW=ex PPA=beineri/opt-qt563-trusty }
|
||||||
|
- { os: osx, env: QT=58 BREW=ex PPA=beineri/opt-qt58-trusty }
|
||||||
|
|
||||||
|
addons:
|
||||||
|
coverity_scan:
|
||||||
|
project:
|
||||||
|
name: "HamedMasafi/Nut"
|
||||||
|
description: "Build submitted via Travis CI"
|
||||||
|
# notification_email: em@h
|
||||||
|
build_command_prepend: >
|
||||||
|
cp -a "$TRAVIS_BUILD_DIR" "$TRAVIS_BUILD_DIR-scan" &&
|
||||||
|
pushd "$TRAVIS_BUILD_DIR-scan" &&
|
||||||
|
qmake -qt=qt5 -Wall -Wlogic -Wparser CONFIG+=debug_and_release
|
||||||
|
build_command: make all
|
||||||
|
#branch_pattern: coverity
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- sudo add-apt-repository --yes ppa:ubuntu-sdk-team/ppa
|
- '[[ "$TRAVIS_OS_NAME" != linux || -z "$PPA" ]] || sudo add-apt-repository -y ppa:$PPA'
|
||||||
- sudo apt-get update -qq
|
- '[ "$TRAVIS_OS_NAME" != linux ] || sudo apt-get -qy update'
|
||||||
- sudo apt-get install qtbase5-dev qtdeclarative5-dev libqt5webkit5-dev libsqlite3-dev
|
- '[ "$TRAVIS_OS_NAME" != osx ] || brew update'
|
||||||
- sudo apt-get install qt5-default qttools5-dev-tools
|
|
||||||
|
install:
|
||||||
|
- '[ "$TRAVIS_OS_NAME" != linux ] || sudo apt-get -qy install cppcheck doxygen graphviz lcov'
|
||||||
|
- '[[ "$TRAVIS_OS_NAME" != linux || "$PPA" != */opt-* ]] || sudo apt-get -qy install qt${QT}base qt${QT}xmlpatterns'
|
||||||
|
- '[[ "$TRAVIS_OS_NAME" != linux || "$PPA" == */opt-* ]] || sudo apt-get -qy install qt5-qmake qtbase5-dev libqt5xmlpatterns5-dev'
|
||||||
|
- '[ "$TRAVIS_OS_NAME" != linux ] || gem install lcoveralls'
|
||||||
|
- '[ "$TRAVIS_OS_NAME" != osx ] || brew install cppcheck doxygen graphviz qt$BREW'
|
||||||
|
- '[ "$TRAVIS_OS_NAME" != osx ] || brew link --force qt$BREW'
|
||||||
|
- qmake -v
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- '[[ "$TRAVIS_OS_NAME" != linux || "$CXX" != clang++ ]] || export QMAKESPEC=linux-clang'
|
||||||
|
- '[[ "$TRAVIS_OS_NAME" != linux || "$CXX" != g++ ]] || export QMAKESPEC=linux-g++'
|
||||||
|
- '[[ "$TRAVIS_OS_NAME" != osx || "$CXX" != clang++ ]] || export QMAKESPEC=macx-clang'
|
||||||
|
- '[[ "$TRAVIS_OS_NAME" != osx || "$CXX" != g++ ]] || export QMAKESPEC=macx-g++'
|
||||||
|
- '[[ "$TRAVIS_OS_NAME" != linux || "$PPA" != */opt-* ]] || . /opt/qt$QT/bin/qt$QT-env.sh'
|
||||||
|
- '[[ "$TRAVIS_OS_NAME" != linux || "$PPA" == */opt-* ]] || export QT_SELECT=qt5'
|
||||||
|
- mkdir -p "$TRAVIS_BUILD_DIR-build"
|
||||||
|
- qmake -o "$TRAVIS_BUILD_DIR-build" -r -Wall -Wlogic -Wparser CONFIG+=debug_and_release "$TRAVIS_BUILD_DIR"
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- qmake nut.pro
|
- make -C "$TRAVIS_BUILD_DIR-build" all
|
||||||
- make
|
- make -C "$TRAVIS_BUILD_DIR-build" -j2 check TESTARGS=-silent
|
||||||
|
|
|
||||||
2
nut.pri
2
nut.pri
|
|
@ -1,5 +1,7 @@
|
||||||
QT += core sql
|
QT += core sql
|
||||||
|
|
||||||
|
CONFIG += c++11
|
||||||
|
|
||||||
INCLUDEPATH += $$PWD/include
|
INCLUDEPATH += $$PWD/include
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
|
|
|
||||||
1
nut.pro
1
nut.pro
|
|
@ -3,6 +3,7 @@ QT -= gui
|
||||||
|
|
||||||
TARGET = nut
|
TARGET = nut
|
||||||
TEMPLATE = lib
|
TEMPLATE = lib
|
||||||
|
CONFIG += c++11
|
||||||
|
|
||||||
DEFINES += QT_DEPRECATED_WARNINGS
|
DEFINES += QT_DEPRECATED_WARNINGS
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ class ChangeLogTable : public Table
|
||||||
NUT_DECLARE_FIELD(QString, version, version, setVersion)
|
NUT_DECLARE_FIELD(QString, version, version, setVersion)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ChangeLogTable(QObject *parentTableSet = Q_NULLPTR);
|
explicit ChangeLogTable(QObject *parentTableSet = Q_NULLPTR);
|
||||||
};
|
};
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,9 @@ NUT_BEGIN_NAMESPACE
|
||||||
qulonglong DatabasePrivate::lastId = 0;
|
qulonglong DatabasePrivate::lastId = 0;
|
||||||
QMap<QString, DatabaseModel> DatabasePrivate::allTableMaps;
|
QMap<QString, DatabaseModel> DatabasePrivate::allTableMaps;
|
||||||
|
|
||||||
DatabasePrivate::DatabasePrivate(Database *parent) : q_ptr(parent), isDatabaseNew(false)
|
DatabasePrivate::DatabasePrivate(Database *parent) : q_ptr(parent),
|
||||||
|
port(0), sqlGenertor(0), changeLogs(0),
|
||||||
|
isDatabaseNew(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -141,7 +143,7 @@ bool DatabasePrivate::updateDatabase()
|
||||||
qDebug("Databse is changed");
|
qDebug("Databse is changed");
|
||||||
|
|
||||||
QStringList sql = sqlGenertor->diff(last, current);
|
QStringList sql = sqlGenertor->diff(last, current);
|
||||||
|
qDebug()<<"database Sql =\n"<<sql;
|
||||||
db.transaction();
|
db.transaction();
|
||||||
foreach (QString s, sql) {
|
foreach (QString s, sql) {
|
||||||
db.exec(s);
|
db.exec(s);
|
||||||
|
|
|
||||||
|
|
@ -43,9 +43,9 @@ class NUT_EXPORT Database : public QObject
|
||||||
Q_DECLARE_PRIVATE(Database)
|
Q_DECLARE_PRIVATE(Database)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Database(QObject *parent = 0);
|
explicit Database(QObject *parent = 0);
|
||||||
Database(const Database &other);
|
explicit Database(const Database &other);
|
||||||
Database(const QSqlDatabase &other);
|
explicit Database(const QSqlDatabase &other);
|
||||||
~Database();
|
~Database();
|
||||||
|
|
||||||
bool open();
|
bool open();
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ class DatabasePrivate
|
||||||
Q_DECLARE_PUBLIC(Database)
|
Q_DECLARE_PUBLIC(Database)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DatabasePrivate(Database *parent);
|
explicit DatabasePrivate(Database *parent);
|
||||||
|
|
||||||
bool open(bool updateDatabase);
|
bool open(bool updateDatabase);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,11 @@ DatabaseModel::DatabaseModel(const QJsonObject &json) :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DatabaseModel::DatabaseModel(DatabaseModel &model)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
TableModel *DatabaseModel::tableByName(QString tableName) const
|
TableModel *DatabaseModel::tableByName(QString tableName) const
|
||||||
{
|
{
|
||||||
for(int i = 0; i < size(); i++){
|
for(int i = 0; i < size(); i++){
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ public:
|
||||||
DatabaseModel(const QString &name = QString::null);
|
DatabaseModel(const QString &name = QString::null);
|
||||||
DatabaseModel(const DatabaseModel &other);
|
DatabaseModel(const DatabaseModel &other);
|
||||||
DatabaseModel(const QJsonObject &json);
|
DatabaseModel(const QJsonObject &json);
|
||||||
|
DatabaseModel(DatabaseModel &model);
|
||||||
|
|
||||||
TableModel *tableByName(QString tableName) const;
|
TableModel *tableByName(QString tableName) const;
|
||||||
TableModel *tableByClassName(QString className) const;
|
TableModel *tableByClassName(QString className) const;
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
#define __NAME "name"
|
#define __NAME "name"
|
||||||
#define __TYPE "type"
|
#define __TYPE "type"
|
||||||
#define __FIELDS "fields"
|
#define __FIELDS "fields"
|
||||||
|
#define __FOREIGN_KEYS "foreign_keys"
|
||||||
#define __nut_FIELD "field"
|
#define __nut_FIELD "field"
|
||||||
|
|
||||||
#define __nut_DB_VERSION "database_version"
|
#define __nut_DB_VERSION "database_version"
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ NUT_BEGIN_NAMESPACE
|
||||||
class MySqlGenerator : public SqlGeneratorBase
|
class MySqlGenerator : public SqlGeneratorBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MySqlGenerator(Database *parent = 0);
|
explicit MySqlGenerator(Database *parent = 0);
|
||||||
|
|
||||||
QString fieldType(FieldModel *field);
|
QString fieldType(FieldModel *field);
|
||||||
QString escapeValue(const QVariant &v) const;
|
QString escapeValue(const QVariant &v) const;
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ NUT_BEGIN_NAMESPACE
|
||||||
class PostgreSqlGenerator : public SqlGeneratorBase
|
class PostgreSqlGenerator : public SqlGeneratorBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PostgreSqlGenerator(Database *parent);
|
explicit PostgreSqlGenerator(Database *parent);
|
||||||
|
|
||||||
QString fieldType(FieldModel *field);
|
QString fieldType(FieldModel *field);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ QString SqlGeneratorBase::masterDatabaseName(QString databaseName)
|
||||||
|
|
||||||
QString SqlGeneratorBase::createTable(TableModel *table)
|
QString SqlGeneratorBase::createTable(TableModel *table)
|
||||||
{
|
{
|
||||||
Q_UNUSED(table);
|
Q_UNUSED(table)
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -114,6 +114,13 @@ QString SqlGeneratorBase::fieldDeclare(FieldModel *field)
|
||||||
return field->name + " " + fieldType(field) + (field->notNull ? " NOT NULL" : "");
|
return field->name + " " + fieldType(field) + (field->notNull ? " NOT NULL" : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString SqlGeneratorBase::relationDeclare(const RelationModel *relation)
|
||||||
|
{
|
||||||
|
return QString("FOREIGN KEY (FK_%1) REFERENCES %2(%1)")
|
||||||
|
.arg(relation->localColumn)
|
||||||
|
.arg(relation->slaveTable->name());
|
||||||
|
}
|
||||||
|
|
||||||
QStringList SqlGeneratorBase::diff(DatabaseModel lastModel,
|
QStringList SqlGeneratorBase::diff(DatabaseModel lastModel,
|
||||||
DatabaseModel newModel)
|
DatabaseModel newModel)
|
||||||
{
|
{
|
||||||
|
|
@ -125,9 +132,11 @@ QStringList SqlGeneratorBase::diff(DatabaseModel lastModel,
|
||||||
TableModel *oldTable = lastModel.tableByName(table->name());
|
TableModel *oldTable = lastModel.tableByName(table->name());
|
||||||
TableModel *newTable = newModel.tableByName(table->name());
|
TableModel *newTable = newModel.tableByName(table->name());
|
||||||
QString sql = diff(oldTable, newTable);
|
QString sql = diff(oldTable, newTable);
|
||||||
|
|
||||||
if (!sql.isEmpty())
|
if (!sql.isEmpty())
|
||||||
ret << sql;
|
ret << sql;
|
||||||
|
// QString sqlRel = diffRelation(oldTable, newTable);
|
||||||
|
// if (!sqlRel.isEmpty())
|
||||||
|
// ret << sqlRel;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
@ -161,14 +170,24 @@ QString SqlGeneratorBase::diff(TableModel *oldTable, TableModel *newTable)
|
||||||
if (!newTable)
|
if (!newTable)
|
||||||
return "DROP TABLE " + oldTable->name();
|
return "DROP TABLE " + oldTable->name();
|
||||||
|
|
||||||
QSet<QString> fieldNames;
|
QList<QString> fieldNames;
|
||||||
|
QList<QString> relations;
|
||||||
|
|
||||||
if (oldTable)
|
if (oldTable) {
|
||||||
foreach (FieldModel *f, oldTable->fields())
|
foreach (FieldModel *f, oldTable->fields())
|
||||||
fieldNames.insert(f->name);
|
if (!fieldNames.contains(f->name))
|
||||||
|
fieldNames.append(f->name);
|
||||||
|
foreach (RelationModel *r, oldTable->foregionKeys())
|
||||||
|
if (!relations.contains(r->localColumn))
|
||||||
|
relations.append(r->localColumn);
|
||||||
|
}
|
||||||
|
|
||||||
foreach (FieldModel *f, newTable->fields())
|
foreach (FieldModel *f, newTable->fields())
|
||||||
fieldNames.insert(f->name);
|
if (!fieldNames.contains(f->name))
|
||||||
|
fieldNames.append(f->name);
|
||||||
|
foreach (RelationModel *r, newTable->foregionKeys())
|
||||||
|
if (!relations.contains(r->localColumn))
|
||||||
|
relations.append(r->localColumn);
|
||||||
|
|
||||||
QStringList columnSql;
|
QStringList columnSql;
|
||||||
foreach (QString fieldName, fieldNames) {
|
foreach (QString fieldName, fieldNames) {
|
||||||
|
|
@ -183,22 +202,104 @@ QString SqlGeneratorBase::diff(TableModel *oldTable, TableModel *newTable)
|
||||||
columnSql << fieldDeclare(newField);
|
columnSql << fieldDeclare(newField);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// foreach (QString fieldName, relations) {
|
||||||
|
// RelationModel *newRelation = newTable->foregionKeyByField(fieldName);
|
||||||
|
// if (oldTable) {
|
||||||
|
// RelationModel *oldRelation = oldTable->foregionKeyByField(fieldName);
|
||||||
|
|
||||||
|
// QString buffer = diff(oldRelation, newRelation);
|
||||||
|
// if (!buffer.isNull())
|
||||||
|
// columnSql << buffer;
|
||||||
|
// } else {
|
||||||
|
// columnSql << relationDeclare(newRelation);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
QString sql;
|
QString sql;
|
||||||
if (oldTable) {
|
if (oldTable) {
|
||||||
sql = QString("ALTER TABLE %1 \n%2").arg(newTable->name()).arg(
|
sql = QString("ALTER TABLE %1 \n%2")
|
||||||
columnSql.join(",\n"));
|
.arg(newTable->name())
|
||||||
|
.arg(columnSql.join(",\n"));
|
||||||
} else {
|
} else {
|
||||||
if (!newTable->primaryKey().isNull())
|
if (!newTable->primaryKey().isNull())
|
||||||
columnSql << QString("CONSTRAINT pk_%1 PRIMARY KEY (%2)")
|
columnSql << QString("CONSTRAINT pk_%1 PRIMARY KEY (%2)")
|
||||||
.arg(newTable->name())
|
.arg(newTable->name())
|
||||||
.arg(newTable->primaryKey());
|
.arg(newTable->primaryKey());
|
||||||
|
|
||||||
sql = QString("CREATE TABLE %1 \n(%2)").arg(newTable->name()).arg(
|
sql = QString("CREATE TABLE %1 \n(%2)")
|
||||||
columnSql.join(",\n"));
|
.arg(newTable->name())
|
||||||
|
.arg(columnSql.join(",\n"));
|
||||||
}
|
}
|
||||||
return sql;
|
return sql;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString SqlGeneratorBase::diffRelation(TableModel *oldTable, TableModel *newTable)
|
||||||
|
{
|
||||||
|
if (!newTable)
|
||||||
|
return "";
|
||||||
|
|
||||||
|
QList<QString> relations;
|
||||||
|
|
||||||
|
if (oldTable)
|
||||||
|
foreach (RelationModel *r, oldTable->foregionKeys())
|
||||||
|
if (!relations.contains(r->localColumn))
|
||||||
|
relations.append(r->localColumn);
|
||||||
|
|
||||||
|
foreach (RelationModel *r, newTable->foregionKeys())
|
||||||
|
if (!relations.contains(r->localColumn))
|
||||||
|
relations.append(r->localColumn);
|
||||||
|
|
||||||
|
QStringList columnSql;
|
||||||
|
foreach (QString fieldName, relations) {
|
||||||
|
RelationModel *newRelation = newTable->foregionKeyByField(fieldName);
|
||||||
|
RelationModel *oldRelation = 0;
|
||||||
|
if (oldTable)
|
||||||
|
oldRelation = oldTable->foregionKeyByField(fieldName);
|
||||||
|
|
||||||
|
QString buffer = diff(oldRelation, newRelation);
|
||||||
|
if (!buffer.isNull())
|
||||||
|
columnSql << buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (columnSql.count())
|
||||||
|
return "ALTER TABLE " + newTable->name() + "\n"
|
||||||
|
+ columnSql.join(",\n");
|
||||||
|
else
|
||||||
|
return "";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SqlGeneratorBase::diff(RelationModel *oldRel, RelationModel *newRel)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
CONSTRAINT FK_PersonOrder FOREIGN KEY (PersonID)
|
||||||
|
REFERENCES Persons(PersonID)
|
||||||
|
|
||||||
|
ADD CONSTRAINT FK_%1 FOREIGN KEY (%1) REFERENCES %2(%3)
|
||||||
|
|
||||||
|
return QString("ADD CONSTRAINT FK_%1 FOREIGN KEY (%1) "
|
||||||
|
"REFERENCES %2(%3)")
|
||||||
|
.arg(newRelation->localColumn)
|
||||||
|
.arg(newRelation->masterTable->name())
|
||||||
|
.arg(newRelation->foreignColumn);
|
||||||
|
*/
|
||||||
|
if (!oldRel)
|
||||||
|
return QString("ADD CONSTRAINT FK_%1 FOREIGN KEY (%1) "
|
||||||
|
"REFERENCES %2(%3)")
|
||||||
|
.arg(newRel->localColumn)
|
||||||
|
.arg(newRel->masterTable->name())
|
||||||
|
.arg(newRel->foreignColumn);
|
||||||
|
|
||||||
|
if (!newRel)
|
||||||
|
return QString("ADD CONSTRAINT FK_%1 FOREIGN KEY (%1) "
|
||||||
|
"REFERENCES %2(%3)")
|
||||||
|
.arg(oldRel->localColumn)
|
||||||
|
.arg(oldRel->masterTable->name())
|
||||||
|
.arg(oldRel->foreignColumn);
|
||||||
|
|
||||||
|
// if (*oldRel == *newRel)
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
QString SqlGeneratorBase::join(const QString &mainTable,
|
QString SqlGeneratorBase::join(const QString &mainTable,
|
||||||
const QList<RelationModel*> list,
|
const QList<RelationModel*> list,
|
||||||
QStringList *order)
|
QStringList *order)
|
||||||
|
|
@ -235,7 +336,7 @@ QString SqlGeneratorBase::join(const QStringList &list, QStringList *order)
|
||||||
//TODO: make this ungly code better and bugless :-)
|
//TODO: make this ungly code better and bugless :-)
|
||||||
/*
|
/*
|
||||||
* Known issues:
|
* Known issues:
|
||||||
* Support onle near joins, far supports with medium table finding not support yet
|
* Support only near joins, far supports with medium table finding not support yet
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!list.count())
|
if (!list.count())
|
||||||
|
|
@ -858,7 +959,7 @@ QString SqlGeneratorBase::createConditionalPhrase(const PhraseData *d) const
|
||||||
else if (op == PhraseData::AddMonths)
|
else if (op == PhraseData::AddMonths)
|
||||||
ret = QString("DATEADD(month, %1, %2)")
|
ret = QString("DATEADD(month, %1, %2)")
|
||||||
.arg(d->operand.toString()).arg(createConditionalPhrase(d->left));
|
.arg(d->operand.toString()).arg(createConditionalPhrase(d->left));
|
||||||
else if (op == PhraseData::AddYears)
|
else if (op == PhraseData::AddDays)
|
||||||
ret = QString("DATEADD(day, %1, %2)")
|
ret = QString("DATEADD(day, %1, %2)")
|
||||||
.arg(d->operand.toString()).arg(createConditionalPhrase(d->left));
|
.arg(d->operand.toString()).arg(createConditionalPhrase(d->left));
|
||||||
else if (op == PhraseData::AddHours)
|
else if (op == PhraseData::AddHours)
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ class SqlGeneratorBase : public QObject
|
||||||
|
|
||||||
Database *_database;
|
Database *_database;
|
||||||
public:
|
public:
|
||||||
|
//TODO: remove this enum
|
||||||
enum CommandType{
|
enum CommandType{
|
||||||
Select,
|
Select,
|
||||||
Insert,
|
Insert,
|
||||||
|
|
@ -56,7 +57,7 @@ public:
|
||||||
SignleField
|
SignleField
|
||||||
};
|
};
|
||||||
|
|
||||||
SqlGeneratorBase(Database *parent);
|
explicit SqlGeneratorBase(Database *parent);
|
||||||
virtual ~SqlGeneratorBase();
|
virtual ~SqlGeneratorBase();
|
||||||
|
|
||||||
virtual QString masterDatabaseName(QString databaseName);
|
virtual QString masterDatabaseName(QString databaseName);
|
||||||
|
|
@ -65,10 +66,13 @@ public:
|
||||||
|
|
||||||
virtual QString fieldType(FieldModel *field) = 0;
|
virtual QString fieldType(FieldModel *field) = 0;
|
||||||
virtual QString fieldDeclare(FieldModel *field);
|
virtual QString fieldDeclare(FieldModel *field);
|
||||||
|
virtual QString relationDeclare(const RelationModel *relation);
|
||||||
|
|
||||||
virtual QStringList diff(DatabaseModel lastModel, DatabaseModel newModel);
|
virtual QStringList diff(DatabaseModel lastModel, DatabaseModel newModel);
|
||||||
virtual QString diff(FieldModel *oldField, FieldModel *newField);
|
virtual QString diff(FieldModel *oldField, FieldModel *newField);
|
||||||
virtual QString diff(TableModel *oldTable, TableModel *newTable);
|
virtual QString diff(TableModel *oldTable, TableModel *newTable);
|
||||||
|
virtual QString diffRelation(TableModel *oldTable, TableModel *newTable);
|
||||||
|
virtual QString diff(RelationModel *oldRel, RelationModel *newRel);
|
||||||
|
|
||||||
virtual QString join(const QString &mainTable,
|
virtual QString join(const QString &mainTable,
|
||||||
const QList<RelationModel*> list,
|
const QList<RelationModel*> list,
|
||||||
|
|
@ -93,7 +97,8 @@ public:
|
||||||
const int take = -1);
|
const int take = -1);
|
||||||
|
|
||||||
virtual QString selectCommand(const QString &tableName,
|
virtual QString selectCommand(const QString &tableName,
|
||||||
const AgregateType &t, const QString &agregateArg,
|
const AgregateType &t,
|
||||||
|
const QString &agregateArg,
|
||||||
const ConditionalPhrase &where,
|
const ConditionalPhrase &where,
|
||||||
const QList<RelationModel *> &joins,
|
const QList<RelationModel *> &joins,
|
||||||
const int skip = -1,
|
const int skip = -1,
|
||||||
|
|
@ -120,7 +125,7 @@ public:
|
||||||
virtual QString phrase(const PhraseData *d) const;
|
virtual QString phrase(const PhraseData *d) const;
|
||||||
virtual QString operatorString(const PhraseData::Condition &cond) const;
|
virtual QString operatorString(const PhraseData::Condition &cond) const;
|
||||||
virtual void appendSkipTake(QString &sql, int skip = -1, int take = -1);
|
virtual void appendSkipTake(QString &sql, int skip = -1, int take = -1);
|
||||||
private:
|
protected:
|
||||||
QString createConditionalPhrase(const PhraseData *d) const;
|
QString createConditionalPhrase(const PhraseData *d) const;
|
||||||
QString createFieldPhrase(const PhraseList &ph);
|
QString createFieldPhrase(const PhraseList &ph);
|
||||||
QString createOrderPhrase(const PhraseList &ph);
|
QString createOrderPhrase(const PhraseList &ph);
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ NUT_BEGIN_NAMESPACE
|
||||||
class SqliteGenerator : public SqlGeneratorBase
|
class SqliteGenerator : public SqlGeneratorBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SqliteGenerator(Database *parent = 0);
|
explicit SqliteGenerator(Database *parent = 0);
|
||||||
|
|
||||||
QString fieldType(FieldModel *field);
|
QString fieldType(FieldModel *field);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,7 @@ QString SqlServerGenerator::fieldType(FieldModel *field)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
Q_UNREACHABLE();
|
||||||
dbType = "";
|
dbType = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -125,7 +126,7 @@ QString SqlServerGenerator::escapeValue(const QVariant &v) const
|
||||||
QPoint pt = v.toPoint();
|
QPoint pt = v.toPoint();
|
||||||
return QString("geography::POINT(%1, %2, 4326)").arg(pt.x()).arg(
|
return QString("geography::POINT(%1, %2, 4326)").arg(pt.x()).arg(
|
||||||
pt.y());
|
pt.y());
|
||||||
} else if (v.type() == QVariant::Point) {
|
} else if (v.type() == QVariant::PointF) {
|
||||||
QPointF pt = v.toPointF();
|
QPointF pt = v.toPointF();
|
||||||
return QString("geography::POINT(%1, %2, 4326)").arg(pt.x()).arg(
|
return QString("geography::POINT(%1, %2, 4326)").arg(pt.x()).arg(
|
||||||
pt.y());
|
pt.y());
|
||||||
|
|
@ -133,23 +134,11 @@ QString SqlServerGenerator::escapeValue(const QVariant &v) const
|
||||||
return SqlGeneratorBase::escapeValue(v);
|
return SqlGeneratorBase::escapeValue(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
//QString SqlServerGenerator::selectCommand(SqlGeneratorBase::AgregateType t,
|
void SqlServerGenerator::appendSkipTake(QString &sql, int skip, int take)
|
||||||
// QString agregateArg,
|
{
|
||||||
// QString tableName,
|
if (take != -1 && skip != -1)
|
||||||
// QList<WherePhrase> &wheres,
|
sql.append(QString(" OFFSET %1 ROWS FETCH NEXT %2 ROWS ONLY")
|
||||||
// QList<WherePhrase> &orders,
|
.arg(skip).arg(take));
|
||||||
// QList<RelationModel*> joins, int skip, int take)
|
}
|
||||||
//{
|
|
||||||
// QString command = SqlGeneratorBase::selectCommand(t, agregateArg,
|
|
||||||
// tableName,
|
|
||||||
// wheres, orders,
|
|
||||||
// joins, skip, take);
|
|
||||||
|
|
||||||
// if (take != -1 && skip != -1)
|
|
||||||
// command.append(QString("OFFSET %1 ROWS FETCH NEXT %2 ROWS ONLY")
|
|
||||||
// .arg(skip)
|
|
||||||
// .arg(take));
|
|
||||||
// return command;
|
|
||||||
//}
|
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ NUT_BEGIN_NAMESPACE
|
||||||
class SqlServerGenerator : public SqlGeneratorBase
|
class SqlServerGenerator : public SqlGeneratorBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SqlServerGenerator(Database *parent = 0);
|
explicit SqlServerGenerator(Database *parent = 0);
|
||||||
|
|
||||||
QString masterDatabaseName(QString databaseName);
|
QString masterDatabaseName(QString databaseName);
|
||||||
|
|
||||||
|
|
@ -37,12 +37,8 @@ public:
|
||||||
QString diff(FieldModel *oldField, FieldModel *newField);
|
QString diff(FieldModel *oldField, FieldModel *newField);
|
||||||
|
|
||||||
QString escapeValue(const QVariant &v) const;
|
QString escapeValue(const QVariant &v) const;
|
||||||
|
void appendSkipTake(QString &sql, int skip, int take);
|
||||||
|
|
||||||
// QString selectCommand(AgregateType t, QString agregateArg,
|
|
||||||
// QString tableName,
|
|
||||||
// QList<WherePhrase> &wheres,
|
|
||||||
// QList<WherePhrase> &orders,
|
|
||||||
// QList<RelationModel *> joins, int skip, int take);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
|
||||||
172
src/phrase.cpp
172
src/phrase.cpp
|
|
@ -26,6 +26,12 @@ NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
#define LOG(s) qDebug() << __func__ << s;
|
#define LOG(s) qDebug() << __func__ << s;
|
||||||
|
|
||||||
|
PhraseData::PhraseData() :
|
||||||
|
className(""), fieldName(""),
|
||||||
|
type(Field), operatorCond(NotAssign),
|
||||||
|
left(0), right(0), operand(QVariant::Invalid), isNot(false)
|
||||||
|
{ }
|
||||||
|
|
||||||
PhraseData::PhraseData(const char *className, const char *fieldName) :
|
PhraseData::PhraseData(const char *className, const char *fieldName) :
|
||||||
className(className), fieldName(fieldName),
|
className(className), fieldName(fieldName),
|
||||||
type(Field), operatorCond(NotAssign),
|
type(Field), operatorCond(NotAssign),
|
||||||
|
|
@ -45,23 +51,20 @@ PhraseData::PhraseData(PhraseData *l, PhraseData::Condition o,
|
||||||
|
|
||||||
PhraseData::PhraseData(PhraseData *l, PhraseData::Condition o, QVariant r)
|
PhraseData::PhraseData(PhraseData *l, PhraseData::Condition o, QVariant r)
|
||||||
: className(0), fieldName(0),
|
: className(0), fieldName(0),
|
||||||
type(WithVariant), operatorCond(o), left(new PhraseData(l)), operand(r), isNot(false)
|
type(WithVariant), operatorCond(o), left(new PhraseData(l)), right(0), operand(r), isNot(false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
PhraseData::PhraseData(const PhraseData *other)
|
PhraseData::PhraseData(const PhraseData &other) :
|
||||||
{
|
left(other.left), right(other.right), operand(other.operand),
|
||||||
left = other->left;
|
operatorCond(other.operatorCond), className(other.className),
|
||||||
right = other->right;
|
fieldName(other.fieldName), type(other.type), isNot(other.isNot)
|
||||||
operand = other->operand;
|
{ }
|
||||||
operatorCond = other->operatorCond;
|
|
||||||
className = other->className;
|
PhraseData::PhraseData(const PhraseData *other) :
|
||||||
fieldName = other->fieldName;
|
left(other->left), right(other->right), operand(other->operand),
|
||||||
type = other->type;
|
operatorCond(other->operatorCond), className(other->className),
|
||||||
isNot = other->isNot;
|
fieldName(other->fieldName), type(other->type), isNot(other->isNot)
|
||||||
if (type != Field) {
|
{ }
|
||||||
qDebug() << "Bug";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString PhraseData::toString() const
|
QString PhraseData::toString() const
|
||||||
{
|
{
|
||||||
|
|
@ -169,7 +172,7 @@ PhraseList::PhraseList() : isValid(false)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PhraseList::PhraseList(const PhraseList &other)
|
PhraseList::PhraseList(const PhraseList &other) : isValid(true)
|
||||||
{
|
{
|
||||||
data = qMove(other.data);
|
data = qMove(other.data);
|
||||||
}
|
}
|
||||||
|
|
@ -211,7 +214,10 @@ PhraseList PhraseList::operator |(PhraseList &other) {
|
||||||
return PhraseList(this, &other);
|
return PhraseList(this, &other);
|
||||||
}
|
}
|
||||||
|
|
||||||
AssignmentPhrase::AssignmentPhrase(AbstractFieldPhrase *l, QVariant r)
|
AssignmentPhrase::AssignmentPhrase(PhraseData *d) : data(d)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
AssignmentPhrase::AssignmentPhrase(AbstractFieldPhrase *l, const QVariant r)
|
||||||
{
|
{
|
||||||
data = new PhraseData(l->data, PhraseData::Equal, r);
|
data = new PhraseData(l->data, PhraseData::Equal, r);
|
||||||
// l->data = 0;
|
// l->data = 0;
|
||||||
|
|
@ -223,6 +229,23 @@ AssignmentPhrase::AssignmentPhrase(AbstractFieldPhrase *l, const AssignmentPhras
|
||||||
// l->data = 0;
|
// l->data = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AssignmentPhrase::AssignmentPhrase(AssignmentPhrase *ph, const QVariant &v)
|
||||||
|
{
|
||||||
|
data = new PhraseData(ph->data, PhraseData::Equal, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
//AssignmentPhrase::AssignmentPhrase(AssignmentPhrase &other)
|
||||||
|
//{
|
||||||
|
// data = other.data;
|
||||||
|
// other.data = 0;
|
||||||
|
//}
|
||||||
|
|
||||||
|
AssignmentPhrase::~AssignmentPhrase()
|
||||||
|
{
|
||||||
|
if (data)
|
||||||
|
delete data;
|
||||||
|
}
|
||||||
|
|
||||||
//AssignmentPhrase::AssignmentPhrase(AssignmentPhrase *l, const AssignmentPhrase *r)
|
//AssignmentPhrase::AssignmentPhrase(AssignmentPhrase *l, const AssignmentPhrase *r)
|
||||||
//{
|
//{
|
||||||
//// data = new PhraseData(l->data, PhraseData::Append, r->data);
|
//// data = new PhraseData(l->data, PhraseData::Append, r->data);
|
||||||
|
|
@ -234,6 +257,11 @@ AssignmentPhraseList AssignmentPhrase::operator &(const AssignmentPhrase &other)
|
||||||
return AssignmentPhraseList(this, &other);
|
return AssignmentPhraseList(this, &other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AssignmentPhraseList::AssignmentPhraseList()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
AssignmentPhraseList::AssignmentPhraseList(const AssignmentPhrase &l)
|
AssignmentPhraseList::AssignmentPhraseList(const AssignmentPhrase &l)
|
||||||
{
|
{
|
||||||
data.append(l.data);
|
data.append(l.data);
|
||||||
|
|
@ -251,11 +279,23 @@ AssignmentPhraseList::AssignmentPhraseList(AssignmentPhrase *l, const Assignment
|
||||||
data.append(r->data);
|
data.append(r->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AssignmentPhraseList::AssignmentPhraseList(const AssignmentPhrase &r, const AssignmentPhrase &l)
|
||||||
|
{
|
||||||
|
data.append(l.data);
|
||||||
|
data.append(r.data);
|
||||||
|
}
|
||||||
|
|
||||||
AssignmentPhraseList AssignmentPhraseList::operator &(const AssignmentPhrase &ph)
|
AssignmentPhraseList AssignmentPhraseList::operator &(const AssignmentPhrase &ph)
|
||||||
{
|
{
|
||||||
return AssignmentPhraseList(this, &ph);
|
return AssignmentPhraseList(this, &ph);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AssignmentPhraseList::~AssignmentPhraseList()
|
||||||
|
{
|
||||||
|
// qDeleteAll(data);
|
||||||
|
// data.clear();
|
||||||
|
}
|
||||||
|
|
||||||
ConditionalPhrase::ConditionalPhrase() : data(0)
|
ConditionalPhrase::ConditionalPhrase() : data(0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
@ -339,7 +379,7 @@ ConditionalPhrase::~ConditionalPhrase()
|
||||||
delete data;
|
delete data;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConditionalPhrase ConditionalPhrase::operator =(const ConditionalPhrase &other)
|
ConditionalPhrase &ConditionalPhrase::operator =(const ConditionalPhrase &other)
|
||||||
{
|
{
|
||||||
this->data = new PhraseData(other.data);
|
this->data = new PhraseData(other.data);
|
||||||
return *this;
|
return *this;
|
||||||
|
|
@ -350,22 +390,67 @@ ConditionalPhrase ConditionalPhrase::operator ==(const QVariant &other)
|
||||||
return ConditionalPhrase(this, PhraseData::Equal, other);
|
return ConditionalPhrase(this, PhraseData::Equal, other);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConditionalPhrase ConditionalPhrase::operator ==(const AbstractFieldPhrase &other)
|
//ConditionalPhrase ConditionalPhrase::operator ==(const AbstractFieldPhrase &other)
|
||||||
{
|
//{
|
||||||
return ConditionalPhrase(this, PhraseData::Equal, other);
|
// return ConditionalPhrase(this, PhraseData::Equal, other);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//ConditionalPhrase ConditionalPhrase::operator &&(const ConditionalPhrase &other)
|
||||||
|
//{
|
||||||
|
// return ConditionalPhrase(this, PhraseData::And,
|
||||||
|
// const_cast<ConditionalPhrase&>(other));
|
||||||
|
//}
|
||||||
|
|
||||||
|
//ConditionalPhrase ConditionalPhrase::operator ||(const ConditionalPhrase &other)
|
||||||
|
//{
|
||||||
|
// return ConditionalPhrase(this, PhraseData::Or,
|
||||||
|
// const_cast<ConditionalPhrase&>(other));
|
||||||
|
//}
|
||||||
|
|
||||||
|
#define DECLARE_CONDITIONALPHRASE_OPERATORS(op, cond) \
|
||||||
|
ConditionalPhrase operator op(const ConditionalPhrase &l, const ConditionalPhrase &r) \
|
||||||
|
{ \
|
||||||
|
ConditionalPhrase p; \
|
||||||
|
p.data = new PhraseData; \
|
||||||
|
p.data->operatorCond = cond; \
|
||||||
|
p.data->left = new PhraseData(l.data); \
|
||||||
|
p.data->right = new PhraseData(r.data); \
|
||||||
|
return p; \
|
||||||
|
} \
|
||||||
|
ConditionalPhrase operator op(const ConditionalPhrase &l, ConditionalPhrase &&r) \
|
||||||
|
{ \
|
||||||
|
ConditionalPhrase p; \
|
||||||
|
p.data = new PhraseData; \
|
||||||
|
p.data->operatorCond = cond; \
|
||||||
|
p.data->left = new PhraseData(l.data); \
|
||||||
|
p.data->right = r.data; \
|
||||||
|
r.data = 0; \
|
||||||
|
return p; \
|
||||||
|
} \
|
||||||
|
ConditionalPhrase operator op(ConditionalPhrase &&l, const ConditionalPhrase &r) \
|
||||||
|
{ \
|
||||||
|
ConditionalPhrase p; \
|
||||||
|
p.data = new PhraseData; \
|
||||||
|
p.data->operatorCond = cond; \
|
||||||
|
p.data->left = l.data; \
|
||||||
|
l.data = 0; \
|
||||||
|
p.data->right = new PhraseData(r.data); \
|
||||||
|
return p; \
|
||||||
|
} \
|
||||||
|
ConditionalPhrase operator op(ConditionalPhrase &&l, ConditionalPhrase &&r) \
|
||||||
|
{ \
|
||||||
|
ConditionalPhrase p; \
|
||||||
|
p.data = new PhraseData; \
|
||||||
|
p.data->operatorCond = cond; \
|
||||||
|
p.data->left = l.data; \
|
||||||
|
p.data->right = r.data; \
|
||||||
|
l.data = r.data = 0; \
|
||||||
|
return p; \
|
||||||
}
|
}
|
||||||
|
|
||||||
ConditionalPhrase ConditionalPhrase::operator &&(const ConditionalPhrase &other)
|
DECLARE_CONDITIONALPHRASE_OPERATORS(==, PhraseData::Equal)
|
||||||
{
|
DECLARE_CONDITIONALPHRASE_OPERATORS(||, PhraseData::Or)
|
||||||
return ConditionalPhrase(this, PhraseData::And,
|
DECLARE_CONDITIONALPHRASE_OPERATORS(&&, PhraseData::And)
|
||||||
const_cast<ConditionalPhrase&>(other));
|
|
||||||
}
|
|
||||||
|
|
||||||
ConditionalPhrase ConditionalPhrase::operator ||(const ConditionalPhrase &other)
|
|
||||||
{
|
|
||||||
return ConditionalPhrase(this, PhraseData::Or,
|
|
||||||
const_cast<ConditionalPhrase&>(other));
|
|
||||||
}
|
|
||||||
|
|
||||||
ConditionalPhrase ConditionalPhrase::operator !()
|
ConditionalPhrase ConditionalPhrase::operator !()
|
||||||
{
|
{
|
||||||
|
|
@ -374,4 +459,27 @@ ConditionalPhrase ConditionalPhrase::operator !()
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//AssignmentPhraseList operator &(const AssignmentPhrase &l, const AssignmentPhrase &r)
|
||||||
|
//{
|
||||||
|
// return AssignmentPhraseList(l, r);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//AssignmentPhraseList operator &(const AssignmentPhrase &l, AssignmentPhrase &&r)
|
||||||
|
//{
|
||||||
|
// r.data = 0;
|
||||||
|
// return AssignmentPhraseList(l, r);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//AssignmentPhraseList operator &(AssignmentPhrase &&l, const AssignmentPhrase &r)
|
||||||
|
//{
|
||||||
|
// l.data = 0;
|
||||||
|
// return AssignmentPhraseList(l, r);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//AssignmentPhraseList operator &(AssignmentPhrase &&l, AssignmentPhrase &&r)
|
||||||
|
//{
|
||||||
|
// r.data = l.data = 0;
|
||||||
|
// return AssignmentPhraseList(l, r);
|
||||||
|
//}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
|
||||||
76
src/phrase.h
76
src/phrase.h
|
|
@ -25,7 +25,7 @@
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
#if __cplusplus >= 201103L
|
#ifdef Q_COMPILER_INITIALIZER_LISTS
|
||||||
# include <initializer_list>
|
# include <initializer_list>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -91,20 +91,21 @@ public:
|
||||||
const char *fieldName;
|
const char *fieldName;
|
||||||
|
|
||||||
Type type;
|
Type type;
|
||||||
Condition operatorCond;
|
|
||||||
|
|
||||||
const PhraseData *left;
|
const PhraseData *left;
|
||||||
const PhraseData *right;
|
const PhraseData *right;
|
||||||
|
|
||||||
QVariant operand;
|
QVariant operand;
|
||||||
|
Condition operatorCond;
|
||||||
bool isNot;
|
bool isNot;
|
||||||
|
|
||||||
|
PhraseData();
|
||||||
PhraseData(const char *className, const char *fieldName);
|
PhraseData(const char *className, const char *fieldName);
|
||||||
PhraseData(PhraseData *l, Condition o);
|
PhraseData(PhraseData *l, Condition o);
|
||||||
PhraseData(PhraseData *l, Condition o, const PhraseData *r);
|
PhraseData(PhraseData *l, Condition o, const PhraseData *r);
|
||||||
PhraseData(PhraseData *l, Condition o, QVariant r);
|
PhraseData(PhraseData *l, Condition o, QVariant r);
|
||||||
|
explicit PhraseData(const PhraseData &other);
|
||||||
PhraseData(const PhraseData *other);
|
explicit PhraseData(const PhraseData *other);
|
||||||
|
|
||||||
QString toString() const;
|
QString toString() const;
|
||||||
|
|
||||||
|
|
@ -115,30 +116,43 @@ class AssignmentPhraseList
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QList<PhraseData*> data;
|
QList<PhraseData*> data;
|
||||||
|
explicit AssignmentPhraseList();
|
||||||
AssignmentPhraseList(const AssignmentPhrase &l);
|
AssignmentPhraseList(const AssignmentPhrase &l);
|
||||||
AssignmentPhraseList(AssignmentPhraseList *l, const AssignmentPhrase *r);
|
AssignmentPhraseList(AssignmentPhraseList *l, const AssignmentPhrase *r);
|
||||||
AssignmentPhraseList(AssignmentPhrase *l, const AssignmentPhrase *r);
|
AssignmentPhraseList(AssignmentPhrase *l, const AssignmentPhrase *r);
|
||||||
|
AssignmentPhraseList(const AssignmentPhrase &r, const AssignmentPhrase &l);
|
||||||
|
|
||||||
AssignmentPhraseList operator &(const AssignmentPhrase &ph);
|
AssignmentPhraseList operator &(const AssignmentPhrase &ph);
|
||||||
|
|
||||||
|
~AssignmentPhraseList();
|
||||||
};
|
};
|
||||||
|
|
||||||
class AssignmentPhrase
|
class AssignmentPhrase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PhraseData *data;
|
PhraseData *data;
|
||||||
AssignmentPhrase(AbstractFieldPhrase *l, QVariant r);
|
explicit AssignmentPhrase(PhraseData *d);
|
||||||
AssignmentPhrase(AbstractFieldPhrase *l, const AssignmentPhrase *r);
|
explicit AssignmentPhrase(AbstractFieldPhrase *l, const QVariant r);
|
||||||
|
explicit AssignmentPhrase(AbstractFieldPhrase *l, const AssignmentPhrase *r);
|
||||||
|
explicit AssignmentPhrase(AssignmentPhrase *ph, const QVariant &v);
|
||||||
|
// explicit AssignmentPhrase(AssignmentPhrase &other);
|
||||||
|
~AssignmentPhrase();
|
||||||
// AssignmentPhrase(AssignmentPhrase *l, const AssignmentPhrase *r);
|
// AssignmentPhrase(AssignmentPhrase *l, const AssignmentPhrase *r);
|
||||||
|
|
||||||
AssignmentPhraseList operator &(const AssignmentPhrase &other);
|
AssignmentPhraseList operator &(const AssignmentPhrase &other);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//AssignmentPhraseList operator &(const AssignmentPhrase &l, const AssignmentPhrase &r);
|
||||||
|
//AssignmentPhraseList operator &(const AssignmentPhrase &l, AssignmentPhrase &&r);
|
||||||
|
//AssignmentPhraseList operator &(AssignmentPhrase &&l, const AssignmentPhrase &r);
|
||||||
|
//AssignmentPhraseList operator &(AssignmentPhrase &&l, AssignmentPhrase &&r);
|
||||||
|
|
||||||
class PhraseList{
|
class PhraseList{
|
||||||
public:
|
public:
|
||||||
bool isValid;
|
bool isValid;
|
||||||
QList<const PhraseData*> data;
|
QList<const PhraseData*> data;
|
||||||
PhraseList();
|
explicit PhraseList();
|
||||||
PhraseList(const PhraseList &other);
|
PhraseList(const PhraseList &other);
|
||||||
PhraseList(const AbstractFieldPhrase &other);
|
PhraseList(const AbstractFieldPhrase &other);
|
||||||
PhraseList(const AbstractFieldPhrase *left, const AbstractFieldPhrase &right);
|
PhraseList(const AbstractFieldPhrase *left, const AbstractFieldPhrase &right);
|
||||||
|
|
@ -171,11 +185,11 @@ public:
|
||||||
ConditionalPhrase(ConditionalPhrase *l, PhraseData::Condition cond, ConditionalPhrase &r);
|
ConditionalPhrase(ConditionalPhrase *l, PhraseData::Condition cond, ConditionalPhrase &r);
|
||||||
virtual ~ConditionalPhrase();
|
virtual ~ConditionalPhrase();
|
||||||
|
|
||||||
ConditionalPhrase operator =(const ConditionalPhrase &other);
|
ConditionalPhrase &operator =(const ConditionalPhrase &other);
|
||||||
ConditionalPhrase operator ==(const QVariant &other);
|
ConditionalPhrase operator ==(const QVariant &other);
|
||||||
ConditionalPhrase operator ==(const AbstractFieldPhrase &other);
|
// ConditionalPhrase operator ==(const AbstractFieldPhrase &other);
|
||||||
ConditionalPhrase operator &&(const ConditionalPhrase &other);
|
// ConditionalPhrase operator &&(const ConditionalPhrase &other);
|
||||||
ConditionalPhrase operator ||(const ConditionalPhrase &other);
|
// ConditionalPhrase operator ||(const ConditionalPhrase &other);
|
||||||
ConditionalPhrase operator !();
|
ConditionalPhrase operator !();
|
||||||
|
|
||||||
SPECIALIZATION_NUMERIC_MEMBER(type, <, PhraseData::Less)
|
SPECIALIZATION_NUMERIC_MEMBER(type, <, PhraseData::Less)
|
||||||
|
|
@ -184,6 +198,16 @@ public:
|
||||||
SPECIALIZATION_NUMERIC_MEMBER(type, >=, PhraseData::GreaterEqual)
|
SPECIALIZATION_NUMERIC_MEMBER(type, >=, PhraseData::GreaterEqual)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define DECLARE_CONDITIONALPHRASE_OPERATORS(op) \
|
||||||
|
ConditionalPhrase operator op(const ConditionalPhrase &l, const ConditionalPhrase &r); \
|
||||||
|
ConditionalPhrase operator op(const ConditionalPhrase &l, ConditionalPhrase &&r); \
|
||||||
|
ConditionalPhrase operator op(ConditionalPhrase &&l, const ConditionalPhrase &r); \
|
||||||
|
ConditionalPhrase operator op(ConditionalPhrase &&l, ConditionalPhrase &&r);
|
||||||
|
|
||||||
|
DECLARE_CONDITIONALPHRASE_OPERATORS(==)
|
||||||
|
DECLARE_CONDITIONALPHRASE_OPERATORS(&&)
|
||||||
|
DECLARE_CONDITIONALPHRASE_OPERATORS(||)
|
||||||
|
|
||||||
class AbstractFieldPhrase
|
class AbstractFieldPhrase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -257,8 +281,8 @@ public:
|
||||||
return ConditionalPhrase(this, PhraseData::Like, term);
|
return ConditionalPhrase(this, PhraseData::Like, term);
|
||||||
}
|
}
|
||||||
|
|
||||||
AssignmentPhrase operator =(const QVariant &other) {
|
AssignmentPhrase operator =(const QVariant &v) {
|
||||||
return AssignmentPhrase(this, other);
|
return AssignmentPhrase(this, v);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -309,6 +333,32 @@ SPECIALIZATION_NUMERIC(qreal)
|
||||||
return ConditionalPhrase(this, cond, val); \
|
return ConditionalPhrase(this, cond, val); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
class FieldPhrase<bool> : public AbstractFieldPhrase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FieldPhrase(const char *className, const char *s) :
|
||||||
|
AbstractFieldPhrase(className, s)
|
||||||
|
{}
|
||||||
|
|
||||||
|
AssignmentPhrase operator =(const bool &other) {
|
||||||
|
return AssignmentPhrase(this, other);
|
||||||
|
}
|
||||||
|
|
||||||
|
FieldPhrase<bool> operator !()
|
||||||
|
{
|
||||||
|
FieldPhrase<bool> f(data->className, data->fieldName);
|
||||||
|
f.data = new PhraseData(data);
|
||||||
|
f.data->isNot = !data->isNot;
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator ConditionalPhrase()
|
||||||
|
{
|
||||||
|
return ConditionalPhrase(this, PhraseData::Equal, !data->isNot);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
class FieldPhrase<QDate> : public AbstractFieldPhrase
|
class FieldPhrase<QDate> : public AbstractFieldPhrase
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
QueryPrivate::QueryPrivate(QueryBase *parent) : q_ptr(parent),
|
QueryPrivate::QueryPrivate(QueryBase *parent) : q_ptr(parent),
|
||||||
skip(-1), take(-1)
|
database(0), tableSet(0), skip(-1), take(-1)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
10
src/query.h
10
src/query.h
|
|
@ -50,7 +50,7 @@ template <class T>
|
||||||
bool m_autoDelete;
|
bool m_autoDelete;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Query(Database *database, TableSetBase *tableSet, bool autoDelete);
|
explicit Query(Database *database, TableSetBase *tableSet, bool autoDelete);
|
||||||
~Query();
|
~Query();
|
||||||
|
|
||||||
//ddl
|
//ddl
|
||||||
|
|
@ -124,8 +124,8 @@ template <class T>
|
||||||
Q_OUTOFLINE_TEMPLATE Query<T>::~Query()
|
Q_OUTOFLINE_TEMPLATE Query<T>::~Query()
|
||||||
{
|
{
|
||||||
Q_D(Query);
|
Q_D(Query);
|
||||||
|
qDebug() << "~Query";// << d->sql;
|
||||||
delete d;
|
delete d;
|
||||||
qDebug() << "~Query";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
|
|
@ -419,8 +419,8 @@ Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::join(const QString &className)
|
||||||
.relationByClassNames(className, d->className);
|
.relationByClassNames(className, d->className);
|
||||||
|
|
||||||
if (!rel) {
|
if (!rel) {
|
||||||
qInfo("No relation between %s and %s",
|
qDebug() << "No relation between" << d->className
|
||||||
qPrintable(d->className), qPrintable(className));
|
<< "and" << className;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -520,7 +520,7 @@ Q_OUTOFLINE_TEMPLATE int Query<T>::update(const AssignmentPhraseList &ph)
|
||||||
ph,
|
ph,
|
||||||
d->wherePhrase);
|
d->wherePhrase);
|
||||||
QSqlQuery q = d->database->exec(d->sql);
|
QSqlQuery q = d->database->exec(d->sql);
|
||||||
|
qDebug() << d->sql;
|
||||||
if (m_autoDelete)
|
if (m_autoDelete)
|
||||||
deleteLater();
|
deleteLater();
|
||||||
return q.numRowsAffected();
|
return q.numRowsAffected();
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ class QueryPrivate{
|
||||||
Q_DECLARE_PUBLIC(QueryBase)
|
Q_DECLARE_PUBLIC(QueryBase)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QueryPrivate(QueryBase *parent);
|
explicit QueryPrivate(QueryBase *parent);
|
||||||
~QueryPrivate();
|
~QueryPrivate();
|
||||||
|
|
||||||
QString sql;
|
QString sql;
|
||||||
|
|
|
||||||
|
|
@ -85,4 +85,9 @@ QVariant SqlModel::data(const QModelIndex &index, int role) const
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SqlModelPrivate::SqlModelPrivate()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ class SqlModel : public QAbstractTableModel
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SqlModel(Database *database, TableSetBase *tableSet, QObject *parent = Q_NULLPTR);
|
explicit SqlModel(Database *database, TableSetBase *tableSet, QObject *parent = Q_NULLPTR);
|
||||||
|
|
||||||
int rowCount(const QModelIndex &parent) const;
|
int rowCount(const QModelIndex &parent) const;
|
||||||
int columnCount(const QModelIndex &parent) const;
|
int columnCount(const QModelIndex &parent) const;
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ class SqlModelPrivate {
|
||||||
SqlModel *q_ptr;
|
SqlModel *q_ptr;
|
||||||
Q_DECLARE_PUBLIC(SqlModel)
|
Q_DECLARE_PUBLIC(SqlModel)
|
||||||
public:
|
public:
|
||||||
|
explicit SqlModelPrivate();
|
||||||
|
|
||||||
QString tableName;
|
QString tableName;
|
||||||
|
|
||||||
QList<Table*> rows;
|
QList<Table*> rows;
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ NUT_BEGIN_NAMESPACE
|
||||||
* This should be fixed to v1.2
|
* This should be fixed to v1.2
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Table::Table(QObject *parent) : QObject(parent), myModel(0)
|
Table::Table(QObject *parent) : QObject(parent), myModel(0), _parentTableSet(0)
|
||||||
{
|
{
|
||||||
setStatus(NewCreated);
|
setStatus(NewCreated);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ QList<FieldModel *> TableModel::fields() const
|
||||||
|
|
||||||
QList<RelationModel *> TableModel::foregionKeys() const
|
QList<RelationModel *> TableModel::foregionKeys() const
|
||||||
{
|
{
|
||||||
return _foregionKeys;
|
return _foreignKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList TableModel::fieldsNames() const
|
QStringList TableModel::fieldsNames() const
|
||||||
|
|
@ -237,9 +237,9 @@ TableModel::TableModel(int typeId, QString tableName)
|
||||||
fk->slaveTable = this;
|
fk->slaveTable = this;
|
||||||
fk->localColumn = name + "Id";
|
fk->localColumn = name + "Id";
|
||||||
fk->localProperty = name;
|
fk->localProperty = name;
|
||||||
fk->foregionColumn = value;
|
fk->foreignColumn = value;
|
||||||
fk->masterClassName = value;
|
fk->masterClassName = value;
|
||||||
_foregionKeys.append(fk);
|
_foreignKeys.append(fk);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(type == __nut_FIELD){
|
if(type == __nut_FIELD){
|
||||||
|
|
@ -292,6 +292,7 @@ TableModel::TableModel(QJsonObject json, QString tableName)
|
||||||
_name = tableName;
|
_name = tableName;
|
||||||
|
|
||||||
QJsonObject fields = json.value(__FIELDS).toObject();
|
QJsonObject fields = json.value(__FIELDS).toObject();
|
||||||
|
QJsonObject relations = json.value(__FOREIGN_KEYS).toObject();
|
||||||
foreach (QString key, fields.keys()) {
|
foreach (QString key, fields.keys()) {
|
||||||
QJsonObject fieldObject = fields.value(key).toObject();
|
QJsonObject fieldObject = fields.value(key).toObject();
|
||||||
FieldModel *f = new FieldModel;
|
FieldModel *f = new FieldModel;
|
||||||
|
|
@ -309,11 +310,16 @@ TableModel::TableModel(QJsonObject json, QString tableName)
|
||||||
_fields.append(f);
|
_fields.append(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(json.keys().contains(__nut_AUTO_INCREMENT))
|
foreach (QString key, relations.keys()) {
|
||||||
field(json.value(__nut_AUTO_INCREMENT).toString())->isAutoIncrement = true;
|
QJsonObject relObject = fields.value(key).toObject();
|
||||||
|
_foreignKeys.append(new RelationModel(relObject));
|
||||||
|
}
|
||||||
|
|
||||||
if(json.keys().contains(__nut_PRIMARY_KEY))
|
// if(json.keys().contains(__nut_AUTO_INCREMENT))
|
||||||
field(json.value(__nut_PRIMARY_KEY).toString())->isAutoIncrement = true;
|
// field(json.value(__nut_AUTO_INCREMENT).toString())->isAutoIncrement = true;
|
||||||
|
|
||||||
|
// if(json.keys().contains(__nut_PRIMARY_KEY))
|
||||||
|
// field(json.value(__nut_PRIMARY_KEY).toString())->isAutoIncrement = true;
|
||||||
|
|
||||||
_allModels.insert(this);
|
_allModels.insert(this);
|
||||||
}
|
}
|
||||||
|
|
@ -322,6 +328,7 @@ QJsonObject TableModel::toJson() const
|
||||||
{
|
{
|
||||||
QJsonObject obj;
|
QJsonObject obj;
|
||||||
QJsonObject fieldsObj;
|
QJsonObject fieldsObj;
|
||||||
|
QJsonObject foreignKeysObj;
|
||||||
|
|
||||||
foreach (FieldModel *f, _fields) {
|
foreach (FieldModel *f, _fields) {
|
||||||
QJsonObject fieldObj;
|
QJsonObject fieldObj;
|
||||||
|
|
@ -337,28 +344,41 @@ QJsonObject TableModel::toJson() const
|
||||||
if(!f->defaultValue.isNull())
|
if(!f->defaultValue.isNull())
|
||||||
fieldObj.insert(__nut_DEFAULT_VALUE, f->defaultValue);
|
fieldObj.insert(__nut_DEFAULT_VALUE, f->defaultValue);
|
||||||
|
|
||||||
fieldsObj.insert(f->name, fieldObj);
|
|
||||||
|
|
||||||
if(f->isAutoIncrement)
|
if(f->isAutoIncrement)
|
||||||
obj.insert(__nut_PRIMARY_KEY, f->name);
|
obj.insert(__nut_AUTO_INCREMENT, f->name);
|
||||||
|
|
||||||
if(f->isPrimaryKey)
|
if(f->isPrimaryKey)
|
||||||
obj.insert(__nut_AUTO_INCREMENT, f->name);
|
obj.insert(__nut_PRIMARY_KEY, f->name);
|
||||||
|
|
||||||
|
fieldsObj.insert(f->name, fieldObj);
|
||||||
}
|
}
|
||||||
|
foreach (RelationModel *rel, _foreignKeys)
|
||||||
|
foreignKeysObj.insert(rel->localColumn, rel->toJson());
|
||||||
|
|
||||||
obj.insert(__FIELDS, fieldsObj);
|
obj.insert(__FIELDS, fieldsObj);
|
||||||
|
obj.insert(__FOREIGN_KEYS, foreignKeysObj);
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
RelationModel *TableModel::foregionKey(QString otherTable) const
|
RelationModel *TableModel::foregionKey(const QString &otherTable) const
|
||||||
{
|
{
|
||||||
foreach (RelationModel *fk, _foregionKeys)
|
foreach (RelationModel *fk, _foreignKeys)
|
||||||
if(fk->masterClassName == otherTable)
|
if(fk->masterClassName == otherTable)
|
||||||
return fk;
|
return fk;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RelationModel *TableModel::foregionKeyByField(const QString &fieldName) const
|
||||||
|
{
|
||||||
|
foreach (RelationModel *fk, _foreignKeys)
|
||||||
|
if(fk->localColumn == fieldName)
|
||||||
|
return fk;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
QString TableModel::toString() const
|
QString TableModel::toString() const
|
||||||
{
|
{
|
||||||
QStringList sl;
|
QStringList sl;
|
||||||
|
|
@ -379,4 +399,61 @@ QString TableModel::primaryKey() const
|
||||||
return QString::null;
|
return QString::null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FieldModel::FieldModel(const QJsonObject &json)
|
||||||
|
{
|
||||||
|
name = json.value(__NAME).toString();
|
||||||
|
type = static_cast<QVariant::Type>(json.value(__TYPE).toInt());
|
||||||
|
length = json.value(__nut_LEN).toInt();
|
||||||
|
notNull = json.value(__nut_NOT_NULL).toBool();
|
||||||
|
isAutoIncrement = json.value(__nut_AUTO_INCREMENT).toBool();
|
||||||
|
isPrimaryKey = json.value(__nut_PRIMARY_KEY).toBool();
|
||||||
|
defaultValue = json.value(__nut_DEFAULT_VALUE).toString();
|
||||||
|
isUnique = json.value(__nut_UNIQUE).toBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject FieldModel::toJson() const
|
||||||
|
{
|
||||||
|
QJsonObject fieldObj;
|
||||||
|
fieldObj.insert(__NAME, name);
|
||||||
|
fieldObj.insert(__TYPE, QString(QVariant::typeToName(type)));
|
||||||
|
fieldObj.insert(__nut_LEN, length);
|
||||||
|
fieldObj.insert(__nut_NOT_NULL, notNull);
|
||||||
|
fieldObj.insert(__nut_AUTO_INCREMENT, isAutoIncrement);
|
||||||
|
fieldObj.insert(__nut_PRIMARY_KEY, isPrimaryKey);
|
||||||
|
fieldObj.insert(__nut_DEFAULT_VALUE, defaultValue);
|
||||||
|
return fieldObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
RelationModel::RelationModel(const QJsonObject &obj)
|
||||||
|
{
|
||||||
|
localColumn = obj.value("localColumn").toString();
|
||||||
|
localProperty = obj.value("localProperty").toString();
|
||||||
|
masterClassName = obj.value("masterClassName").toString();
|
||||||
|
foreignColumn = obj.value("foreignColumn").toString();
|
||||||
|
slaveTable = masterTable = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject RelationModel::toJson() const
|
||||||
|
{
|
||||||
|
QJsonObject o;
|
||||||
|
o.insert("localColumn", localColumn);
|
||||||
|
o.insert("localProperty", localProperty);
|
||||||
|
o.insert("masterClassName", masterClassName);
|
||||||
|
o.insert("foreignColumn", foreignColumn);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator ==(const RelationModel &l, const RelationModel &r)
|
||||||
|
{
|
||||||
|
return r.foreignColumn == l.foreignColumn
|
||||||
|
&& r.localColumn == l.localColumn
|
||||||
|
&& r.localProperty == l.localColumn
|
||||||
|
&& r.masterClassName == l.masterClassName;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator !=(const RelationModel &l, const RelationModel &r)
|
||||||
|
{
|
||||||
|
return !(l == r);
|
||||||
|
}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -31,12 +31,14 @@ NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class TableModel;
|
class TableModel;
|
||||||
struct FieldModel{
|
struct FieldModel{
|
||||||
FieldModel() : name(QString::null), length(0), defaultValue(QString::null),
|
explicit FieldModel() : name(QString::null), length(0), defaultValue(QString::null),
|
||||||
notNull(false), isPrimaryKey(false), isAutoIncrement(false), isUnique(false)
|
notNull(false), isPrimaryKey(false), isAutoIncrement(false), isUnique(false)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
explicit FieldModel(const QJsonObject &json);
|
||||||
|
|
||||||
QString name;
|
QString name;
|
||||||
//TODO: QMetaType::Type??
|
//TODO: QMetaType::Type??
|
||||||
QVariant::Type type;
|
QVariant::Type type;
|
||||||
|
|
@ -63,25 +65,35 @@ struct FieldModel{
|
||||||
bool operator !=(const FieldModel &f) const{
|
bool operator !=(const FieldModel &f) const{
|
||||||
return !(*this == f);
|
return !(*this == f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject toJson() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RelationModel{
|
struct RelationModel{
|
||||||
|
RelationModel() : localColumn(""), localProperty(""), slaveTable(0),
|
||||||
|
foreignColumn(""), masterTable(0), masterClassName("")
|
||||||
|
{}
|
||||||
|
explicit RelationModel(const QJsonObject &obj);
|
||||||
|
|
||||||
//slave
|
//slave
|
||||||
QString localColumn;
|
QString localColumn;
|
||||||
QString localProperty;
|
QString localProperty;
|
||||||
TableModel *slaveTable;
|
TableModel *slaveTable;
|
||||||
//master
|
//master
|
||||||
QString foregionColumn;
|
QString foreignColumn;
|
||||||
TableModel *masterTable;
|
TableModel *masterTable;
|
||||||
|
|
||||||
QString masterClassName;
|
QString masterClassName;
|
||||||
|
|
||||||
|
QJsonObject toJson() const;
|
||||||
};
|
};
|
||||||
|
bool operator ==(const RelationModel &l, const RelationModel &r);
|
||||||
|
bool operator !=(const RelationModel &l, const RelationModel &r);
|
||||||
class TableModel
|
class TableModel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
explicit TableModel(int typeId, QString tableName = QString::null);
|
||||||
TableModel(int typeId, QString tableName = QString::null);
|
explicit TableModel(QJsonObject json, QString tableName);
|
||||||
TableModel(QJsonObject json, QString tableName);
|
|
||||||
|
|
||||||
QJsonObject toJson() const;
|
QJsonObject toJson() const;
|
||||||
|
|
||||||
|
|
@ -91,7 +103,8 @@ public:
|
||||||
|
|
||||||
FieldModel *field(int n) const;
|
FieldModel *field(int n) const;
|
||||||
FieldModel *field(QString name) const;
|
FieldModel *field(QString name) const;
|
||||||
RelationModel *foregionKey(QString otherTable) const;
|
RelationModel *foregionKey(const QString &otherTable) const;
|
||||||
|
RelationModel *foregionKeyByField(const QString &fieldName) const;
|
||||||
|
|
||||||
QString toString() const;
|
QString toString() const;
|
||||||
|
|
||||||
|
|
@ -122,7 +135,7 @@ private:
|
||||||
QString _className;
|
QString _className;
|
||||||
int _typeId;
|
int _typeId;
|
||||||
QList<FieldModel*> _fields;
|
QList<FieldModel*> _fields;
|
||||||
QList<RelationModel*> _foregionKeys;
|
QList<RelationModel*> _foreignKeys;
|
||||||
static QSet<TableModel*>_allModels;
|
static QSet<TableModel*>_allModels;
|
||||||
bool checkClassInfo(const QMetaClassInfo &classInfo,
|
bool checkClassInfo(const QMetaClassInfo &classInfo,
|
||||||
QString &type, QString &name, QString &value);
|
QString &type, QString &name, QString &value);
|
||||||
|
|
|
||||||
|
|
@ -39,8 +39,8 @@ template<class T>
|
||||||
class NUT_EXPORT TableSet : public TableSetBase
|
class NUT_EXPORT TableSet : public TableSetBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TableSet(Database *parent);
|
explicit TableSet(Database *parent);
|
||||||
TableSet(Table *parent);
|
explicit TableSet(Table *parent);
|
||||||
|
|
||||||
void append(T *t);
|
void append(T *t);
|
||||||
void append(QList<T *> t);
|
void append(QList<T *> t);
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,8 @@ class TableSetBase : public QObject
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TableSetBase(Database *parent);
|
explicit TableSetBase(Database *parent);
|
||||||
TableSetBase(Table *parent);
|
explicit TableSetBase(Table *parent);
|
||||||
|
|
||||||
virtual int save(Database *db, bool cleanUp = false);
|
virtual int save(Database *db, bool cleanUp = false);
|
||||||
void clearChilds();
|
void clearChilds();
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,8 @@ class NUT_EXPORT DbGeography
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit DbGeography();
|
explicit DbGeography();
|
||||||
DbGeography(const DbGeography &other);
|
explicit DbGeography(const DbGeography &other);
|
||||||
DbGeography(const QVariant &value);
|
explicit DbGeography(const QVariant &value);
|
||||||
|
|
||||||
qreal longitude() const;
|
qreal longitude() const;
|
||||||
qreal latitude() const;
|
qreal latitude() const;
|
||||||
|
|
|
||||||
|
|
@ -1,234 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
**
|
|
||||||
** 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 <http://www.gnu.org/licenses/>.
|
|
||||||
**
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#include <QDataStream>
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
#include "phrase.h"
|
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
|
||||||
|
|
||||||
PhraseData::PhraseData(const char *className, const char *s)
|
|
||||||
{
|
|
||||||
Q_UNUSED(className)
|
|
||||||
text = QString("[%1].%2").arg(className).arg(s);
|
|
||||||
type = Field;
|
|
||||||
operatorCond = NotAssign;
|
|
||||||
}
|
|
||||||
|
|
||||||
PhraseData::PhraseData(PhraseData *l, PhraseData::Condition o) : left(l)
|
|
||||||
{
|
|
||||||
operatorCond = o;
|
|
||||||
type = WithoutOperand;
|
|
||||||
}
|
|
||||||
|
|
||||||
PhraseData::PhraseData(PhraseData *l, PhraseData::Condition o,
|
|
||||||
const PhraseData *r)
|
|
||||||
: left(l), right(r)
|
|
||||||
{
|
|
||||||
operatorCond = o;
|
|
||||||
type = WithOther;
|
|
||||||
}
|
|
||||||
|
|
||||||
PhraseData::PhraseData(PhraseData *l, PhraseData::Condition o, QVariant r)
|
|
||||||
: left(l), operand(r)
|
|
||||||
{
|
|
||||||
operatorCond = o;
|
|
||||||
type = WithVariant;
|
|
||||||
}
|
|
||||||
|
|
||||||
PhraseData::~PhraseData()
|
|
||||||
{
|
|
||||||
if (type == WithOther) {
|
|
||||||
delete left;
|
|
||||||
delete right;
|
|
||||||
}
|
|
||||||
if (type == WithVariant) {
|
|
||||||
if (left)
|
|
||||||
delete left;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PhraseData *WherePhrase::data() const
|
|
||||||
{
|
|
||||||
return _data;
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase::WherePhrase(const char *className, const char *s)
|
|
||||||
{
|
|
||||||
_data = new PhraseData(className, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase::WherePhrase(const WherePhrase &l)
|
|
||||||
{
|
|
||||||
_data = l._data;
|
|
||||||
_dataPointer = QSharedPointer<PhraseData>(l._dataPointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase::WherePhrase(WherePhrase *l)
|
|
||||||
{
|
|
||||||
_data = l->_data;
|
|
||||||
|
|
||||||
l->_data = 0;
|
|
||||||
l->_dataPointer.reset(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase::WherePhrase(WherePhrase *l, PhraseData::Condition o)
|
|
||||||
{
|
|
||||||
_data = new PhraseData(l->_data, o);
|
|
||||||
l->_data = 0;
|
|
||||||
l->_dataPointer.reset(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase::WherePhrase(WherePhrase *l, PhraseData::Condition o,
|
|
||||||
WherePhrase *r)
|
|
||||||
{
|
|
||||||
_data = new PhraseData(l->_data, o, r->_data);
|
|
||||||
l->_data = 0;
|
|
||||||
r->_data = 0;
|
|
||||||
|
|
||||||
l->_dataPointer.reset(0);
|
|
||||||
r->_dataPointer.reset(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase::WherePhrase(WherePhrase *l, PhraseData::Condition o, QVariant r)
|
|
||||||
{
|
|
||||||
_data = new PhraseData(l->_data, o, r);
|
|
||||||
l->_data = 0;
|
|
||||||
l->_dataPointer.reset(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase::~WherePhrase()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase WherePhrase::operator==(const WherePhrase &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Equal, (WherePhrase *)&other);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase WherePhrase::operator!=(const WherePhrase &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::NotEqual, (WherePhrase *)&other);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase WherePhrase::operator<(const WherePhrase &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Less, (WherePhrase *)&other);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase WherePhrase::operator>(const WherePhrase &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Greater, (WherePhrase *)&other);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase WherePhrase::operator<=(const WherePhrase &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::LessEqual, (WherePhrase *)&other);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase WherePhrase::operator>=(const WherePhrase &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::GreaterEqual, (WherePhrase *)&other);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase WherePhrase::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 WherePhrase &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Set, (WherePhrase *)&other);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase WherePhrase::operator+(const WherePhrase &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Add, (WherePhrase *)&other);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase WherePhrase::operator-(const WherePhrase &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Minus, (WherePhrase *)&other);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase WherePhrase::operator*(const WherePhrase &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Multiple, (WherePhrase *)&other);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase WherePhrase::operator/(const WherePhrase &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Divide, (WherePhrase *)&other);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase WherePhrase::operator&&(const WherePhrase &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::And, (WherePhrase *)&other);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase WherePhrase::operator||(const WherePhrase &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Or, (WherePhrase *)&other);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase WherePhrase::operator&(const WherePhrase &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Append, (WherePhrase *)&other);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase WherePhrase::operator==(const QVariant &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Equal, other);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase WherePhrase::operator!=(const QVariant &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::NotEqual, other);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase WherePhrase::operator<(const QVariant &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Less, other);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase WherePhrase::operator>(const QVariant &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Greater, other);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase WherePhrase::operator<=(const QVariant &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::LessEqual, other);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase WherePhrase::operator>=(const QVariant &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::GreaterEqual, other);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
|
||||||
|
|
@ -1,515 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
**
|
|
||||||
** 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 <http://www.gnu.org/licenses/>.
|
|
||||||
**
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef WHEREPHRASE_H
|
|
||||||
#define WHEREPHRASE_H
|
|
||||||
|
|
||||||
#include <QtCore/qglobal.h>
|
|
||||||
|
|
||||||
#include <QVariant>
|
|
||||||
#include <QDate>
|
|
||||||
#include <QDateTime>
|
|
||||||
#include <QTime>
|
|
||||||
#include <QPoint>
|
|
||||||
#include <QSharedPointer>
|
|
||||||
#include "defines.h"
|
|
||||||
#include "types/dbgeography.h"
|
|
||||||
|
|
||||||
#if __cplusplus >= 201103L
|
|
||||||
#include <initializer_list>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
|
||||||
|
|
||||||
class SqlGeneratorBase;
|
|
||||||
//class PhraseData
|
|
||||||
//{
|
|
||||||
//public:
|
|
||||||
// enum Condition {
|
|
||||||
// NotAssign = 0,
|
|
||||||
// Equal,
|
|
||||||
// Less,
|
|
||||||
// LessEqual,
|
|
||||||
// Null,
|
|
||||||
// In,
|
|
||||||
// Like,
|
|
||||||
|
|
||||||
// Not = 10,
|
|
||||||
// NotEqual,
|
|
||||||
// GreaterEqual,
|
|
||||||
// Greater,
|
|
||||||
// NotNull,
|
|
||||||
// NotIn,
|
|
||||||
// NotLike,
|
|
||||||
|
|
||||||
// And = 20,
|
|
||||||
// Or,
|
|
||||||
|
|
||||||
// Append,
|
|
||||||
// Set,
|
|
||||||
|
|
||||||
// Add,
|
|
||||||
// Minus,
|
|
||||||
// Multiple,
|
|
||||||
// Divide,
|
|
||||||
|
|
||||||
// // special types
|
|
||||||
// Distance
|
|
||||||
// };
|
|
||||||
|
|
||||||
// enum Type { Field, WithVariant, WithOther, WithoutOperand };
|
|
||||||
// Type type;
|
|
||||||
|
|
||||||
// Condition operatorCond;
|
|
||||||
|
|
||||||
// QString text;
|
|
||||||
// const PhraseData *left;
|
|
||||||
// const PhraseData *right;
|
|
||||||
// QVariant operand;
|
|
||||||
|
|
||||||
// PhraseData(const char *className, const char *s);
|
|
||||||
// PhraseData(PhraseData *l, Condition o);
|
|
||||||
// PhraseData(PhraseData *l, Condition o, const PhraseData *r);
|
|
||||||
// PhraseData(PhraseData *l, Condition o, QVariant r);
|
|
||||||
|
|
||||||
// ~PhraseData();
|
|
||||||
//};
|
|
||||||
|
|
||||||
class WherePhrase
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
PhraseData *_data;
|
|
||||||
QSharedPointer<PhraseData> _dataPointer;
|
|
||||||
|
|
||||||
public:
|
|
||||||
WherePhrase(const char *className, const char *s);
|
|
||||||
|
|
||||||
WherePhrase(const WherePhrase &l);
|
|
||||||
WherePhrase(WherePhrase *l);
|
|
||||||
WherePhrase(WherePhrase *l, PhraseData::Condition o);
|
|
||||||
WherePhrase(WherePhrase *l, PhraseData::Condition o, WherePhrase *r);
|
|
||||||
WherePhrase(WherePhrase *l, PhraseData::Condition o, QVariant r);
|
|
||||||
|
|
||||||
~WherePhrase();
|
|
||||||
|
|
||||||
WherePhrase operator==(const WherePhrase &other);
|
|
||||||
WherePhrase operator!=(const WherePhrase &other);
|
|
||||||
WherePhrase operator<(const WherePhrase &other);
|
|
||||||
WherePhrase operator>(const WherePhrase &other);
|
|
||||||
WherePhrase operator<=(const WherePhrase &other);
|
|
||||||
WherePhrase operator>=(const WherePhrase &other);
|
|
||||||
|
|
||||||
WherePhrase operator==(const QVariant &other);
|
|
||||||
WherePhrase operator!=(const QVariant &other);
|
|
||||||
WherePhrase operator<(const QVariant &other);
|
|
||||||
WherePhrase operator>(const QVariant &other);
|
|
||||||
WherePhrase operator<=(const QVariant &other);
|
|
||||||
WherePhrase operator>=(const QVariant &other);
|
|
||||||
|
|
||||||
WherePhrase operator!();
|
|
||||||
WherePhrase operator=(const WherePhrase &other);
|
|
||||||
|
|
||||||
WherePhrase operator+(const WherePhrase &other);
|
|
||||||
WherePhrase operator-(const WherePhrase &other);
|
|
||||||
WherePhrase operator*(const WherePhrase &other);
|
|
||||||
WherePhrase operator/(const WherePhrase &other);
|
|
||||||
|
|
||||||
WherePhrase operator&&(const WherePhrase &other);
|
|
||||||
WherePhrase operator||(const WherePhrase &other);
|
|
||||||
|
|
||||||
WherePhrase operator&(const WherePhrase &other);
|
|
||||||
|
|
||||||
PhraseData *data() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class FieldPhrase : public WherePhrase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
FieldPhrase(const char *className, const char *s);
|
|
||||||
|
|
||||||
WherePhrase operator=(const FieldPhrase<T> &other);
|
|
||||||
|
|
||||||
WherePhrase operator=(const WherePhrase &other);
|
|
||||||
WherePhrase operator=(const QVariant &other);
|
|
||||||
WherePhrase operator+(const QVariant &other);
|
|
||||||
WherePhrase operator!();
|
|
||||||
|
|
||||||
WherePhrase operator==(const QVariant &other);
|
|
||||||
WherePhrase operator!=(const QVariant &other);
|
|
||||||
WherePhrase operator<(const QVariant &other);
|
|
||||||
WherePhrase operator>(const QVariant &other);
|
|
||||||
WherePhrase operator<=(const QVariant &other);
|
|
||||||
WherePhrase operator>=(const QVariant &other);
|
|
||||||
|
|
||||||
WherePhrase isNull();
|
|
||||||
WherePhrase in(QList<T> list);
|
|
||||||
// WherePhrase in(QStringList list);
|
|
||||||
WherePhrase like(QString pattern);
|
|
||||||
};
|
|
||||||
|
|
||||||
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=(const FieldPhrase<T> &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Equal, &other);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase<T>::
|
|
||||||
operator=(const WherePhrase &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Set, &other);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase<T>::
|
|
||||||
operator+(const QVariant &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Add, 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>::
|
|
||||||
operator==(const QVariant &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Equal, other);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase<T>::
|
|
||||||
operator!=(const QVariant &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::NotEqual, other);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase<T>::
|
|
||||||
operator<(const QVariant &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Less, other);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase<T>::
|
|
||||||
operator>(const QVariant &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Greater, other);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase<T>::
|
|
||||||
operator<=(const QVariant &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::LessEqual, other);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase<T>::
|
|
||||||
operator>=(const QVariant &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::GreaterEqual, other);
|
|
||||||
}
|
|
||||||
|
|
||||||
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(QList<T> list)
|
|
||||||
{
|
|
||||||
QVariantList vlist;
|
|
||||||
foreach (T t, list)
|
|
||||||
vlist.append(QVariant::fromValue(t));
|
|
||||||
|
|
||||||
return WherePhrase(this, PhraseData::In, vlist);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Custom types
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Custom types
|
|
||||||
template <>
|
|
||||||
class FieldPhrase<QPoint> : public WherePhrase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
FieldPhrase(const char *className, const char *s)
|
|
||||||
: WherePhrase(className, s)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase distance(const QPoint &geo)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Distance,
|
|
||||||
QVariant::fromValue(geo));
|
|
||||||
}
|
|
||||||
WherePhrase operator=(const QPoint &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Set, other);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Custom types
|
|
||||||
template <>
|
|
||||||
class FieldPhrase<QPointF> : public WherePhrase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
FieldPhrase(const char *className, const char *s)
|
|
||||||
: WherePhrase(className, s)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase distance(const QPointF &geo)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Distance,
|
|
||||||
QVariant::fromValue(geo));
|
|
||||||
}
|
|
||||||
WherePhrase operator=(const QPointF &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Set, other);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// template<>
|
|
||||||
// class FieldPhrase<QString>: public WherePhrase {
|
|
||||||
// public:
|
|
||||||
// FieldPhrase(const char *className, const char* s) : WherePhrase(className,
|
|
||||||
// s){
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
// WherePhrase like(QString pattern)
|
|
||||||
// {
|
|
||||||
// return WherePhrase(this, PhraseData::Like, pattern);
|
|
||||||
// }
|
|
||||||
//};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
class FieldPhrase<bool> : public WherePhrase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
FieldPhrase(const char *className, const char *s)
|
|
||||||
: WherePhrase(className, s)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase operator==(const bool &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Equal, other ? 1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase operator=(const bool &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Set, other ? 1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase operator!()
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Equal, 0);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class NumericFieldPhrase : public WherePhrase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
NumericFieldPhrase(const char *className, const char *s)
|
|
||||||
: WherePhrase(className, s)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase operator=(const QVariant &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Set, other);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase operator+(const QVariant &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Add, other);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase operator-(const QVariant &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Minus, other);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase operator++()
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Add, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase operator--()
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Minus, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase operator==(const QVariant &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Equal, other);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase operator!=(const QVariant &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::NotEqual, other);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase operator<(const QVariant &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Less, other);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase operator>(const QVariant &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Greater, other);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase operator<=(const QVariant &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::LessEqual, other);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase operator>=(const QVariant &other)
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::GreaterEqual, other);
|
|
||||||
}
|
|
||||||
|
|
||||||
WherePhrase isNull()
|
|
||||||
{
|
|
||||||
return WherePhrase(this, PhraseData::Null);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
WherePhrase in(QList<T> list)
|
|
||||||
{
|
|
||||||
QVariantList vlist;
|
|
||||||
foreach (T t, list)
|
|
||||||
vlist.append(QVariant::fromValue(t));
|
|
||||||
return WherePhrase(this, PhraseData::In, vlist);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if __cplusplus >= 201103L
|
|
||||||
template<typename T>
|
|
||||||
WherePhrase in(std::initializer_list<T> list)
|
|
||||||
{
|
|
||||||
return in(QList<T>(list));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
WherePhrase in(int count, ...)
|
|
||||||
{
|
|
||||||
QVariantList vlist;
|
|
||||||
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, count);
|
|
||||||
|
|
||||||
for (int i = 0; i < count; ++i)
|
|
||||||
vlist.append(QVariant::fromValue(va_arg(ap, int)));
|
|
||||||
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
return WherePhrase(this, PhraseData::In, vlist);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#define SPECIALIZATION_NUMERIC(type) \
|
|
||||||
template <> \
|
|
||||||
class FieldPhrase<type> : public NumericFieldPhrase \
|
|
||||||
{ \
|
|
||||||
public: \
|
|
||||||
FieldPhrase(const char *className, const char *s) \
|
|
||||||
: NumericFieldPhrase(className, s) \
|
|
||||||
{ \
|
|
||||||
} \
|
|
||||||
WherePhrase operator=(const WherePhrase &other) \
|
|
||||||
{ \
|
|
||||||
return WherePhrase(this, PhraseData::Set, (WherePhrase *)&other); \
|
|
||||||
} \
|
|
||||||
};
|
|
||||||
|
|
||||||
SPECIALIZATION_NUMERIC(qint8)
|
|
||||||
SPECIALIZATION_NUMERIC(qint16)
|
|
||||||
SPECIALIZATION_NUMERIC(qint32)
|
|
||||||
SPECIALIZATION_NUMERIC(qint64)
|
|
||||||
|
|
||||||
SPECIALIZATION_NUMERIC(quint8)
|
|
||||||
SPECIALIZATION_NUMERIC(quint16)
|
|
||||||
SPECIALIZATION_NUMERIC(quint32)
|
|
||||||
SPECIALIZATION_NUMERIC(quint64)
|
|
||||||
|
|
||||||
SPECIALIZATION_NUMERIC(qreal)
|
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
|
||||||
|
|
||||||
#endif // PHRASE_H
|
|
||||||
|
|
@ -69,6 +69,7 @@ void MainTest::createUser()
|
||||||
|
|
||||||
void MainTest::createPost()
|
void MainTest::createPost()
|
||||||
{
|
{
|
||||||
|
TIC();
|
||||||
Post *newPost = new Post;
|
Post *newPost = new Post;
|
||||||
newPost->setTitle("post title");
|
newPost->setTitle("post title");
|
||||||
newPost->setSaveDate(QDateTime::currentDateTime());
|
newPost->setSaveDate(QDateTime::currentDateTime());
|
||||||
|
|
@ -93,6 +94,7 @@ void MainTest::createPost()
|
||||||
postId = newPost->id();
|
postId = newPost->id();
|
||||||
|
|
||||||
QTEST_ASSERT(newPost->id() != 0);
|
QTEST_ASSERT(newPost->id() != 0);
|
||||||
|
TOC();
|
||||||
qDebug() << "New post inserted with id:" << newPost->id();
|
qDebug() << "New post inserted with id:" << newPost->id();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -119,6 +121,26 @@ void MainTest::createPost2()
|
||||||
qDebug() << "New post2 inserted with id:" << newPost->id();
|
qDebug() << "New post2 inserted with id:" << newPost->id();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainTest::updatePostOnTheFly()
|
||||||
|
{
|
||||||
|
auto c = db.postTable()->query()
|
||||||
|
->where(Post::idField() == postId)
|
||||||
|
->update(Post::titleField() = "New title");
|
||||||
|
|
||||||
|
QTEST_ASSERT(c == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainTest::selectPublicts()
|
||||||
|
{
|
||||||
|
auto q = db.postTable()->query()
|
||||||
|
->where(Post::isPublicField())
|
||||||
|
->toList();
|
||||||
|
|
||||||
|
auto q2 = db.postTable()->query()
|
||||||
|
->where(!Post::isPublicField())
|
||||||
|
->toList();
|
||||||
|
}
|
||||||
|
|
||||||
void MainTest::selectPosts()
|
void MainTest::selectPosts()
|
||||||
{
|
{
|
||||||
auto q = db.postTable()->query()
|
auto q = db.postTable()->query()
|
||||||
|
|
|
||||||
|
|
@ -27,12 +27,14 @@ private slots:
|
||||||
void createUser();
|
void createUser();
|
||||||
void createPost();
|
void createPost();
|
||||||
void createPost2();
|
void createPost2();
|
||||||
|
void selectPublicts();
|
||||||
void join();
|
void join();
|
||||||
void selectPosts();
|
void selectPosts();
|
||||||
void selectScoreAverage();
|
void selectScoreAverage();
|
||||||
void selectFirst();
|
void selectFirst();
|
||||||
void selectPostsWithoutTitle();
|
void selectPostsWithoutTitle();
|
||||||
void selectPostIds();
|
void selectPostIds();
|
||||||
|
void updatePostOnTheFly();
|
||||||
void testDate();
|
void testDate();
|
||||||
void selectWithInvalidRelation();
|
void selectWithInvalidRelation();
|
||||||
void modifyPost();
|
void modifyPost();
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ class Post : public Table
|
||||||
NUT_DECLARE_FIELD(QDateTime, saveDate, saveDate, setSaveDate)
|
NUT_DECLARE_FIELD(QDateTime, saveDate, saveDate, setSaveDate)
|
||||||
|
|
||||||
NUT_DECLARE_FIELD(QString, body, body, setBody)
|
NUT_DECLARE_FIELD(QString, body, body, setBody)
|
||||||
|
NUT_DECLARE_FIELD(bool, isPublic, isPublic, setPublic)
|
||||||
|
|
||||||
NUT_DECLARE_CHILD_TABLE(Comment, comments)
|
NUT_DECLARE_CHILD_TABLE(Comment, comments)
|
||||||
NUT_DECLARE_CHILD_TABLE(Score, scores)
|
NUT_DECLARE_CHILD_TABLE(Score, scores)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue