Introduzione

Per un moderno database lavorare in multiutenza è diventato un requisito obbligatorio, ed in effetti disporre di una base dati comune consultabile da tutti gli utenti di una stessa equipe è un istinto naturale, direi primordiale.

Da questo punto di vista la piattaforma che FileMaker Inc. propone è particolarmente avanzata, tanto da coprire l'utenza di rete LAN, WAN, l'utenza web e quella mobile. Abbiamo quindi una lunga serie di opzioni, ognuna con i suoi pro e i suoi contro.

Vediamole rapidamente.

Le opzioni di condivisione dei dati in FileMaker

1. Utilizzo di un sistema server/client

Si tratta della modalità classica di utilizzo di FileMaker in rete, sia essa locale o WAN.

Pro: nessun lavoro aggiuntivo.

Contro: il client deve essere sempre collegato al server.

2. Utilizzo di una interfaccia web

Pro: utilizzabile senza client specifico.

Contro: il browser deve potersi collegare al server web.

3. Utilizzo di copie del database - Dropbox

Pro: nessun lavoro aggiuntivo.

Contro: siamo in realtà in singola utenza.

In questa voce rientrano varie metodologie di condivisione, molte delle quali ferocemente sbagliate (come il navigare fino ad una cartella di rete condivisa e aprire i file di FileMaker). A queste pratiche si è recentemente aggiunto l'utilizzo di Dropbox. Quest'ultimo, fornendo un sistema di condivisione dei file, ha creato anche una certa confusione tra gli utenti: aprire un file dentro una cartella di Dropbox equivale infatti ad aprirlo dentro una cartella locale o di rete. Ciò significa che siamo sempre in singola utenza: il rischio è di aprire il file in più persone e di ritrovarci con più copie del nostro database, ognuna contenente una parte dei dati.

Di recente l'avvento dei dispositivi mobili ha creato una nuova esigenza: quella della sincronizzazione. In pratica, i dati vengono scritti localmente e vengono riportati nel database principale.

Che soluzioni offre FileMaker sul fronte della sincronizzazione dei dati?

Le opzioni di sincronizzazione dati in FileMaker

In questo caso, le opzioni offerte da FileMaker sono più limitate:

1. Utilizzo di un file offline e successiva importazione dei dati con le funzioni di importazione record di FileMaker

In questo caso, facciamo riferimento all’opzione di importazione che consente di utilizzare un campo chiave per aggiornare i dati esistenti ed aggiungere i nuovi.

Pro: semplice.

Contro: richiede una importazione per ogni tabella; non gestisce eventuali problemi durante l’importazione.

2. Utilizzo di un file offline e creazione di una procedura di sincronizzazione

Pro: potente, flessibile.

Contro: complicato.

Come ci aveva annunciato la pagina di supporto FileMaker,

It is a very advanced FileMaker development task that requires an in-depth understanding of scripting, calculations, and data-structure concepts. Non-expert developers should seek the assistance of a professional FileMaker consultant for all but the very simplest of database solutions.

Lo scopo di questo articolo è proprio quello di accompagnare il lettore nella realizzazione di una procedura robusta ma di alta portabilità, facile da replicare nei suoi file e semplice da modificare.

Entriamo quindi nel dettaglio della sincronizzazione, ed iniziamo distinguendo due forme di sincronizzazione.

Sincronizzazione bidirezionale

La sincronizzazione bidirezionale parte da due basi dati separate. La procedura fa sì che i dati delle due basi si uniscano, con il risultato di avere in entrambe gli stessi dati. (Volendo essere pignoli, questa è la vera sincronizzazione).

Sincronizzazione monodirezionale

Nella sincronizzazione monodirezionale esistono due file separati, di cui quello remoto viene utilizzato per raccogliere i dati che verranno riversati nel file centrale.

È di questa forma di sincronizzazione che ci occuperemo principalmente in questo articolo.

Quest'ultima forma si sta rapidamente facendo largo nel panorama dei database perchè soddisfa un bisogno molto frequente nella realtà quotidiana. Specialmente in situazioni in cui lavorare localmente può sopperire alla mancanza di connettività e/o ad una performance scadente.

Anche in condizioni di connettività o di performance accettabili, esiste poi una serie di casistiche in cui è inutile portarsi dietro tutto il database. Spesso ce ne serve solo una piccola parte, anche minima: quella che utilizzeremo quando usciamo dal nostro ufficio.

Facciamo un esempio: un ospedale vuole controllare tramite visite a domicilio l'andamento dei pazienti dimessi. In questo caso, poter consultare tutto il nostro database non ci serve: al massimo potremmo voler consultare i dati dei pazienti che andremo a vedere.

Un altro esempio? Un agente di commercio si reca a visitare i suoi clienti e crea dei preventivi in base alle indicazioni del cliente. Anche in questo caso le uniche cose che ci servono sono l'anagrafica clienti e il listino: il resto è superfluo.

