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.