Rapid-Q by William Yu (c)1999-2000 .

Upload il tuo script su Rapidq.it

Capitolo 14: Programmare con MySQL

14. Programmare con MySQL

Questo capitolo è una rapida panoramica su cosa è possibile fare con il componente QMYSQL. Non tratta SQL o come costruire query correttamente. E' dato per scontato che abbiate una conoscenza precedente di SQL, ma non necessariamante MySQL.

14.1 Introduzione
MySQL è gratuito per Unix e OS/2, ma Rapid-Q supporta solamente MySQL per Linux e Windows, dal momento che le mie risorse sono limitate a queste macchine. In Windows, se vi piace MySQL, è richiesto il pagamento della licenza dopo un periodo di prova di 30 giorni. Non confondete questo con il pagare me, ovviamente, ma se proprio volete ve ne sarò riconoscente. Perchè o scelto MySQL anzichè un altro database? Il motivo è semplice, tuttavia merita una spiegazione. MySQL è gratis, o quasi, ed è multipiattaforma, il che è in linea con Rapid-Q. E' anche semplice da testare, e piuttosto facile da implementare in Rapid-Q. E' abbastanza leggero, veloce, affidabile e, forse l'ho già detto, gratis. Forse in futuro saranno supportati altri database, ad esempio tramite MyODBC o ODBC in Windows.
Dopo aver installato MySQL server, provatelo per accertarvi che funzioni (vi rimando alla documentazione); avrete anche bisogno di copiare LIBMYSQL.DLL (in Windows) e libmysqlclient.* (in Linux) nella directory che contiene le librerie, C:\WINDOWS\SYSTEM in Windows, and probabilmente /usr/lib in Linux (potete anche aggiungere un percorso al file anzichè spostarlo). Queste librerie sono richieste da Rapid-Q, e dovrebbero essere incluse nel pacchetto MySQL, probabilmente in C:\MYSQL\LIB e /usr/local/lib/mysql, a seconda dell'installazione. Se avete già MySQL installato, assicuratevi che sia aggiornato, eventualmente contattando il vostro amministratore.

14.2 Collegamento a MySQL
L'introduzione sottointende l'installazione del server MySQL nel vostro computer, ma è possibile accedeere un database MySQL da qualunque punto, a patto ovviamente che abbiate un accesso. Se non volete installare il server MySQL nella vostra macchina (perchè no?) assicuratevi di avere le librerie necessarie per il client, cioè LIBMYSQL.DLL. Per cominciare, supponiamo che abbiate installato il server MySQL. Collegarsi al server MySQL locale è piuttosto semplice:
            DIM MySQL AS QMYSQL

            Host$ = ''
            User$ = ''
            Password$ = ''
            MySQL.Connect(Host$, User$, Password$)

            IF MySQL.Connected THEN PRINT 'Connessione riuscita'
Cambiate User$ e Password$ a vostro piacimento. Host$ può assumere anche il valore 'localhost' ma in questo caso non è necessario. Per collegarsi ad un server MySQL remoto che si trova, diciamo, presso allsql.com
            DIM MySQL AS QMYSQL

            Host$ = 'allsql.com'
            User$ = 'anonymous'
            Password$ = 'guest'
            MySQL.Connect(Host$, User$, Password$)

            IF MySQL.Connected THEN PRINT 'Successfully connected'
Most servers will use the standard MySQL port 3306, but if you know the exact port, then you can use the method RealConnect.
            DIM MySQL AS QMYSQL

            Host$ = 'allsql.com'
            User$ = 'anonymous'
            Password$ = 'guest'
            Port% = 12345
            MySQL.RealConnect(Host$, User$, Password$, '', Port%, '', 0)

            IF MySQL.Connected THEN PRINT 'Connessione riuscita'
Vedere la sezione Appendice per i parametri di QMYSQL.RealConnect. La documentazione di MySQL suggerisce l'utilizzo di RealConnect anzichè Connect.

14.3 Come effettuare query ed estrarre i risultati
Scrivete le vostre query come di consueto, ad esempio se volete selezionare tutto da una determinata tabella chiamata user, potete fare così:
            DIM MySQL AS QMYSQL

            '' Prima collegarsi al server

            '' Usare il database
            MySQL.SelectDB('mysql')

            '' Eseguire la query
            MySQL.Query('select * from user')
Il risultato della query è registrato internamente e sequenzialmente. Per ottenere il risultato è necessario recuperarlo (Fetch). Potete visualizzare una tabella a 2 dimensioni:
 