Ovviamente questo principio non si applica in situazioni in cui essere aggiornati al secondo è fondamentale, ad esempio quando dobbiamo gestire prenotazioni a fronte di una ricettività fissa, o vendere articoli da un magazzino che potrebbe non essere più lo stesso di quando siamo usciti.

I principi generali della sincronizzazione

I principi generali di una procedura di sincronizzazione sono ben delineati:

  • l’utente avvia la procedura nel file remoto;
  • vengono trovati i records da trasmettere;
  • la procedura tenta di connettersi col server per verificarne la disponibilità;
  • viene eseguito il passaggio dei dati;
  • in un momento separato, una seconda procedura nel file centrale si occupa di processare i dati passati dalla procedura di sincronizzazione.

Uno dei fattori chiave per realizzare una procedura di sincronizzazione affidabile è l'integrità transazionale

Di cosa si tratta? Ce lo spiega direttamente FileMaker, Inc. nella FileMaker Sync Guide – v12.0:

Because of the possibility of losing network connection, it is important that the sync scripts complete all changes to a given record or group of records before commit. Modifications should be done in a way that locks the record for the shortest possible time and makes relevant changes while the record remains locked.

This will ensure that the complete set of changes is transmitted in a single action, providing transactional integrity.

If the connection is lost during transfer of a record, the record will not have been committed and all the changes to it will be lost.

In buona sostanza: il passaggio dei dati deve avvenire in forma atomica, seguire la legge del tutto o nulla, perchè si possa essere certi dell'affidabilità dei dati che vengono trasmessi.

Una volta stabilite le regole generali ed i termini del problema vediamo cosa offre il mercato.

Sincronizzazione: le alternative in commercio

Come si vede dalla tabella sottostante, esistono varie opzioni, commerciali o open source, in grado di realizzare sincronizzazioni mono o bidirezionali, native o necessitanti plugin o altro software, rispettando o meno la transazionalità.

Tabella1

In linea di massima si tratta di procedure sofisticate, a volte molto ben documentate ma quasi sempre complicate, ardue da riprodurre e difficili da riportare nei propri file.

Alle procedure elencate nella tabella si affianca FMGo Syncro.

Cos'è FMGo Syncro

Si tratta di un sistema modulare che utilizza solo funzioni native di FileMaker.

Consente una sincronizzazione monodirezionale da FMGo a FileMaker utilizzando una procedura completamente transazionale.

Perchè FMGo Syncro?

L'idea di fondo di FMGo Syncro è quella di dare risposta ad un bisogno primario nato un secondo dopo aver preso in mano un iPad con dentro FMGo: come faccio adesso a passare i dati al mio computer?

La risposta doveva essere semplice, facile da replicare, modulare, scalabile per adattarsi a più situazioni, slegata da altre app e anche possibilmente da plugin, transazionale, perchè l'integrità dei dati non ha prezzo.

Il risultato? FMGo Syncro.

Il razionale di FMGo Syncro è in linea con quanto prospettato dalla FileMaker, Inc.:

  • vengono trovati i records da sincronizzare (uno o n);
  • si verifica la presenza di connesione col server;
  • In caso di esito positivo la procedura raccoglie tutti i dati relativi ad un insieme di tabelle, ad una transazione, in un unico blocco di testo;
  • viene eseguito il passaggio dei dati;
  • nel file centrale si ha – in un momento separato - la ricostruzione dei dati.

Come funziona e come facciamo a trasportare FMGo Syncro nei nostri files ?

Il porting , come dettagliato di seguito, è semplice: alcuni semplici azioni di configurazione dei files e il copia/incolla degli script, con qualche piccola modifica.

Per quanto riguarda la configurazione dei files:

1. nel file remoto deve essere impostata la posizione del file centrale, indicando a livello di Gestione origini dati (figura 2) il path al file centrale.

Fig 2

2. A livello di definizione campi va aggiunto un campo nel file remoto per marcare il record processato correttamente. Va inoltre impostata l’autoimmissione delle chiavi primarie delle varie tabelle con la funzione Get(UUID), così da renderle uniche. Nel file centrale va aggiunta la tabella Importazioni, contenente un unico campo testo, testoINPUT. Un riferimento a questa tabella va messo nel grafico delle relazioni del file remoto e va creato un layout legato a questa TO.

3. Nel file remoto deve essere creato un layout in cui vanno messi i campi della tabella master e i portali delle tabelle correlate che si vogliono sincronizzare.

Fig 3

4. In entrambi i file vanno create 2 Custom Functions per il passaggio dei dati. Sono 2 semplici CF basate sugli originali di Andy Knasinski (vedi sotto) e servono per incapsulare il testo da passare in un guscio XML così da superare agilmente ogni problema riguardante il contenuto dei nostri campi.

