mercredi 13 février 2002

MyBase


MYBASE

MyBase est une mini base de donnée fonctionnant avec le composant TClientDataSet. MyBase nécessite aucun moteur de base de donnée. MyBase utilise des fichiers xml ou binaire. Lors de son utilisation, il suffit d'inclure midas.dll sous windows ou midas.so sous linux.

Il est aussi possible de mettre MidasLib dans la clause du unit afin de ne pas être obligé de déployer les librairies mentionné ci-haut.MyBase fonctionne sous windows et linux, son utilisation peut donc s'avérer très intéressante.

Afin de faciliter la compréhension de MyBase, nous allons créer un programme fort simple de gestion de courriel pour des écoles. Nous verrons ainsi les relations maitre-détails. Chaque courriel sera associé à une école.

Préparation de la bd

A partir de l'onglet "accès bd, déposé sur la fiche 2 TDataSource et 2 TClientDataSet.


Inscriver à la propriété name d'un TClientDataSet cdsEcole pour l'autre inscriver cdsCourriel. Ensuite pour les TDataSource inscriver pour leur nom dsEcole et pour l'autre dsCourriel.


Ensuite relier le TDataSource au TClientDataSet grâce à sa propriété dataset. Pour dsEcole, choisisé cdsEcole faite de même pour dsCourriel.



Création d'une base de donnée

Maintenant nous allons créer les champs pour chaque clientdataset. cdsEcole aura un champ NoEcole et Ecole. cdsCourriel aura un champ courriel et noecole.
  • Sélectionner cdsCourriel, faite un click droit de la souris dessus. Cliquer sur "Editeur de champs..."

  • Faite une click droit de la souris dans la fenêtre blanche qui apparaît et cliquer sur Nouveau champ


  • Inscriver NoEcole dans la case Nom, la case Composant s'inscrit automatiquement. Pour ce champ, nous allons sélectionner le type AutoInc. Le système se chargera d'attribuer à chaque ajout une nouvelle valeur à ce champ. Pour le champ Ecole et courriel, sélectionner le type string et inscriver 25 dans la case taille.


  • Faite un click droit de la souris sur cdsEcole, cliquer sur "Créer un ensemble de donnée". Ensuite cliquer sur "Enregistrer dans une table Xml MyBase..." et tapé ecole comme nom de base de donnée. Faite de même pour cdsCourriel et nommer sa base de donnée courriel.

  • A la propriété de cdsEcole inscriver le nom de la base de donnée que vous avez créer précédemment: ecole.xml pour cdsEcole et courriel.xml pour cdsCourriel.


Nous allons maintenant permettre d'ajouter des écoles. Pour ce faire, déposer 1 TBouton et 1 TEdit sur la fiche.




Dans la propriété click du bouton pour ajouter une école, nous allons ajouter quelques instructions.

procedure TMyBase.cmdEcoleClick(Sender: TObject);
begin
  if txtEcole.text <> '' then 
  begin
    cdsEcole.Insert;
    cdsEcole.FieldByName('Ecole').AsString; := txtEcole.Text;
    cdsEcole.Post;
    txtEcole.Text := '';
  end;
end;
Insert, permet d'ajouter un enregistrement vide.

La deuxième instruction copie la valeur du TEdit dans le champ courant Ecole. La propriété FieldByName permet de trouver un champ par son nom. On peut ainsi leur affecter des valeurs.

Il est aussi possible d'y accéder par un index. Je vous conseille vivement d'aller regarder les nombreuses propriétés des TClientDataSet.

Post envoit les enregistrements dans un journal de modification. Les données ne seront écrites dans le fichier xml que lorsqu'on appellera la méthode mergechangelog.

Nous allons ajouter un TDBLookupComboBox à la fiche. Ce composant permettra de voir toutes les écoles disponibles.





La propriété "ListSource", permet d'établir la source de donnée qui remplira la TDBLookupListBox.

La propriété "ListField" correspond aux champs qui seront affichés dans la TDBLookupListBox. Il est possible d'en afficher plusieurs en les séparants par un ";". Il aurait donc été possible d'afficher le champ NoEcole et Ecole par l'instruction "NoEcole;Ecole".

La propriété "KeyField" sera utile lorsqu'on établira le lien pour effectuer la relation maitre/détail.Nous en parlerons en détail un peu plus loin.

Dans l'évènement AfterPost de cdsEcole, nous pouvons ajouter "cdsEcole.MergeChangeLog;". Ainsi les ajouts, modification, suppression qui auront été notés dans le journal de modification sont appliqué au fichier xml en appelant la méthode MergeChangeLog.

Après avoir ajouté quelques écoles, voici le résultat





Nous allons maintenant nous attaquer au courriel. Poser un dbgrid sur la fiche ainsi qu'un bouton. Modifiez la propriété datasource du dbgrid pour dsCourriel.
Dans la propriété click du bouton pour ajouter des adresses courriels, nous allons ajouter quelques instructions.

