Section courante

A propos

Section administrative du site

Travailler avec une base de données

Interface IRdbms

L'interface IRdbms n'est qu'un enveloppe léger pour le paquet SQLdb de Free Pascal. Les systèmes RDBMS actuellement pris en charge sont :

Création d'une connexion à la base de données

MySQL

  1. Var db:IRdbms;
  2. ...
  3. db := TMySQLDb.create('MySQL 5.7');
  4. db.connect('localhost', 'your_db_name','your_db_username','yoursecretpassword',3306);

Cela ouvrira la connexion à la base de données vers le serveur MySQL 5.7 sur l'hôte local sur le port 3306.

Remplacez 5.7 par votre version de MySQL, par exemple 5.5 pour vous connecter au serveur de base de données MySQL 5.5. Veuillez noter que la chaîne de caractères MySQL 5.7 est comparée sans distinction de casse. MySQL 5.7 ou mysql 5.7 sont donc identiques.

PostgreSQL

  1. Var db:IRdbms;
  2. ...
  3. db := TPostgreSqlDb.create();
  4. db.connect('localhost', 'your_db_name', 'your_db_username', 'yoursecretpassword', 5432);

Il ouvrira la connexion à la base de données au serveur PostgreSQL sur l'hôte local sur le port 5432.

Firebird

  1. var db:IRdbms;
  2. ...
  3. db := TFirebirdDb.create();
  4. db.connect('localhost', 'your_db_name', 'your_db_username', 'yoursecretpassword', 3050);

Il ouvrira la connexion à la base de données au serveur Firebird sur l'hôte local sur le port 3050.

SQLite

Le SQLite est un moteur de base de données léger non client-serveur. Vous pouvez donc laisser l'hôte, le port, le nom d'utilisateur et le mot de passe vides. Le nom de la base de données doit être défini sur le chemin où le fichier de base de données est entreposé.

  1. Var db:IRdbms;
  2. ...
  3. db:=TSQLiteDb.create();
  4. db.connect('', 'your_data.db', '', '', 0);

Cela ouvrira la base de données étant entreposée dans votre your_data.db.

ODBC

Si vous utilisez une base de données n'étant pas encore prise en charge directement par la bibliothèque sqldb de Free Pascal, vous pouvez utiliser une connexion ODBC. La classe TOdbcDb est un enveloppe léger pour la classe TODBCConnection implémentant l'interface IRdbms.

Par exemple, si vous avez /etc/odbcinst.ini avec le contenu suivant :

[my-mariadb-odbc-driver]
Description = MariaDB Connector/ODBC v.3.0
Driver = /usr/lib/libmaodbc.so

et le contenu de /etc/odbc.ini :

[my-app-db]
Description=Ma base de données d'applications
Driver=my-mariadb-odbc-driver
SERVER=localhost
PORT=3306
USER=<votre nom d'utilisateur>
PASSWORD=<votre mot de passe>
DATABASE=<nom de la base de données>

Pour vous connecter à la base de données à l'aide de my-app-db DSN, définissez le paramètre de base de données avec le nom du DSN comme suit :

  1. Var db:IRdbms;
  2. ...
  3. db:=TOdbcDb.create();
  4. db.connect('', 'my-app-db', '', '', 0);

Si vous souhaitez modifier la valeur, par exemple pour utiliser un port différent de celui défini dans /etc/odbc.ini, remplissez simplement le paramètre de port avec la valeur souhaitée :

  1. Var db:IRdbms;
  2. ...
  3. db:=TOdbcDb.create();
  4. db.connect('', 'my-app-db', '', '', 3307);

Enregistrement d'une instance IRdbms dans un conteneur de dépendances

Vous pouvez enregistrer une instance IRdbms dans un conteneur de dépendances afin de pouvoir accéder facilement à son instance.

  1. Var container:IDependencyContainer;
  2. ...
  3. container.add(
  4.     'db',
  5.     TMysqlDbFactory.create(
  6.         'mysql 5.7',
  7.         'localhost',
  8.         'your_db_name',
  9.         'your_db_username',
  10.         'yoursecretpassword',
  11.         3306
  12.     )
  13. );

