Revision 3b82c8c0
Von Christian Ehringfeld vor mehr als 9 Jahren hinzugefügt
| src/entityhelper.cpp | ||
|---|---|---|
|
const QHash<Relation, QMetaProperty> EntityHelper::getRelationProperties(
|
||
|
const Entity *entity) {
|
||
|
auto h = QHash<Relation, QMetaProperty>();
|
||
|
auto relations = entity->getRelations();
|
||
|
for (int var = 0; var < entity->metaObject()->propertyCount(); ++var) {
|
||
|
QMetaProperty m = entity->metaObject()->property(var);
|
||
|
if (m.isValid() && relations.contains(QString(m.name()))) {
|
||
|
h.insert(relations.value(m.name()), m);
|
||
|
if(entity) {
|
||
|
auto relations = entity->getRelations();
|
||
|
for (int var = 0; var < entity->metaObject()->propertyCount(); ++var) {
|
||
|
QMetaProperty m = entity->metaObject()->property(var);
|
||
|
if (m.isValid() && relations.contains(QString(m.name()))) {
|
||
|
h.insert(relations.value(m.name()), m);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return h;
|
||
| src/entitymanager.cpp | ||
|---|---|---|
|
QList<QSharedPointer<Entity>> EntityManager::findEntityByAttributes(
|
||
|
const QSharedPointer<Entity>
|
||
|
&entity,
|
||
|
bool ignoreID) {
|
||
|
bool ignoreID, const bool refresh, const bool resolveRelations) {
|
||
|
auto maps = this->findAllByAttributes(entity, ignoreID);
|
||
|
return this->convert(maps, EntityHelper::getClassname(entity.data()));
|
||
|
return this->convert(maps, EntityHelper::getClassname(entity.data()), refresh,
|
||
|
resolveRelations);
|
||
|
}
|
||
|
|
||
|
QHash<QString, QVariant> EntityManager::findByPk(qint64 id,
|
||
| ... | ... | |
|
}
|
||
|
|
||
|
quint32 EntityManager::count(const QSharedPointer<Entity> &entity, bool ignoreID,
|
||
|
bool followInheritance) {
|
||
|
bool followInheritance) {
|
||
|
Query q = Query();
|
||
|
auto qb = this->schema->getQueryBuilder();
|
||
|
QHash<QString, QVariant> values;
|
||
| src/entitymanager.h | ||
|---|---|---|
|
QSharedPointer<Entity> findById(const qint64 &id, const QString &classname);
|
||
|
QList<QSharedPointer<Entity>> findEntityByAttributes(const
|
||
|
QSharedPointer<Entity> &entity,
|
||
|
bool ignoreID = false);
|
||
|
bool ignoreID = false, const bool refresh = false, const bool resolveRelations = true);
|
||
|
qint64 findId(QSharedPointer<Entity> &entity);
|
||
|
/**
|
||
|
* @todo should be an insert statement with many values
|
||
| ... | ... | |
|
bool createTable(QString className, bool createRelationTables = true);
|
||
|
bool removeTable(QString className);
|
||
|
quint32 count(const QSharedPointer<Entity> &entity, bool ignoreID = true,
|
||
|
bool followInheritance = false);
|
||
|
bool followInheritance = false);
|
||
|
quint32 count(const QString &tableName);
|
||
|
QSharedPointer<Database> getDb() const;
|
||
|
void setDb(const QSharedPointer<Database> &value);
|
||
| ... | ... | |
|
QSharedPointer<QueryBuilder> getQueryBuilder() const;
|
||
|
|
||
|
template<class T> QList<QSharedPointer<T>> find(Query &q,
|
||
|
const bool joinBaseClasses = false, const bool resolveRelations = true) {
|
||
|
const bool joinBaseClasses = false, const bool resolveRelations = true,
|
||
|
const bool refresh = false) {
|
||
|
QSharedPointer<Entity> ptr = QSharedPointer<Entity>
|
||
|
(EntityInstanceFactory::createInstance<T *>());
|
||
|
if (ptr) {
|
||
| ... | ... | |
|
QSqlQuery query = this->queryInterpreter->build(q);
|
||
|
auto maps = this->convertQueryResult(query);
|
||
|
auto converted = this->convert(maps, EntityHelper::getClassname(ptr.data()),
|
||
|
false,
|
||
|
refresh,
|
||
|
resolveRelations);
|
||
|
return EntityManager::convertList<T>(converted);
|
||
|
}
|
||
| ... | ... | |
|
}
|
||
|
|
||
|
template<class T> QList<QSharedPointer<T>> findAll(const bool resolveRelations =
|
||
|
true) {
|
||
|
true, const bool refresh = false) {
|
||
|
QSharedPointer<Entity> ptr = QSharedPointer<Entity>
|
||
|
(EntityInstanceFactory::createInstance<T *>());
|
||
|
if (ptr) {
|
||
|
auto maps = this->findAll(ptr);
|
||
|
auto converted = this->convert(maps, EntityHelper::getClassname(ptr.data()),
|
||
|
false,
|
||
|
refresh,
|
||
|
resolveRelations);
|
||
|
return EntityManager::convertList<T>(converted);
|
||
|
}
|
||
|
return QList<QSharedPointer<T>>();
|
||
|
}
|
||
|
|
||
|
template<class T> QSharedPointer<T> findById(const qint64 &id) {
|
||
|
template<class T> QSharedPointer<T> findById(const qint64 &id,
|
||
|
const bool refresh = false) {
|
||
|
auto e = EntityInstanceFactory::createInstance<T *>();
|
||
|
QSharedPointer<Entity> ptr = QSharedPointer<Entity>(e);
|
||
|
return this->findById(id, ptr).objectCast<T>();
|
||
|
return this->findById(id, ptr, refresh).objectCast<T>();
|
||
|
}
|
||
|
|
||
|
template<class T>
|
||
|
QSharedPointer<T> findEntityByAttributes(
|
||
|
const QHash<QString, QVariant>
|
||
|
&attributes, const bool joinBaseClasses = false,
|
||
|
const bool resolveRelations = true) {
|
||
|
const bool resolveRelations = true, const bool refresh) {
|
||
|
auto list = this->findAllEntitiesByAttributes<T>(attributes, 1, 0,
|
||
|
joinBaseClasses, resolveRelations);
|
||
|
joinBaseClasses, resolveRelations, refresh);
|
||
|
if (list.isEmpty()) {
|
||
|
return QSharedPointer<T>();
|
||
|
}
|
||
| ... | ... | |
|
template<class T> QList<QSharedPointer<T>> findAllEntitiesByAttributes(
|
||
|
const QHash<QString, QVariant> &attributes =
|
||
|
QHash<QString, QVariant>(), quint64 limit = 0, quint64 offset = 0,
|
||
|
bool joinBaseClasses = false, const bool resolveRelations = true) {
|
||
|
bool joinBaseClasses = false, const bool resolveRelations = true,
|
||
|
const bool refresh = false) {
|
||
|
QSharedPointer<Entity> e = QSharedPointer<Entity>
|
||
|
(EntityInstanceFactory::createInstance<T*>());
|
||
|
if (e) {
|
||
| ... | ... | |
|
query.setOffset(offset);
|
||
|
QSqlQuery q = this->queryInterpreter->build(query);
|
||
|
auto results = this->convertQueryResult(q);
|
||
|
auto list = this->convert(results, EntityHelper::getClassname(e.data()), false,
|
||
|
auto list = this->convert(results, EntityHelper::getClassname(e.data()), refresh,
|
||
|
resolveRelations);
|
||
|
return EntityManager::convertList<T>(list);
|
||
|
}
|
||
| ... | ... | |
|
return newList;
|
||
|
}
|
||
|
|
||
|
protected:
|
||
|
protected:
|
||
|
bool saveObject(QSharedPointer<Entity> &entity, QList<Entity *> &mergedObjects,
|
||
|
const bool persistRelations = true,
|
||
|
const bool ignoreHasChanged = false, const bool validate = true,
|
||
| ... | ... | |
|
QHash<QString, QVariant> findByPk(qint64 id, const QSharedPointer<Entity> &e);
|
||
|
void manyToOne(const QSharedPointer<Entity> &entity, const QVariant &id,
|
||
|
Attribute *&attr, const bool refresh = false);
|
||
|
void oneToMany(const QSharedPointer<Entity> &entity, Attribute *&attr, const bool refresh = false);
|
||
|
void oneToMany(const QSharedPointer<Entity> &entity, Attribute *&attr,
|
||
|
const bool refresh = false);
|
||
|
void manyToMany(const QSharedPointer<Entity> &entity, Attribute *&attr,
|
||
|
const bool refresh = false);
|
||
|
void oneToOne(const QSharedPointer<Entity> &entity, Attribute *&attr, const bool refresh = false,
|
||
|
void oneToOne(const QSharedPointer<Entity> &entity, Attribute *&attr,
|
||
|
const bool refresh = false,
|
||
|
const QVariant &id = "");
|
||
|
void persistManyToMany(const QSharedPointer<Entity> &entity, const Relation &r,
|
||
|
QVariant &property, QList<Entity *> &mergedObjects,
|
||
| src/expression.cpp | ||
|---|---|---|
|
|
||
|
Expression::Expression(QString expression, QHash<QString, QVariant> params,
|
||
|
bool onlyColumn) {
|
||
|
for(auto i = params.begin(); i != params.end(); ++i) {
|
||
|
expression.replace(":" + i.key(),":" + this->generateParam());
|
||
|
this->appendParam(i.key(),i.value());
|
||
|
}
|
||
|
this->expression = expression;
|
||
|
this->params = params;
|
||
|
this->onlyColumn = onlyColumn;
|
||
|
}
|
||
|
|
||
|
Expression::Expression(QString expression, QString key, QVariant value, bool onlyColumn) {
|
||
|
this->expression = expression.replace(":" + key, ":" + this->generateParam());
|
||
|
this->appendParam(key, value);
|
||
|
this->onlyColumn = onlyColumn;
|
||
|
}
|
||
|
|
||
| ... | ... | |
|
onlyColumn = value;
|
||
|
}
|
||
|
|
||
|
QString Expression::generateParam() {
|
||
|
return (QString("emP") + QString::number(this->params.size() + 1));
|
||
|
}
|
||
|
|
||
|
void Expression::appendParam(QString key, const QVariant &value) {
|
||
|
this->params.insert(this->generateParam(), value);
|
||
|
this->params.insert(key.replace('.','_'), value);
|
||
|
}
|
||
|
|
||
| src/expression.h | ||
|---|---|---|
|
explicit Expression(QString expression,
|
||
|
QHash<QString, QVariant> params = QHash<QString, QVariant>(),
|
||
|
bool onlyColumn = false);
|
||
|
explicit Expression(QString expression,QString key,QVariant value,
|
||
|
bool onlyColumn = false);
|
||
|
explicit Expression(QString expression, bool onlyColumn);
|
||
|
QString getExpression() const;
|
||
|
void setExpression(const QString &value);
|
||
| ... | ... | |
|
bool getOnlyColumn() const;
|
||
|
void setOnlyColumn(bool value);
|
||
|
|
||
|
QString generateParam();
|
||
|
void appendParam(QString key, const QVariant &value);
|
||
|
QHash<QString, QVariant> getParams() const;
|
||
|
void setParams(const QHash<QString, QVariant> &value);
|
||
| src/querybuilder.cpp | ||
|---|---|---|
|
}
|
||
|
|
||
|
QString QueryBuilder::placeHolder(QString key) const {
|
||
|
return QString(":" + key.replace('.', '_'));
|
||
|
//return QString(":" + key.replace('.', '_'));
|
||
|
return QString(":" + key);
|
||
|
}
|
||
|
|
||
|
QString QueryBuilder::where(const QHash<QString, QVariant> &m,
|
||
| ... | ... | |
|
}
|
||
|
|
||
|
Expression QueryBuilder::equal(QString &key, QVariant &value) {
|
||
|
Expression exp = Expression(this->where(key, value, false, true, false));
|
||
|
exp.appendParam(key, value);
|
||
|
Expression exp = Expression(this->where(key, value, false, true, false),key,value);
|
||
|
return exp;
|
||
|
}
|
||
|
|
||
| src/queryinterpreter.cpp | ||
|---|---|---|
|
sqlCondition += this->builder->getSeparator();
|
||
|
}
|
||
|
}
|
||
|
auto params = exp.getParams();
|
||
|
for (auto i = params.begin(); i != params.end(); ++i) {
|
||
|
QString key = this->generateParam(q);
|
||
|
expression.replace(":" + i.key(), ":" + key);
|
||
|
q.appendParam(key, i.value());
|
||
|
}
|
||
|
sqlCondition += expression;
|
||
|
q.appendParams(exp.getParams());
|
||
|
}
|
||
|
return sqlCondition;
|
||
|
}
|
||
|
|
||
|
QString QueryInterpreter::generateParam(Query &q) const {
|
||
|
return "eP" + QString::number(q.getParams().size() + 1);
|
||
|
}
|
||
| src/queryinterpreter.h | ||
|---|---|---|
|
const quint64 &limit, const quint64 &offset) const;
|
||
|
QString buildOrderBy(const QList<OrderBy> &columns) const;
|
||
|
QString buildCondition(Query &q, const QList<Expression> &conditions) const;
|
||
|
QString generateParam(Query &q) const;
|
||
|
|
||
|
private:
|
||
|
QueryBuilder *builder;
|
||
| src/src.pro | ||
|---|---|---|
|
android: {
|
||
|
include($$[QT_INSTALL_PREFIX]/../Src/qtbase/src/3rdparty/sqlite.pri)
|
||
|
}
|
||
|
unix!android: {
|
||
|
unix:!android: {
|
||
|
system-sqlite:!contains(LIBS, .*sqlite3.*) {
|
||
|
include($$[QT_INSTALL_PREFIX]/../Src/qtbase/src/3rdparty/sqlite.pri)
|
||
|
} else {
|
||
| tests/em/tst_querybuilder.cpp | ||
|---|---|---|
|
QSharedPointer<Person> p = this->e->findEntityByAttributes<Person>(attributes, true);
|
||
|
QVERIFY(p);
|
||
|
attributes.clear();
|
||
|
attributes["leader"] = QVariant(p);
|
||
|
QVariant var;
|
||
|
var.setValue<QSharedPointer<Person>>(p);
|
||
|
attributes["leader"] = var;
|
||
|
QSharedPointer<Group> group = e->findEntityByAttributes<Group>
|
||
|
(attributes, true);
|
||
|
QVERIFY(group);
|
||
| ... | ... | |
|
QVERIFY(p);
|
||
|
QCOMPARE(p->getFamilyName(), QString("Zero"));
|
||
|
attributes.clear();
|
||
|
attributes["persons"] = QVariant(p);
|
||
|
QVariant var;
|
||
|
var.setValue<QSharedPointer<Person>>(p);
|
||
|
attributes["persons"] = var;
|
||
|
QSharedPointer<Group> group = e->findEntityByAttributes<Group>
|
||
|
(attributes, true);
|
||
|
QVERIFY(group);
|
||
| ... | ... | |
|
QCOMPARE(list.at(0)->getFamilyName(), QString("Mes."));
|
||
|
}
|
||
|
|
||
|
void QuerybuilderTest::testQueryBuilderSingleAttributeOr() {
|
||
|
auto qb = e->getQueryBuilder();
|
||
|
Query q = Query();
|
||
|
q.appendWhere(q.equal(qb, "nickName", QString("Lotta")));
|
||
|
q.appendWhere(q.orOperator(qb));
|
||
|
q.appendWhere(q.equal(qb, "nickName", QString("Fenni")));
|
||
|
QList<QSharedPointer<Person>> list = e->find<Person>(q, true);
|
||
|
QCOMPARE(list.size(), 2);
|
||
|
}
|
||
|
|
||
|
void QuerybuilderTest::testQueryBuilderManyToOneRelation() {
|
||
|
auto qb = e->getQueryBuilder();
|
||
|
Query q = Query();
|
||
| tests/em/tst_querybuilder.h | ||
|---|---|---|
|
void testQueryBuilderEntityInheritanceWithoutJoin();
|
||
|
void testQueryBuilderArbitraryOperator();
|
||
|
void testQueryBuilderJoins();
|
||
|
void testQueryBuilderSingleAttributeOr();
|
||
|
void testQueryBuilderManyToOneRelation();
|
||
|
void testQueryBuilderManyToOneRelationAttribute();
|
||
|
void testQueryBuilderManyToManyRelation();
|
||
Auch abrufbar als: Unified diff
some improvements