--style=google --delete-empty-lines --add-brackets --convert-tabs --close-templates --break-after-logical --max-code-length=90 --pad-oper
You need to link against the CuteEntityManager lib.
#include "../src/entity.h"
class Person: public CuteEntityManager::Entity { //you can also use using namespace CuteEntityManager;
Q_OBJECT //really important!
EM_MACRO(Person) //aswell important, too!
Q_PROPERTY(QString firstName READ getFirstName WRITE setFirstName)
Q_PROPERTY(QString familyName READ getFamilyName WRITE setFamilyName)
//... getter and setter
private:
QString firstName;
QString familyName;
}
class Group: public CuteEntityManager::Entity {
Q_OBJECT
EM_MACRO(Group)
Q_PROPERTY(QList<QSharedPointer<Pupil>> pupils READ getPupils WRITE setPupils)
Q_PROPERTY(QList<QSharedPointer<Person>> persons READ getPersons WRITE
setPersons)
Q_PROPERTY(QString name READ getName WRITE setName)
Q_PROPERTY(QSharedPointer<Person> mainTeacher READ getMainTeacher WRITE
setMainTeacher)
//...
}
You must place the following code at a really early execution point:
#include "entityinstancefactory.h"
//...
CuteEntityManager::EntityInstanceFactory::registerClass<Person>();
CuteEntityManager::EntityInstanceFactory::registerClass<Group>();
If you don't do that, the entitymanager can't create dynamic instances of entities (especially needed for find method)
#include "../src/entitymanager.h"
//...
CuteEntityManager::EntityManager *em = new CuteEntityManager::EntityManager("QSQLITE", QDir::currentPath() + "/db.sqlite", "", "", "", 0, true);
QStringList inits = QStringList() << "Contact" << "Address" << "Person" <<
"Pupil" << "Group";
em->startup("0.1", inits,
true);
This creates tables for the entity classes Contact, Address, Person, Pupil and Group. Once called, the method "startup()" creates a new DatabaseMigration in the backgroud( http://jenkins.danfai.de/jenkins/job/cuteentitymanager/doxygen/class_cute_entity_manager_1_1_database_migration.html). The attribute "version" of DatabaseMigration has the value "0.1".
em->createTable("Person"); //if you don't want that relationTables will be created, please append a parameter with false
QSharedPointer<Entity> entity = QSharedPointer<Person>(new Person()).objectCast<Entity>();
em->createTable(entity);
See http://jenkins.danfai.de/jenkins/job/cuteentitymanager/doxygen/class_cute_entity_manager_1_1_entity_manager.html for more information.
When any method have been called, the database will be changed.
QSharedPointer<Person> person = QSharedPointer<Person>(new Person());
person->setFirstName("Max");
person->setFamilyName("Mustermann");
em->create(person.objectCast<Entity>());
//or
em->save(person.objectCast<Entity>());
//we reuse person from create
person->setFamilyName("Musterfrau");
em->merge(person.objectCast<Entity>());
//or
em->save(person.objectCast<Entity>());
em->remove(person.objectCast<Entity>());
em->remove<Person>(1); //id
There are several opportunities:
QSharedPointer<Entity> entity = em->findById(1, "Person");
QSharedPointer<Person> entity = em->findById<Person>(1);
QList<QSharedPointer<Person> entities = em->findAll<Person>();
QHash<QString, QVariant> attributes = QHash<QString, QVariant>();
attributes.insert("firstName","Max");
QSharedPointer<Person> max = em->findEntitiesByAttributes<Person>(attributes); //gives the first Person with firstName "Max"
QList<QSharedPointer<Person>> multiMax = em->findAllEntitiesByAttributes<Person>(attributes); //gives all Persons with firstName "Max"
QList<QSharedPointer<Person>> sqlMax = em->findEntitiesBySql<Person>("SELECT * FROM person WHERE firstName = \"Max\"); //same as findEntitiesByAttributes
See http://jenkins.danfai.de/jenkins/job/cuteentitymanager/doxygen/class_cute_entity_manager_1_1_query.html and http://jenkins.danfai.de/jenkins/job/cuteentitymanager/doxygen/class_cute_entity_manager_1_1_query_builder.html
Simple example:
Query query = Query();
query.appendWhere(e->getQueryBuilder()->like(QString("firstname"), QString("Ma"),
JokerPosition::BEHIND));
query.appendWhere(e->getQueryBuilder()->andOperator());
query.appendWhere(e->getQueryBuilder()->arbitraryOperator("<", "birthday",
QDate(1950, 10, 10)));
query.setDistinct(true);
query.appendOrderBy(OrderBy(QString("birthday"), Direction::SORT_DESC));
query.setLimit(10);
QList<QSharedPointer<Person>> list = e->find<Person>(query, true);
This would generate:
SELECT DISTINCT * FROM person WHERE firstname LIKE "Ma%" AND birthday < "1950-10-10" ORDER BY birthday DESC LIMIT 10;
See http://jenkins.danfai.de/jenkins/job/cuteentitymanager/doxygen/class_cute_entity_manager_1_1_relation.html for more information about the "Relation" class.
Class Entitiy has this method:
virtual const QHash<QString, Relation> getRelations() const;
const QHash<QString, CuteEntityManager::Relation> Person::getRelations() const {
QHash<QString,CuteEntityManager::Relation> hash = QHash<QString, CuteEntityManager::Relation>();
//... relations
return hash;
}
//Relation to class Person from class Group
//Headerfile:
Q_PROPERTY(QSharedPointer<Person> mainTeacher READ getMainTeacher WRITE setMainTeacher)
QSharedPointer<Person> getMainTeacher() const;
void setMainTeacher(const QSharedPointer<Person> &value);
QSharedPointer<Person> mainTeacher;
//Implementation in getRelations:
hash.insert("mainTeacher", CuteEntityManager::Relation("mainTeacher", RelationType::MANY_TO_ONE));
//Relation to class Group from class Person
//Headerfile:
Q_PROPERTY(QList<QSharedPointer<Group>> maintainedGroups READ getMaintainedGroups WRITE setMaintainedGroups)
QList<QSharedPointer<Group> > getMaintainedGroups() const;
void setMaintainedGroups(const QList<QSharedPointer<Group> > &value);
QList <QSharedPointer<Group>> maintainedGroups;
//Implementation in getRelations:
hash.insert("maintainedGroups", CuteEntityManager::Relation("maintainedGroups",RelationType::ONE_TO_MANY,QString("mainTeacher")));
//Third parameter is "mappedBy". This means that this relation is already defined in class Group (as many-to-one).
//Relation to class Address from class Person
//Headerfile:
Q_PROPERTY(QList<QSharedPointer<Address>> addresses READ getAddresses WRITE setAddresses)
QList<QSharedPointer<Address> > getAddresses() const;
void setAddresses(const QList<QSharedPointer<Address> > &value);
QList <QSharedPointer<Address>> addresses;
//Implementation in getRelations:
hash.insert("addresses", CuteEntityManager::Relation("addresses", RelationType::MANY_TO_MANY));
Special case of Many-To-One. You can use a syntax similiar to the one used in Many-To-One or/and One-To-Many.
Class "Entitiy" has this method:
virtual const QStringList getTransientAttributes() const;
const QStringList Person::getTransientAttributes() const {
QStringList list = QStringList();
list.append("firstName"); // Attribute firstName won't persisted
return list;
}
Entity has this method:
//header
virtual InheritanceStrategy getInheritanceStrategy() const;
//cpp
InheritanceStrategy Entity::getInheritanceStrategy() const {
return InheritanceStrategy::JOINED_TABLE;
}
If you choose PER_CLASS_TABLE, you can get these tables (if you let EntityManager create them for you):
First table:
Person - with columns "id", "firstName", "lastName"
Second table:
Pupil - with columns "id", "firstName", "lastName" and "guardianNote". Both tables are NOT joined. They don't have any relation.
Entity has this method:
//header
virtual bool isInheritanceCascaded() const;
//cpp
bool Entity::isInheritanceCascaded() const {
return true;
}
For example: you have the class "Person" and the class "Pupil" (which inherits from Person). If this method returns true, a Person will also be deleted if you remove a Pupil object.
There are several validators: CompareValidator, EmailValidator, NumberValidator, etc.
virtual QList<ValidationRule> validationRules() const;
QList<ValidationRule> Person::validationRules() const {
QList<ValidationRule> rules = QList<ValidationRule>();
rules.append(ValidationRule("length", {"firstName", "familyName"}, "min", 2));
rules.append(ValidationRule("date", "birthday", "past", "", "min", QDate(1973, 1, 1)));
return rules;
}
em->validate(entity);
entity->getErrors();
(returns QList<ErrorMsg>) or you can call entity->getErrorsAsString()
entity->hasErrors()
(returns bool)
Example:
QSharedPointer<Entity> p1 = QSharedPointer<Person>(new Person("Thomas", "B", Person::Gender::MALE, "", QString(), QString(), QDate(), 0));
//validation takes also place before save/create/merge
qDebug() << "p1 valid:" << e->validate(p1);
Validate would give back a "false" cause the lastname is too short (only "B" was specified but string length must be longer than or equal to 2).em->create()
, em->merge()
and em->save()
will also call "validate" method. You can disable the validation in these method calls if you provide additional parameters. For additional information look into the Validators sample provided by the repository.
/**
* You can define the following validators:
* "compare" -> CompareValidator (Params: ==, !=, <,>,<=,>=)
* "default" -> DefaultValidator You must only provide a value. Param name can be empty.
* "email" -> EmailValidator You can provide "full" param.
* It would check "Max Example<max.example@synlos.net>".
* Without this param it checks for "max.example@synlos.net"
* "exists" -> ExistValidator Checks if a MANY_TO_ONE/ONE_TO_ONE Relation Entity already has a ID
* "file" -> FileValidator (Params: mimeTypes, extensions, minSize, maxSize)
* "image" -> ImageValidator !Only Available when the EM was compiled with QT += gui
* (Params: minWidth, maxWidth, minHeight, maxHeight)
* "number" -> NumberValidator (Params: min, max)
* "date" -> DateValidator (Params: future, past, min, max)
* "required" -> RequiredValidator If specified it checks if a QVariant is null or a QString is empty
* "unique" -> UniqueValidator - Not done, checks if a value was already used
* "url" -> UrlValidator (Params: defaultSchemes) Checks for a valid URL(https://... or http://...)
* "pattern" -> PatternValidator You can define a param Name, but you only need to provide a Param value with the Pattern for the regular expression
* "length"-> LengthValidator (Params: min, max)
*
* You must override virtual QList<ValidationRule> validationRules() const; of Entity Class
* You can define a ValidationRule for example with:
* ValidationRule("length", {"firstName", "familyName"}, "min", 2);
* First is everytime the shortcut of the specific validator
* Second must be a single attribute or a list of attributes
* Then you can specify the params with values.
*/
Daily up to date doxygen documentation:
http://jenkins.danfai.de/jenkins/job/cuteentitymanager/doxygen/