Ritorna alla home page

Usare MySQL
con Borland C++ Builder

Valid HTML 4.01 Transitional

Valid CSS!

Premessa: per lavoro avevo la necessità di accedere al server MySQL tramite un programma scritto in Borland C++ Builder, ma non avevo la più pallida idea di come fosse possibile utilizzando l'API ufficialmente supportata. Dopo una buona ricerca in internet sono riuscito a trovare un solo sito francese che ne parlava, di cui però ho smarrito l'URL; non appena riuscirò a ritrovarlo inserirò il link, che comunque sarà la versione non tradotta di questa pagina.

Nota: l'autore non si assume alcuna responsabilità su eventuali danni derivanti dall'utilizzo delle informazioni qui descritte.

Software: quanto descritto (ad eccezione del punto 9 e seguenti) è stato testato su Windows 98 con Borland C++ Builder 5 e MySQL 3.23.55.

 

DOWNLOAD

Parto dal presupposto che tutto sia installato a dovere, compreso il server MySQL (anche perchè non usandolo così spesso in ambiente windows, non sarei proprio in grado di darvi molti suggerimenti sull'installazione).
Quando si installa il server, vengono installati insieme anche alcuni file che permettono di realizzare l'API in C, una delle poche ufficialmente supportate. Abbiamo quindi tutto già pronto, non resta altro che capire come fare.

 

1 - PREPARARE IL PROGETTO

1.1 - Creare un nuovo progetto

Creare un nuovo progetto e salvarlo in una directory. Copiare all'interno di quest'ultima directory libmySQL.dll (che si trova nella sottodirectory \bin della directory dove è installato MySQL) e tutto quello che è contenuto nella sottodirectory \include della directory dove è installato MySQL.

1.2 - Creazione della libreria d'importazione

E' necessario creare la libreria libmySQL.lib attraverso il programma implib contenuto nella sottodirectory /bin della directory dove è installato Borland C++ Builder:

  implib libmySQL.lib libmySQL.dll

La libreria così creata deve essere aggiunta al progetto (Shift + F11).

1.3 - Aggiornare gli header file

Nel file mySQL.h bisogna modificare intorno la linea 34:

  #ifdef __LCC__
  #include <winsock.h> /* For windows */
  #endif

che diventa:

  #if ( defined(__LCC__) || defined(__WIN__) )
  #include <winsock.h> /* For windows */
  #endif

1.4 - Aggiornare gli header file

Nelle unit che usano le funzioni API MySQL, aggiungere le due seguenti linee di codice:

  #define __WIN__
  #include "mysql.h"

Il progetto ora è pronto.

 

2 - INIZIALIZZARE LA CONNESSIONE A MySQL

Prima di tutto è necessario inizializzare l'accesso alla DLL.

  MYSQL *mySQL;
  mySQL = mysql_init(NULL);

Al ritorno mySQL contiene l'indirizzo della struttura che permette l'interfacciamento con mySQL, oppure NULL in caso di errore.

 

3 - FERMARE LA CONNESSIONE

  MYSQL *mySQL;
  mysql_close(mySQL);

mysql_close ferma la connessione al database e libera le risorse allocate durante la creazione della connessione.

 

4 - CONNETTERSI AL DATABASE

  MYSQL *mySQL;

  if (!mysql_real_connect(mySQL, "127.0.0.1", "root", "root", "test", 0, NULL, 0))
  {
    // connessione fallita    
  }
  else
  {
    // connessione riuscita    
  }

mysql_real_connect apre la connessione con il database e aggiorna la struttura mySQL in funzione di questa connessione. I parametri sono:

Un valore di ritorno pari a zero indica che è avvenuto un errore, altrimenti significa che la connessione è andata a buon fine.

 

5 - VISUALIZZARE LE TABELLE DI UN DATABASE

  MYSQL *mySQL;
  MYSQL_ROW myROW;
  MYSQL_RES *myRES;
  AnsiString aStr;

  myRES = mysql_list_tables(mySQL, NULL);

  if (myRES)
  {
    for (unsigned int i = 0; i < myRES->row_count; i++)
    {
      myROW = mysql_fetch_row(myRES);
      for (unsigned int j = 0; j < mysql_num_fields(myRES); j++)
      {
        aStr.sprintf("%s", myROW[j]);
        ListBox1->Items->Add(aStr);
      }
    }
    mysql_free_result(myRES);
  }

mysql_list_tables permette di leggere i nomi di tutte le tabelle del database associato a mySQL. I parametri sono:

Il valore di ritorno è una struttura del tipo MYSQL_RES che è l'handle del risultato della richiesta. Se la richiesta fallisce, il risultato di ritorno è NULL.

La proprietà row_count di myRES restituisce il numero di record contenuti nel risultato.

mysql_fetch_row ritorna il record seguente del risultato della richiesta, in una struttura del tipo MYSQL_ROW.

La funzione mysql_num_fields permette di conoscere il numero di campi restituiti dalla richiesta.

Una volta che non si ha più la necessità di avere il risultato della richiesta, non bisogna scordarsi di liberare le risorse chiamando la funzione mysql_free_result.

 

6 - ACCEDERE AI DATI DI UNA TABELLA

  MYSQL *mySQL;
  MYSQL_RES *myRES;
  MYSQL_ROW myROW;
  AnsiString aStr;

  if (!mysql_query(mySQL, "select * from testbcb"))
  {
    myRES = mysql_store_result(mySQL);
    if (myRES)
    {
      for (unsigned int i = 0; i < myRES->row_count; i++)
      {
        myROW = mysql_fetch_row(myRES);
        for (unsigned int j = 0; j < mysql_num_fields(myRES); j++)
        {
          aStr = myROW[j];
          ListBox1->Items->Add(aStr);
        }
      }
      mysql_free_result(myRES);
    }
  }

La funzione mysql_query effettua una richiesta. Un valore di ritorno pari a zero indica che la richiesta ha avuto successo, altri valori indicano un errore.

Per accedere al risultato della richiesta è necessario chiamare la funzione mysql_store_results, che ritorna un puntatore del tipo MYSQL_RES.

mysql_fetch_row restituisce il record successivo in una struttura del tipo MYSQL_ROW.

 

7 - VISUALIZZARE LA STRUTTURA DI UNA TABELLA

  MYSQL *mySQL;
  MYSQL_RES *myRES;
  MYSQL_FIELD *myFields;
  AnsiString aStr;
  int CountFields;

  if (!mysql_query(mySQL, "select * from testbcb"))
  {
    myRES = mysql_store_result(mySQL);
    if (myRES)
    {
      CountFields = mysql_num_fields(myRES);
      myFields = mysql_fetch_fields(myRES);
      for (unsigned int i = 0; i < CountFields; i++)
      {
        aStr.sprintf("Field %s is type %d",myFields[i].name, myFields[i].type);
        ListBox1->Items->Add(aStr);
      }
    }
    mysql_free_result(myRES);
  }

La funzione mysql_fetch_fields riempie una struttura del tipo MYSQL_FIELDS, che contiene una tabella con tutte le informazioni dei campi restituiti dalla richiesta.

 

8 - GESTIONE DEGLI ERRORI

8.1 - Ottenere il codice d'errore

  unsigned int myErrorCode;
  myErrorCode = mysql_errno(mySQL);

mySQL_errno ritorna un numero d'errore indicante l'errore che è occorso durante l'ultima chiamata all'API per la connessione al database. Un valore pari a zero indica che non c'è stato alcun errore.

8.2 - Ottenere un messaggio che descrive l'errore

  AnsiString myErrorMsg;
  myErrorMsg = mysql_error(mySQL);

mySQL_error restituisce un messaggio che descrive l'errore che è avvenuto durante l'ultima chiamata all'API per la connessione al database. Un messaggio vuoto significa che non c'è stato alcun errore.

 

9 - UTILIZZARE LA VERSIONE INTEGRATA DEL SERVER MySQL

Dalla versione 4 esiste la possibilità di avviare il server MySQL dall'applicazione. L'utilizzo di questo sistema implica alcune modifiche al progetto e al file di configurazione di MySQL.

9.1 - Modifica del file di configurazione di MySQL

Nel file di configurazione di MySQL è necessario aggiungere almeno:

  [embedded]
  basedir=e:/mysql
  datadir=e:/mysql/data

Si tratta della configurazione del server, ma relativa alla versione integrata del server.

9.2 - Modifica del progetto

Durante la creazione del progetto è necessario sostituire la DLL libmySQL.dll con la DLL libmySQLD.dll; questo per tutte le fasi del progetto.

9.3 - Avvio del server

  if (!mysql_server_init(0, NULL, NULL)
  {
    // il server si è avviato    
  }
  else
  {
    // il server non si è avviato    
  }

La funzione mysql_server_init permette di avviare il server MySQL. I parametri sono gli stessi eventuali parametri che si passerebbero dalla linea di comando. Un valore di ritorno pari a zero indica che il processo di avvio ha avuto successo; un valore differente indica che è avvenuto un errore.

9.4 - Arresto del server

  mysql_server_end();

La funzione mysql_server_end arresta il server MySQL.

Ritorna alla home page