Accueil | Téléchargement | Exemple rapide |
Tutoriel (4)
|
Manuel (2)
|
Forum | Nos clients |
QxOrm >> Manuel d'utilisation de l'application QxEntityEditor |
|
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 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 :
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 :
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 :
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++ :
Vues de l'écran principal de QxEntityEditor
Voici une copie écran présentant les différentes zones d'affichage de l'application QxEntityEditor :
Zoomer/dézoomer le diagramme d'entités
Il est possible de zoomer/dézoomer le diagramme d'entités :
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++ :
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 :
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 :
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
La création d'un nouveau projet QxEntityEditor se fait par le menu principal File >> New project :
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 : 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 : 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 :
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 : 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) :
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é.
La création d'une nouvelle entité se fait par :
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.
La modification d'une entité se fait par :
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.
La suppression d'une (ou plusieurs) entité se fait par :
Le clonage d'une entité se fait par :
Remarque : une entité clonée dispose de toutes les propriétés de l'entité source. Les relations ne sont pas clonées.
Les paramètres de l'entité sélectionnée sont accessibles dans l'onglet de paramétrage Entity :
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éé.
-- Section Entity triggers :
-- 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.
-- 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.
-- 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.
Les couleurs d'une entité peuvent être modifiées par le menu contextuel sur un clic-droit sur une entité Define 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é : 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 :
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.
-- Section Property type :
-- 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.
-- Section Advanced :
-- 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.
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 : 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 :
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.
-- Section Advanced :
-- 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.
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é.
Les paramètres de l'énumération sélectionnée sont accessibles dans l'onglet de paramétrage Enumeration :
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éé.
-- Section List of values : liste des valeurs de l'énumération.
-- 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.
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 :
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 :
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 :
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 :
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. 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).
Les couleurs d'une note peuvent être modifiées par le menu contextuel sur un clic-droit sur une note Define comment 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.
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...). 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. 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 :
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.
Remarque : cette fonction peut être utile suite à un processus d'import pour harmoniser le code C++ généré.
Tous les processus d'import de l'application QxEntityEditor sont accessibles depuis le menu principal Import :
Un projet QxEntityEditor (fichier *.qxee) peut être géré par une équipe de développeurs : le code source d'un projet QxEntityEditor peut être exporté/importé (manuellement ou en ligne de commande) avec les plugins QxEESourceControlExport et QxEESourceControlImport.
Associé à un gestionnaire de code source (Git, Perforce, CVS, etc.), ces 2 plugins permettent ainsi :
Le paramètre à renseigner correspond au fichier JSON présent à la racine du répertoire où a été exporté le projet *.qxee. Ce fichier est nommé <nom_du_projet>.qxee.export.json, par exemple pour le projet de test qxBlog : qxBlog.qxee.export.json. Attention : un import 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 répertoire associé à un gestionnaire de code source au démarrage de l'application. Exemple de ligne de commande : QxEntityEditor --project="<path_to_your_qxee_project_file>" --plugin=QxEESourceControlImport --QxEESourceControlImport_path="<path_to_the_root_source_control_json_file>" Importer un projet à partir d'un fichier texte au format JSON
Remarque : pour travailler avec un gestionnaire de code source (Git, Perforce, CVS, etc.), il est conseillé d'utiliser les plugins QxEESourceControlExport et QxEESourceControlImport (au lieu de créer un fichier unique).
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. 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 :
Cet écran d'import est divisé en plusieurs sections : -- Section MySQL (or MariaDB) database connection :
-- Section Import settings :
-- Section Relationship import settings :
-- 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 :
-- 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 :
Cet écran d'import est divisé en plusieurs sections : -- Section PostgreSQL database connection :
-- Section Import settings :
-- Section Relationship import settings :
-- 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 :
-- 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 :
Cet écran d'import est divisé en plusieurs sections : -- Section Database connection :
-- Section Import settings :
-- Section Relationship import settings :
-- 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 :
-- 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...
Cet écran d'import est divisé en plusieurs sections : -- Section Database connection :
-- Section Import settings :
-- Section Relationship import settings :
-- 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 :
-- 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.
Tous les processus d'export de l'application QxEntityEditor sont accessibles depuis le menu principal Export :
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é.
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) :
Cet écran d'export est divisé en plusieurs sections : -- Section C++ export settings :
-- Section Custom script (Javascript file) to change the default behaviour of the export process : paramétrage du moteur de personnalisation de l'export.
-- 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@@.
Présentation du projet C++ généré
Le projet C++ généré dispose de l'arborescence suivante :
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...).
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 :
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.
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) :
Cet écran d'export est divisé en plusieurs sections : -- Section C++ model/view export settings :
-- Section Custom script (Javascript file) to change the default behaviour of the export process : paramétrage du moteur de personnalisation de l'export.
-- 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@@.
Le projet C++ model/view généré dispose de l'arborescence suivante :
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.
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) :
Cet écran d'export est divisé en plusieurs sections : -- Section C++ services export settings :
-- Section Custom script (Javascript file) to change the default behaviour of the export process : paramétrage du moteur de personnalisation de l'export.
-- 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@@.
Le projet C++ de type services (client et serveur) généré dispose de l'arborescence suivante :
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 :
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 : Cet écran est divisé en plusieurs sections : -- Section Plugins services :
-- Section Database connection parameters :
-- Section Server parameters :
-- Section Log last client-server reply-request transaction :
-- Section Log last server error :
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) :
Cet écran d'export est divisé en plusieurs sections : -- Section DDL export settings :
-- Section Mapping C++ type to database SQL type :
-- Section Custom script (Javascript file) to change the default behaviour of the export process : paramétrage du moteur de personnalisation de l'export.
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) :
Un projet QxEntityEditor (fichier *.qxee) peut être géré par une équipe de développeurs : le code source d'un projet QxEntityEditor peut être exporté/importé (manuellement ou en ligne de commande) avec les plugins QxEESourceControlExport et QxEESourceControlImport.
Associé à un gestionnaire de code source (Git, Perforce, CVS, etc.), ces 2 plugins permettent ainsi :
Le paramètre à renseigner correspond au répertoire dans lequel seront générés les fichiers JSON. Chaque élément du projet *.qxee (entités, propriétés, relations, commentaires, etc.) est exporté dans un fichier JSON spécifique. Le répertoire où sont exportés les fichiers JSON a la structure suivante : Remarque : il est possible d'exporter un projet en ligne de commande sans démarrer l'interface utilisateur de l'application QxEntityEditor. Exemple de ligne de commande : QxEntityEditor --no_gui --project="<path_to_your_qxee_project_file>" --plugin=QxEESourceControlExport --QxEESourceControlExport_path="<path_to_your_export_output_directory>" Exporter le projet sous format XML ou JSON
Remarque : pour travailler avec un gestionnaire de code source (Git, Perforce, CVS, etc.), il est conseillé d'utiliser les plugins QxEESourceControlExport et QxEESourceControlImport (au lieu de créer un fichier unique).
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) : 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 :
Par défaut, le débogueur est désactivé lors d'un export. Pour l'activer et afficher l'écran suivant, vous devez :
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 :
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. 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étailler 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>" -- Exemple n°6 : afficher la documentation de tous les paramètres en ligne de commande : QxEntityEditor --? Ce qui produit le résultat suivant : *** QxEntityEditor 1.2.5 application global command line parameters *** --project="<full path to *.qxee project file>" : run QxEntityEditor defining a *.qxee project to load at startup --no_gui : run QxEntityEditor without displaying the user interface --viewer_mode : run QxEntityEditor in read-only mode, this parameter can be used to open large *.qxee projects without any registered license key --log_sql : run QxEntityEditor tracing all SQL logs, this parameter logs all SQL queries executed to *.qxee SQLite database --font : define application font (due to issues since macOS Catalina 10.15) with syntax <family>||<pointSize>||<weight>||<italic> (only <family> is required), for example : Courier New||14 --style_sheet : define application style sheet (more details here : https://doc.qt.io/qt-5/stylesheet-reference.html), for example : QWidget { background-color: black } --plugin=<plugin name> : run QxEntityEditor and execute automatically a plugin process (see below for specific parameters per plugin) *** Import plugin QxEEJsonImport *** --QxEEJsonImport_file="<full path to your json file>" : [Required] run QxEntityEditor loading a *.qxee project from a JSON file *** Import plugin QxEEMySQLImport *** --QxEEMySQLImport_db_ip="<DB IP>" : [Required] Database server address (IP) --QxEEMySQLImport_db_port="<DB port>" : [Required] Port number to connect to database --QxEEMySQLImport_db_name="<DB name>" : [Required] Database name --QxEEMySQLImport_filter_regexp="<Regular Expression>" : [Optional] Filter to select tables from database to import --QxEEMySQLImport_login="<DB Login>" : [Optional] Login to connect to database --QxEEMySQLImport_pwd="<DB Password>" : [Optional] Password to connect to database --QxEEMySQLImport_namespace="<Namespace>" : [Optional] C++ namespace where imported classes will be located --QxEEMySQLImport_delete_namespace=0/1 : [Optional] Delete all entities in the namespace before importing --QxEEMySQLImport_import_comment=0/1 : [Optional] Import tables/columns comment to entities/properties description --QxEEMySQLImport_import_default_value=0/1 : [Optional] Import columns default value --QxEEMySQLImport_boost_optional=0/1 : [Optional] Add boost::optional<T> decoration if a column definition allows NULL value --QxEEMySQLImport_organize_diagram=0/1 : [Optional] Organize diagram layout after import process --QxEEMySQLImport_relation_decoration=<numeric value> : [Optional] Decoration used for relationships (0=no decoration, 1=boost::shared_ptr, 2=QSharedPointer, 5=std::shared_ptr) --QxEEMySQLImport_relation_collection=<numeric value> : [Optional] Collection used for relationships (1=qx::QxCollection, 2=std::vector, 3=std::list, 8=QHash, 10=QList) --QxEEMySQLImport_mapping_sql_to_cpp="sql1~cpp1;sql2~cpp2;etc..." : [Optional] List of mappings from SQL type to C++ type --QxEEMySQLImport_verbose=0/1 : [Optional] Display more details during the import process *** Import plugin QxEEOdbcImport *** --QxEEOdbcImport_dsn="<ODBC DSN>" : [Required] ODBC DSN to connect to database --QxEEOdbcImport_db_type=<numeric value> : [Required] Database engine type (0=generic, 1=postgresql, 2=mysql, 3=oracle, 4=mssqlserver, 5=sqlite) --QxEEOdbcImport_filter_regexp="<Regular Expression>" : [Optional] Filter to select tables from database to import --QxEEOdbcImport_login="<DB Login>" : [Optional] Login to connect to database --QxEEOdbcImport_pwd="<DB Password>" : [Optional] Password to connect to database --QxEEOdbcImport_namespace="<Namespace>" : [Optional] C++ namespace where imported classes will be located --QxEEOdbcImport_delete_namespace=0/1 : [Optional] Delete all entities in the namespace before importing --QxEEOdbcImport_import_comment=0/1 : [Optional] Import tables/columns comment to entities/properties description --QxEEOdbcImport_import_default_value=0/1 : [Optional] Import columns default value --QxEEOdbcImport_boost_optional=0/1 : [Optional] Add boost::optional<T> decoration if a column definition allows NULL value --QxEEOdbcImport_organize_diagram=0/1 : [Optional] Organize diagram layout after import process --QxEEOdbcImport_relation_decoration=<numeric value> : [Optional] Decoration used for relationships (0=no decoration, 1=boost::shared_ptr, 2=QSharedPointer, 5=std::shared_ptr) --QxEEOdbcImport_relation_collection=<numeric value> : [Optional] Collection used for relationships (1=qx::QxCollection, 2=std::vector, 3=std::list, 8=QHash, 10=QList) --QxEEOdbcImport_mapping_sql_to_cpp="sql1~cpp1;sql2~cpp2;etc..." : [Optional] List of mappings from SQL type to C++ type --QxEEOdbcImport_verbose=0/1 : [Optional] Display more details during the import process *** Import plugin QxEEPostgreSQLImport *** --QxEEPostgreSQLImport_db_ip="<DB IP>" : [Required] Database server address (IP) --QxEEPostgreSQLImport_db_port="<DB port>" : [Required] Port number to connect to database --QxEEPostgreSQLImport_db_name="<DB name>" : [Required] Database name --QxEEPostgreSQLImport_filter_regexp="<Regular Expression>" : [Optional] Filter to select tables from database to import --QxEEPostgreSQLImport_login="<DB Login>" : [Optional] Login to connect to database --QxEEPostgreSQLImport_pwd="<DB Password>" : [Optional] Password to connect to database --QxEEPostgreSQLImport_namespace="<Namespace>" : [Optional] C++ namespace where imported classes will be located --QxEEPostgreSQLImport_delete_namespace=0/1 : [Optional] Delete all entities in the namespace before importing --QxEEPostgreSQLImport_import_comment=0/1 : [Optional] Import tables/columns comment to entities/properties description --QxEEPostgreSQLImport_import_default_value=0/1 : [Optional] Import columns default value --QxEEPostgreSQLImport_boost_optional=0/1 : [Optional] Add boost::optional<T> decoration if a column definition allows NULL value --QxEEPostgreSQLImport_organize_diagram=0/1 : [Optional] Organize diagram layout after import process --QxEEPostgreSQLImport_relation_decoration=<numeric value> : [Optional] Decoration used for relationships (0=no decoration, 1=boost::shared_ptr, 2=QSharedPointer, 5=std::shared_ptr) --QxEEPostgreSQLImport_relation_collection=<numeric value> : [Optional] Collection used for relationships (1=qx::QxCollection, 2=std::vector, 3=std::list, 8=QHash, 10=QList) --QxEEPostgreSQLImport_mapping_sql_to_cpp="sql1~cpp1;sql2~cpp2;etc..." : [Optional] List of mappings from SQL type to C++ type --QxEEPostgreSQLImport_verbose=0/1 : [Optional] Display more details during the import process *** Import plugin QxEESQLiteImport *** --QxEESQLiteImport_db_path="<DB File Path>" : [Required] SQLite database file path --QxEESQLiteImport_filter_regexp="<Regular Expression>" : [Optional] Filter to select tables from database to import --QxEESQLiteImport_namespace="<Namespace>" : [Optional] C++ namespace where imported classes will be located --QxEESQLiteImport_delete_namespace=0/1 : [Optional] Delete all entities in the namespace before importing --QxEESQLiteImport_import_comment=0/1 : [Optional] Import tables/columns comment to entities/properties description --QxEESQLiteImport_import_default_value=0/1 : [Optional] Import columns default value --QxEESQLiteImport_boost_optional=0/1 : [Optional] Add boost::optional<T> decoration if a column definition allows NULL value --QxEESQLiteImport_organize_diagram=0/1 : [Optional] Organize diagram layout after import process --QxEESQLiteImport_relation_decoration=<numeric value> : [Optional] Decoration used for relationships (0=no decoration, 1=boost::shared_ptr, 2=QSharedPointer, 5=std::shared_ptr) --QxEESQLiteImport_relation_collection=<numeric value> : [Optional] Collection used for relationships (1=qx::QxCollection, 2=std::vector, 3=std::list, 8=QHash, 10=QList) --QxEESQLiteImport_mapping_sql_to_cpp="sql1~cpp1;sql2~cpp2;etc..." : [Optional] List of mappings from SQL type to C++ type --QxEESQLiteImport_verbose=0/1 : [Optional] Display more details during the import process *** Export plugin QxEECppExport *** !!! Note : this plugin loads automatically previous parameters values before starting the export process, but you can use following parameters to override them !!! --QxEECppExport_path="<Export Path>" : [Optional] C++ export path parameter --QxEECppExport_template_type=<numeric value> : [Optional] C++ template type selected to build C++ files (0=no_inheritance, 1=ix_persistable, 2=qx_persistable, 3=ix_persistable_and_q_object, 4=custom) --QxEECppExport_template_header="<Template Header>" : [Optional] Custom C++ template header file path (QxEECppExport_template_type parameter must be equal to 4, which means custom) --QxEECppExport_template_source="<Template Source>" : [Optional] Custom C++ template source file path (QxEECppExport_template_type parameter must be equal to 4, which means custom) --QxEECppExport_qxorm_relative_path=0/1 : [Optional] Relative path to QxOrm library --QxEECppExport_generate_custom_files=0/1 : [Optional] Generate a custom directory with custom files for each entity --QxEECppExport_custom_javacript="<Custom JS>" : [Optional] Custom script (javascript file) to change the default behaviour of the export process *** Export plugin QxEECppModelViewExport *** !!! Note : this plugin loads automatically previous parameters values before starting the export process, but you can use following parameters to override them !!! --QxEECppModelViewExport_path="<Export Path>" : [Optional] C++ model/view export path parameter --QxEECppModelViewExport_namespace="<Namespace>" : [Optional] Namespace where to put all model/view classes --QxEECppModelViewExport_template_type=<numeric value> : [Optional] C++ model/view template type selected to build C++ files (0=default, 1=custom, 2=qx_model_service) --QxEECppModelViewExport_template_header="<Template Header>" : [Optional] Custom C++ template header file path (QxEECppModelViewExport_template_type parameter must be equal to 1, which means custom) --QxEECppModelViewExport_template_source="<Template Source>" : [Optional] Custom C++ template source file path (QxEECppModelViewExport_template_type parameter must be equal to 1, which means custom) --QxEECppModelViewExport_generate_custom_files=0/1 : [Optional] Generate a custom directory with custom files for each entity --QxEECppModelViewExport_custom_javacript="<Custom JS>" : [Optional] Custom script (javascript file) to change the default behaviour of the export process *** Export plugin QxEECppServicesExport *** !!! Note : this plugin loads automatically previous parameters values before starting the export process, but you can use following parameters to override them !!! --QxEECppServicesExport_path="<Export Path>" : [Optional] C++ services export path parameter --QxEECppServicesExport_namespace="<Namespace>" : [Optional] Namespace where to put all services classes --QxEECppServicesExport_template_type=<numeric value> : [Optional] C++ services template type selected to build C++ files (0=default, 1=custom) --QxEECppServicesExport_template_header="<Template Header>" : [Optional] Custom C++ template header file path (QxEECppServicesExport_template_type parameter must be equal to 1, which means custom) --QxEECppServicesExport_template_source="<Template Source>" : [Optional] Custom C++ template source file path (QxEECppServicesExport_template_type parameter must be equal to 1, which means custom) --QxEECppServicesExport_generate_custom_files=0/1 : [Optional] Generate a custom directory with custom files for each entity --QxEECppServicesExport_custom_javacript="<Custom JS>" : [Optional] Custom script (javascript file) to change the default behaviour of the export process --QxEECppServicesExport_generate_server_app=0/1 : [Optional] Generate a sample server application --QxEECppServicesExport_server_app_path="<Server App Path>" : [Optional] Server application location *** Export plugin QxEEGenericDDLExport *** !!! Note : this plugin loads automatically previous parameters values before starting the export process, but you can use following parameters to override them !!! --QxEEGenericDDLExport_path="<Export Path>" : [Optional] DDL export path parameter --QxEEGenericDDLExport_db_type=<numeric value> : [Optional] Database type (0=default, 1=sqlite, 2=mysql, 3=postgresql, 4=oracle, 5=mssqlserver) --QxEEGenericDDLExport_relation_as_fk=0/1 : [Optional] Export relationships as foreign keys in database --QxEEGenericDDLExport_schema_type=<numeric value> : [Optional] Way to export database schema (0=full, 1=evolution, 2=full_and_evolution) --QxEEGenericDDLExport_custom_javacript="<Custom JS>" : [Optional] Custom script (javascript file) to change the default behaviour of the export process *** Export plugin QxEEPrinter *** !!! Note : this plugin loads automatically previous parameters values before starting the export process !!! *** Export plugin QxEEXmlExport *** !!! Note : this plugin loads automatically previous parameters values before starting the export process, but you can use following parameters to override them !!! --QxEEXmlExport_path="<Export Path>" : [Optional] XML or JSON export path parameter --QxEEXmlExport_as_json=0/1 : [Optional] Export project as JSON format Remarque : pour faire apparaitre les logs générés par l'application QxEntityEditor :
-- Exemple n°7 : importer en ligne de commande un schéma de base de données par ODBC (plugin QxEEOdbcImport) : QxEntityEditor --no_gui --project="<project_path>" --plugin=QxEEOdbcImport --QxEEOdbcImport_db_type=1 --QxEEOdbcImport_dsn="<your_dsn>" --QxEEOdbcImport_login="<your_login>" --QxEEOdbcImport_pwd="<your_password>" --QxEEOdbcImport_delete_namespace=1 -- Exemple n°8 : importer en ligne de commande un schéma de base de données PostgreSQL (plugin QxEEPostgreSQLImport) : QxEntityEditor --no_gui --project="<project_path>" --plugin=QxEEPostgreSQLImport --QxEEPostgreSQLImport_db_ip="<ip>" --QxEEPostgreSQLImport_db_port=5432 --QxEEPostgreSQLImport_db_name="<dbname>" --QxEEPostgreSQLImport_login="<your_login>" --QxEEPostgreSQLImport_pwd="<your_password>" --QxEEPostgreSQLImport_delete_namespace=1 -- Exemple n°9 : exporter en ligne de commande un projet QxEntityEditor associé à un gestionnaire de code source Git, Perforce, CVS, etc. (plugin QxEESourceControlExport) : QxEntityEditor --no_gui --project="<path_to_your_qxee_project_file>" --plugin=QxEESourceControlExport --QxEESourceControlExport_path="<path_to_your_export_output_directory>" -- Exemple n°10 : importer en ligne de commande un projet QxEntityEditor associé à un gestionnaire de code source Git, Perforce, CVS, etc. (plugin QxEESourceControlImport) : QxEntityEditor --project="<path_to_your_qxee_project_file>" --plugin=QxEESourceControlImport --QxEESourceControlImport_path="<path_to_the_root_source_control_json_file>" |
© 2011-2024 Lionel Marty - contact@qxorm.com |