QxOrm Windows Linux Macintosh C++

Accueil Téléchargement Exemple rapide Tutoriel (4)
Manuel (2)
Forum Nos clients

QxOrm >> Manuel d'utilisation de l'application QxEntityEditor
Version courante :  QxOrm 1.4.4 - documentation en ligne de la bibliothèque QxOrm
QxEntityEditor 1.2.2
Version française du site Web site english version
Sélection du manuel : Manuel QxOrm Manuel QxEntityEditor


Manuel d'utilisation de l'application QxEntityEditor - Table des matières

  1. Introduction
    1. QxEntityEditor : éditeur graphique pour la bibliothèque QxOrm
    2. Téléchargement et installation
    3. Vidéos de présentation de l'application QxEntityEditor
  2. Présentation générale
    1. Vues de l'écran principal de QxEntityEditor
      1. Zoomer/dézoomer le diagramme d'entités
      2. Affichage en mode "splitter"
    2. Paramétrage de l'application QxEntityEditor
    3. Enregistrer un code licence
    4. Créer/ouvrir un projet *.qxee
      1. Architecture d'un fichier projet *.qxee (base de données SQLite)
    5. Paramétrage d'un projet *.qxee
    6. Gestion des entités
      1. Créer une entité
      2. Modifier une entité
      3. Supprimer une entité
      4. Cloner une entité
      5. Paramètres d'une entité
      6. Couleur associée à une entité
    7. Gestion des propriétés associées à une entité
      1. Ajouter/modifier/supprimer une propriété
      2. Paramétrage détaillé d'une propriété
    8. Gestion des relations entre entités
      1. Ajouter/modifier/supprimer une relation
      2. Paramétrage détaillé d'une relation
    9. Gestion des énumérations
      1. Ajouter/modifier/supprimer/cloner une énumération
      2. Paramètres d'une énumération
      3. Couleur associée à une énumération
    10. Gestion des espaces de nom (namespace)
      1. Renommer un espace de nom
      2. Gestion des couleurs d'un espace de nom
    11. Gestion des notes (ou post-it)
      1. Ajouter/modifier/supprimer/cloner une note
      2. Couleur associée à une note
    12. Organisation automatique du diagramme d'entités
    13. Historique d'un projet *.qxee
    14. Aperçu du code C++ d'une entité/énumération
    15. Convention de nommage (snake_case, camelCase)
    16. Liste des plugins disponibles
  3. Plugins d'import
    1. Importer un projet à partir d'un fichier texte au format JSON
    2. Importer à partir d'une base de données MySQL ou MariaDB
    3. Importer à partir d'une base de données PostgreSQL
    4. Importer à partir d'une base de données SQLite
    5. Importer à partir d'une base de données en utilisant un driver ODBC (Oracle, MS SQL Server, etc.)
  4. Plugins d'export
    1. Exporter en projet C++
      1. Paramètres de l'export C++
      2. Présentation du projet C++ généré
      3. Compilation du projet C++ généré (par qmake ou cmake)
      4. Exemple d'utilisation
    2. Exporter en projet C++ de type model/view
      1. Paramètres de l'export
      2. Présentation du projet généré
    3. Exporter en projet C++ de type services
      1. Paramètres de l'export
      2. Présentation du projet généré
      3. Serveur d'applications générique
    4. Exporter le schéma de base de données SQL DDL
    5. Imprimer le diagramme d'entités
    6. Exporter le projet sous format XML ou JSON
  5. Moteur Javascript pour personnaliser les exports
    1. Architecture et fonctionnement du moteur de personnalisation Javascript
      1. Liste des paramètres d'appel du moteur Javascript
    2. Fonctions disponibles par Javascript
      1. Obtenir les informations associées à une entité
      2. Parcourir la liste des propriétés d'une entité
      3. Obtenir les informations associées à une propriété
      4. Obtenir les informations associées à une énumération
      5. Accès aux méta-données d'une entité/propriété/énumération
      6. Accéder aux variables d'environnement
      7. Gestion des fichiers : lecture et écriture
      8. Obtenir la liste des toutes les entités/énumérations d'un projet
      9. Récupérer le paramétrage de l'application (niveau global, projet et plugin)
    3. Ajout d'une action (placeholder) personnalisée dans le template d'export C++
    4. Exemple de script : ajout automatique de la définition Q_PROPERTY sur les propriétés C++ générées
    5. Activation du débogueur Javascript intégré
  6. Exécution de scripts personnalisés avant/après exécution d'un plugin
  7. Exécuter QxEntityEditor en ligne de commande
qt_ambassador
QxOrm library has been accepted into the Qt Ambassador Program


Introduction

L'objectif de ce manuel utilisateur est de présenter de manière structurée l'ensemble des fonctionnalités proposées par l'application QxEntityEditor (éditeur graphique de la bibliothèque QxOrm). Ce manuel est destiné aux développeurs et architectes logiciel qui souhaitent gérer une couche de données persistante en C++/Qt. Des compétences techniques en C++ et base de données sont requises pour la bonne compréhension de ce document.

Remarque : un manuel utilisateur dédié à la bibliothèque QxOrm est également disponible.

QxEntityEditor : éditeur graphique pour la bibliothèque QxOrm

QxEntityEditor est un éditeur graphique pour la bibliothèque QxOrm : QxEntityEditor permet de gérer graphiquement le modèle d'entités.
QxEntityEditor est multi-plateforme (disponible pour Windows, Linux et Mac OS X) et génère du code natif pour tous les environnements : bureau (Windows, Linux, Mac OS X), embarqué et mobile (Android, iOS, Windows Phone, Raspberry Pi, etc.).

QxEntityEditor est basé sur un système de plugins et propose diverses fonctionnalités pour importer/exporter le modèle de données :
QxEntityEditor on Windows QxEntityEditor on Linux QxEntityEditor on Mac OS X
QxEntityEditor on Windows QxEntityEditor on Linux QxEntityEditor on Mac OS X


QxEntityEditor est développé par Lionel Marty, Ingénieur en développement logiciel depuis 2003.


Téléchargement et installation

L'application QxEntityEditor peut être téléchargée sur la page de téléchargement du site QxOrm. Plusieurs versions sont disponibles :
  • Windows (de Windows XP à Windows 10) en mode 32bits et 64bits ;
  • Linux (les distributions les plus populaires sont supportées, Ubuntu, Fedora, etc...) en mode 32bits et 64bits ;
  • Mac OS X (64bits uniquement).
Pour Windows, QxEntityEditor est disponible avec un setup d'installation ou bien un fichier ZIP portable.
Pour Linux et Mac OS X, QxEntityEditor est disponible uniquement en fichier ZIP portable.
Aucune dépendance supplémentaire n'est requise, l'installation est très simple : il suffit de dézipper le fichier téléchargé et de lancer l'exécutable QxEntityEditor.

Vidéos de présentation de l'application QxEntityEditor

Voici une vidéo de présentation de l'application QxEntityEditor :



Cette vidéo présente les étapes suivantes :
  • Télécharger et installer la bibliothèque QxOrm (10s) ;
  • Télécharger et installer l'application QxEntityEditor (56s) ;
  • Créer un projet QxEntityEditor (1m 46s) ;
  • Exporter les entités vers un projet C++/Qt (8m 26s) ;
  • Exporter les entités vers un script DDL SQL de base de données (10m 22s) ;
  • Créer une application client/serveur pour transférer son modèle de données sur le réseau (12m 31s) ;
  • Exporter un projet QxEntityEditor vers un fichier XML ou JSON (17m 13s) ;
  • Exécuter QxEntityEditor en ligne de commande (sans IHM) (18m 07s).



Voici une autre vidéo de l'application QxEntityEditor pour montrer comment importer une structure de base de données existante (projet MySQL Workbench) :



Cette vidéo présente les étapes suivantes :
  • Projet MySQL Workbench - exemple de base de données Sakila (10s) ;
  • Création d'un DSN pour se connecter à MySQL par ODBC (46s) ;
  • Import de la structure de base de données dans un projet QxEntityEditor (1m 15s) ;
  • Export du projet QxEntityEditor vers un projet C++ Qt (3m 10s) ;
  • Compilation des classes générées du projet C++ Qt (4m 22s).

Présentation générale

QxEntityEditor est un éditeur graphique permettant de gérer : entités, propriétés, relations entre entités, énumérations, espaces de nom (namespace). Pour faire le lien entre la base de données et le code C++ :
  • une entité correspond à une table côté base de données, et à une classe côté code C++ ;
  • une propriété correspond à une colonne d'une table côté base de données, et à une donnée membre d'une classe côté code C++ ;
  • une relation (1-n, n-1, 1-1 ou n-n) correspond à une liaison entre 2 tables de la base de données (clé étrangère), et à une liaison entre 2 classes C++ ;
  • une énumération correspond à une liste de valeurs disponibles côté code C++ (pour le moment pas de notion côté base de données : converti en valeur numérique) ;
  • un espace de nom (namespace) correspond à un schéma de base de données, et un namespace où se trouve une classe côté code C++.

Vues de l'écran principal de QxEntityEditor

Voici une copie écran présentant les différentes zones d'affichage de l'application QxEntityEditor :

All views

  • Zone 1 : menu principal et barre d'outils de l'application QxEntityEditor ==> toutes les actions sont accessibles par ces boutons ;
  • Zone 2 : liste déroulante permettant d'accéder rapidement aux projets chargés récemment ;
  • Zone 3 : liste sous forme d'arbre (tree view) présentant les éléments du projet chargés (entités, propriétés, relations, énumérations, espaces de nom) ;
  • Zone 4 : vue "Navigator" permettant de se déplacer rapidement dans le diagramme d'entités (particulièrement utile pour des projets volumineux) ;
  • Zone 5 : diagramme d'entités affichant tous les éléments du projet dans un vue graphique ;
  • Zone 6 : écran de paramétrage (sous forme d'onglets) des entités, propriétés, relations, énumérations + prévisualisation du code C++ ;
  • Zone 7 : zoom sur le diagramme d'entités.

Zoomer/dézoomer le diagramme d'entités

Il est possible de zoomer/dézoomer le diagramme d'entités :
  • par le menu principal : View >> Zoom view to XX% ;
  • par la petite fenêtre (slider) tout en bas à droite de l'écran ;
  • par menu contextuel suite à un clic-droit sur le diagramme d'entités, sous menu : View >> Zoom view to XX% ;
  • en maintenant clic-gauche + molette de la souris sur le diagramme d'entités.

Zoom

Affichage en mode "splitter"

Le menu View >> Show/hide splitter mode permet de basculer l'affichage des onglets des paramètres des entités, propriétés, relations, énumérations + prévisualisation du code C++ :
  • sur la partie droite de l'écran permettant d'avoir un accès rapide à la fois sur le diagramme d'entités et le détails des paramètres de l'élément sélectionné ;
  • masqué sous forme d'oglets permettant d'afficher le diagramme d'entités en mode plein écran (valeur par défaut).

Splitter mode

Paramétrage de l'application QxEntityEditor

L'accès au paramétrage global (pour tous les projets) de l'application QxEntityEditor se fait par le menu principal Tools >> Global settings :

Global settings
  • Champ « QxOrm library path » : chemin d'accès au répertoire de la bibliothèque QxOrm. Ce paramètre est requis pour démarrer un export C++ afin de trouver le fichier de configuration QxOrm.pri (ou QxOrm.cmake). Il est possible de renseigner un chemin absolu, ou bien d'indiquer une variable d'environnement, par exemple : $$(QXORM_DIR) ;
  • Champ « Auto load last opened project at startup » : démarre QxEntityEditor en chargeant automatiquement le dernier projet ouvert ;
  • Champ « Display property type in entities viewer » : affiche sur le diagramme d'entités le type des propriétés ;
  • Champ « Use old style to draw relationships » : simplifie l'affichage des relations (1-n, n-1, 1-1 ou n-n) ;
  • Champ « Disable undo/redo feature » : désactive la fonctionnalité undo/redo, peut être utile pour optimiser les performances sur des projets volumineux ;
  • Champs « Entity/Enum/Comment width » : permet de régler la largeur par défaut des éléments graphiques.

Enregistrer un code licence

Sans clé de licence valide, un projet QxEntityEditor est limité à 5 entités par projet. Afin de supprimer cette limitation, l'accès à l'enregistrement d'un code licence se fait par le menu principal Help >> License information :

License

Il suffit d'entrer la clé de license fournie dans le champ License key, puis d'appuyer sur le bouton Save. Un accès à internet est requis pour l'enregistrement d'une clé de licence. Si aucune erreur n'apparait, la clé de licence est enregistrée et l'application QxEntityEditor peut alors être utilisée sans aucune limitation jusqu'à la date indiquée dans le champ Expiration date.

Remarque : si une erreur de connexion internet apparait au moment de l'enregistrement, vous pouvez essayer de cocher la case If you are behind a proxy....

Autre remarque : pour acquérir une clé de licence valide, vous pouvez nous contacter à l'adresse suivante : contact@qxorm.com

Créer/ouvrir un projet *.qxee

La création d'un nouveau projet QxEntityEditor se fait par le menu principal File >> New project :

Project new
  • Champ « Project name » : nom du projet QxEntityEditor. Le fichier du nouveau projet portera le même nom avec l'extension *.qxee ;
  • Champ « Project location » : chemin d'accès au fichier associé au projet QxEntityEditor. Il est possible d'utiliser le bouton "..." afin de sélectionner le répertoire de destination.

L'ouverture d'un projet QxEntityEditor se fait par le menu principal File >> Open project : il suffit de sélectionner un fichier projet avec l'extension *.qxee. Sous la barre d'outils du menu principal, une liste des projets récents est disponible et permet de basculer rapidement d'un projet à un autre :

Project list

Architecture d'un fichier projet *.qxee (base de données SQLite)

Un fichier projet *.qxee de l'application QxEntityEditor est une base de données SQLite.
Un même projet peut être partagé sur tous les environnements supportés par QxEntityEditor : Windows, Linux et Mac OS X.
Un fichier projet *.qxee peut être ouvert par un outil de gestion de base de données SQLite : par exemple, le plugin gratuit de Firefox SQLite Manager :

Project database

Remarque : en utilisant la fonctionnalité Exécution de scripts personnalisés avant/après exécution d'un plugin, il est possible par exemple d'appliquer un script (.bat ou .sh) modifiant certaines données du projet SQLite *.qxee après un import de base de données par exemple.

Paramétrage d'un projet *.qxee

Le paramétrage d'un projet QxEntityEditor *.qxee se fait par le menu principal Tools >> Project settings :

Project settings tab 1

  • Champ « Default entity namespace » : espace de nom par défaut des entités à leur création (il est possible de définir un autre espace de nom dans l'écran de paramétrage d'une entité) ;
  • Champ « Table name prefix » : préfixe à appliquer sur la table associée à une entité ;
  • Champ « Table name suffix » : suffixe à appliquer sur la table associée à une entité ;
  • Champ « Primary key prefix » : préfixe par défaut de la clé primaire d'une entité ;
  • Champ « Primary key suffix » : suffixe par défaut de la clé primaire d'une entité ;
  • Champ « Default primary key type » : type C++ par défaut pour les clés primaires ;
  • Champ « Default property type » : type C++ par défaut pour les propriétés des entités.

Le 2ème onglet de l'écran de paramétrage d'un projet permet de gérer les couleurs des différents éléments du diagramme d'entités au niveau projet :

Project settings tab 2

Remarque : les couleurs des éléments du diagramme d'entités peuvent être gérées à plusieurs niveaux (du niveau le plus global au plus spécifique) :

Gestion des entités

Une entité dans l'application QxEntityEditor correspond à une table de la base de données, et correspond également à une classe (persistante et enregistrée dans le contexte QxOrm) dans le code C++. L'application QxEntityEditor permet de créer, modifier, supprimer et cloner une entité.

Créer une entité

La création d'une nouvelle entité se fait par :
  • Le menu principal : Actions >> New entity ;
  • Un menu contextuel sur clic-droit dans le diagramme d'entités : Entity >> New entity ;
  • Le bouton Create a new entity sur l'écran de paramétrage d'une entité lorsque aucune entité n'est sélectionnée.

Entity new

Remarque : ces actions ouvrent l'écran de paramétrage d'une entité en mode création. L'entité sera réellement créée et ajoutée au projet *.qxee au moment de l'enregistrement de l'écran de paramétrage.

Modifier une entité

La modification d'une entité se fait par :
  • Le menu principal : Actions >> Modify entity ;
  • Un menu contextuel sur clic-droit dans le diagramme d'entités : Entity >> Modify entity ;
  • Le double-clic sur le nom d'une entité dans le diagramme.

Entity modify

Remarque : ces actions ouvrent l'écran de paramétrage d'une entité en mode modification. Les modifications de l'entité seront réellement appliquées au projet *.qxee au moment de l'enregistrement de l'écran de paramétrage.

Supprimer une entité

La suppression d'une (ou plusieurs) entité se fait par :
  • Le menu principal : Actions >> Delete entity ;
  • Un menu contextuel sur clic-droit dans le diagramme d'entités : Entity >> Delete entity ;
  • La touche "Suppr" du clavier lorsqu'une (ou plusieurs) entité est sélectionnée.

Entity delete

Cloner une entité

Le clonage d'une entité se fait par :
  • Le menu principal : Actions >> Clone entity ;
  • Un menu contextuel sur clic-droit dans le diagramme d'entités : Entity >> Clone entity ;

Entity clone

Remarque : une entité clonée dispose de toutes les propriétés de l'entité source. Les relations ne sont pas clonées.

Paramètres d'une entité

Les paramètres de l'entité sélectionnée sont accessibles dans l'onglet de paramétrage Entity :

Entity settings

Cet écran de paramétrage est divisé en plusieurs sections :

-- Section Entity information (version XX) : la version de l'entité est incrémentée à chaque historique de projet créé.
  • Champ « Name » : nom de l'entité et de la classe C++ générée ;
  • Champ « Table name » : nom de la table en base de données associée à l'entité (utilise le préfixe/suffixe par défaut défini dans les paramètres du projet) ;
  • Champ « Namespace » : espace de nom de l'entité et de la classe C++ associée, chaque sous-namespace doit être séparé par ::, par exemple : ns1::ns2::ns3 ;
  • Champ « Description » : description de l'entité (apparait dans le code C++ généré) ;
  • Champ « Inherit from » : entité parente (ou classe C++ de base) : l'entité fille récupère automatiquement la clé primaire et la liste des propriétés définies dans l'entité parente ;
  • Champ « Read only » : si coché, alors entité en lecture seule : la bibliothèque QxOrm autorise uniquement des requêtes SQL de type SELECT sur l'entité (fonctions de récupération/fetch du namespace qx::dao de QxOrm). Si coché, alors les requêtes SQL de type INSERT, UPDATE et DELETE ne sont pas disponibles. Ce paramètre peut par exemple être utilisé pour mapper une entité à une vue (lecture seule) de la base de données ;
  • Champ « Abstract » : une entité abstraite n'a pas de table associée dans la base de données, et la classe C++ générée ne peut pas être instantiée (classe abstraite) : ce paramètre peut être utile par exemple pour créer des entités parentes contenant une liste de propriétés communes à toutes les autres entités ;
  • Champ « Soft delete column » : si vide, une suppression de l'entité en base de données correspond à une suppression physique. Si non vide, ce champ correspond à la colonne en base de données utilisée pour effectuer une suppression logique (conserve les informations de suppression et l'entité reste en base de données).
  • Champ « Validator method name » : nom de la méthode de validation (par exemple IsValid) utilisée pour valider une entité avant insertion et modification en base de données. L'implémentation de la méthode de validation est à la charge du développeur dans son propre fichier source *.cpp : voir le module QxValidator de la bibliothèque QxOrm pour plus de détails.

-- Section Entity triggers :
  • Cases à cocher « Before fetch, After fetch, Before insert, etc... » : si coché(s), ajoute les définitions dans le code C++ des méthodes onBeforeFetch(), onAfterFetch(), onBeforeInsert(), etc... L'implémentation des méthodes de trigger est à la charge du développeur dans son propre fichier source *.cpp : voir le manuel utilisateur de la bibliothèque QxOrm pour plus de détails.