Fig 4


Andiamo adesso a vedere la procedura di passaggio dati.

Trasferire i dati da FileMaker Go a FileMaker

Per mostrare questa procedura ipotizziamo una situazione in cui si ha in sede remota la gestione di Preventivi (con relativa tabella contenente i dettagli del preventivo) intestati a dei Clienti con articoli inseriti da un Listino.

Le stesse tabelle sono presenti su un file centrale.

Si prevede di utilizzare il file sull'iPad con Filemaker Go inserendo i nuovi preventivi in sede remota, e successivamente passare i dati da Filemaker Go sull'iPad al file centrale ospitato da un computer della rete locale (FM server o peer-to-peer). Computer sul quale una procedura elabora i dati ricevuti dall'iPad e ricostruisce nel database centrale i preventivi creati sull'iPad.

La trasmisione dei dati avviene utilizzando uno script: quella che viene descritta è la versione che trasmette il singolo record.

Si inizia controllando che il record non sia già stato trasmesso:
If [ Preventivi::FlagProcessato = 1 ]

Beep

Show Custom Dialog [ Title: "Errore"; Message: "Il record è già stato trasferito"; Default Button: “OK”, Commit: “No” ]

Exit Script [ ]

End If

Lo script poi continua esegue il tentativo di connessione col file centrale:

Perform Script [ “Handshaking” ]

