Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision b0bf458e

Von Christian Ehringfeld vor mehr als 9 Jahren hinzugefügt

  • ID b0bf458ea9c799ed5425bc667242201e120bf61e
  • Vorgänger 586bb527
  • Nachfolger 24c5480c

wip

Unterschiede anzeigen:

EntityManager.pro
src/tableschema.h \
src/schema/pgsqlschema.h \
src/schema/mysqlschema.h \
src/databasemigration.h \
src/querybuilder.h \
src/databasemigration.h
src/schema/sqlitequerybuilder.h
SOURCES += \
src/entity.cpp \
......
src/tableschema.cpp \
src/schema/pgsqlschema.cpp \
src/schema/mysqlschema.cpp \
src/databasemigration.cpp \
src/querybuilder.cpp \
src/databasemigration.cpp
src/schema/sqlitequerybuilder.cpp
unix {
target.path = /usr/lib
src/entitymanager.cpp
#include "entitymanager.h"
#include "enums/databasetype.h"
#include <QMetaObject>
#include <QMetaProperty>
using namespace CuteEntityManager;
/**
* Relationen fehlen noch
......
auto schema = CuteEntityManager::getSchema(CuteEntityManager::getDatabaseType(
this->db.data()->getDatabase().driverName()), this->db);
this->schema = QSharedPointer<Schema>(schema);
this->schema.data()->setTables(this->schema.data()->getTableSchemas());
}
EntityManager::EntityManager(QSqlDatabase database) {
......
this->init();
}
//inline bool EntityManager::checkTable(Entity *entity) {
// bool rc = true;
// if (!this->db->containsTable(entity->getTablename())) {
// qDebug() << "Tabelle" << entity->getTablename() << "existiert noch nicht.";
// if (this->createTable(entity)) {
// this->db->refreshTableList();
// rc = this->db->containsTable(entity->getTablename());
// }
// }
// return rc;
//}
bool EntityManager::checkTable(const QSharedPointer<Entity> &entity) {
bool rc = true;
if (!this->schema.data()->containsTable(entity.data()->getTablename())) {
if (this->schema.data()->getQueryBuilder().data()->createTable(entity)) {
this->schema.data()->getTableSchema(entity.data()->getTablename(), true);
rc = this->schema.data()->getTables().contains(entity.data()->getTablename());
}
}
return rc;
}
QSharedPointer<Database> EntityManager::getDb() const {
return db;
......
schema = value;
}
QHash<QString, QVariant> EntityManager::getEntityAttributes(const QSharedPointer<Entity> &entity) {
Entity *e = entity.data();
auto map = QHash<QString, QVariant>();
auto metaObject = e->metaObject();
auto transientAttrs = e->getTransientAttributes();
for (int var = 0; var < metaObject->propertyCount(); ++var) {
auto p = metaObject->property(var);
QString name = QString(p.name());
if (p.isValid() && !transientAttrs.contains(name)) {
QVariant v = p.read(e);
//Relation
if (v.canConvert<Entity *>()) {
this->insertRelationId(qvariant_cast<Entity *>(v),map,name);
} else if (v.canConvert<QSharedPointer<Entity>>()) {
this->insertRelationId(qvariant_cast<QSharedPointer<Entity>>(v).data(),map,name);
} else if (QString(p.typeName()).contains("QList")) {
/**
@TODO
//List and/or ManyToManyRelation
*/
auto n = static_cast<QList<CuteEntityManager::Entity *>*>(v.data());
for (int var = 0; var < n->size(); ++var) {
CuteEntityManager::Entity *entity = n->at(var);
qDebug() << entity->toString();
}
} else {
map.insert(name, v);
}
}
}
return map;
}
void EntityManager::insertRelationId(const Entity *e, QHash<QString, QVariant> &map, QString relName) {
if (e && e->getId() > -1) {
map.insert(relName + "_id", e->getId());
}
}
QString EntityManager::createConnection() {
QStringList l = EntityManager::getConnectionNames();
QString conName = "";
......
return rc;
}
//QString EntityManager::createTableQuery(QSharedPointer<Entity> entity) {
// QChar c = this->db->escapeChar();
// QHash<QString, QString> m = entity->getProperties(this->db->getDatabaseType());
// bool first = true;
// QString s = "CREATE TABLE IF NOT EXISTS ";
// s.append(c).append(entity->getTablename()).append(c).append("(");
// QHash<QString, QString>::const_iterator i = m.constBegin();
// while (i != m.constEnd()) {
// if (first) {
// first = false;
// } else {
// s.append(',');
// }
// s.append(c).append(i.key()).append(c).append(" " + i.value());
// ++i;
// }
// s.append(");");
// return s;
//}
//bool EntityManager::createTable(Entity *entity) {
// bool rc = false;
// this->db->containsTable(entity->getTablename()) ? rc = true : rc = false;
// if (!rc) {
// QSqlQuery q = this->db->getQuery(this->createTableQuery(entity));
// if (this->db->transaction(q)) {
// this->db->refreshTableList();
// rc = true;
// }
// }
// return rc;
//}
void EntityManager::setConnectionNames(QStringList list) {
EntityManager::connectionNames = list;
}
src/entitymanager.h
void init();
QString where(const QSharedPointer<Entity> &entity, QString conjunction = ",", bool ignoreID = false);
QString where(const QHash<QString, QVariant> &m, const QString &conjunction = ",", bool ignoreID = false);
void insertRelationId(const Entity *e, QHash<QString, QVariant> &map, QString relName);
public:
EntityManager(QSqlDatabase database);
......
void setDb(const QSharedPointer<Database> &value);
QSharedPointer<Schema> getSchema() const;
void setSchema(const QSharedPointer<Schema> &value);
QHash<QString, QVariant> getEntityAttributes(const QSharedPointer<Entity> &entity);
};
}
src/querybuilder.cpp
#include "querybuilder.h"
#include "database.h"
#include <QMetaObject>
#include <QMetaProperty>
#include "entity.h"
using namespace CuteEntityManager;
QueryBuilder::QueryBuilder() {
//bool QueryBuilder::createTable(QString tablename, QHash<QString, QString> tableDefinition) {
//// QHash<QString, QString> Artikel::getProperties(DatabaseType type) {
//// QHash<QString, QString> h = QHash<QString, QString>();
//// h.insert("id",this->idColumnSQL());
//// h.insert("preis","DOUBLE");
//// h.insert("name","TEXT");
//// return h;
//// }
//}
QueryBuilder::QueryBuilder(QSharedPointer<Schema> schema, QSharedPointer<Database> database) {
this->schema = schema;
this->database = database;
}
QueryBuilder::~QueryBuilder() {
bool QueryBuilder::createTable(const QSharedPointer<Entity> &entity) const {
return this->createTable(entity.data()->getTablename(), this->generateTableDefinition(entity));
}
bool QueryBuilder::createTable(const QString &tableName, const QHash<QString, QString> &tableDefinition) const {
bool rc = false;
this->schema.data()->containsTable(tableName) ? rc = true : rc = false;
if (!rc) {
QSqlQuery q = this->database.data()->getQuery(this->createTableQuery(tableName, tableDefinition));
if (this->database.data()->transaction(q)) {
this->schema.data()->getTableSchema(tableName);
rc = true;
}
}
return rc;
}
QString QueryBuilder::createTableQuery(const QString &tableName, const QHash<QString, QString> &tableDefinition) const {
bool first = true;
QString s = "CREATE TABLE ";
s.append(this->schema.data()->quoteTableName(tableName).append(" (\n"));
QHash<QString, QString>::const_iterator i = tableDefinition.constBegin();
while (i != tableDefinition.constEnd()) {
if (first) {
first = false;
} else {
s.append(',');
}
s.append(this->schema.data()->quoteColumnName(i.key())).append(" " + i.value());
++i;
}
s.append("\n);");
return s;
}
QSharedPointer<Database> QueryBuilder::getDatabase() const {
return database;
}
void QueryBuilder::setDatabase(const QSharedPointer<Database> &value) {
database = value;
}
bool QueryBuilder::createTable(QString tablename, QHash<QString, QString> tableDefinition) {
// QHash<QString, QString> Artikel::getProperties(DatabaseType type) {
// QHash<QString, QString> h = QHash<QString, QString>();
// h.insert("id",this->idColumnSQL());
// h.insert("preis","DOUBLE");
// h.insert("name","TEXT");
// return h;
// }
QHash<QString, QString> QueryBuilder::generateTableDefinition(const QSharedPointer<Entity> &entity) const {
auto map = QHash<QString, QString>();
auto o = entity.data()->metaObject();
for (int var = 0; var < o->propertyCount(); ++var) {
auto m = o->property(var);
if (m.isReadable() && !entity.data()->getTransientAttributes().contains(m.name())) {
m.typeName();
/**
@TODO
*/
}
}
return map;
}
QHash<QString, QVariant> QueryBuilder::getEntityAttributes(const QSharedPointer<Entity> &entity) {
Entity *e = entity.data();
auto map = QHash<QString, QVariant>();
auto metaObject = e->metaObject();
auto transientAttrs = e->getTransientAttributes();
for (int var = 0; var < metaObject->propertyCount(); ++var) {
auto p = metaObject->property(var);
QString name = QString(p.name());
if (p.isValid() && !transientAttrs.contains(name)) {
QVariant v = p.read(e);
//Relation
if (v.canConvert<Entity *>()) {
this->insertRelationId(qvariant_cast<Entity *>(v), map, name);
} else if (v.canConvert<QSharedPointer<Entity>>()) {
this->insertRelationId(qvariant_cast<QSharedPointer<Entity>>(v).data(), map, name);
} else if (QString(p.typeName()).contains("QList")) {
/**
@TODO
//List and/or ManyToManyRelation
*/
auto n = static_cast<QList<CuteEntityManager::Entity *>*>(v.data());
for (int var = 0; var < n->size(); ++var) {
CuteEntityManager::Entity *entity = n->at(var);
qDebug() << entity->toString();
}
} else {
map.insert(name, v);
}
}
}
return map;
}
void QueryBuilder::insertRelationId(const Entity *e, QHash<QString, QVariant> &map, QString relName) {
if (e && e->getId() > -1) {
map.insert(relName + "_id", e->getId());
}
}
QSharedPointer<Schema> QueryBuilder::getSchema() const {
return schema;
}
void QueryBuilder::setSchema(const QSharedPointer<Schema> &value) {
schema = value;
}
src/querybuilder.h
#ifndef QUERYBUILDER_H
#define QUERYBUILDER_H
#include "schema.h"
#include <QString>
#include <QHash>
#include <QSharedPointer>
namespace CuteEntityManager {
class Schema;
class Entity;
class Database;
class QueryBuilder {
public:
QueryBuilder(QSharedPointer<Schema> schema, QSharedPointer<Database> database);
virtual ~QueryBuilder();
virtual bool createTable(const QSharedPointer<Entity> &entity) const;
virtual bool createTable(const QString &tableName, const QHash<QString, QString> &tableDefinition) const;
virtual QString createTableQuery(const QString &tableName, const QHash<QString, QString> &tableDefinition) const;
virtual bool renameTable(QString tableName, QString newName) const;
virtual bool dropTable(QString tableName) const;
virtual bool truncateTable(QString tableName) const;
virtual bool addColumn(QString tableName, QString columnName, QString columnType) const;
virtual QString dropColumn(QString tableName, QString columName)const;
virtual QString renameColumn(QString tableName, QString oldName, QString newName);
virtual QString alterColumn(QString tableName, QString columnName, QString newType)const;
virtual QString addPrimaryKey(QString name, QString tableName, QStringList columns)const;
virtual QString dropPrimaryKey(QString name, QString tableName) const;
virtual QString addForeignKey(QString name, QString tableName, QStringList columns, QString refTableName,
QStringList refColumns, QString deleteConstraint, QString updateConstraint);
virtual QString dropForeignKey(QString name, QString tableName) const;
virtual QString createIndex(QString name, QString tableName, QStringList columns, bool unique)const;
virtual QString dropIndex(QString name, QString tableName)const;
QHash<QString, QVariant> getEntityAttributes(const QSharedPointer<Entity> &entity);
QSharedPointer<Schema> getSchema() const;
void setSchema(const QSharedPointer<Schema> &value);
class QueryBuilder
{
public:
QueryBuilder();
~QueryBuilder();
bool createTable(QString tablename, QHash<QString, QString> tableDefinition);
QSharedPointer<Database> getDatabase() const;
void setDatabase(const QSharedPointer<Database> &value);
QHash<QString, QString> generateTableDefinition(const QSharedPointer<Entity> &entity) const;
protected:
void insertRelationId(const Entity *e, QHash<QString, QVariant> &map, QString relName);
QSharedPointer<Schema> schema;
QSharedPointer<Database> database;
};
}
#endif // QUERYBUILDER_H
src/schema.cpp
Schema::Schema(QSharedPointer<Database> database) {
this->database = database;
this->typeMap = QSharedPointer<QHash<QString, QString>>(new QHash<QString, QString>());
this->queryBuilder = QSharedPointer<QueryBuilder>();
}
Schema::~Schema() {
}
QHash<QString, QString> Schema::getAbstractDatabaseTypes() {
auto typeMap = QHash<QString, QString>();
typeMap.insert("bool", TYPE_SMALLINT);
typeMap.insert("short", TYPE_SMALLINT);
typeMap.insert("int", TYPE_INTEGER);
typeMap.insert("long", TYPE_INTEGER);
typeMap.insert("long long", TYPE_INTEGER);
typeMap.insert("float", TYPE_FLOAT);
typeMap.insert("double", TYPE_FLOAT);
typeMap.insert("long double", TYPE_FLOAT);
typeMap.insert("qint", TYPE_INTEGER);
typeMap.insert("quint", TYPE_INTEGER);
typeMap.insert("quuid", TYPE_INTEGER);
typeMap.insert("qfloat", TYPE_FLOAT);
typeMap.insert("unsigned short", TYPE_SMALLINT);
typeMap.insert("unsigned int", TYPE_INTEGER);
typeMap.insert("unsigned long", TYPE_INTEGER);
typeMap.insert("unsigned long long", TYPE_INTEGER);
typeMap.insert("char",TYPE_CHAR);
typeMap.insert("std::string", TYPE_TEXT);
typeMap.insert("QString", TYPE_TEXT);
typeMap.insert("QVariant", TYPE_TEXT);
typeMap.insert("QUuid", TYPE_TEXT);
typeMap.insert("QDate", TYPE_DATE);
typeMap.insert("QTime", TYPE_TIME);
typeMap.insert("QDateTime", TYPE_DATETIME);
typeMap.insert("QByteArray", TYPE_BINARY);
typeMap.insert("QBitArray", TYPE_BINARY);
return typeMap;
}
QString Schema::quoteSimpleTableName(QString name) {
return name.indexOf("`") ? name : "`" + name + "`";
}
......
if (schema != "") {
name = schema + "." + names.at(i);
}
TableSchema *t = this->getTableSchema(name, refresh);
if (t) {
this->tables.insert(name, QSharedPointer<TableSchema>(t));
}
this->getTableSchema(name, refresh);
}
return this->tables;
}
......
return this->tables.contains(tblname);
}
QString Schema::quoteValue(QString str) {
}
TableSchema *Schema::getTableSchema(QString name, bool refresh) {
QSharedPointer<TableSchema> Schema::getTableSchema(QString name, bool refresh) {
if (refresh) {
this->refresh();
}
if (this->tables.contains(name)) {
return this->tables.value(name).data();
return this->tables.value(name);
}
QString realName = this->getRawTable(name);
auto ts = this->loadTableSchema(realName);
if (ts.data()) {
this->tables.insert(name, ts);
}
return ts.data();
return ts;
}
QSharedPointer<Database> Schema::getDatabase() const {
......
void Schema::setDatabase(const QSharedPointer<Database> &value) {
database = value;
}
QSharedPointer<QueryBuilder> Schema::getQueryBuilder() const {
return queryBuilder;
}
QHash<QString, QSharedPointer<TableSchema> > Schema::getTables() const {
return this->tables;
src/schema.h
#include <QHash>
#include <QSharedPointer>
#include <QSqlField>
#include "querybuilder.h"
namespace CuteEntityManager {
class Database;
class Schema {
......
virtual QHash<QString, QString> *getTypeMap() = 0;
QHash<QString, QString> getAbstractDatabaseTypes();
virtual QString quoteSimpleTableName(QString name);
virtual QString quoteTableName(QString name);
virtual QString quoteColumnName(QString name);
virtual QString quoteSimpleColumnName(QString name);
virtual QHash<QString, QSharedPointer<TableSchema>> getTableSchemas(QString schema = "", bool refresh = false);
virtual QSharedPointer<TableSchema> getTableSchema(QString name, bool refresh = false);
virtual QStringList getTableNames(QString schema = "");
//virtual QueryBuilder getQueryBuilder();
//virtual QueryBuilder createQueryBuilder();
virtual QVariant getLastInsertID();
virtual void refresh();
virtual QString getRawTable(QString name);
virtual bool containsTable(QString tblname);
virtual QString quoteValue(QString str);
virtual void initQueryBuilder();
QHash<QString, QSharedPointer<TableSchema> > getTables() const;
void setTables(const QHash<QString, QSharedPointer<TableSchema> > &value);
......
QSharedPointer<Database> getDatabase() const;
void setDatabase(const QSharedPointer<Database> &value);
QSharedPointer<QueryBuilder> getQueryBuilder() const;
protected:
virtual QStringList findTableNames(QString schema = "") = 0;
virtual QHash<QString, QStringList> findUniqueIndexes(const QSharedPointer<TableSchema> &table) = 0;
virtual void findConstraints(const QSharedPointer<TableSchema> &ts) = 0;
virtual bool findColumns(const QSharedPointer<TableSchema> &ts) = 0;
virtual QSharedPointer<TableSchema> loadTableSchema(QString name) = 0;
virtual TableSchema *getTableSchema(QString name, bool refresh = false);
QSharedPointer<Database> database;
QSharedPointer<QHash<QString, QString>> typeMap;
QHash<QString, QSharedPointer<TableSchema>> tables;
QSharedPointer<QueryBuilder> queryBuilder;
};
src/schema/sqlitequerybuilder.cpp
#include "sqlitequerybuilder.h"
CuteEntityManager::SqliteQueryBuilder::SqliteQueryBuilder(QSharedPointer<CuteEntityManager::Schema> schema,
QSharedPointer<CuteEntityManager::Database> database) : QueryBuilder(schema, database) {
}
CuteEntityManager::SqliteQueryBuilder::~SqliteQueryBuilder() {
}
src/schema/sqlitequerybuilder.h
#ifndef SQLITEQUERYBUILDER_H
#define SQLITEQUERYBUILDER_H
#include "../querybuilder.h"
namespace CuteEntityManager {
class SqliteQueryBuilder : public QueryBuilder
{
public:
SqliteQueryBuilder(QSharedPointer<Schema> schema, QSharedPointer<Database> database);
~SqliteQueryBuilder();
};
}
#endif // SQLITEQUERYBUILDER_H
src/schema/sqliteschema.cpp
#include "../database.h"
#include <QSqlRecord>
#include <QSqlResult>
#include "sqlitequerybuilder.h"
using namespace CuteEntityManager;
SqliteSchema::SqliteSchema(QSharedPointer<Database> database) : Schema(database) {
this->queryBuilder = QSharedPointer<QueryBuilder>(new SqliteQueryBuilder(QSharedPointer<Schema>(this), database));
}
SqliteSchema::~SqliteSchema() {
......
}
QHash<QString, QString> *SqliteSchema::getTypeMap() {
/**
this->typeMap.data()->insert("bool", "SMALLINT");
this->typeMap.data()->insert("short", "SMALLINT");
this->typeMap.data()->insert("int", "INTEGER");
this->typeMap.data()->insert("long", "INTEGER");
this->typeMap.data()->insert("long long", "INTEGER");
this->typeMap.data()->insert("float", "FLOAT");
this->typeMap.data()->insert("double", "FLOAT");
this->typeMap.data()->insert("long double", "FLOAT");
this->typeMap.data()->insert("unsigned short", "SMALLINT");
this->typeMap.data()->insert("unsigned int", "INTEGER");
this->typeMap.data()->insert("unsigned long", "INTEGER");
this->typeMap.data()->insert("unsigned long long", "INTEGER");
this->typeMap.data()->insert("std::string", "TEXT");
this->typeMap.data()->insert("std::wstring", "TEXT");
this->typeMap.data()->insert("QString", "TEXT");
this->typeMap.data()->insert("QVariant", "TEXT");
this->typeMap.data()->insert("QUuid", "TEXT");
this->typeMap.data()->insert("QDate", "DATE");
this->typeMap.data()->insert("QTime", "TIME");
this->typeMap.data()->insert("QDateTime", "TIMESTAMP");
this->typeMap.data()->insert("QByteArray", "BLOB");
*/
if (this->typeMap.data()->empty()) {
this->typeMap.data()->insert(TYPE_SMALLINT, "tinyint");
this->typeMap.data()->insert(TYPE_BOOLEAN, "boolean");
......
QSqlQuery q2 = this->database.data()->getQuery();
q2.setForwardOnly(true);
if (q.value("unique").toBool()) {
q2.exec("PRAGMA index_info(" + this->quoteValue(indexName) + ")");
q2.exec("PRAGMA index_info(" + this->quoteSimpleTableName(indexName) + ")");
QStringList indexInfo = QStringList();
while (q2.next()) {
indexInfo.append(q2.value("name").toString());

Auch abrufbar als: Unified diff