Visualizzazione post con etichetta database. Mostra tutti i post
Visualizzazione post con etichetta database. Mostra tutti i post

martedì 31 ottobre 2017

Sanitizzazione query SQL

All'ultimo linux day di Milano è stato chiesto, da chi presenziava alla mia presentazione, che tipo di sicurezze offre Livecode contro gli attacchi tipi SQL injection.
Indagando, con mia grande sorpresa ho scoperto che livecode contiene la parametrizzazione delle query.
In pratica quando si esegue la parametrizzazione di una query, la query viene eseguita e poi modificati valori.
Per eseguire una parametrizzazione, basta immettere nella query le variabili sotto forma di numero anteponendo i due punti:


put "red" into valueX
put "10" into valueY
put revDataFromQuery(tab,return,myID,"SELECT x,y FROM test WHERE x = :1 AND y = :2", "valueX", "valueY" ) into tResults

Ricordatevi di mettere tra virgolette le variabili associate ai segnaposto e non avrete più problemi di attacchi sql.

martedì 29 agosto 2017

Libreria CouchDB

Vi ho già parlato del database couchDB. Ora è disponibile per Livecode una serie di funzioni già pronte a l'uso, si possono scaricare, vedere e modificare da: https://github.com/madpink/couchdb4livecode

Rigraziamo il programmatore Greg (pink) Miller per aver condiviso il suo lavoro.

domenica 27 agosto 2017

Problemi con mysql.sock?

Se usate MySQL, può capitare che livecode non si conetta e restituisca come errore:

Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

Che significa?
significa che il serve MySQL a cui vi collegate ha delle impostazioni diverse del solito, quindi dovete dire a livecode dove è il file mysql.sock da utilizzare.
Le impostazioni di MySQL sono in un file chiamato my.cnf, in linux si trova nella cartella:
/etc/mysql

Se lo leggete troverete una riga del tipo:

socket = /var/run/mysqld/mysqld.sock

ora sapete dove è il file per connettersi a MySQL. A questo punto invocate la connessione con i parametri giusti, cioè:

put revOpenDatabase("MySQL", DatabaseAddress, DatabaseName, DatabaseUser, DatabasePassword, false, "/var/run/mysqld/mysqld.sock") 

Problema risolto!

lunedì 26 giugno 2017

Ricerca binaria

La ricerca binaria o logaritmica è un modo di trovare un elemento in una lista molto velocemente, a patto che la lista sia ordinata.
Ecco un raffronto tra la velocità di ricerca normale e quella binaria:
Come potete vedere la velocità della ricerca binaria rimane stabile con il numero di elementi di una lista, mentre una ricerca eseguita in senso classico ha un tempo di ricerca che cresce linearmente col crescere della lista.
Il problema della ricerca di tipo binario è che ha bisogno di una lista ordinata (per valore, alfabeticamente, o qualsiasi altro ordinamento).
Per questo la ricerca di tipo binario porta grandi benefici quando la lista viene modificata raramente, mentre la ricerche sono molto più frequenti; altrimenti il tempo necessario ogni volta a riordinare la lista vanifica ogni vantaggio.
Se per esempio la lista è un array di livecode, per ordinarla è necessaria questa funzione:

function sortedArray @pArray   
   # fetch the keys and sort them using the array entry values   
   get the keys of pArray   
   sort lines of it by pArray[each]   
   split it by return   
   # create a new sorted array using the mapped keys   
   put 1 into tNextIndex
   repeat for each element tIndex in it      
      put pArray[tIndex] into tSortedArray[tNextIndex]      
      add 1 to tNextIndex      
   end repeat   
   return tSortedArray   
end sortedArray

Una volta ordinata la ricerca binaria può avvenire con questa funzione:

