Merge pull request #13 from HamedMasafi/wip/zerocopy

Wip/zerocopy
This commit is contained in:
Hamed Masafi 2018-03-13 11:32:58 +03:30 committed by GitHub
commit f8bfdc8ff3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 918 additions and 1018 deletions

View File

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

View File

@ -1,5 +1,7 @@
QT += core sql QT += core sql
CONFIG += c++11
INCLUDEPATH += $$PWD/include INCLUDEPATH += $$PWD/include
HEADERS += \ HEADERS += \

View File

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

View File

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

View File

@ -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);
@ -188,6 +190,7 @@ bool DatabasePrivate::getCurrectScheema()
// TODO: change logs must not be in model // TODO: change logs must not be in model
int changeLogTypeId = qRegisterMetaType<ChangeLogTable*>(); int changeLogTypeId = qRegisterMetaType<ChangeLogTable*>();
currentModel.append( currentModel.append(
new TableModel(changeLogTypeId, __CHANGE_LOG_TABLE_NAME)); new TableModel(changeLogTypeId, __CHANGE_LOG_TABLE_NAME));
tables.insert(ChangeLogTable::staticMetaObject.className(), tables.insert(ChangeLogTable::staticMetaObject.className(),

View File

@ -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();

View File

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

View File

@ -57,6 +57,10 @@ DatabaseModel::DatabaseModel(const QJsonObject &json) :
} }
} }
DatabaseModel::~DatabaseModel()
{
}
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++){
@ -223,4 +227,16 @@ DatabaseModel *DatabaseModel::modelByName(const QString &name)
return Q_NULLPTR; return Q_NULLPTR;
} }
void DatabaseModel::deleteAllModels()
{
QMapIterator<QString, DatabaseModel*> i(_models);
while (i.hasNext()) {
i.next();
// cout << i.key() << ": " << i.value() << endl;
delete i.value();
}
// qDeleteAll(_models.values());
_models.clear();
}
NUT_END_NAMESPACE NUT_END_NAMESPACE

View File

@ -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();
TableModel *tableByName(QString tableName) const; TableModel *tableByName(QString tableName) const;
TableModel *tableByClassName(QString className) const; TableModel *tableByClassName(QString className) const;
@ -69,6 +70,7 @@ public:
void fixRelations(); void fixRelations();
static DatabaseModel *modelByName(const QString &name); static DatabaseModel *modelByName(const QString &name);
static void deleteAllModels();
}; };
NUT_END_NAMESPACE NUT_END_NAMESPACE

View File

