wip: join

This commit is contained in:
Hamed Masafi 2017-09-10 18:48:20 +04:30
parent c4f0c30b0f
commit 8601167e7e
16 changed files with 107 additions and 52 deletions

View File

@ -305,16 +305,12 @@ void DatabasePrivate::createChangeLogs()
Database::Database(QObject *parent) Database::Database(QObject *parent)
: QObject(parent), d_ptr(new DatabasePrivate(this)) : QObject(parent), d_ptr(new DatabasePrivate(this))
{ {
Q_D(Database);
// d->changeLogs->sett
DatabasePrivate::lastId++; DatabasePrivate::lastId++;
} }
Database::Database(const Database &other, QObject *parent) Database::Database(const Database &other, QObject *parent)
: QObject(parent), d_ptr(new DatabasePrivate(this)) : QObject(parent), d_ptr(new DatabasePrivate(this))
{ {
Q_D(Database);
DatabasePrivate::lastId++; DatabasePrivate::lastId++;
setDriver(other.driver()); setDriver(other.driver());
@ -392,7 +388,6 @@ DatabaseModel Database::model() const
QString Database::tableName(QString className) QString Database::tableName(QString className)
{ {
Q_D(Database);
TableModel *m = model().tableByClassName(className); TableModel *m = model().tableByClassName(className);
if (m) if (m)
return m->name(); return m->name();
@ -514,20 +509,23 @@ QSqlQuery Database::exec(QString sql)
void Database::add(TableSetBase *t) 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; int rowsAffected = 0;
foreach (TableSetBase *ts, tableSets) foreach (TableSetBase *ts, d->tableSets)
rowsAffected += ts->save(this); rowsAffected += ts->save(this, cleanUp);
return rowsAffected; return rowsAffected;
} }
void Database::cleanUp() void Database::cleanUp()
{ {
foreach (TableSetBase *ts, tableSets) Q_D(Database);
foreach (TableSetBase *ts, d->tableSets)
ts->clearChilds(); ts->clearChilds();
} }

View File

@ -53,9 +53,7 @@ public:
QSqlQuery exec(QString sql); QSqlQuery exec(QString sql);
//TODO: make me private and rename me int saveChanges(bool cleanUp = false);
void add(TableSetBase *);
int saveChanges();
void cleanUp(); void cleanUp();
QString databaseName() const; QString databaseName() const;
@ -86,8 +84,9 @@ public slots:
void setDriver(QString driver); void setDriver(QString driver);
private: private:
//TODO: move me to database_p.h void add(TableSetBase *);
QSet<TableSetBase *> tableSets;
friend class TableSetBase;
}; };
NUT_END_NAMESPACE NUT_END_NAMESPACE

View File

@ -37,7 +37,6 @@ class DatabasePrivate
public: public:
DatabasePrivate(Database *parent); DatabasePrivate(Database *parent);
bool open(bool updateDatabase); bool open(bool updateDatabase);
bool updateDatabase(); bool updateDatabase();
@ -56,7 +55,6 @@ public:
QString connectionName; QString connectionName;
QString driver; QString driver;
SqlGeneratorBase *sqlGenertor; SqlGeneratorBase *sqlGenertor;
DatabaseModel currentModel; DatabaseModel currentModel;
@ -66,6 +64,8 @@ public:
QHash<QString, QString> tables; QHash<QString, QString> tables;
static QMap<QString, DatabaseModel> allTableMaps; static QMap<QString, DatabaseModel> allTableMaps;
static int lastId; static int lastId;
QSet<TableSetBase *> tableSets;
}; };
NUT_END_NAMESPACE NUT_END_NAMESPACE

View File

@ -120,6 +120,7 @@ QVariant MySqlGenerator::readValue(const QVariant::Type &type, const QVariant &d
if (type == QVariant::PointF) { if (type == QVariant::PointF) {
qDebug() << "QVariant::PointF" << dbValue; qDebug() << "QVariant::PointF" << dbValue;
} }
return SqlGeneratorBase::readValue(type, dbValue);
} }
QString MySqlGenerator::phrase(const PhraseData *d) const QString MySqlGenerator::phrase(const PhraseData *d) const

View File

@ -95,7 +95,7 @@ QString PostgreSqlGenerator::fieldType(FieldModel *field)
dbType = ""; dbType = "";
} }
if(field->type == QMetaType::type("Nut::DbGeography")) if(field->type == (unsigned)QMetaType::type("Nut::DbGeography"))
dbType = "GEOGRAPHY"; dbType = "GEOGRAPHY";
return dbType; return dbType;

View File

