diff --git a/src/database.cpp b/src/database.cpp index ca189a3..5abe025 100644 --- a/src/database.cpp +++ b/src/database.cpp @@ -305,16 +305,12 @@ void DatabasePrivate::createChangeLogs() Database::Database(QObject *parent) : QObject(parent), d_ptr(new DatabasePrivate(this)) { - Q_D(Database); - // d->changeLogs->sett DatabasePrivate::lastId++; } Database::Database(const Database &other, QObject *parent) : QObject(parent), d_ptr(new DatabasePrivate(this)) { - Q_D(Database); - DatabasePrivate::lastId++; setDriver(other.driver()); @@ -392,7 +388,6 @@ DatabaseModel Database::model() const QString Database::tableName(QString className) { - Q_D(Database); TableModel *m = model().tableByClassName(className); if (m) return m->name(); @@ -514,20 +509,23 @@ QSqlQuery Database::exec(QString sql) void Database::add(TableSetBase *t) { - tableSets.insert(t); + Q_D(Database); + d->tableSets.insert(t); } -int Database::saveChanges() +int Database::saveChanges(bool cleanUp) { + Q_D(Database); int rowsAffected = 0; - foreach (TableSetBase *ts, tableSets) - rowsAffected += ts->save(this); + foreach (TableSetBase *ts, d->tableSets) + rowsAffected += ts->save(this, cleanUp); return rowsAffected; } void Database::cleanUp() { - foreach (TableSetBase *ts, tableSets) + Q_D(Database); + foreach (TableSetBase *ts, d->tableSets) ts->clearChilds(); } diff --git a/src/database.h b/src/database.h index 705daed..4166e69 100644 --- a/src/database.h +++ b/src/database.h @@ -53,9 +53,7 @@ public: QSqlQuery exec(QString sql); - //TODO: make me private and rename me - void add(TableSetBase *); - int saveChanges(); + int saveChanges(bool cleanUp = false); void cleanUp(); QString databaseName() const; @@ -86,8 +84,9 @@ public slots: void setDriver(QString driver); private: - //TODO: move me to database_p.h - QSet tableSets; + void add(TableSetBase *); + + friend class TableSetBase; }; NUT_END_NAMESPACE diff --git a/src/database_p.h b/src/database_p.h index ac01411..33c4b05 100644 --- a/src/database_p.h +++ b/src/database_p.h @@ -37,7 +37,6 @@ class DatabasePrivate public: DatabasePrivate(Database *parent); - bool open(bool updateDatabase); bool updateDatabase(); @@ -56,7 +55,6 @@ public: QString connectionName; QString driver; - SqlGeneratorBase *sqlGenertor; DatabaseModel currentModel; @@ -66,6 +64,8 @@ public: QHash tables; static QMap allTableMaps; static int lastId; + + QSet tableSets; }; NUT_END_NAMESPACE diff --git a/src/mysqlgenerator.cpp b/src/mysqlgenerator.cpp index 44f6fb9..f2d4c1a 100644 --- a/src/mysqlgenerator.cpp +++ b/src/mysqlgenerator.cpp @@ -120,6 +120,7 @@ QVariant MySqlGenerator::readValue(const QVariant::Type &type, const QVariant &d if (type == QVariant::PointF) { qDebug() << "QVariant::PointF" << dbValue; } + return SqlGeneratorBase::readValue(type, dbValue); } QString MySqlGenerator::phrase(const PhraseData *d) const diff --git a/src/postgresqlgenerator.cpp b/src/postgresqlgenerator.cpp index b0eb3d0..0ff4b46 100644 --- a/src/postgresqlgenerator.cpp +++ b/src/postgresqlgenerator.cpp @@ -95,7 +95,7 @@ QString PostgreSqlGenerator::fieldType(FieldModel *field) dbType = ""; } - if(field->type == QMetaType::type("Nut::DbGeography")) + if(field->type == (unsigned)QMetaType::type("Nut::DbGeography")) dbType = "GEOGRAPHY"; return dbType; diff --git a/src/query.h b/src/query.h index 937f90e..a14b845 100644 --- a/src/query.h +++ b/src/query.h @@ -64,6 +64,8 @@ public: Query *skip(int &n); Query *take(int &n); Query *orderBy(WherePhrase phrase); + Query *include(TableSetBase *t); + Query *include(Table *t); int count(); QVariant max(FieldPhrase &f); @@ -355,6 +357,22 @@ Q_OUTOFLINE_TEMPLATE Query *Query::orderBy(WherePhrase phrase) return this; } +template +Q_OUTOFLINE_TEMPLATE Query *Query::include(TableSetBase *t) +{ + Q_D(Query); + d->joinClassName = t->childClassName(); + return this; +} + +template +Q_OUTOFLINE_TEMPLATE Query *Query::include(Table *t) +{ + Q_D(Query); + d->joinClassName = t->metaObject()->className(); + return this; +} + template Q_OUTOFLINE_TEMPLATE int Query::update(WherePhrase phrase) { diff --git a/src/querybase_p.h b/src/querybase_p.h index 087c714..c5f370d 100644 --- a/src/querybase_p.h +++ b/src/querybase_p.h @@ -27,6 +27,7 @@ NUT_BEGIN_NAMESPACE +//TODO: remove this class class QueryBase : public QObject { Q_OBJECT diff --git a/src/sqlgeneratorbase.cpp b/src/sqlgeneratorbase.cpp index 43c1f02..4876d0f 100644 --- a/src/sqlgeneratorbase.cpp +++ b/src/sqlgeneratorbase.cpp @@ -187,7 +187,7 @@ QString SqlGeneratorBase::insertRecord(Table *t, QString tableName) .arg(changedPropertiesText) .arg(values.join(", ")); - replaceTableNames(sql); + removeTableNames(sql); return sql; } @@ -208,7 +208,7 @@ QString SqlGeneratorBase::updateRecord(Table *t, QString tableName) .arg(key) .arg(t->primaryValue().toString()); - replaceTableNames(sql); + removeTableNames(sql); return sql; } @@ -309,6 +309,9 @@ QString SqlGeneratorBase::selectCommand(SqlGeneratorBase::AgregateType t, QString tableName, QString joinClassName, int skip, int take) { + Q_UNUSED(take); + Q_UNUSED(skip); + QString select = agregateText(t, agregateArg); QString where = createWhere(wheres); QString order = ""; @@ -354,7 +357,13 @@ QString SqlGeneratorBase::createWhere(QList &wheres) void SqlGeneratorBase::replaceTableNames(QString &command) { foreach (TableModel *m, TableModel::allModels()) - command = command.replace("[" + m->className() + "].", m->name() + "."); + command = command.replace("[" + m->className() + "].", "`" + m->name() + "`."); +} + +void SqlGeneratorBase::removeTableNames(QString &command) +{ + foreach (TableModel *m, TableModel::allModels()) + command = command.replace("[" + m->className() + "].", ""); } QString SqlGeneratorBase::deleteCommand(QList &wheres, @@ -391,11 +400,19 @@ QString SqlGeneratorBase::updateCommand(WherePhrase &phrase, sql = sql.replace(_database->model().at(i)->className() + ".", _database->model().at(i)->name() + "."); - replaceTableNames(sql); + removeTableNames(sql); return sql; } +QString SqlGeneratorBase::joinTables(QStringList tables) +{ + Q_UNUSED(tables); + //TODO: implement me +// _database->model().relationByClassNames() + return ""; +} + QString SqlGeneratorBase::escapeValue(const QVariant &v) const { switch (v.type()) { @@ -441,13 +458,16 @@ QString SqlGeneratorBase::escapeValue(const QVariant &v) const case QVariant::Invalid: qFatal("Invalud field value"); return ""; + + default: + return ""; } - return ""; } QVariant SqlGeneratorBase::readValue(const QVariant::Type &type, const QVariant &dbValue) { + Q_UNUSED(type); return dbValue; } @@ -601,9 +621,10 @@ SqlGeneratorBase::operatorString(const PhraseData::Condition &cond) const case PhraseData::Append: return ","; - } - return QString(""); + default: + return QString(""); + } } NUT_END_NAMESPACE diff --git a/src/sqlgeneratorbase_p.h b/src/sqlgeneratorbase_p.h index 3aba191..9714948 100644 --- a/src/sqlgeneratorbase_p.h +++ b/src/sqlgeneratorbase_p.h @@ -88,6 +88,8 @@ public: virtual QString updateCommand(WherePhrase &phrase, QList &wheres, QString tableName); + virtual QString joinTables(QStringList tables); + virtual QString escapeValue(const QVariant &v) const; virtual QVariant readValue(const QVariant::Type &type, const QVariant &dbValue); virtual QString phrase(const PhraseData *d) const; @@ -100,6 +102,7 @@ private: QString createWhere(QList &wheres); QString phraseOrder(const PhraseData *d) const; void replaceTableNames(QString &command); + void removeTableNames(QString &command); }; NUT_END_NAMESPACE diff --git a/src/table.h b/src/table.h index 8e369f3..da9f8cb 100644 --- a/src/table.h +++ b/src/table.h @@ -48,7 +48,6 @@ public: Deleted }; - void add(TableSetBase *); int save(Database *db); QString primaryKey() const; @@ -77,9 +76,12 @@ private: QSet tableSets; void clear(); + void add(TableSetBase *); template friend class Query; + + friend class TableSetBase; }; NUT_END_NAMESPACE diff --git a/src/tablemodel.h b/src/tablemodel.h index 3e2b9c6..700032e 100644 --- a/src/tablemodel.h +++ b/src/tablemodel.h @@ -38,6 +38,7 @@ struct FieldModel{ } QString name; + //TODO: QMetaType::Type?? QVariant::Type type; QString typeName; int length; diff --git a/src/tablesetbase.cpp b/src/tablesetbase.cpp index e9bc7f5..1891885 100644 --- a/src/tablesetbase.cpp +++ b/src/tablesetbase.cpp @@ -35,7 +35,7 @@ TableSetBase::TableSetBase(Table *parent) : QObject(parent), _database(0), _tabl parent->add(this); } -int TableSetBase::save(Database *db) +int TableSetBase::save(Database *db, bool cleanUp) { int rowsAffected = 0; foreach (Table *t, _tablesList) { @@ -46,16 +46,23 @@ int TableSetBase::save(Database *db) || t->status() == Table::Modified || t->status() == Table::Deleted){ rowsAffected += t->save(db); + + if(cleanUp) + t->deleteLater(); } } + if (cleanUp) + _tablesList.clear(); + return rowsAffected; } void TableSetBase::clearChilds() { foreach (Table *t, _tablesList) - delete t; + t->deleteLater(); + _tablesList.clear(); } void TableSetBase::add(Table *t) diff --git a/src/tablesetbase_p.h b/src/tablesetbase_p.h index 50dd5a6..68f7df0 100644 --- a/src/tablesetbase_p.h +++ b/src/tablesetbase_p.h @@ -38,7 +38,7 @@ public: TableSetBase(Database *parent); TableSetBase(Table *parent); - virtual int save(Database *db); + virtual int save(Database *db, bool cleanUp = false); void clearChilds(); void add(Table* t); QString childClassName() const; diff --git a/test/basic/maintest.cpp b/test/basic/maintest.cpp index 7bb0b6d..5365825 100644 --- a/test/basic/maintest.cpp +++ b/test/basic/maintest.cpp @@ -26,12 +26,15 @@ void MainTest::initTestCase() db.setDriver(DRIVER); db.setHostName(HOST); - db.setDatabaseName(DATABASE); + db.setDatabaseName("nut_tst_basic"); db.setUserName(USERNAME); db.setPassword(PASSWORD); bool ok = db.open(); + db.comments()->query()->remove(); + db.posts()->query()->remove(); + QTEST_ASSERT(ok); } @@ -116,10 +119,17 @@ void MainTest::selectPostsWithoutTitle() auto q = db.posts()->query(); q->setWhere(Post::titleField().isNull()); auto count = q->count(); - qDebug() << "selectPostsWithoutTitle, count=" << count; + qDebug() << q->sqlCommand(); QTEST_ASSERT(count == 0); } +void MainTest::selectPostIds() +{ + auto ids = db.posts()->query()->select(Post::idField()); + + QTEST_ASSERT(ids.count() == 2); +} + void MainTest::testDate() { QDateTime d = QDateTime::currentDateTime(); @@ -177,18 +187,11 @@ void MainTest::modifyPost() void MainTest::emptyDatabase() { - auto count = db.posts()->query() - ->setWhere(Post::idField() == postId) - ->remove(); + auto commentsCount = db.comments()->query()->remove(); + auto postsCount = db.posts()->query()->remove(); - QTEST_ASSERT(count == 1); - - count = db.posts()->query() - ->setWhere(Post::idField() == postId) - ->count(); - - QTEST_ASSERT(count == 0); + QTEST_ASSERT(postsCount == 3); + QTEST_ASSERT(commentsCount == 6); } - QTEST_MAIN(MainTest) diff --git a/test/basic/maintest.h b/test/basic/maintest.h index 7689640..2d55666 100644 --- a/test/basic/maintest.h +++ b/test/basic/maintest.h @@ -25,6 +25,7 @@ private slots: void createPost2(); void selectPosts(); void selectPostsWithoutTitle(); + void selectPostIds(); void testDate(); void selectWithInvalidRelation(); void select10NewstPosts(); diff --git a/test/common/consts.h b/test/common/consts.h index 96cb683..9475fa9 100644 --- a/test/common/consts.h +++ b/test/common/consts.h @@ -1,17 +1,17 @@ #ifndef CONSTS_H #define CONSTS_H -#define DRIVER "QPSQL" -#define HOST "127.0.0.1" -#define DATABASE "nutdb2" -#define USERNAME "postgres" -#define PASSWORD "856856" - -//#define DRIVER "QMYSQL" +//#define DRIVER "QPSQL" //#define HOST "127.0.0.1" -//#define DATABASE "nutdb" -//#define USERNAME "root" -//#define PASSWORD "onlyonlyi" +//#define DATABASE "nutdb2" +//#define USERNAME "postgres" +//#define PASSWORD "856856" + +#define DRIVER "QMYSQL" +#define HOST "127.0.0.1" +#define DATABASE "nutdb" +#define USERNAME "root" +#define PASSWORD "onlyonlyi" //#define DRIVER "QODBC" //#define HOST "127.0.0.1"