@ -32,73 +32,77 @@
# define NUT_EXPORT Q_DECL_EXPORT # define NUT_EXPORT Q_DECL_EXPORT
#endif #endif
#define NUT_INFO(type, name, value) \ #define NUT_INFO(type, name, value) \
Q_CLASSINFO(__nut_NAME_PERFIX type #name #value, type "\n" #name "\n" #value) Q_CLASSINFO(__nut_NAME_PERFIX type #name #value, \
type "\n" #name "\n" #value)
// Database // Database
#define NUT_DB_VERSION(version) \ #define NUT_DB_VERSION(version) \
NUT_INFO(__nut_DB_VERSION, version, 0) NUT_INFO(__nut_DB_VERSION, version, 0)
#define NUT_DECLARE_TABLE(type, name) \ #define NUT_DECLARE_TABLE(type, name) \
NUT_INFO(__nut_TABLE, type, name) \ NUT_INFO(__nut_TABLE, type, name) \
Q_PROPERTY(type* name READ name) \ Q_PROPERTY(type* name READ name) \
Q_PROPERTY(NUT_WRAP_NAMESPACE(TableSet<type>) name##Table READ name##Table) \ Q_PROPERTY(NUT_WRAP_NAMESPACE(TableSet<type>) name##Table READ name##Table)\
type* m_##name; \ type* m_##name; \
NUT_WRAP_NAMESPACE(TableSet<type>) *m_##name##Table; \ NUT_WRAP_NAMESPACE(TableSet<type>) *m_##name##Table; \
public: \ public: \
static const type _##name; \ static const type _##name; \
type* name() const{ return m_##name; } \ type* name() const{ return m_##name; } \
NUT_WRAP_NAMESPACE(TableSet<type>) *name##Table() const { return m_##name##Table; } NUT_WRAP_NAMESPACE(TableSet<type>) *name##Table() const \
{ return m_##name##Table; }
//Table //Table
#define NUT_DECLARE_FIELD(type, name, read, write) \ #define NUT_DECLARE_FIELD(type, name, read, write) \
Q_PROPERTY(type name READ read WRITE write) \ Q_PROPERTY(type name READ read WRITE write) \
NUT_INFO(__nut_FIELD, name, 0) \ NUT_INFO(__nut_FIELD, name, 0) \
type m_##name; \ type m_##name; \
public: \ public: \
static NUT_WRAP_NAMESPACE(FieldPhrase<type>) name ## Field(){ \ static NUT_WRAP_NAMESPACE(FieldPhrase<type>) name ## Field(){ \
static NUT_WRAP_NAMESPACE(FieldPhrase<type>) f = NUT_WRAP_NAMESPACE(FieldPhrase<type>)(staticMetaObject.className(), #name); \ static NUT_WRAP_NAMESPACE(FieldPhrase<type>) f = \
return f; \ NUT_WRAP_NAMESPACE(FieldPhrase<type>) \
} \ (staticMetaObject.className(), #name); \
type read() const{ \ return f; \
return m_##name; \ } \
} \ type read() const{ \
void write(type name){ \ return m_##name; \
m_##name = name; \ } \
propertyChanged(#name); \ void write(type name){ \
m_##name = name; \
propertyChanged(#name); \
} }
#define NUT_FOREGION_KEY(type, keytype, name, read, write) \ #define NUT_FOREGION_KEY(type, keytype, name, read, write) \
Q_PROPERTY(type* name READ read WRITE write) \ Q_PROPERTY(type* name READ read WRITE write) \
NUT_DECLARE_FIELD(keytype, name##Id, read##Id, write##Id) \ NUT_DECLARE_FIELD(keytype, name##Id, read##Id, write##Id) \
NUT_INFO(__nut_FOREGION_KEY, name, type) \ NUT_INFO(__nut_FOREGION_KEY, name, type) \
type *m_##name; \ type *m_##name; \
public: \ public: \
type *read() const { return m_##name ; } \ type *read() const { return m_##name ; } \
void write(type *name){ \ void write(type *name){ \
m_##name = name; \ m_##name = name; \
} }
#define NUT_DECLARE_CHILD_TABLE(type, n) \ #define NUT_DECLARE_CHILD_TABLE(type, n) \
private: \ private: \
NUT_WRAP_NAMESPACE(TableSet)<type> *m_##n; \ NUT_WRAP_NAMESPACE(TableSet)<type> *m_##n; \
public: \ public: \
static type *n##Table(); \ static type *n##Table(); \
NUT_WRAP_NAMESPACE(TableSet)<type> *n(); NUT_WRAP_NAMESPACE(TableSet)<type> *n();
#define NUT_IMPLEMENT_CHILD_TABLE(class, type, n) \ #define NUT_IMPLEMENT_CHILD_TABLE(class, type, n) \
type *class::n##Table(){ \ type *class::n##Table(){ \
static type *f = new type(); \ static type *f = new type(); \
return f; \ return f; \
} \ } \
NUT_WRAP_NAMESPACE(TableSet)<type> *class::n(){ \ NUT_WRAP_NAMESPACE(TableSet)<type> *class::n(){ \
return m_##n; \ return m_##n; \
} }
#define NUT_PRIMARY_KEY(x) NUT_INFO(__nut_PRIMARY_KEY, x, 0) #define NUT_PRIMARY_KEY(x) NUT_INFO(__nut_PRIMARY_KEY, x, 0)
#define NUT_AUTO_INCREMENT(x) NUT_INFO(__nut_AUTO_INCREMENT, x, 0) #define NUT_AUTO_INCREMENT(x) NUT_INFO(__nut_AUTO_INCREMENT, x, 0)
#define NUT_PRIMARY_AUTO_INCREMENT(x) NUT_PRIMARY_KEY(x) \ #define NUT_PRIMARY_AUTO_INCREMENT(x) NUT_PRIMARY_KEY(x) \
NUT_AUTO_INCREMENT(x) NUT_AUTO_INCREMENT(x)
#define NUT_DISPLAY_NAME(field, name) NUT_INFO(__nut_DISPLAY, field, name) #define NUT_DISPLAY_NAME(field, name) NUT_INFO(__nut_DISPLAY, field, name)
#define NUT_UNIQUE(x) NUT_INFO(__nut_UNIQUE, x, 0) #define NUT_UNIQUE(x) NUT_INFO(__nut_UNIQUE, x, 0)

View File

@ -21,9 +21,10 @@
#ifndef DEFINES_P_H #ifndef DEFINES_P_H
#define DEFINES_P_H #define DEFINES_P_H
#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"

View File

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

View File

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

View File

@ -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())
@ -466,6 +567,7 @@ QString SqlGeneratorBase::selectCommand(const QString &tableName,
sql = sql.replace(_database->model().at(i)->className() + ".", sql = sql.replace(_database->model().at(i)->className() + ".",
_database->model().at(i)->name() + "."); _database->model().at(i)->name() + ".");
appendSkipTake(sql, skip, take);
replaceTableNames(sql); replaceTableNames(sql);
return sql + " "; return sql + " ";
@ -495,6 +597,7 @@ QString SqlGeneratorBase::selectCommand(const QString &tableName,
sql = sql.replace(_database->model().at(i)->className() + ".", sql = sql.replace(_database->model().at(i)->className() + ".",
_database->model().at(i)->name() + "."); _database->model().at(i)->name() + ".");
appendSkipTake(sql, skip, take);
replaceTableNames(sql); replaceTableNames(sql);
return sql + " "; return sql + " ";
@ -826,6 +929,12 @@ SqlGeneratorBase::operatorString(const PhraseData::Condition &cond) const
} }
} }
void SqlGeneratorBase::appendSkipTake(QString &sql, int skip, int take)
{
Q_UNUSED(sql);
Q_UNUSED(skip);
Q_UNUSED(take);
}
QString SqlGeneratorBase::createConditionalPhrase(const PhraseData *d) const QString SqlGeneratorBase::createConditionalPhrase(const PhraseData *d) const
{ {
@ -852,7 +961,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)

View File

@ -34,13 +34,14 @@ struct FieldModel;
class DatabaseModel; class DatabaseModel;
class TableModel; class TableModel;
class Database; class Database;
class RelationModel; struct RelationModel;
class SqlGeneratorBase : public QObject class SqlGeneratorBase : public QObject
{ {
// Q_OBJECT // Q_OBJECT
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,
@ -119,8 +124,8 @@ public:
virtual QVariant readValue(const QVariant::Type &type, const QVariant &dbValue); virtual QVariant readValue(const QVariant::Type &type, const QVariant &dbValue);
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);
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);

View File

@ -71,24 +71,12 @@ QString SqliteGenerator::fieldType(FieldModel *field)
return dbType; return dbType;
} }
//QString SqliteGenerator::selectCommand(SqlGeneratorBase::AgregateType t, void SqliteGenerator::appendSkipTake(QString &sql, int skip, int take)
// QString agregateArg, {
// QString tableName, if (take != -1 && skip != -1)
// QList<WherePhrase> &wheres, sql.append(QString(" LIMIT %1 OFFSET %2")
// QList<WherePhrase> &orders, .arg(take)
// QList<RelationModel*> joins, .arg(skip));
// int skip, int take) }
//{
// QString command = SqlGeneratorBase::selectCommand(t, agregateArg,
// tableName,
// wheres, orders,
// joins, skip, take);
// if (take != -1 && skip != -1)
// command.append(QString(" LIMIT %1 OFFSET %2")
// .arg(take)
// .arg(skip));
// return command;
//}
NUT_END_NAMESPACE NUT_END_NAMESPACE

View File

@ -29,15 +29,11 @@ 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);
// QString selectCommand(AgregateType t, QString agregateArg, void appendSkipTake(QString &sql, int skip, int take);
// QString tableName,
// QList<WherePhrase> &wheres,
// QList<WherePhrase> &orders,
// QList<RelationModel *> joins, int skip, int take);
}; };
NUT_END_NAMESPACE NUT_END_NAMESPACE