procedure TMyBase.cmdCourrielClick(Sender: TObject);
begin
  if cdsCourriel.state in [dsInsert, dsEdit] then cdsCourriel.Post;
end;

Puisque nous utilisons un composant lié directement avec une base de donnée, nous devons vérifier dans quel état est le clientdataset avant de faire un post. Si nous n'effectuons pas une vérification et que le clientdataset ne serait pas en mode insertion ou modification, il y aurait un message d'erreur qui s'afficherait. Cette vérification n'était pas nécessaire tantôt puisqu'on appelait la méthode insert, on attribuait une valeur au champ et finalement on appelait la méthode post. En liant le dbgrid au clientdataset beaucoup de travail est fait pour nous.

Dans l'évènement AfterPost de cdsCourriel, nous pouvons ajouter "cdsCourriel.MergeChangeLog;". Ainsi les ajouts, modification, suppression qui auront été noté dans le journal de modification sont appliqués au fichier xml en appelant la méthode MergeChangeLog.

Nous pouvons dès maintenant débuter à ajouter des courriels, mais ils ne seront pas lié à une école automatiquement.

Relation maitre/détail

Établir une telle relation est assez facile.
1) Sélectionner cdsCourriel, inscrivé dsEcole pour sa propriété MasterSource





2) Cliquer sur la propriété MasterFields. C'est ici qu'on va établir la relation maitre(ecole), détail (courriel)





Maintenant après avoir sélectionné une école, lorsque vous entrez un courriel le champ noecole sera lié. Ceci est dû à la propriété KeyField du TDBLookupListBox.

À partir de ce moment, lorsque vous sélectionnerez une école, seul les courriels qui y sont lié seront affichés.

Vous pouvez visionner le contenu des fichier xml en tout temps à l'aide d'un navigateur web.
Vous pouvez télécharger les sources du projet ici.

dimanche 3 février 2002

Exception

EXCEPTION
Tout programme n’est pas à l’abri d’erreurs : valeur erronée, fichier introuvable, type de donnée incompatible... Se mettre dans la peau d’un usager aide à voir le type d’erreur qu’il pourrait faire. On doit gérer les erreurs d'un programme avec les exceptions, même s'il est possible de le faire autrement.
Répondre aux exceptions
Lorsqu'une exception survient, l'application lève une exception. On peut ainsi exécuter une partie de code fonctionnel et détruirel'erreur.
Certaine ressources devraient toujours être protégées
  • Les fichiers
  • La mémoire
  • Les ressources de Windows ou de Linux
  • Les objets
La syntaxe des traitements des exceptions est simple

try avec except


try
  instruction
except
  on TypeException do begin
  instruction
end;
end;

Le mot try débute le bloc d’exception, on inscrit les instructions voulues. Si durant le 
déroulement du programme une exception de type TypeException est levé, les instructions de ce 
bloc seront exécutées 

try avec finally

Quoiqu'il arrive dans le déroulement du programme, le code contenu dans le bloc finally sera exécuté s'il y a une erreur ou non
try
   instruction
finally
   instruction
end;

var
  bit:tbitmap;
begin
  try
    bit  := tbitmap.Create;
  finally
    bit.free;
  end;
end;

Librairie d'exécution

Lorsqu'on utilise les librairies d'exécution (rtl)comme les fonctions, les procédures de fichiers, les conversions..., les rtl reportent les erreurs à l'application sous la forme d'exception. Un message généré à l'usager lui sera affiché. On peut définir nos propres exceptions lorsqu'on fait appel à ce type de librairie.

begin
  try
    Result:=Dividende div Diviseur;
  except
    on EDivByZero do
    begin
      result:=0;
      showMessage('Division par zéro impossible');
    end;
  end;
end;
On pourrait arriver aux mêmes résultats en utilisant un if, mais l'utilisation des exceptions est beaucoup plus efficace.
Code source disponible ici.

Définir ses exceptions

Afin de sécuriser nos applications contre d'éventuelles erreurs, on peut créer nos propres exceptions afin de les prévenir. Les exceptions sont des objets, alors nous devons les déclarer comme un objet.

type
   EMotInvalide = class(Exception);
Après avoir déclaré notre exception, on peut l'appeler à tout moment. On doit employer le mot raise pour appeler l'exception.
if Mot == MotInvalide then 
   raise EMotInvalide.create('Mot invalide');

Les exceptions silencieuses

Les applications de Delphi manipulent la plupart des exceptions que votre code ne manipule pas spécifiquement en affichant un message d'erreur. Il est possible d'arriver au même résultat en utilisant les exceptions dites silencieuses, qui n'afficheront pas de message d'erreur à l'usager. Ce type d'exception est particulièrement intéressante, lorsqu'un veut arrêter une partie d'un programme.

Pour ce faire, on utilise la procédure Abort;