function logarithmicSearch @pArray, pItem, pLeft, pRight
   local tIndex
   local tResult
   # create a new range pointer that points to the item that lies
   # right between the left and right range pointers
   put round ((pLeft + pRight) / 2) into tIndex
   # if we have found the matching item then stop processing and return it
   if pArray[tIndex] = pItem then
      put tIndex into tResult
      # if any of the range pointers have the same value
      # then the item we are looking for does not exist in the array and we return 0
   else if (pLeft = pRight or pLeft = tIndex or pRight = tIndex) then
      put 0 into tResult
      # if we have not yet found a match and none of the range pointers have the same
      # value then call logarithmicSearch again with a smaller search range
      # we are effectively halving the search area, each time we call logarithmicSearch
   else if pArray[tIndex] > pItem then
      put logarithmicSearch (pArray, pItem, pLeft, tIndex) into tResult
   else
      put logarithmicSearch (pArray, pItem, tIndex, pRight) into tResult
   end if
   return tResult
end logarithmicSearch

Per chiamare la funzione bisogna indicare l'array, il valore cercato, zero e il numero di elementi dell'array, ad esempio:

put sortedArray(tArr) into tArr
put the number of lines of the keys of tArr into tnkeys
put logarithmicSearch (tArr, "testo da cercare", 0, tnkeys )


In alternativa a tutto ciò, vi ricordo che SQLite è integrato in livecode e permette delle ricerche molto veloci.

giovedì 25 maggio 2017

DBLib e DB

Per chi è interessato ai database Andre Garzia ha sviluppato la libreria aggintiva DBLib che funziona anche su dispositivi mobili.
Mentre per chi è interessato ai database NoSQL c'è la libreria datastorage lib
Per più informazione potete leggere la seguente pagina: http://andregarzia.com/en/projects/dblib
oppure i sorgente su gitHub: https://github.com/soapdog/livecode-dblib

martedì 23 maggio 2017

CouchDB

Livecode è compatibile con il database CouchDB, qui potete trovare una guida: http://livecode.wikia.com/wiki/CouchDB
CouchDB è un database a documenti stile NoSQL, quindi non ha tabelle, ma solo documenti con dati.
Ogni documento può conentere un numero infinito di dati e sotto documenti.
Il vantaggio del NoSQL è quando non si sa con cosa si avrà a che fare. Ad esempio un negozio che aggiunge oggetti con proprietà sempre diverse: colore, grandezza, peso, luminosità, velocità, ecc. Grazie a NoSQL, quando arriva una nuova proprietà da inserire, non bisogna modificare le tabelle.

mercoledì 28 gennaio 2015

Salvare le immagini in un database

Oggi vedremo come salvare le immagini dentro un database per poi utilizzarle successivamente.
In livecode potete sfruttare due informazioni riguardo le immagini: la proprietà imagedata e la proprietà text. Queste due proprietà rappresentano l'immagine, ma in due modi diversi. La proprietà imagedata contiene le informazioni sui pixels dell'immagine e basta; la proprietà text contiene più informazioni: il tipo di immagine (bmp,jpg, ecc.), il tipo di compressione dei dati, i pixels, ecc.
Se dobbiamo lavorare con più immagini di diverso formato (jpg, gif, png, ecc.), non possiamo mettere direttamente solo l'imagedata in una immagine di livecode, perchè se i formati sono differenti livecode dà errore e l'immagine non compare.
Dobbiamo lavorare con la proprietà text, ma vediamo nel dettaglio come fare.
Per scegliere un'immagine da caricare conviene utilizzare questo codice:

answer file "Scegli il nuovo file per l'immagine da salvare:"
if the result is not "Cancel" then
   put it into tpath
   lock screen
   put the rect of image "logo" into temp
   put url ("binfile:" & tpath) into image 1
   set the rect of image 1 to temp
   unlock screen
end if

Notate due cose, l'immagine può non avere la dimensione (altezza e larghezza) desiderata, memorizzando prima la proprietà rect e poi impostandola dopo aver caricato l'immagine, non rischiamo di trovarci immagini con dimensioni assurde fluttuanti  in giro per il programma.
Il secondo elemento da notare è il codice per mettere tutti i dati dell'immagine del computer dentro al controllo immagine di livecode (che ho chiamato semplicemente image 1):

   put url ("binfile:" & tpath) into image 1