View File

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

View File

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

View File

@ -24,45 +24,72 @@
NUT_BEGIN_NAMESPACE 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), parents(1)
{ }
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),
left(0), right(0), operand(QVariant::Invalid), isNot(false) left(0), right(0), operand(QVariant::Invalid), isNot(false), parents(1)
{ } { }
PhraseData::PhraseData(PhraseData *l, PhraseData::Condition o) PhraseData::PhraseData(PhraseData *l, PhraseData::Condition o)
: className(0), fieldName(0), : className(0), fieldName(0),
type(WithoutOperand), operatorCond(o), left(new PhraseData(l)), right(0), isNot(false) type(WithoutOperand), operatorCond(o), left(l), right(0),
{ } isNot(false), parents(1)
{
l->parents++;
}
PhraseData::PhraseData(PhraseData *l, PhraseData::Condition o, PhraseData::PhraseData(PhraseData *l, PhraseData::Condition o,
const PhraseData *r) PhraseData *r)
: className(0), fieldName(0), : className(0), fieldName(0),
type(WithOther), operatorCond(o), left(new PhraseData(l)), right(new PhraseData(r)), isNot(false) type(WithOther), operatorCond(o),
{ } left(l), right(r),
isNot(false), parents(1)
{
l->parents++;
r->parents++;
}
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(l),
right(0), operand(r), isNot(false), parents(1)
{ } { }
PhraseData::PhraseData(const PhraseData *other) PhraseData *PhraseData::operator =(PhraseData *other)
{ {
left = other->left; LOG("");
right = other->right; other->parents++;
operand = other->operand; return other;
operatorCond = other->operatorCond;
className = other->className;
fieldName = other->fieldName;
type = other->type;
isNot = other->isNot;
if (type != Field) {
qDebug() << "Bug";
}
} }
PhraseData &PhraseData::operator =(PhraseData &other)
{
other.parents++;
return other;
}
//PhraseData::PhraseData(const PhraseData &other) :
// left(other.left), right(other.right), operand(other.operand),
// operatorCond(other.operatorCond), className(other.className),
// fieldName(other.fieldName), type(other.type), isNot(other.isNot),
// parents(other.parents + 1)
//{ }
//PhraseData::PhraseData(const PhraseData *other) :
// left(other->left), right(other->right), operand(other->operand),
// operatorCond(other->operatorCond), className(other->className),
// fieldName(other->fieldName), type(other->type), isNot(other->isNot),
// parents(other->parents + 1)
//{ }
QString PhraseData::toString() const QString PhraseData::toString() const
{ {
return QString("[%1].%2").arg(className).arg(fieldName); return QString("[%1].%2").arg(className).arg(fieldName);
@ -78,10 +105,34 @@ PhraseData::~PhraseData()
// if (left) // if (left)
// delete left; // delete left;
// } // }
// if (right && !--right->parents)
// delete right;
// if (left && !--left->parents)
// delete left;
LOG(""); LOG("");
} }
AbstractFieldPhrase::AbstractFieldPhrase(const char *className, const char *fieldName) void PhraseData::cleanUp()
{
// cleanUp(this);
}
void PhraseData::cleanUp(PhraseData *d)
{
if (d->left)
cleanUp(d->left);
if (d->right)
cleanUp(d->right);
}
AbstractFieldPhrase::AbstractFieldPhrase(PhraseData *d) : data(d)
{ }
AbstractFieldPhrase::AbstractFieldPhrase(const char *className,
const char *fieldName)
:data(new PhraseData(className, fieldName)) :data(new PhraseData(className, fieldName))
{ {
qDebug() <<"AbstractFieldPhrase created"<<className<<fieldName; qDebug() <<"AbstractFieldPhrase created"<<className<<fieldName;
@ -89,21 +140,30 @@ AbstractFieldPhrase::AbstractFieldPhrase(const char *className, const char *fiel
AbstractFieldPhrase::AbstractFieldPhrase(const AbstractFieldPhrase &other) AbstractFieldPhrase::AbstractFieldPhrase(const AbstractFieldPhrase &other)
{ {
qDebug() <<"4444444444444444"; data = other.data;
data = new PhraseData(other.data); data->parents++;
qDebug() <<"Copy ctor"<<other.data->toString()<<other.data->parents;
}
AbstractFieldPhrase::AbstractFieldPhrase(AbstractFieldPhrase &&other)
{
data = other.data;
data->parents++;
other.data = 0;
} }
AbstractFieldPhrase::~AbstractFieldPhrase() AbstractFieldPhrase::~AbstractFieldPhrase()
{ {
if (data) { if (data) {
LOG(data->toString()); LOG(data->toString()) << data->parents;
} else { } else {
LOG(""); LOG("");
} }
if (data) { if (data) {
delete data; --data->parents;
data = 0; if (data->parents <= 0)
delete data;
} }
} }
@ -118,9 +178,11 @@ ConditionalPhrase AbstractFieldPhrase::isNull()
} }
ConditionalPhrase AbstractFieldPhrase::operator ==(const ConditionalPhrase &other) ConditionalPhrase AbstractFieldPhrase::operator ==(const ConditionalPhrase
&other)
{ {
return ConditionalPhrase(this, PhraseData::Equal, const_cast<ConditionalPhrase&>(other)); return ConditionalPhrase(this, PhraseData::Equal,
const_cast<ConditionalPhrase&>(other));
} }
#define AbstractFieldPhraseOperatorVariant(class, op, cond) \ #define AbstractFieldPhraseOperatorVariant(class, op, cond) \
@ -147,9 +209,8 @@ AbstractFieldPhraseOperatorField(>=, PhraseData::GreaterEqual)
AbstractFieldPhrase AbstractFieldPhrase::operator !() AbstractFieldPhrase AbstractFieldPhrase::operator !()
{ {
//TODO: classname and s
AbstractFieldPhrase f(data->className, data->fieldName); AbstractFieldPhrase f(data->className, data->fieldName);
f.data = new PhraseData(data);
f.data->isNot = !data->isNot; f.data->isNot = !data->isNot;
return f; return f;
} }
@ -169,60 +230,113 @@ PhraseList::PhraseList() : isValid(false)
} }
PhraseList::PhraseList(const PhraseList &other) PhraseList::PhraseList(const PhraseList &other) : isValid(true)
{ {
LOG("");
data = qMove(other.data); data = qMove(other.data);
const_cast<PhraseList&>(other).data.clear();
}
PhraseList::PhraseList(PhraseList &&other)
{
LOG("");
data = other.data;
} }
PhraseList::PhraseList(const AbstractFieldPhrase &other) : isValid(true) PhraseList::PhraseList(const AbstractFieldPhrase &other) : isValid(true)
{ {
data.append(new PhraseData(other.data)); data.append(other.data);
incAllDataParents();
} }
PhraseList::PhraseList(const AbstractFieldPhrase *left, const AbstractFieldPhrase &right) PhraseList::PhraseList(const AbstractFieldPhrase *left,
const AbstractFieldPhrase &right)
: isValid(true) : isValid(true)
{ {
data.append(new PhraseData(left->data)); data.append(left->data);
data.append(new PhraseData(right.data)); data.append(right.data);
incAllDataParents();
} }
PhraseList::PhraseList(PhraseList *left, PhraseList *right) : isValid(true) PhraseList::PhraseList(PhraseList *left, PhraseList *right) : isValid(true)
{ {
data = qMove(left->data + right->data); // data = qMove(left->data + right->data);
data.append(left->data);
data.append(right->data);
// left->data.clear();
// right->data.clear();
} }
PhraseList::PhraseList(PhraseList *left, const AbstractFieldPhrase *right) PhraseList::PhraseList(PhraseList *left, const AbstractFieldPhrase *right)
: isValid(true) : isValid(true)
{ {
data = left->data; data.append(left->data);
data.append(new PhraseData(right->data)); data.append(right->data);
incAllDataParents();
} }
PhraseList::~PhraseList() PhraseList::~PhraseList()
{ {
// data.clear(); LOG("");
}
PhraseList &PhraseList::operator =(const PhraseList &other)
{
data.append(const_cast<PhraseList&>(other).data);
return *this;
} }
PhraseList PhraseList::operator |(const AbstractFieldPhrase &other) { PhraseList PhraseList::operator |(const AbstractFieldPhrase &other) {
return PhraseList(this, &other); return PhraseList(this, &other);
} }
void PhraseList::incAllDataParents()
{
// foreach (PhraseData *d, data)
// d->parents++;
}
PhraseList PhraseList::operator |(PhraseList &other) { 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)
{ {
d->parents++;
}
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;
} }
AssignmentPhrase::AssignmentPhrase(AbstractFieldPhrase *l, const AssignmentPhrase *r) AssignmentPhrase::AssignmentPhrase(AbstractFieldPhrase *l,
const AssignmentPhrase *r)
{ {
data = new PhraseData(l->data, PhraseData::Equal, r->data); data = new PhraseData(l->data, PhraseData::Equal, r->data);
// 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)
if (!--data->parents)
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,35 +348,70 @@ 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);
incAllDataParents();
} }
AssignmentPhraseList::AssignmentPhraseList(AssignmentPhraseList *l, const AssignmentPhrase *r) AssignmentPhraseList::AssignmentPhraseList(AssignmentPhraseList *l,
const AssignmentPhrase *r)
{ {
data.append(l->data); data.append(l->data);
data.append(r->data); data.append(r->data);
incAllDataParents();
} }
AssignmentPhraseList::AssignmentPhraseList(AssignmentPhrase *l, const AssignmentPhrase *r) AssignmentPhraseList::AssignmentPhraseList(AssignmentPhrase *l,
const AssignmentPhrase *r)
{ {
data.append(l->data); data.append(l->data);
data.append(r->data); data.append(r->data);
incAllDataParents();
} }
AssignmentPhraseList AssignmentPhraseList::operator &(const AssignmentPhrase &ph) AssignmentPhraseList::AssignmentPhraseList(const AssignmentPhrase &r,
const AssignmentPhrase &l)
{
data.append(l.data);
data.append(r.data);
incAllDataParents();
}
AssignmentPhraseList AssignmentPhraseList::operator &(const AssignmentPhrase
&ph)
{ {
return AssignmentPhraseList(this, &ph); return AssignmentPhraseList(this, &ph);
} }
AssignmentPhraseList::~AssignmentPhraseList()
{
foreach (PhraseData *d, data)
if (!--d->parents)
delete d;
// qDeleteAll(data);
// data.clear();
}
void AssignmentPhraseList::incAllDataParents()
{
foreach (PhraseData *d, data)
d->parents++;
}
ConditionalPhrase::ConditionalPhrase() : data(0) ConditionalPhrase::ConditionalPhrase() : data(0)
{ } { }
ConditionalPhrase::ConditionalPhrase(const ConditionalPhrase &other) ConditionalPhrase::ConditionalPhrase(const ConditionalPhrase &other)
{ {
qDebug() << "************* ctor called:"; qDebug() << "************* ctor called:";
this->data = new PhraseData(other.data); data = other.data;
data->parents++;
// const_cast<ConditionalPhrase&>(other).data = 0; // const_cast<ConditionalPhrase&>(other).data = 0;
} }
@ -276,7 +425,8 @@ ConditionalPhrase::ConditionalPhrase(const ConditionalPhrase &&other)
ConditionalPhrase::ConditionalPhrase(const PhraseData *data) ConditionalPhrase::ConditionalPhrase(const PhraseData *data)
{ {
this->data = new PhraseData(data); this->data = const_cast<PhraseData*>(data);
this->data->parents++;
} }
ConditionalPhrase::ConditionalPhrase(AbstractFieldPhrase *l, ConditionalPhrase::ConditionalPhrase(AbstractFieldPhrase *l,
@ -335,13 +485,17 @@ ConditionalPhrase::ConditionalPhrase(ConditionalPhrase *l,
ConditionalPhrase::~ConditionalPhrase() ConditionalPhrase::~ConditionalPhrase()
{ {
LOG(""); LOG("");
if (data) if (data) {
delete data; data->cleanUp();
if (!--data->parents)
delete data;
}
} }
ConditionalPhrase ConditionalPhrase::operator =(const ConditionalPhrase &other) ConditionalPhrase &ConditionalPhrase::operator =(const ConditionalPhrase &other)
{ {
this->data = new PhraseData(other.data); data = other.data;
data->parents++;
return *this; return *this;
} }
@ -350,22 +504,75 @@ 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 = l.data; \
p.data->right = r.data; \
l.data->parents++; \
r.data->parents++; \
return p; \
} \
ConditionalPhrase operator op(const 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->parents++; \
r.data->parents++; \
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; \
p.data->right = r.data; \
l.data->parents++; \
r.data->parents++; \
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->parents++; \
r.data->parents++; \
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 +581,63 @@ ConditionalPhrase ConditionalPhrase::operator !()
return f; return f;
} }
PhraseDataList::PhraseDataList() : QList<PhraseData*>()
{
}
PhraseDataList::PhraseDataList(const PhraseDataList &other) : QList<PhraseData*>()
{
PhraseDataList &o = const_cast<PhraseDataList&>(other);
PhraseDataList::iterator i;
for (i = o.begin(); i != o.end(); ++i)
append(*i);
}
void PhraseDataList::append(PhraseData *d)
{
d->parents++;
QList<PhraseData*>::append(d);
}
void PhraseDataList::append(QList<PhraseData *> &dl)
{
foreach (PhraseData *d, dl)
d->parents++;
QList<PhraseData*>::append(dl);
}
PhraseDataList::~PhraseDataList()
{
QList<PhraseData*>::iterator i;
for (i = begin(); i != end(); ++i) {
(*i)->cleanUp();
if (!--(*i)->parents)
delete *i;
}
}
//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

View File

@ -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,71 +91,111 @@ public:
const char *fieldName; const char *fieldName;
Type type; Type type;
Condition operatorCond;
const PhraseData *left; PhraseData *left;
const PhraseData *right; PhraseData *right;
QVariant operand; QVariant operand;
Condition operatorCond;
bool isNot; bool isNot;
quint16 parents;
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, PhraseData *r);
PhraseData(PhraseData *l, Condition o, QVariant r); PhraseData(PhraseData *l, Condition o, QVariant r);
// explicit PhraseData(const PhraseData &other);
// explicit PhraseData(const PhraseData *other);
PhraseData(const PhraseData *other); PhraseData *operator =(PhraseData *other);
PhraseData &operator =(PhraseData &other);
QString toString() const; QString toString() const;
~PhraseData(); ~PhraseData();
void cleanUp();
private:
void cleanUp(PhraseData *d);
};
class PhraseDataList : public QList<PhraseData*>
{
public:
PhraseDataList();
PhraseDataList(const PhraseDataList &other);
void append(PhraseData *d);
void append(QList<PhraseData*> &dl);
virtual ~PhraseDataList();
}; };
class AssignmentPhraseList 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();
private:
void incAllDataParents();
}; };
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; PhraseDataList data;
PhraseList(); explicit PhraseList();
PhraseList(const PhraseList &other); PhraseList(const PhraseList &other);
PhraseList(PhraseList &&other);
PhraseList(const AbstractFieldPhrase &other); PhraseList(const AbstractFieldPhrase &other);
PhraseList(const AbstractFieldPhrase *left, const AbstractFieldPhrase &right); PhraseList(const AbstractFieldPhrase *left, const AbstractFieldPhrase &right);
PhraseList(PhraseList *left, PhraseList *right); PhraseList(PhraseList *left, PhraseList *right);
PhraseList(PhraseList *left, const AbstractFieldPhrase *right); PhraseList(PhraseList *left, const AbstractFieldPhrase *right);
virtual ~PhraseList(); virtual ~PhraseList();
PhraseList &operator =(const PhraseList &other);
PhraseList operator |(PhraseList &other); PhraseList operator |(PhraseList &other);
PhraseList operator |(const AbstractFieldPhrase &other); PhraseList operator |(const AbstractFieldPhrase &other);
private:
void incAllDataParents();
}; };
class ConditionalPhrase class ConditionalPhrase
{ {
public: public:
PhraseData *data; PhraseData *data;
QSharedPointer<PhraseData> leftDataPointer; // QSharedPointer<PhraseData> leftDataPointer;
QSharedPointer<PhraseData> rightDataPointer; // QSharedPointer<PhraseData> rightDataPointer;
ConditionalPhrase(); ConditionalPhrase();
ConditionalPhrase(const ConditionalPhrase &other); ConditionalPhrase(const ConditionalPhrase &other);
#ifdef Q_COMPILER_RVALUE_REFS #ifdef Q_COMPILER_RVALUE_REFS
@ -171,11 +211,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,12 +224,24 @@ 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:
PhraseData *data; PhraseData *data;
explicit AbstractFieldPhrase(PhraseData *d);
AbstractFieldPhrase(const char *className, const char *fieldName); AbstractFieldPhrase(const char *className, const char *fieldName);
AbstractFieldPhrase(const AbstractFieldPhrase &other); AbstractFieldPhrase(const AbstractFieldPhrase &other);
AbstractFieldPhrase(AbstractFieldPhrase &&other);
virtual ~AbstractFieldPhrase(); virtual ~AbstractFieldPhrase();
@ -257,8 +309,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 +361,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
{ {

View File

@ -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)
{ {
} }

View File

@ -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
@ -73,9 +73,6 @@ public:
Query<T> *where(const ConditionalPhrase &ph); Query<T> *where(const ConditionalPhrase &ph);
Query<T> *setWhere(const ConditionalPhrase &ph); Query<T> *setWhere(const ConditionalPhrase &ph);
Query<T> *include(TableSetBase *t);
Query<T> *include(Table *t);
//data selecting //data selecting
T *first(); T *first();
QList<T*> toList(int count = -1); QList<T*> toList(int count = -1);
@ -124,8 +121,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>
@ -139,7 +136,7 @@ Q_OUTOFLINE_TEMPLATE QList<T *> Query<T>::toList(int count)
d->sql = d->database->sqlGenertor()->selectCommand( d->sql = d->database->sqlGenertor()->selectCommand(
d->tableName, d->fieldPhrase, d->wherePhrase, d->orderPhrase, d->tableName, d->fieldPhrase, d->wherePhrase, d->orderPhrase,
d->relations, d->skip, d->take); d->relations, d->skip, d->take);
qDebug() <<d->sql;
QSqlQuery q = d->database->exec(d->sql); QSqlQuery q = d->database->exec(d->sql);
if (q.lastError().isValid()) { if (q.lastError().isValid()) {
qDebug() << q.lastError().text(); qDebug() << q.lastError().text();
@ -419,8 +416,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;
} }
@ -496,20 +493,6 @@ Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::orderBy(const PhraseList &ph)
return this; return this;
} }
template <class T>
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::include(TableSetBase *t)
{
Q_D(Query);
return this;
}
template <class T>
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::include(Table *t)
{
Q_D(Query);
return this;
}
template <class T> template <class T>
Q_OUTOFLINE_TEMPLATE int Query<T>::update(const AssignmentPhraseList &ph) Q_OUTOFLINE_TEMPLATE int Query<T>::update(const AssignmentPhraseList &ph)
{ {

View File

@ -31,13 +31,13 @@ NUT_BEGIN_NAMESPACE
class Database; class Database;
class TableSetBase; class TableSetBase;
class QueryBase; class QueryBase;
class RelationModel; struct RelationModel;
class QueryPrivate{ class QueryPrivate{
QueryBase *q_ptr; QueryBase *q_ptr;
Q_DECLARE_PUBLIC(QueryBase) Q_DECLARE_PUBLIC(QueryBase)
public: public:
QueryPrivate(QueryBase *parent); explicit QueryPrivate(QueryBase *parent);
~QueryPrivate(); ~QueryPrivate();
QString sql; QString sql;

View File

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

View File

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

View File

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

View File

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

View File

@ -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,19 +310,31 @@ 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);
} }
TableModel::~TableModel()
{
qDeleteAll(_fields);
qDeleteAll(_foreignKeys);
}
QJsonObject TableModel::toJson() const 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 +350,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 +405,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

View File

@ -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,36 @@ 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;
}; };
class TableModel bool operator ==(const RelationModel &l, const RelationModel &r);
bool operator !=(const RelationModel &l, const RelationModel &r);
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); virtual ~TableModel();
QJsonObject toJson() const; QJsonObject toJson() const;
@ -91,7 +104,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 +136,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);

View File

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

View File

@ -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();

View File

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

View File

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

View File

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

View File

@ -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()
@ -187,7 +209,7 @@ void MainTest::testDate()
db.postTable()->append(newPost); db.postTable()->append(newPost);
db.saveChanges(); db.saveChanges(true);
auto q = db.postTable()->query() auto q = db.postTable()->query()
->setWhere(Post::idField() == newPost->id()) ->setWhere(Post::idField() == newPost->id())
@ -247,4 +269,13 @@ void MainTest::emptyDatabase()
QTEST_ASSERT(commentsCount == 6); QTEST_ASSERT(commentsCount == 6);
} }
void MainTest::cleanupTestCase()
{
post->deleteLater();
user->deleteLater();
qDeleteAll(TableModel::allModels());
DatabaseModel::deleteAllModels();
}
QTEST_MAIN(MainTest) QTEST_MAIN(MainTest)

View File

@ -27,16 +27,20 @@ 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();
void emptyDatabase(); void emptyDatabase();
void cleanupTestCase();
}; };
#endif // MAINTEST_H #endif // MAINTEST_H

View File

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