wip: join
This commit is contained in:
parent
c4f0c30b0f
commit
8601167e7e
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<TableSetBase *> tableSets;
|
||||
void add(TableSetBase *);
|
||||
|
||||
friend class TableSetBase;
|
||||
};
|
||||
|
||||
NUT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -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<QString, QString> tables;
|
||||
static QMap<QString, DatabaseModel> allTableMaps;
|
||||
static int lastId;
|
||||
|
||||
QSet<TableSetBase *> tableSets;
|
||||
};
|
||||
|
||||
NUT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
18
src/query.h
18
src/query.h
|
|
@ -64,6 +64,8 @@ public:
|
|||
Query<T> *skip(int &n);
|
||||
Query<T> *take(int &n);
|
||||
Query<T> *orderBy(WherePhrase phrase);
|
||||
Query<T> *include(TableSetBase *t);
|
||||
Query<T> *include(Table *t);
|
||||
|
||||
int count();
|
||||
QVariant max(FieldPhrase<int> &f);
|
||||
|
|
@ -355,6 +357,22 @@ Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::orderBy(WherePhrase phrase)
|
|||
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>
|
||||
Q_OUTOFLINE_TEMPLATE int Query<T>::update(WherePhrase phrase)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
NUT_BEGIN_NAMESPACE
|
||||
|
||||
//TODO: remove this class
|
||||
class QueryBase : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
|
|
|||
|
|
@ -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<WherePhrase> &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<WherePhrase> &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 "<FAIL>";
|
||||
|
||||
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("<FAIL>");
|
||||
default:
|
||||
return QString("<FAIL>");
|
||||
}
|
||||
}
|
||||
|
||||
NUT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -88,6 +88,8 @@ public:
|
|||
|
||||
virtual QString updateCommand(WherePhrase &phrase, QList<WherePhrase> &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<WherePhrase> &wheres);
|
||||
QString phraseOrder(const PhraseData *d) const;
|
||||
void replaceTableNames(QString &command);
|
||||
void removeTableNames(QString &command);
|
||||
};
|
||||
|
||||
NUT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@ public:
|
|||
Deleted
|
||||
};
|
||||
|
||||
void add(TableSetBase *);
|
||||
int save(Database *db);
|
||||
|
||||
QString primaryKey() const;
|
||||
|
|
@ -77,9 +76,12 @@ private:
|
|||
|
||||
QSet<TableSetBase*> tableSets;
|
||||
void clear();
|
||||
void add(TableSetBase *);
|
||||
|
||||
template<class T>
|
||||
friend class Query;
|
||||
|
||||
friend class TableSetBase;
|
||||
};
|
||||
|
||||
NUT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ struct FieldModel{
|
|||
}
|
||||
|
||||
QString name;
|
||||
//TODO: QMetaType::Type??
|
||||
QVariant::Type type;
|
||||
QString typeName;
|
||||
int length;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ private slots:
|
|||
void createPost2();
|
||||
void selectPosts();
|
||||
void selectPostsWithoutTitle();
|
||||
void selectPostIds();
|
||||
void testDate();
|
||||
void selectWithInvalidRelation();
|
||||
void select10NewstPosts();
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Reference in New Issue