Lo script Handshaking chiama uno script nel file centrale passandogli un parametro (per il testo dello script Handshaking si veda la figura sotto:

Fig5


Set Variable [ $err; Value:Get(ScriptResult) ]

If[$err 0]

#file centrale non aperto => stop

Beep
Show Custom Dialog [ Title: "Errore"; Message: "Il file centrale non è disponibile¶Controllare che sia aperto e controllare le impostazioni¶La procedura si interrompe"; Default Button: “OK”, Commit: “Yes” ]

Exit Script [ ]

End If

Una volta accertata la presenza di connessione col file centrale si passa all'azione vera e propria:

Set Variable [ $lay; Value:Get(LayoutName) ]

Go to Layout [ “radunaDATI” (Preventivi) ]

Perform Script [ “raduna dati XML style” ]

Questo subscript è quello in cui i dati della transazione vengono raccolti in un unico blocco di testo e ritornati allo script chiamante con la funzione Get(ScriptResult). Si veda dopo per la descrizione.

Set Variable [ $dati; Value:Get ( ScriptResult ) ]

Go to Layout [ “import” (importazioni) ]

NB: il layout appartiene alla tabella del file centrale ...

New Record/Request

Set Variable [ $err; Value:Get(LastError) ]

Set Field [ importazioni::testoINPUT; $dati ]

Set Variable [ $err; Value:Get(LastError) + $err ]

Commit Records/Requests

Set Variable [ $err; Value:Get(LastError) + $err ]

Go to Layout [ $lay ]

Set Variable [ $err; Value:Get(LastError) + $err ]

Si noti l’error trapping “estremo” nel corso dello script, tale da monitorizzare un eventuale errore ad ogni step:

If [ $err = 0 ]

#nessun errore :)

Set Field [ Preventivi::FlagProcessato; 1 ]

Show Custom Dialog [ Title: "Messaggio"; Message: "Record trasferito con successo"; Default Button: “OK”, Commit: “Yes” ]

EndIf

Vediamo in dettaglio lo script [“raduna dati XML style”]. Lo script inizia impostando una serie di variabili in cui memorizzare il campo da cui si inizia la procedura e la tabella in cui siamo:

Loop

If (GetValue ( Substitute ( FieldType ( Get( FileName) ; Get ( ActiveFieldTableName ) & "::" & Get ( ActiveFieldName ) ) ; " " ; "¶" ) ; 2 )  = "container" )

il campo è di tipo contenitore

Set Variable [ $dati; Value:$dati & "¶" &

PassaXML ( Get ( ActiveFieldName ) ; Base64Encode ( GetField( Get ( ActiveFieldTableName ) & "::" & Get ( ActiveFieldName )) )) ]

Else

il campo NON è di tipo contenitore

Set Variable [ $dati; Value: $dati & "¶" & PassaXML ( Get ( ActiveFieldName ) ; Get ( ActiveFieldContents ) ) ]

End If

Questa è la parte centrale della creazione del blocco dati che contiene i dati della transazione: per ogni campo incontrato dalla procedura si crea un insieme strutturato come <nome campo>contenuto</nome campo>.

Go to Next Field
Exit Loop If [ il campo successivo appartiene ad altra tabella o è uguale al campo da cui abbiamo iniziato la procedura]
End Loop
If [ Get ( ActiveFieldTableName ) & "::" & Get ( ActiveFieldName ) = $stop ]

#non ci sono dati nei portali => stop

Set Variable [ $dati; Value:$dati & "¶" & "</" & $tab_pre & ">" & "¶¶" ]
Exit Script [ Result: $dati ]

End If

Una volta terminato il loop all'interno dei campi della tabella master si passa ai campi e ai record del portale:

Set Variable [ $dati; Value:$dati & "¶" & "</" & $tab_pre & ">" & "¶¶" & "<" & Get ( ActiveFieldTableName ) & ">"  & "¶" & "<riga" & Get ( ActivePortalRowNumber ) & ">" ]
Set Variable [ $n; Value:Get ( ActivePortalRowNumber ) ]
Set Variable [ $tabella; Value:Get ( ActiveFieldTableName ) ]

#si imposta il primo campo della prima riga>

If [il campo è di tipo contenitore]

Set Variable [ $dati; Value:$dati & "¶" & PassaXML (  Get ( ActiveFieldName ) ; Base64Encode ( GetField( Get ( ActiveFieldTableName ) & "::" & Get ( ActiveFieldName )) ) )]

Else
Set Variable [ $dati; Value:$dati & "¶" & PassaXML ( Get ( ActiveFieldName ) ; Get ( ActiveFieldContents ) )

End If
#si imposta il primo campo della prima riga/>

Loop

Go to Next Field

If [il campo successivo appartiene ad altra riga]  => si marca il fine riga

Else if

[il campo successivo  è uguale al campo da cui abbiamo iniziato la procedura] => si marca il fine tabella correlata

End If

ExitLoop If (Get ( ActiveFieldTableName )  & "::"  & Get ( ActiveFieldName ) = $stop)

If [il campo è di tipo contenitore]

Set Variable [ $dati; Value:$dati & "¶" & PassaXML (  Get ( ActiveFieldName ) ; Base64Encode ( GetField( Get ( ActiveFieldTableName ) & "::" & Get ( ActiveFieldName )) ) )]

Else
Set Variable [ $dati; Value:$dati & "¶" & PassaXML ( Get ( ActiveFieldName ) ; Get ( ActiveFieldContents ) )

End If

End Loop

Il risultato finale della procedura è un grosso blocco di testo strutturato in questo modo:

<tabella master>

<campo master>contenuto</campo master>

<altro campo master>contenuto</altro campo master>

</tabella master>

<tabella correlata>

<riga 1>

<campo correlato>contenuto</campo correlato>

<altro campo correlato>contenuto</altro campo correlato>

</riga 1>

<riga 2>

<campo correlato>contenuto</campo correlato>

<altro campo correlato>contenuto</altro campo correlato>

</riga 2>

</tabella correlata>

Lo script principale procede a trasferire questo grosso blocco di testo nella tabella Importazioni del file centrale, un record per ogni transazione, come già visto.

Conclusioni

Nella seconda parte dell'articolo proseguiremo la nostra panoramica sulla procedura di ricostruzione dati in FileMaker, e vedremo i pro e contro dell'utilizzo di FMGo Syncro. Non vedete l'ora di metterlo alla prova? Nel prossimo articolo troverete allegato FMGo Syncro, nella sua ultima versione e scaricabile in modo totalmente gratuito.

Alla prossima!

Qual è il tuo metodo preferito per sincronizzare un database? Raccontaci la tua soluzione e condividi le tue idee con gli altri Guru: scopri la comunità FileMaker su Guru Corner!

2 Commenti

  1. Ho caricato sul server il mio db. Quando ora vado sulla mia scrivania e clicco sul file, mi si apre una finestra che mi chiede se voglio usare la versione local o la versione ospitata.
    Avevo precedentemente aggiunto una scheda nella versione ospitata e una diversa della versione local.
    Speravo che almeno una delle due si aggiornasse. Sopratutto che la scheda Local importasse quanto inserito in quella ospitata.E' invece no 🙁
    Ma dalla spiegazione data nell'articolo non capisco come devo fare per effettuare la sincronizzazione bidirezionale o monodirezionale.

  2. Ciao Caterina
    Diciamo che la cosa è un pò un gioco di specchi, ed è facile fare confusione 🙁
    La sincronizzazione che si intende realizzare è MONO direzionale, dal file Remoto (quello che ti porti in giro) a quello Centrale (quello che risiede nella rete locale)
    Quindi nel file remoto deve essere impostata la posizione del file centrale, indicando a livello di Gestione origini dati il path al file centrale.
    Poi lanci la procedura che
    1. verifica che ci sia connessione al file centrale
    2. raduna i dati da "impacchettare"
    3. li passa ad una tabella del file centrale in un unico blocco XML

    Separamente, in un secondo tempo, nel file Centrale esegui la procedura con cui dall'XML metti i dati nelle varie tabelle

    Spero di averti aiutato, se ti serve altro scrivici 🙂

LASCIA UN COMMENTO

Please enter your comment!
Please enter your name here