Per salutarvi dopo la pausa estiva voglio riaprire il blog scegliendo l’argomento dei Tips&Tricks per il quale avete mostrato più interesse: come sincronizzare modifiche al database effettuate da software esterni.
Come sapete, il servizio di sincronizzazione della Document Orientation usa due modalità diverse a seconda delle condizioni: completa o parziale. Quando l’utente sincronizza per la prima volta (o non lo fa da troppo tempo) viene usata la sincronizzazione completa, in cui tutti i documenti vengono letti dalle relative tabelle del database e inviati al device. Quando l’utente deve ricevere soltanto le ultime variazioni viene usata la sincronizzazione parziale, dove i dati sono letti dalla tabella ZZ_Sync. Il framework scrive le variazioni nella ZZ_Sync tutte le volte che viene modificato un documento che ha il flag Sincronizzazione abilitato.
Il problema nasce se ci sono altri software che modificano la stessa base dati perché in questo caso nessuno si occupa di scrivere le variazioni, che quindi non verranno inviate al dispositivo durante la prossima sincronizzazione parziale. Per risolvere dobbiamo trovare il modo di aggiornare correttamente la ZZ_Sync.
Per farlo non è consigliabile aggiornare direttamente il database, perché è complicato e dovremmo conoscere la sintassi giusta. L’approccio migliore consiste nell’usare lo stesso framework, simulando un salvataggio. In questo progetto di esempio abbiamo ottenuto il risultato desiderato per la classe Product usando:
- la proprietà di classe Product.LastExternalChange.
- la procedura HandleExternalChanges.
- l’evento Product.BeforeSave.
La proprietà LastExternalChange rappresenta la risposta alla domanda “quand’è che l’applicazione esterna ha modificato il prodotto nel database?”. Questo è l’unico vero requisito che deve essere soddisfatto, senza rispondere a questa domanda non si può sapere quali prodotti devono essere gestiti. Nel nostro caso è valorizzata dalla procedura SimulateExternalChange con un update sulla tabella. Potete verificarlo subito, avviate le applicazioni del progetto e sincronizzate l’app mobile, poi usate il bottone SimulateExternalChange dell’applicazione web e sincronizzate nuovamente, vedrete che quest’ultima modifica viene ignorata.
Nella procedura HandleExternalChanges prendiamo tutti i prodotti modificati dall’applicazione esterna, ne mettiamo a true la proprietà inserted e impostiamo un tag skipupdating con valore -1. Dopodiché salviamo il prodotto.
Nell’evento Product.BeforeSave, se il tag skipupdating vale -1, simuliamo il salvataggio impostando a true il parametro skip.
Grazie a inserted = true il prodotto è considerato come da inserire sul database e grazie a skip = true il salvataggio non viene davvero eseguito. In questo caso particolare il framework scriverà comunque nella ZZ_Sync una nuova variazione contenente tutte le proprietà del documento, anche quelle modificate dall’applicazione esterna. Usate il comando HandleExternalChanges dell’applicazione web e poi sincronizzate nuovamente l’app mobile per vedere il risultato.
Beh, a questo punto buona sincronizzazione 🙂