@ -64,6 +64,8 @@ public:
Query<T> *skip(int &n); Query<T> *skip(int &n);
Query<T> *take(int &n); Query<T> *take(int &n);
Query<T> *orderBy(WherePhrase phrase); Query<T> *orderBy(WherePhrase phrase);
Query<T> *include(TableSetBase *t);
Query<T> *include(Table *t);
int count(); int count();
QVariant max(FieldPhrase<int> &f); QVariant max(FieldPhrase<int> &f);
@ -355,6 +357,22 @@ Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::orderBy(WherePhrase phrase)
return this; return this;
} }
template <class T>
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::include(TableSetBase *t)
{
Q_D(Query);
d->joinClassName = t->childClassName();
return this;
}
template <class T>
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::include(Table *t)
{
Q_D(Query);
d->joinClassName = t->metaObject()->className();
return this;
}
template <class T> template <class T>
Q_OUTOFLINE_TEMPLATE int Query<T>::update(WherePhrase phrase) Q_OUTOFLINE_TEMPLATE int Query<T>::update(WherePhrase phrase)
{ {

View File

@ -27,6 +27,7 @@
NUT_BEGIN_NAMESPACE NUT_BEGIN_NAMESPACE
//TODO: remove this class
class QueryBase : public QObject class QueryBase : public QObject
{ {
Q_OBJECT Q_OBJECT

View File

@ -187,7 +187,7 @@ QString SqlGeneratorBase::insertRecord(Table *t, QString tableName)
.arg(changedPropertiesText) .arg(changedPropertiesText)
.arg(values.join(", ")); .arg(values.join(", "));
replaceTableNames(sql); removeTableNames(sql);
return sql; return sql;
} }
@ -208,7 +208,7 @@ QString SqlGeneratorBase::updateRecord(Table *t, QString tableName)
.arg(key) .arg(key)
.arg(t->primaryValue().toString()); .arg(t->primaryValue().toString());
replaceTableNames(sql); removeTableNames(sql);
return sql; return sql;
} }
@ -309,6 +309,9 @@ QString SqlGeneratorBase::selectCommand(SqlGeneratorBase::AgregateType t,
QString tableName, QString tableName,
QString joinClassName, int skip, int take) QString joinClassName, int skip, int take)
{ {
Q_UNUSED(take);
Q_UNUSED(skip);
QString select = agregateText(t, agregateArg); QString select = agregateText(t, agregateArg);
QString where = createWhere(wheres); QString where = createWhere(wheres);
QString order = ""; QString order = "";
@ -354,7 +357,13 @@ QString SqlGeneratorBase::createWhere(QList<WherePhrase> &wheres)
void SqlGeneratorBase::replaceTableNames(QString &command) void SqlGeneratorBase::replaceTableNames(QString &command)
{ {
foreach (TableModel *m, TableModel::allModels()) 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<WherePhrase> &wheres, QString SqlGeneratorBase::deleteCommand(QList<WherePhrase> &wheres,
@ -391,11 +400,19 @@ QString SqlGeneratorBase::updateCommand(WherePhrase &phrase,
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() + ".");
replaceTableNames(sql); removeTableNames(sql);
return 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 QString SqlGeneratorBase::escapeValue(const QVariant &v) const
{ {
switch (v.type()) { switch (v.type()) {
@ -441,13 +458,16 @@ QString SqlGeneratorBase::escapeValue(const QVariant &v) const
case QVariant::Invalid: case QVariant::Invalid:
qFatal("Invalud field value"); qFatal("Invalud field value");
return "<FAIL>"; return "<FAIL>";
default:
return "";
} }
return "";
} }
QVariant SqlGeneratorBase::readValue(const QVariant::Type &type, QVariant SqlGeneratorBase::readValue(const QVariant::Type &type,
const QVariant &dbValue) const QVariant &dbValue)
{ {
Q_UNUSED(type);
return dbValue; return dbValue;
} }
@ -601,9 +621,10 @@ SqlGeneratorBase::operatorString(const PhraseData::Condition &cond) const
case PhraseData::Append: case PhraseData::Append:
return ","; return ",";
}
return QString("<FAIL>"); default:
return QString("<FAIL>");
}
} }
NUT_END_NAMESPACE NUT_END_NAMESPACE

View File

@ -88,6 +88,8 @@ public:
virtual QString updateCommand(WherePhrase &phrase, QList<WherePhrase> &wheres, QString tableName); virtual QString updateCommand(WherePhrase &phrase, QList<WherePhrase> &wheres, QString tableName);
virtual QString joinTables(QStringList tables);
virtual QString escapeValue(const QVariant &v) const; virtual QString escapeValue(const QVariant &v) const;
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;
@ -100,6 +102,7 @@ private:
QString createWhere(QList<WherePhrase> &wheres); QString createWhere(QList<WherePhrase> &wheres);
QString phraseOrder(const PhraseData *d) const; QString phraseOrder(const PhraseData *d) const;
void replaceTableNames(QString &command); void replaceTableNames(QString &command);
void removeTableNames(QString &command);
}; };
NUT_END_NAMESPACE NUT_END_NAMESPACE

View File

@ -48,7 +48,6 @@ public:
Deleted Deleted
}; };
void add(TableSetBase *);
int save(Database *db); int save(Database *db);
QString primaryKey() const; QString primaryKey() const;
@ -77,9 +76,12 @@ private:
QSet<TableSetBase*> tableSets; QSet<TableSetBase*> tableSets;
void clear(); void clear();
void add(TableSetBase *);
template<class T> template<class T>
friend class Query; friend class Query;
friend class TableSetBase;
}; };
NUT_END_NAMESPACE NUT_END_NAMESPACE

View File