Siccome il risultato è registrato sequenzialmente, è necessario recuperare una riga alla volta (non è sempre vero, ma fingiamo di non avere altra scelta). Fare questo è molto semplice:
            WHILE MySQL.FetchRow       '' Recupera la riga successiva
                MySQL.FieldSeek(0)     '' Reset la posizione del campo
                FOR I = 0 TO MySQL.FieldCount-1
                    PRINT MySQL.Row(I) '' Leggi l'elemento I della riga corrente
                NEXT
            WEND
MySQL.FetchRow recupera la riga successiva. Finchè ci sono righe disponibili, MySQL.FetchRow restituisce TRUE (numero diverso da zero). MySQL.FieldCount è utilizzato per contare quanti campi per riga contiene la tabella corrente. Il resto si spiega da sè.


14.4 Interfacciare QMYSQL con QSTRINGGRID
Come potete notare, sarebbe bello porter se i risultati fossero caricati in una griglia anzichè dover fare il tutto manualmente. Sfortunatamente, non ho intenzione di fare questo al momento, ma potete usare questo semplice codice finchè mi deciderò ad implementarlo internamente:
            SUB ExecuteQuery(MySQL AS QMYSQL, Grid AS QSTRINGGRID, Query AS STRING)
                IF MySQL.Query(Query) = 0 THEN
                   '' Esecuzione fallita
                   EXIT SUB
                END IF

                DEFINT I = 0, J

                ''-- Scrivi il titolo
                Grid.ColCount = MySQL.FieldCount
                WHILE MySQL.FetchField
                   Grid.Cell(I,0) = MySQL.Field.Name
                   I++
                WEND

                Grid.RowCount = MySQL.RowCount+1
                J = 1
                WHILE MySQL.FetchRow       '' Recupera la riga successiva
                   MySQL.FieldSeek(0)      '' Resetta la posizione del campo
                   FOR I = 0 TO MySQL.FieldCount-1
                      Grid.Cell(I,J) = MySQL.Row(I)
                   NEXT
                   J++
               WEND
            END SUB

            ''-- Esempio
            ExecuteQuery(MySQL, MyGrid, 'select * from user')
Ovviamente, potete interfacciare QMYSQL con qualunque componente vogliate.

14.5 Memorizzare e recuperare blob
I blob sono solamente dati in formato binario che richiedono una lavorazione particolare. Siccome posso contenere caratteri NULL ed altri caratteri speciali che possono influenzare MYSQL e Rapid-Q sarà necessario elaborare i dati binari in modo particolare. Notate che hanno dimensioni variabili a seconda del tipo del campo. Un BLOB, per default, può contenere fino a 65535 byte (un LONGBLOB può contenere 2^32-1 byte). Se volete variare la dimensione del buffer, dovrete leggervi (max_allowed_packet). Per memorizzare dati binari, come le immagini, dovrete elaborare determinati caratteri prima di inviarli al vostro database MYSQL.
            $INCLUDE 'RAPIDQ.INC'

            DIM MySQL AS QMYSQL

            ''-- Collegarsi al database, ecc...

            DIM File AS QFILESTREAM
            File.Open('test.bmp', fmOpenRead)

            ''-- Leggere il file come binario, conservando i caratteri NULL
            Buffer$ = File.ReadBinStr(File.Size)

            ''-- Ecco l'elaborazione particolare
            ''-- Converte NULL in \0 ed altri
            ProcessedBuffer$ = MySQL.EscapeString(Buffer$, File.Size)

            ''-- Inserire il blob nella tabella
            MySQL.Query('insert into MyImageTable values('Label 1', '' + _
                        ProcessedBuffer$ + '')')

            File.Close
            MySQL.Close
Dal momento che stiamo trattando dati binari, notate che non utilizziamo LEN() o altre funzioni concernenti le stringhe. Notate anche che possiamo memorizzare testo nei campi del blob, ed in questo caso è possibile utilizzare le funzioni di manipolazione delle stringhe. notice that MySQL.EscapeString converte i dati binari in un formato utilizzabile che può essere passato al database MYSQL. In pratica, non fa altro che convertire NULL in '\0', ' in \', ' in \', e CRLF in \r e \n rispettivamente. Una volta convertita, viene restituita la nuova stringa, ed è utilizzabile in una query. Fin qui tutto bene, supponiamo ora di estrarre i nostri blob:
            $INCLUDE 'RAPIDQ.INC'
            $INCLUDE 'MYSQL.INC'

            DIM MySQL AS QMYSQL

            ''-- Collegarsi al database, ecc...

            DIM File AS QFILESTREAM
            File.Open('out.bmp', fmCreate) ''-- Creare un nuovo file

            ''-- Indicare la vostra query
            MySQL.Query('select * from MyImageTable')

            WHILE MySQL.FetchRow
                MySQL.FieldSeek(0)
                MySQL.FetchLengths ''-- Necessario per dati binari
                FOR I = 0 TO MySQL.NumField-1
                    MySQL.FetchField
                    IF MySQL.Field.Type = FIELD_TYPE_BLOB THEN
                        ''-- Leggere dati binari dalla tabella
                        Buffer$ = MySQL.RowBlob(I, MySQL.Length(I))
                        File.WriteBinStr(Buffer$, MySQL.Length(I))
                    ELSE
                        Buffer$ = MySQL.Row(I)
                    END IF
                NEXT
            WEND

            File.Close
            MySQL.Close
