C - Théorie APIs de table pour SQL Server
Transcription
C - Théorie APIs de table pour SQL Server
2013 C - Théorie APIs de table pour SQL Server Établissement: HEG Arc — Haute école Arc — Gestion Dernière modification le: 01.07.2013 Réalisé par: M. Arnaud Senft Informaticien de gestion 2009-2013 Date de création: 26.04.2013 S’adresse à: M.Fabrice Camus Version du document: 1.0 Date de début et de fin du travail de Bachelor 08.04.2013 – 05.07.2013 Type de réalisation: Intra-muros APIs de table pour SQL Server Rapport Théorique Arnaud Senft Sommaire 1 Introduction .................................................................................................................... 6 2 Gestion de projet ............................................................................................................ 7 3 Prérequis ........................................................................................................................ 8 4 3.1 Méthode .................................................................................................................. 8 3.2 Modèle .................................................................................................................... 8 3.3 Méthodologies de développement ..........................................................................10 Les APIs de table ..........................................................................................................11 4.1 Concept des APIs de table .....................................................................................11 4.2 Principe de fonctionnement général .......................................................................12 4.3 Principe de fonctionnement technique ....................................................................13 4.4 Fonctionnalités couvertes .......................................................................................14 4.5 Autogénération de valeurs de clé primaire. ............................................................15 4.5.1 Définition .........................................................................................................15 4.5.2 Réalisation ......................................................................................................15 4.6 Colonnes d’informations d’audit de manipulation. ...................................................16 4.6.1 Définition .........................................................................................................16 4.6.2 Réalisation ......................................................................................................16 4.7 Journal de trace de toutes les manipulations ..........................................................18 4.7.1 Définition .........................................................................................................18 4.7.2 Réalisation ......................................................................................................18 4.8 Personnalisation des APIs de table ........................................................................20 4.8.1 Définition .........................................................................................................20 4.8.2 Réalisation ......................................................................................................20 4.8.3 Légende ..........................................................................................................21 4.9 Maintien d’un journal de trace de toutes les exceptions. .........................................23 4.9.1 Définition .........................................................................................................23 Page 2 sur 76 APIs de table pour SQL Server 4.9.2 4.10 5 6 Rapport Théorique Arnaud Senft Principe ...........................................................................................................23 Analyse du contenu des triggers ............................................................................26 Spécificités du SGBDR SQL Server de Microsoft ..........................................................30 5.1 Contexte.................................................................................................................30 5.2 Base de données utilisée par le SGBDR SQL Server.............................................31 5.3 Instance .................................................................................................................32 5.4 Différence entre utilisateur et schéma ....................................................................33 5.4.1 Introduction .....................................................................................................33 5.4.2 Overview .........................................................................................................33 5.4.3 What Is User Schema Separation? .................................................................34 Transact SQL ................................................................................................................35 6.1 GO .........................................................................................................................36 6.2 Fonction System ....................................................................................................36 6.3 Curseurs ................................................................................................................38 6.3.1 6.4 @@FETCH_STATUS .....................................................................................39 Triggers ..................................................................................................................40 6.4.1 Déclencheurs AFTER......................................................................................40 6.4.2 Déclencheurs INSTEAD OF ............................................................................40 6.5 Table inserted et deleted ........................................................................................41 7 Utilisation du plugin .......................................................................................................44 8 Architecture du plugin de génération des APIs de table pour SQL Server .....................45 8.1 Introduction ............................................................................................................45 8.2 Principe de séparation des couches .......................................................................46 8.3 Couplage entre les couches ...................................................................................47 8.4 Séparation effective des couches ...........................................................................48 8.5 Patterns utilisés ......................................................................................................49 8.5.1 DAO ................................................................................................................49 Page 3 sur 76 APIs de table pour SQL Server 9 Rapport Théorique Arnaud Senft 8.5.2 Factory Method ...............................................................................................50 8.5.3 Singleton .........................................................................................................50 8.6 Diagramme de classe.............................................................................................51 8.7 Organisation des packages ....................................................................................54 8.7.1 Package generationAPIsTableSQLServer.......................................................55 8.7.2 Package model ...............................................................................................55 8.7.3 Package exceptions ........................................................................................56 8.7.4 Package persistence.DAO ..............................................................................56 8.7.5 Package persistence.database .......................................................................56 8.7.6 Package presentation......................................................................................57 8.7.7 Package presentation.action ...........................................................................57 8.7.8 Package scripts ...............................................................................................57 8.7.9 Package service ..............................................................................................58 8.7.10 Package utils ...................................................................................................58 8.8 Package presentation et model ..............................................................................59 8.9 Package presentation et service.............................................................................60 8.10 Package service et scripts ......................................................................................61 Gestion des erreurs .......................................................................................................63 9.1 Exceptions .............................................................................................................64 9.2 Messages pour l’utilisateur .....................................................................................66 9.3 Logs .......................................................................................................................67 9.4 Transactions ..........................................................................................................68 10 Visual Paradigm ............................................................................................................69 10.1 Structuration du référentiel .....................................................................................69 10.2 Ajout de librairies....................................................................................................70 10.3 Présentation d’Open API ........................................................................................70 10.4 Librairie et structure du projet Java ........................................................................71 Page 4 sur 76 APIs de table pour SQL Server 10.5 Rapport Théorique Arnaud Senft Implémenter le point de départ ...............................................................................72 10.5.1 Classe PluginLoader .......................................................................................72 10.5.2 Fichier plugin.xml ............................................................................................72 10.6 Utilisation des objets ..............................................................................................74 10.7 Objets du référentiel ...............................................................................................75 Page 5 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft 1 Introduction Ce document vous présente les différents éléments assimilés lors de la réalisation de ce travail. Il vous informe également des études menées et les principes utilisés lors du déroulement du projet. Évidemment je ne réexplique pas tout ce qui a été utilisé, mais uniquement ce qui est nouveau ou ce qui m’a paru judicieux de présenter afin de comprendre correctement la suite du travail. Ce document respecte la séparation théorique/pratique imposée par la Haute école de Gestion ARC. C’est-à-dire que ce présent document expose des notions pouvant être reprises et adaptées à un projet similaire. Le premier chapitre présente des explications concernant la gestion de projet appliquée à un travail d’étudiant. Le but étant de présenter la situation effective. Par la suite, quelques brefs rappels concernant les notions de méthode et modèles puis de méthodologies de développements sont présentés afin de rafraîchir les connaissances nécessaires à la bonne compréhension de ce travail. Le chapitre suivant entre dans le vif du sujet en présentant les principes des APIs de table. Ce chapitre fixe les différents objectifs de chaque fonctionnalité des APIs de table afin de vérifier la bonne couverture métier en fin de projet. Pas la suite, les chapitres 5 et 6 exposent les éléments techniques qui permettront de générer le code des APIs de table remplissant les fonctionnalités présentées dans le chapitre précédent. Le chapitre 7 présente, grâce à un schéma UML, les interactions présentes entre les différents éléments. La partie suivante présente l’architecture ayant été mise en place afin de développer ledit plugin. Le chapitre 9 détaille quelques concepts sur la gestion des erreurs. Je conclus avec une présentation des principes de fonctionnement de l’API permettant d’étendre les fonctionnalités de Visual Paradigm. Page 6 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft 2 Gestion de projet Dans le cadre de ce travail de Bachelor, aucune directive n’a été donnée concernant la gestion de projet. Pour ma part, il est important de décrire, dans ce rapport, quelques éléments clés de la gestion de projet sans toutefois en appliquer rigoureusement une. Je vais donc présenter, ici, quelques principes que j’ai utilisés. D’après différents documents que j’ai pu lire (notamment [WEB-MIC-07]) et ce que l’on m’a enseigné, tout projet se compose de 3 éléments: F IGURE 1 : TRIANGLE DE GESTION DE PROJET Un projet dépend donc de l’argent y ayant été injecté, des objectifs fixés et du temps qu’il a fallu pour le réaliser. La modification de l’un de ses trois paramètres aura comme effet de modifier au minimum l’un des deux autres. Le but étant de respecter les trois critères afin de réaliser un projet répondant aux attentes. Dans le cadre de ce travail de Bachelor, il n’y a pas de contrainte de budget. De plus le travail est réalisé, avant tout, dans le but d’obtenir son Bachelor. Cela modifie quelque peu la vision des choses. En effet contrairement à un projet classique, l’étudiant peut décider d’augmenter le nombre d’heures normalement prévu à l’horaire, sans pour autant modifier l’un des 3 critères cités ci-dessus. C’est d’ailleurs le seul élément que celui-ci peut faire varier. Effectivement, le délai est fixe et les objectifs le sont également une fois le projet ratifié. Au vu des différents documents à produire et au vu du travail demandé, il est impératif de revoir à la hausse, ce nouveau critère. Page 7 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft 3 Prérequis 3.1 Méthode La méthode représente le référentiel commun qui véhicule la culture collective (de l’organisme), dynamise et fédère les compétences, structure la démarche globale de travail et rend accessible la mise en œuvre des ressources techniques les plus adéquates à la situation opérationnelle des projets.1 En reprenant les notions enseignées par M.P-A. Sunier2, une méthode est la combinaison de 3 facteurs: La technique Les modèles Les outils Une méthode permet le dialogue sur la base d’un référentiel commun. 3.2 Modèle Un modèle au sens d’Oracle Designer et de Visual Paradigm, est une représentation d’un système à l’aide d’éléments d’un référentiel commun. Chaque modèle possède son propre espace de nommage. C’est-à-dire qu’un élément d’un modèle peut exister dans un autre et porter le même nom. Il n’y aura pas de problème pour les identifier, car ils sont chacun dans un modèle différent. Un modèle étant une représentation de la réalité il est possible de réaliser plusieurs modèles représentant le même système, mais sous des angles différents. Il existe trois types de dimension: Le niveau d’abstraction: Représente la distance que l’on met entre notre modèle et ce qu’il représente. Plus la distance est grande et plus le modèle est pérenne. Au contraire plus la distance est petite est plus le modèle risque de devoir être modifié. Le dynamisme: Il s’agit de la différentiation des modèles statiques et dynamiques. Les modèles statiques représentant les modèles de données tandis que les modèles dynamiques représentent les modèles de traitement. Le temps: Effectivement et comme expliquée dans le document [DOC-STB-01], une troisième dimension est présente. Celle-ci exprime les différents modèles dans le temps. La courbe de Merise (illustration suivante) représente cette évolution. 1 [DOC-SPA-05] 2 [DOC-SPA-05] Page 8 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft Premièrement, les modèles représenteront l’analyse critique de l’existant en partant du niveau physique pour ensuite s’élever au niveau logique puis conceptuel. Cette première étape permet de cerner l’état des éléments actuellement mis en place (Existant). Dans un second temps, le modèle conceptuel sera amélioré et modifié afin d’obtenir un modèle conceptuel idéal (Idéal). Ce nouveau modèle représente le système qui sera mis en place. Finalement, la dernière étape représente le réel. Le modèle conceptuel sera dégradé dû à des contraintes techniques et les modèles de plus bas niveau seront réalisés à partir du modèle conceptuel dégradé. Il s’agit dans un premier temps d’une démarche bottom-up puis, secondement, d’une démarche top-down. 3 3 Les principes expliqués ci-dessus sont tirés des documents [DOC-SPA-07] et [DOC-STB-01]. Page 9 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft 3.3 Méthodologies de développement Oracle Designer repose sur les principes méthodologiques du courant de pensée systémique qui se nomme CASE*METHOD. La méthode systémique CASE*METHOD préconise les trois concepts suivants: 4 Avoir une vue globale du système d’information: Il faut considérer les données et les traitements comme constituant unique et intégré. Distinguer plusieurs niveaux d’abstraction: Il est nécessaire de modéliser chaque niveau d’abstraction séparément afin de commencer par le niveau le plus général (conceptuel) et terminer par le niveau le plus technique (physique). Mettre en évidence la dualité donnée/traitements: Les données et les traitements doivent être modélisés séparément et seront confrontés une fois la modélisation de chaque partie terminée. 4 Chapitre inspiré de [DOC-SPA-08]. Page 10 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft 4 Les APIs de table 4.1 Concept des APIs de table Les principes présentés ci-dessous ne sont pas indépendants du SGBDR. Ils ont été prévus pour fonctionner avec le SGBDR SQL Server de Microsoft. Les APIs de tables sont un ensemble de triggers et procédures stockées invoqués par les applications clientes pour exécuter des manipulations de données sur les tables. Les applications clientes n’envoient pas directement de requêtes SQL-DML (INSERT, UPDATE, DELETE) de manipulations de tables, mais elles passent par l’appel de procédures offertes par les APIs de tables. À chaque table est associé un ensemble de trigger et procédures stockées permettant de réaliser les opérations de base, à savoir: Insérer un nouvel enregistrement. Mettre à jour un enregistrement. Supprimer un enregistrement. Bloquer (Lock) un enregistrement avant une mise à jour ou une suppression. La finalité des APIs de tables n’est pas de remplacer les requêtes SQL-DML (INSERT, UPDATE, DELETE). En fait, les APIs enrichissent ou complètent les contraintes spécifiées par les scripts SQL-DDL de définition des données: Ils valident les données qui seront utilisées par les requêtes SQL-DML. Si les données sont correctes et complètes, ils envoient les requêtes SQL-DML; si les données sont incorrectes, ils envoient un message d’erreur à l’application cliente appelante et n’exécutent pas les requêtes SQL-DML. Ils prennent en charge de multiples contraintes usuelles de SII de gestion qui ne sont pas supporté par la norme SQL ANSI-92. Plus concrètement, les APIs de tables effectuent les opérations suivantes avant d’envoyer les requêtes SQL DML: Validation des colonnes obligatoires. Validation des contraintes de clé primaire, de clé étrangère, d’unicité ou encore de check. Validation des contraintes d’exclusion entre associations. Validation de valeurs par rapport à une table de code de référence (reference code tables) Validation de valeurs de domaines. Autogénération de valeurs de colonnes: o Valeurs uniques et séquentielles pour les colonnes alimentées par une séquence. o Valeurs prédéfinies. o Valeurs dérivées. o Informations d’audit de manipulation des enregistrements. Conversion de valeurs de colonnes en majuscule. Maintien d’un journal de trace de toutes les manipulations effectuées sur une table. Maintien de valeurs actualisées de colonnes dénormalisées. Page 11 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft La liste ci-dessus n’est pas exhaustive; de plus, le concepteur peut ajouter son propre code dans les APIs de tables pour pouvoir réaliser des contraintes qui ne sont pas prévues.5 4.2 Principe de fonctionnement général La génération des APIs de table se base sur le modèle conceptuel de données, comme vous pouvez le constater ci-dessous6 : F IGURE 2 - V UE GLOBAL 5 Chapitre repris et adapté du document [DOC-SPA-04]. 6 Provient de [DOC-CFA-03] Page 12 sur 76 APIs de table pour SQL Server 4.3 Principe de fonctionnement technique Voici une illustration du fonctionnement technique des APIs de table F IGURE 3 - P RINCIPE DE FONCTIONNEMENT DES API S DE TABLE ① Requête sur une table ② Déclenchement d’un trigger ③ Les triggers font appel aux procédures stockées ④ Les procédures stockées exécutent des traitements ⑤ Exécution de la requête Page 13 sur 76 Rapport Théorique Arnaud Senft APIs de table pour SQL Server Rapport Théorique Arnaud Senft 4.4 Fonctionnalités couvertes Le plugin remplit les mêmes fonctionnalités que le plugin «Génération des APIs de table pour le SGBDR Oracle». Elles sont listées ci-dessous (tiré du document [DOC-SPA-04]): Autogénération de valeurs de colonnes d’informations d’audit de manipulation des enregistrements. Maintien d’un journal de trace des toutes les manipulations effectuées sur une table. Maintien d’un journal de trace de toutes les exceptions. Ajout de code personnalisé avant et après chaque requête de manipulations effectuées sur une table. Autogénération des valeurs de clé primaire. Cette dernière notion ne sera pas prise en charge par les APIs de table générées. Celle-ci sera déclarée dans le code de définition de la structure d’une table grâce à la propriété identity. Page 14 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft 4.5 Autogénération de valeurs de clé primaire. 4.5.1 Définition L’autogénération de valeurs de clé primaire exprime le fait que la clé primaire soit gérée par le système. 4.5.2 Réalisation Lors de la définition d’une table, l’opération suivante permet d’indiquer au système, la délégation de la gestion de la valeur de celle-ci. CREATE TABLE [dbo].[Employes] ( [Numero] [int] IDENTITY(1,1) PRIMARY KEY, [DEP_Numero] [int] NOT NULL, [Mnemo] [varchar](5) NOT NULL, [Nom] [varchar](40) NOT NULL, [Prenom] [varchar](20) NOT NULL) Go Les APIs de table n’ont dont pas besoin de mettre en place un système permettant de gérer la génération des valeurs de clé primaire. Page 15 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft 4.6 Colonnes d’informations d’audit de manipulation. 4.6.1 Définition Une colonne d’informations d’audit de manipulation des enregistrements permet d’enregistrer la date de création, l’utilisateur ayant exécuté l’insertion, la date de la dernière modification ainsi que l’utilisateur ayant exécuté cette requête. 4.6.2 Réalisation Voici un exemple d’utilisation de valeurs de colonne d’informations d’audit de manipulation des enregistrements (Il s’agit d’un exemple découlant d’une requête SQL DML INSERT). F IGURE 4 - EXEMPLE D ’ UTILISATION DE VALEURS DE COLONNE D ’ INFORMATIONS D ’ AUDIT DE MANIPULATION DES ENREGISTREMENTS Afin de réaliser un système me permettant d’autogénérer les valeurs de colonnes d’informations d’audit, il est nécessaire de mettre en place les éléments suivant : un trigger INSTEAD OF INSERT et un trigger INSTEAD OF UPDATE. Le premier permettant d’intercepter les requêtes d’insertion et le deuxième les requête de mise à jour des données. Les colonnes suivantes doivent être ajoutées, à la table que l’on souhaite auditer : CTRLAJDATE de type date : Permet de stocker le nom de l’utilisateur ayant créé le tuple. CTRLAJUSER de type texte : Permet de stocker la date de création du tuple. CTRLMODATE de type date : Permet de stocker le nom d’utilisateur ayant effectué la dernière modification. CTRLMOUSER de type texte : Permet de stocker la date de la dernière modification. CTRLAJUSER et CTRLMOUSER sont de type NVARCHAR(128), car ce type correspond à celui d’un nom d’un utilisateur de SQL Server. Tandis que CTRLAJDATE et CTRLMODATE sont de type DATETIME. Effectivement, celui-ci permet de stocker une date et une heure. Lors de l’exécution d’une requête SQL DML de type INSERT, les 4 colonnes devront être renseignées par le trigger. Pour être plus précis, les colonnes CTRLAJDATE et CTRLMODATE recevront comme valeur la date et l’heure actuelle tandis que les colonnes CTRLAJUSER et CTRLMOUSER seront renseignées à l’aide du nom d’utilisateur de la base de données (celui ayant exécuté la requête). Si une requête SQL DML de type UPDATE est exécutée, 2 colonnes seront modifiées par le trigger. Il s’agit des colonnes CTRLMODATE qui correspondra à la date actuelle et CTRLMOUSER qui sera renseignée à l’aide de l’utilisateur ayant exécuté la requête. Voici une seconde illustration7 : 7 Par illustration j’exprime le concept et non l’exactitude technique. Page 16 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft F IGURE 5 - I LLUSTRATION D ' UN SYSTÈME D ' AUDIT Cette illustration représente une requête d’insertion. Le trigger en rouge étant celui déclenché par la requête. La loupe illustre le contenu dudit trigger. Enfin, s’il s’agit d’une requête SQL DML de type DELETE, aucune colonne ne sera à renseigner. Les colonnes à auditer seront explicitement exprimées par l’utilisateur grâce aux valeurs taguées suivantes : Type de tag Nom du tag Valeur du tag Niveau Champs d’audit CTRLAJUSER oui/non MCD/MLD Champs d’audit CTRLAJDATE oui/non MCD/MLD Champs d’audit CTRLMOUSER oui/non MCD/MLD Champs d’audit CTRLMODATE oui/non MCD/MLD Page 17 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft 4.7 Journal de trace de toutes les manipulations 4.7.1 Définition Un journal de trace de toutes les manipulations effectuées sur une table permet d’obtenir un historique de l’évolution des données. 4.7.2 Réalisation Voici un exemple de journal de trace (Il s’agit d’un exemple découlant d’une requête SQL DML INSERT). F IGURE 6 - J OURNAL DE TRACE Dans le but de mettre en place un système de journalisation des traces de toutes les manipulations effectuées sur une table, il est nécessaire de mettre en place les éléments suivants: un triggers INSERT, un trigger UPDATE, un trigger DELETE, une procédure stockée et une table de journalisation. (Je ne spécifie volontairement pas le type de trigger car tous les types de trigger peuvent être utilisés.) Ces triggers devront être exécutés pour chaque ligne, car chaque ligne doit être, indépendamment l’une de l’autre, journalisée. La table de journalisation se compose des colonnes déjà présentes dans la table à journaliser, mais y ajoute 5 autres colonnes: jn_appln : Cette colonne journalise le nom du trigger ayant été déclenché. jn_operation : Cette colonne journalise le nom de l’opération ayant été exécutée (INS, UPD, DEL). jn_db_user : Cette colonne journalise le nom de l’utilisateur de la base de données. jn_dateTime : Cette colonne journalise le temps. jn_session : Cette colonne journalise le numéro de session. Voici une illustration8 du mécanisme de journalisation: 8 Par illustration j’exprime le concept et non l’exactitude technique. Page 18 sur 76 APIs de table pour SQL Server F IGURE 7 - ILLUSTRATION Rapport Théorique Arnaud Senft DU MÉCANISME DE JOURNALISATION ① La requête SQL DML est interceptée par le trigger. ② Le trigger renseigne les deux variables jn_appln et jn_operation qui seront utilisées pour journaliser la requête. ③ Le trigger fait appel à la procédure stockée ins_jn. ④ Celle-ci renseigne les variables jn_db_user, jn_dateTime et jn_session qui seront également utilisées pour la journalisation. ⑤ La procédure stockée insère les données de journalisation dans la base de données. ⑥ Le trigger exécute la requête SQL DML. Sur cette illustration, il s’agit d’une requête d’insertion. Le trigger en rouge étant celui déclenché par la requête SQL DML. La journalisation sera spécifiée par l’utilisateur grâce à la valeur taguée suivante: Type de tag Nom du tag Valeur du tag Niveau Journalisation JOURNAL oui/non MCD/MLD Page 19 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft 4.8 Personnalisation des APIs de table 4.8.1 Définition L’un des objectifs de ce projet était d’offrir à l’utilisateur la possibilité de personnaliser les APIs de table grâce à l’ajout de partie de code à différents emplacements. 4.8.2 Réalisation La personnalisation des APIs de table passe au travers des valeurs taguées. Effectivement, le code personnalisé à insérer, sera transmis aux triggers grâce aux valeurs taguées désirées. Cette valeur taguée détermine l’endroit où sera inséré le code personnalisé. Il est également possible de créer nos propres procédures grâce à la valeur taguée «PROCEDURE». Il suffira ensuite de faire appel à cette procédure grâce aux valeurs taguées permettant d’insérer des portions de codes personnalisées. J’ai identifié plusieurs valeurs taguées / emplacements permettant d’insérer une personnalisation des APIs de table: Type de tag Procédures internes Nom du tag PROCEDURES Valeur du tag Procédure Niveau MLD Déclenchement PRE-IOF-INS-ROW Appel ou procédure MLD Déclenchement PRE-IOF-INS-STMT Appel ou procédure MLD Déclenchement PRE-IOF-UPD-ROW Appel ou procédure MLD Déclenchement PRE-IOF-UPD-STMT Appel ou procédure MLD Déclenchement PRE-IOF-DEL-ROW Appel ou procédure MLD Déclenchement PRE-IOF-DEL-STMT Appel ou procédure MLD Déclenchement PRE-AFTER-INS-ROW Appel ou procédure MLD Déclenchement PRE-AFTER-INS-STMT Appel ou procédure MLD Déclenchement PRE-AFTER-UPD-ROW Appel ou procédure MLD Déclenchement PRE-AFTER-UPD-STMT Appel ou procédure MLD Déclenchement PRE-AFTER-DEL-ROW Appel ou procédure MLD Déclenchement PRE-AFTER-DEL-STMT Appel ou procédure MLD Déclenchement POST-IOF-INS-ROW Appel ou procédure MLD Déclenchement POST-IOF-INS-STMT Appel ou procédure MLD Page 20 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft Déclenchement POST-IOF-UPD-ROW Appel ou procédure MLD Déclenchement POST-IOF-UPD-STMT Appel ou procédure MLD Déclenchement POST-IOF-DEL-ROW Appel ou procédure MLD Déclenchement POST-IOF-DEL-STMT Appel ou procédure MLD Déclenchement POST-AFTER-INS-ROW Appel ou procédure MLD Déclenchement POST-AFTER-INS-STMT Appel ou procédure MLD Déclenchement POST-AFTER-UPD-ROW Appel ou procédure MLD Déclenchement POST-AFTER-UPD-STMT Appel ou procédure MLD Déclenchement POST-AFTER-DEL-ROW Appel ou procédure MLD Déclenchement POST-AFTER-DEL-STMT Appel ou procédure MLD Les valeurs taguées PRE_INS, POST_INS, PRE_UPD, POST_UPD, PRE_DEL et POST_DEL permettent de personnaliser tous les triggers. Par exemple, la valeur taguée PRE_INS permet de personnaliser tous les triggers interceptant une instruction SQL d’insertion. Les autres valeurs taguées présentées ci-dessus sont propres à un et un seul trigger. 4.8.3 Légende Le tableau ci-dessus fait appel à plusieurs abréviations que je présente ci-dessous: POST Permets d’insérer le code personnalisé après une instruction. PRE Permets d’insérer le code personnalisé avant une instruction. IOF Permets d’insérer le code personnalisé dans un trigger INSTEAD OF. AFTER Permet d’insérer le code personnalisé dans un trigger AFTER. INS Permet d’insérer le code personnalisé dans un trigger se déclenchant sur lors de l’exécution d’une instruction SQL DML d’insertion de données. UPD Permet d’insérer le code personnalisé dans un trigger se déclenchant sur lors de l’exécution d’une instruction SQL DML de modification de données. DEL Permet d’insérer le code personnalisé dans un trigger se déclenchant sur lors de l’exécution d’une instruction SQL DML d’effacement de données. Page 21 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft ROW Permets d’insérer le code personnalisé dans un trigger se déclenchant sur chaque ligne de la transaction. STMT Permets d’insérer le code personnalisé dans un trigger se déclenchant une seule fois pour l’ensemble de la transaction (celle déclenchée par l’utilisateur). Page 22 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft 4.9 Maintien d’un journal de trace de toutes les exceptions. 4.9.1 Définition Un journal de trace de toutes les exceptions levées sur une table permet d’obtenir un historique de celles-ci. 4.9.2 Principe Voici les quelques principes lors de la levée d’une exception: L’annulation de toutes les opérations en cours L’arrêt impératif de tout traitement La remontée du message d’erreur à l’utilisateur L’enregistrement des paramètres de l’environnement9 Voici un schéma représentant la gestion d’une exception10 : F IGURE 8 - S CHÉMA REPRÉSENTANT LES PRINCIPES DE LA LEVÉE D ' EXCEPTION 9 Tiré de [DOC-SPA-03] 10 Schéma tiré de [DOC-SPA-03] Page 23 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft 4.9.2.1 Journalisation de l’exception Dans le but de mettre en place un système permettant la journalisation des exceptions, il est nécessaire d’implémenter les éléments suivants : une table permettant de journaliser, une procédure permettant la journalisation et un blog try - catch permettant de détecter l’exception. Voici un exemple : F IGURE 9 - LEVÉE D 'EXCEPTION La table de journalisation des exceptions se compose des colonnes suivantes : error_line Permet de stocker le numéro de la ligne de code ayant déclenchée une exception. Permets de sauvegarder le message expliquant l’exception. error_message Permets de stocker le numéro de l’erreur. error_number error_source Permets de stocker le nom de l’élément dans lequel l’exception s’est produite. Permets de stocker le niveau de gravité de l’exception. error_severity Permets de stocker le numéro de l’état de l’erreur (le contexte). error_state Permets de stocker la date à laquelle l’exception a été levée. jn_dateTime Permets de stocker le numéro de session de l’utilisateur. jn_session Permets de stocker le nom de l’utilisateur. jn_user La procédure stockée se chargera d’alimenter la table stockant les exceptions en cas d’exception. Page 24 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft 4.9.2.2 Journalisation de la trace de l’exception Afin de journaliser les traces des exceptions, il est nécessaire de mettre en place quelques éléments dont : une table permettant de stocker les traces, une procédure stockée et un bloc try – catch permettant d’intercepter l’exception. La table de journalisation des exceptions se compose des colonnes suivantes : numero Corresponds au numéro de l’exception journalisée par le système de journalisation des exceptions. Indique le nombre de fois que l’exception a été remontée. nb_throw Indique le nom de l’élément ayant remonté l’exception. error_throw Indique le code de l’exception. error_number Indique le message de l’exception. error_message Error_number et error_message sont des champs dénormalisés, car ceux-ci sont déjà présents dans la table de journalisation des exceptions. Je les répète volontairement, car ceci facilite l’analyse des exceptions lors d’une maintenance corrective. Deux procédures doivent encore être créées. La première permettant d’insérer une trace dans la table, la deuxième, permet de vérifier si l’exception a été remontée ou si elle vient d’être levée. Page 25 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft 4.10 Analyse du contenu des triggers La liste ci-dessous présente, dans un ordre précis, le contenu des différents triggers. Ce contenu est l’aboutissement d’une analyse concernant l’orchestration des différents éléments composants les triggers. 1. Header Corresponds à la déclaration de la méthode (Signature). Est présent pour chaque trigger. Le schéma où sera créé le trigger, le nom du trigger, le schéma et le nom de la table cible varient. 2. Déclaration des variables Déclaration des variables utilisées dans le trigger. Certaines variables peuvent en fonction du type de trigger et des valeurs taguées apparaitre ou non. Le tableau suivant récapitule les variables dépendantes des valeurs taguées. Valeurs Tagguées Valeur Variable à déclarer CtrlAjUser Oui @ctrlAjUser CtrlAjDate Oui @ctrlAjDate CtrlMoUser Oui @ctrlMoUser CtrlMoDate Oui @ctrlMoDate Journal Oui @appln @operation 3. Begin Début du body du trigger. Toujours présent. 4. Set de variables systèmes Instruction de configuration de la base de données. Toujours présent . 5. Début du Try 6. Set de la variable de contexte de journalisation Apparais si la valeur taguée de journalisation est à Oui. La variable @appln permet de journaliser le type de trigger en cours. Voici les valeurs qu’elle peut prend en fonction du trigger : Page 26 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft Trigger Valeur de @appln INSTEAD OF INSERT ROW API_IIR_NomDeLaTable INSTEAD OF UPDATE ROW API_IUR_NomDeLaTable INSTEAD OF DELETE ROW API_IDR_NomDeLaTable AFTER OF INSERT ROW API_AIR_NomDeLaTable AFTER OF UPDATE ROW API_AUR_NomDeLaTable AFTER OF DELETE ROW API_ADR_NomDeLaTable INSTEAD OF INSERT STMT API_IIS_NomDeLaTable INSTEAD OF UPDATE STMT API_IUS_NomDeLaTable INSTEAD OF DELETE STMT API_IDS_NomDeLaTable AFTER OF INSERT STMT API_AIS_NomDeLaTable AFTER OF UPDATE STMT API_AUS_NomDeLaTable AFTER OF DELETE STMT API_ADS_NomDeLaTable 7. Déclaration du curseur Curseur permettant de récupérer les données des requêtes Présent uniquement s’il s’agit d’un curseur «FOR EACH ROW». Les paramètres de celui-ci varient en fonction des valeurs taguées CtrlAjUser, CtrlAjDate, CtrlMoUser et CtrlMoDate. 8. Ouverture et parcours du curseur Déclenchement du curseur et récupération des premières données. Présent uniquement si le trigger est de type «FOR EACH ROW». Les paramètres de celui-ci varient en fonction des valeurs taguées CtrlAjUser, CtrlAjDate, CtrlMoUser et CtrlMoDate. 9. Set des valeurs de colonnes d’informations d’audit de manipulation des enregistrements et des variables de journalisation Présent uniquement si les valeurs taguées Journal, CtrlAjUser, CtrlAjDate, CtrlMoUser et CtrlMoDate sont à Oui (indépendamment l’une de l’autre). 10. Ajout du code de personnalisation du trigger PRE requête La valeur taguée à utiliser dépend du type de trigger. Uniquement présent si celle-ci contient une instruction ou un appel de procédure. Voici un tableau récapitulant les valeurs taguées à utiliser en fonction du trigger : Trigger Valeurs taguées INSTEAD OF INSERT ROW PRE_IOF_INS_ROW INSTEAD OF UPDATE ROW PRE_IOF_UPD_ROW INSTEAD OF DELETE ROW PRE_IOF_DEL_ROW AFTER OF INSERT ROW PRE_AFTER_INS_ROW AFTER OF UPDATE ROW PRE_ AFTER _UPD_ROW Page 27 sur 76 APIs de table pour SQL Server AFTER OF DELETE ROW PRE_ AFTER _DEL_ROW INSTEAD OF INSERT STMT PRE_AFTER_INS_ROW INSTEAD OF UPDATE STMT PRE_ AFTER _UPD_ROW INSTEAD OF DELETE STMT PRE_ AFTER _DEL_ROW AFTER OF INSERT STMT PRE_AFTER_INS_STMT AFTER OF UPDATE STMT PRE_ AFTER _UPD_ STMT AFTER OF DELETE STMT PRE_ AFTER _DEL_ STMT Rapport Théorique Arnaud Senft 11. Ajout du code de personnalisation de la requête avant son exécution Code renseigné par l’utilisateur à l’aide des valeurs taguées PRE_INS, PRE_UPD et PRE_DEL. Uniquement présent si celle-ci contient une instruction ou un appel de procédure. 12. Exécution de la requête SQL DML Requête exécutée uniquement pour les triggers «INSTEAD OF». Requête dépendante du type de trigger (insert, update, delete). Requête dépendante des valeurs taguées CtrlAjUser, CtrlAjDate, CtrlMoUser et CtrlMoDate. 13. Ajout du code de personnalisation de la requête après son exécution Code renseigné par l’utilisateur à l’aide des valeurs taguées POST_INS, POST_UPD et POST_DEL. Uniquement présent si celle-ci contient une instruction ou un appel de procédure. 14. Récupération de la clé primaire venant d’être insérée Afin de la renseigné dans la table de journalisation. Uniquement présent si la valeur taguée Journal est à Oui. 15. Exécution de la journalisation Appel de la procédure de journalisation si la valeur taguée Journal est à Oui. 16. Ajout du code de personnalisation du trigger POST requête La valeur taguée à utiliser dépend du type de trigger. Uniquement présent si celle-ci contient une instruction ou un appel de procédure. Voici un tableau récapitulant les valeurs taguées à utiliser en fonction du trigger : Page 28 sur 76 APIs de table pour SQL Server Trigger Valeurs taguées INSTEAD OF INSERT ROW POST_IOF_INS_ROW INSTEAD OF UPDATE ROW POST_IOF_UPD_ROW INSTEAD OF DELETE ROW POST_IOF_DEL_ROW AFTER OF INSERT ROW POST_AFTER_INS_ROW AFTER OF UPDATE ROW POST_ AFTER _UPD_ROW AFTER OF DELETE ROW POST_ AFTER _DEL_ROW INSTEAD OF INSERT STMT POST_AFTER_INS_ROW INSTEAD OF UPDATE STMT POST_ AFTER _UPD_ROW INSTEAD OF DELETE STMT POST_ AFTER _DEL_ROW AFTER OF INSERT STMT POST_AFTER_INS_STMT AFTER OF UPDATE STMT POST_ AFTER _UPD_ STMT AFTER OF DELETE STMT POST_ AFTER _DEL_ STMT Rapport Théorique Arnaud Senft 17. Récupération des valeurs suivantes contenues dans le curseur Présent s’il s’agit d’un trigger «FOR EACH ROW». Paramètre dépendant des valeurs taguées CtrlAjUser, CtrlAjDate, CtrlMoUser et CtrlMoDate. 18. Fermeture du curseur Présent s’il s’agit d’un trigger «FOR EACH ROW». 19. Catch des exceptions 20. Déclaration des variables Ces variables permettent de journaliser les exceptions. 21. Fermeture du curseur Présent s’il s’agit d’un trigger «FOR EACH ROW». 22. Set des variables de journalisation de l’exception Set des valeurs aux variables de journalisation des exceptions. 23. Exécution de la requête de journalisation de l’exception 24. Footer (Fin du trigger) Page 29 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft 5 Spécificités du SGBDR SQL Server de Microsoft 5.1 Contexte Afin de bien comprendre l’existence de ce chapitre, il est nécessaire que je vous présente le contexte. Au sein de la Haute école de Gestion ARC de Neuchâtel, j’ai été formé essentiellement sur le SGBDR Oracle. Il a donc fallu, dans un premier temps, que je comprenne les différences qui existent entre le SGBDR SQL Server de Microsoft et celui d’Oracle. Ce chapitre a donc pour but de présenter quelques éléments ayant directement un impact sur le projet. Page 30 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft 5.2 Base de données utilisée par le SGBDR SQL Server Pour fonctionner, SQL Server utilise quatre bases de données : Master: La base de données master contient l’intégralité des informations système relatives à un système SQL Server. Cela inclut les métadonnées relatives à l’instance, dont les comptes d’ouverture de session, les points de terminaison, les serveurs liés et les paramètres de configuration du système. La base de données master enregistre également l’existence de toutes les bases de données et l’emplacement de leurs fichiers, et contient les informations d’initialisation de SQL Server. Par conséquent, SQL Server ne peut pas démarrer si la base de données master n’est pas disponible. Dans SQL Server, les objets système ne sont plus stockés dans la base de données master, mais dans la base de données des ressources 11 Model: La base de données model fait office de modèle pour toutes les bases de données créées sur une instance de SQL Server. Étant donné que la base de données tempdb est créée chaque fois que SQL Server est démarré, la base de données model doit toujours exister sur un système SQL Server.12 MSDB: La base de données msdb est utilisée par l’Agent SQL Server pour planifier des alertes et des travaux, ainsi que par d’autres fonctionnalités telles que Service Broker et la messagerie de base de données.13 Tempdb: La base de données système tempdb est une ressource globale disponible pour tous les utilisateurs connectés à l’instance de SQL Server et sert de conteneur aux éléments suivants : o Les objets utilisateurs temporaires créés explicitement, tels que : les tables temporaires locales ou globales, les procédures stockées temporaires, les variables de table ou les curseurs. o Des objets internes créés par le Moteur de base de données SQL Server, par exemple, les tables de travail servant à stocker des résultats intermédiaires pour les mises en attente ou le tri. o Les versions de ligne générées par les transactions de modification de données dans une base de données qui utilise l’isolement de version de lignes read committed ou les transactions d’isolement de capture instantanée. o Les versions de ligne générées par des transactions de modification de données pour des fonctionnalités telles que : les opérations d’index en ligne, les déclencheurs et les connexions MARS (Multiple Active Result Sets).14 11 [WEB-MIC-09] 12 [WEB-MIC-10] 13 [WEB-MIC-11] 14 [WEB-MIC-12] Page 31 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft 5.3 Instance An instance of the Database Engine operates as a service that handles all application requests to work with the data in any of the databases managed by that instance. It is the target of the connection requests (logins) from applications. The connection runs through a network connection if the application and instance are on separate computers. If the application and instance are on the same computer, the SQL Server connection can run as either a network connection or an in-memory connection. When a connection has been completed, an application sends Transact-SQL statements across the connection to the instance. The instance resolves the Transact-SQL statements into operations against the data and objects in the databases, and if the required permissions have been granted to the login credentials, performs the work. Any data retrieved is returned to the application, along with any messages such as errors. You can run multiple instances of the Database Engine on a computer. One instance can be the default instance. The default instance has no name. If a connection request specifies only the name of the computer, the connection is made to the default instance. A named instance is one where you specify an instance name when installing the instance. A connection request must specify both the computer name and instance name in order to connect to the instance. There is no requirement to install a default instance; all of the instances running on a computer can be named instances.15 15 [WEB-MIC-22] Page 32 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft 5.4 Différence entre utilisateur et schéma 5.4.1 Introduction Microsoft SQL Server 2005 introduced the concept of database object schemas. Schemas are analogous to separate namespaces or containers used to store database objects. Security permissions apply to schemas, making them an important tool for separating and protecting database objects based on access rights. Schemas reduce the work required, and improve the flexibility, for security-related administration of a database. This white paper discusses the opportunities for improvements in the security administration of a user database, and it outlines some best practices around using schemas to manage database objects in development and production databases. Specifically, it addresses three real-world scenarios: Protecting database objects from being altered by users without the knowledge of the database owner Preventing database base objects, independent software vendor (ISV) databases in particular, from ad hoc or incorrect user access leading to poor application performance Bringing related groups of objects (logical entities) together within one physical database to reduce physical database administrative overhead 5.4.2 Overview In releases prior to SQL Server 2005, database object owners and users were the same things. SQL Server 2005 introduced the concept of database schemas and the separation between database objects and ownership by users. An object owned by a database user is no longer tied to that user. The object now belongs to a schema – a container that can hold many database objects. The schema owner may own one or many schemas. This concept creates opportunities to expose database objects within a database for consumption yet protect them from modification, direct access using poor query techniques, or removal by users other than the owner. The ability to protect database objects in this way has many practical applications. One example of relevance is the protection of database objects in application development environments where developers and testers share the same set of database objects. Another example of protecting database objects is in ISV products such as Siebel or SAP. Unmanaged access by ad hoc queries or poorly tuned queries of the base objects will negatively impact the performance of the application. Additionally, the use of schemas can help to combine entities from separate applications or functional areas, or logical groups, into a single physical database. Page 33 sur 76 APIs de table pour SQL Server 5.4.3 Rapport Théorique Arnaud Senft What Is User Schema Separation? Prior to SQL Server 2005, a database object (for example, a table) is owned by a user. That user could be DBO or any valid user account. That table is now directly linked to that user– the user cannot be deleted without removing the table or changing the owner of the table. The table can only ever be owned by one user. User-schema separation, introduced in SQL Server 2005, means that the table is no longer owned by any user; it belongs to a schema. In turn, the schema is owned by a user. A schema is separate entity within the database. It is created by using the CREATE SCHEMA statement. A schema can be owned by a user, a role, or a group (for more information about possible schema owners, see the “Principals” section in this document). A user executing CREATE SCHEMA can be the owner of the schema or it can allocate another user as the schema owner (with appropriate IMPERSONATE permissions). A schema only has one owner, but a user can own many schemas. Schema ownership is transferrable. Database objects are created and contained within a schema. For example, when the following statement is executed, the table MyTable is created within the MySchema schema: CREATE TABLE MySchema.MyTable (col1 int, col2 int) This separation means objects and schemas can be created before users are added to the database. It also means a user can be dropped without specifically dropping the objects owned by that user. Note: A schema cannot be dropped if it contains any objects. If a DROP SCHEMA statement is executed while it contains objects, the drop operation fails. There are many advantages to user-schema separation, including: The matrix of permissions on schemas and the database objects within them is significantly more complex than in earlier releases. This allows much more control of access, and levels of access, for the administrator. Ownership of schemas and the database objects within them is transferable. Objects can be moved between schemas Multiple database users can share a single schema. A database user can be dropped without dropping objects in a corresponding schema.16 16 [WEB-MIC-21] Page 34 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft 6 Transact SQL Le Transact-SQL (T-SQL) est une extension propriétaire de Sybase et Microsoft au langage SQL. Transact-SQL a été développé à l’origine par la société Sybase, dès les premières versions de son moteur de base de données du même nom. De manière similaire au PL/SQL d’Oracle, Transact-SQL fournissait le moyen d’étendre les fonctionnalités de base du SGBD, via des programmes appelés «procédures stockées». Le code source comme compilé est en effet stocké dans la base de données, par opposition aux programmes écrits en langage de programmation classique, dont le code source d’une part, le code compilé d’autre part, sont stockés dans des fichiers du système de fichiers. 17 17 [WEB-WIKI-02] Page 35 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft 6.1 GO Signale la fin d’un traitement Transact-SQL aux utilitaires SQL Server.18 6.2 Fonction System Les fonctions système permettent d’accéder aux informations à partir des tables système SQL Server sans avoir à accéder directement à ces tables. Plusieurs fonctions Transact-SQL ont des noms commençant avec le double signe arobase (@@). Bien que dans des versions antérieures de SQL Server, les fonctions débutantes par @@ sont appelées variables globales, elles ne sont pas des variables et n’en ont pas le comportement. Elles sont en réalité des fonctions système, et leur syntaxe suit les mêmes règles que celle des fonctions normales.19 18 [WEB-MIC-16] 19 [WEB-MIC-19] Page 36 sur 76 APIs de table pour SQL Server 20 Rapport Théorique Arnaud Senft Variable Explication @@CONNECTIONS Le nombre d’authentifications depuis le dernier démarrage de SQL Server @@MAX_CONNECTIONS Le nombre maximum de connexions simultanées @@CPU_BUSY La quantité de temps que l’UC a passé afin de traiter les requêtes SQL Server @@ERROR Retourne 1 si une erreur s’est produite @@IDENTITY La dernière IDENTITY @@IDLE La quantité de temps d’inactivité du serveur depuis son démarrage @@IO_BUSY La quantité de temps que le serveur a passé afin de traiter les opérations d’E/S @@LANGID Retourne l’identifiant de la langue actuellement utilisée @@LANGUAGE Retourne le nom de la langue actuellement utilisée @@MAXCHARLEN Le nombre de caractères maximums, en octets, par défaut @@PACK_RECEIVED Le nombre de paquets lu, par le serveur SQL, depuis son démarrage @@PACK_SENT Le nombre de paquets écrit, par le serveur SQL, depuis son démarrage @@PACKET_ERRORS Le nombre d’erreurs s’étant produites lors de l’envoi/réception de paquets @@ROWCOUNT Le nombre de lignes affectées par la dernière commande @@SERVERNAME Le nom local du serveur SQL @@SPID Le numéro du processus actuellement en cours @@TEXTSIZE La taille maximum, en octets, d’un objet retourné par une requête SELECT @@TIMETICKS Le nombre de microsecondes par cycle @@TOTAL_READ/@@TOTAL_WRITE Le nombre de lectures/écritures sur le disque, effectuées par SQL Server depuis son dernier démarrage. @@TRANCOUNT Le nombre d’instructions BEGIN TRANSACTION qui se sont produite sur la connexion actuelle. @@VERSION La version du serveur SQL [WEB-MIC-20] Page 37 sur 76 valeur insérée 20 dans un champ APIs de table pour SQL Server Rapport Théorique Arnaud Senft 6.3 Curseurs Les curseurs Transact-SQL sont principalement utilisés dans les procédures stockées, les déclencheurs et les scripts Transact-SQL, où ils permettent à d’autres instructions TransactSQL d’accéder au contenu d’un ensemble de résultats. En général, pour utiliser un curseur Transact-SQL dans une procédure stockée ou un déclencheur, procédez comme suit : 1. Déclarez les variables Transact-SQL devant contenir les données retournées par le curseur. Déclarez une variable pour chaque colonne de l’ensemble de résultats. Déclarez des variables suffisamment importantes pour contenir les valeurs retournées par la colonne et dont le type de données peut être converti implicitement à partir du type de données de la colonne. 2. Associez un curseur Transact-SQL à une instruction SELECT à l’aide de l’instruction DECLARE CURSOR. L’instruction DECLARE CURSOR définit également les caractéristiques du curseur, comme son nom, et indique s’il s’agit d’un curseur en lecture seule ou d’un curseur avant uniquement. 3. Utilisez l’instruction OPEN pour exécuter l’instruction SELECT et remplir le curseur. 4. Utilisez l’instruction FETCH INTO pour extraire des lignes individuelles et placer les données de chaque colonne dans une variable spécifiée. Les autres instructions Transact-SQL peuvent ensuite référencer ces variables pour accéder aux valeurs des données extraites. Les curseurs Transact-SQL ne permettent pas de rechercher des blocs de lignes. 5. Lorsque vous avez terminé d’utiliser le curseur, utilisez l’instruction CLOSE. La fermeture d’un curseur libère des ressources, comme l’ensemble de résultats du curseur et ses verrous sur la ligne en cours. Cependant, la structure du curseur vous permet encore de procéder à un nouveau traitement si vous réutilisez une instruction OPEN. Étant donné que le curseur est encore présent, vous ne pouvez pas réutiliser son nom à ce stade. L’instruction DEALLOCATE libère entièrement toutes les ressources allouées au curseur, y compris son nom. Après avoir désalloué un curseur, utilisez l’instruction DECLARE pour reconstruire le curseur.21 21 [WEB-MIC-17] Page 38 sur 76 APIs de table pour SQL Server 6.3.1 Rapport Théorique Arnaud Senft @@FETCH_STATUS Retourne l’état de la dernière instruction FETCH effectuée sur un curseur actuellement ouvert par la connexion. Valeur retour de Description 0 L’instruction FETCH a réussi. -1 L’instruction FETCH a échoué ou la ligne se situait au-delà du jeu de résultats. -2 La ligne recherchée est manquante. 22 Cette fonction système est utilisée, par exemple, afin de boucler sur un curseur jusqu’à ce que celui-ci soit vide. WHILE @@FETCH_STATUS = 0 BEGIN SET @mnemo = UPPER(@mnemo) INSERT INTO dbo.Employes( DEP_Numero, Mnemo, Nom, Prenom, DateNaissance, RueNo) VALUES( @depNumero, @mnemo, @nom, @prenom, @dateNaissance, @rueNo); FETCH NEXT FROM inserted_Cursor INTO @depNumero, @mnemo, @nom, @prenom, @dateNaissance, @rueNo END CLOSE inserted_Cursor DEALLOCATE inserted_Cursor 22 [WEB-MIC-18] Page 39 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft 6.4 Triggers 6.4.1 Déclencheurs AFTER Les déclencheurs AFTER sont exécutés après l’action associée à une instruction INSERT, UPDATE ou DELETE. La définition du déclencheur AFTER s’effectue de la même façon que celle de FOR, unique option disponible dans les versions antérieures de Microsoft SQL Server. Les déclencheurs AFTER peuvent être spécifiés uniquement sur des tables.23 6.4.2 Déclencheurs INSTEAD OF Les déclencheurs INSTEAD OF sont exécutés à la place de l’action de déclenchement habituelle. Ils peuvent également être définis sur une vue avec une ou plusieurs tables de base, afin d’étendre les types de mises à jour pouvant être prises en charge par celle-ci.24 Bien entendu, s’agissant de trigger se déroulant «à la place de», il est nécessaire de ré exécuté la requête ayant déclenchée le trigger. 23 [WEB-MIC-14] 24 [WEB-MIC-14] Page 40 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft 6.5 Table inserted et deleted Les instructions de déclenchement DML utilisent deux tables spéciales : la table deleted et la table inserted. SQL Server les crée et les gère automatiquement. Ces tables temporaires résidant en mémoire servent à tester les effets de certaines modifications de données et à définir des conditions pour les actions de déclenchement DML. Vous ne pouvez pas modifier directement les données contenues dans les tables ou effectuer des opérations DDL (Data Definition Language) sur les tables. La table deleted stocke des copies des lignes affectées par les instructions DELETE et UPDATE. Pendant l’exécution d’une instruction DELETE ou UPDATE, certaines lignes sont supprimées de la table du déclencheur et déplacées vers la table deleted. La table deleted et la table du déclencheur n’ont habituellement pas de ligne en commun. La table inserted stocke des copies des lignes affectées par les instructions INSERT et UPDATE. Pendant une transaction d’insertion ou de mise à jour, de nouvelles lignes sont ajoutées dans la table inserted et dans la table du déclencheur. Les lignes de la table inserted sont des copies des lignes créées dans la table du déclencheur. D’un point de vue théorique, une transaction de mise à jour est une opération de suppression suivie d’une opération d’insertion; les anciennes lignes sont d’abord copiées dans la table deleted, et les nouvelles lignes sont ensuite copiées dans la table du déclencheur et dans la table inserted.25 Les triggers FOR EACH ROW n’existant, il faut faire appel aux tables deleted et inserted. Il est donc nécessaire, dans un trigger, de récupérer les différentes données de la requête ayant déclenché le trigger à l’intérieur des tables inserted ou deleted. Pour ce faire, un curseur doit être utilisé afin de récupérer toutes les lignes. Exemple : Je veux mettre à jour les enregistrements suivant, car l’adresse a changée (la poste a ajouté un «a» au numéro de l’adresse) : F IGURE 10 - T ABLE INSERTED ET DELETED - POINT DE DÉPART 25 [WEB-MIC-15] Page 41 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft Voici la requête SQL DML : UPDATE [AGL_RH].[dbo].[Employes] SET [RueNo] = «Route de Bienne 20a» WHERE [Localite] [RueNo] [Nom] GO = «La Neuveville» AND = «Route de Bienne 20' AND = «Rossi» Le schéma ci-dessous représente les différentes étapes imagées de l’exécution de la requête : F IGURE 11 - É TAPES IMAGÉES DE L ’ EXÉCUTION DE LA REQUÊTE Page 42 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft Voici ce qui se passe réellement : ① La requête SQL DML est interceptée par le trigger INSTEAD OF UPDATE. ② Celui-ci va déclarer un curseur qui récupère les données à modifier. Celles-ci sont dans la table INSERTED. ③ La requête UPDATE est exécutée pour une ligne. ④ Le curseur récupère le prochain enregistrement. ⑤ Une boucle est créée jusqu’à ce qu’il n’y est plus d’enregistrement à traiter. Voici le résultat : F IGURE 12 - 6.5 T ABLE INSERTED ET DELETED - R ÉSULTAT Page 43 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft 7 Utilisation du plugin L’utilisation du plugin est présentée ci-dessous afin de comprendre les différentes interactions présentes entre chaque élément (une représentation A3 du schéma est présente en annexe). F IGURE 13 - U TILISATION DU PLUGIN Page 44 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft 8 Architecture du plugin de génération des APIs de table pour SQL Server 8.1 Introduction Le chapitre suivant décrit l’architecture qui a été étudiée et mise en place. Il a été décidé, en commun accord avec mon directeur de travail de Bachelor, de ne pas reprendre le plugin «Génération des APIs de table pour Oracle». En effet, après analyse, celui-ci, l’architecture utilisée ne se prête malheureusement pas à son extension. Page 45 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft 8.2 Principe de séparation des couches Le fait de repartir sur une nouvelle base me permet de mettre en place l’architecture que j’estime la plus adaptée à ce projet. En séparant les couches, je facilite la compréhension globale du plugin. J’ai décelé 4 couches : la couche de présentation, la couche de service, la couche métier et la couche de persistance. Couche de présentation Cette couche représente la partie visible et interactive avec l’utilisateur. Elle se charge donc principalement de guider et d’informer l’utilisateur. Couche de service Cette couche permet de créer un point d’entré afin de faciliter et garantir la manipulation des éléments a trait à une même problématique. Elle cache donc la complexité métier à l’aide de service faisant «façade». Couche de métier Cette couche permet de décrire toute la problématique métier de l’application. Elle est souvent appelée «Domain Model». Contrairement à la couche service, cette couche possède une granularité fine. Couche de persistance Cette couche implémente la logique permettant l’accès et la mémorisation des données dans un référentiel. Page 46 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft 8.3 Couplage entre les couches Chaque couche doit interagir avec ses voisines et seulement ses voisines. Cette notion se nomme «Faible couplage entre les couches». En général chaque couche ne connait que sa voisine du dessous, et ce de façon unidirectionnelle «Top-Down». 26 26 [CBA-IND-01] Page 47 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft 8.4 Séparation effective des couches Voici un bref schéma représentant l’interconnexion entre les différentes couches du plugin. F IGURE 14 - S ÉPARATION EFFECTIVE DES COUCHES Page 48 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft 8.5 Patterns utilisés Java Enterprise Edition «J2EE» définit un certain nombre de Pattern. Ces patterns permettent de recenser les bonnes pratiques de programmation en Java. 8.5.1 DAO Le Pattern «Data Access Object» fait partie de ce catalogue. Son objectif est de définir une méthode de séparation par couche de la logique de persistance des autres types de logiques. Le but de cette séparation est de pouvoir rendre l’application indépendante du système de persistance utilisé. Le changement ou la modification de notre système de persistance, par exemple le passage d’une base de données «SQL Server» à une base de données «Oracle», se fera ainsi beaucoup plus facilement. En effet, notre couche contenant la logique de persistance est la seule partie de code qu’il faudra adapter, le reste du code pourra lui être conservé. Le Pattern «Data Access Object» est généralement utilisé avec un Pattern de création. F IGURE 15 - DAO Page 49 sur 76 APIs de table pour SQL Server 8.5.2 Rapport Théorique Arnaud Senft Factory Method Un Pattern de création définit une méthode permettant de simplifier le processus de création, instanciation d’objet. Le Pattern de création qui nous intéresse, ici «Factory Method», est tiré d’un livre écrit par le «GoF» qui définit 23 Patterns. Il permet d’instancier des objets dont le type est dérivé d’un type abstrait. La classe exacte de l’objet n’est donc pas connue par l’appelant. Plusieurs fabriques peuvent être regroupées en une fabrique abstraite permettant d’instancier des objets dérivant de plusieurs types abstraits différents. Comme en général, les fabriques sont uniques dans un programme, on utilise souvent le patron de conception singleton pour les implémenter.27 F IGURE 16 - F ACTORY M ETHOD 8.5.3 Singleton Ce design pattern permet de garantir qu’une classe n’a qu’une seule instance et fournit un point d’accès de type global à cette classe. F IGURE 17 - S INGLETON 27 [WEB-WIKI-03] Page 50 sur 76 APIs de table pour SQL Server 8.6 Diagramme de classe Ces 3 diagrammes sont disponibles en annexe. F IGURE 18 - D IAGRAMME DE CLASSE Page 51 sur 76 Rapport Théorique Arnaud Senft APIs de table pour SQL Server F IGURE 19 - D IAGRAMME DE CLASSE Page 52 sur 76 Rapport Théorique Arnaud Senft APIs de table pour SQL Server F IGURE 20 - D IAGRAMME DE CLASSE Page 53 sur 76 Rapport Théorique Arnaud Senft APIs de table pour SQL Server 8.7 Organisation des packages Ce chapitre a pour but d’expliquer l’organisation des différents packages ainsi que de définir leurs responsabilités. Voici l’organisation des packages à l’intérieur du projet : F IGURE 21 - O RGANISATION DES PACKAGES Les chapitres suivants décrivent les packages, leurs contenus et les différents choix effectués. Page 54 sur 76 APIs de table pour SQL Server 8.7.1 Package generationAPIsTableSQLServer F IGURE 22 - P ACKAGE GENERATION API S T ABLE SQLS ERVER Ce package contient les classes/méthodes devant initialiser le plugin. Cette classe m’a semblé être la plus adaptée afin d’initialiser le plugin. Effectivement, à chaque démarrage de Visual Paradigm, la méthode «loaded» sera appelée automatiquement. Il m’a donc paru judicieux de l’utiliser afin d’initialiser certain composent du plugin. Cependant, il faut être conscient que même si le plugin n’est pas déclenché, la méthode sera appelée. 8.7.2 Package model F IGURE 23 - P ACKAGE MODEL Ce package permet de représenter, en mémoire, les objets contenus dans le référentiel de Visual Paradigm. Il a donc la responsabilité d’initialiser ces objets depuis le référentiel de Visual Paradigm et de faciliter l’accès à certains éléments. Ainsi, un et un seul accès au référentiel est effectué lors du lancement du plugin. 8.7.2.1 Classe Model Cette classe à la responsabilité de représenter et récupérer les éléments «tables» contenus dans le référentiel. Cet élément tables contient chaque table contant le stéréotype «MLD». Elle contient également une représentation du DiagramManager qui permet notamment de récupérer des informations propres au diagramme. Cette classe implémente le pattern Singleton afin de garantir qu’une et une seule instance de la classe existe. 8.7.2.2 Classe AbsTable et implémentations Cette classe représente une table précise présente dans le référentiel. Afin de faciliter la manipulation des différentes valeurs taguées, celles-ci sont présentes sous forme d’attribut de classe. La représentation de ses valeurs taguées pouvant changer, une classe abstraite, contenant les valeurs taguées «de base», a été créée. Une FactoryMethod a également été créée afin de s’abstraire de la complexité d’instanciation de l’objet correspondant au SGBDR. Page 55 sur 76 APIs de table pour SQL Server 8.7.3 Package exceptions F IGURE 24 - P ACKAGE EXCEPTIONS Ce package contient toutes les exceptions de type checked. C’est-à-dire toutes les exceptions étant potentiellement dues à une erreur de l’utilisateur. Si une de ses exceptions se produit, un message sera envoyé à l’utilisateur. Ce message devant lui permettre de comprendre et résoudre le problème. 8.7.4 Package persistence.DAO F IGURE 25 - P ACKAGE PERSISTENCE .DAO Ce package comprend la logique d’accès aux données. Il a la responsabilité de manipuler les objets présents dans la base de données. Une classe abstraite a été créée afin de garantir la cohérence lors de l’ajout d’un nouveau SGBDR. La classe abstraite permet également d’instancier l’implémentation correspondant au SGBDR. 8.7.5 Package persistence.database F IGURE 26 - P ACKAGE PERSISTENCE .DATABASE Ce package permet de regrouper la logique permettant l’accès à une base de données. Une classe abstraite devant être implémentée lors de l’ajout d’un nouveau SGBDR est présente afin de garantir la cohérence de la future implémentation représentant le nouveau SGBDR. Elle permet également d’instancier l’implémentation correspondant au SGBDR. Page 56 sur 76 APIs de table pour SQL Server 8.7.6 Package presentation F IGURE 27- P ACKAGE PRESENTATION Ce package regroupe toute la logique de présentation. Il permet donc, dans notre cas, de communiquer avec l’utilisateur. 8.7.7 Package presentation.action F IGURE 28 - P ACKAGE PRESENTATION . ACTION Ce package comprend les différentes classes/méthodes étant appelées lors du déclenchement du plugin. Il a la responsabilité d’appeler le service permettant de générer les scripts ainsi que d’appeler la couche model. 8.7.8 Package scripts F IGURE 29 - P ACKAGE SCRIPTS Ce package regroupe toutes les classes ayant la responsabilité de générer les fichiers script. Trois scripts seront générés. Chaque classe, permettant de générer le contenu des scripts, possède une classe abstraite permettant de garantir la cohérence des futures classes dépendantes du SGBDR. Le Design Pattern Factory Method est utilisé afin de s’abstraire de la complexité d’instanciation des objets. Effectivement, en fonction de la base de données utilisée et du type de script désiré, les objets à instancier changeront. Une classe Utils propre à chaque SGBDR peut être créée afin de regrouper les différentes méthodes regroupant et centralisant les parties de code récurrentes. Page 57 sur 76 APIs de table pour SQL Server 8.7.9 Package service F IGURE 30 - P ACKAGE SERVICE Ce package regroupe tous les services offerts par le plugin. Il correspond au point d’entrée pour quiconque veut réutiliser le plugin dans un autre contexte. L’interface permet l’utilisation, à distance, du service (par exemple avec un WEB Service). La classe concrète «GenerateAPIsTableImpl» implémente le pattern Singleton afin de garantir qu’une et une seule instance du service existe. 8.7.10 Package utils F IGURE 31 - P ACKAGE UTILS Ce package regroupe différentes classes et managers permettant notamment la réutilisation de ceux-ci. Page 58 sur 76 APIs de table pour SQL Server Rapport Théorique Arnaud Senft 8.8 Package presentation et model F IGURE 32 - P ACKAGE PRESENTATION ET MODEL Comme expliqué précédemment, le package «presentation» demande une instance de la classe Model. Ensuite, la classe Model va créer et peupler les éléments permettant de représenter une Table (AbsTable et son implémentation, ici SQLServerTable). Page 59 sur 76 APIs de table pour SQL Server 8.9 Package presentation et service F IGURE 33 - P ACKAGE PRESENTATION Le package «presentation» appelle le service. Page 60 sur 76 ET SERVICE APIs de table pour SQL Server 8.10 Package service et scripts Disponible en annexe. F IGURE 34 - P ACKAGE SERVICE ET SCRIPTS Page 61 sur 76 Rapport Théorique Arnaud Senft APIs de table pour SQL Server Rapport Théorique Arnaud Senft Le package service appelle la méthode de génération des scripts du package script. Cette méthode demande une AbstractFactory de script. Celle-ci retourne une factory en fonction du SGBDR. Cette dernière factory permet ensuite d’instancier la classe correspondant au script désiré. Page 62 sur 76 APIs de table pour SQL Server 9 Gestion des erreurs Une bonne gestion des erreurs doit permettre de faciliter la maintenance, d’aider l’utilisateur du logiciel à comprendre la raison d’un dysfonctionnement et d’assurer une certaine robustesse et fiabilité au logiciel. Après analyse, quatre axes tournent autour de cette problématique : la gestion des exceptions, les messages d’informations pour l’utilisateur, l’écriture d’informations dans des fichiers pour conserver une trace et enfin la gestion des transactions. En ce qui concerne l’écriture d’informations dans des fichiers par une application, je retiens le terme de log. Page 63 sur 76 APIs de table pour SQL Server 9.1 Exceptions Les mécanismes de gestion des exceptions en programmation ne sont pas expliqués ici, car la documentation trouvable sur Internet le fait déjà de manière probante. Bien que les langages de programmation fournissent les instruments nécessaires à la gestion des exceptions, chacun est libre de les utiliser de la manière qu’il le souhaite. Une mauvaise utilisation de ceux-ci peut supprimer les avantages qu’ils apportent. Pour cette raison, la décision de respecter les bonnes pratiques a été prise : Use Exceptions Instead Of Error Values : Il est conseillé d’utiliser des exceptions en place et lieu de simples codes d’erreurs, et ce, pour beaucoup de raisons. L’une d’elles est d’obliger le développeur qui appelle une méthode pouvant soulever une exception à la gérer, tout simplement. Name The Problem Not The Trower : Ce pattern nous aide à savoir comment nommer ses exceptions. Par exemple, l’on préférera utiliser le nom «NoPrimaryKey» plutôt que «GenerateTableAPIsImpossible». Dont Throw Generic Exceptions : Les exceptions ne doivent pas être génériques, mais, à l’inverse, spécifiques. L’on évitera donc de réutiliser la même exception pour plusieurs cas différents, de même que d’utiliser les exceptions dites «implicites» ou «unchecked», telles que ClassNotFoundException en Java, par exemple. En effet, le traitement de celles-ci n’est pas obligatoire et elles ne sont pas visibles par le programmeur au travers de l’IDE. Elles peuvent alors être remontées à la surface sans que personne ne pense à les gérer. Un autre avantage à utiliser des exceptions spécifiques est que le programmeur se voit contraint de traiter individuellement chacune d’elles, sans que toutes ne soient gérées de manière similaire dans un seul bloc. Une phrase de M. Justin Wells explique bien ceci : «Exceptions force you to deal with error cases. Programmers are lazy and often in a hurry; they don't notice or don't bother to check error cases. With exceptions, the compiler forces programmers to handle all the cases.» Let Exception Propagate : Lorsqu’une méthode reçoit une exception et qu’elle ne sait pas comment la gérer, elle doit la remonter. Ainsi, les exceptions se propagent, jusqu’à ce qu’une méthode appelante puisse la traiter. Il est obligatoire que toute exception soit traitée avant d’atteindre l’utilisateur final, sinon le programme s’arrête subitement. Catch What You Can Handle : À contresens du précédent, ce pattern nous demande de traiter les exceptions que l’on peut gérer. Ainsi, il ne faut pas laisser se propager toutes les exceptions, mais seulement celles qui ne sont pas de notre ressort. Page 64 sur 76 APIs de table pour SQL Server Cette liste ne représente pas toutes les bonnes pratiques, mais expose les plus importantes. Respecter ces principes permet de traiter les erreurs possibles à tous les niveaux du code, que ce soit autant dans les méthodes très spécifiques qui réalisent une action précise, ou dans celles qui englobent toute une série de procédures différentes. Lorsqu’une exception survient durant l’utilisation du logiciel, elle peut être, à choix, affichée à l’utilisateur, «loggée», ou les deux. La décision de savoir que faire d’une exception dépend de chaque cas et revient au programmeur. Par ailleurs, il se peut que, dans certaines circonstances d’utilisation, il soit préférable de n’afficher ou de logger que lorsque cela est important. Pour solutionner le problème qui consiste à différencier les exceptions importantes ou non, l’on retrouve fréquemment la notion de Level, qui consiste à définir le niveau d’importance des messages qui doivent être affichés ou «loggés». Dans la pratique, le programmeur doit déclarer le «level» de chaque message ou log et, en fonction du niveau défini globalement, le système va décider de lui-même si elle doit être prise en compte ou non. Ce mécanisme qui a été mis en œuvre dans le plug-in est décrit de façon détaillée dans le rapport pratique. Page 65 sur 76 APIs de table pour SQL Server 9.2 Messages pour l’utilisateur Lorsque le programme ne parvient pas à s’exécuter correctement, l’utilisateur doit être averti. En effet, ce dernier doit toujours avoir un retour immédiat sur les actions qu’il effectue, d’après les critères d’ergonomies connus de M. Bastien et Scapin. Cela est également vrai si l’on sort du cadre de la gestion des erreurs. En effet, il est aussi pertinent d’afficher des messages d’informations dès lors qu’un traitement s’est bien déroulé, par exemple. Une classe de programmation qui a pour tâche de gérer l’envoi de messages à l’utilisateur offre l’avantage de centraliser et réutiliser les instructions nécessaires à cela et par conséquent, d’améliorer la flexibilité en cas de changement de la méthode d’affichage. En effet, l’on peut imaginer que, d’un moment à l’autre, la méthode d’affichage souhaitée change et que, par exemple, au lieu d’afficher ces messages dans une console, ils parviennent à l’utilisateur sous forme de boîtes de dialogue. La mise en place d’une nouvelle fonctionnalité de ce type se réaliserait alors rapidement, car seules les instructions de cette classe centralisatrice devraient être adaptées. Cette idée a aussi été retenue pour le développement du module d’extension Visual Paradigm. Page 66 sur 76 APIs de table pour SQL Server 9.3 Logs La persistance de messages dans des fichiers peut être utilisée dans deux contextes distincts : Conservation de la trace d’exceptions levées Sauvegarde des actions effectuées par le plug-in Dans le premier contexte, l’utilisation des logs sert avant tout à la maintenance, car il permet au programmeur de retrouver la provenance les exceptions afin d’effectuer des corrections de bogues. Le second ne poursuit pas le même objectif, car il s’agit ici de suivre le comportement de l’algorithme dans les détails. L’on pourrait imaginer que, en plus des informations générales affichées dans la console de Visual Paradigm, l’utilisateur puisse consulter un fichier qui résume les actions exactes qui ont été faites (par exemple la création d’une table, la suppression d’une colonne, etc.). Pour l’instant, uniquement la première de ces deux utilisations est retenue, car elle semble essentielle en vue d’une utilisation réelle du programme dans le futur. La seconde, bien que très intéressante, ne paraît pas primordiale au vu des nombreuses fonctionnalités qui pourraient aussi être implémentées durant ce projet. Elle ne doit toutefois pas être mise à l’écart, mais le simple affichage des informations dans la console peut temporairement la substituée. L’inscription d’une exception dans un fichier de logs doit être constituée de suffisamment d’informations pour permettre une localisation de l’erreur survenue. Voici celles que j’ai retenues et qui me semblent essentielles : Nom de la classe qui a levé l’exception Message livré avec l’exception Nom de l’exception Date et heure où l’erreur est survenue Enfin, l’on peut se demander comment effectuer la découpe entre les différents fichiers de logs. Effectivement, il n’est pas imaginable que toutes les exceptions s’enregistrent indéfiniment au même endroit. Une décomposition fonctionnelle, qui consiste à créer, par exemple, un fichier par classe de programmation, ne semble pas intéressante dans notre contexte, car le nombre d’erreurs par classe ne devrait pas être conséquent, chacune d’elles ne devant pas forcément disposer d’un nombre élevé de méthodes soulevant potentiellement des exceptions. Le choix se porte sur un découpage temporel, qui semble être une approche plus pragmatique. En effet, il sera ainsi aisé de retrouver l’erreur soulevée par un utilisateur dès lors que celui-ci nous avertit avoir rencontré un problème un jour donné. L’espace temporel à utiliser entre chaque fichier différent est difficilement quantifiable actuellement, et je retiens le principe de permettre à l’utilisateur de paramétrer ce choix comme il le souhaite. Page 67 sur 76 APIs de table pour SQL Server 9.4 Transactions Le dernier des quatre axes qui tournent autour de la gestion des erreurs est celui de la prise en compte des transactions. Les transactions sont une notion apportée par les bases de données. Elles offrent l’énorme avantage de pouvoir annuler une série d’instructions déjà exécutées, à l’aide d’une simple commande ROLLBACK. 28 28 Chapitre entièrement repris de [DOC-STB-01] Page 68 sur 76 APIs de table pour SQL Server 10 Visual Paradigm 10.1 Structuration du référentiel Comme un exemple vaut mieux que mille mots, prenons nos tables « EMPLOYES » et « DEPARTEMENTS ». F IGURE 35 - S TRUCTURATION DU RÉFÉRENTIEL - EXEMPLE Voici la représentation des deux tables du modèle dans le référentiel. F IGURE 36 - S TRUCTURATION DU RÉFÉRENTIEL - EXEMPLE Comme vous pouvez le remarquer, la représentation dans le référentiel est très simple. représente le modèle représente une table représente une colonne représente une clé étrangère représente une clé primaire Page 69 sur 76 APIs de table pour SQL Server 10.2 Ajout de librairies Visual Paradigm offre la possibilité d’ajouter des librairies à qui le désir. Celles-ci seront automatiquement et systématiquement chargées au démarrage du programme. C’est-àdire que si je décide d’ajouter une librairie au dossier lib de Visual Paradigm (voir chemin plus bas) et que je ne déclenche pas le plugin l’utilisant, celle-ci sera quand même chargée. Je ne pense donc pas que ceci soit la bonne solution. C:\Program Files (x86)\Visual Paradigm for UML 10.1\lib De plus, le démarrage de Visual Paradigm étant déjà lent, je pense que l’alourdir encore plus est une mauvaise idée. 10.3 Présentation d’Open API Open API, concrétisé par la librairie openapi.jar, est nécessaire pour disposer des classes et méthodes qui travaillent sur les objets de Visual Paradigm. Dès lors que l’on souhaite effectuer une action dans Visual Paradigm avec le plug-in, les méthodes de l’API devront être utilisées. Avant de pouvoir utiliser convenablement Open API, une phase d’apprentissage a été nécessaire. Ce chapitre présente donc les fondamentaux permettant de comprendre cette API. Page 70 sur 76 APIs de table pour SQL Server 10.4 Librairie et structure du projet Java Tout d’abord, il est a signalé que la librairie Open API est livré directement avec Visual Paradigm. Elle se trouve à l’adresse suivante, qu’il convient d’adapter en fonction du système d’exploitation et du chemin vers lequel le programme a été installé : C:\Program Files (x86)\Visual Paradigm for UML 10.1\lib\openapi.jar Il suffit d’intégrer cette librairie aux libraires d’un projet Java pour disposer de toutes les méthodes nécessaires au développement du plug-in. Il faut uniquement respecter l’organisation suivante du projet afin que Visual Paradigm puisse prendre en charge le plugin : F IGURE 37 - L IBRAIRIE ET STRUCTURE DU PROJET J AVA Toutes les classes compilées doivent se trouver dans un répertoire classes, alors que le fichier de configuration plugin.xml doit se trouver à la racine. Le nom du répertoire racine doit correspondre au nom du projet créé dans l’environnement de développement29 29 Tiré de [DOC-STB-01] Page 71 sur 76 APIs de table pour SQL Server 10.5 Implémenter le point de départ 10.5.1 Classe PluginLoader Cette classe doit obligatoirement implémenter l’interface VPPlugin car celle-ci sera automatiquement appelée par Visual Paradigm. Voici la définition de la classe : Il est ensuite nécessaire d’implémenter les deux méthodes suivantes: La première sera appelée lors du chargement du plugin par Visual Paradigm. La deuxième lors de l’extinction du programme. Il faut être conscient que même si le plugin n’est pas utilisé, les méthodes load et unload seront appelées. Par contre, si le plugin est déclenché plusieurs fois sans extinction du programme, celles-ci seront appelées une et une seule fois. 10.5.2 Fichier plugin.xml Le fichier plugin.xml contient les descriptions des représentations visuelles que le plugin ajoute à Visual Paradigm. Elles peuvent être sous les formes suivantes : Action : L’action est, en fait, un bouton qui va déclencher une méthode. Les actions viennent s’ajouter dans la barre d’outils principale de Visual Paradigm. Popup menu : Un «popup menu» est, en réalité, une action qui s’ajoute dans un menu contextuel et non une barre d’outils. Il n’est possible d’ajouter des actions que dans les menus contextuels qui apparaissent lorsque l’on effectue un clic droit sur un élément visuel de la zone de dessin. Shape : Une nouvelle forme peut être créée et associée à un type de diagramme particulier. Elle vient alors s’ajouter dans la barre d’outils spécifique au diagramme, et peut être glisser-déposer dans la zone de dessin. Lorsqu’une de ces fonctionnalités est ajoutée dans le fichier XML de description, une nouvelle possibilité s’ajoute ainsi pour l’utilisateur du programme. Lorsqu’il appuie sur une action, qu’elle soit de type «Action» ou «Popup menu», une méthode est lancée. Ceci ne se réalise pas par miracle, mais la spécification de l’action doit comprendre le chemin vers la classe qui implémente l’action, que l’on peut considérer comme étant de type «Listener», car elle écoute et attend qu’on lui demande quelque chose. Voici à quoi peut ressembler la description d’une action :30 30 Tiré de [DOC-STB-01] Page 72 sur 76 APIs de table pour SQL Server <action id="action.GenerationAPIsTableSQLServer» actionType="generalAction» label="Generation APIs de table pour SQLServer» tooltip="Generation APIs de table pour SQLServer» style="normal» menuPath="Tools/Report» toolbarPath="toolbar.GenerationAPIsTableSQLServer/#"> <actionController class="ch.hearc.ig.generationAPIsTableSQLServer.presentation.action.ActionController"/> </action> On voit ainsi que la balise <actionController> permet de définir le chemin vers la classe qui implémente l’action. En plus de cela, d’autres informations peuvent y être associées. Par exemple, l’attribut icon permet d’indiquer une image à utiliser pour l’affichage de l’action. Il existe aussi menuPath qui peut s’avérer utile, car il permet de définir précisément l’emplacement de l’action dans la barre d’outils ou le menu contextuel. Certaines propriétés ne sont pas inscrites «en dur», mais sous forme de variables précédées de «%». En fait, ceci est une possibilité offerte, fort intéressant et simple d’utilisation : ces variables représentent simplement les propriétés définies dans le fichier plugin.properties, que l’on peut créer et placer au même endroit que plugin.xml. Chaque clé de propriété devient alors directement utilisable sous forme de variable au sein de ce dernier. La classe qui réalise une action doit implémenter l’une des interfaces VPActionController ou VPContextActionController d’Open API pour fonctionner. La première sert à une action de barre d’outils, et la seconde à celle d’un menu contextuel. Dans les deux cas, c’est la méthode portant la signature suivante qui doit être implémentée par la classe créée : public void performAction(VPAction action, VPContext context, ActionEvent e) { Le paramètre contexte n’est présent que si notre action provient d’un menu contextuel. Il permet de récupérer l’objet de Visual Paradigm sur lequel l’utilisateur a cliqué pour lancer l’action. C’est donc dans cette méthode que doivent être réalisées les instructions souhaitées. Elle représente, en quelque sorte, le point de départ du plug-in.31 31 Tiré de [DOC-STB-01] Page 73 sur 76 APIs de table pour SQL Server 10.6 Utilisation des objets Le dernier apprentissage nécessaire avant de pouvoir débuter un développement est, bien entendu, celui qui consiste à connaître l’architecture des classes présentes dans l’API. En effet, il est, selon moi, primordial de connaître cela, sans quoi les différentes recherches de méthodes demanderaient un temps bien trop grand. Pour organiser clairement les choses, j’ai opté pour la réalisation d’un diagramme de classes qui ne montre que les classes et les différentes relations entre elles, dans le but de rester simple au maximum. F IGURE 38 - U TILISATION DES OBJETS Les éléments de couleur bleue identifient ceux qui sont directement utiles à la réalisation du plug-in, car ils ont directement attrait au référentiel. Ceux en vert sont relatifs aux diagrammes et, enfin, les deux classes orange sont des fabriques qui permettent d’instancier les différentes classes. La première remarque importante est que le diagramme présenté n’est pas correct en soi. Effectivement, toutes les classes sont, en fait, des interfaces; elles commencent d’ailleurs par la lettre «I». Les compositions, agrégations et associations ne pourraient donc pas exister de la sorte. En fait, chacune de ces interfaces est implémentée par une classe qui n’est pas visible par l’utilisateur de l’API, et ce sont ces classes-là qui détiennent les relations que présentées ici. Seulement, par souci de simplification. Cette problématique n’a simplement pas été considérée sur le diagramme, de manière à le rendre le plus simple et lisible possible. Au final, le développeur qui utilise le plug-in n’est pas obligé de savoir qu’il s’agit d’interfaces, car toute la complexité lui est cachée.32 32 Tiré de [DOC-STB-01] Page 74 sur 76 APIs de table pour SQL Server 10.7 Objets du référentiel Les classes présentées en couleur bleue, dans le chapitre précédent, sont celles qui sont le plus à même d’être utilisées, car elles permettent de travailler avec les éléments concrets du référentiel tels que les classes, les paquetages ou les associations. L’API a été pensée de manière à favoriser au maximum l’héritage. Ainsi, tous les éléments de modèles héritent d’IModelElement. Un objet de ce type peut être un IModelElementParent, qui ne fait qu’ajouter la possibilité d’imbriquer récursivement d’autres éléments en son sein. Pour ainsi dire, toutes les classes sont de ce type. Ceci rend le programme très flexible, bien que ça n’ait pas toujours du sens. Par exemple, il est tout à fait possible d’imbriquer des classes. Cela se voit directement dans l’explorateur de modèles de Visual Paradigm si l’on tente diverses possibilités. F IGURE 39 - O BJETS DU RÉFÉRENTIEL Tous les objets de type IModelElement sont soit présents à la racine du projet et, dans ce cas, leur liaison avec ce dernier est obligatoire, soit contenue dans un parent. La fabrique IModelElementFactory est le seul moyen possible pour instancier des objets qui implémentent ces interfaces. Il est possible, à choix, d’utiliser directement la méthode de création de l’objet désirée, ou d’opter pour une autre générique qui demande alors qu’on lui spécifie le type souhaité en paramètre. //Création de la table avec la méthode spécialisée IDBTable table = IModelElementFactory.instance().createDBTable(); //Création de la table avec la méthode générique String type = IModelElement.MODEL_TYPE_DBTABLE; IDBTable table = (IDBTable)IModelElementFactory.instance().create(type); Il est possible de récupérer les objets qui sont déjà présents dans le projet Visual Paradigm. Pour se faire, nous devons récupérer l’instance du projet courant à l’aide d’une classe nommée ApplicationManager. Une méthode toModelElementArray(), que l’on retrouve également pour chaque IModelElementParent, permet de récupérer un tableau de tous les composants du projet. Il est possible d’y spécifier le type de ceux qui doivent être retournés : Page 75 sur 76 APIs de table pour SQL Server IProject currentProject = ApplicationManager.instance().getProjectManager().getProject(); String type = IModelElementFactory.MODEL_TYPE_CLASS; IModelElement[] classesTab = currentProject.toModelElementArray(type); for(IModelElement genericClasse : classesTab){ IClass classe = (IClass) genericClasse; } Comme le montre le code ci-dessus, une boucle permet ensuite de récupérer, à l’aide d’une conversion de type, le bon objet à traiter. À partir de là, toutes les possibilités sont offertes. Par exemple, il est possible d’ajouter des attributs, des stéréotypes ou tout autre élément à un objet de type classe, en utilisant les méthodes à disposition et la fabrique.33 33 Tiré de [DOC-STB-01] Page 76 sur 76