SQLite3 per Ruby e il caricamento delle estensioni
SQLite è un'ottima libreria open source e multipiattaforma per la gestione di un vero e proprio database relazionale in locale (su file) con pochissimo overhead sia in termini applicativi che di gestione. Proprio recentemente è arrivata un'ulteriore conferma della bontà di questa libreria in seguito al debutto di Google Gears che internamente utilizza SQLite per la memorizzazione dei dati offline. Una delle testimonianze della flessibilità di questa libreria risiede nella possibilità di caricare dinamicamente moduli esterni per estenderne le funzionalità, come nel caso dei due moduli ufficiali ma sperimentali FTS1 e FTS2 che implementano la ricerca full text in SQLite, purtroppo però non è ancora possibile farlo in Ruby poiché l'ultima versione della libreria sqlite3-ruby (v1.2.1) non espone ancora l'interfaccia di SQLite per il caricamento di estensioni. Fortunatamente qualcuno ci ha pensato e 与太郎 (Yotaro) ha preparato una pezza patch da applicare ai sorgenti originali, mettendola a disposizione sul suo sito dove inoltre fornisce uno zip con il tutto già compilato per Win32 tramite Mingw (ho mirrorato il suo zip per evitargli ulteriore consumo di banda). Purtroppo l'applicazione della patch attraverso il comando omonimo mi ha dato problemi in Windows dal momento che ha generato degli errori, per cui nel dubbio ho preparato uno zip con i sorgenti già patchati per evitare problemi a chi volesse compilare il tutto in autonomia in ambiente Win32. A questo punto occorre sostituire i file originali di sqlite3-ruby con quelli patchati insieme al modulo .so compilato, ecco la lista dei file modificati nel caso vogliate sostituire solo quelli: sqlite3_api.so, sqlite3/database.rb, sqlite3/driver/native/driver.rb, sqlite3/driver/dl/driver.rb, sqlite3/sqlite3/driver/dl/api.rb. Ovviamente vale lo stesso discorso anche nel caso abbiate installato sqlite3-ruby tramite rubygem. Questa patch aggiunge due metodi di istanza alla classe SQLite3::Database, trattasi di enable_load_extension e load_extension i quali permettono rispettivamente di abilitare il caricamento delle estensioni e di indicare il file binario dell'estensione da caricare, come da esempio:
require 'rubygems' require 'sqlite3' db = SQLite3::Database.new(':memory:') # apre un database in memoria e non su file db.enable_load_extension(1) # abilita il caricamento delle estensioni in SQLite db.load_extension('fts2.dll') # carica il modulo FTS2 di SQLite