martedì 23 dicembre 2014

Calendario dell'Avvento ITPUG: 22 Dicembre

Io personalmente non lo uso per scopi specifici, quanto piu' per "collegare" un'istanza PostgreSQL a diversi database del mio desktop KDE. Molte applicazioni KDE infatti si appoggiano a SQLite, e a dire il vero anche altri strumenti come fossil (fossil-scm.org) lo fanno. Lo scopo pe rme è quello solo e puramente di studio dei meccanismi interni di aclune applicazioni, un giorno forse avrò anche bisogno di manipolare in diretta i dati. Ad ogni modo l'uso è abbastanza semplice, quasi banale per chi è abituato ai fdw.

Faccio un esempio specifico: digikam

== Passo 1: fare il dump dello schema del database ==

% sqlite3 -interactive digikam4.db
sqlite> .output digikam.sql
sqlite> .schema
sqlite> .q

== Passo 2: preparare uno script di migrazione ==

Mi faccio aiutare qui da Perl (lo script lo riporto in seguito):

% perl export.pl digikam.sql digikam_server /tmp/digikam4.db >
export_digikam.sql

così facendo creo un file export_digikam.sql che creerà il server "digikam_server" partendo dal file di dump "digikam.sql". Il nome del file "digikam.db" serve solo per collegare il data wrapper al database SQLite giusto.

== Passo 3: caricare le tabelle e il foreign data wrapper ==

Da un promp psql è abbstanza banale accedere via fdw:

image=# CREATE EXTENSION sqlite_fdw;
image=# \i ~/Pictures/digikam_export.sql

e tutto è fatto!
Ok, vediamo quanta "roba" c'è nel database:

image=# SELECT count(id) as Foto, sum( filesize ) / (1024 * 1024 *
1024) as Gigabytes FROM images;

foto  | gigabytes
------+-----------
39491 | 285




===== script perl di conversione ======
#! /usr/bin/perl

use v5.10;
my $IN;
my $server = $ARGV[ 1 ];
my $file = $ARGV[ 2 ];
open $IN, "<", $ARGV[ 0 ] || die "\nImpossibile leggere file dump\n$!"; 
say "CREATE SERVER $server FOREIGN DATA WRAPPER sqlite_fdw OPTIONS (database \'$file\');"; while (<$IN>) {

if ( /CREATE TABLE (\w+)/ ) {
  $table = $1;
  $sql = "CREATE FOREIGN TABLE $1 (\n";
}
elsif ( $table ){
  chomp;
  s/DATETIME/TIMESTAMP/;
  s/PRIMARY KEY/NOT NULL/;
  s/\(//;
  $sql .= $_ . "\n" unless /(UNIQUE | \)\; ) /xms;
  if ( /[\)\;]/ ){
    $sql =~ s/,$//;
    $sql .= ") \n\t SERVER $server \n\t OPTIONS (table \'$table\' );\n" ;
    say $sql;
    undef $table;
    undef $sql;
  }
 }

}

Nessun commento: