Accueil
Rechercher:
sur developpez.com sur les forums
Forums | Tutoriels | F.A.Q's | Participez | Hébergement | Contacts
Accueil Conception Java DotNET Visual Basic  C  C++ Delphi MS-Office SQL & SGBD Oracle  4D  Business Intelligence
Club Emploi Blogs   TV   Dév. Web PHP XML Python Autres 2D-3D-Jeux Sécurité Windows Linux PC Mac
ACCUEIL IB/FB FORUM IB/FB F.A.Q IB/FB TUTORIELS IB/FB OUTILS IB/FB

Utilisation de Kylix pour écrire une UDF FireBird sous Linux

Date de publication : 20/09/2005 , Date de mise a jour : 20/09/2005

Par Eric SIBERT (Site)
 

Utilisation de Kylix pour écrire une UDF (user defined function) pour Firebird sous Linux


I. Introduction
II. Ecriture de la librairie
III. Installation de la librairie sur le serveur
IV. Utilisation sous FireBird
V. Conclusion


I. Introduction

La norme SQL ne prévoit pas beaucoup de possibilitées de calculs à l'intérieur des requêtes. Interbase et FireBird, qui respectent la norme SQL d'assez près, ne fournissent pas plus de support pour les calculs. Par contre, ils disposent d'une possibilité d'extension avec l'importation de fonctions de calcul depuis des librairies externes à chargement dynamique. Il s'agit des UDF, User Defined Functions. Le terrain de prédilection de ces fonctions va être les calculs mathématiques ou les traitements de chaînes. Les fonctions seront exécutées sur le serveur, tout comme les procédures stockées. Pour ceci, ces librairies dynamiques doivent être installées sur le même ordinateur que le serveur Interbase/FireBird, en tenant compte de son système d'exploitation. Si Interbase/FireBird tourne sous Linux, la librairie devra être compilée pour Linux.

Dans la suite de cet article, je vais vous montrer comment créer et mettre en œuvre une telle librairie pour un serveur FireBird sous Linux/i386 à l'aide Kylix.

D'un point de vue pratique, j'ai utilisé un serveur  SME 6.0 qui dérive de RedHat 7.3. J'ai installé dessus FireBird 1.5.2 SuperServer (FirebirdSS-1.5.2.4731-0.rpm). Kylix 2 était installé sur une station de travail avec RedHat 9.


II. Ecriture de la librairie

Il faut écrire une librairie dynamique (.so shared object sous Linux,  DLL sous Windows). Dans mon cas, je voulais calculer la distance entre deux points à la surface de la terre en fonction de leurs latitudes/longitudes respectives. Il y a une petite formule à base de sinus et cosinus dont je vous dispense. J'ai démarré Kylix. J'ai fait Fichier|Nouveau|Autre ... Comme je n'ai pas trouvé de quoi faire une librairie, j'ai pris l'option Application console. J'ai mis le code suivant :

library geocentric; uses Math; {$APPTYPE CONSOLE} function GEO_DISTANCE(var Lat1, Long1, Lat2, Long2 : double) : double; cdecl; export; // calcul la distance entre deux points à la surface de la sphère // le résultat est en radian // à multiplier par le rayon de la sphère pour avoir une distance réelle begin result:=arccos(sin(Lat1)*sin(Lat2)+cos(Lat1)*cos(Lat2)*cos(Long2-Long1)); end; exports GEO_DISTANCE; end.
Notez que pour la première ligne, j'ai remplacé Program par Library. J'ai aussi donnée un nom (geocentric) à ma librairie et j'ai sauvé le projet avec le même nom. La fonction est exportée avec la convention cdecl. Une compilation et ma librairie est prête. Le fichier résultant s'appelle libgeocentric.so. Avec lib accolé au début du nom.


III. Installation de la librairie sur le serveur

Il faut maintenant prendre le fichier libgeocentric.so et le copier sur le serveur dans le dossier /opt/firebird/UDF/. Nous allons changer ses droits pour que l'utilisateur firebird puissent s'en sevrir et personne d'autre. On se connecte à la ligne de commande Linux en root et on exécute les instructions suivantes :

chmod 500 /opt/firebird/UDF/libgeocentric.so chown firebird /opt/firebird/UDF/libgeocentric.so chgrp firebird /opt/firebird/UDF/libgeocentric.so
Le mode 500 correspond à la lecture et l'exécution du fichier mais sans modification possible, et le tout uniquement pour le propriétaire (firebird).


