Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision dbd41a3a

Von Christian Ehringfeld vor mehr als 8 Jahren hinzugefügt

  • ID dbd41a3a0674608cf6da011a58efb8a53f06a2f0
  • Vorgänger 46d2de48
  • Nachfolger 686d9ffe

...

Unterschiede anzeigen:

.travis.yml
- CONFIG=Debug
install:
- if [ "${TRAVIS_OS_NAME}" = "linux" ]; then
sudo apt-add-repository -y ppa:ubuntu-toolchain-r/test
&& sudo apt-add-repository -y ppa:beineri/opt-qt541
&& sudo apt-get -qq update
&& sudo apt-get -qq install gcc-5 libc6-i386 qt54tools qt54svg qt54webkit
&& export CXX="g++-5"
&& export CC="gcc-5"
&& export QMAKE=/usr/lib/x86_64-linux-gnu/qt5/bin/qmake
;
else
brew update
&& brew unlink cmake
&& brew install cmake
&& brew install qt5
&& chmod -R 755 /usr/local/opt/qt5/*
;
fi
- sudo add-apt-repository -y ppa:ubuntu-sdk-team/ppa &&
sudo apt-get update &&
sudo apt-get install qtbase5-dev libqt5sql5-mysql libqt5sql5-sqlite &&
sudo apt-get install lcov odbcinst libmyodbc odbc-postgresql
script:
- QMAKE
appveyor.yml
# http://www.appveyor.com/docs/build-configuration
os: unstable
configuration:
- debug
- release
install:
- set QTDIR=C:\Qt\5.4\mingw491_32
- set QTDIR=C:\Qt\5.5\mingw482_32
- set PATH=%PATH%;%QTDIR%\bin;C:\MinGW\bin
# - set RELEASE_PATH=appveyor\release
build_script:
# using a header file without MemoryBarrier, that causes the build to fail
- qmake EntityManager.pro
# - qmake QOwnNotes.pro -r -spec win32-g++ "CONFIG+=debug"
- mingw32-make -j8
# creating the release path
# - md ..\%RELEASE_PATH%
src/attributeresolver.cpp
#include "attributeresolver.h"
#include "entityhelper.h"
#include "querybuilder.h"
#include <QDebug>
using namespace CuteEntityManager;
AttributeResolver::AttributeResolver(QSharedPointer<QueryBuilder> queryBuilder) {
this->qb = queryBuilder;
}
AttributeResolver::~AttributeResolver() {
this->qb = QSharedPointer<QueryBuilder>(nullptr);
if(!this->attributes.isEmpty()) {
QMutableHashIterator<QString, QHash<QString, Attribute*>> i(this->attributes);
while(i.hasNext()) {
i.next();
auto embeddedHash = i.value();
QMutableHashIterator<QString, Attribute*> i2(embeddedHash);
while(i2.hasNext()) {
i2.next();
auto attr = i2.value();
delete attr;
i2.remove();
}
i.remove();
}
}
}
QHash<QString, QHash<QString, Attribute *>> AttributeResolver::getAttributes() const {
return attributes;
}
void AttributeResolver::setAttributes(const QHash<QString, QHash<QString, Attribute*>>
&value) {
attributes = value;
}
Attribute *AttributeResolver::resolveManyToManyAttribute(const QSharedPointer<Entity> &e,
const QString &attr, const Relation &r, const QSharedPointer<Entity> &target) {
auto ptr = e;
QString attributeName = r.getPropertyName();
QString foreignColumnName = target->getTablename();
auto baseObj = EntityHelper::getBaseClassObject(e, attributeName);
Entity* foreignBaseObj = target.data();
if (!r.getMappedBy().isEmpty()) {
ptr = target;
attributeName = r.getMappedBy();
foreignBaseObj = EntityHelper::getBaseClassObject(ptr, attributeName);
foreignColumnName = foreignBaseObj->getTablename();
}
Attribute *attrObj = new Attribute(attr,
this->qb->generateColumnNameID(baseObj->getTablename()),
baseObj->getTablename(), e->metaObject());
this->resolveInheritance(e, attrObj);
attrObj->setRelation(foreignBaseObj->getTablename(), target->metaObject(), r,
this->qb->generateManyToManyTableName((r.getMappedBy().isEmpty() ? baseObj->getTablename()
: foreignBaseObj->getTablename()), attributeName),
this->qb->generateColumnNameID(foreignColumnName));
delete baseObj;
if(foreignBaseObj != target.data()) {
delete foreignBaseObj;
}
return attrObj;
}
Attribute *AttributeResolver::resolveManyToOneAttribute(const QSharedPointer<Entity> &e,
const QString &attr, const Relation &r, const QSharedPointer<Entity> &target) {
Q_UNUSED(r);
auto obj = EntityHelper::getBaseClassObject(e, attr);
Attribute *attrObj = new Attribute(attr,
this->qb->generateColumnNameID(attr),
e->getTablename(), e->metaObject());
this->resolveInheritance(e, attrObj);
attrObj->setRelation(target->getTablename(), target->metaObject(), r, "", "id");
delete obj;
return attrObj;
}
Attribute *AttributeResolver::resolveOneToManyAttribute(const QSharedPointer<Entity> &e,
const QString &attr, const Relation &r, const QSharedPointer<Entity> &target) {
auto obj = EntityHelper::getBaseClassObject(e, attr);
Attribute *attrObj = new Attribute(attr, "id",
e->getTablename(), e->metaObject());
this->resolveInheritance(e, attrObj);
attrObj->setRelation(target->getTablename(), target->metaObject(), r, "",
this->qb->generateColumnNameID(r.getMappedBy()));
delete obj;
return attrObj;
}
Attribute *AttributeResolver::resolveNonRelatedAttribute(const QSharedPointer<Entity> &e,
const QString &attr) {
Attribute *obj = new Attribute(attr, attr, e->getTablename(), e->metaObject());
this->resolveInheritance(e, obj);
return obj;
}
const QMetaObject *AttributeResolver::resolveInheritance(const QSharedPointer<Entity> &e,
Attribute *&attribute) {
auto obj = EntityHelper::getBaseClassObject(e, attribute->getName());
if(obj && obj->getTablename() != e->getTablename()) {
attribute->setInheritance(obj->getTablename(), obj->metaObject());
}
return obj->metaObject();
}
void AttributeResolver::addAttribute(const QString &className, Attribute *&attr) {
auto attrs = this->attributes.value(className);
attrs.insert(attr->getName(), attr);
this->attributes.insert(className, attrs);
}
Attribute *AttributeResolver::resolveExplicitAttribute(const QSharedPointer<Entity>
&classObj, const QString &attribute, QSharedPointer<Entity> related) {
Attribute* a = nullptr;
if(classObj->getRelations().contains(attribute)) {
auto relation = classObj->getRelations().value(attribute);
if(relation.getType() == RelationType::MANY_TO_MANY) {
a = this->resolveManyToManyAttribute(classObj, attribute, relation, related);
} else if(relation.getType() == RelationType::MANY_TO_ONE ||
(relation.getType() == RelationType::ONE_TO_ONE && relation.getMappedBy().isEmpty())) {
a = this->resolveManyToOneAttribute(classObj, attribute, relation, related);
} else {
a = this->resolveOneToManyAttribute(classObj, attribute, relation, related);
}
} else {
a = this->resolveNonRelatedAttribute(classObj, attribute);
}
return a;
}
QSharedPointer<QueryBuilder> AttributeResolver::getQb() const {
return qb;
}
bool AttributeResolver::containsAttribute(const QString &className,
const QString &attribute) const {
bool r = false;
auto attributes = this->getAttributes();
if(!this->attributes.isEmpty() && attributes.contains(className) &&
!attributes.value(className).isEmpty() &&
attributes.value(className).contains(attribute)) {
r = true;
}
return r;
}
Attribute *AttributeResolver::resolveAttribute(const QSharedPointer<Entity> &classObj,
const QString &attribute, QSharedPointer<Entity> related) {
Attribute *attr = nullptr;
if(this->containsAttribute(classObj->getClassname(), attribute)) {
attr = this->attributes.value(classObj->getClassname()).value(attribute);
} else {
attr = this->resolveExplicitAttribute(classObj, attribute, related);
this->addAttribute(classObj->getClassname(), attr);
}
return attr;
}
Attribute *AttributeResolver::resolveAttribute(const QString &className,
const QString &attribute, const QString related) {
Attribute *attr = nullptr;
if(!className.isEmpty()) {
if(this->containsAttribute(className, attribute)) {
attr = this->attributes.value(className).value(attribute);
} else {
QSharedPointer<Entity> e = QSharedPointer<Entity>(EntityInstanceFactory::createInstance(
className));
QSharedPointer<Entity> rel = QSharedPointer<Entity>(EntityInstanceFactory::createInstance(
related));
attr = this->resolveExplicitAttribute(e, attribute, rel);
this->addAttribute(className, attr);
}
}
return attr;
}
src/attributeresolver.h
#ifndef ATTRIBUTERESOLVER_H
#define ATTRIBUTERESOLVER_H
#include <QHash>
#include <QString>
#include "attribute.h"
#include "entity.h"
namespace CuteEntityManager {
class QueryBuilder;
class AttributeResolver {
public:
AttributeResolver(QSharedPointer<QueryBuilder> queryBuilder);
virtual ~AttributeResolver();
bool containsAttribute(const QString &className, const QString &attribute) const;
Attribute* resolveAttribute(const QSharedPointer<Entity> &classObj,
const QString &attribute, QSharedPointer<Entity> related = QSharedPointer<Entity>());
Attribute* resolveAttribute(const QString &className, const QString &attribute,
const QString related = "");
QHash<QString, QHash<QString, Attribute *>> getAttributes() const;
void setAttributes(const QHash<QString, QHash<QString, Attribute *>> &value);
QSharedPointer<QueryBuilder> getQb() const;
protected:
Attribute* resolveManyToManyAttribute(const QSharedPointer<Entity> &e,
const QString &attr, const Relation &r, const QSharedPointer<Entity> &target);
Attribute* resolveManyToOneAttribute(const QSharedPointer<Entity> &e, const QString &attr,
const Relation &r, const QSharedPointer<Entity> &target);
Attribute* resolveOneToManyAttribute(const QSharedPointer<Entity> &e, const QString &attr,
const Relation &r, const QSharedPointer<Entity> &target);
Attribute* resolveNonRelatedAttribute(const QSharedPointer<Entity> &e,
const QString &attr);
const QMetaObject *resolveInheritance(const QSharedPointer<Entity> &e,
Attribute *&attribute);
void addAttribute(const QString &className, Attribute *&attr);
Attribute* resolveExplicitAttribute(const QSharedPointer<Entity> &classObj,
const QString &attribute, QSharedPointer<Entity> related = QSharedPointer<Entity>());
private:
QSharedPointer<QueryBuilder> qb;
QHash<QString, QHash<QString, Attribute*>> attributes;
};
}
#endif // ATTRIBUTERESOLVER_H
src/entitymanager.cpp
this->schema = QSharedPointer<Schema>(Database::getSchema(Database::getDatabaseType(
this->db->getDatabase().driverName()), this->db));
this->schema->setTables(this->schema->getTableSchemas());
<<<<<<< Updated upstream
this->queryInterpreter = QSharedPointer<QueryInterpreter>(new QueryInterpreter(
this->schema->getQueryBuilder().data()));
=======
this->ar = QSharedPointer<AttributeResolver>(new AttributeResolver(
this->schema->getQueryBuilder()));
this->queryInterpreter = QSharedPointer<QueryInterpreter>(new QueryInterpreter(
this->ar));
>>>>>>> Stashed changes
this->appendToInstanceList();
if (inspect) {
EntityInspector inspector = EntityInspector(msgType);
src/entitymanager.h
if (joinBaseClasses) {
q.appendJoins(this->schema->getQueryBuilder()->joinBaseClasses(ptr));
}
QSqlQuery query = this->queryInterpreter->build(q);
QSqlQuery query = this->queryInterpreter->build(q,ptr->metaObject());
auto maps = this->convertQueryResult(query);
auto converted = this->convert(maps, EntityHelper::getClassname(ptr.data()),
false,
src/query.cpp
#include "query.h"
#include "entity.h"
#include "querybuilder.h"
#include "entityinstancefactory.h"
using namespace CuteEntityManager;
Query::Query() {
}
......
return qb->like(conditions, conjunction, jp, wildcard);
}
QVariant Query::convertParam(QVariant &val) {
if(QString(val.typeName()).contains("QSharedPointer")) {
auto entity = EntityInstanceFactory::castQVariant(val);
if(entity && entity->getId() != -1) {
return entity->getProperty(entity->getPrimaryKey());
}
}
return val;
}
QString Query::getSelectOption() const {
return selectOption;
}
src/query.h
class Query {
public:
Query();
~Query();
virtual ~Query();
explicit Query(QStringList from, QList<Expression> where = QList<Expression>(),
QList<Join> joins = QList<Join>(),
QHash<QString, QVariant> params = QHash<QString, QVariant>(), quint64 limit = 0,
......
QHash<QString, QVariant> conditions,
QString conjunction = QStringLiteral("AND"),
JokerPosition jp = JokerPosition::BOTH, QChar wildcard = '%');
protected:
QVariant convertParam(QVariant &val);
private:
QList<Expression> select;
src/querybuilder.cpp
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <QMetaObject>
#include <QRegularExpression>
#include <QStringList>
#include "querybuilder.h"
#include "database.h"
#include <QMetaObject>
#include "entity.h"
#include <QRegularExpression>
#include "entityinstancefactory.h"
#include "entityhelper.h"
#include "logger.h"
......
}
QString QueryBuilder::placeHolder(const QString &key) const {
return QString(":" + key);
QString nKey = key;
nKey.replace(".","_");
return QString(":" + nKey);
}
QString QueryBuilder::where(const QHash<QString, QVariant> &m,
src/queryinterpreter.cpp
#include "queryinterpreter.h"
#include "join.h"
#include "query.h"
#include "querybuilder.h"
#include "attributeresolver.h"
#include "orderby.h"
#include "expression.h"
#include "schema.h"
using namespace CuteEntityManager;
QueryInterpreter::QueryInterpreter(QueryBuilder *builder) {
this->builder = builder;
QueryInterpreter::QueryInterpreter(QSharedPointer<AttributeResolver> ar) {
this->ar = ar;
}
QSqlQuery QueryInterpreter::build(Query &q) {
QSqlQuery QueryInterpreter::build(Query &q, const QMetaObject *obj) {
QList<QString> clauses = QList<QString>();
clauses.append(this->buildSelect(q, q.getSelect(), q.getDistinct(),
q.getSelectOption()));
......
if (first) {
first = false;
} else {
sql += this->builder->getSeparator();
sql += this->ar->getQb()->getSeparator();
}
sql += clause;
}
}
sql = this->buildOrderByAndLimit(sql, q.getOrderBy(), q.getLimit(),
q.getOffset());
QSqlQuery sqlQuery = this->builder->getQuery();
QSqlQuery sqlQuery = this->ar->getQb()->getQuery();
sqlQuery.prepare(sql);
this->builder->bindValues(q.getParams(), sqlQuery, false);
this->ar->getQb()->bindValues(q.getParams(), sqlQuery, false);
return sqlQuery;
}
QString QueryInterpreter::buildSelect(Query &q,
const QList<Expression> &columns,
const bool &distinct, const QString &selectOption) const {
QString sqlSelect = distinct ? ("SELECT " + this->builder->distinct() + " ") :
QString sqlSelect = distinct ? ("SELECT " + this->ar->getQb()->distinct() + " ") :
"SELECT ";
if (!selectOption.isEmpty()) {
sqlSelect += selectOption + " ";
......
q.appendParams(e.getParams());
QString nExp = e.getExpression();
if (e.getOnlyColumn()) {
sqlSelect += this->builder->getSchema()->quoteColumnName(e.getExpression());
sqlSelect += this->ar->getQb()->getSchema()->quoteColumnName(e.getExpression());
} else if (!nExp.contains("(")) {
QRegularExpression re =
QRegularExpression(
......
for (int var = 0; var < 2; ++var) {
QRegularExpressionMatch match = iterator.next();
if (var == 1) {
sqlSelect += this->builder->getSchema()->quoteColumnName(
match.captured()) + " AS " + this->builder->getSchema()->quoteColumnName("a" +
sqlSelect += this->ar->getQb()->getSchema()->quoteColumnName(
match.captured()) + " AS " + this->ar->getQb()->getSchema()->quoteColumnName("a" +
QString::number(i));
}
}
} else {
nExp = this->builder->getSchema()->quoteColumnName(nExp);
nExp = this->ar->getQb()->getSchema()->quoteColumnName(nExp);
}
} else {
sqlSelect += nExp + " AS " + this->builder->getSchema()->quoteColumnName("a" +
sqlSelect += nExp + " AS " + this->ar->getQb()->getSchema()->quoteColumnName("a" +
QString::number(i));
}
}
......
if (from.isEmpty()) {
return "";
}
auto tables = this->builder->quoteTableNames(from);
auto tables = this->ar->getQb()->quoteTableNames(from);
QString clause = "FROM ";
bool first = true;
for (int var = 0; var < tables.size(); ++var) {
......
QString sqlJoin = "";
for (int i = 0; i < joins.size(); ++i) {
Join j = joins.at(i);
sqlJoin += j.getType() + this->builder->getSeparator() +
this->builder->getSchema()->quoteTableName(j.getForeignTable());
sqlJoin += j.getType() + this->ar->getQb()->getSeparator() +
this->ar->getQb()->getSchema()->quoteTableName(j.getForeignTable());
if (!j.getExpression().getExpression().isEmpty()) {
QString expression = j.getExpression().getExpression();
int count = expression.count("=");
if (count < 1) {
expression = this->builder->getSchema()->quoteTableName(expression);
expression = this->ar->getQb()->getSchema()->quoteTableName(expression);
} else if (count == 1) {
QStringList list = expression.split("=");
expression = this->builder->getSchema()->quoteColumnName(list.at(
expression = this->ar->getQb()->getSchema()->quoteColumnName(list.at(
0).trimmed()) + " = ";
expression += this->builder->getSchema()->quoteColumnName(list.at(1).trimmed());
expression += this->ar->getQb()->getSchema()->quoteColumnName(list.at(1).trimmed());
}
sqlJoin += " ON " + expression;
}
......
}
QString QueryInterpreter::buildGroupBy(const QStringList &groupBy) const {
return groupBy.isEmpty() ? "" : "GROUP BY " + this->builder->buildColumns(
return groupBy.isEmpty() ? "" : "GROUP BY " + this->ar->getQb()->buildColumns(
groupBy);
}
......
const quint64 &offset) const {
QString sqlOrderBy = this->buildOrderBy(orderBy);
if (!sqlOrderBy.isEmpty()) {
sql += this->builder->getSeparator() + sqlOrderBy;
sql += this->ar->getQb()->getSeparator() + sqlOrderBy;
}
QString sqlLimit = this->builder->limit(limit, offset, false);
QString sqlLimit = this->ar->getQb()->limit(limit, offset, false);
if (!sqlLimit.isEmpty()) {
sql += this->builder->getSeparator() + sqlLimit;
sql += this->ar->getQb()->getSeparator() + sqlLimit;
}
return sql;
}
......
if (order.getColumn().isEmpty()) {
sqlOrder += order.getExpressedDirection().getExpression();
} else {
sqlOrder += this->builder->getSchema()->quoteColumnName(order.getColumn());
sqlOrder += this->ar->getQb()->getSchema()->quoteColumnName(order.getColumn());
switch (order.getDirection()) {
case Direction::SORT_ASC:
sqlOrder += " ASC";
......
if (first) {
first = false;
} else if (expression.at(0) != ' ') {
sqlCondition += this->builder->getSeparator();
sqlCondition += this->ar->getQb()->getSeparator();
}
}
sqlCondition += expression;
src/queryinterpreter.h
#include <QRegularExpressionMatchIterator>
namespace CuteEntityManager {
class Query;
class QueryBuilder;
class Join;
class OrderBy;
class Expression;
class AttributeResolver;
class QueryInterpreter {
public:
QueryInterpreter(QueryBuilder *builder);
QSqlQuery build(Query &q);
QueryInterpreter(QSharedPointer<AttributeResolver> ar);
QSqlQuery build(Query &q, const QMetaObject *obj=nullptr);
protected:
QString buildSelect(Query &q, const QList<Expression> &columns,
......
QString buildCondition(Query &q, const QList<Expression> &conditions) const;
private:
QueryBuilder *builder;
QSharedPointer<AttributeResolver> ar;
};

Auch abrufbar als: Unified diff