Estrarre blob dal database è un pò più complicato che registrarli. La prima cosa da notare è che leggere dati binari e stringhe di testo sono due operazioni differenti. Dal momento che le stringhe terminano con NULL, non è necessario preoccuparsi di quanti byte leggere, in quanto il calcolo è automatico. Tuttavia, siccome i dati binari possono contenere caratteri NULL, leggere i blob è un pò arduo. Bisogna conoscere la lunghezza di ciascun campo, in quanto la nostra tabella contiene blob, chiamando MySQL.FetchLengths per ciascuna riga. Poi, per trovare la lunghezza di ciascun campo, si utilizza la matrice interna MySQL.Length(index%) che restituisce la lunghezza del campo index%. Perchè dobbiamo fare questo? Perchè dobbiamo conoscere la dimensione del nostro blob prima di potervi leggere. Per leggere dati binari nel nostro database si utilizza la funzione MySQL.RowBlob(Row%, Bytes%) che restituisce una stringa binaria. Con questa è possibile scrivere i dati in un file o in memoria, o manipolarli direttamente. Nell'esempio precedente i dati vengono scritti in un file.

14.6 Utilizzo di LOADBLOB e SAVEBLOB
Nella sezione precedente abbiamo esaminato i metodi per immagazzinare e recuperare blob (dati binari). Tuttavia, c'è un sistema migliore e più rapido per fare la stessa cosa.
            ''-- Metodo precedente
            ProcessedBuffer$ = MySQL.EscapeString(Buffer$, File.Size)
            MySQL.Query('insert into MyImageTable values('Label 1', '' + _
                        ProcessedBuffer$ + '')')

            ''-- Utilizzo di LOADBLOB
            ProcessedBuffer$ = MySQL.LoadBlob('test.bmp')
            MySQL.Query('insert into MyImageTable values('Label 1', '' + _
                        ProcessedBuffer$ + '')')
L'uso di LOADBLOB evita l'utilizzo di MySQL.EscapeString in quanto è già implementato internamente. Riceve semplicemente un argomento (il nome del file da includere), e restituisce la stringa elaborata. Per estrarre un blob dal database e salvarlo in un file, potete provare così:
            WHILE MySQL.FetchRow
                MySQL.FieldSeek(0)
                '' MySQL.FetchLengths
                FOR I = 0 TO MySQL.NumField-1
                    MySQL.FetchField
                    IF MySQL.Field.Type = FIELD_TYPE_BLOB THEN
                        ''-- Salva i dati in un file
                        MySQL.SaveBlob(I, 'temp.bmp')
                    ELSE
                        Buffer$ = MySQL.Row(I)
                    END IF
                NEXT
            WEND
In questo caso possiamo ignorare l'uso di MySQL.FetchLengths in quanto, anche questo, è implementato internamente. MySQL.SaveBlob riceve due argomenti. Il primo è l'indice (o numero del campo se preferite), ed il secondo è il nome del file in cui salvare il tutto. Questa funzione non restituisce alcun valore.

14.7 Conclusioni
L'utilizzo di MYSQL può farvi risparmiare tempo ed energie, in quanto non dovrete progettare il vostro database, e le ricerche sono piuttosto veloci. Inoltre, MYSQL è multipiattaforma, così potete utilizzarlo sia in Windows che in Linux. Se avete un'esperienza precedente con la programmazione in MYSQL, noterete probabilmente alcune differenze. Ad esempio,
            I = MySQL.SelectDB('mysql')
In Rapid-Q, questa funzione restituisce 0 se non si può aprire il database, ed un numero diverso da zero in caso contrario. Tuttavia, se avete utilizzato LIBMYSQL.DLL in precedenza, questa funzione (mysql_select_db)) restituisce 0 in caso di successo e -1 in caso di insuccesso. In pratica, quando utilizzate Rapid-Q dovete pensare in modo opposto.




2003 Holyguard.net - 2007 Abruzzoweb