-- Section Primary key property : définition rapide de la clé primaire (un paramétrage détaillé de la clé primaire de l'entité est disponible).
-- Section List of properties : définition rapide de la liste des propriétés (un paramétrage détaillé des propriétés de l'entité est disponible). Cette liste peut être ordonnée par les 2 boutons flèche haut et flèche bas.
  • Colonne « Name » : nom de la propriété de l'entité, et nom de la donnée membre associée dans le code C++ ;
  • Colonne « Type » : type C++ de la propriété (le type par défaut peut être défini dans les paramètres du projet) ;
  • Colonne « Decoration » : ajoute une décoration au type C++ (par exemple boost::optional pour gérer les valeurs NULL) ;
  • Colonne « Collection » : si la propriété est une liste, alors défini le type de liste C++ ;
  • Colonne « Default value » : valeur par défaut de la propriété ;
  • Colonne « Index » : optimisation des requêtes SQL de type SELECT pour les recherches en base de données ;
  • Colonne « Transient » : si coché, alors la donnée membre C++ n'est pas mappée à une colonne de la base de données (la propriété est enregistrée dans le contexte QxOrm mais n'est pas persistante) ;
  • Bouton « Delete » : supprime la propriété de la liste.

-- Section List of relationships : définition rapide de la liste des relations (un paramétrage détaillé des relations de l'entité est disponible). Cette liste peut être ordonnée par les 2 boutons flèche haut et flèche bas.
  • Colonne « Name » : nom de la relation, et nom de la donnée membre associée dans le code C++ ;
  • Colonne « Target » : entité cible ;
  • Colonne « n-1 » : type de relation many-to-one ;
  • Colonne « 1-n » : type de relation one-to-many ;
  • Colonne « n-n » : type de relation many-to-many ;
  • Colonne « 1-1 » : type de relation one-to-one ;
  • Colonne « Decoration » : ajoute une décoration au type C++ (pour les relations, la bibliothèque QxOrm recommande l'utilisation de pointeurs intelligents : boost::shared_ptr, std::shared_ptr ou QSharedPointer) ;
  • Colonne « Collection » : si le type de relation nécessite une liste (1-n et n-n), alors défini le type de liste C++ ;
  • Colonne « Foreign key » : clé étrangère de la relation : nom d'une propriété de l'entité cible ;
  • Bouton « Delete » : supprime la relation de la liste.

-- Section List of meta-data : les méta-données permettent d'ajouter des paramètres supplémentaires et sont accessibles dans le code C++ (moteur d'introspection de QxOrm) et le moteur Javascript de personnalisation des exports de QxEntityEditor.
  • Colonne « Key » : clé de la méta-donnée ;
  • Colonne « Value » : valeur de la méta-donnée ;
  • Bouton « Delete » : supprime la méta-donnée de la liste.

Couleur associée à une entité

Les couleurs d'une entité peuvent être modifiées par le menu contextuel sur un clic-droit sur une entité Define entity colors :

Entity colors

Remarque : les couleurs des éléments du diagramme d'entités peuvent être gérées à plusieurs niveaux (du niveau le plus global au plus spécifique) :

Gestion des propriétés associées à une entité

Une propriété dans l'application QxEntityEditor correspond à une colonne d'une table de la base de données, et correspond également à une donnée membre d'une classe C++ (enregistrée dans le contexte QxOrm). L'application QxEntityEditor permet de créer, modifier, supprimer et ordonner les propriétés d'une entité.

Ajouter/modifier/supprimer une propriété

L'ajout et la suppression d'une propriété se fait depuis l'écran de paramétrage d'une entité : la section List of properties de cet écran de paramétrage permet d'ajouter et supprimer des propriétés. Il est également possible d'ordonner cette liste pour positionner les propriétés dans l'ordre voulu.

La modification d'une propriété est accessible par un bouton qui s'affiche sur le diagramme d'entités lorsque la souris est positionnée sur une propriété :

Property settings access

Paramétrage détaillé d'une propriété

Les paramètres détaillés d'une propriété sélectionnée sont accessibles dans l'onglet de paramétrage Property :

Property settings

Cet écran de paramétrage est divisé en plusieurs sections :

-- Section Property information (version XX) : la version de la propriété dépend du niveau d'historique du projet.
  • Champ « Name » : nom de la propriété de l'entité, et nom de la donnée membre associée dans le code C++ ;
  • Champ « Column name » : nom de la colonne dans la base de données (si vide, alors Column name == Name) ;
  • Champ « Description » : description de la propriété (apparait dans le code C++ généré) ;
  • Champ « Index » : optimisation des requêtes SQL de type SELECT pour les recherches en base de données ;
  • Champ « Transient » : si coché, alors la donnée membre C++ n'est pas mappée à une colonne de la base de données (la propriété est enregistrée dans le contexte QxOrm mais n'est pas persistante) ;
  • Champ « Serializable » : si coché, la propriété est prise en compte par le moteur de sérialisation de la bibliothèque QxOrm ;
  • Champ « Obsolete » : cocher cette option pour supprimer une propriété sans casser la compatibilité ascendante du moteur de sérialisation de la bibliothèque QxOrm : la propriété devient privée sans accesseur Get/Set.

-- Section Property type :
  • Champ « Type » : type C++ de la propriété (le type par défaut peut être défini dans les paramètres du projet) ;
  • Champ « Decoration » : ajoute une décoration au type C++ (par exemple boost::optional pour gérer les valeurs NULL) ;
  • Champ « Default value » : valeur par défaut de la propriété ;
  • Champ « Collection » : si la propriété est une liste, alors défini le type de liste C++.

-- Section Property validation : validation d'une propriété avant insertion/modification en base de données par le module QxValidator de la bibliothèque QxOrm.
  • Champ « Min value » : valeur minimale autorisée pour une propriété de type numérique ;
  • Champ « Max value » : valeur maximale autorisée pour une propriété de type numérique ;
  • Champ « Min length » : longueur minimale autorisée pour une propriété de type chaine de caractères ;
  • Champ « Max length » : longueur maximale autorisée pour une propriété de type chaine de caractères ;
  • Champ « Regular expression » : expression régulière utilisée pour valider la valeur d'une propriété ;
  • Champ « Not NULL » : vérifie que la valeur de la propriété n'est pas NULL ;
  • Champ « Unique » : valeur unique en base de données : 2 lignes dans la table ne peuvent avoir la même valeur sur la colonne associée à cette propriété.

-- Section Advanced :
  • Champ « Accessibility », valeurs « public, protected ou private » : une propriété public est accessible sans accesseur Get/Set, une propriété protected est accessible uniquement par les classes dérivées, une propriété private est accessible uniquement par les accesseurs Get/Set ;
  • Champ « SQL type » : la bibliothèque QxOrm associe automatiquement un type SQL en fonction du type C++ de la propriété, il est possible de surcharger le type SQL par défaut avec ce paramètre ;
  • Champ « SQL alias » : force un alias sur cette colonne utilisé par la bibliothèque QxOrm lors de la construction des requêtes SQL ;
  • Champ « Format » : défini le format (syntaxe printf) de la propriété pour le stockage en base de données (peut être utile pour gérer les dates et heures par exemple) ;
  • Champ « Get/Set accessors » : si coché, des accesseurs Get/Set seront disponibles dans la classe C++ pour accéder/modifier la valeur de la propriété ;
  • Champ « Read only » : si coché, un seul accesseur Get est disponible dans la classe C++, ce qui rend la propriété en lecture seule ;
  • Champ « Get method implementation » : permet de surcharger l'implémentation par défaut de la méthode Get dans la classe C++ pour accéder à la valeur de la propriété ;
  • Champ « Set method implementation » : permet de surcharger l'implémentation par défaut de la méthode Set dans la classe C++ pour modifier la valeur de la propriété.

-- Section List of meta-data : les méta-données permettent d'ajouter des paramètres supplémentaires et sont accessibles dans le code C++ (moteur d'introspection de QxOrm) et le moteur Javascript de personnalisation des exports de QxEntityEditor.
  • Colonne « Key » : clé de la méta-donnée ;
  • Colonne « Value » : valeur de la méta-donnée ;
  • Bouton « Delete » : supprime la méta-donnée de la liste.

Gestion des relations entre entités

Une relation entre 2 entités (1-n, n-1, 1-1 ou n-n) dans l'application QxEntityEditor permet de lier 2 tables dans la base de données, et 2 classes dans le code C++. L'application QxEntityEditor permet de créer, modifier, supprimer et ordonner les relations d'une entité.

Ajouter/modifier/supprimer une relation

L'ajout et la suppression d'une relation se fait depuis l'écran de paramétrage d'une entité : la section List of relationships de cet écran de paramétrage permet d'ajouter et supprimer des relations. Il est également possible d'ordonner cette liste pour positionner les relations dans l'ordre voulu.

La modification d'une relation est accessible par un bouton qui s'affiche sur le diagramme d'entités lorsque la souris est positionnée sur une relation :

Relation settings access

Paramétrage détaillé d'une relation

Les paramètres détaillés d'une relation sélectionnée sont accessibles dans l'onglet de paramétrage Relationship :

Relation settings

Cet écran de paramétrage est divisé en plusieurs sections :

-- Section Relationship information (version XX) : la version de la relation dépend du niveau d'historique du projet.
  • Champ « Name » : nom de la relation, et nom de la donnée membre associée dans le code C++ ;
  • Champ « Target » : entité cible ;
  • Champ « Description » : description de la relation (apparait dans le code C++ généré) ;
  • Champs « 1-n, n-1, 1-1 ou n-n » : type de relation, suivant le type sélectionné certains paramètres sont actifs ou inactifs ;
  • Champ « Column name » : actif uniquement pour les relations de type n-1, nom de la colonne dans la base de données (si vide, alors Column name == Name) ;
  • Champ « Decoration » : ajoute une décoration au type C++ (pour les relations, la bibliothèque QxOrm recommande l'utilisation de pointeurs intelligents : boost::shared_ptr, std::shared_ptr ou QSharedPointer) ;
  • Champ « Collection » : si le type de relation nécessite une liste (1-n et n-n), alors défini le type de liste C++ ;
  • Champ « Foreign key » : clé étrangère de la relation : nom d'une propriété de l'entité cible ;
  • Champ « FK owner » : utilisé uniquement pour les relations de type n-n ;
  • Champ « Extra-table » : utilisé uniquement pour les relations de type n-n, correspond au nom de la table qui lie les 2 entités ;
  • Champ « Index » : optimisation des requêtes SQL de type SELECT pour les recherches en base de données ;
  • Champ « Serializable » : si coché, la relation est prise en compte par le moteur de sérialisation de la bibliothèque QxOrm ;
  • Champ « Obsolete » : cocher cette option pour supprimer une relation sans casser la compatibilité ascendante du moteur de sérialisation de la bibliothèque QxOrm : la relation devient privée sans accesseur Get/Set.

-- Section Advanced :
  • Champ « Accessibility », valeurs « public, protected ou private » : une relation public est accessible sans accesseur Get/Set, une relation protected est accessible uniquement par les classes dérivées, une relation private est accessible uniquement par les accesseurs Get/Set ;
  • Champ « Get/Set accessors » : si coché, des accesseurs Get/Set seront disponibles dans la classe C++ pour accéder/modifier la valeur de la relation ;
  • Champ « Read only » : si coché, un seul accesseur Get est disponible dans la classe C++, ce qui rend la relation en lecture seule ;
  • Champ « Get method implementation » : permet de surcharger l'implémentation par défaut de la méthode Get dans la classe C++ pour accéder à la valeur de la relation ;
  • Champ « Set method implementation » : permet de surcharger l'implémentation par défaut de la méthode Set dans la classe C++ pour modifier la valeur de la relation.

-- Section List of meta-data : les méta-données permettent d'ajouter des paramètres supplémentaires et sont accessibles dans le code C++ (moteur d'introspection de QxOrm) et le moteur Javascript de personnalisation des exports de QxEntityEditor.
  • Colonne « Key » : clé de la méta-donnée ;
  • Colonne « Value » : valeur de la méta-donnée ;
  • Bouton « Delete » : supprime la méta-donnée de la liste.

Gestion des énumérations

Une énumération dans l'application QxEntityEditor correspond à une liste de valeurs disponibles côté code C++ (pour le moment pas de notion côté base de données : converti en valeur numérique). L'application QxEntityEditor permet de créer, modifier, supprimer et cloner une énumération.

Ajouter/modifier/supprimer/cloner une énumération

L'ajout, la modification, la suppression et le clonage d'une énumération se fait de la même façon que pour une entité.
Une énumération dispose des mêmes menus qu'une entité.

Paramètres d'une énumération

Les paramètres de l'énumération sélectionnée sont accessibles dans l'onglet de paramétrage Enumeration :

Enumeration settings

Cet écran de paramétrage est divisé en plusieurs sections :

-- Section Enumeration information (version XX) : la version de l'énumération est incrémentée à chaque historique de projet créé.
  • Champ « Name » : nom de l'énumération et de la classe C++ générée ;
  • Champ « Description » : description de l'énumération (apparait dans le code C++ généré) ;
  • Champ « Namespace » : espace de nom de l'énumération et de la classe C++ associée, chaque sous-namespace doit être séparé par ::, par exemple : ns1::ns2::ns3 ;
  • Champ « Use Qt macro Q_ENUM » : utilise la macro Q_ENUM fournie par Qt pour définir une énumération compatible avec le moteur d'introspection de Qt ;

-- Section List of values : liste des valeurs de l'énumération.
  • Colonne « Key » : clé associé à la valeur ;
  • Colonne « Value » : valeur ;
  • Bouton « Delete » : supprime la valeur de la liste.

-- Section List of meta-data : les méta-données permettent d'ajouter des paramètres supplémentaires et sont accessibles dans le code C++ (moteur d'introspection de QxOrm) et le moteur Javascript de personnalisation des exports de QxEntityEditor.
  • Colonne « Key » : clé de la méta-donnée ;
  • Colonne « Value » : valeur de la méta-donnée ;
  • Bouton « Delete » : supprime la méta-donnée de la liste.

Couleur associée à une énumération

Les couleurs d'une énumération peuvent être modifiées par le menu contextuel sur un clic-droit sur une énumération Define enumeration colors :

Enumeration colors

Remarque : les couleurs des éléments du diagramme d'entités peuvent être gérées à plusieurs niveaux (du niveau le plus global au plus spécifique) :

Gestion des espaces de nom (namespace)

Un espace de nom (ou namespace) dans l'application QxEntityEditor permet de regrouper plusieurs entités et énumérations dans une même zone. Côté base de données, un espace de nom représente généralement un schéma. Côté code C++, un espace de nom regroupe plusieurs classes ou fonctions C++ dans une même zone.

La notion d'espace de nom est utilisée par la fonction : Organisation automatique du diagramme d'entités (permet un regroupement automatique).

La gestion des espaces de nom dans QxEntityEditor se fait depuis l'arborescence du projet :

Namespace menu

Renommer un espace de nom

Pour renommer un espace de nom, il faut faire un clic-droit sur l'arborescence du projet, puis menu contextuel Move entities to another namespace :

Namespace rename

Gestion des couleurs d'un espace de nom

Pour définir les couleurs des éléments d'un espace de nom, il faut faire un clic-droit sur l'arborescence du projet, puis menu contextuel Define colors by namespace :

Namespace colors

La partie gauche de l'écran liste tous les espaces de nom disponibles et définis dans le projet.
La partie droite permet de définir les couleurs des éléments faisant partie de l'espace de nom. Il est également possible de définir une couleur de fond (de préférence, une couleur claire), permettant de regrouper visuellement les éléments dans le diagramme d'entités.

Remarque : les couleurs des éléments du diagramme d'entités peuvent être gérées à plusieurs niveaux (du niveau le plus global au plus spécifique) :

Gestion des notes (ou post-it)

Une note (ou post-it) dans l'application QxEntityEditor permet de coller une étiquette dans le diagramme d'entités pour fournir des informations sur le modèle de données ou le projet en cours. Cette note peut être positionnée n'importe où dans le diagramme d'entités. Une note dispose d'un titre et d'un texte libre. Il est possible d'écrire du texte au format HTML pour ajouter des couleurs, mettre en gras, en italique, etc...

L'application QxEntityEditor permet de créer, modifier, supprimer et cloner une note.

Post-it / comments

Ajouter/modifier/supprimer/cloner une note

L'ajout, la modification, la suppression et le clonage d'une note se fait de la même façon que pour une entité.
Une note dispose des mêmes menus qu'une entité (il suffit de remplacer le terme entity par comment dans les menus).

Couleur associée à une note

Les couleurs d'une note peuvent être modifiées par le menu contextuel sur un clic-droit sur une note Define comment colors :

Post-it colors

Remarque : les couleurs des éléments du diagramme d'entités peuvent être gérées à plusieurs niveaux (du niveau le plus global au plus spécifique) :

Organisation automatique du diagramme d'entités

Une fonction permet de regrouper automatiquement les éléments du diagramme d'entités en fonction des espaces de nom, et en fonction des relations entre entités : menu principal View >> Organize diagram layout. Cette fonction est particulièrement utile pour organiser le diagramme d'entités après un processus d'import par exemple.

Organize diagram layout

Historique d'un projet *.qxee

Un projet QxEntityEditor peut être historisé : menu principal Actions >> Tag project state.

Chaque historique de projet fait évoluer les n° de version des différents éléments du projet (entités, propriétés, relations, etc...). Ces n° de version sont utiles pour assurer une compatibilité ascendante avec le moteur de sérialisation de la bibliothèque QxOrm. L'historique de projet est également utilisé par l'export DDL de schéma de base de données : permet de suivre l'évolution du schéma de base de données (ajout d'une table, suppression d'une colonne, ajout d'un index, etc...).

Tag project state tab 1

Le 1er onglet de l'écran d'historique permet de poser une étiquette (par exemple : date/heure, numéro de version du projet, etc...) et un commentaire en texte libre.

Tag project state tab 2

Le 2ème onglet de l'écran d'historique liste tous les historiques du projet, et permet de récupérer l'état d'un projet à un instant donné sous plusieurs formats (XML, JSON ou bien fichier projet *.qxee).

Aperçu du code C++ d'une entité/énumération

