' 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. * File richiesti: * MySQL_serverversione 3.22.xx o successiva * Librerie Rapid-Q MySQL * MySQL Client se non volete utilizzare un server 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.FetchRowrecupera 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è. [http://www.rapidq.it/public/hell_editor/homepages/images/chap14d1.gif] 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