I. Présentation▲
L'utilité d'une base de données n'est plus à démontrer de nos jours, où la grande majorité des applications y font appel pour le stockage et la manipulation d'informations.
Au cours de ce tutoriel, nous verrons, en implémentant une application simple, comment consulter et mettre à jour une liste de contacts, et ce, sous Firebird SQL avec Delphi 2010.
II. Prérequis▲
- Firebird est une base de données relationnelle SQL conformeconformité de Firebird à la norme SQL au standard ANSI SQL-2003, fonctionnant sous Linux, Windows et plusieurs autres plates-formes. Il a été récemment élu par la communauté SourceForge comme étant le meilleur projet pour l'entreprise en 2009. Vous pouvez télécharger son fichier d'installation pour Windows icitélécharger le serveur firebird sql en version 2.1.3.
- Une version d'évaluation de 30 jours de l'environnement de développement Delphi 2010 avec les drivers dbExpress pour l'accès à Firebird est disponible icitélécharger la version d'évaluation de delphi 2010.
- Le script iSql de création de la base de données et de la table des contacts est téléchargeable iciscript de création de la base de données.
SET
SQL
DIALECT 3
;
CREATE
DATABASE
'localhost/3050:c:\dbexpressfirebird\bd_tuto.fdb'
DEFAULT
CHARACTER
SET
ISO8859_1 ;
/* Generators or sequences */
CREATE
GENERATOR GEN_T_CONTACT_CON_ID;
/* Table: T_CONTACT_CON, Owner: SYSDBA */
CREATE
TABLE
T_CONTACT_CON (
CON_ID INTEGER
NOT
NULL
,
CON_EMAIL VARCHAR
(
64
)
,
CON_SITE_WEB VARCHAR
(
128
)
,
CON_NOM VARCHAR
(
30
)
,
CON_PRENOM VARCHAR
(
30
)
,
CON_TELEPHONE VARCHAR
(
30
)
,
CON_FAX VARCHAR
(
30
)
,
CON_ADRESSE VARCHAR
(
255
)
,
CON_COMMENTAIRES VARCHAR
(
255
)
,
CON_DATE_NAISSANCE DATE
,
CONSTRAINT
PK_T_CONTACT_CON PRIMARY
KEY
(
CON_ID))
;
COMMIT
WORK
;
SET
AUTODDL OFF
;
SET
TERM ^
;
/* Stored procedures */
CREATE
PROCEDURE
SP_GEN_T_CONTACT_CON_ID RETURNS
(
ID INTEGER
)
AS
BEGIN
EXIT
; END
^
ALTER
PROCEDURE
SP_GEN_T_CONTACT_CON_ID RETURNS
(
ID INTEGER
)
AS
begin
id =
gen_id(
gen_t_contact_con_id, 1
)
;
suspend
;
end
^
SET
TERM ; ^
COMMIT
WORK
;
SET
AUTODDL ON
;
SET
TERM ^
;
/* Triggers only will work for SQL triggers */
CREATE
TRIGGER
T_CONTACT_CON_BI FOR
T_CONTACT_CON
ACTIVE BEFORE
INSERT
POSITION
0
as
begin
if
(
new
.con_id is
null
)
then
new
.con_id =
gen_id(
gen_t_contact_con_id,1
)
;
end
^
COMMIT
WORK
^
SET
TERM ; ^
III. Installation de Firebird SQL▲
L'installation du serveur Firebird est très simple, il suffit d'exécuter le fichier d'installation et de suivre les étapes de l'assistant. Laissez toutes les options à leur choix par défaut, mais pensez à cocher la case permettant de copier la bibliothèque fbclient.dll dans le répertoire système de la machine.
Quelques étapes importantes de l'installation en images :
Il s'agit ici d'indiquer à l'installateur l'emplacement où seront copiés les fichiers du serveur Firebird.
- Composants serveur : dans le cas où le poste d'installation hébergera le serveur, cette option doit être cochée. Sous Windows il est conseillé d'utiliser le super serveur, qui utilise un thread pour chaque nouvelle connexion, tandis que le serveur classique utilise un processus par connexion. Le mode serveur classique est préconisé pour un faible nombre de connexions tandis que pour un nombre élevé de connexions, c'est le mode super serveur qui est indiqué.
- Composants outils développeur et administrateur : cette option doit être cochée, car nous allons utiliser l'outil ISQL. Elle permet aussi la copie de divers fichiers, tels que la base de données exemple employee.fdb.
- Composants client : cette option installe les bibliothèques requises pour se connecter au serveur firebird (bibliothèque fbclient.dll par exemple).
- Utiliser Guardian pour contrôler le serveur : Guardian est un processus additionnel chargé de surveiller le processus serveur Firebird. Si ce dernier est arrêté suite à une défaillance, le Guardian va essayer de le relancer.
- Modes d'exécution du serveur Firebird : l'exécution en tant qu'application fait tourner le processus Firebird sous le compte utilisateur actuellement connecté, tandis que l'exécution en tant que service fait tourner ce dernier sous le compte système local.
- Exécuter automatiquement Firebird à chaque démarrage : cocher cette option revient à lancer le serveur automatiquement lors du démarrage de Windows.
- Installer l'application du panneau de configuration : l'application du panneau de configuration est un petit utilitaire permettant de contrôler l'activité du serveur, et d'arrêter ou démarrer le serveur.
- Copier la bibliothèque client Firebird dans le répertoire system : cette option donne l'accès à la bibliothèque cliente à toutes les applications installées.
- Générer la bibliothèque gds32.dll pour les anciennes applications : le serveur Interbase, père de Firebird, utilise lui une bibliothèque client nommée gds32.dll. Pour rendre des applications utilisant cette dll compatible à Firebird, cochez cette option.
Attention, l'application du panneau de configuration ne fonctionne pas sous Vista. Si vous êtes sur ce système d'exploitation, il faudra penser à décocher cette option.
IV. Création de la base de données et de la table de Contacts▲
Pour créer notre base de données, nous allons utiliser ISQL. ISQL est un outil en ligne de commande permettant l'accès aux bases de données Firebird, utilisé principalement pour des tâches administratives. On peut l'utiliser pour créer ou supprimer une base de données par exemple.
Enregistrez le script de création de la base de données sous c:\DBExpressFirebird\create_script.sql, puis lancez l'utilitaire ISQL.
Sous Windows XP, utilisez le menu Démarrer -> Tous les programmes -> Firebird -> Firebird ISQL Tool pour démarrer l'utilitaire, puis saisissez ensuite dans l'invite la commande :
IN c:\DBExpressFirebird\create_script.sql;
Puis, entrez la commande exit; pour sortir de l'utilitaire.
Pensez à remplacer le chemin c:\dbexpressfirebird\ par le chemin d'accès à votre fichier de script.
Les noms des objets de notre base de données ont été normalisés en suivant les règles de nommage des objets que vous pouvez consulter à cette adresse https://sqlpro.developpez.com/cours/standards/Normalisation des noms des objets des bases de données
La base de données est créée. À présent, passons à la création du projet sous Delphi 2010.
V. Création du projet sous Delphi 2010▲
La création d'un projet sous Delphi 2010 est similaire aux éditions précédentes, il faut faire Fichier -> Nouveau -> Applications Fiches VCL - Delphi. Un nouveau projet est créé, contenant un seul formulaire. Les propriétés du formulaire à changer sont celles-ci :
Propriété |
Valeur |
---|---|
Caption |
TUTORIEL FIREBIRD ET DELPHI 2010 |
Name |
FMain |
Une fois cela fait, utilisez la combinaison des touches Ctrl+Shift+S pour enregistrer tout le projet. Nous avons choisi d'enregistrer le projet dans un dossier nommé c:\DBExpressFirebird, le formulaire a été sauvegardé sous le nom uMain.pas, et le projet sous le nom DBExpressFirebird.dpr.
À présent, le projet ayant été créé ainsi qu'un formulaire, nous allons mettre en place la connexion à la source de données.
V-A. Configuration de la connexion sous l'IDE▲
Pour configurer notre connexion, cliquez sur le menu Explorateur de données et choisissez l'option Ajouter une nouvelle connexion.
Si le menu explorateur de données ne s'affiche pas, cliquez sur un élément dans l'explorateur de données et réessayez.
Dans la boîte de dialogue qui s'ouvre, sélectionnez FIREBIRD comme fournisseur, et donnez un nom à la connexion. Ici nous avons choisi comme nom de connexion TUTO_D2010FB.
La connexion est à présent créée, il faut maintenant la configurer. Pour ce faire, dans l'explorateur de données, développez le nœud FIREBIRD, faites un menu contextuel sur le nœud que l'on vient de créer et choisissez l'option modifier la connexion.
Dans la première zone de texte, saisissez le chemin complet d'accès à la base de données, puis dans la seconde le nom de l'utilisateur, et enfin dans la troisième le mot de passe de l'utilisateur. Le tableau ci-dessous renseigne les valeurs utilisées :
Paramètre |
Valeur |
---|---|
Base de données |
localhost/3050:C:\DBExpressFirebird\BD_TUTO.FDB |
Utilisateur |
sysdba |
Mot de passe |
masterkey |
Cliquez ensuite sur tester la connexion pour s'assurer que les paramètres sont corrects et enfin, cliquez sur le bouton OK pour enregistrer la connexion. On peut dès à présent utiliser cette connexion.
Il se peut que le test ne fonctionne pas si vous n'avez pas installé la bibliothèque client Firebird dans le répertoire système de Windows. Auquel cas, pour la suite du tutoriel, pensez à définir la propriété VendorLib du composant SQLConnection vers le chemin complet d'accès à la bibliothèque fbclient.dll.
V-B. Connexion de l'application à Firebird SQL▲
Dans cette étape, nous allons connecter l'application à la base de données et accéder aux informations de la table T_CONTACT_CON afin d'afficher ses enregistrements dans une grille de données.
Nous allons maintenant relier notre fiche à la base de données. Mais avant voici les composants à utiliser pour y arriver, ainsi que leur rôle.
TSQLConnection : il permet de gérer la connexion à une base de données.
TSQLQuery : c'est le composant qui nous permettra d'exécuter des requêtes SQL sur la base de données.
TDataSetProvider : ce composant nous permettra d'accéder aux données du TSQLQuery et de résoudre les mises à jour que l'on y aura apportées vers le serveur de base de données.
TClientDataSet : nous utiliserons ce composant pour nous permettre principalement d'afficher les données lues du serveur dans une grille. Car il faut savoir que les composants dbExpress qui nous permettent de lire les données ne nous permettent pas au même titre que les autres descendants de TDataset de naviguer dans l'ensemble de données.
TDataSource : c'est ce dernier qui sera chargé d'effectuer la liaison entre nos composants orientés données, et notre jeu de données client (ici TClientDataSet).
TDBGrid : c'est le composant orienté données que nous avons choisi. Il nous permettra d'afficher nos données sous forme de grille éditable.
Passons à présent au design de notre formulaire. Déposez une instance de chacun des composants cités ci-dessus sur notre fiche.
l'IDE Insight peut aider grandement à le faire.
Le premier composant à configurer à présent est le SQLConnexion1. Définissez sa propriété ConnectionName au nom de la connexion que nous avons créée plus haut, soit tuto_d2010fb et définissez la propriété LoginPrompt à False (cela afin de nous éviter l'apparition d'une boîte de dialogue demandant la saisie du nom d'utilisateur et du mot de passe Firebird à chaque tentative de connexion à la base de données). Si la bibliothèque cliente Firebird n'a pas été copiée dans le répertoire système, ou dans tout autre répertoire visible dans le PATH, modifiez également la propriété VendorLib pour indiquer l'emplacement du fichier fbclient.dll. Testez enfin le composant en mettant à True la valeur de sa propriété Connected.
Passons ensuite au composant SQLQuery1. On doit lui dire par quel composant SQLConnexion passer pour accéder à la base de données, pour cela définissez la propriété SQLConnection à SQLConnection1. Il faut également lui dire quelle requête SQL doit être exécutée. Pour ce faire, définir sa propriété SQL à « SELECT * FROM T_CONTACT_CON ». Le composant devra donc retourner la liste complète des contacts enregistrés dans notre table T_CONTACT_CON. Mettez à True la propriété Active de SQLQuery1 pour s'assurer que la requête est bien exécutée.
Pour le DataSetProvider1, définissez sa propriété Dataset à SQLQuery1.
Définissez également la propriété ProviderName du ClientDataSet1 à DataSetProvider1, et mettez sa propriété Active à True pour s'assurer qu'il se connecte bien au SQLQuery1 via le DataSetProvider1.
Définissez la propriété DataSet du DataSource1 à ClientDataSet1.
Enfin, mettez la propriété DataSource du DBGrid1 à DataSource1. La grille affiche alors les colonnes correspondantes à notre requête SQL, ce qui signifie que la connexion s'est établie parfaitement.
Ci-dessous, vous avez le tableau récapitulatif de la configuration des composants utilisés :
Nom du composant |
Propriété |
Valeur |
---|---|---|
SQLConnection1 |
ConnectionName |
tuto_d2010fb |
LoginPrompt |
False |
|
VendorLib |
Fbclient.dll (ou chemin d'accès complet à la bibliothèque) |
|
Connected |
True |
|
SQLQuery1 |
SQLConnection |
SQLConnection1 |
SQL |
SELECT * FROM T_CONTACT_CON |
|
Active |
True |
|
DataSetProvider1 |
Dataset |
SQLQuery1 |
ClientDataSet1 |
ProviderName |
DataSetProvider1 |
Active |
True |
|
DataSource1 |
DataSet |
ClientDataSet1 |
DBGrid1 |
DataSource |
DataSource1 |
Finalement, l'on doit avoir l'arborescence suivante dans la structure de notre fiche
Enregistrez le projet et exécutez-le.
La grille vous permet d'ores et déjà de créer et modifier des enregistrements. Néanmoins si l'on ferme et relance l'application toutes nos saisies ont disparu !
Par ailleurs, étant donné que nous avons créé un générateur pour le champ ID, nous ne devrions pas avoir à lui fournir de valeur manuellement. Cependant si vous tentez de créer une ligne sans lui fournir de valeur alors une exception requérant que le champ soit valué se déclenchera.
Qu'est-ce qu'un générateur? C'est un numéroteur unique qu'on peut associer à un champ d'une ou plusieurs tables et obtenir ainsi des numéros uniques et automatiques (on parle d'auto-incrément sous d'autres SGBD). Nous en utilisons un dans notre table pour notre clé primaire.
Pour en savoir plus consultez la Faq FirebirdLes générateurs et l'article Les générateurs purs InterbaseLes générateurs purs Interbase
Pourquoi les données ne sont-elles pas conservées ? Eh bien, tout simplement parce que notre ClientDataSet1 est un ensemble de données en mémoire ! Toutes nos manipulations sont enregistrées en mémoire et ne sont pas répercutées sur la base de données. Lorsque l'on ouvre le ClientDataSet1, celui-ci via le DataSetProvider1 obtient les données du composant SQLQuery1 et les sauvegarde en mémoire vive. Toutes nos manipulations se font uniquement dans cette sauvegarde en mémoire vive, mais ne sont pas répercutées dans la base de données.
Nous allons à présent voir comment appliquer nos modifications vers la base de données.
V-C. Application des modifications en base de données▲
Ajoutez un nouveau bouton à la fiche, changez sa propriété Caption en « Appliquer les modifications ». Double-cliquez sur le bouton pour ouvrir son gestionnaire d'évènement OnClick et saisissez ce code :
procedure
TFMain.Button1Click(Sender: TObject);
var
n: Integer
;
begin
n := ClientDataSet1.ApplyUpdates(-1
);
ShowMessageFmt('Modification(s) appliquée(s), %d erreur(s) survenue(s)'
, [n]);
end
;
Lancez le projet, enregistrez de nouveau quelques lignes et cliquez sur le bouton Appliquer les modifications. Vérifiez que les lignes ont été enregistrées en base de données en relançant de nouveau le projet.
V-D. Utilisation du générateur pour la clé primaire▲
Comme vous l'avez certainement remarqué, il faut à chaque fois spécifier une valeur pour la colonne ID qui est la clé primaire faute de quoi une exception est levée lorsque l'on veut enregistrer la ligne. Ayant pourtant créé un générateur pour cette clé primaire, l'on devrait s'attendre à ce que celle-ci soit renseignée automatiquement, au lieu de cela, on a une belle exception lorsqu'elle est absente lors de l'enregistrement.
Pour éviter l'exception et permettre d'avoir une clé générée automatiquement, nous allons modifier les propriétés du champ ID dans notre SQLQuery1.
Pour ce faire, double-cliquez sur le composant SQLQuery1, faites un menu contextuel dans la petite boîte de dialogue qui est apparue et choisissez l'option ajouter tous les champs. Ensuite, cliquez sur le champ CON_ID et mettez sa propriété Required à False.
Enregistrez et exécutez le projet, saisissez une nouvelle ligne en omettant la valeur de la colonne ID et enregistrez la ligne (en changeant de ligne tout simplement). Aucune exception n'est levée !
Néanmoins, la valeur de la colonne ID n'est pas affichée, bien qu'elle ait été générée. Pour qu'elle s'affiche, il faut relire les enregistrements à partir du serveur. Dans la section suivante, nous allons au travers d'une synchronisation avec le serveur effectuer cette opération.
Notre générateur génère des nombres à partir de 1 en s'incrémentant à chaque fois. Si dans les enregistrements saisis précédemment vous en avez un avec l'ID à 1 par exemple, l'enregistrement va lever une exception, car notre table n'autorise pas deux enregistrements avec le même ID.
V-E. Fonctionnement en mode déconnecté et enregistrement dans un fichier au format XML▲
Nous allons à présent rendre notre application indépendante de la base de données, c'est-à-dire que nous allons faire en sorte que l'on puisse continuer à faire des modifications dans notre liste de contacts, même si nous ne sommes pas connectés à la base de données. Pour cela nous utiliserons une fonctionnalité très intéressante du TClientDataSet, qui est de pouvoir enregistrer les informations qu'il a en mémoire dans un fichier. Le fichier peut être binaire ou au format XML.
La logique de notre application sera donc celle-ci : lorsque l'on ouvre l'application, l'on charge les données à partir du fichier XML. Un bouton nous permettra de faire la mise à jour des éventuelles modifications vers le serveur de base de données. Lors de la fermeture de l'application, ou lors du clic sur un bouton, on enregistrera nos données dans le fichier XML.
L'application fonctionnera donc en mode déconnecté, le seul moment où elle se connectera réellement à la base de données sera pour effectuer les mises à jour.
Mettez la propriété Connected du SQLConnection1 à False pour que l'application ne se connecte plus automatiquement à la base de données au démarrage.
Allez dans le gestionnaire de l'évènement OnCreate de la fiche et saisissez le code suivant :
procedure
TFMain.FormCreate(Sender: TObject);
begin
// charger les données du disque local
if
FileExists(ChangeFileExt(Application.ExeName, '.xml'
)) then
ClientDataSet1.LoadFromFile(ChangeFileExt(Application.ExeName, '.xml'
))
else
begin
// on n'a pas encore de fichier xml, il faut le créer
// activer le clientdataset active également le sqlquery qui à son tour
// active le sqlconnection, si l'une des étapes échoue, une exception sera
// levée
try
ClientDataSet1.Active := True
;
// sauvegarde des données lues dans un fichier xml
ClientDataSet1.SaveToFile(ChangeFileExt(Application.ExeName, '.xml'
), dfXML);
// fermeture de la connexion à la base de données
SQLConnection1.Close();
except
ShowMessage('Erreur lors de l''ouverture de la base de données'
);
end
;
end
;
end
;
Puis celui-ci dans le gestionnaire de l'évènement OnClose de la fiche :
procedure
TFMain.FormClose(Sender: TObject; var
Action: TCloseAction);
begin
// enregistrer les données sur le disque local
ClientDataSet1.SaveToFile(ChangeFileExt(Application.ExeName, '.xml'
), dfXML);
end
;
Changez la propriété Caption du bouton Button1 à « Synchroniser » et modifiez le code de son gestionnaire d'évènement OnClick ainsi :
procedure
TFMain.Button1Click(Sender: TObject);
var
n: Integer
;
begin
try
// se connecter au serveur de base de données
SQLConnection1.Open();
// synchronisation des données avec le serveur de base de données
n := ClientDataSet1.ApplyUpdates(-1
);
ShowMessageFmt('Modification(s) appliquée(s), %d erreur(s) survenue(s)'
, [n]);
// fermer et rouvrir le client dataset pour avoir les ID
ClientDataSet1.Close();
ClientDataSet1.Open();
// fermer la connexion à la base de données une fois la synchronisation effectuée
SQLConnection1.Close();
except
ShowMessage('Erreur lors de la synchronisation'
);
end
;
end
;
Ajoutez un second bouton et mettez sa propriété Caption à « Enregistrer sur le disque », puis saisissez le code suivant dans son gestionnaire d'évènement OnClick :
// enregistrer les données sur le disque local
ClientDataSet1.SaveToFile(ChangeFileExt(Application.ExeName, '.xml'
), dfXML);
Vous pouvez saisir le code comme bon vous semble, sans le mettre en forme, ensuite utilisez la combinaison de touches Ctrl+D, ou faites menu Edition - Formatter le source pour mettre en forme tout votre code source, ou juste la portion de code sélectionnée.
Compilez le projet et exécutez-le. Lors du premier lancement, l'application essaie tout d'abord de charger les données depuis le fichier XML. Si celui-ci est absent du disque, l'application se connecte à la base de données, lit les données de la table et les enregistre dans le fichier XML, puis se déconnecte de la base de données. On peut ensuite saisir ou modifier les données dans la grille, celles-ci seront conservées en mémoire jusqu'au moment où l'on va invoquer l'enregistrement sur disque dans le fichier XML en fermant l'application ou en cliquant sur le bouton enregistrer sur disque. Les données sont mises à jour sur le serveur lorsque l'on clique sur le bouton synchroniser.
V-F. Gestion des erreurs lors des mises à jour▲
Peut-être ne l'avez-vous pas encore remarqué, mais il est possible que lors de notre synchronisation sur le serveur, des données aient changé par rapport à celles que nous avons enregistrées dans notre fichier XML. Dans le cas où nous sommes les seuls à utiliser l'application, cette situation est impossible. Mais imaginez un instant que plusieurs personnes utilisent la même application, et qu'une seconde personne modifie le même enregistrement que vous. Que va-t-il se passer lors de la mise à jour ?
Le composant TClientDataSet a prévu des situations pareilles, et propose un évènement OnReconcileError pour gérer ces cas de figure. Mieux encore, Delphi dispose d'une boîte de dialogue toute prête chargée de la gestion des erreurs de réconciliation. Nous allons l'utiliser dans notre exemple.
Ajoutez recerror dans les uses de la section interface de notre unité. Puis créez un gestionnaire pour l'évènement OnReconcileError et ajoutez-y le code suivant :
procedure
TFMain.ClientDataSet1ReconcileError(DataSet: TCustomClientDataSet;
E: EReconcileError; UpdateKind: TUpdateKind; var
Action: TReconcileAction);
begin
// utiliser la boîte de dialogue de Delphi pour réconcilier les erreurs
Action := recerror.HandleReconcileError(DataSet, UpdateKind, E);
end
;
Désormais lors de la synchronisation des données, pour chaque enregistrement modifié par rapport à la copie locale, la boîte de dialogue de réconciliation apparaîtra pour vous demander quoi faire.
VI. Téléchargements▲
DBExpressFirebird.zip : les sources du projet.
create_script.sql : le script de création de la base de données du projet.
http://www.firebirdsql.org/index.php?op=files&id=engine_213 : la page de téléchargement du serveur Firebird SQL v 2.1.3.
https://downloads.embarcadero.com/free/delphi : la page de téléchargement de la version d'évaluation de delphi 2010.
VII. Conclusion▲
Tout au long de ce tutoriel, nous avons vu comment mettre facilement en œuvre une connexion à une base de données Firebird et l'utiliser grâce au tout nouveau driver dbExpress disponible avec Delphi 2010.
VIII. Remerciements▲
Un grand merci à Laurent Dardenneprofil forum de Laurent Dardenne, aityahiaprofil forum de aityahia, nono40profil forum de nono40, Franck SORIANOprofil forum de Franck SORIANO, ero-senninprofil forum de ero-sennin et Aka Guymelefprofil forum de Aka Guymelef pour leurs conseils, suggestions et corrections, sans oublier Bovinoprofil forum de Bovino pour sa relecture orthographique.