Il est possible de prévisualiser à tout moment le code C++ (fichier header *.h et fichier source *.cpp) associé à une entité et une énumération (ce code C++ peut être généré par le processus d'export C++). Cette prévisualisation est accessible en sélectionnant un élément dans le diagramme d'entités, puis aller dans l'onglet C++ preview :

C++ preview

Convention de nommage (snake_case, camelCase)

L'application QxEntityEditor fournit une fonction permettant d'appliquer rapidement une convention de nommage sur tous les éléments du projet (entités, propriétés, relations, etc...). Cette fonction conserve (ne casse pas) le mapping vers la base de données. L'accès à cette fonction se fait par le menu principal : Naming convention. 3 styles de convention de nommage sont proposés : snake_case, camelCase et PascalCase.

Naming convention

Remarque : cette fonction peut être utile suite à un processus d'import pour harmoniser le code C++ généré.

Liste des plugins disponibles

L'application QxEntityEditor est basée sur un système de plugins pour gérer les processus d'import/export. Une liste des plugins disponibles avec les n° de version et une description de chaque plugin est accessible depuis le menu principal : Help >> About plugins.

List of plugins

Plugins d'import

Tous les processus d'import de l'application QxEntityEditor sont accessibles depuis le menu principal Import :

Import plugins

Importer un projet à partir d'un fichier texte au format JSON

Il est possible de gérer un projet QxEntityEditor avec un fichier texte au format JSON : menu principal Import >> Import from JSON file.
Pour connaitre la structure du fichier JSON à respecter, il est conseillé au préalable d'effectuer un 1er export de projet au format JSON.

Import JSON

L'écran d'import dispose d'un seul champ à renseigner : le fichier JSON à importer.

Attention : un import JSON efface tous les éléments du projet courant (entités, propriétés, relations, etc...).

Remarque : il est possible de démarrer QxEntityEditor en ligne de commande pour charger automatiquement un fichier JSON au démarrage de l'application.

Exemple de ligne de commande :
QxEntityEditor --project="<path_to_your_qxee_project_file>" --plugin=QxEEJsonImport --QxEEJsonImport_file="<path_to_your_json_file>"

Exemple de fichier JSON (présent dans le dossier ./samples/qxBlog.json du package QxEntityEditor) :
{
    "app_version": 0,
    "description": "",
    "dt_creation": "20131206221737",
    "dt_modification": "20131206221737",
    "id": 1,
    "list_all_entities": [
        {
            "app_version": 0,
            "description": "",
            "dt_creation": "20131206221810",
            "dt_modification": "20140617214144",
            "id": 1,
            "is_abstract": false,
            "is_read_only": false,
            "key": "",
            "list_functions": null,
            "list_functions_static": null,
            "list_meta_data": null,
            "list_properties": [
                {
                    "accessibility": "protected",
                    "allow_null": false,
                    "app_version": 0,
                    "column_name": "",
                    "description": "",
                    "dt_creation": "20131206221810",
                    "dt_modification": "20140617214144",
                    "entity_id": {
                        "id": 1
                    },
                    "force_sql_alias": "",
                    "force_sql_type": "",
                    "format": "",
                    "get_method": "",
                    "id": 1,
                    "is_index": true,
                    "is_obsolete": false,
                    "is_primary_key": true,
                    "is_read_only": false,
                    "is_serializable": true,
                    "is_transient": false,
                    "is_unique": false,
                    "key": "",
                    "list_meta_data": null,
                    "max_length": "",
                    "max_value": "",
                    "min_length": "",
                    "min_value": "",
                    "name": "author_id",
                    "order_level": 0,
                    "project_version": 0,
                    "property_type_id": {
                        "app_version": 0,
                        "collection": "",
                        "decoration": "",
                        "default_value": "",
                        "dt_creation": "20131206221810",
                        "dt_modification": "20140617214144",
                        "entity_id": null,
                        "enumeration_id": null,
                        "id": 1,
                        "list_meta_data": null,
                        "primitive_type": "long",
                        "property_id": {
                            "id": 1
                        },
                        "user_id_creation": 0,
                        "user_id_modification": 0
                    },
                    "qt_property": "",
                    "reg_exp": "",
                    "relation_id": null,
                    "set_method": "",
                    "user_id_creation": 0,
                    "user_id_modification": 0,
                    "version": 0,
                    "write_accessors": true
                },
                {
                    "accessibility": "protected",
                    "allow_null": true,
                    "app_version": 0,
                    "column_name": "",
                    "description": "",
                    "dt_creation": "20131206221810",
                    "dt_modification": "20140617214144",
                    "entity_id": {
                        "id": 1
                    },
                    "force_sql_alias": "",
                    "force_sql_type": "",
                    "format": "",
                    "get_method": "",
                    "id": 2,
                    "is_index": false,
                    "is_obsolete": false,
                    "is_primary_key": false,
                    "is_read_only": false,
                    "is_serializable": true,
                    "is_transient": false,
                    "is_unique": false,
                    "key": "",
                    "list_meta_data": null,
                    "max_length": "",
                    "max_value": "",
                    "min_length": "",
                    "min_value": "",
                    "name": "firstname",
                    "order_level": 1,
                    "project_version": 0,
                    "property_type_id": {
                        "app_version": 0,
                        "collection": "",
                        "decoration": "",
                        "default_value": "",
                        "dt_creation": "20131206221810",
                        "dt_modification": "20140617214144",
                        "entity_id": null,
                        "enumeration_id": null,
                        "id": 2,
                        "list_meta_data": null,
                        "primitive_type": "QString",
                        "property_id": {
                            "id": 2
                        },
                        "user_id_creation": 0,
                        "user_id_modification": 0
                    },
                    "qt_property": "",
                    "reg_exp": "",
                    "relation_id": null,
                    "set_method": "",
                    "user_id_creation": 0,
                    "user_id_modification": 0,
                    "version": 0,
                    "write_accessors": true
                },
                {
                    "accessibility": "protected",
                    "allow_null": true,
                    "app_version": 0,
                    "column_name": "",
                    "description": "",
                    "dt_creation": "20131206221810",
                    "dt_modification": "20140617214144",
                    "entity_id": {
                        "id": 1
                    },
                    "force_sql_alias": "",
                    "force_sql_type": "",
                    "format": "",
                    "get_method": "",
                    "id": 3,
                    "is_index": true,
                    "is_obsolete": false,
                    "is_primary_key": false,
                    "is_read_only": false,
                    "is_serializable": true,
                    "is_transient": false,
                    "is_unique": false,
                    "key": "",
                    "list_meta_data": null,
                    "max_length": "",
                    "max_value": "",
                    "min_length": "",
                    "min_value": "",
                    "name": "lastname",
                    "order_level": 2,
                    "project_version": 0,
                    "property_type_id": {
                        "app_version": 0,
                        "collection": "",
                        "decoration": "",
                        "default_value": "",
                        "dt_creation": "20131206221810",
                        "dt_modification": "20140617214144",
                        "entity_id": null,
                        "enumeration_id": null,
                        "id": 3,
                        "list_meta_data": null,
                        "primitive_type": "QString",
                        "property_id": {
                            "id": 3
                        },
                        "user_id_creation": 0,
                        "user_id_modification": 0
                    },
                    "qt_property": "",
                    "reg_exp": "",
                    "relation_id": null,
                    "set_method": "",
                    "user_id_creation": 0,
                    "user_id_modification": 0,
                    "version": 0,
                    "write_accessors": true
                },
                {
                    "accessibility": "protected",
                    "allow_null": true,
                    "app_version": 0,
                    "column_name": "",
                    "description": "",
                    "dt_creation": "20131206221810",
                    "dt_modification": "20140617214144",
                    "entity_id": {
                        "id": 1
                    },
                    "force_sql_alias": "",
                    "force_sql_type": "",
                    "format": "",
                    "get_method": "",
                    "id": 4,
                    "is_index": true,
                    "is_obsolete": false,
                    "is_primary_key": false,
                    "is_read_only": false,
                    "is_serializable": true,
                    "is_transient": false,
                    "is_unique": false,
                    "key": "",
                    "list_meta_data": null,
                    "max_length": "",
                    "max_value": "",
                    "min_length": "",
                    "min_value": "",
                    "name": "birthdate",
                    "order_level": 3,
                    "project_version": 0,
                    "property_type_id": {
                        "app_version": 0,
                        "collection": "",
                        "decoration": "",
                        "default_value": "",
                        "dt_creation": "20131206221810",
                        "dt_modification": "20140617214144",
                        "entity_id": null,
                        "enumeration_id": null,
                        "id": 4,
                        "list_meta_data": null,
                        "primitive_type": "QDateTime",
                        "property_id": {
                            "id": 4
                        },
                        "user_id_creation": 0,
                        "user_id_modification": 0
                    },
                    "qt_property": "",
                    "reg_exp": "",
                    "relation_id": null,
                    "set_method": "",
                    "user_id_creation": 0,
                    "user_id_modification": 0,
                    "version": 0,
                    "write_accessors": true
                },
                {
                    "accessibility": "protected",
                    "allow_null": true,
                    "app_version": 0,
                    "column_name": "",
                    "description": "",
                    "dt_creation": "20131206221810",
                    "dt_modification": "20140617214144",
                    "entity_id": {
                        "id": 1
                    },
                    "force_sql_alias": "",
                    "force_sql_type": "",
                    "format": "",
                    "get_method": "",
                    "id": 5,
                    "is_index": false,
                    "is_obsolete": false,
                    "is_primary_key": false,
                    "is_read_only": false,
                    "is_serializable": true,
                    "is_transient": false,
                    "is_unique": false,
                    "key": "",
                    "list_meta_data": null,
                    "max_length": "",
                    "max_value": "",
                    "min_length": "",
                    "min_value": "",
                    "name": "sex",
                    "order_level": 4,
                    "project_version": 0,
                    "property_type_id": {
                        "app_version": 0,
                        "collection": "",
                        "decoration": "",
                        "default_value": "",
                        "dt_creation": "20131206221810",
                        "dt_modification": "20140617214144",
                        "entity_id": null,
                        "enumeration_id": {
                            "id": 1
                        },
                        "id": 5,
                        "list_meta_data": null,
                        "primitive_type": "sex::enum_sex",
                        "property_id": {
                            "id": 5
                        },
                        "user_id_creation": 0,
                        "user_id_modification": 0
                    },
                    "qt_property": "",
                    "reg_exp": "",
                    "relation_id": null,
                    "set_method": "",
                    "user_id_creation": 0,
                    "user_id_modification": 0,
                    "version": 0,
                    "write_accessors": true
                },
                {
                    "accessibility": "protected",
                    "allow_null": true,
                    "app_version": 0,
                    "column_name": "",
                    "description": "",
                    "dt_creation": "20131206222031",
                    "dt_modification": "20140617214144",
                    "entity_id": {
                        "id": 1
                    },
                    "force_sql_alias": "",
                    "force_sql_type": "",
                    "format": "",
                    "get_method": "",
                    "id": 18,
                    "is_index": false,
                    "is_obsolete": false,
                    "is_primary_key": false,
                    "is_read_only": false,
                    "is_serializable": true,
                    "is_transient": false,
                    "is_unique": false,
                    "key": "",
                    "list_meta_data": null,
                    "max_length": "",
                    "max_value": "",
                    "min_length": "",
                    "min_value": "",
                    "name": "list_of_blog",
                    "order_level": 17,
                    "project_version": 0,
                    "property_type_id": {
                        "app_version": 0,
                        "collection": "qx::QxCollection",
                        "decoration": "boost::shared_ptr",
                        "default_value": "",
                        "dt_creation": "20131206222031",
                        "dt_modification": "20140617214144",
                        "entity_id": {
                            "id": 4
                        },
                        "enumeration_id": null,
                        "id": 18,
                        "list_meta_data": null,
                        "primitive_type": "",
                        "property_id": {
                            "id": 18
                        },
                        "user_id_creation": 0,
                        "user_id_modification": 0
                    },
                    "qt_property": "",
                    "reg_exp": "",
                    "relation_id": {
                        "app_version": 0,
                        "dt_creation": "20131206222031",
                        "dt_modification": "20140617214144",
                        "extra_table": "",
                        "foreign_key": "author",
                        "foreign_key_owner": "",
                        "id": 2,
                        "inverse_property_id": {
                            "id": 15
                        },
                        "list_meta_data": null,
                        "property_id": {
                            "id": 18
                        },
                        "type_relation": "one-to-many",
                        "user_id_creation": 0,
                        "user_id_modification": 0
                    },
                    "set_method": "",
                    "user_id_creation": 0,
                    "user_id_modification": 0,
                    "version": 0,
                    "write_accessors": true
                }
            ],
            "name": "author",
            "namespace": "",
            "parent_id": null,
            "project_id": {
                "id": 1
            },
            "project_version": 0,
            "property_id": {
                "accessibility": "protected",
                "allow_null": false,
                "app_version": 0,
                "column_name": "",
                "description": "",
                "dt_creation": "20131206221810",
                "dt_modification": "20140617214144",
                "entity_id": {
                    "id": 1
                },
                "force_sql_alias": "",
                "force_sql_type": "",
                "format": "",
                "get_method": "",
                "id": 1,
                "is_index": true,
                "is_obsolete": false,
                "is_primary_key": true,
                "is_read_only": false,
                "is_serializable": true,
                "is_transient": false,
                "is_unique": false,
                "key": "",
                "list_meta_data": null,
                "max_length": "",
                "max_value": "",
                "min_length": "",
                "min_value": "",
                "name": "author_id",
                "order_level": 0,
                "project_version": 0,
                "property_type_id": {
                    "app_version": 0,
                    "collection": "",
                    "decoration": "",
                    "default_value": "",
                    "dt_creation": "20131206221810",
                    "dt_modification": "20140617214144",
                    "entity_id": null,
                    "enumeration_id": null,
                    "id": 1,
                    "list_meta_data": null,
                    "primitive_type": "long",
                    "property_id": {
                        "id": 1
                    },
                    "user_id_creation": 0,
                    "user_id_modification": 0
                },
                "qt_property": "",
                "reg_exp": "",
                "relation_id": null,
                "set_method": "",
                "user_id_creation": 0,
                "user_id_modification": 0,
                "version": 0,
                "write_accessors": true
            },
            "soft_delete_column": "",
            "table_name": "t_author",
            "trigger_after_delete": false,
            "trigger_after_fetch": false,
            "trigger_after_insert": false,
            "trigger_after_update": false,
            "trigger_before_delete": false,
            "trigger_before_fetch": false,
            "trigger_before_insert": false,
            "trigger_before_update": false,
            "user_id_creation": 0,
            "user_id_modification": 0,
            "validator_method": "",
            "version": 0
        },
        {
            "app_version": 0,
            "description": "",
            "dt_creation": "20131206222031",
            "dt_modification": "20140617214043",
            "id": 4,
            "is_abstract": false,
            "is_read_only": false,
            "key": "",
            "list_functions": null,
            "list_functions_static": null,
            "list_meta_data": null,
            "list_properties": [
                {
                    "accessibility": "protected",
                    "allow_null": false,
                    "app_version": 0,
                    "column_name": "",
                    "description": "",
                    "dt_creation": "20131206222031",
                    "dt_modification": "20140617214043",
                    "entity_id": {
                        "id": 4
                    },
                    "force_sql_alias": "",
                    "force_sql_type": "",
                    "format": "",
                    "get_method": "",
                    "id": 12,
                    "is_index": true,
                    "is_obsolete": false,
                    "is_primary_key": true,
                    "is_read_only": false,
                    "is_serializable": true,
                    "is_transient": false,
                    "is_unique": false,
                    "key": "",
                    "list_meta_data": null,
                    "max_length": "",
                    "max_value": "",
                    "min_length": "",
                    "min_value": "",
                    "name": "blog_id",
                    "order_level": 11,
                    "project_version": 0,
                    "property_type_id": {
                        "app_version": 0,
                        "collection": "",
                        "decoration": "",
                        "default_value": "",
                        "dt_creation": "20131206222031",
                        "dt_modification": "20140617214043",
                        "entity_id": null,
                        "enumeration_id": null,
                        "id": 12,
                        "list_meta_data": null,
                        "primitive_type": "long",
                        "property_id": {
                            "id": 12
                        },
                        "user_id_creation": 0,
                        "user_id_modification": 0
                    },
                    "qt_property": "",
                    "reg_exp": "",
                    "relation_id": null,
                    "set_method": "",
                    "user_id_creation": 0,
                    "user_id_modification": 0,
                    "version": 0,
                    "write_accessors": true
                },
                {
                    "accessibility": "protected",
                    "allow_null": false,
                    "app_version": 0,
                    "column_name": "",
                    "description": "",
                    "dt_creation": "20131206222031",
                    "dt_modification": "20140617214043",
                    "entity_id": {
                        "id": 4
                    },
                    "force_sql_alias": "",
                    "force_sql_type": "",
                    "format": "",
                    "get_method": "",
                    "id": 13,
                    "is_index": true,
                    "is_obsolete": false,
                    "is_primary_key": false,
                    "is_read_only": false,
                    "is_serializable": true,
                    "is_transient": false,
                    "is_unique": false,
                    "key": "",
                    "list_meta_data": null,
                    "max_length": "",
                    "max_value": "",
                    "min_length": "",
                    "min_value": "",
                    "name": "title",
                    "order_level": 12,
                    "project_version": 0,
                    "property_type_id": {
                        "app_version": 0,
                        "collection": "",
                        "decoration": "",
                        "default_value": "",
                        "dt_creation": "20131206222031",
                        "dt_modification": "20140617214043",
                        "entity_id": null,
                        "enumeration_id": null,
                        "id": 13,
                        "list_meta_data": null,
                        "primitive_type": "QString",
                        "property_id": {
                            "id": 13
                        },
                        "user_id_creation": 0,
                        "user_id_modification": 0
                    },
                    "qt_property": "",
                    "reg_exp": "",
                    "relation_id": null,
                    "set_method": "",
                    "user_id_creation": 0,
                    "user_id_modification": 0,
                    "version": 0,
                    "write_accessors": true
                },
                {
                    "accessibility": "protected",
                    "allow_null": true,
                    "app_version": 0,
                    "column_name": "",
                    "description": "",
                    "dt_creation": "20131206222031",
                    "dt_modification": "20140617214043",
                    "entity_id": {
                        "id": 4
                    },
                    "force_sql_alias": "",
                    "force_sql_type": "",
                    "format": "",
                    "get_method": "",
                    "id": 14,
                    "is_index": false,
                    "is_obsolete": false,
                    "is_primary_key": false,
                    "is_read_only": false,
                    "is_serializable": true,
                    "is_transient": false,
                    "is_unique": false,
                    "key": "",
                    "list_meta_data": null,
                    "max_length": "",
                    "max_value": "",
                    "min_length": "",
                    "min_value": "",
                    "name": "text",
                    "order_level": 13,
                    "project_version": 0,
                    "property_type_id": {
                        "app_version": 0,
                        "collection": "",
                        "decoration": "",
                        "default_value": "",
                        "dt_creation": "20131206222031",
                        "dt_modification": "20140617214043",
                        "entity_id": null,
                        "enumeration_id": null,
                        "id": 14,
                        "list_meta_data": null,
                        "primitive_type": "QString",
                        "property_id": {
                            "id": 14
                        },
                        "user_id_creation": 0,
                        "user_id_modification": 0
                    },
                    "qt_property": "",
                    "reg_exp": "",
                    "relation_id": null,
                    "set_method": "",
                    "user_id_creation": 0,
                    "user_id_modification": 0,
                    "version": 0,
                    "write_accessors": true
                },
                {
                    "accessibility": "protected",
                    "allow_null": true,
                    "app_version": 0,
                    "column_name": "",
                    "description": "",
                    "dt_creation": "20131206222031",
                    "dt_modification": "20140617214043",
                    "entity_id": {
                        "id": 4
                    },
                    "force_sql_alias": "",
                    "force_sql_type": "",
                    "format": "",
                    "get_method": "",
                    "id": 15,
                    "is_index": false,
                    "is_obsolete": false,
                    "is_primary_key": false,
                    "is_read_only": false,
                    "is_serializable": true,
                    "is_transient": false,
                    "is_unique": false,
                    "key": "",
                    "list_meta_data": null,
                    "max_length": "",
                    "max_value": "",
                    "min_length": "",
                    "min_value": "",
                    "name": "author",
                    "order_level": 14,
                    "project_version": 0,
                    "property_type_id": {
                        "app_version": 0,
                        "collection": "qx::QxCollection",
                        "decoration": "boost::shared_ptr",
                        "default_value": "",
                        "dt_creation": "20131206222031",
                        "dt_modification": "20140617214043",
                        "entity_id": {
                            "id": 1
                        },
                        "enumeration_id": null,
                        "id": 15,
                        "list_meta_data": null,
                        "primitive_type": "",
                        "property_id": {
                            "id": 15
                        },
                        "user_id_creation": 0,
                        "user_id_modification": 0
                    },
                    "qt_property": "",
                    "reg_exp": "",
                    "relation_id": {
                        "app_version": 0,
                        "dt_creation": "20131206222031",
                        "dt_modification": "20140617214043",
                        "extra_table": "",
                        "foreign_key": "",
                        "foreign_key_owner": "",
                        "id": 1,
                        "inverse_property_id": {
                            "id": 18
                        },
                        "list_meta_data": null,
                        "property_id": {
                            "id": 15
                        },
                        "type_relation": "many-to-one",
                        "user_id_creation": 0,
                        "user_id_modification": 0
                    },
                    "set_method": "",
                    "user_id_creation": 0,
                    "user_id_modification": 0,
                    "version": 0,
                    "write_accessors": true
                },
                {
                    "accessibility": "protected",
                    "allow_null": true,
                    "app_version": 0,
                    "column_name": "",
                    "description": "",
                    "dt_creation": "20131206222031",
                    "dt_modification": "20140617214043",
                    "entity_id": {
                        "id": 4
                    },
                    "force_sql_alias": "",
                    "force_sql_type": "",
                    "format": "",
                    "get_method": "",
                    "id": 16,
                    "is_index": false,
                    "is_obsolete": false,
                    "is_primary_key": false,
                    "is_read_only": false,
                    "is_serializable": true,
                    "is_transient": false,
                    "is_unique": false,
                    "key": "",
                    "list_meta_data": null,
                    "max_length": "",
                    "max_value": "",
                    "min_length": "",
                    "min_value": "",
                    "name": "list_of_comment",
                    "order_level": 15,
                    "project_version": 0,
                    "property_type_id": {
                        "app_version": 0,
                        "collection": "qx::QxCollection",
                        "decoration": "boost::shared_ptr",
                        "default_value": "",
                        "dt_creation": "20131206222031",
                        "dt_modification": "20140617214043",
                        "entity_id": {
                            "id": 3
                        },
                        "enumeration_id": null,
                        "id": 16,
                        "list_meta_data": null,
                        "primitive_type": "",
                        "property_id": {
                            "id": 16
                        },
                        "user_id_creation": 0,
                        "user_id_modification": 0
                    },
                    "qt_property": "",
                    "reg_exp": "",
                    "relation_id": {
                        "app_version": 0,
                        "dt_creation": "20131206222031",
                        "dt_modification": "20140617214043",
                        "extra_table": "",
                        "foreign_key": "blog_id",
                        "foreign_key_owner": "",
                        "id": 3,
                        "inverse_property_id": {
                            "id": 19
                        },
                        "list_meta_data": null,
                        "property_id": {
                            "id": 16
                        },
                        "type_relation": "one-to-many",
                        "user_id_creation": 0,
                        "user_id_modification": 0
                    },
                    "set_method": "",
                    "user_id_creation": 0,
                    "user_id_modification": 0,
                    "version": 0,
                    "write_accessors": true
                },
                {
                    "accessibility": "protected",
                    "allow_null": true,
                    "app_version": 0,
                    "column_name": "",
                    "description": "",
                    "dt_creation": "20131206222031",
                    "dt_modification": "20140617214043",
                    "entity_id": {
                        "id": 4
                    },
                    "force_sql_alias": "",
                    "force_sql_type": "",
                    "format": "",
                    "get_method": "",
                    "id": 17,
                    "is_index": false,
                    "is_obsolete": false,
                    "is_primary_key": false,
                    "is_read_only": false,
                    "is_serializable": true,
                    "is_transient": false,
                    "is_unique": false,
                    "key": "",
                    "list_meta_data": null,
                    "max_length": "",
                    "max_value": "",
                    "min_length": "",
                    "min_value": "",
                    "name": "list_of_category",
                    "order_level": 16,
                    "project_version": 0,
                    "property_type_id": {
                        "app_version": 0,
                        "collection": "qx::QxCollection",
                        "decoration": "boost::shared_ptr",
                        "default_value": "",
                        "dt_creation": "20131206222031",
                        "dt_modification": "20140617214043",
                        "entity_id": {
                            "id": 2
                        },
                        "enumeration_id": null,
                        "id": 17,
                        "list_meta_data": null,
                        "primitive_type": "",
                        "property_id": {
                            "id": 17
                        },
                        "user_id_creation": 0,
                        "user_id_modification": 0
                    },
                    "qt_property": "",
                    "reg_exp": "",
                    "relation_id": {
                        "app_version": 0,
                        "dt_creation": "20131206222031",
                        "dt_modification": "20140617214043",
                        "extra_table": "t_qxee_blog_category",
                        "foreign_key": "blog_id",
                        "foreign_key_owner": "category_id",
                        "id": 5,
                        "inverse_property_id": {
                            "id": 20
                        },
                        "list_meta_data": null,
                        "property_id": {
                            "id": 17
                        },
                        "type_relation": "many-to-many",
                        "user_id_creation": 0,
                        "user_id_modification": 0
                    },
                    "set_method": "",
                    "user_id_creation": 0,
                    "user_id_modification": 0,
                    "version": 0,
                    "write_accessors": true
                }
            ],
            "name": "blog",
            "namespace": "",
            "parent_id": null,
            "project_id": {
                "id": 1
            },
            "project_version": 0,
            "property_id": {
                "accessibility": "protected",
                "allow_null": false,
                "app_version": 0,
                "column_name": "",
                "description": "",
                "dt_creation": "20131206222031",
                "dt_modification": "20140617214043",
                "entity_id": {
                    "id": 4
                },
                "force_sql_alias": "",
                "force_sql_type": "",
                "format": "",
                "get_method": "",
                "id": 12,
                "is_index": true,
                "is_obsolete": false,
                "is_primary_key": true,
                "is_read_only": false,
                "is_serializable": true,
                "is_transient": false,
                "is_unique": false,
                "key": "",
                "list_meta_data": null,
                "max_length": "",
                "max_value": "",
                "min_length": "",
                "min_value": "",
                "name": "blog_id",
                "order_level": 11,
                "project_version": 0,
                "property_type_id": {
                    "app_version": 0,
                    "collection": "",
                    "decoration": "",
                    "default_value": "",
                    "dt_creation": "20131206222031",
                    "dt_modification": "20140617214043",
                    "entity_id": null,
                    "enumeration_id": null,
                    "id": 12,
                    "list_meta_data": null,
                    "primitive_type": "long",
                    "property_id": {
                        "id": 12
                    },
                    "user_id_creation": 0,
                    "user_id_modification": 0
                },
                "qt_property": "",
                "reg_exp": "",
                "relation_id": null,
                "set_method": "",
                "user_id_creation": 0,
                "user_id_modification": 0,
                "version": 0,
                "write_accessors": true
            },
            "soft_delete_column": "",
            "table_name": "t_blog",
            "trigger_after_delete": false,
            "trigger_after_fetch": false,
            "trigger_after_insert": false,
            "trigger_after_update": false,
            "trigger_before_delete": false,
            "trigger_before_fetch": false,
            "trigger_before_insert": false,
            "trigger_before_update": false,
            "user_id_creation": 0,
            "user_id_modification": 0,
            "validator_method": "",
            "version": 0
        },
        {
            "app_version": 0,
            "description": "",
            "dt_creation": "20131206221933",
            "dt_modification": "20140617214115",
            "id": 2,
            "is_abstract": false,
            "is_read_only": false,
            "key": "",
            "list_functions": null,
            "list_functions_static": null,
            "list_meta_data": null,
            "list_properties": [
                {
                    "accessibility": "protected",
                    "allow_null": false,
                    "app_version": 0,
                    "column_name": "",
                    "description": "",
                    "dt_creation": "20131206221933",
                    "dt_modification": "20140617214115",
                    "entity_id": {
                        "id": 2
                    },
                    "force_sql_alias": "",
                    "force_sql_type": "",
                    "format": "",
                    "get_method": "",
                    "id": 6,
                    "is_index": true,
                    "is_obsolete": false,
                    "is_primary_key": true,
                    "is_read_only": false,
                    "is_serializable": true,
                    "is_transient": false,
                    "is_unique": false,
                    "key": "",
                    "list_meta_data": null,
                    "max_length": "",
                    "max_value": "",
                    "min_length": "",
                    "min_value": "",
                    "name": "category_id",
                    "order_level": 5,
                    "project_version": 0,
                    "property_type_id": {
                        "app_version": 0,
                        "collection": "",
                        "decoration": "",
                        "default_value": "",
                        "dt_creation": "20131206221933",
                        "dt_modification": "20140617214115",
                        "entity_id": null,
                        "enumeration_id": null,
                        "id": 6,
                        "list_meta_data": null,
                        "primitive_type": "QString",
                        "property_id": {
                            "id": 6
                        },
                        "user_id_creation": 0,
                        "user_id_modification": 0
                    },
                    "qt_property": "",
                    "reg_exp": "",
                    "relation_id": null,
                    "set_method": "",
                    "user_id_creation": 0,
                    "user_id_modification": 0,
                    "version": 0,
                    "write_accessors": true
                },
                {
                    "accessibility": "protected",
                    "allow_null": true,
                    "app_version": 0,
                    "column_name": "",
                    "description": "",
                    "dt_creation": "20131206221933",
                    "dt_modification": "20140617214115",
                    "entity_id": {
                        "id": 2
                    },
                    "force_sql_alias": "",
                    "force_sql_type": "",
                    "format": "",
                    "get_method": "",
                    "id": 7,
                    "is_index": false,
                    "is_obsolete": false,
                    "is_primary_key": false,
                    "is_read_only": false,
                    "is_serializable": true,
                    "is_transient": false,
                    "is_unique": false,
                    "key": "",
                    "list_meta_data": null,
                    "max_length": "",
                    "max_value": "",
                    "min_length": "",
                    "min_value": "",
                    "name": "name",
                    "order_level": 6,
                    "project_version": 0,
                    "property_type_id": {
                        "app_version": 0,
                        "collection": "",
                        "decoration": "",
                        "default_value": "",
                        "dt_creation": "20131206221933",
                        "dt_modification": "20140617214115",
                        "entity_id": null,
                        "enumeration_id": null,
                        "id": 7,
                        "list_meta_data": null,
                        "primitive_type": "QString",
                        "property_id": {
                            "id": 7
                        },
                        "user_id_creation": 0,
                        "user_id_modification": 0
                    },
                    "qt_property": "",
                    "reg_exp": "",
                    "relation_id": null,
                    "set_method": "",
                    "user_id_creation": 0,
                    "user_id_modification": 0,
                    "version": 0,
                    "write_accessors": true
                },
                {
                    "accessibility": "protected",
                    "allow_null": true,
                    "app_version": 0,
                    "column_name": "",
                    "description": "",
                    "dt_creation": "20131206221933",
                    "dt_modification": "20140617214115",
                    "entity_id": {
                        "id": 2
                    },
                    "force_sql_alias": "",
                    "force_sql_type": "",
                    "format": "",
                    "get_method": "",
                    "id": 8,
                    "is_index": false,
                    "is_obsolete": false,
                    "is_primary_key": false,
                    "is_read_only": false,
                    "is_serializable": true,
                    "is_transient": false,
                    "is_unique": false,
                    "key": "",
                    "list_meta_data": null,
                    "max_length": "",
                    "max_value": "",
                    "min_length": "",
                    "min_value": "",
                    "name": "description",
                    "order_level": 7,
                    "project_version": 0,
                    "property_type_id": {
                        "app_version": 0,
                        "collection": "",
                        "decoration": "",
                        "default_value": "",
                        "dt_creation": "20131206221933",
                        "dt_modification": "20140617214115",
                        "entity_id": null,
                        "enumeration_id": null,
                        "id": 8,
                        "list_meta_data": null,
                        "primitive_type": "QString",
                        "property_id": {
                            "id": 8
                        },
                        "user_id_creation": 0,
                        "user_id_modification": 0
                    },
                    "qt_property": "",
                    "reg_exp": "",
                    "relation_id": null,
                    "set_method": "",
                    "user_id_creation": 0,
                    "user_id_modification": 0,
                    "version": 0,
                    "write_accessors": true
                },
                {
                    "accessibility": "protected",
                    "allow_null": true,
                    "app_version": 0,
                    "column_name": "",
                    "description": "",
                    "dt_creation": "20131206222031",
                    "dt_modification": "20140617214115",
                    "entity_id": {
                        "id": 2
                    },
                    "force_sql_alias": "",
                    "force_sql_type": "",
                    "format": "",
                    "get_method": "",
                    "id": 20,
                    "is_index": false,
                    "is_obsolete": false,
                    "is_primary_key": false,
                    "is_read_only": false,
                    "is_serializable": true,
                    "is_transient": false,
                    "is_unique": false,
                    "key": "",
                    "list_meta_data": null,
                    "max_length": "",
                    "max_value": "",
                    "min_length": "",
                    "min_value": "",
                    "name": "list_of_blog",
                    "order_level": 19,
                    "project_version": 0,
                    "property_type_id": {
                        "app_version": 0,
                        "collection": "qx::QxCollection",
                        "decoration": "boost::shared_ptr",
                        "default_value": "",
                        "dt_creation": "20131206222031",
                        "dt_modification": "20140617214115",
                        "entity_id": {
                            "id": 4
                        },
                        "enumeration_id": null,
                        "id": 20,
                        "list_meta_data": null,
                        "primitive_type": "",
                        "property_id": {
                            "id": 20
                        },
                        "user_id_creation": 0,
                        "user_id_modification": 0
                    },
                    "qt_property": "",
                    "reg_exp": "",
                    "relation_id": {
                        "app_version": 0,
                        "dt_creation": "20131206222031",
                        "dt_modification": "20140617214115",
                        "extra_table": "t_qxee_blog_category",
                        "foreign_key": "category_id",
                        "foreign_key_owner": "blog_id",
                        "id": 6,
                        "inverse_property_id": {
                            "id": 17
                        },
                        "list_meta_data": null,
                        "property_id": {
                            "id": 20
                        },
                        "type_relation": "many-to-many",
                        "user_id_creation": 0,
                        "user_id_modification": 0
                    },
                    "set_method": "",
                    "user_id_creation": 0,
                    "user_id_modification": 0,
                    "version": 0,
                    "write_accessors": true
                }
            ],
            "name": "category",
            "namespace": "",
            "parent_id": null,
            "project_id": {
                "id": 1
            },
            "project_version": 0,
            "property_id": {
                "accessibility": "protected",
                "allow_null": false,
                "app_version": 0,
                "column_name": "",
                "description": "",
                "dt_creation": "20131206221933",
                "dt_modification": "20140617214115",
                "entity_id": {
                    "id": 2
                },
                "force_sql_alias": "",
                "force_sql_type": "",
                "format": "",
                "get_method": "",
                "id": 6,
                "is_index": true,
                "is_obsolete": false,
                "is_primary_key": true,
                "is_read_only": false,
                "is_serializable": true,
                "is_transient": false,
                "is_unique": false,
                "key": "",
                "list_meta_data": null,
                "max_length": "",
                "max_value": "",
                "min_length": "",
                "min_value": "",
                "name": "category_id",
                "order_level": 5,
                "project_version": 0,
                "property_type_id": {
                    "app_version": 0,
                    "collection": "",
                    "decoration": "",
                    "default_value": "",
                    "dt_creation": "20131206221933",
                    "dt_modification": "20140617214115",
                    "entity_id": null,
                    "enumeration_id": null,
                    "id": 6,
                    "list_meta_data": null,
                    "primitive_type": "QString",
                    "property_id": {
                        "id": 6
                    },
                    "user_id_creation": 0,
                    "user_id_modification": 0
                },
                "qt_property": "",
                "reg_exp": "",
                "relation_id": null,
                "set_method": "",
                "user_id_creation": 0,
                "user_id_modification": 0,
                "version": 0,
                "write_accessors": true
            },
            "soft_delete_column": "",
            "table_name": "t_category",
            "trigger_after_delete": false,
            "trigger_after_fetch": false,
            "trigger_after_insert": false,
            "trigger_after_update": false,
            "trigger_before_delete": false,
            "trigger_before_fetch": false,
            "trigger_before_insert": false,
            "trigger_before_update": false,
            "user_id_creation": 0,
            "user_id_modification": 0,
            "validator_method": "",
            "version": 0
        },
        {
            "app_version": 0,
            "description": "",
            "dt_creation": "20131206221951",
            "dt_modification": "20131206221951",
            "id": 3,
            "is_abstract": false,
            "is_read_only": false,
            "key": "",
            "list_functions": null,
            "list_functions_static": null,
            "list_meta_data": null,
            "list_properties": [
                {
                    "accessibility": "protected",
                    "allow_null": false,
                    "app_version": 0,
                    "column_name": "",
                    "description": "",
                    "dt_creation": "20131206221951",
                    "dt_modification": "20131206221951",
                    "entity_id": {
                        "id": 3
                    },
                    "force_sql_alias": "",
                    "force_sql_type": "",
                    "format": "",
                    "get_method": "",
                    "id": 9,
                    "is_index": true,
                    "is_obsolete": false,
                    "is_primary_key": true,
                    "is_read_only": false,
                    "is_serializable": true,
                    "is_transient": false,
                    "is_unique": false,
                    "key": "",
                    "list_meta_data": null,
                    "max_length": "",
                    "max_value": "",
                    "min_length": "",
                    "min_value": "",
                    "name": "comment_id",
                    "order_level": 8,
                    "project_version": 0,
                    "property_type_id": {
                        "app_version": 0,
                        "collection": "",
                        "decoration": "",
                        "default_value": "",
                        "dt_creation": "20131206221951",
                        "dt_modification": "20131206221951",
                        "entity_id": null,
                        "enumeration_id": null,
                        "id": 9,
                        "list_meta_data": null,
                        "primitive_type": "long",
                        "property_id": {
                            "id": 9
                        },
                        "user_id_creation": 0,
                        "user_id_modification": 0
                    },
                    "qt_property": "",
                    "reg_exp": "",
                    "relation_id": null,
                    "set_method": "",
                    "user_id_creation": 0,
                    "user_id_modification": 0,
                    "version": 0,
                    "write_accessors": true
                },
                {
                    "accessibility": "protected",
                    "allow_null": true,
                    "app_version": 0,
                    "column_name": "",
                    "description": "",
                    "dt_creation": "20131206221951",
                    "dt_modification": "20131206221951",
                    "entity_id": {
                        "id": 3
                    },
                    "force_sql_alias": "",
                    "force_sql_type": "",
                    "format": "",
                    "get_method": "",
                    "id": 10,
                    "is_index": false,
                    "is_obsolete": false,
                    "is_primary_key": false,
                    "is_read_only": false,
                    "is_serializable": true,
                    "is_transient": false,
                    "is_unique": false,
                    "key": "",
                    "list_meta_data": null,
                    "max_length": "",
                    "max_value": "",
                    "min_length": "",
                    "min_value": "",
                    "name": "title",
                    "order_level": 9,
                    "project_version": 0,
                    "property_type_id": {
                        "app_version": 0,
                        "collection": "",
                        "decoration": "",
                        "default_value": "",
                        "dt_creation": "20131206221951",
                        "dt_modification": "20131206221951",
                        "entity_id": null,
                        "enumeration_id": null,
                        "id": 10,
                        "list_meta_data": null,
                        "primitive_type": "QString",
                        "property_id": {
                            "id": 10
                        },
                        "user_id_creation": 0,
                        "user_id_modification": 0
                    },
                    "qt_property": "",
                    "reg_exp": "",
                    "relation_id": null,
                    "set_method": "",
                    "user_id_creation": 0,
                    "user_id_modification": 0,
                    "version": 0,
                    "write_accessors": true
                },
                {
                    "accessibility": "protected",
                    "allow_null": true,
                    "app_version": 0,
                    "column_name": "",
                    "description": "",
                    "dt_creation": "20131206221951",
                    "dt_modification": "20131206221951",
                    "entity_id": {
                        "id": 3
                    },
                    "force_sql_alias": "",
                    "force_sql_type": "",
                    "format": "",
                    "get_method": "",
                    "id": 11,
                    "is_index": false,
                    "is_obsolete": false,
                    "is_primary_key": false,
                    "is_read_only": false,
                    "is_serializable": true,
                    "is_transient": false,
                    "is_unique": false,
                    "key": "",
                    "list_meta_data": null,
                    "max_length": "",
                    "max_value": "",
                    "min_length": "",
                    "min_value": "",
                    "name": "text",
                    "order_level": 10,
                    "project_version": 0,
                    "property_type_id": {
                        "app_version": 0,
                        "collection": "",
                        "decoration": "",
                        "default_value": "",
                        "dt_creation": "20131206221951",
                        "dt_modification": "20131206221951",
                        "entity_id": null,
                        "enumeration_id": null,
                        "id": 11,
                        "list_meta_data": null,
                        "primitive_type": "QString",
                        "property_id": {
                            "id": 11
                        },
                        "user_id_creation": 0,
                        "user_id_modification": 0
                    },
                    "qt_property": "",
                    "reg_exp": "",
                    "relation_id": null,
                    "set_method": "",
                    "user_id_creation": 0,
                    "user_id_modification": 0,
                    "version": 0,
                    "write_accessors": true
                },
                {
                    "accessibility": "protected",
                    "allow_null": true,
                    "app_version": 0,
                    "column_name": "",
                    "description": "",
                    "dt_creation": "20131206222031",
                    "dt_modification": "20131206222031",
                    "entity_id": {
                        "id": 3
                    },
                    "force_sql_alias": "",
                    "force_sql_type": "",
                    "format": "",
                    "get_method": "",
                    "id": 19,
                    "is_index": false,
                    "is_obsolete": false,
                    "is_primary_key": false,
                    "is_read_only": false,
                    "is_serializable": true,
                    "is_transient": false,
                    "is_unique": false,
                    "key": "",
                    "list_meta_data": null,
                    "max_length": "",
                    "max_value": "",
                    "min_length": "",
                    "min_value": "",
                    "name": "blog_id",
                    "order_level": 18,
                    "project_version": 0,
                    "property_type_id": {
                        "app_version": 0,
                        "collection": "qx::QxCollection",
                        "decoration": "boost::shared_ptr",
                        "default_value": "",
                        "dt_creation": "20131206222031",
                        "dt_modification": "20131206222031",
                        "entity_id": {
                            "id": 4
                        },
                        "enumeration_id": null,
                        "id": 19,
                        "list_meta_data": null,
                        "primitive_type": "",
                        "property_id": {
                            "id": 19
                        },
                        "user_id_creation": 0,
                        "user_id_modification": 0
                    },
                    "qt_property": "",
                    "reg_exp": "",
                    "relation_id": {
                        "app_version": 0,
                        "dt_creation": "20131206222031",
                        "dt_modification": "20131206222031",
                        "extra_table": "",
                        "foreign_key": "",
                        "foreign_key_owner": "",
                        "id": 4,
                        "inverse_property_id": {
                            "id": 16
                        },
                        "list_meta_data": null,
                        "property_id": {
                            "id": 19
                        },
                        "type_relation": "many-to-one",
                        "user_id_creation": 0,
                        "user_id_modification": 0
                    },
                    "set_method": "",
                    "user_id_creation": 0,
                    "user_id_modification": 0,
                    "version": 0,
                    "write_accessors": true
                }
            ],
            "name": "comment",
            "namespace": "",
            "parent_id": null,
            "project_id": {
                "id": 1
            },
            "project_version": 0,
            "property_id": {
                "accessibility": "protected",
                "allow_null": false,
                "app_version": 0,
                "column_name": "",
                "description": "",
                "dt_creation": "20131206221951",
                "dt_modification": "20131206221951",
                "entity_id": {
                    "id": 3
                },
                "force_sql_alias": "",
                "force_sql_type": "",
                "format": "",
                "get_method": "",
                "id": 9,
                "is_index": true,
                "is_obsolete": false,
                "is_primary_key": true,
                "is_read_only": false,
                "is_serializable": true,
                "is_transient": false,
                "is_unique": false,
                "key": "",
                "list_meta_data": null,
                "max_length": "",
                "max_value": "",
                "min_length": "",
                "min_value": "",
                "name": "comment_id",
                "order_level": 8,
                "project_version": 0,
                "property_type_id": {
                    "app_version": 0,
                    "collection": "",
                    "decoration": "",
                    "default_value": "",
                    "dt_creation": "20131206221951",
                    "dt_modification": "20131206221951",
                    "entity_id": null,
                    "enumeration_id": null,
                    "id": 9,
                    "list_meta_data": null,
                    "primitive_type": "long",
                    "property_id": {
                        "id": 9
                    },
                    "user_id_creation": 0,
                    "user_id_modification": 0
                },
                "qt_property": "",
                "reg_exp": "",
                "relation_id": null,
                "set_method": "",
                "user_id_creation": 0,
                "user_id_modification": 0,
                "version": 0,
                "write_accessors": true
            },
            "soft_delete_column": "",
            "table_name": "t_comment",
            "trigger_after_delete": false,
            "trigger_after_fetch": false,
            "trigger_after_insert": false,
            "trigger_after_update": false,
            "trigger_before_delete": false,
            "trigger_before_fetch": false,
            "trigger_before_insert": false,
            "trigger_before_update": false,
            "user_id_creation": 0,
            "user_id_modification": 0,
            "validator_method": "",
            "version": 0
        }
    ],
    "list_comments": [
        {
            "app_version": 0,
            "comment_text": "- Design the entity model in few minutes\n\n- Generate C++ persistent classes automatically\n\n- Generate DDL SQL script automatically\n\n- Manage schema evolution for each project version\n\n- Compile C++ native code everywhere : Windows, Linux, MacOSX, Android, iOS, etc...\n\n- Transfer your data model over network and create quickly client/server applications",
            "comment_text_html": false,
            "comment_title": "qxBlog project",
            "dt_creation": "20131206222130",
            "dt_modification": "20140107093142",
            "id": 1,
            "list_meta_data": null,
            "user_id_creation": 0,
            "user_id_modification": 0
        }
    ],
    "list_enumerations": [
        {
            "app_version": 0,
            "description": "",
            "dt_creation": "20131206221840",
            "dt_modification": "20131210205552",
            "id": 1,
            "key": "",
            "list_meta_data": null,
            "list_of_key_value": {
                "female": 2,
                "male": 1,
                "unknown": 3
            },
            "name": "sex",
            "namespace": "",
            "project_id": {
                "id": 1
            },
            "project_version": 0,
            "qt_enum": false,
            "user_id_creation": 0,
            "user_id_modification": 0,
            "version": 0
        }
    ],
    "list_groups": null,
    "list_meta_data": null,
    "list_namespaces": null,
    "location": "C:/Temp/qxee",
    "name": "qxBlog",
    "project_guid": "{16335d56-73ac-48cf-8fcd-f74cc7d97201}",
    "project_parameters": {
        "app_version": 0,
        "default_entity_namespace": "",
        "default_primary_key_type": "long",
        "default_property_type": "QString",
        "dt_creation": "20131206221737",
        "dt_modification": "20131206221737",
        "id": 1,
        "list_meta_data": null,
        "lst_plugin_script": {
        },
        "primary_key_prefix": "",
        "primary_key_suffix": "_id",
        "project_id": {
            "id": 1
        },
        "table_name_prefix": "t_",
        "table_name_suffix": "",
        "user_id_creation": 0,
        "user_id_modification": 0
    },
    "user_id_creation": 0,
    "user_id_modification": 0,
    "version": 0
}


Importer à partir d'une base de données MySQL ou MariaDB

L'import d'une base de données MySQL (ou MariaDB) dans l'application QxEntityEditor se fait par le menu principal : Import >> Import from MySQL (or MariaDB) database :

Import MySQL or MariaDB

Cet écran d'import est divisé en plusieurs sections :

-- Section MySQL (or MariaDB) database connection :
  • Champ « Database server address (IP) » : adresse IP ou nom du serveur MySQL ;
  • Champ « Database port » : n° de port pour se connecter à la base de données MySQL ;
  • Champ « Database name » : nom de la base de données qu'on souhaite importer ;
  • Champ « Database login » : nom d'utilisateur pour se connecter à la base de données ;
  • Champ « Database password » : mot de passe pour se connecter à la base de données ;
  • Bouton « Connect to database » : démarre la connexion à la base de données : si une erreur se produit, un message d'avertissement est affiché, sinon la liste des tables de la base de données apparait dans la section « Database items to import to QxEntityEditor project ».

-- Section Import settings :
  • Champ « Namespace » : espace de nom utilisé pour regrouper les entités importées ;
  • Champ « Delete all entities in the namespace before importing » : supprime les entités de l'espace de nom ci-dessus avant de démarrer l'import des tables de la base de données ;
  • Champ « Import tables/columns comment to entities/properties description » : importe les commentaires des tables et colonnes définis dans la base de données ;
  • Champ « Add boost::optional<T> decoration if a column definition allows NULL value » : ajoute automatiquement la décoration boost::optional pour gérer la valeur NULL ;
  • Champ « Import columns default value » : importe les valeurs par défaut définies au niveau des colonnes de la base de données ;
  • Champ « Organize diagram layout after import process » : démarre automatiquement une réorganisation du diagramme d'entités après le processus d'import.

-- Section Relationship import settings :
  • Champ « Decoration » : décoration par défaut du type C++ (pour les relations, la bibliothèque QxOrm recommande l'utilisation de pointeurs intelligents : boost::shared_ptr, std::shared_ptr ou QSharedPointer) ;
  • Champ « Collection » : si le type de relation nécessite une liste (1-n et n-n), alors défini le type de liste C++ par défaut ;

-- Section Mapping database SQL type to C++ type : QxEntityEditor définit un mapping par défaut pour associer un type SQL à un type C++. Il est possible d'utiliser cette liste pour surcharger le comportement par défaut :
  • Colonne « SQL type » : type SQL à mapper. La recherche du type SQL n'est pas sensible à la casse, et s'effectue sur les 1er caractères : par exemple, mettre varchar va mapper VARCHAR(255) ;
  • Colonne « C++ type » : type C++ correspondant au type SQL ;
  • Bouton « Supprimer » : supprime une association type SQL / type C++.

-- Section Database items to import to QxEntityEditor project : lorsque QxEntityEditor est connecté à la base de données, la liste de tous les éléments (tables, colonnes, clés primaires, relations, vues, etc...) pouvant être importés dans le projet QxEntityEditor sont affichés dans cette section. Par défaut, aucun élément n'est sélectionné. Il est possible de tout sélectionner en 1 clic en cochant l'élément racine de l'arborescence. Il est également possible de sélectionner uniquement les éléments appartenant à un schéma. Une fois les éléments sélectionnés, le bouton « Ok » devient actif pour démarrer le processus d'import.


Remarque : tous les paramètres d'import (connexion à la base de données, paramètres d'import et des relations, liste mapping type SQL / type C++, etc...) sont enregistrés à la fermeture de cette fenêtre d'import. Tous les paramètres d'import sont automatiquement valorisés à la ré-ouverture de la fenêtre d'import.

Autre remarque : une vidéo de QxEntityEditor est disponible pour montrer un exemple d'import de la base de données de test MySQL : sakila.

Importer à partir d'une base de données PostgreSQL

L'import d'une base de données PostgreSQL dans l'application QxEntityEditor se fait par le menu principal : Import >> Import from PostgreSQL database :

Import PostgreSQL

Cet écran d'import est divisé en plusieurs sections :

-- Section PostgreSQL database connection :
  • Champ « Database server address (IP) » : adresse IP ou nom du serveur PostgreSQL ;
  • Champ « Database port » : n° de port pour se connecter à la base de données PostgreSQL ;
  • Champ « Database name » : nom de la base de données qu'on souhaite importer ;
  • Champ « Database login » : nom d'utilisateur pour se connecter à la base de données ;
  • Champ « Database password » : mot de passe pour se connecter à la base de données ;
  • Bouton « Connect to database » : démarre la connexion à la base de données : si une erreur se produit, un message d'avertissement est affiché, sinon la liste des tables de la base de données apparait dans la section « Database items to import to QxEntityEditor project ».

-- Section Import settings :
  • Champ « Namespace » : espace de nom utilisé pour regrouper les entités importées ;
  • Champ « Delete all entities in the namespace before importing » : supprime les entités de l'espace de nom ci-dessus avant de démarrer l'import des tables de la base de données ;
  • Champ « Import tables/columns comment to entities/properties description » : importe les commentaires des tables et colonnes définis dans la base de données ;
  • Champ « Add boost::optional<T> decoration if a column definition allows NULL value » : ajoute automatiquement la décoration boost::optional pour gérer la valeur NULL ;
  • Champ « Import columns default value » : importe les valeurs par défaut définies au niveau des colonnes de la base de données ;
  • Champ « Organize diagram layout after import process » : démarre automatiquement une réorganisation du diagramme d'entités après le processus d'import.

-- Section Relationship import settings :
  • Champ « Decoration » : décoration par défaut du type C++ (pour les relations, la bibliothèque QxOrm recommande l'utilisation de pointeurs intelligents : boost::shared_ptr, std::shared_ptr ou QSharedPointer) ;
  • Champ « Collection » : si le type de relation nécessite une liste (1-n et n-n), alors défini le type de liste C++ par défaut ;

-- Section Mapping database SQL type to C++ type : QxEntityEditor définit un mapping par défaut pour associer un type SQL à un type C++. Il est possible d'utiliser cette liste pour surcharger le comportement par défaut :
  • Colonne « SQL type » : type SQL à mapper. La recherche du type SQL n'est pas sensible à la casse, et s'effectue sur les 1er caractères : par exemple, mettre varchar va mapper VARCHAR(255) ;
  • Colonne « C++ type » : type C++ correspondant au type SQL ;
  • Bouton « Supprimer » : supprime une association type SQL / type C++.

-- Section Database items to import to QxEntityEditor project : lorsque QxEntityEditor est connecté à la base de données, la liste de tous les éléments (tables, colonnes, clés primaires, relations, vues, etc...) pouvant être importés dans le projet QxEntityEditor sont affichés dans cette section. Par défaut, aucun élément n'est sélectionné. Il est possible de tout sélectionner en 1 clic en cochant l'élément racine de l'arborescence. Il est également possible de sélectionner uniquement les éléments appartenant à un schéma. Une fois les éléments sélectionnés, le bouton « Ok » devient actif pour démarrer le processus d'import.


Remarque : tous les paramètres d'import (connexion à la base de données, paramètres d'import et des relations, liste mapping type SQL / type C++, etc...) sont enregistrés à la fermeture de cette fenêtre d'import. Tous les paramètres d'import sont automatiquement valorisés à la ré-ouverture de la fenêtre d'import.

Autre remarque : une vidéo de QxEntityEditor est disponible pour montrer un exemple d'import de la base de données de test MySQL : sakila.

Importer à partir d'une base de données SQLite

L'import d'une base de données SQLite dans l'application QxEntityEditor se fait par le menu principal : Import >> Import from SQLite database :

Import SQLite

Cet écran d'import est divisé en plusieurs sections :

-- Section Database connection :
  • Champ « Database path » : chemin d'accès au fichier base de données SQLite ;
  • Bouton « Connect to database » : démarre la connexion à la base de données : si une erreur se produit, un message d'avertissement est affiché, sinon la liste des tables de la base de données apparait dans la section « Database items to import to QxEntityEditor project ».

-- Section Import settings :
  • Champ « Namespace » : espace de nom utilisé pour regrouper les entités importées ;
  • Champ « Delete all entities in the namespace before importing » : supprime les entités de l'espace de nom ci-dessus avant de démarrer l'import des tables de la base de données ;
  • Champ « Import tables/columns comment to entities/properties description » : importe les commentaires des tables et colonnes définis dans la base de données ;
  • Champ « Add boost::optional<T> decoration if a column definition allows NULL value » : ajoute automatiquement la décoration boost::optional pour gérer la valeur NULL ;
  • Champ « Import columns default value » : importe les valeurs par défaut définies au niveau des colonnes de la base de données ;
  • Champ « Organize diagram layout after import process » : démarre automatiquement une réorganisation du diagramme d'entités après le processus d'import.

-- Section Relationship import settings :
  • Champ « Decoration » : décoration par défaut du type C++ (pour les relations, la bibliothèque QxOrm recommande l'utilisation de pointeurs intelligents : boost::shared_ptr, std::shared_ptr ou QSharedPointer) ;
  • Champ « Collection » : si le type de relation nécessite une liste (1-n et n-n), alors défini le type de liste C++ par défaut ;

-- Section Mapping database SQL type to C++ type : QxEntityEditor définit un mapping par défaut pour associer un type SQL à un type C++. Il est possible d'utiliser cette liste pour surcharger le comportement par défaut :
  • Colonne « SQL type » : type SQL à mapper. La recherche du type SQL n'est pas sensible à la casse, et s'effectue sur les 1er caractères : par exemple, mettre varchar va mapper VARCHAR(255) ;
  • Colonne « C++ type » : type C++ correspondant au type SQL ;
  • Bouton « Supprimer » : supprime une association type SQL / type C++.

-- Section Database items to import to QxEntityEditor project : lorsque QxEntityEditor est connecté à la base de données, la liste de tous les éléments (tables, colonnes, clés primaires, relations, vues, etc...) pouvant être importés dans le projet QxEntityEditor sont affichés dans cette section. Par défaut, aucun élément n'est sélectionné. Il est possible de tout sélectionner en 1 clic en cochant l'élément racine de l'arborescence. Il est également possible de sélectionner uniquement les éléments appartenant à un schéma. Une fois les éléments sélectionnés, le bouton « Ok » devient actif pour démarrer le processus d'import.


Remarque : tous les paramètres d'import (connexion à la base de données, paramètres d'import et des relations, liste mapping type SQL / type C++, etc...) sont enregistrés à la fermeture de cette fenêtre d'import. Tous les paramètres d'import sont automatiquement valorisés à la ré-ouverture de la fenêtre d'import.

Autre remarque : une vidéo de QxEntityEditor est disponible pour montrer un exemple d'import de la base de données de test MySQL : sakila.

Importer à partir d'une base de données en utilisant un driver ODBC (Oracle, MS SQL Server, etc.)

L'application QxEntityEditor fournit un import générique de base de données par connexion ODBC : menu principal Import >> Import from database using ODBC driver. Ce type d'import nécessite de défnir un DSN (Data Source Name) dans l'environnement. L'import par ODBC de l'application QxEntityEditor permet d'importer des bases de données de type : Oracle, Microsoft SQL Server, SQLite, MySQL/MariaDB, PostgreSQL, etc...

Import ODBC

Cet écran d'import est divisé en plusieurs sections :

-- Section Database connection :
  • Champ « DSN or connection string » : DSN (Data Source Name) défini dans l'environnement permettant de se connecter à la base de données par ODBC ;
  • Champ « Login » : nom d'utilisateur pour se connecter à la base de données (optionnel suivant les DSN) ;
  • Champ « Password » : mot de passe pour se connecter à la base de données (optionnel suivant les DSN) ;
  • Champ « Database type » : type de base de données : le type Generic permet de se connecter à tous types de bases mais avec certaines limitations (pas de relation, pas de clé primaire sur plusieurs colonnes). Il est conseillé de sélectionner le type réèl de base de données avant de démarrer la connexion à la base (Oracle, Microsoft SQL Server, SQLite, MySQL/MariaDB, PostgreSQL) ;
  • Bouton « Connect to database » : démarre la connexion à la base de données : si une erreur se produit, un message d'avertissement est affiché, sinon la liste des tables de la base de données apparait dans la section « Database items to import to QxEntityEditor project ».

-- Section Import settings :
  • Champ « Namespace » : espace de nom utilisé pour regrouper les entités importées ;
  • Champ « Delete all entities in the namespace before importing » : supprime les entités de l'espace de nom ci-dessus avant de démarrer l'import des tables de la base de données ;
  • Champ « Import tables/columns comment to entities/properties description » : importe les commentaires des tables et colonnes définis dans la base de données ;
  • Champ « Add boost::optional<T> decoration if a column definition allows NULL value » : ajoute automatiquement la décoration boost::optional pour gérer la valeur NULL ;
  • Champ « Import columns default value » : importe les valeurs par défaut définies au niveau des colonnes de la base de données ;
  • Champ « Organize diagram layout after import process » : démarre automatiquement une réorganisation du diagramme d'entités après le processus d'import.

-- Section Relationship import settings :
  • Champ « Decoration » : décoration par défaut du type C++ (pour les relations, la bibliothèque QxOrm recommande l'utilisation de pointeurs intelligents : boost::shared_ptr, std::shared_ptr ou QSharedPointer) ;
  • Champ « Collection » : si le type de relation nécessite une liste (1-n et n-n), alors défini le type de liste C++ par défaut ;

-- Section Mapping database SQL type to C++ type : QxEntityEditor définit un mapping par défaut pour associer un type SQL à un type C++. Il est possible d'utiliser cette liste pour surcharger le comportement par défaut :
  • Colonne « SQL type » : type SQL à mapper. La recherche du type SQL n'est pas sensible à la casse, et s'effectue sur les 1er caractères : par exemple, mettre varchar va mapper VARCHAR(255) ;
  • Colonne « C++ type » : type C++ correspondant au type SQL ;
  • Bouton « Supprimer » : supprime une association type SQL / type C++.

-- Section Database items to import to QxEntityEditor project : lorsque QxEntityEditor est connecté à la base de données, la liste de tous les éléments (tables, colonnes, clés primaires, relations, vues, etc...) pouvant être importés dans le projet QxEntityEditor sont affichés dans cette section. Par défaut, aucun élément n'est sélectionné. Il est possible de tout sélectionner en 1 clic en cochant l'élément racine de l'arborescence. Il est également possible de sélectionner uniquement les éléments appartenant à un schéma. Une fois les éléments sélectionnés, le bouton « Ok » devient actif pour démarrer le processus d'import.


Remarque : tous les paramètres d'import (connexion à la base de données, paramètres d'import et des relations, liste mapping type SQL / type C++, etc...) sont enregistrés à la fermeture de cette fenêtre d'import. Tous les paramètres d'import sont automatiquement valorisés à la ré-ouverture de la fenêtre d'import.

Autre remarque : une vidéo de QxEntityEditor est disponible pour montrer un exemple d'import de la base de données de test MySQL : sakila.

Plugins d'export

Tous les processus d'export de l'application QxEntityEditor sont accessibles depuis le menu principal Export :

Export plugins

Exporter en projet C++

L'export C++ génère un projet complet C++ prêt à être compilé (par qmake et/ou cmake) et contenant toutes les entités/propriétés/relations/énumérations enregistrées dans le contexte de la bibliothèque QxOrm. Toutes les fonctionnalités de la bibliothèque QxOrm (persistance, sérialisation, introspection, etc...) sont ainsi disponibles pour l'ensemble du projet C++ généré.

Paramètres de l'export C++

Les paramètres de l'export C++ sont accessibles par le menu principal : Tools >> Export to C++ project (settings). Cet écran de paramètrage apparait automatiquement au 1er export si aucun paramètre n'a été enregistré au niveau du projet. Lorsqu'un export C++ a déjà été réalisé, alors cette fenêtre de paramétrage est accessible uniquement par le menu principal : Tools >> Export to C++ project (settings) :

Export C++

Cet écran d'export est divisé en plusieurs sections :

-- Section C++ export settings :
  • Champ « C++ project location » : répertoire de destination qui contiendra tous les fichiers du projet C++ généré. Il est possible de renseigner dans ce champ un chemin relatif par rapport au fichier projet *.qxee ;
  • Champ « Relative path to QxOrm library » : si coché, le projet C++ référence la bibliothèque QxOrm avec un chemin relatif, sinon la dépendance à la bibliothèque QxOrm est définie avec un chemin absolu. Il est conseillé d'utiliser une variable d'environnement dans les paramètres de l'application QxEntityEditor (par exemple : $$(QXORM_DIR)) à la place de cette option ;
  • Champ « Generate a custom directory with custom files for each entity » : si coché, le projet C++ généré contient un fichier personnalisé par entité. Par défaut, ces fichiers custom sont vides et ne seront jamais écrasés par un nouvel export C++. Ces fichiers custom peuvent être utilisés par exemple pour implémenter les méthodes de validation, ou bien les méthodes de trigger.

-- Section Custom script (Javascript file) to change the default behaviour of the export process : paramétrage du moteur de personnalisation de l'export.
  • Champ « Custom script file » : chemin d'accès au fichier Javascript permettant de personnaliser l'export C++. Si vide, aucune personnalisation n'est appliquée (export par défaut). Il est possible de renseigner dans ce champ un chemin relatif par rapport au fichier projet *.qxee, par exemple ./my_script.js si le fichier my_script.js se trouve dans le même répertoire que le fichier projet *.qxee ;
  • Bouton « Debug custom Javascript file » : si un fichier Javascript est défini, un clic sur ce bouton déclenchera le mode débogage Javascript au prochain lancement d'export C++. Au lieu d'utiliser ce bouton, il est également possible d'activer le mode débogage Javascript en maintenant la touche SHIFT au moment de lancer un export C++.

-- Section C++ template files : cette section définit le code C++ des entités pour les fichiers Header *.h et Source *.cpp. Le moteur d'export utilise des mots-clé (placeholder sous la forme @@ACTION@@) pour remplacer le code par la valeur correspondante. Cette notion de placeholder est la base du moteur de personnalisation Javascript. Il est possible de renseigner des placeholder personnalisés en prefixant par @@CUSTOM_, par exemple : @@CUSTOM_MY_ACTION@@.
  • Option « No inheritance » : si coché (option par défaut), la classe C++ n'a pas d'héritage (aucune classe de base) ;
  • Option « qx::IxPersistable » : si coché, chaque classe C++ générée hérite de l'interface qx::IxPersistable (fourni une interface commune pour les actions de persistance à la base de données). Cette option rallonge les temps de compilation du projet C++ ;
  • Option « qx::IxPersistable + QObject » : si coché, chaque classe C++ générée hérite de l'interface qx::IxPersistable et de la classe Qt QObject. Cette option rallonge les temps de compilation du projet C++ ;
  • Option « Custom » : si coché, possibilité de fournir son propre code C++ (il est cependant conseillé de commencer à copier/coller Header *.h et Source *.cpp d'une des 3 autres options pour récupérer les placeholder à utiliser).

Présentation du projet C++ généré

Le projet C++ généré dispose de l'arborescence suivante :

Export C++ output

  • le dossier « bin » est vide par défaut, et contiendra le binaire compilé (*.dll sous Windows, *.so sous Linux, etc...) ;
  • le dossier « build » est vide par défaut, il peut être utilisé pour produire les fichiers CMake ;
  • le dossier « custom » est alimenté si l'option « Generate a custom directory with custom files for each entity » est coché. Ces fichiers custom peuvent être utilisés par exemple pour implémenter les méthodes de validation, ou bien les méthodes de trigger ;
  • le dossier « include » contient les définitions de toutes les classes entités et énumérations du projet ;
  • le dossier « src » contient les implémentations de toutes les classes entités et énumérations du projet ;
  • le fichier « CMakeLists.txt » peut être utilisé pour compiler le projet C++ avec CMake ;
  • les fichiers « *.gen.pri » et « *.gen.pro » peuvent être utilisés pour compiler le projet C++ avec qmake ;

Compilation du projet C++ généré (par qmake ou cmake)

Le projet C++ généré peut être compilé avec CMake ou qmake.
La bibliothèque QxOrm dispose de certaines options de compilation documentées dans les fichiers QxOrm.pri et QxOrm.cmake (il est possible de conserver les options par défaut).
Le manuel utilisateur de la bibliothèque QxOrm indique comment procéder à la compilation du projet.
Un tutoriel est également disponible pour expliquer l'installation d'un environnement de développement sous Windows avec MSVC.
Une fois le projet C++ compilé avec succès, le binaire est disponible dans le dossier « bin » du projet exporté (*.dll sous Windows, *.so sous Linux, etc...).

Exemple d'utilisation

Le dossier ./samples/ du package QxEntityEditor fournit un projet de test : qxBlog.qxee. Ce projet de test peut être ouvert même avec une version de QxEntityEditor sans clé de licence active. Une fois exporté en projet C++, il est possible de compiler le projet afin d'obtenir une bibliothèque partagée qxBlog.dll (ou qxBlog.so sous Linux). Cette bibliothèque partagée possède toutes les entités et énumérations du projet enregistrées dans le contexte QxOrm : toutes les fonctionnalités de la bibliothèque QxOrm sont ainsi disponibles.

Le dossier ./samples/ du package QxEntityEditor fournit également un projet d'exemple d'utilisation du binaire compilé : qxBlogExec.zip. Une fois dézippé, le fichier readme.txt à la racine contient les instructions d'installation et compilation de ce projet d'exemple :

--------------------------------------------
-- To build qxBlogExec project with qmake --
--------------------------------------------

1- Export the 'qxBlog.qxee' project as a C++ project with QxEntityEditor and build it
2- Open the 'qxBlogExec.pro' file
3- Replace '$$(QXORM_DIR)' by your QxOrm library installation path
4- Replace 'C:/Temp/qxee/cpp/' by the path where you have exported the 'qxBlog.qxee' project as a C++ project
5- run command line : qmake
6- run command line : make debug (or make release)


--------------------------------------------
-- To build qxBlogExec project with CMake --
--------------------------------------------

1- Export the 'qxBlog.qxee' project as a C++ project with QxEntityEditor and build it
2- Open the 'CMakeLists.txt' file
3- Replace '$ENV{QXORM_DIR}' by your QxOrm library installation path
4- Replace 'C:/Temp/qxee/cpp/' by the path where you have exported the 'qxBlog.qxee' project as a C++ project
5- run cmake or cmake-gui to configure and generate your make files


Voici le contenu commenté de la fonction main() qui montre un exemple d'utilisation (proche du tutoriel qxBlog) :

int main(int argc, char * argv[])
{
   // Qt application
   QCoreApplication app(argc, argv);
   QFile::remove("./qxBlog.sqlite");

   // Parameters to connect to database
   qx::QxSqlDatabase::getSingleton()->setDriverName("QSQLITE");
   qx::QxSqlDatabase::getSingleton()->setDatabaseName("./qxBlog.sqlite");
   qx::QxSqlDatabase::getSingleton()->setHostName("localhost");
   qx::QxSqlDatabase::getSingleton()->setUserName("root");
   qx::QxSqlDatabase::getSingleton()->setPassword("");

   // Only for debug purpose : assert if invalid offset detected fetching a relation
   qx::QxSqlDatabase::getSingleton()->setVerifyOffsetRelation(true);

   // !!! TO CREATE TABLES, PLEASE USE THE C++ DDL SQL EXPORT PLUGIN OF QXENTITYEDITOR !!!
   // Create all tables in database (you should not use 'qx::dao::create_table<T>()' function in a production software, use it just for prototypes or samples)
   QSqlError daoError = qx::dao::create_table<author>();
   daoError = qx::dao::create_table<comment>();
   daoError = qx::dao::create_table<category>();
   daoError = qx::dao::create_table<blog>();

   // Create a list of 3 author
   author_ptr author_1; author_1.reset(new author());
   author_ptr author_2; author_2.reset(new author());
   author_ptr author_3; author_3.reset(new author());

   author_1->setlastname("author_1");
   author_1->setsex(sex::male);
   author_1->setbirthdate(QDateTime::currentDateTime());
   author_2->setlastname("author_2");
   author_2->setsex(sex::female);
   author_2->setbirthdate(QDateTime::currentDateTime());
   author_3->setlastname("author_3");
   author_3->setsex(sex::female);
   author_3->setbirthdate(QDateTime::currentDateTime());

   list_of_author authorX;
   authorX.insert(1, author_1);
   authorX.insert(2, author_2);
   authorX.insert(3, author_3);

   // Insert list of 3 author into database
   daoError = qx::dao::insert(authorX);
   qAssert(qx::dao::count<author>() == 3);

   // Clone author n°2 : 'author_id_2'
   author_ptr author_clone = qx::clone(* author_2);
   qAssert(author_clone->getauthor_id() == author_2->getauthor_id());
   qAssert(author_clone->getsex() == sex::female);

   // Create a query to fetch only female author : 'author_id_2' and 'author_id_3'
   qx::QxSqlQuery query("WHERE t_author.sex = :sex");
   query.bind(":sex", sex::female);

   list_of_author list_of_female_author;
   daoError = qx::dao::fetch_by_query(query, list_of_female_author);
   qAssert(list_of_female_author.count() == 2);

   // Dump list of female author (xml serialization)
   qx::dump(list_of_female_author);

   // Create 3 categories
   category_ptr category_1 = category_ptr(new category("cat_1"));
   category_ptr category_2 = category_ptr(new category("cat_2"));
   category_ptr category_3 = category_ptr(new category("cat_3"));

   category_1->setname("category_1"); category_1->setdescription("desc_1");
   category_2->setname("category_2"); category_2->setdescription("desc_2");
   category_3->setname("category_3"); category_3->setdescription("desc_3");

   { // Create a scope to destroy temporary connexion to database

   // Open a transaction to database
   QSqlDatabase db = qx::QxSqlDatabase::getDatabase();
   bool bCommit = db.transaction();

   // Insert 3 categories into database, use 'db' parameter for the transaction
   daoError = qx::dao::insert(category_1, (& db));    bCommit = (bCommit && ! daoError.isValid());
   daoError = qx::dao::insert(category_2, (& db));    bCommit = (bCommit && ! daoError.isValid());
   daoError = qx::dao::insert(category_3, (& db));    bCommit = (bCommit && ! daoError.isValid());

   qAssert(bCommit);
   qAssert(category_1->getcategory_id() != "");
   qAssert(category_2->getcategory_id() != "");
   qAssert(category_3->getcategory_id() != "");

   // Terminate transaction => commit or rollback if there is error
   if (bCommit) { db.commit(); }
   else { db.rollback(); }

   } // End of scope : 'db' is destroyed

   // Create a blog with the class name (factory)
   boost::any blog_any = qx::create("blog");
   blog_ptr blog_1;
   try { blog_1 = boost::any_cast<blog_ptr>(blog_any); }
   catch (...) { blog_1.reset(new blog()); }
   blog_1->settext("blog_text_1");
   blog_1->settitle("blog_title_1");
   blog_1->setauthor(author_1);

   // Insert 'blog_1' into database with 'save()' method
   daoError = qx::dao::save(blog_1);

   // Modify 'blog_1' properties and save into database
   blog_1->settext("update blog_text_1");
   blog_1->setauthor(author_2);
   daoError = qx::dao::save(blog_1);

   // Add 2 comments to 'blog_1'
   comment_ptr comment_1; comment_1.reset(new comment());
   comment_ptr comment_2; comment_2.reset(new comment());

   comment_1->settext("comment_1 text");
   comment_1->setblog_id(blog_1);
   comment_2->settext("comment_2 text");
   comment_2->setblog_id(blog_1);

   daoError = qx::dao::insert(comment_1);
   daoError = qx::dao::insert(comment_2);
   qAssert(qx::dao::count<comment>() == 2);

   // Add 2 categories to 'blog_1' => must insert into extra-table 'category_blog'
   blog::type_list_of_category lst_category;
   lst_category.insert(category_1->getcategory_id(), category_1);
   lst_category.insert(category_3->getcategory_id(), category_3);
   blog_1->setlist_of_category(lst_category);
   daoError = qx::dao::save_with_relation("list_of_category", blog_1);

   // Fetch blog into a new variable with all relation : 'author', 'comment' and 'category'
   blog_ptr blog_tmp; blog_tmp.reset(new blog());
   blog_tmp->setblog_id(blog_1->getblog_id());
   daoError = qx::dao::fetch_by_id_with_all_relation(blog_tmp);

   qAssert(blog_tmp->list_of_comment().count() == 2);
   qAssert(blog_tmp->list_of_category().count() == 2);
   qAssert(blog_tmp->gettext() == "update blog_text_1");
   qAssert(blog_tmp->getauthor() && blog_tmp->getauthor()->getauthor_id() == author_2->getauthor_id());

   // Fetch blog into a new variable with many relations using "*->*->*->*" (4 levels of relationships)
   blog_tmp.reset(new blog());
   blog_tmp->setblog_id(blog_1->getblog_id());
   daoError = qx::dao::fetch_by_id_with_relation("*->*->*->*", blog_tmp);

   qAssert(blog_tmp->list_of_comment().count() == 2);
   qAssert(blog_tmp->list_of_category().count() == 2);
   qAssert(blog_tmp->gettext() == "update blog_text_1");
   qAssert(blog_tmp->getauthor() && blog_tmp->getauthor()->getauthor_id() == author_2->getauthor_id());

   // Dump 'blog_tmp' result from database (xml serialization)
   qx::dump(blog_tmp);

   // Check qx::dao::save_with_relation_recursive() function
   daoError = qx::dao::save_with_relation_recursive(blog_tmp);
   qAssert(! daoError.isValid());
   daoError = qx::dao::save_with_relation_recursive(blog_tmp, qx::dao::save_mode::e_update_only);
   qAssert(! daoError.isValid());

   // Call 'age()' method with class name and method name (reflexion)
   //qx_bool bInvokeOk = qx::QxClassX::invoke("author", "age", author_1);
   //qAssert(bInvokeOk);

   // Test 'isDirty()' method
   qx::dao::ptr<blog> blog_isdirty = qx::dao::ptr<blog>(new blog());
   blog_isdirty->setblog_id(blog_1->getblog_id());
   daoError = qx::dao::fetch_by_id(blog_isdirty);
   qAssert(! daoError.isValid() && ! blog_isdirty.isDirty());

   blog_isdirty->settext("blog property 'text' modified => blog is dirty !!!");
   QStringList lstDiff; bool bDirty = blog_isdirty.isDirty(lstDiff);
   qAssert(bDirty && (lstDiff.count() == 1) && (lstDiff.at(0) == "text"));
   if (bDirty) { qDebug("[QxOrm] test dirty 1 : blog is dirty => '%s'", qPrintable(lstDiff.join("|"))); }

   // Update only property 'm_text' of 'blog_isdirty'
   daoError = qx::dao::update_optimized(blog_isdirty);
   qAssert(! daoError.isValid() && ! blog_isdirty.isDirty());
   qx::dump(blog_isdirty);

   // Test 'isDirty()' method with a container
   typedef qx::dao::ptr< QList<author_ptr> > type_lst_author_test_is_dirty;
   type_lst_author_test_is_dirty container_isdirty = type_lst_author_test_is_dirty(new QList<author_ptr>());
   daoError = qx::dao::fetch_all(container_isdirty);
   qAssert(! daoError.isValid() && ! container_isdirty.isDirty() && (container_isdirty->count() == 3));

   author_ptr author_ptr_dirty = container_isdirty->at(1);
   author_ptr_dirty->setlastname("author name modified at index 1 => container is dirty !!!");
   bDirty = container_isdirty.isDirty(lstDiff);
   qAssert(bDirty && (lstDiff.count() == 1));
   if (bDirty) { qDebug("[QxOrm] test dirty 2 : container is dirty => '%s'", qPrintable(lstDiff.join("|"))); }

   author_ptr_dirty = container_isdirty->at(2);
   author_ptr_dirty->setfirstname("firstname changed");
   bDirty = container_isdirty.isDirty(lstDiff);
   qAssert(bDirty && (lstDiff.count() == 2));
   if (bDirty) { qDebug("[QxOrm] test dirty 3 : container is dirty => '%s'", qPrintable(lstDiff.join("|"))); }

   // Update only property 'm_name' at position 1, only property 'm_birthdate' at position 2 and nothing at position 0
   daoError = qx::dao::update_optimized(container_isdirty);
   qAssert(! daoError.isValid() && ! container_isdirty.isDirty());
   qx::dump(container_isdirty);

   // Fetch only property 'm_text' of blog
   QStringList lstColumns = QStringList() << "text";
   QList<blog_ptr> lst_blog_with_only_text;
   daoError = qx::dao::fetch_all(lst_blog_with_only_text, NULL, lstColumns);
   qAssert(! daoError.isValid() && (lst_blog_with_only_text.size() > 0));
   if ((lst_blog_with_only_text.size() > 0) && (lst_blog_with_only_text[0].get() != NULL))
   { qAssert(lst_blog_with_only_text[0]->gettitle().isEmpty()); }
   qx::dump(lst_blog_with_only_text);

   // Dump all registered classes into QxOrm context (introspection engine)
   qx::QxClassX::dumpAllClasses();

   // Call a custom SQL query or a stored procedure
   qx_query testStoredProc("SELECT * FROM t_author");
   daoError = qx::dao::call_query(testStoredProc);
   qAssert(! daoError.isValid());
   testStoredProc.dumpSqlResult();

   // Call a custom SQL query or a stored procedure and fetch automatically properties (with a collection of items)
   qx_query testStoredProcBis("SELECT * FROM t_author");
   authorX.clear();
   daoError = qx::dao::execute_query(testStoredProcBis, authorX);
   qAssert(! daoError.isValid()); qAssert(authorX.count() > 0);
   qx::dump(authorX);

   // Call a custom SQL query or a stored procedure and fetch automatically properties
   qx_query testStoredProcThird("SELECT name, category_id FROM t_category");
   category_ptr category_tmp = category_ptr(new category());
   daoError = qx::dao::execute_query(testStoredProcThird, category_tmp);
   qAssert(! daoError.isValid()); qAssert(category_tmp->getcategory_id() != "");
   qx::dump(category_tmp);

   return 0;
}


Exporter en projet C++ de type model/view

La bibliothèque QxOrm fournit le module QxModelView. Une documentation sur le module QxModelView est disponible dans le manuel utilisateur de la bibliothèque QxOrm. Le module QxModelView permet d'utiliser le moteur model/view de Qt avec toutes les classes enregistrées dans le contexte QxOrm :
  • QML : toute propriété enregistrée dans le contexte QxOrm est accessible en QML : le module QxModelView permet ainsi de faciliter l'intéraction entre QML et les bases de données ;
  • Qt widgets : utilisation de QTableView ou QListView par exemple pour afficher/modifier le contenu d'une table de la base de données.

L'application QxEntityEditor permet de générer un projet C++ de type model/view complet et prêt à être compilé : ainsi toutes les entités et leurs relations sont accessibles dans des vues QML par exemple.

Paramètres de l'export

Les paramètres de l'export C++ de type model/view sont accessibles par le menu principal : Tools >> Export to C++ model/view project (settings). Cet écran de paramètrage apparait automatiquement au 1er export si aucun paramètre n'a été enregistré au niveau du projet. Lorsqu'un export C++ model/view a déjà été réalisé, alors cette fenêtre de paramétrage est accessible uniquement par le menu principal : Tools >> Export to C++ model/view project (settings) :

Export C++ model/view

Cet écran d'export est divisé en plusieurs sections :

-- Section C++ model/view export settings :
  • Champ « C++ model/view project location » : répertoire de destination qui contiendra tous les fichiers du projet C++ model/view généré. Il est possible de renseigner dans ce champ un chemin relatif par rapport au fichier projet *.qxee ;
  • Champ « C++ entities project location » : lecture seule uniquement, indique le répertoire de destination du projet C++ généré (entités enregistrées dans le contexte QxOrm) dont dépend le projet C++ model/view ;
  • Champ « Namespace for model/view » : espace de nom utilisé pour les classes C++ générées de type model/view (ces classes implémentent l'interface qx::IxModel) ;
  • Champ « Generate custom files » : si coché, le projet C++ généré contient un fichier personnalisé par entité. Par défaut, ces fichiers custom sont vides et ne seront jamais écrasés par un nouvel export C++.

-- Section Custom script (Javascript file) to change the default behaviour of the export process : paramétrage du moteur de personnalisation de l'export.
  • Champ « Custom script file » : chemin d'accès au fichier Javascript permettant de personnaliser l'export C++. Si vide, aucune personnalisation n'est appliquée (export par défaut). Il est possible de renseigner dans ce champ un chemin relatif par rapport au fichier projet *.qxee, par exemple ./my_script.js si le fichier my_script.js se trouve dans le même répertoire que le fichier projet *.qxee ;
  • Bouton « Debug custom Javascript file » : si un fichier Javascript est défini, un clic sur ce bouton déclenchera le mode débogage Javascript au prochain lancement d'export C++. Au lieu d'utiliser ce bouton, il est également possible d'activer le mode débogage Javascript en maintenant la touche SHIFT au moment de lancer un export C++.

-- Section C++ model/view template files : cette section définit le code C++ model/view pour les fichiers Header *.h et Source *.cpp. Le moteur d'export utilise des mots-clé (placeholder sous la forme @@ACTION@@) pour remplacer le code par la valeur correspondante. Cette notion de placeholder est la base du moteur de personnalisation Javascript. Il est possible de renseigner des placeholder personnalisés en prefixant par @@CUSTOM_, par exemple : @@CUSTOM_MY_ACTION@@.

Présentation du projet généré

Le projet C++ model/view généré dispose de l'arborescence suivante :

Export C++ model/view output

  • le dossier « bin » est vide par défaut, et contiendra le binaire compilé (*.dll sous Windows, *.so sous Linux, etc...) ;
  • le dossier « build » est vide par défaut, il peut être utilisé pour produire les fichiers CMake ;
  • le dossier « custom » est alimenté si l'option « Generate custom files » est cochée ;
  • le dossier « include » contient les définitions de tous les modèles du projet ;
  • le dossier « src » contient les implémentations de tous les modèles du projet ;
  • le fichier « CMakeLists.txt » peut être utilisé pour compiler le projet C++ avec CMake ;
  • les fichiers « *.gen.pri » et « *.gen.pro » peuvent être utilisés pour compiler le projet C++ avec qmake ;

Exporter en projet C++ de type services

La bibliothèque QxOrm fournit le module QxService. Une documentation sur le module QxService est disponible dans le manuel utilisateur de la bibliothèque QxOrm. Le module QxService de la bibliothèque QxOrm permet de créer rapidement un serveur d'applications C++ performant (notion de services avec demande du client et réponse du serveur). Un tutoriel est disponible sur le site QxOrm afin de présenter un exemple d'utilisation du module QxService.

L'application QxEntityEditor permet de générer un projet C++ de type services (un projet C++ pour gérer la couche cliente et un projet C++ pour publier les services côté serveur) complet et prêt à être compilé : ainsi toutes les entités et leurs relations peuvent être transférées sur le réseau pour une application de type client/serveur.

Paramètres de l'export

Les paramètres de l'export C++ de type services sont accessibles par le menu principal : Tools >> Export to C++ services project (settings). Cet écran de paramètrage apparait automatiquement au 1er export si aucun paramètre n'a été enregistré au niveau du projet. Lorsqu'un export C++ de type services a déjà été réalisé, alors cette fenêtre de paramétrage est accessible uniquement par le menu principal : Tools >> Export to C++ services project (settings) :

Export C++ services

Cet écran d'export est divisé en plusieurs sections :

-- Section C++ services export settings :
  • Champ « C++ services project location » : répertoire de destination qui contiendra tous les fichiers du projet C++ de type services généré. Il est possible de renseigner dans ce champ un chemin relatif par rapport au fichier projet *.qxee ;
  • Champ « C++ entities project location » : lecture seule uniquement, indique le répertoire de destination du projet C++ généré (entités enregistrées dans le contexte QxOrm) dont dépend le projet C++ services ;
  • Champ « Namespace for services » : espace de nom utilisé pour les classes C++ générées de type services (ces classes permettent de transférer les entités sur le réseau, couche cliente et serveur) ;
  • Champ « Generate custom files » : si coché, le projet C++ généré contient un fichier personnalisé par entité. Par défaut, ces fichiers custom sont vides et ne seront jamais écrasés par un nouvel export C++. Ces fichiers custom peuvent par exemple être utilisés pour implémenter des nouveaux services ;
  • Champ « Generate server application » : si coché, un projet C++ d'exemple de type serveur d'applications est généré et permet de charger et publier les services côté serveur avec un système de plugins ;
  • Champ « Server application location » : si l'option « Generate server application » est cochée, défini le répertoire de destination du projet d'exemple serveur d'applications.

-- Section Custom script (Javascript file) to change the default behaviour of the export process : paramétrage du moteur de personnalisation de l'export.
  • Champ « Custom script file » : chemin d'accès au fichier Javascript permettant de personnaliser l'export C++. Si vide, aucune personnalisation n'est appliquée (export par défaut). Il est possible de renseigner dans ce champ un chemin relatif par rapport au fichier projet *.qxee, par exemple ./my_script.js si le fichier my_script.js se trouve dans le même répertoire que le fichier projet *.qxee ;
  • Bouton « Debug custom Javascript file » : si un fichier Javascript est défini, un clic sur ce bouton déclenchera le mode débogage Javascript au prochain lancement d'export C++. Au lieu d'utiliser ce bouton, il est également possible d'activer le mode débogage Javascript en maintenant la touche SHIFT au moment de lancer un export C++.

-- Section C++ services template files : cette section définit le code C++ des services pour les fichiers Header *.h et Source *.cpp (client et serveur). Le moteur d'export utilise des mots-clé (placeholder sous la forme @@ACTION@@) pour remplacer le code par la valeur correspondante. Cette notion de placeholder est la base du moteur de personnalisation Javascript. Il est possible de renseigner des placeholder personnalisés en prefixant par @@CUSTOM_, par exemple : @@CUSTOM_MY_ACTION@@.
  • Option « Default » : si coché (option par défaut), génère les services (couche cliente et serveur) par défaut : les entités peuvent être transférées sur le réseau et les actions CRUD sur la base de données sont supportées ;
  • Option « Custom » : si coché, possibilité de fournir son propre code C++ pour générer les services (il est cependant conseillé de commencer à copier/coller Header *.h et Source *.cpp de l'option par défaut pour récupérer les placeholder à utiliser).

Présentation du projet généré

Le projet C++ de type services (client et serveur) généré dispose de l'arborescence suivante :

Export C++ services output

  • le dossier « bin » est vide par défaut, et contiendra les binaires compilés (*.dll sous Windows, *.so sous Linux, etc...) pour la partie cliente et serveur ;
  • le dossier « build » est vide par défaut, il peut être utilisé pour produire les fichiers CMake ;
  • le dossier « client » contient les fichiers qmake et CMake pour compiler la couche cliente du projet ;
  • le dossier « custom » est alimenté si l'option « Generate custom files » est cochée ;
  • le dossier « include » contient les définitions de tous les services du projet ;
  • le dossier « server » contient les fichiers qmake et CMake pour compiler la couche serveur du projet ;
  • le dossier « src » contient les implémentations de tous les services du projet ;
  • le fichier « CMakeLists.txt » peut être utilisé pour compiler le projet C++ (client et serveur) avec CMake ;
  • les fichiers « *.gen.pri » et « *.gen.pro » peuvent être utilisés pour compiler le projet C++ (client et serveur) avec qmake ;
  • le fichier « *.gen.json » est utilisé par la couche serveur pour générer un plugin pouvant être chargé dynamiquement par le serveur d'applications.

Serveur d'applications générique

Si l'option « Generate server application » est cochée, l'export C++ de type services génère également un exemple de serveur d'applications générique pouvant publier des services en chargeant des plugins. Tout comme les autres projets C++ générés par QxEntityEditor, le serveur d'applications générique peut être compilé qmake et CMake. Ce projet d'exemple dispose de l'arborescence suivante :

Export C++ services server app output

Une fois compilé, l'exécutable se trouve dans le dossier « bin ». Le lancement du serveur d'applications générique ouvre la fenêtre suivante :

Export C++ services server app

Cet écran est divisé en plusieurs sections :

-- Section Plugins services :
  • Champ « Plugins path » : il est nécessaire de définir le répertoire contenant les plugins à charger. Ces plugins correspondent à la couche serveur du projet C++ de type services. Une fois chargé, les plugins publient des services pouvant être appelés par les applications clientes. Si aucun plugin n'est chargé après la sélection du répertoire, il est possible de définir la variable d'environnement QT_DEBUG_PLUGINS afin d'avoir des logs sur l'erreur de chargement de plugin (en général, une dépendance du plugin non trouvé).

-- Section Database connection parameters :
  • Cette section contient tous les paramètres nécessaires pour initialiser la connexion à la base de données utilisée par les services (utilisation de la classe qx::QxSqlDatabase).

-- Section Server parameters :
  • Champ « Port number » : défini le n° de port utilisé par le serveur d'applications pour publier les services. Les applications clientes devront se connecter sur ce port pour effectuer des requêtes au serveur ;
  • Champ « Thread count » : nombre de threads utilisés par le serveur pour traiter les requêtes provenant des applications clientes ;
  • Champ « Serialization type » : type de sérialisation utilisé pour renvoyer les réponses du serveur au client ;
  • Champ « Compress data » : si coché, les données renvoyées au client sont compressées ;
  • Champ « Encrypt data » : si coché, les données renvoyées au client sont cryptées (possibilité de définir une clé de cryptage) ;
  • Bouton « Start server » : bouton permettant de démarrer et arrêter le serveur.

-- Section Log last client-server reply-request transaction :
  • Affiche dans un flux XML ou JSON les détails de la dernière transaction client-serveur traitée par le serveur d'applications.

-- Section Log last server error :
  • Si une erreur se produit sur le serveur d'applications, elle est automatiquement logguée dans cette section.

Exporter le schéma de base de données SQL DDL

L'application QxEntityEditor permet de générer le schéma de base de données dans un format DDL SQL. L'application QxEntityEditor supporte les bases de données les plus fréquemment utilisées : SQLite, MySQL, MariaDB, PostgreSQL, Oracle et Microsoft SQL Server. Le script DDL SQL généré par QxEntityEditor peut être importé par la base de données pour créer automatiquement toutes les tables, colonnes, clés primaires, relations, index, etc... Les paramètres de l'export DDL SQL sont accessibles par le menu principal : Tools >> Export to DDL SQL script file (settings) :

Export SQL DDL

Cet écran d'export est divisé en plusieurs sections :

-- Section DDL export settings :
  • Champ « File location » : répertoire de destination qui contiendra le script DDL SQL généré ;
  • Champ « Database type » : type de base de données qui sera utilisé pour importer le schéma DDL SQL (SQLite, MySQL, MariaDB, PostgreSQL, Oracle ou Microsoft SQL Server) ;
  • Champ « Relationships » : si coché, des clés étrangères (foreign keys) sont créées pour gérer les relations entre entités ;
  • Champ « Schema » : défini le type d'export DDL : 1 fichier contenant toute la structure du projet *.qxee, ou bien 1 fichier par version du projet *.qxee (gestion de l'évolution du schéma de base de données).

-- Section Mapping C++ type to database SQL type :
  • Liste permettant d'associer un type C++ (renseigné au niveau des propriétés du projet *.qxee) à un type SQL.

-- Section Custom script (Javascript file) to change the default behaviour of the export process : paramétrage du moteur de personnalisation de l'export.
  • Champ « Custom script file » : chemin d'accès au fichier Javascript permettant de personnaliser l'export DDL. Si vide, aucune personnalisation n'est appliquée (export par défaut). Il est possible de renseigner dans ce champ un chemin relatif par rapport au fichier projet *.qxee, par exemple ./my_script.js si le fichier my_script.js se trouve dans le même répertoire que le fichier projet *.qxee ;
  • Bouton « Debug custom Javascript file » : si un fichier Javascript est défini, un clic sur ce bouton déclenchera le mode débogage Javascript au prochain lancement d'export DDL. Au lieu d'utiliser ce bouton, il est également possible d'activer le mode débogage Javascript en maintenant la touche SHIFT au moment de lancer un export DDL.

Imprimer le diagramme d'entités

L'application QxEntityEditor permet d'imprimer le diagramme d'entités dans un format PNG et/ou PDF. Les paramètres d'impression sont accessibles par le menu principal : Tools >> Print the entities diagram (settings) :

Export print PNG/PDF

Exporter le projet sous format XML ou JSON

L'application QxEntityEditor permet d'exporter l'intégralité d'un projet *.qxee dans un format XML ou JSON. Les paramètres d'export XML/JSON sont accessibles par le menu principal : Tools >> Export to XML or JSON file (settings) :

Export XML/JSON

Remarque : un export XML ne peut pas être importé dans un projet *.qxee. Par contre, un fichier JSON peut être utilisé pour importer les données dans un projet *.qxee en utilisant le plugin d'import : Importer un projet à partir d'un fichier texte au format JSON.

Moteur Javascript pour personnaliser les exports

L'application QxEntityEditor fournit un puissant moteur de personnalisation des exports. Ce moteur utilise le langage Javascript pour écrire des scripts pour personnaliser les exports. Ces scripts Javascript ont accès à l'ensemble des paramètres d'un projet *.qxee, et peuvent être débogués à l'aide d'un débogueur intégré à QxEntityEditor. Il est également possible d'écrire de nouveaux fichiers lors des exports.

Remarque : le dossier ./samples/ du package QxEntityEditor fournit 2 exemples de scripts documentés : custom_script.js et q_property.js.

Architecture et fonctionnement du moteur de personnalisation Javascript

Tous les plugins d'export de l'application QxEntityEditor dispose d'un paramétrage nommé : Custom script (Javascript file) to change the default behaviour of the export process. Il est ainsi possible de paramétrer un script Javascript utilisé au moment de l'export. Le moteur d'export utilise des mots-clé (placeholder sous la forme @@ACTION@@) pour remplacer le code par la valeur correspondante. Cette notion de placeholder est la base du moteur de personnalisation Javascript. Il est possible de renseigner des placeholder personnalisés en prefixant par @@CUSTOM_, par exemple : @@CUSTOM_MY_ACTION@@. Lors d'un export, l'application QxEntityEditor parcourt la liste de toutes les entités définies dans le projet *.qxee. Chaque fois qu'un placeholder (sous la forme @@ACTION@@) est rencontré, le script Javascript est appelé avec tous les paramètres nécessaires pour effectuer ou non une personnalisation.

Voici un exemple de script Javascript minimal. Ce script ne fait rien, il permet de montrer uniquement la structure minimale d'un Javascript valide pour QxEntityEditor :
({

// Here is the entry point of the QxEntityEditor javascript engine
// This function is called for each placeholder defined in the C++ template section
customProcess : function(params)
{
   try
   {
      // quit with 'params[0]' means : doesn't change the default export behaviour
      return params[0];
   }
   catch (err)
   { return ("[CustomScriptError] an unexpected error occurred : " + err); }
}

});


Liste des paramètres d'appel du moteur Javascript

Le paramètre d'entrée params de la fonction customProcess() est un tableau contenant une liste de valeurs (ce qui correspond au contexte d'appel du script). Voici un exemple de fonction qui peut être utilisée dans vos scripts pour lister et donner une signification aux valeurs d'entrée :

function printParams(params)
{
   var log = "";
   log = log + "\n - default_value = " + params[0];
   log = log + "\n - project_name = " + params[1];
   log = log + "\n - project_file = " + params[2];
   log = log + "\n - plugin_name = " + params[3];
   log = log + "\n - current_file = " + params[4];
   log = log + "\n - action (or placeholder) = " + params[5];
   log = log + "\n - entity_name = " + params[6];
   log = log + "\n - entity_table_name = " + params[7];
   log = log + "\n - property_name = " + params[8];
   log = log + "\n - property_type = " + params[9];
   log = log + "\n - property_column_name = " + params[10];
   log = log + "\n - property_is_primary_key = " + params[11];
   log = log + "\n - enumeration_name = " + params[12];
   log = log + "\n - entity_id = " + params[13];
   log = log + "\n - property_id = " + params[14];
   log = log + "\n - enumeration_id = " + params[15];
   log = log + "\n - output_location = " + params[16];

   print(log); // print value to the custom script debugger window
   helper.print(log); // print value to the standard output (for example, on Windows, use the 'DebugView' application to see all logs)
   return log;
}


Fonctions disponibles par Javascript

Le moteur de personnalisation des exports de QxEntityEditor supporte toutes les fonctionnalités du langage Javascript (ECMAScript 5). L'application QxEntityEditor fournit en plus une instance d'objet nommée helper qui peut être utilisée pour accéder à de nouvelles fonctionnalités. Nous allons lister dans ce chapitre les cas d'usage les plus couramment utilisés pour personnaliser les exports.

Obtenir les informations associées à une entité

Voici comment récupérer le paramétrage de l'entité courante, helper.getEntityDetails(entity_id) :

var entity_id = params[13];
printEntityDetails(entity_id);

//...

function printEntityDetails(entity_id)
{
   var details = helper.getEntityDetails(entity_id);
   if (details.length == 0) { return details; }

   var log = "";
   log = log + "\n - entity_id = " + details[0];
   log = log + "\n - entity_key = " + details[1];
   log = log + "\n - entity_name = " + details[2];
   log = log + "\n - entity_namespace = " + details[3];
   log = log + "\n - entity_tablename = " + details[4];
   log = log + "\n - entity_description = " + details[5];
   log = log + "\n - entity_is_read_only = " + details[6];
   log = log + "\n - entity_is_abstract = " + details[7];
   log = log + "\n - entity_version = " + details[8];
   log = log + "\n - entity_primary_key_property_id = " + details[9];
   log = log + "\n - entity_list_of_properties_id = " + details[10];
   log = log + "\n - entity_has_triggers = " + details[11];
   log = log + "\n - entity_trigger_on_before_fetch = " + details[12];
   log = log + "\n - entity_trigger_on_after_fetch = " + details[13];
   log = log + "\n - entity_trigger_on_before_insert = " + details[14];
   log = log + "\n - entity_trigger_on_after_insert = " + details[15];
   log = log + "\n - entity_trigger_on_before_update = " + details[16];
   log = log + "\n - entity_trigger_on_after_update = " + details[17];
   log = log + "\n - entity_trigger_on_before_delete = " + details[18];
   log = log + "\n - entity_trigger_on_after_delete = " + details[19];
   log = log + "\n - entity_parent_id = " + details[20];
   log = log + "\n - entity_soft_delete_column = " + details[21];
   log = log + "\n - entity_validator_method = " + details[22];

   print(log); // print value to the custom script debugger window
   helper.print(log); // print value to the standard output (for example, on Windows, use the 'DebugView' application to see all logs)
   return details;
}


Parcourir la liste des propriétés d'une entité

Voici comment parcourir la liste des propriétés de l'entité courante :

var entity_id = params[13];
var entity_details = helper.getEntityDetails(entity_id);
var entity_list_of_properties_id = ((entity_details.length > 0) ? entity_details[10] : "");
var entity_list_of_properties_array = entity_list_of_properties_id.split("|");
for (var idx = 0; idx < entity_list_of_properties_array.length; idx++)
{
   var property_id = entity_list_of_properties_array[idx];
   var property_details = helper.getPropertyDetails(property_id);
   // ...
}


Obtenir les informations associées à une propriété

Voici comment récupérer le paramétrage d'une propriété, helper.getPropertyDetails(property_id) :

function printPropertyDetails(property_id)
{
   var details = helper.getPropertyDetails(property_id);
   if (details.length == 0) { return details; }

   var log = "";
   log = log + "\n - property_id = " + details[0];
   log = log + "\n - property_key = " + details[1];
   log = log + "\n - property_name = " + details[2];
   log = log + "\n - property_column_name = " + details[3];
   log = log + "\n - property_description = " + details[4];
   log = log + "\n - property_type = " + details[5];
   log = log + "\n - property_version = " + details[6];
   log = log + "\n - property_entity_id = " + details[7];
   log = log + "\n - property_is_read_only = " + details[8];
   log = log + "\n - property_is_primary_key = " + details[9];
   log = log + "\n - property_is_serializable = " + details[10];
   log = log + "\n - property_is_transient = " + details[11];
   log = log + "\n - property_is_obsolete = " + details[12];
   log = log + "\n - property_is_index = " + details[13];
   log = log + "\n - property_is_unique = " + details[14];
   log = log + "\n - property_allow_null = " + details[15];
   log = log + "\n - property_order_level = " + details[16];
   log = log + "\n - property_default_value = " + details[17];
   log = log + "\n - property_format = " + details[18];
   log = log + "\n - property_force_sql_type = " + details[19];
   log = log + "\n - property_force_sql_alias = " + details[20];
   log = log + "\n - property_min_value = " + details[21];
   log = log + "\n - property_max_value = " + details[22];
   log = log + "\n - property_min_length = " + details[23];
   log = log + "\n - property_max_length = " + details[24];
   log = log + "\n - property_reg_exp = " + details[25];
   log = log + "\n - property_accessibility = " + details[26];
   log = log + "\n - property_is_relationship = " + details[27];
   log = log + "\n - property_relation_type = " + details[28];
   log = log + "\n - property_relation_entity_target_id = " + details[29];
   log = log + "\n - property_relation_inverse_property_id = " + details[30];
   log = log + "\n - property_relation_foreign_key = " + details[31];
   log = log + "\n - property_relation_foreign_key_owner = " + details[32];
   log = log + "\n - property_relation_extra_table = " + details[33];
   log = log + "\n - property_relation_type_desc = " + details[34];

   print(log); // print value to the custom script debugger window
   helper.print(log); // print value to the standard output (for example, on Windows, use the 'DebugView' application to see all logs)
   return details;
}


Obtenir les informations associées à une énumération

Voici comment récupérer le paramétrage de l'énumération courante, helper.getEnumerationDetails(enumeration_id) :

var enumeration_id = params[15];
printEnumerationDetails(enumeration_id);

//...

function printEnumerationDetails(enumeration_id)
{
   var details = helper.getEnumerationDetails(enumeration_id);
   if (details.length == 0) { return details; }

   var log = "";
   log = log + "\n - enumeration_id = " + details[0];
   log = log + "\n - enumeration_key = " + details[1];
   log = log + "\n - enumeration_name = " + details[2];
   log = log + "\n - enumeration_namespace = " + details[3];
   log = log + "\n - enumeration_description = " + details[4];
   log = log + "\n - enumeration_version = " + details[5];
   log = log + "\n - enumeration_use_qt_enum_macro = " + details[6];
   log = log + "\n - enumeration_list_of_keys = " + details[7];
   log = log + "\n - enumeration_list_of_values = " + details[8];

   print(log); // print value to the custom script debugger window
   helper.print(log); // print value to the standard output (for example, on Windows, use the 'DebugView' application to see all logs)
   return details;
}


Accès aux méta-données d'une entité/propriété/énumération

L'application QxEntityEditor permet de définir des méta-données liées à une entité, propriété ou énumération. Ces méta-données peuvent être utilisées par exemple pour définir du paramétrage supplémentaire non fourni par défaut par QxEntityEditor. Ces méta-données sont accessibles dans le code C++ généré (moteur d'introspection de la bibliothèque QxOrm), et sont accessibles également dans le moteur Javascript de QxEntityEditor. Voici comment récupérer des méta-données en Javascript :

var entity_id = params[13];
var entity_meta_data = helper.getEntityMetaData(entity_id, "MY_ENTITY_META_DATA_KEY");

// ...

var property_meta_data = helper.getPropertyMetaData(property_id, "MY_PROPERTY_META_DATA_KEY");

// ...

var enumeration_id = params[15];
var enumeration_meta_data = helper.getEnumerationMetaData(enumeration_id, "MY_ENUM_META_DATA_KEY");


Accéder aux variables d'environnement

Voici comment accéder aux variables d'environnement, helper.getEnvironmentVariable() et helper.setEnvironmentVariable() :

var env_var = helper.getEnvironmentVariable("QT_DIR");
var set_env_var_ok = helper.setEnvironmentVariable("MY_ENV_VAR", "my_value");


Gestion des fichiers : lecture et écriture

Le moteur de personnalisation des exports Javascript de QxEntityEditor permet de lire des fichiers, et permet d'écrire dans des fichiers. Les classes Javascript file et dir permettent d'instancier des objets Javascript pour effectuer des traitements sur les fichiers.

La classe file propose la même définition que la classe Qt QFile :

/*
   --- 'file' class methods available by script (QFile wrapper : http://doc.qt.io/qt-5/qfile.html) ---

   bool copy(string fileName, string newName);
   bool exists(string fileName);
   bool link(string fileName, string linkName);
   bool remove(string fileName);
   bool rename(string oldName, string newName);
   string readAll(string fileName);

   void setFileName(string name);
   string fileName();
   bool open(int mode); // enum QIODevice::OpenMode, for example : 26 = (QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text) = (2 + 8 + 16)
   int error(); // enum QFile::FileError
   void close();
   bool atEnd();
   string readLine();
   void write(string text);
*/


La classe dir propose la même définition que la classe Qt QDir :

/*
   --- 'dir' class methods available by script (QDir wrapper : http://doc.qt.io/qt-5/qdir.html) ---

   void setPath(string path);
   string path();
   string appPath();
   string homePath();
   string rootPath();
   string tempPath();

   string fromNativeSeparators(string pathName);
   string toNativeSeparators(string pathName);

   string cleanPath(string path);
   bool isAbsolutePath(string path);
   bool isRelativePath(string path);
   bool match(string filter, string fileName);

   bool mkdir(string dirName);
   bool mkpath(string dirPath);
   bool rmdir(string dirName);
   bool rmpath(string dirPath);
   bool exists(string name);

   bool cdUp();
   bool cd(string dirName);
   string absoluteFilePath(string fileName);
   string absolutePath();
   string canonicalPath();
   string dirName();
   string filePath(string fileName);
   void refresh();
   string relativeFilePath(string fileName);

   bool isAbsolute();
   bool isReadable();
   bool isRelative();
   bool isRoot();
*/


Exemple : lire le contenu d'un fichier :

var f1 = new file();
var f1_content = f1.readAll("C:\\Temp\\my_file.txt");


Autre exemple : écrire dans un fichier :

var f2 = new file();
f2.setFileName("C:\\Temp\\file_generated_by_script.txt");
f2.open(26); // (QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text) = (2 + 8 + 16)
f2.write("aaa");
f2.write("bbb");
f2.close();


Obtenir la liste des toutes les entités/énumérations d'un projet

Voici comment récupérer la liste de toutes les entités et énumérations d'un projet *.qxee :

var listOfAllEntities = helper.getListOfAllEntities(); // 'listOfAllEntities' variable is an array, each item of this array contains : <entity_id>|<entity_name>
var listOfAllEnums = helper.getListOfAllEnums(); // 'listOfAllEnums' variable is an array, each item of this array contains : <enum_id>|<enum_name>


Récupérer le paramétrage de l'application (niveau global, projet et plugin)

Voici comment récupérer tout le paramétrage défini au niveau de l'application (au format JSON) :
var globalSettings = helper.getQxEEGlobalSettingsJson();    // the result is a string in JSON format ==> so just use JSON.parse() function to get a javascript object instance
var projectSettings = helper.getQxEEProjectSettingsJson();  // the result is a string in JSON format ==> so just use JSON.parse() function to get a javascript object instance
var pluginSettings = helper.getQxEEPluginSetingsJson();     // the result is a string in JSON format ==> so just use JSON.parse() function to get a javascript object instance

print(globalSettings); helper.print(globalSettings);
print(projectSettings); helper.print(projectSettings);
print(pluginSettings); helper.print(pluginSettings);

globalSettings = JSON.parse(globalSettings);    // Now 'globalSettings' is a javascript object instance
projectSettings = JSON.parse(projectSettings);  // Now 'projectSettings' is a javascript object instance
pluginSettings = JSON.parse(pluginSettings);    // Now 'pluginSettings' is a javascript object instance


Ajout d'une action (placeholder) personnalisée dans le template d'export C++

Les plugins d'export C++ disposent d'un paramètre permettant de définir le code source des fichiers Header *.h et Source *.cpp. L'application QxEntityEditor propose plusieurs template par défaut, et il est possible d'écrire son propre template (option « Custom »). Cette définition des fichiers Header *.h et Source *.cpp utilisent des mots-clé (placeholder sous la forme @@ACTION@@) pour remplacer le code par la valeur correspondante. Cette notion de placeholder est la base du moteur de personnalisation Javascript. Il est possible de renseigner des placeholder personnalisés en prefixant par @@CUSTOM_, par exemple : @@CUSTOM_MY_ACTION@@.

Voici comment tester le code action courant (placeholder) dans le moteur Javascript :

/* you can define your own placeholder in the template, it must start with @@CUSTOM_, for example : @@CUSTOM_MY_ACTION@@ ==> then, in the custom script, check if you are processing your custom action with this code : */
var action = params[5];
if (action == "CUSTOM_MY_ACTION")
{
   return "quit with my custom code here";
}


Exemple de script : ajout automatique de la définition Q_PROPERTY sur les propriétés C++ générées

Voici un exemple de script documenté (fourni dans le dossier ./samples/q_property.js du package QxEntityEditor) pour montrer comment ajouter automatiquement la définition Q_PROPERTY pour chacune des propriétés du projet *.qxee :

({

/* ----------------------------------------------------------------------------------------
   ----------------------------------------------------------------------------------------
   'q_property.js' : custom javascript file to customize QxEntityEditor C++ export process.
   This script is an example to show how to use QxEntityEditor javascript engine to add a Q_PROPERTY definition for each property generated by QxEntityEditor.
   More details about Q_PROPERTY macro on Qt web site : http://doc.qt.io/qt-5/properties.html

   To use this javascript file :
      1- go to the main menu of QxEntityEditor 'Tools >> Export to C++ project (settings)' ;
      2- select the C++ template 'qx::IxPersistable + QObject' : now generated entities will inherit from QObject, which is required to use the Qt Q_PROPERTY macro ;
      3- in the field 'Custom script file' : put the location of this 'q_property.js' custom javascript file ;
      4- save the settings and start the C++ export process ;
      5- check generated files : Q_PROPERTY should be added automatically by the export process.
   ----------------------------------------------------------------------------------------
   ---------------------------------------------------------------------------------------- */

// Here is the entry point of the QxEntityEditor javascript engine
// This function is called for each placeholder defined in the C++ template section
customProcess : function(params)
{
   try
   {
      // We use here the @@MACRO_QX_PERSISTABLE_HPP@@ placeholder which is present in the default C++ template 'qx::IxPersistable + QObject'
      // You could also create your own custom C++ template (based on 'qx::IxPersistable + QObject' template), and create your own placeholder (which must be prefixed by @@CUSTOM_), for example : @@CUSTOM_Q_PROPERTY@@
      var action = params[5];
      if (action != "MACRO_QX_PERSISTABLE_HPP") { return params[0]; } // quit with 'params[0]' means : doesn't change the default export behaviour

      // Check if we have an entity
      var entity_id = params[13];
      if ((entity_id == "") || (entity_id == "0")) { return params[0]; } // quit with 'params[0]' means : doesn't change the default export behaviour

      // Get the list of properties
      var entity_details = helper.getEntityDetails(entity_id);
      var entity_list_of_properties_id = ((entity_details.length > 0) ? entity_details[10] : "");
      var entity_list_of_properties_array = entity_list_of_properties_id.split("|");
      if (entity_list_of_properties_array.length <= 0) { return params[0]; } // quit with 'params[0]' means : doesn't change the default export behaviour

      // Prepare output string
      var output = params[0] + "\n";

      // Iterate over each property
      for (var idx = 0; idx < entity_list_of_properties_array.length; idx++)
      {
         // Get property details
         var property_id = entity_list_of_properties_array[idx];
         var property_details = helper.getPropertyDetails(property_id);

         // Here you could also get property meta-data that you can define in QxEntityEditor, property parameters screen, section 'List of meta-data'
         // This is a way to manage your own property parameters which are not a part of QxEntityEditor
         // It could be useful for example to manage some Q_PROPERTY settings like : RESET, NOTIFY, REVISION, DESIGNABLE, SCRIPTABLE, FINAL, etc...
         // To get a property meta-data value, just write this code : var my_meta_data = helper.getPropertyMetaData(property_id, "MY_META_DATA_KEY");

         // Get property type and name
         var property_type = property_details[5];
         var property_name = property_details[2];

         // Check if property type can be used with Q_PROPERTY macro
         if (list_of_compatible_property_type.indexOf(property_type) == -1) { continue; }

         // Create Q_PROPERTY definition
         output += "\n   Q_PROPERTY(" + property_type + " " + property_name + " READ get" + property_name + " WRITE set" + property_name + ")";
      }

      return output;
   }
   catch (err)
   { return ("[CustomScriptError] an unexpected error occurred : " + err); }
}

});

// Here is a list of C++ types compatible with Qt Q_PROPERTY macro (C++ type can be converted to/from QVariant)
// You can of course register your own C++ types to be able to use them with Q_PROPERTY macro (using Qt Q_DECLARE_METATYPE() macro)
// So the following array is not fixed : you can add all C++ types you want...
var list_of_compatible_property_type = [ "QBitArray", "QBitmap", "bool", "QBrush", "QByteArray", "QChar", "QColor", "QDate", "QDateTime", "double", 
                                         "QUuid", "QFont", "QVariantHash", "QIcon", "QImage", "int", "QLine", "QLineF", "QVariantList", "qlonglong", 
                                         "QVariantMap", "QMatrix", "QMatrix4x4", "QPixmap", "QPoint", "QPointF", "QPolygon", "QPolygonF", "QRect", "QRectF", 
                                         "QRegExp", "QRegion", "QSize", "QSizeF", "QString", "QStringList", "QTime", "uint", "qulonglong", "QUrl", 
                                         "QVector2D", "QVector3D", "QVector4D" ];


Activation du débogueur Javascript intégré

Le moteur Javascript de personnalisation des exports de QxEntityEditor intègre un débogueur. Cet environnement de débogage dispose de toutes les fonctionnalités nécessaires pour vous aider à développer et corriger vos scripts :
  • définition de points d'arrêt (breakpoints) ;
  • mode pas à pas pour passer d'une ligne de code à une autre pendant l'exécution du script ;
  • visualisation des variables et de leur valeur au fil de l'exécution ;
  • affichage d'une fenêtre de logs.

Par défaut, le débogueur est désactivé lors d'un export. Pour l'activer et afficher l'écran suivant, vous devez :
  • aller dans les paramètres d'export, définir un script à utiliser, puis cliquer sur le bouton « Debug custom Javascript file » ;
  • ou bien maintenir la touche SHIFT au lancement d'un export.

JS debug

Exécution de scripts personnalisés avant/après exécution d'un plugin

L'application QxEntityEditor permet de définir des scripts de type *.bat (Windows), *.sh (Linux) ou même des exécutables à lancer avant ou après exécution d'un plugin QxEntityEditor. Chaque script (ou processus) est appelé avec un paramètre d'entrée : le chemin d'accès au fichier projet *.qxee. Cette fonctionnalité peut être utilisée par exemple pour :
  • intégrer les fichiers générés par un export QxEntityEditor dans un gestionnaire de code source (Git, Perforce, CVS, etc...) ;
  • démarrer la compilation d'un projet C++ généré par QxEntityEditor ;
  • exécuter des tests unitaires ou bien lancer une intégration continue avec un serveur Jenkins par exemple ;
  • modifier des valeurs dans la base de données SQLite d'un projet *.qxee suite à un import de base de données.

Pour définir les scripts ou exécutables à lancer suite à un processus d'import ou d'export de QxEntityEditor, aller dans le menu principal : Tools >> Plugins scripts.

Plugin scripts

Remarque : pour définir un script à exécuter dans cette liste, il est possible de renseigner le chemin d'accès absolu au script, ou bien un chemin relatif par rapport au projet *.qxee. Par exemple, en mettant le chemin relatif ./my_script.sh, le fichier my_script.sh doit se trouver dans le même répertoire que le fichier projet *.qxee de QxEntityEditor.

Exécuter QxEntityEditor en ligne de commande

L'application QxEntityEditor peut être démarrée en ligne de commande. Nous allons détaillé dans ce chapitre quelques exemples d'appels :


-- Exemple n°1 : démarrer QxEntityEditor en spécifiant un projet *.qxee à charger (paramètre --project) :
QxEntityEditor --project="c:\test\qxBlog.qxee"


-- Exemple n°2 : démarrer QxEntityEditor sans afficher l'interface graphique (paramètre --no_gui), en spécifiant un projet *.qxee à charger (paramètre --project) et en démarrant automatiquement un processus d'export C++ (paramètre --plugin) :
QxEntityEditor --no_gui --project="c:\test\qxBlog.qxee" --plugin=QxEECppExport


-- Exemple n°3 : démarrer QxEntityEditor en mode visionneuse (paramètre --viewer_mode), ce mode permet d'ouvrir QxEntityEditor en mode lecture seule et permet de charger des projets *.qxee sans clé de licence :
QxEntityEditor --viewer_mode


-- Exemple n°4 : démarrer QxEntityEditor avec affichage des logs SQL (paramètre --log_sql), ce paramètre permet de tracer toutes les requêtes SQL effectuées sur la base de données SQLite du projet *.qxee :
QxEntityEditor --log_sql


-- Exemple n°5 : démarrer QxEntityEditor en chargeant un projet *.qxee à partir d'un fichier JSON :
QxEntityEditor --project="<path_to_your_qxee_project_file>" --plugin=QxEEJsonImport --QxEEJsonImport_file="<path_to_your_json_file>"




QxOrm © 2017 Lionel Marty - contact@qxorm.com