solo così la nostra immagine image 1 contiene la proprietà text.
Il database dovrà avere un campo di tipo TEXT (testo), ciò ci permette di non dover impazzirci con i dati in formato binario, che di solito sono un problema quando si trasferiscono da un sistema ad un altro.
Ora i dati dell'immagine, cioè la proprietà text,  deve essere salvata nel database preservando tutte le informazioni, il sistema migliore è utilizzare la funzione base64encode(); in questo moto tutti i bit sono trasformati in caratteri accettati dai campi text dei database. Ecco un esempio di codice per inserire un'immagine in un database:

put base64encode(the text of image 1) into temp
put "UPDATE bandiere SET immagine='"& temp &"' WHERE nome='italia' ;" into tSQL
revExecuteSQL connID,tSQL

Per recuperare l'immagine, basta fare il procedimento inverso. La proprietà si ottiene utilizzando la funzione base64decode(), e poi la inseriamo nel controllo immagine, nel nostro caso image 1, di livecode.

put "SELECT immagine FROM bandiere WHERE nome='italia' "   into tSQL
put revDataFromQuery(tab,return,connID,tSQL) into tRecord
lock screen
put the rect of image 1 into tempR   
put base64decode(tRecord) into temp
put temp into image 1         
set the rect of image 1 to tempR
unlock screen

Separare i dati utilizzando il carattere TAB è molto utile, perchè se dovete richiedere più dati insieme non avrete possibilità di confondere i dati, poichè il carattere TAB non esce dalla funzione base64encode().

lunedì 15 dicembre 2014

SQLite: controllare l'esistenza di una colonna

SQLite è un database che presenta molti vantaggi: portabile, non necessita di un server, basato su un solo file, piccolo e potente. L'altro lato della medaglia, al momento, è che gli mancano delle funzioni sofisticate sull'analisi e la modifica: ad esempio per sapere se esiste una colonna in una tabella, non c'è un metodo diretto.
SQLite mette a disposizione solamente il comando PRAGMA table_info(table-name). Questo comando restituisce una tabella come la seguente:
cidnametypenotnulldflt valuepk
0prima colonna TEXT00
1seconda colonna TEXT00

i nomi della tabella sono quelli della colonna name. Se ad esempio volessimo veirificare l'esitenza della colonna musiche nella tabella miatabella, sfruttando livecode possiamo scrivere il seguente codice atto alla verifica dell'esistenza di una colonna.:

put "PRAGMA table_info(miatabella);" into tSQL
put revDataFromQuery(comma,return,connID,tSQL) into tRecords
if "musiche" is not among the items of tRecords then   
   answer "La colonna musiche non esiste"
else
   answer "Colonna musiche trovata"
end if

giovedì 6 novembre 2014

XML

E' possibile lavorare con i file in formato XML utilizzando le funzioni XML presenti in Livecode.
Interagire con un file XML è molto simile all'interazione con i database, ci si connette ad un dato sotto forma di XML. A quel punto il file (o il dato) XML è caricato in memoria, e anche se lo modifichiamo, finchè non lo scarichiamo da qualche parte, non verranno salvate le modifiche da nessuna parte.
Prima di tutto vediamo come caricare un file XML, se abbiamo un file il codice è il seguente:


on mouseUp
   answer file "FIle XML da caricare:"
   put "file:" & it into tXMLData
   put revXMLCreateTreeFromFile(tXMLData, true, true, true) into sXMLID
   set the conID of this card to sXMLID #così recuperiamo il dato
end mouseUp

Se invece avete i dati da qualche altra parte, basta:
on mouseUp
   put revXMLCreateTree(tXMLData, true, true, true) into sXMLID
   set the conID of this card to sXMLID #così recuperiamo il dato
end mouseUp

Adesso ipotizziamo che il dato XML sia:

<amici></amici>

