SQLite

SQLite : supporto per il .Net Compact Framework 3.9 e Windows Embedded Compact 2013

E’ ormai noto che la Microsoft ha fatto una scelta ben precisa per quanto riguarda l’utilizzo di un DBMS all’interno dei propri prodotti embedded, dagli smartphone (Windows Phone) ai tablet (Surface WinRT) passando per i dispositivi basati su Windows Embedded Compact 2013; questa scelta ha un nome ben preciso ed è SQLite !

Passaggio da WEC7 a WEC2013 : SQL Server Compact rimosso !

Per quanto riguarda Windows Embedded Compact, il passo è stato effettuato dalla versione 7 alla 2013, rimuovendo addirittura la feature “SQL Server Compact” dal Catalog Items del Platform Builder (tra le features “Core” associata alla variabile SYSGEN_SQLCOMPACT) attraverso la quale era semplicissimo aggiungere il supporto per questo DBMS all’immagine del sistema operativo.

01

Inoltre, nella documentazione ufficiale MSDN del .Net Compact Framework 3.9 è descritta la rimozione del supporto per SQL Server Compact all’interno del framework stesso e proprio l’uso di SQLite è riportato come possibile “workaround”.

02

A questo punto, non ci resta che accettare la scelta fatta da Microsoft ed esplorare in che modo sia possibile utilizzare SQLite sui nostri sistemi embedded.

SQLite : supporto nativo e managed con ADO.NET

SQLite è un DBMS standalone alla pari di SQL Server Compact e caratterizzato da una singola DLL attraverso la quale è possibile gestire i propri database. Sul sito ufficiale sono disponibili i sorgenti che per Windows Embedded Compact 2013 vanno necessariamente ricompilati. Per fortuna, esiste un utilissimo progetto su CodePlex, SQLite for Windows Embedded Compact 2013, di David Jones (insieme a me uno dei membri della “board of director” della Embedded101 community) attraverso il quale è possibile avere a disposizione il binario in codice nativo della libreria SQLite in modo da poterla anche includere nell’immagine del sistema operativo attraverso il Catalog Items del Platform Builder con un semplice click.

03

Per quanto riguarda il supporto managed, è disponibile da poco tempo un wrapper ADO.NET sul sito ufficiale nella sezione “Precompiled Binaries for Windows CE (.Net Compact Framework)” per il .Net Compact Framework 3.9 (sia per architettura ARM che x86). Esso si aggiunge a quello già disponibile per il .Net Compact Framework 3.5.

04

In questo modo si completa il supporto di SQLite per Windows Embedded Compact 7 e 2013 sia in codice nativo che managed.

SQLite ADO.NET : una panoramica

Una volta scaricato il file zip relativo all’architettura che ci interessa (ARM o x86) per il .Net Compact Framework 3.9, al suo interno troveremo la libreria nativa precompilata (SQLite.Interop.090.dll) ed il wrapper ADO.NET in codice managed (System.Data.SQLite.dll); entrambi i file vanno distribuiti sul nostro target : la libreria nativa potrebbe essere inclusa direttamente nell’immagine del sistema operativo attraverso un subproject ed un relativo file BIB mentre l’assembly ADO.NET può essere incluso nella cartella dell’applicazione stessa.

Per chi già conosce l’accesso ai dati attraverso ADO.NET (con SQL Server Compact o meno) l’utilizzo del namespace System.Data.SQLite con tutte le relative classi risulterà assolutamente familiare.

La connessione ad un database è creata attraverso la classe SQLiteConnection alla quale è necessario fornire la connection string che deve contenere il path assoluto del database; successivamente l’apertura viene eseguita attraverso il metodo Open() che provvede a creare il database qualora esso non esista.

string databasefile = "test.db";
SQLiteConnection conn = new SQLiteConnection(string.Format("Data Source={0};Version=3;",
    Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase), databasefile)));
conn.Open();

Una volta stabilita la connessione, è possibile effettuare tutte le operazioni CRUD sul database.

Ciascun comando per interagire con il database è rappresentato dalla classe SQLiteCommand che può essere istanziata utilizzando il costruttore relativo oppure il metodo CreateCommand() della classe SQLiteConnection. L’esecuzione di un comando viene effettuata attraverso la classe SQLiteDataReader utilizzando i metodi ExecuteReader(), ExecuteScalar() e ExecuteNonQuery().

string cmdText = "SELECT * FROM MyTable";
SQLiteCommand cmd = new SQLiteCommand(cmdText);
cmd.Connection = conn;
SQLiteDataReader reader = cmd.ExecuteReader();

while (reader.Read())
{
    Console.WriteLine(reader.GetInt32(0) + " " + reader.GetString(1) + " " + reader.GetString(2));
}
reader.Close();

//...

SQLiteCommand cmd = conn.CreateCommand();
cmd.CommandText = "SELECT * FROM MyTable";
SQLiteDataReader reader = cmd.ExecuteReader();

while (reader.Read())
{
    Console.WriteLine(reader.GetInt32(0) + " " + reader.GetString(1) + " " + reader.GetString(2));
}
reader.Close();

Inoltre, è disponibile il supporto alle transazioni utilizzando la classe SQLiteTransaction che va istanziata mediante il metodo BeginTransaction() della classe SQLiteConnection e che può essere committata o annullata attraverso i metodi di Commit() e Rollback().

using (SQLiteTransaction trans = conn.BeginTransaction())
{
    try
    {
        using (SQLiteCommand cmd = new SQLiteCommand())
        {
            //...
        }
        trans.Commit();
    }
    catch
    {
        trans.Rollback();
    }
}

L’ultima modalità di interazione è attraverso i DataSet per un accesso disconnesso ai dati, utilizzando la classe SQLiteDataAdapter ed il relativo metodo Fill(), per caricare i dati, ed il metodo Update() per aggiornarli sul database.

DataSet ds = new DataSet("MyDataSet");

SQLiteDataAdapter adapter = new SQLiteDataAdapter(cmd);
adapter.Fill(ds, "MyTable");

Conclusioni

La scelta di Microsoft di adottare un nuovo database per le applicazioni embedded e di non puntare su un prodotto fatto in casa può essere condivisa o meno. Il passaggio da SQL Server Compact a SQLite può essere considerato indolore grazie all’utilizzo dell’interfaccia ADO.NET. Inoltre, può essere un vantaggio l’ampio utilizzo di SQLite anche su altri sistemi operativi ed in ambito mobile oltre al fatto che sia completamente open source. Sicuramente c’è da attendersi in futuro sempre una maggiore integrazione tra gli strumenti di sviluppo di casa Microsoft e questo DBMS, diventato il punto di riferimento nell’ambito dei device.