Interbase Borland Data Provider - John COLIBRI. |
- abstract:utilisation du Borland Data Provider sous Windows Forms pour gérer en Delphi 8 des données Interbase
- mots clé:BDP - Borland Data Provider - .Net SDK - Windows Forms -
Delphi 8 - Interbase - Firebird
- logiciel utilisé: Windows XP, Delphi 8, Interbase 6
- matériel utilisé: Pentium 1.400Mhz, 256 M de mémoire
- champ d'application: Delphi 8 sur Windows, Interbase, Firebird
- niveau: débutant Delphi et Base de Données
- plan:
1 - Introduction J'ai choisi de présenter à Borcon 2004 les différents moyens d'utiliser Interbase:
- pour Delphi 5 à 6, les API, le BDE et Sql Links, Interbase Express, dbExpress et Ado
- pour Delphi 8:
- en mode VCL.Net, dbExpress.Net, Ibx.Net
- en mode Windows Forms, Ado.Net et le BDP
Cet article va se concentrer sur le mode Windows Forms et le Borland Data Provider.
Pour les autres façons d'utiliser Interbase, vous pouvez consulter sur ce site: - le tutorial interbase: comment utiliser des bases
de données en mode Client Serveur (Delphi 6, Ibx). L'article d'initiation le plus complet
- Interbase dbExpresss: le mode dbExpress
(Delphi 6, dbExpress). Le mode qui permet le mieux de comprendre l'architecture Ado.Net qui en est directement issue
- Interbase Ibx.Net: le portage sous .Net de la mécanique Ibx (Delphi 8, Ibx.Net). Le moyen le plus simple d'utiliser
Interbase et Delphi 8. Contient aussi un comparatif de toutes ces architectures avec les schémas correspondants
- Interbase dbExpress.Net: le portage sous .Net de la mécanique dbExpress (Delphi 8, dbExpress.Net). L'utilisation
des techniques VCL pour Interbase ET pour les autres serveurs (Oracle, Sql Server, MyBase etc)
Nous nous adressons pour cet article à un programmeur Delphi ayant une idée
élémentaire de Delphi: Palette, Inspecteur, OnClick. Tout le reste sera expliqué. Nous supposons: - que Delphi 8 est installé (la version "développeur": pas la version
"étudiant" qui n'a pas les bases de données, et pas besoin de la version "Entreprise" ou "Architecte", mais tout marche aussi avec ces deux dernières)
- qu'Interbase est installé (voyez le tutorial interbase qui détaille cette installation). J'ai utilisé la version
Interbase 6 que j'ai installée et que j'utilise couremment avec Delphi 6, mais tout fonctionne bien sûr avec les versions 7 et FireBird.
2 - Architecture
Une fois les librairies .Net installées, nous pouvons utiliser des Serveurs de bases de données en utilisant une couche appelée Ado.Net. Cette couche définit des composant pour communiquer avec des "sources de données". Ces
sources sont très générales: des courriers Outlook, des données Excel et des données provenant d'un Serveur Sql. Pour les bases de données, Ado.Net permet de gérer: - de façon native
- "Sql Data Provider" pour Sql Server
- en ajoutant des modules supplémentaires, d'autres bases de données:
- pour Oracle, le module "Oracle Data Provider"
- pour les serveurs pour lesquels existe un pilote ODBC, le module "ODBC Data Provider"
- pour les serveurs ayant un pilote OleDb COM, le module "OleDb Data Provider"
- le module "Borland Data Provider" qui est un provider générique pour plusieurs serveurs, tels que Sql Server, Oracle, DB2, FireBird et Interbase.
Pour accéder à Interbase, nous pouvons donc: - acheter un pilote ODBC (EasySoft)
- acheter un pilote OleDb (IbProvider)
- utiliser le BDP fourni avec Delphi 8
Notez aussi que le BDP est un module .Net général: il peut être utilisé avec n'importe quel langage qui communique avec les librairies .Net (Delphi 8, bien sûr, mais aussi les autres langages via les divers outils de
développement). L'architecture générale a donc l'allure suivante:
3 - La connection 3.1 - Préparation
Le BDP ne sait pas créer de base vierge. Seul Ibx, en mode Delphi 6, ou Ibx.Net en mode Delphi 8 peuvent le faire. Nous allons donc utiliser une
base créée auparavant, en la copiant dans un répertoire proche pour éviter de la rechercher nichées dans des répertoires dépendant de chaque installation. Nous allons: |
créer un répertoire _DATA au même niveau que nos sources (dans n'importe quel répertoire qui vous convient) | |
copier une base Interbase dans ce répertoire. Par exemple INSTITUT_PASCAL.GDB provenant de nos tutoriaux antérieurs, ou EMPLOYEE.GDB provenant de "FICHIERS COMMUNS" etc |
| renommer cette base INSTITUT_PASCAL_5.GDB | 3.2 - La connection Commençons par nous connecter à note base Interbase:
| lancez Delphi 8 | |
créez une nouvelle application en cliquant "Fichiers | Nouveau | Windows Forms" et renommez-la "p_ib_bdp_connection" | |
dans la page "Borland Data Provider" sélectionnez un BdpConnection: et posez-le sur le Forme |
| comme d'habitude, le BdpConnection est affiché sous la Windows Forms: |
| sélectionner BdpConnection1, et avec un Click droit souris, ouvrez l'Editeur de Connections. Par défaut il affiche les propriétés du serveur DB2:
| | tapez les propriétés de notre base:
- sélectionnez le pilote IbConn1
- tapez le chemin
_DATA\INSTITUT_PASCAL_5.GDB - testez la connection en cliquant "Test"
Si le chemin et le nom de la base sont corrects, un dialogue "Connection
Successful" apparaît. Fermez-le - fermez le dialogue de connection en cliquant "OK"
Notez que - j'ai eu le plaisir de voir que le "UserName" et "Password" sont déjà
remplis, et que le LoginPrompt est False par défaut. Passer sa journée, sur sa propre machine, à taper les sempiternels "SYSDBA" et "masterkey" n'est pas particulièrement productif.
- le dialecte 3 est déjà initialisé (nous avons créé notre base avec ce dialecte).
| |
Delphi a rempli les propriétés ConnectionString et ConnectionOptions dans l'Inspecteur d'Objet: - ConnectionString contient:
assembly=Borland.Data.Interbase, Version=1.5.0.0,
Culture=neutral, PublicKeyToken=91d62ebb5b0d1b1b; vendorclient=gds32.dll; database=..\_data\INSTITUT_PASCAL_5.GDB;
provider=Interbase; username=sysdba; password=masterkey | - ConnectionOption contient:
waitonlocks=False; commitretain=False; sqldialect=3;
transaction isolation=ReadCommitted; servercharset=; rolename=myrole | |
4 - Créer et remplir une Table 4.1 - Principe Nous allons créer une table contenant pour chaque formation: - un code (par exemple 8)
- un nom (par exemple "Delphi Interbase")
- le nombre de jours (par exemple 3)
- un prix (par exemple 1.400)
La syntaxe de la requête SQL à envoyer vers le Server est la suivante:
CREATE TABLE formations_5 (f_numero INTEGER, f_nom CHARACTER(23), f_jours
INTEGER, f_prix NUMERIC(5, 2) ) | Pour envoyer cette requête vers le Serveur:
- nous utilisons un BdpConnection qui assurera la connection vers le Serveur
- nous créons un objet BdpCommand en utilisant:
my_c_bdp_command:= my_c_bdp_connection.CreateCommand;
- nous remplissons la requête par:
my_c_bdp_command.CommandText:= 'CREATE etc'; - nous envoyons la requête vers le Serveur par:
my_c_bdp_command.ExecuteNonQuery; Nous pouvons aussi ajouter des transactions pour encadrer cette création.
Donc:
| créez une nouvelle application Windows Forms et appelez-la "p_ib_bdp_create_table" | |
posez un Button, appelez-le "create_", créez son événement OnClick et tapez les instructions de création de table:
const k_database_file= '..\_data\INSTITUT_PASCAL_5.GDB';
k_table_name= 'formations_5';
k_connection_string= 'assembly=Borland.Data.Interbase, Version=1.5.0.0, '
+ 'Culture=neutral,PublicKeyToken=91d62ebb5b0d1b1b;vendorclient=gds32.dll;'
+ 'database='+ k_database_file+ ';'
+ 'provider=Interbase;username=sysdba;password=masterkey';
k_sql_create= 'CREATE TABLE '+ k_table_name
+ ' (f_id INTEGER, f_name CHAR(28), f_days INTEGER, f_price DOUBLE PRECISION )';
procedure TWinForm.create_transaction__Click(sender: System.Object; e: System.EventArgs);
var l_c_bdp_connection: BdpCOnnection;
l_c_bdp_transaction: BdpTransaction;
l_c_bdp_command: BdpCommand; begin
try try
l_c_bdp_connection:= BdpConnection.Create(k_connection_string);
Include(l_c_bdp_connection.StateChange, BdpConnection1_StateChange);
l_c_bdp_connection.Open;
l_c_bdp_transaction:= l_c_bdp_connection.BeginTransaction;
l_c_bdp_command:= l_c_bdp_connection.CreateCommand;
l_c_bdp_command.CommandText:= k_sql_create;
l_c_bdp_command.Connection:= l_c_bdp_connection;
l_c_bdp_command.Transaction:= l_c_bdp_transaction;
l_c_bdp_command.ExecuteNonQuery; finally
l_c_bdp_transaction.Commit;
l_c_bdp_connection.Close; end;
except
on e:exception do
begin l_c_bdp_transaction.RollBack;
display_bug_stop(e.Message);
end; end; // try ... except
end; // create_transaction__Click | | |
compilez, exécutez, et cliquez le bouton |
Dans la foulée, nous pouvons effacer la même table avec la requête Sql suivante: Donc: |
placez un autre tButton sur la Forme, nommez-le "drop_table" et placez-y la requête de suppression:
const k_sql_drop= 'DROP TABLE '+ k_table_name;
procedure TWinForm.drop_transaction__Click(sender: System.Object; e: System.EventArgs);
var l_c_bdp_connection: BdpCOnnection;
l_c_bdp_transaction: BdpTransaction;
l_c_bdp_command: BdpCommand; begin
try try
l_c_bdp_connection:= BdpConnection.Create(k_connection_string);
Include(l_c_bdp_connection.StateChange, BdpConnection1_StateChange);
l_c_bdp_connection.Open;
l_c_bdp_transaction:= l_c_bdp_connection.BeginTransaction;
l_c_bdp_command:= l_c_bdp_connection.CreateCommand;
l_c_bdp_command.CommandText:= k_sql_drop;
l_c_bdp_command.Connection:= l_c_bdp_connection;
l_c_bdp_command.Transaction:= l_c_bdp_transaction;
l_c_bdp_command.ExecuteNonQuery; finally
l_c_bdp_transaction.Commit;
l_c_bdp_connection.Close; end;
except
on e:exception do
begin l_c_bdp_transaction.RollBack;
display_bug_stop(e.Message);
end; end; // try ... except
end; // drop_transaction__Click |
| |
compilez, exécutez, et cliquez le bouton |
Vous pouvez télécharger le sources du projet "win_bdp_create_table.zip".
4.2 - Vérifier la création
Nous pouvons vérifier que la création a été effectuée en utilisant la fonction GetMetaData de BdpConnection. La technique est similaire à celle utilisée par tSession.GetTableNames du temps de l'antique BDE. Dans notre cas:
| créez une nouvelle application en cliquant "Fichiers | Nouveau | Windows Forms" et renommez-la "p_win_bdp_metadata" |
| posez une ListBox sur la Forme | |
posez un Button, nommez-le "table_", créez son événement OnClick qui va afficher dans ListBox1 le nom des tables:
procedure TWinForm.tables_Click(sender: System.Object; e: System.EventArgs);
var l_c_bdp_connection: BdpCOnnection;
l_c_data_table: DataTable;
l_table_index: integer; begin try
Datagrid1.DataSource:= nil;
l_c_bdp_connection:= BdpConnection.Create(k_connection_string);
Include(l_c_bdp_connection.StateChange, BdpConnection1_StateChange);
l_c_bdp_connection.Open; try
l_c_data_table:= l_c_bdp_connection.GetMetaData.GetTables('',
Borland.Data.Schema.TableType.Table);
DataGrid1.DataSource:= l_c_data_table;
ListBox2.Items.Clear;
for l_table_index:=0 to l_c_data_table.Rows.Count-1 do
ListBox2.Items.Add(l_c_data_table.Rows[l_table_index].Item['TableName']);
finally l_c_bdp_connection.Close;
end; except
on e:exception do
DataGrid1.CaptionText:= e.Message;
end; // try ... except end; // tables_Click |
| | posez un DataGrid sur la Forme |
| sélectionnez ListBox1, créez son événement MouseDown et affichez le contenu de la table sélectionnée:
procedure TWinForm.ListBox2_MouseDown(sender: System.Object; e: System.Windows.Forms.MouseEventArgs);
var l_c_bdp_connection: BdpCOnnection;
l_c_data_table: DataTable;
l_table_name: String; begin
try Datagrid1.DataSource:= nil;
Text:= k_database_file;
l_c_bdp_connection:= BdpConnection.Create(k_connection_string);
Include(l_c_bdp_connection.StateChange, BdpConnection1_StateChange);
l_c_bdp_connection.Open; try
l_table_name:= ListBox2.Items[ListBox2.SelectedIndex].ToString;
l_c_data_table:= l_c_bdp_connection.GetMetaData.GetColumns(l_table_name,
'', Borland.Data.Schema.ColumnType.Unknown);
DataGrid1.DataSource:= l_c_data_table;
finally l_c_bdp_connection.Close;
end; except
on e:exception do
DataGrid1.CaptionText:=e.Message;
end; end; // ListBox2_MouseDown | |
| compilez et exécutez. Cliquez "table_" et cliquez "FORMATIONS_5" | |
voici le résultat: |
5 - Ajouter des Données Pour ajouter un enregistrement
3, Interbase Delphi l'instruction SQL à exécuter est: INSERT INTO formations
(f_numero, f_nom) VALUES (3, 'Interbase Delphi') |
Créons une nouvelle application pour pouvoir ajouter quelques lignes: | créez une nouvelle application Windows Forms et appelez-la
"p_win_bdp_insert_data" | | posez un Button, appelez-le "insert_", créez son événement OnClick et tapez les instructions qui inséreront une ligne:
const k_sql_insert=
'INSERT INTO '+ k_table_name
+ ' (f_id, f_name, f_days, f_price)'
+ ' VALUES (3, ''Delphi Interbase'', 3, 1400)';
procedure TWinForm.insert_Click(sender: System.Object; e: System.EventArgs);
var l_c_bdp_connection: BdpCOnnection;
l_c_bdp_command: BdpCommand; begin
try try
l_c_bdp_connection:= BdpConnection.Create(k_connection_string);
Include(l_c_bdp_connection.StateChange, BdpConnection1_StateChange);
l_c_bdp_connection.Open;
l_c_bdp_command:= l_c_bdp_connection.CreateCommand;
l_c_bdp_command.CommandText:= k_sql_insert;
l_c_bdp_command.ExecuteNonQuery; finally
l_c_bdp_connection.Close; end;
except
on e:exception do
display_bug_stop(e.Message);
end; // try ... except end; // insert_Click |
| | compilez, exécutez, et cliquez le bouton |
Nous pouvons automatiser ces ajouts en paramétrant la procédure qui envoie les valeurs littérales. Voici un exemple: |
posez un Button, appelez-le "insert_several_", créez son événement OnClick et tapez les instructions qui inséreront plusieurs lignes:
procedure TWinForm.insert_several__Click(sender: System.Object; e: System.EventArgs);
var l_c_bdp_connection: BdpCOnnection;
l_c_bdp_command: BdpCommand;
procedure insert_generic(p_number: Integer; p_name: String;
p_days: Integer; p_price: Double);
var l_sql_text: String; begin
DecimalSeparator:= '.'; l_sql_text:=
'INSERT INTO '+ k_table_name
+ ' (f_id, f_name, f_days, f_price)'
+ ' VALUES '
+ ' ('
+ IntToStr(p_number)+ ', '+ QuotedStr(p_name)+ ', '
+ IntToStr(p_days)+ ', '+ FloatToStr(p_price)
+ ' )';
DecimalSeparator:= ','; display(l_sql_text);
l_c_bdp_command.CommandText:= l_sql_text;
Try l_c_bdp_command.ExecuteNonQuery;
Except
on e: Exception do
display(' *** pb_insert '+ e.Message);
end; end; // insert_generic
begin // insert_several__Click try
try
l_c_bdp_connection:= BdpConnection.Create(k_connection_string);
Include(l_c_bdp_connection.StateChange, BdpConnection1_StateChange);
l_c_bdp_connection.Open;
l_c_bdp_command:= l_c_bdp_connection.CreateCommand;
insert_generic(1, 'Initiation Delphi', 3, 1400.40);
insert_generic(2, 'Bases de Données Delphi', 3, 1400);
insert_generic(3, 'Interbase Delphi', 3, 1400);
insert_generic(4, 'Composants Delphi', 3, 1400);
insert_generic(5, 'UML et Patterns Delphi', 3, 1400);
insert_generic(6, 'Delphi Asp', 3, 1400); finally
l_c_bdp_connection.Close; end;
except
on e:exception do
display_bug_stop(e.Message);
end; // try ... except end; // insert_several__Click
| | | compilez, exécutez, et cliquez le bouton |
6 - Lire et Afficher 6.1 - Affichage par code Nous allons maintenant afficher les données. Une première technique consiste à lire les données en utilisant un DataReader.
Plaçons cet affichage dans le projet précédent: | posez un Button, appelez-le "select_", créez son événement OnClick et
tapez les instructions qui afficheront les lignes dans un TextBox:
procedure TWinForm.select__Click(sender: System.Object; e: System.EventArgs);
var l_c_bdp_connection: BdpConnection;
l_c_bdp_command: BdpCommand;
l_c_data_reader: BdpDataReader;
l_field_index: Integer; l_line: String;
l_formatted_value: String; begin
try try
l_c_bdp_connection:= BdpConnection.Create(k_connection_string);
Include(l_c_bdp_connection.StateChange, BdpConnection1_StateChange);
l_c_bdp_connection.Open;
l_c_bdp_command:= l_c_bdp_connection.CreateCommand;
l_c_bdp_command.CommandText:= k_sql_select;
l_c_data_reader:= l_c_bdp_command.ExecuteReader;
while l_c_data_reader.Read do
begin l_line:= '';
for l_field_index:= 0 to l_c_data_reader.FieldCount- 1 do
begin
l_formatted_value:= l_c_data_reader.GetValue(l_field_index).ToString;
Case l_field_index of
0 : l_formatted_value:= Format('%-3s', [l_formatted_value]);
1 : l_formatted_value:= Format('%-28s', [l_formatted_value]);
2 : l_formatted_value:= Format('%-3s', [l_formatted_value]);
3 : l_formatted_value:= Format('%-6s', [l_formatted_value]);
end; // case
l_line:= l_line+ l_formatted_value+ '|'
end; // for all fields
display(l_line);
end; // while Read Finally
l_c_data_reader.Close;
End; // try ... finally Except
On e: Exception do
display('*** '+ e.Message)
end; // try ... except display('< select');
end; // select__Click | | |
compilez, exécutez, et cliquez le bouton | | voici le résultat: |
6.2 - Affichage en mode conception Nous allons aussi utiliser des composants posés sur la Forme au lieu d'utiliser la création dynamique par code:
| créez une nouvelle application Windows Forms et appelez-la "p_win_bdp_select" | | connectez le Serveur:
- dans la page "Borland Data Provider" sélectionnez un BdpConnection et posez-le sur le Forme
- sélectionner BdpConnection1, et avec un Click droit souris, ouvrez l'Editeur de Connections
- sélectionnez le pilote IbConn1
- tapez le chemin _DATA\INSTITUT_PASCAL_5.GDB
- testez la connection en cliquant "Test"
- fermez le dialogue de connection en cliquant "OK"
|
| dans la page "Borland Data Provider" sélectionnez un BdpDataAdapter: et posez-le sur le Forme
Définissez la requête de sélection: - sélectionnez le BdpDataAdapter1, cliquez sur le bouton droit, sélectionnez "Configure Data Adapter"
- le Configurateur de Data Adapter est affiché:
- sélectionnez FORMATIONS_5, puis "Generate Sql"
- le code "SELECT ... " est généré
- sélectionnez l'onglet "Preview Data"
- cliquez "Refresh"
- les données de la table sont affichés:
- pour afficher les données sur la Forme, nous créons un DataSet qui sera rempli par le BdpDataprovider.
Pour cela, sélectionnez l'onglet "Dataset" du configurateur, choisissez le bouton "New Data": Fermez le Configurateur en cliquant "OK" - DataSet1 est automatiquement ajouté aux composants
De plus sur disque est apparu DataSet1Unit.pas (19 K, tout de même) avec, semble-t-il, les champs persistents et des événements de gestion des modifications et de traitements .XML |
| dans l'onglet "Data Controls" sélectionnez un DataGrid: et posez le sur la Forme. Puis:
- sélectionnez sa propriété DataSource et mettez-y DataSet1
- sélectionnez sa propriété DataMember et mettez-y FORMATIONS_5
| |
ouvrez le DataAdapter1: sélectionnez sa propriété Active et basculez-la sur True | | les données sont affichées dans DataGrid1:
|
7 - Modifier des Données Nous allons à présent mettre en place la modification de données. Commençons
par une application qui affiche des données dans un DataGrid: | créez une nouvelle application Windows Forms et appelez-la
"p_win_bdp_update_data" | | connectez le Serveur: - dans la page "Borland Data Provider" sélectionnez un BdpConnection et
posez-le sur le Forme
- sélectionner BdpConnection1, et avec un Click droit souris, ouvrez l'Editeur de Connections
- sélectionnez le pilote IbConn1
- tapez le chemin _DATA\INSTITUT_PASCAL_5.GDB
- testez la connection en cliquant "Test"
- fermez le dialogue de connection en cliquant "OK"
| |
dans la page "Borland Data Provider" sélectionnez un BdpDataAdapter et posez-le sur le Forme Définissez la requête de sélection: - sélectionnez le BdpDataAdapter1, cliquez sur le bouton
droit, sélectionnez "Configure Data Adapter"
- sélectionnez FORMATIONS_5, toutes ses colonnes, puis "Generate Sql"
- le code "SELECT ... " est généré
- sélectionnez l'onglet "Preview Data"
- cliquez "Refresh"
- les données de la table sont affichés
- pour afficher les données sur la Forme, nous créons un DataSet qui sera rempli par le BdpDataprovider.
Pour cela, sélectionnez l'onglet "Dataset" du configurateur,
choisissez le bouton "New Data". Fermez le Configurateur en cliquant "OK" - DataSet1 est automatiquement ajouté aux composants et DataSet1Unit.pas est généré sur disque
|
| dans l'onglet "Data Controls" sélectionnez un DataGrid et posez le sur la Forme. Puis: - sélectionnez sa propriété DataSource et mettez-y DataSet1
- sélectionnez sa propriété DataMember et mettez-y FORMATIONS_5
| |
ouvrez le DataAdapter1: sélectionnez sa propriété Active et basculez-la sur True |
A présent la partie de mise à jour:
| sélectionnez DataAdapter1 et sa propriété UpdateCommand: vous voyez dans sa propriété CommandText la requête Sql suivante:
UPDATE FORMATIONS_5 SET F_ID = ?, F_NAME = ?, F_DAYS = ?, F_PRICE = ?
WHERE F_ID = ? AND F_NAME = ? AND F_DAYS = ? AND F_PRICE = ? | Cette requête a en fait été générée automatiquement lorsque nous avons crée
la requête SELECT. Si cette requête ne nous convient pas, nous pourrions la modifier (changer le WHERE pour retrouver l'ancienne ligne sur la clé uniquement, par exemple) |
| ajoutons l'instruction de mise à jour: posez un Button sur la Forme, nommez-le "update_" et créez son événement OnClick:
const k_table_name= 'formations_5';
procedure TWinForm.update__Click(sender: System.Object; e: System.EventArgs);
begin if DataSet1.HasChanges
then begin
BdpDataAdapter1.AutoUpdate(DataSet1, k_table_name, BdpUpdateMode.All, [], []);
end; end; // tables_Click | |
| compilez, exécutez. Puis - modifiez la ligne "Delphi Asp" en "ASP.NET ET DELPHI", par exemple
- changez de ligne pour poster
- cliquez "update_"
- fermez et réouvrez: la modification a bien été enregistrée
|
8 - Evaluation
Voici quelques commentaires sur cette première utilisation du BDP - le fonctionnement est nettement plus sympathique qu'avec Ado.Net. Freud dirait que j'aurais pu mettre ce commentaire avant de commencer à utiliser
le BPD. Quel que soit mon biais, l'empilement Ado.Net, Com Interoperability Layer, OleDb puis le client Interbase (ou autre) ne peut pas être très efficace par défaut
- au niveau de l'interface programmeur:
- l'Editeur de Connection de BdpConnection ne se souvient pas toujours de la connection courante (il s'ouvre toujours sur Db2Conn1)
- pour les bugs:
- NUMERIC :
- j'avais au début utilisé le type NUMERIC(5, 2) provenant d'un précédent article
- pour une raison inconnue, l'affichage via un DataSet ne fonctionnait pas. De plus toute la mécanique que nous avons présenté pour afficher en mode conception n'arrêtait pas de présenter des erreur ("input string not of the correct format")
- j'ai changé le type réel en DOUBLE PRECISION et tout est rentré dans l'ordre
- j'ai aussi eu des misères en essayant d'utiliser une table gérée en Delphi 6 et qui comportait des dates.
Par conséquent: - il vaut mieux pour le moment s'en tenir aux types Interbase simples
- le diagnostic de l'erreur a été plus que laborieux. Heureusement que j'avais display: l'affichage de l'indice du champ traité a débusqué le
problème
- BDP est proche dans sa philosophie de dbExpress, et s'en éloigne par la mise en oeuvre. Ce qui est très proche:
- nous retrouvons la chaîne connection (tSqlConnection / BdpConnection)
adaptateur (tDataSetProvider / BdpDataAdapter) dataset (tClientDataset / DataSet) puis affichage (tdbGrid / DataGrid)
- la modification se fait en appelant Update et des paramètres qui guident
le mode de mise a jour
Et ce qui change: - avec le BDP, la relation entre l'adaptateur et le DataSet est initialisée par l'Adaptateur. C'est en fait toute l'architecture des
composants de visualisation qui a été généralisée, et ceci explique ce changement de liaison
- le DataGrid a 2 propriétés (DataSource ET DataMember)
- d'une façon plus générale, la masse de code générée par Delphi 8 pour faire fonctionner l'ensemble est à la fois impressionnant et, à mon avis, un peu inquiétant: soit cette masse est impérative et c'est un défaut, soit
Borland a forcé le comportement très général de Ado.Net pour le façonner au moule Delphi 6 et cela m'incite à voir quel serait le fonctionnement sans tout cela...
Delphi 8 propose aussi un explorateur de données "Voir | Data Explorer": et en cliquant "Interbase", "IbConn1" et FORMATIONS_5 nous avons bien notre table et ses données:
Cet explorateur est en fait un .EXE autonome. Mais je n'ai pas très bien su l'exploiter: - comment fournir la base à examiner (la chaîne de connection)
- les changement de l'application Delphi semble sélectionner ou modifier la base utilisée
9 - Télécharger les Exemples Voici les sources de cet article:
Ces .ZIP qui comprennent:
- le .DPR, la forme principale, les formes annexes eventuelles
- les fichiers de paramètres (le schéma et le batch de création)
- dans chaque .ZIP, toutes les librairies nécessaires à chaque projet (chaque .ZIP est autonaume)
Ces .ZIP contiennent des chemins RELATIFS. Par conséquent: - créez un répertoire n'importe où sur votre machine
- placez le .ZIP dans ce répertoire
- dézippez et les sous-répertoires nécessaires seront créés
- compilez et exécutez
Ces .ZIP ne modifient pas votre PC (pas de changement de la Base de Registre, de DLL ou autre). Pour supprimer le projet, effacez le répertoire.
Comme d'habitude:
- nous vous remercions de nous signaler toute erreur, inexactitude ou problème de téléchargement en envoyant un e-mail à jcolibri@jcolibri.com. Les corrections
qui en résulteront pourront aider les prochains lecteurs
- tous vos commentaires, remarques, questions, critiques, suggestion d'article, ou mentions d'autres sources sur le même sujet seront de même
les bienvenus à jcolibri@jcolibri.com.
- plus simplement, vous pouvez taper (anonymement ou en fournissant votre e-mail pour une réponse) vos commentaires ci-dessus et nous les envoyer en
cliquant "envoyer" :
- et si vous avez apprécié cet article, faites connaître notre site,
ajoutez un lien dans vos listes de liens ou citez-nous dans vos blogs ou réponses sur les messageries. C'est très simple: plus nous aurons de visiteurs et de références Google, plus nous écrirons d'articles.
10 - Conclusion Le BDP est une couche .Net proche dans son esprit de dbExpress sous Delphi 6, qui permet l'accès à de nombreux moteurs Sql, et qui peut être
utilisée depuis plusieurs langages .Net, dont, bien sûr, Delphi. Sa flexibilité en font l'outil favori pour accéder aux données en mode Windows Forms.
11 - Références
- Ramesh THEIVENDTRAN
The Borland Data Provider - a Borland White Paper - January 2004 - CodeCentral Présentation de l'architecture - Ramesh THEIVENDTRAN
Integrating into the Borland Data Provider (BDP) - September 2004 - CodeCentral présente la spécification des INTERFACES composant le BDP
12 - L'auteur
John COLIBRI est passionné par le développement Delphi et les applications de Bases de Données. Il a écrit de nombreux livres et articles, et partage son temps entre le développement de projets (nouveaux projets, maintenance, audit, migration BDE, migration Xe_n, refactoring) pour ses clients, le
conseil (composants, architecture, test) et la
formation. Son site contient des articles
avec code source, ainsi que le programme et le calendrier des stages de formation Delphi, base de données, programmation objet, Services Web, Tcp/Ip et
UML qu'il anime personellement tous les mois, à Paris, en province ou sur site client. |