Perchè vogliamo fare una rubrica con i nostri amici, allora dobbiamo inserire un identificativo unico per ognuno di essi, quindi il codice da usare è:


   put the conID of this card into tID
   revXMLAddNode tID, "amici", "ID","1"
   revXMLAddNode tID, "amici", "ID","2"


Quando si aggiunge un nodo, bisogna sempre tutto l'albero fino a dove vogliamo inserirlo. Abbiamo aggiunto due nodi ID e abbiamo aggiunto il valore 1 e 2 in essi, quindi il nostro dato XML è:

<?xml version="1.0"?>
<amici>
  <ID>1</ID>

  <ID>2</ID>
</amici>



La prima riga è stata aggiunta da Livecode per specificare il formato XML utilizzato. Bene ora dobbiamo inserire i nomi, i valori del tag si specificano con le parentesi quadre:

on mouseUp
   put the conID of this card into tID
   revXMLAddNode tID, "amici/ID[1]", "Nome","Mario"
   revXMLAddNode tID, "amici/ID[2]", "Nome","Luigi"
end mouseUp

Ora il nostro dato XML è:

<?xml version="1.0"?>
<amici>
   <ID>1

        <Nome>Mario</Nome>
   </ID>
   <ID>2
        <Nome>Luigi</Nome>
    </ID>
</amici>

Per aggiungere i cognomi, basta:

on mouseUp
   put the conID of this card into tID
   revXMLAddNode tID, "amici/ID[1]", "Cognome","Rossi"
   revXMLAddNode tID, "amici/ID[2]", "Cognome","Bianchi"
end mouseUp

e il nostro dato diviene:

<?xml version="1.0"?>
<amici>
   <ID>1

      <Nome>Mario</Nome>
      <Cognome>Rossi</Cognome>
   </ID>
   <ID>2
      <Nome>Luigi</Nome>
      <Cognome>Bianchi</Cognome>
   </ID>
</amici>

Per sapere il nome del primo contatto basta:

put revXMLNodeContents(tiD, "amici/id[1]/nome")

Per  eliminare un nodo basta:

on mouseUp
   put the conID of this card into tID
   revXMLDeleteNode tID,"amici/ID[1]"
end mouseUp

e il nostro dato sarà:

<?xml version="1.0"?>
<amici>
   <ID>2

      <Nome>Luigi</Nome>
      <Cognome>Bianchi</Cognome>
   </ID>
</amici>

Per avere tutto l'albero basta:

put revXMLtext(tID)

In questo modo possiamo salvarlo dove ci pare.

giovedì 4 settembre 2014

Interagire con il cloud

I servizi di cloud sono servizi dove i dati sono distribuiti su più computer. Tipicamente sono servizi basati su database, come Amazon AWS.
Esiste un servizio cloud anche per Livecode, lo potete provare gratuitamente qui: http://livecloud.io/

E' basato su NoSQL, quindi segue l'ultima moda in fatto di database.
Non è un servizio inventato dai creatori di Livecode, ma da un'altra società informatica.

Al momento è gratuito e in fase beta, i vantaggi è che si integra facilmente in un linguaggio di programmazione semplice come livecode. Sono sicuro che verrà migliorato notevolmente, ma per chi cerca di avvicinarsi al cloud, può essere un'ottima occasione.

Qui trovate una guida: http://livecloud.io/livecloud-documentation/

Ecco un video esplicativo.

giovedì 26 giugno 2014

Valentina DB