IV. Utilisation sous FireBird

Pour utiliser la fonction sous FireBird, il faut commencer par la déclarer. Toujours en étant connecté sur le serveur en root, démarrez isql et connectez vous à la base où vous voulez utiliser votre fonction.

/opt/firebird/bin/isql connect waypoints.fdb user SYSDBA password 'passSysdba';
La déclaration elle-même, toujours dans isql :

DECLARE EXTERNAL FUNCTION GEO_DISTANCE DOUBLE PRECISION, DOUBLE PRECISION, DOUBLE PRECISION, DOUBLE PRECISION RETURNS DOUBLE PRECISION BY VALUE ENTRY_POINT 'GEO_DISTANCE' MODULE_NAME 'libgeocentric.so';
Il n'y a plus qu'à tester votre fonction.

SQL> select geo_distance(0.8,0.1,0.9,0.2) from rdb$database; GEO_DISTANCE ======================= 0.1197329466389183
Et ça marche ... Vous pouvez alors utiliser votre fonction où vous voulez comme dans un SELECT.

SELECT ID_WAYPOINT, GEO_DISTANCE(0.79,0.1,WP_LATITUDE,WP_LONGITUDE) AS DISTANCE FROM WAYPOINTS WHERE (GEO_DISTANCE(0.79,0.1,WP_LATITUDE,WP_LONGITUDE)<=0.01) ORDER BY 2;
Cette charmante requête va me sélectionner l'ID et la distance de tous les points GPS autour d'un point au sud de la Chartreuse (45°15'49''N/5°72'96''E), dans un rayon de 63,71 km (rayon_terre*0,01) et va me classer l'ensemble suivant la distance.


V. Conclusion

L'exemple présenté dans cet article a permis de voir comment programmer et mettre en œuvre une fonction définie par l'utilisateur pour l'utiliser dans FireBird sous Linux. C'est très simple et il ne faut pas hésiter à s'en servir si on en a besoin. Bien que je n'ai pas testé, la méthode doit s'appliquer à l'identique avec Interbase.

A priori, le même mécanisme doit être possible sous Windows avec Delphi en générant une DLL. Je n'ai pas fait d'essai. Il doit falloir remplacer cdecl par stdcall dans l'entête des fonctions. N'hésitez pas à aller voir le tutoriel sur la  création de DLL avec Delphi. A terme, je pense plutôt passer à  FreePascal d'une part parce que Kylix est une branche morte et d'autre part pour supporter une plus grande variété de serveurs et d'OS, comme FireBird lui-même et avec en ligne de mire la plateforme x86_64 qui pourraît se généraliser en serveur sous Linux et Windows. Certains ont déjà essayé avec succès d'utiliser FreePascal.

Je n'ai pas abordé le problème des chaînes de caractères renvoyées en résultat d'une fonction.  L'article qui m'a servi de support pour écrire ce didactitiel en parle longuement. Il y a quelques difficultés, analogues à celles qu'on rencontre quand une fonction d'une DLL classique écrite avec Delphi doit renvoyer une chaîne de caractères. Le tutoriel sur  Strings et PChars en Delphi aborde aussi cette difficulté et explique les fonctionnement sous-jacents.


Liste de mes articles :
Types énumérés, intervalle et ensemble
MMX avec Delphi 6 / Kylix
Préchargement de données dans le cache
MMX ( 2 ) avec Delphi 6 / Kylix
Instructions SIMD sur les réels
Internationaliser un projet Delphi
Installer D6 sous Windows 95
Tramage d'une image
Coder le PNG soi-même
Utiliser LibTiff avec Delphi
Ecrire une UDF FireBird avec Kylix


Copyright © 20/09/2005 Eric Sibert. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. Cette page est déposée à la SACD.

Responsables bénévoles de la rubrique InterBase / Firebird : qi130 et Benjamin Gagneux (yobenzen) - Contacter par EMail :
Vos questions techniques : forum d'entraide InterBase / Firebird - Publiez vos articles, tutoriels et cours
et rejoignez-nous dans l'équipe de rédaction du club d'entraide des développeurs francophones
Nous contacter - Copyright © 2000-2008 www.developpez.com - Legal informations.