Remplacez TMysqlDbFactory par TPostgreSqlDbFactory, TFirebirdSqlDbFactory, TSQLiteDbFactory, TOdbcDbFactory pour PostgreSQL, Firebird, base de données SQLite et ODBC respectivement.

Pour TOdbcDbFactory, en utilisant ODBC avec DSN, vous pouvez vous inscrire simplement en utilisant son nom DSN par exemple :

  1. container.add(
  2.     'db',
  3.     TOdbcDbFactory.create()
  4.         .database('my-app-db')
  5. );

Récupérer l'instance IRdmbs à partir du conteneur de dépendances

Pour obtenir l'instance d'IRdbms, récupérez-la simplement à partir du conteneur de dépendances comme indiqué dans le code suivant :

  1. var db:IRdbms;
  2. ...
  3. db:=container.get('db') as IRdbms;

ou avec une syntaxe de type tableau :

  1. var db:IRdbms;
  2. ...
  3. db:=container['db'] as IRdbms;

Exécution d'une requête SQL

  1. Var
  2.     db:IRdbms;
  3.     resultSet:IModelResultSet;
  4. ...
  5. resultSet := db.prepare('SELECT * FROM users').execute();

Contrairement à SQLdb séparant la manière dont vous exécutez les commandes SQL renvoyant un ensemble de résultats et celles ne renvoyant pas d'ensemble de résultats telles que open() pour SELECT et execSQL() pour INSERT ou UPDATE, l'interface IRdbms fait abstraction de cela, vous appelez donc toujours la méthode execute() pour SELECT, INSERT ou UPDATE :

  1. fRdbms.prepare(
  2.     'INSERT INTO atable ' +
  3.     '(id, operation, resetTimestamp) VALUES ' +
  4.     '(:idCol, :oprCol, :resetTmp)'
  5. ).paramStr('idCol', 'abc')
  6. .paramInt('oprCol', 10)
  7. .paramInt('resetTmp', 2000)
  8. .execute();

Passer des paramètres à une requête SQL

Pour éviter l'injection SQL, il est recommandé d'utiliser une instruction préparée avec un paramètre :

  1. resultSet := db.prepare('SELECT * FROM users WHERE user_email = :userEmail')
  2.     .paramStr('userEmail', 'smaltais@gladir.com')
  3.     .execute();

Pour transmettre des données de type entier, flottant ou date/heure, utilisez respectivement paramInt(), paramFloat() et paramDateTime().

Obtenir le nombre total de lignes dans l'ensemble de résultats

  1. Var totData:Integer;
  2. ...
  3. totData:=resultSet.resultCount();

Lire les données à partir de l'ensemble de résultats

  1. Var userId:Integer;
  2.     userEmail:String;
  3. ...
  4. userId:=resultSet.fields().fieldByName('user_id').asInteger;
  5. userEmail:=resultSet.fields().fieldByName('user_email').asString;

Avancer le curseur jusqu'à la position suivante

fields() lira les données à la position actuelle du curseur. Pour lire les données suivantes dans l'ensemble de résultats, il est nécessaire d'appeler next() pour avancer la position du curseur :

  1. resultSet.next();

Testez si à la fin de l'ensemble de résultats

La méthode fieldByName() génère une exception si vous essayez de lire des données lorsque le curseur est à la fin du fichier. Pour l'éviter, vous devez vérifier la condition de fin de fichier avec eof(). Donc, pour lire toutes les données de l'ensemble de résultats, vous avez besoin de la boucle suivante :

  1. While Not resultSet.eof() do Begin
  2.     userId:=resultSet.fields().fieldByName('user_id').asInteger;
  3.     //Faire quelque chose avec l'identificateur utilisateur
  4.     resultSet.next();
  5. End;

Exécution de la transaction

  1. db.beginTransaction();
  2. Try
  3.     //effectuer plusieurs opérations de base de données
  4. Finally
  5.     db.commit();
  6. End;

Ce qui peut mal se passer

Il se peut que certaines choses ne fonctionnent pas en raison d'une bibliothèque manquante, par exemple si vous n'avez pas installé la bibliothèque cliente MySQL ou la bibliothèque cliente ODBC.



Dernière mise à jour : Vendredi, le 18 octobre 2024