Se avete letto gli ultimi post, Livecode può interagire con molti database, tra cui Valentina. Questo database merita un discorso a parte, perchè, oltre a poter funzionare come tutti i database basati su SQL, è anche un NOSQL database.
Per chi non lo sapesse i database NOSQL stanno prendendo piede in molte realtà come Amazon, Ebay e altri ambiti dove si ha a che fare tanti dati non uniformi. Per riassumere in poche parole un database NOSQL è come lavorare con un database classico dove le tabelle hanno righe e colonne come al solito, ma non tutte le righe hanno un valore per tutte le colonne. Facciamo un semplice esempio: immaginiamo di creare una tabelle con le colonne NOME e COGNOME, poi ad un certo punto della tabella ad una persona vogliamo aggiungere SECONDO NOME senza dover aggiungere il secondo nome a tutte le altre righe; con il metodo NOSQL è possibile.
Il vantaggio del NOSQL risiede nel poter estrarre alcuni dati senza dover pensare ad astruse query di ricerca che incorporino alcuni risultati ed escludino altri.
Valentina è sia gratuito che a pagamento, a seconda della licenza che vi serve. Potete usare insieme Livecode e Valentina per sperimentare i vantaggi dei database NOSQL.

mercoledì 25 giugno 2014

Connettersi ad un database MicrosfotSQL Server

Riprendendo l'ultimo post, ecco la riga di codice necessaria a connettersi ad un database Microsoft SQL server:



put revOpenDatabase("ODBC","DRIVER=SQL Server;SERVER=server_name;DATABASE=database_name;UID=username;PWD=password;Trusted_Connection=No",,,) into connID

martedì 24 giugno 2014

Lavorare con i database

Livecode puo' lavorare con qualunque database. Livecode ha integrato SQLite, ma potete interfacciarci con qualunque database cha abbia una interfaccia ODBC (quasi tutti ce l'hanno), ecco i piu' popolari:
  • SQLite
  • MySQL
  • Oracle
  • PostgreSQL
  • Valentina
I database sono, di solito, dei file esterni al nostro programma che possono essere sullo stesso pc su cui gira il nostro programma o su un server remoto. I database contengono tantissime informazioni catalogate. Grazie ai database noi possiamo ricercare informazioni, inserire o cancellare dei dati, tutto secondo particolari criteri che impostiamo noi.
Il linguaggio utilizzato da quasi tutti i database è il SQL. Generalmente i comandi validi per un database, valgono anche per tutti gli altri.
Riassumendo in poche parole un database, si può affermare che si tratta di una raccolta di tabelle, dentro ogni tabella i dati sono organizzati per righe e per colonne.
I database hanno dei vantaggi:
  • veloci a trovare i dati che si servono tra migliaia di dati
  • occupano poco spazio
  • sono ottimizzati per fare il loro lavoro
  • sono velocissimi
  • si riescono ad incrociare i dati di piu' tabelle facilmente
Potreste fare le stesse cose di un database con una matrice, ma trattando molti dati, vi consiglio di imparare ad utilizzare i database.

Connessione

Per utilizzare un database bisogna prima connettersi ad un database, utilizzando la funzione revOpenDatabase() e memorizzare l'identificato della connessione. Per esempio con SQLite si scrivera':

put revOpenDatabase("sqlite", "./mioDB.sqlite", , , , ) into connID




in questo esempio la variabile connID contiene l'identificativo della connessione (e' un semplice numero). Potete stabilire piu' connessioni contemporaneamente.

Interrogare

Per recuperare delle informazioni dal database, in gergo si dice interrogare, basta usare il comando la funzione revDataFromQuery, specificando come separare righe e colonne:


put "SELECT * from utenti ; " into tSQL
put revDataFromQuery(tab,return,connID,tSQL) into tRecords




in questo caso abbiamo che tRecords contiene tutti i dati dove ogni colonna e' separata dall'altro dal carattere TAB e ogni riga da un accapo. Questa forma potete cambiarla, ma e' molto comoda perchè permette di visualizzare i dati un un campo di testo come una vera tabella (field, label).

Eseguire

Per eseguire dei comandi che modificano in database, basta usare il comando revExecuteSQL, ad esempio:


put "INSERT into users (name,surname) VALUES ('Jack','Sparrow')" into tSQL
revExecuteSQL connID,tSQL

Chiudere la connessione

Quando si lavora su database installati su server, tipo MySQL, conviene chiudere la connessione quando non si lavora più con il database, ecco il codice:
revCloseDatabase connID