Revision 99140fe9
Von Christian Ehringfeld vor mehr als 10 Jahren hinzugefügt
| src/database.cpp | ||
|---|---|---|
|
|
||
|
|
||
|
bool Database::commitTransaction() {
|
||
|
this->supportTransactions &&this->database.commit();
|
||
|
return this->supportTransactions &&this->database.commit();
|
||
|
}
|
||
|
|
||
|
bool Database::rollbackTransaction() {
|
||
| src/entity.cpp | ||
|---|---|---|
|
return this->property(name.toLatin1().constData());
|
||
|
}
|
||
|
|
||
|
bool Entity::setProperty(const QString &name, const QVariant &value) {
|
||
|
return this->setProperty(name.toLatin1().constData(), value);
|
||
|
}
|
||
|
|
||
|
qint64 Entity::getId() const {
|
||
|
return id;
|
||
|
}
|
||
| src/entity.h | ||
|---|---|---|
|
const QHash<Relation, QMetaProperty> getRelationProperties() const;
|
||
|
const char *getClassname() const;
|
||
|
QVariant property(const QString &name) const;
|
||
|
bool setProperty(const QString &name, const QVariant &value);
|
||
|
|
||
|
qint64 getId() const;
|
||
|
void setId(const qint64 &value);
|
||
| src/entitymanager.cpp | ||
|---|---|---|
|
void EntityManager::setProperty(const QSharedPointer<Entity> &entiy,
|
||
|
QSharedPointer<Entity> value,
|
||
|
const QMetaProperty &property) const {
|
||
|
if (value.data() && value.data()->getId() > -1) {
|
||
|
if (value && value.data()->property(value.data()->getPrimaryKey()).toLongLong()
|
||
|
> -1) {
|
||
|
property.write(entiy.data(), QVariant(value));
|
||
|
}
|
||
|
}
|
||
| ... | ... | |
|
const bool persistRelations, const bool checkDuplicate) {
|
||
|
bool rc = false;
|
||
|
if (this->checkTable(entity) && !(checkDuplicate && this->count(entity) == 0)) {
|
||
|
QSqlQuery q = this->schema.data()->getQueryBuilder().data()->create(entity);
|
||
|
rc = this->db->transaction(q);
|
||
|
if (rc) {
|
||
|
entity.data()->setId(q.lastInsertId().toLongLong(&rc));
|
||
|
QList<QSqlQuery> q = this->schema.data()->getQueryBuilder().data()->create(
|
||
|
entity);
|
||
|
this->db->startTransaction();
|
||
|
bool first = true;
|
||
|
for (int var = 0; var < q.size(); ++var) {
|
||
|
auto query = q.at(var);
|
||
|
query.exec();
|
||
|
if (first) {
|
||
|
entity.data()->setProperty(entity.data()->getPrimaryKey(),
|
||
|
query.lastInsertId().toLongLong(&rc));
|
||
|
first = false;
|
||
|
}
|
||
|
}
|
||
|
if (!this->db->commitTransaction() || !rc) {
|
||
|
this->db->rollbackTransaction();
|
||
|
entity.data()->setId(-1);
|
||
|
rc = false;
|
||
|
} else {
|
||
|
if (persistRelations) {
|
||
|
this->saveRelations(entity);
|
||
|
}
|
||
|
this->cache.insert(entity);
|
||
|
rc = true;
|
||
|
}
|
||
|
}
|
||
|
return rc;
|
||
| src/entitymanager.h | ||
|---|---|---|
|
*@TODO use conditions
|
||
|
*/
|
||
|
/**
|
||
|
* @TODO Inheritance at create,save,merge
|
||
|
* @TODO Inheritance at merge
|
||
|
*/
|
||
|
template<class T> qint8 count(QHash<QString, QString> condition =
|
||
|
QHash<QString, QString>()) {
|
||
| src/querybuilder.cpp | ||
|---|---|---|
|
#include "querybuilder.h"
|
||
|
#include "database.h"
|
||
|
#include <QMetaObject>
|
||
|
#include <QMetaProperty>
|
||
|
#include "entity.h"
|
||
|
#include <QRegularExpression>
|
||
|
#include "entityinstancefactory.h"
|
||
| ... | ... | |
|
return q;
|
||
|
}
|
||
|
|
||
|
QSqlQuery QueryBuilder::create(const QSharedPointer<Entity> &entity) const {
|
||
|
QHash<QString, QVariant> values = this->saveAttributes(entity);
|
||
|
return this->insert(entity.data()->getTablename(), values,
|
||
|
entity.data()->getPrimaryKey());
|
||
|
QList<QSqlQuery> QueryBuilder::create(const QSharedPointer<Entity> &entity)
|
||
|
const {
|
||
|
auto attrs = this->inheritedAttributes(entity);
|
||
|
auto queries = QList<QSqlQuery>();
|
||
|
for (int var = 0; var < attrs.size(); ++var) {
|
||
|
auto attr = attrs.at(var);
|
||
|
auto attrHash = attr.getAttributes();
|
||
|
queries.append(this->insert(attr.getName(), attrHash, attr.getPk()));
|
||
|
}
|
||
|
return queries;
|
||
|
}
|
||
|
|
||
|
QSqlQuery QueryBuilder::insert(const QString &tableName,
|
||
| ... | ... | |
|
return this->database.data()->getQuery();
|
||
|
}
|
||
|
|
||
|
|
||
|
QHash<QString, QVariant> QueryBuilder::saveAttributes(const
|
||
|
QSharedPointer<Entity> &entity) const {
|
||
|
auto props = entity.data()->getMetaProperties();
|
||
|
QSharedPointer<Entity> &entity, QHash<QString, QMetaProperty> props,
|
||
|
QHash<QString, Relation> relations) const {
|
||
|
if (props.isEmpty()) {
|
||
|
props = entity.data()->getMetaProperties();
|
||
|
}
|
||
|
auto values = this->getEntityAttributes(props, entity);
|
||
|
auto relValues = this->getManyToOneAttributes(props, entity);
|
||
|
auto relValues = this->getManyToOneAttributes(props, entity, relations);
|
||
|
auto iterator = relValues.constBegin();
|
||
|
while (iterator != relValues.constEnd()) {
|
||
|
values.insert(iterator.key(), iterator.value());
|
||
| ... | ... | |
|
return values;
|
||
|
}
|
||
|
|
||
|
QHash<QString, QMetaProperty> QueryBuilder::processProperties(
|
||
|
const QSharedPointer<Entity> &e,
|
||
|
QHash<QString, QMetaProperty> &usedProperties) const {
|
||
|
auto properties = e.data()->getMetaProperties();
|
||
|
auto i = QMutableHashIterator<QString, QMetaProperty>(properties);
|
||
|
while (i.hasNext()) {
|
||
|
if (usedProperties.contains(i.key()) && i.key() != e.data()->getPrimaryKey()) {
|
||
|
properties.remove(i.key());
|
||
|
} else {
|
||
|
usedProperties.insert(i.key(), i.value());
|
||
|
}
|
||
|
i.next();
|
||
|
}
|
||
|
return properties;
|
||
|
}
|
||
|
|
||
|
QHash<QString, Relation> QueryBuilder::processRelations(
|
||
|
const QSharedPointer<Entity> &e,
|
||
|
QHash<QString, Relation> &usedRelations) const {
|
||
|
auto relations = e.data()->getRelations();
|
||
|
auto i = QMutableHashIterator<QString, Relation>(relations);
|
||
|
while (i.hasNext()) {
|
||
|
if (usedRelations.contains(i.key())) {
|
||
|
relations.remove(i.key());
|
||
|
} else {
|
||
|
usedRelations.insert(i.key(), i.value());
|
||
|
}
|
||
|
i.next();
|
||
|
}
|
||
|
return relations;
|
||
|
}
|
||
|
|
||
|
QList<QueryBuilder::ClassAttributes> QueryBuilder::inheritedAttributes(
|
||
|
const QSharedPointer<Entity> &entity) const {
|
||
|
auto list = QList<QueryBuilder::ClassAttributes>();
|
||
|
|
||
|
|
||
|
if (entity.data()->getInheritanceStrategy() == JOINED_TABLE) {
|
||
|
auto classes = QList<const QMetaObject *>();
|
||
|
classes.append(entity.data()->metaObject());
|
||
|
classes.append(entity.data()->superClasses(true));
|
||
|
auto usedProperties = QHash<QString, QMetaProperty>();
|
||
|
auto usedRelations = QHash<QString, Relation>();
|
||
|
QSharedPointer<Entity> e;
|
||
|
for (int var = classes.size(); var >= 0; --var) {
|
||
|
auto metaObj = classes.at(var);
|
||
|
e = QSharedPointer<Entity>(EntityInstanceFactory::createInstance(
|
||
|
metaObj->className()));
|
||
|
if (e) {
|
||
|
list.append(QueryBuilder::ClassAttributes(e.data()->getTablename(),
|
||
|
this->saveAttributes(entity, this->processProperties(e, usedProperties),
|
||
|
this->processRelations(e, usedRelations)), e.data()->getPrimaryKey()));
|
||
|
} else {
|
||
|
qDebug() << "Instance of " << metaObj->className() << " could not created";
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
list.append(QueryBuilder::ClassAttributes(entity.data()->getTablename(),
|
||
|
this->saveAttributes(entity), entity.data()->getPrimaryKey()));
|
||
|
}
|
||
|
return list;
|
||
|
}
|
||
|
|
||
|
QString QueryBuilder::leftJoin(const QString &foreignTable,
|
||
| ... | ... | |
|
}
|
||
|
|
||
|
QHash<QString, QVariant> QueryBuilder::getManyToOneAttributes(
|
||
|
const QHash<QString, QMetaProperty>
|
||
|
&props,
|
||
|
const QSharedPointer<Entity> &entity) const {
|
||
|
QHash<QString, QMetaProperty>
|
||
|
props,
|
||
|
const QSharedPointer<Entity> &entity,
|
||
|
QHash<QString, Relation> relations) const {
|
||
|
Entity *e = entity.data();
|
||
|
auto map = QHash<QString, QVariant>();
|
||
|
auto relations = e->getRelations();
|
||
|
if (relations.isEmpty()) {
|
||
|
relations = e->getRelations();
|
||
|
}
|
||
|
auto i = relations.constBegin();
|
||
|
while (i != relations.constEnd()) {
|
||
|
Relation r = i.value();
|
||
| ... | ... | |
|
schema = value;
|
||
|
}
|
||
|
|
||
|
QueryBuilder::ClassAttributes::ClassAttributes(const QString name,
|
||
|
const QHash<QString, QVariant> attributes, QString pk) {
|
||
|
this->name = name;
|
||
|
this->attributes = attributes;
|
||
|
this->pk = pk;
|
||
|
}
|
||
|
|
||
|
QString QueryBuilder::ClassAttributes::getName() const {
|
||
|
return name;
|
||
|
}
|
||
| ... | ... | |
|
&value) {
|
||
|
attributes = value;
|
||
|
}
|
||
|
|
||
|
QString QueryBuilder::ClassAttributes::getPk() const {
|
||
|
return pk;
|
||
|
}
|
||
|
|
||
|
void QueryBuilder::ClassAttributes::setPk(const QString &value) {
|
||
|
pk = value;
|
||
|
}
|
||
|
|
||
| src/querybuilder.h | ||
|---|---|---|
|
#include <QPointer>
|
||
|
#include <QSqlQuery>
|
||
|
#include <QStringList>
|
||
|
#include <QMetaProperty>
|
||
|
#include "relation.h"
|
||
|
namespace CuteEntityManager {
|
||
|
class Schema;
|
||
| ... | ... | |
|
QSqlQuery count(const QSharedPointer<Entity> &entity, bool ignoreID) const;
|
||
|
QSqlQuery count(const QString &tableName) const;
|
||
|
QSqlQuery merge(const QSharedPointer<Entity> &entity) const;
|
||
|
QSqlQuery create(const QSharedPointer<Entity> &entity) const;
|
||
|
QList<QSqlQuery> create(const QSharedPointer<Entity> &entity) const;
|
||
|
QSqlQuery oneToMany(const QString &tableName, const QString &attribute,
|
||
|
const qint64 &id,
|
||
|
const qint64 &limit = 0);
|
||
| ... | ... | |
|
|
||
|
protected:
|
||
|
class ClassAttributes {
|
||
|
public:
|
||
|
public:
|
||
|
ClassAttributes() { }
|
||
|
explicit ClassAttributes(const QString name,
|
||
|
const QHash<QString, QVariant> attributes, QString pk = "id");
|
||
|
QString getName() const;
|
||
|
void setName(const QString &value);
|
||
|
|
||
|
QHash<QString, QVariant> getAttributes() const;
|
||
|
void setAttributes(const QHash<QString, QVariant> &value);
|
||
|
|
||
|
private:
|
||
|
QString getPk() const;
|
||
|
void setPk(const QString &value);
|
||
|
|
||
|
private:
|
||
|
QString name;
|
||
|
QString pk;
|
||
|
QHash<QString, QVariant> attributes;
|
||
|
};
|
||
|
|
||
| ... | ... | |
|
void insertRelationId(const Entity *e, QHash<QString, QVariant> &map,
|
||
|
QString relName) const;
|
||
|
QString buildColumns(const QStringList &columns) const;
|
||
|
QHash<QString, QVariant> getManyToOneAttributes(const
|
||
|
QHash<QString, QMetaProperty>
|
||
|
&props,
|
||
|
const QSharedPointer<Entity> &entity) const;
|
||
|
QHash<QString, QVariant> getManyToOneAttributes(QHash<QString, QMetaProperty>
|
||
|
props,
|
||
|
const QSharedPointer<Entity> &entity,
|
||
|
QHash<QString, Relation> relations = QHash<QString, Relation>()) const;
|
||
|
QHash<QString, QMetaProperty> getMetaProperties(const QSharedPointer<Entity>
|
||
|
&entity)
|
||
|
const;
|
||
| ... | ... | |
|
QString attributes(const QHash<QString, QVariant> &m,
|
||
|
const QString &conjunction = ",",
|
||
|
bool ignoreID = false, const QString &primaryKey = "id") const;
|
||
|
QHash<QString, QVariant> saveAttributes(const QSharedPointer<Entity> &entity)
|
||
|
QHash<QString, QVariant> saveAttributes(const QSharedPointer<Entity> &entity,
|
||
|
QHash<QString, QMetaProperty> props = QHash<QString, QMetaProperty> (),
|
||
|
QHash<QString, Relation> relations = QHash<QString, Relation>())
|
||
|
const;
|
||
|
QHash<QString, QMetaProperty> processProperties(const QSharedPointer<Entity> &e,
|
||
|
QHash<QString, QMetaProperty> &usedProperties) const;
|
||
|
QHash<QString, Relation> processRelations(const QSharedPointer<Entity> &e,
|
||
|
QHash<QString, Relation> &usedRelations) const;
|
||
|
QList<ClassAttributes> inheritedAttributes(
|
||
|
const QSharedPointer<Entity> &entity) const;
|
||
|
const QSharedPointer<Entity> &entity) const;
|
||
|
|
||
|
QString leftJoin(const QString &foreignTable, const QString &tableName,
|
||
|
const QString &foreignKey = "id", const QString &primaryKey = "id") const;
|
||
Auch abrufbar als: Unified diff
inheritance insert