@ -38,6 +38,7 @@ struct FieldModel{
} }
QString name; QString name;
//TODO: QMetaType::Type??
QVariant::Type type; QVariant::Type type;
QString typeName; QString typeName;
int length; int length;

View File

@ -35,7 +35,7 @@ TableSetBase::TableSetBase(Table *parent) : QObject(parent), _database(0), _tabl
parent->add(this); parent->add(this);
} }
int TableSetBase::save(Database *db) int TableSetBase::save(Database *db, bool cleanUp)
{ {
int rowsAffected = 0; int rowsAffected = 0;
foreach (Table *t, _tablesList) { foreach (Table *t, _tablesList) {
@ -46,16 +46,23 @@ int TableSetBase::save(Database *db)
|| t->status() == Table::Modified || t->status() == Table::Modified
|| t->status() == Table::Deleted){ || t->status() == Table::Deleted){
rowsAffected += t->save(db); rowsAffected += t->save(db);
if(cleanUp)
t->deleteLater();
} }
} }
if (cleanUp)
_tablesList.clear();
return rowsAffected; return rowsAffected;
} }
void TableSetBase::clearChilds() void TableSetBase::clearChilds()
{ {
foreach (Table *t, _tablesList) foreach (Table *t, _tablesList)
delete t; t->deleteLater();
_tablesList.clear();
} }
void TableSetBase::add(Table *t) void TableSetBase::add(Table *t)

View File

@ -38,7 +38,7 @@ public:
TableSetBase(Database *parent); TableSetBase(Database *parent);
TableSetBase(Table *parent); TableSetBase(Table *parent);
virtual int save(Database *db); virtual int save(Database *db, bool cleanUp = false);
void clearChilds(); void clearChilds();
void add(Table* t); void add(Table* t);
QString childClassName() const; QString childClassName() const;

View File

@ -26,12 +26,15 @@ void MainTest::initTestCase()
db.setDriver(DRIVER); db.setDriver(DRIVER);
db.setHostName(HOST); db.setHostName(HOST);
db.setDatabaseName(DATABASE); db.setDatabaseName("nut_tst_basic");
db.setUserName(USERNAME); db.setUserName(USERNAME);
db.setPassword(PASSWORD); db.setPassword(PASSWORD);
bool ok = db.open(); bool ok = db.open();
db.comments()->query()->remove();
db.posts()->query()->remove();
QTEST_ASSERT(ok); QTEST_ASSERT(ok);
} }
@ -116,10 +119,17 @@ void MainTest::selectPostsWithoutTitle()
auto q = db.posts()->query(); auto q = db.posts()->query();
q->setWhere(Post::titleField().isNull()); q->setWhere(Post::titleField().isNull());
auto count = q->count(); auto count = q->count();
qDebug() << "selectPostsWithoutTitle, count=" << count; qDebug() << q->sqlCommand();
QTEST_ASSERT(count == 0); QTEST_ASSERT(count == 0);
} }
void MainTest::selectPostIds()
{
auto ids = db.posts()->query()->select(Post::idField());
QTEST_ASSERT(ids.count() == 2);
}
void MainTest::testDate() void MainTest::testDate()
{ {
QDateTime d = QDateTime::currentDateTime(); QDateTime d = QDateTime::currentDateTime();
@ -177,18 +187,11 @@ void MainTest::modifyPost()
void MainTest::emptyDatabase() void MainTest::emptyDatabase()
{ {
auto count = db.posts()->query() auto commentsCount = db.comments()->query()->remove();
->setWhere(Post::idField() == postId) auto postsCount = db.posts()->query()->remove();
->remove();
QTEST_ASSERT(count == 1); QTEST_ASSERT(postsCount == 3);
QTEST_ASSERT(commentsCount == 6);
count = db.posts()->query()
->setWhere(Post::idField() == postId)
->count();
QTEST_ASSERT(count == 0);
} }
QTEST_MAIN(MainTest) QTEST_MAIN(MainTest)

View File

@ -25,6 +25,7 @@ private slots:
void createPost2(); void createPost2();
void selectPosts(); void selectPosts();
void selectPostsWithoutTitle(); void selectPostsWithoutTitle();
void selectPostIds();
void testDate(); void testDate();
void selectWithInvalidRelation(); void selectWithInvalidRelation();
void select10NewstPosts(); void select10NewstPosts();

View File

@ -1,17 +1,17 @@
#ifndef CONSTS_H #ifndef CONSTS_H
#define CONSTS_H #define CONSTS_H
#define DRIVER "QPSQL" //#define DRIVER "QPSQL"
#define HOST "127.0.0.1"
#define DATABASE "nutdb2"
#define USERNAME "postgres"
#define PASSWORD "856856"
//#define DRIVER "QMYSQL"
//#define HOST "127.0.0.1" //#define HOST "127.0.0.1"
//#define DATABASE "nutdb" //#define DATABASE "nutdb2"
//#define USERNAME "root" //#define USERNAME "postgres"
//#define PASSWORD "onlyonlyi" //#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 DRIVER "QODBC"
//#define HOST "127.0.0.1" //#define HOST "127.0.0.1"