This commit is contained in:
Hamed Masafi 2018-01-11 13:06:48 +03:30
parent 1713a237eb
commit dc71ce1270
9 changed files with 145 additions and 99 deletions

View File

@ -33,15 +33,15 @@
#endif
#define NUT_INFO(type, name, value) \
Q_CLASSINFO(__nut_NAME_PERFIX #type #name #value, #value)
Q_CLASSINFO(__nut_NAME_PERFIX #type #name #value, #type "\n" #name "\n" #value)
// Database
//TODO: remove minor version
#define NUT_DB_VERSION(version) \
Q_CLASSINFO(QT_STRINGIFY(__nut_NAME_PERFIX __nut_DB_VERSION), #version)
NUT_INFO(__nut_DB_VERSION, version, 0)
#define NUT_DECLARE_TABLE(type, name) \
Q_CLASSINFO(QT_STRINGIFY(__nut_NAME_PERFIX __nut_TABLE " " #type), #name) \
NUT_INFO(__nut_TABLE, type, name) \
Q_PROPERTY(type* name READ name) \
Q_PROPERTY(NUT_WRAP_NAMESPACE(TableSet<type>) name##s READ name##s) \
type* m_##name; \
@ -54,7 +54,7 @@ public: \
//Table
#define NUT_DECLARE_FIELD(type, name, read, write) \
Q_PROPERTY(type name READ read WRITE write) \
Q_CLASSINFO(QT_STRINGIFY(__nut_NAME_PERFIX #name " " __nut_FIELD), #name) \
NUT_INFO(__nut_FIELD, name, 0) \
type m_##name; \
public: \
static NUT_WRAP_NAMESPACE(FieldPhrase<type>) name ## Field(){ \
@ -72,7 +72,7 @@ public: \
#define NUT_FOREGION_KEY(type, keytype, name, read, write) \
Q_PROPERTY(type* name READ read WRITE write) \
NUT_DECLARE_FIELD(keytype, name##Id, read##Id, write##Id) \
Q_CLASSINFO(QT_STRINGIFY(__nut_NAME_PERFIX #name "Id " __nut_FOREGION_KEY), #type) \
NUT_INFO(__nut_FOREGION_KEY, name, type) \
type *m_##name; \
public: \
type *read() const { return m_##name ; } \
@ -97,14 +97,14 @@ public: \
}
#define NUT_PRIMARY_KEY(x) Q_CLASSINFO(QT_STRINGIFY(__nut_NAME_PERFIX #x " " __nut_PRIMARY_KEY), #x)
#define NUT_AUTO_INCREMENT(x) Q_CLASSINFO(QT_STRINGIFY(__nut_NAME_PERFIX #x " " __nut_AUTO_INCREMENT), #x)
#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_PRIMARY_AUTO_INCREMENT(x) NUT_PRIMARY_KEY(x) \
NUT_AUTO_INCREMENT(x)
#define NUT_UNIQUE(x) Q_CLASSINFO(QT_STRINGIFY(__nut_NAME_PERFIX #x " " __nut_UNIQUE), #x)
#define NUT_LEN(field, len) Q_CLASSINFO(QT_STRINGIFY(__nut_NAME_PERFIX #field " " __nut_LEN), #len)
#define NUT_DEFAULT_VALUE(x, n) Q_CLASSINFO(QT_STRINGIFY(__nut_NAME_PERFIX #x " " __nut_DEFAULT_VALUE), #n)
#define NUT_NOT_NULL(x) Q_CLASSINFO(QT_STRINGIFY(__nut_NAME_PERFIX #x " " __nut_NOT_NULL), "1")
#define NUT_UNIQUE(x) NUT_INFO(__nut_UNIQUE, x, 0)
#define NUT_LEN(field, len) NUT_INFO(__nut_LEN, field, len)
#define NUT_DEFAULT_VALUE(x, n) NUT_INFO(__nut_DEFAULT_VALUE, x, n)
#define NUT_NOT_NULL(x) NUT_INFO(__nut_NOT_NULL, x, 1)
#define NUT_INDEX(name, field, order)
#endif // SYNTAX_DEFINES_H

View File

@ -377,22 +377,12 @@ QString SqlGeneratorBase::deleteRecords(QString tableName, QString where)
return sql;
}
QString SqlGeneratorBase::selectCommand(SqlGeneratorBase::AgregateType t,
QString agregateArg,
QList<WherePhrase> &wheres,
QList<WherePhrase> &orders,
QStringList joins, int skip, int take)
{
return selectCommand(t, agregateArg, wheres, orders, joins, skip, take);
}
QString SqlGeneratorBase::selectCommand(SqlGeneratorBase::AgregateType t,
QString agregateArg,
QList<WherePhrase> &wheres,
QList<WherePhrase> &orders,
QStringList joins,
int skip, int take,
QStringList *order)
int skip, int take)
{
Q_UNUSED(take);
Q_UNUSED(skip);
@ -402,8 +392,6 @@ QString SqlGeneratorBase::selectCommand(SqlGeneratorBase::AgregateType t,
QString from = join(joins, &joinedOrders);
QString where = createWhere(wheres);
QString orderText = joinedOrders.join(", ");
if (order != Q_NULLPTR)
order = joinedOrders;
foreach (WherePhrase p, orders) {
if (orderText != "")

View File

@ -83,13 +83,6 @@ public:
QList<WherePhrase> &orders,
QStringList joins,
int skip = -1, int take = -1);
virtual QString selectCommand(AgregateType t,
QString agregateArg,
QList<WherePhrase> &wheres,
QList<WherePhrase> &orders,
QStringList joins,
int skip = -1, int take = -1,
QStringList *order = Q_NULLPTR);
virtual QString deleteCommand(QList<WherePhrase> &wheres, QString tableName);

View File

@ -104,6 +104,7 @@ Q_OUTOFLINE_TEMPLATE Query<T>::Query(Database *database, TableSetBase *tableSet,
d->database = database;
d->tableSet = tableSet;
d->className = T::staticMetaObject.className();
d->tableName
= // TableModel::findByClassName(T::staticMetaObject.className())->name();
d->database->model()
@ -125,22 +126,76 @@ Q_OUTOFLINE_TEMPLATE QList<T *> Query<T>::toList(int count)
QList<T*> result;
d->select = "*";
d->joins.prepend(d->tableName);
d->joins.prepend(d->className);
qDebug() << "JOINS="<< d->joins;
qDebug() << "JOINS="<< d->database->sqlGenertor()->join(d->joins);
// QSqlQuery q =
// d->database->exec(d->database->sqlGenertor()->selectCommand(d->wheres,
// d->orders, d->tableName, d->joinClassName));
QStringList orders;
d->sql = d->database->sqlGenertor()->selectCommand(
SqlGeneratorBase::SelectAll, "", d->wheres, d->orderPhrases,
d->joins, d->skip, d->take, &orders);
d->joins, d->skip, d->take);
QSqlQuery q = d->database->exec(d->sql);
while (q.next()) {
struct LevelData{
QString key;
QString className;
QVariant keyValue;
int typeId;
TableSetBase *tableSet;
Table *lastRow;
};
QVector<LevelData> levels;
foreach (QString className, d->joins) {
LevelData data;
data.className = className;
TableModel *m = d->database->model().tableByClassName(className);
if (!m)
qFatal("Model '%s' not found!!!", qPrintable(className));
data.key = m->primaryKey();
data.typeId = m->typeId();
data.keyValue = QVariant();
data.tableSet = 0;
levels.append(data);
}
QList<T*> returnList;
while (q.next()) {
for (int i = 0; i < levels.count(); i++) {
LevelData &data = levels[i];
if (!data.tableSet || data.keyValue != q.value(data.key)) {
//create table row
Table *childTable;
if (data.className == d->className) {
childTable = new T();
returnList.append(dynamic_cast<T*>(childTable));
} else {
const QMetaObject *childMetaObject
= QMetaType::metaObjectForType(data.typeId);
childTable = qobject_cast<Table *>(childMetaObject->newInstance());
}
QStringList childFields
= d->database->model().tableByClassName(data.className)->fieldsNames();
foreach (QString field, childFields)
childTable->setProperty(field.toLatin1().data(), q.value(field));
//set last created row
data.lastRow = childTable;
if (i < levels.count() - 1) {
QSet<TableSetBase *> tableSets = childTable->tableSets;
foreach (TableSetBase *ts, tableSets)
if (ts->childClassName() == levels[i + 1].className)
data.tableSet = ts;
}
if (i)
childTable->setTableSet(levels[i - 1].tableSet);
}
}
}
if (m_autoDelete)
deleteLater();
return returnList;
/*
QString pk = d->database->model().tableByName(d->tableName)->primaryKey();
QVariant lastPkValue = QVariant();
int childTypeId = 0;
@ -173,15 +228,6 @@ Q_OUTOFLINE_TEMPLATE QList<T *> Query<T>::toList(int count)
T *t = new T();
foreach (QString field, masterFields)
t->setProperty(field.toLatin1().data(), q.value(field));
// for (int i = 0; i < t->metaObject()->propertyCount();
// i++) {
// const QMetaProperty p =
// t->metaObject()->property(i);
// p.write(t,
// d->database->sqlGenertor()->readValue(p.type(),
// q.value(p.name())));
// }
t->setTableSet(d->tableSet);
t->setStatus(Table::FeatchedFromDB);
@ -226,6 +272,7 @@ Q_OUTOFLINE_TEMPLATE QList<T *> Query<T>::toList(int count)
if (m_autoDelete)
deleteLater();
return result;
*/
}
template <typename T>

View File

@ -41,6 +41,7 @@ public:
~QueryPrivate();
QString sql;
QString className;
QString tableName;
QString select;
Database *database;

View File

@ -22,6 +22,7 @@
#include <QVariant>
#include "table.h"
#include "database.h"
#include "databasemodel.h"
#include "generators/sqlgeneratorbase_p.h"
NUT_BEGIN_NAMESPACE
@ -130,6 +131,7 @@ int Table::save(Database *db)
{
QSqlQuery q = db->exec(db->sqlGenertor()->saveRecord(this, db->tableName(metaObject()->className())));
if(status() == Added && isPrimaryKeyAutoIncrement())
setProperty(primaryKey().toLatin1().data(), q.lastInsertId());

View File

@ -144,6 +144,23 @@ bool TableModel::operator !=(const TableModel &t) const
return !(*this == t);
}
bool TableModel::checkClassInfo(const QMetaClassInfo &classInfo, QString type, QString name, QString value)
{
if (!QString(classInfo.name()).startsWith(__nut_NAME_PERFIX)) {
return false;
} else {
QStringList parts = QString(classInfo.value()).split("\n");
if (parts.count() != 3)
return false;
type = parts[0];
name = parts[1];
value = parts[2];
qDebug() << Q_FUNC_INFO << parts;
return true;
}
}
TableModel::TableModel(int typeId, QString tableName)
{
//TODO: check that
@ -163,20 +180,19 @@ TableModel::TableModel(int typeId, QString tableName)
// get fields names
for(int j = 0; j < tableMetaObject->classInfoCount(); j++){
QString name = tableMetaObject->classInfo(j).name();
name = name.replace("\"", "");
QString type;
QString name;
QString value;
name = name.remove(__nut_NAME_PERFIX);
if(name.contains(" ")){
QStringList parts = name.split(" ");
QString propName = parts.at(1);
if(propName == __nut_FIELD){
FieldModel *f = new FieldModel;
f->name = parts.at(0);
_fields.append(f);
if (!checkClassInfo(tableMetaObject->classInfo(j),
type, name, value)) {
continue;
}
if(type == __nut_FIELD){
FieldModel *f = new FieldModel;
f->name = name;
_fields.append(f);
}
}
// Browse all fields
@ -195,48 +211,46 @@ TableModel::TableModel(int typeId, QString tableName)
// Browse class infos
for(int j = 0; j < tableMetaObject->classInfoCount(); j++){
QString name = tableMetaObject->classInfo(j).name();
QString value = tableMetaObject->classInfo(j).value();
QString type;
QString name;
QString value;
name = name.replace("\"", "").remove(__nut_NAME_PERFIX);
value = value.replace("\"", "");
if (!checkClassInfo(tableMetaObject->classInfo(j),
type, name, value)) {
continue;
}
if(name.contains(" ")){
QStringList parts = name.split(" ");
QString propName = parts.at(1);
if(propName == __nut_FOREGION_KEY){
if(type == __nut_FOREGION_KEY){
RelationModel *fk = new RelationModel;
fk->localColumn = parts.at(0);
fk->localColumn = name;
fk->foregionColumn = value;
fk->className = value;
_foregionKeys.append(fk);
qDebug() << "REL="<<parts<<value<<fk;
}
if(propName == __nut_FIELD){
if(type == __nut_FIELD){
}
FieldModel *f = field(parts.at(0));
FieldModel *f = field(name);
if(!f)
continue;
if(propName == __nut_LEN)
if(type == __nut_LEN)
f->length = value.toInt();
else if(propName == __nut_NOT_NULL)
else if(type == __nut_NOT_NULL)
f->notNull = true;
else if(propName == __nut_DEFAULT_VALUE)
else if(type == __nut_DEFAULT_VALUE)
f->defaultValue = value;
else if(propName == __nut_PRIMARY_KEY)
else if(type == __nut_PRIMARY_KEY)
f->isPrimaryKey = true;
else if(propName == __nut_AUTO_INCREMENT)
else if(type == __nut_AUTO_INCREMENT)
f->isAutoIncrement = true;
else if(propName == __nut_UNIQUE)
else if(type == __nut_UNIQUE)
f->isUnique = true;
}
}
if(!findByTypeId(typeId) && !tableName.isNull())

View File

@ -117,6 +117,7 @@ private:
QList<FieldModel*> _fields;
QList<RelationModel*> _foregionKeys;
static QSet<TableModel*>_allModels;
bool checkClassInfo(const QMetaClassInfo &classInfo, QString type, QString name, QString value);
};
NUT_END_NAMESPACE

View File

@ -13,7 +13,7 @@ class MainTest : public QObject
WeblogDatabase db;
int postId;
Post *post;
User *User;
User *user;
public:
explicit MainTest(QObject *parent = 0);