Autore Topic: Sincronizzazione fra mysql e sqlite  (Letto 2017 volte)

Offline mrfalco

  • Utente junior
  • **
  • Post: 81
  • Respect: +2
    • Mostra profilo
    • www.falcodomingo.it
  • Dispositivo Android:
    Samsung Galazy S
  • Sistema operativo:
    Windows Vista
Sincronizzazione fra mysql e sqlite
« il: 04 Luglio 2011, 19:59:08 CEST »
0
Ciao a tutti come da titolo sto creando un'applicativo che invia e riceve dati verso mysql (lato server) e con sqlite(lato android).
Fin qui tutto bene.
Uso json come parser e php per scrivere su mysql.

Solo che volevo scrivere una classe che sincronizzava(in background) una o piu' tabelle dei 2 database(mysql e sqlite).

Qualcuno ha realizzato qualcosa in proposito?

Grazie

Offline mrfalco

  • Utente junior
  • **
  • Post: 81
  • Respect: +2
    • Mostra profilo
    • www.falcodomingo.it
  • Dispositivo Android:
    Samsung Galazy S
  • Sistema operativo:
    Windows Vista
Re:Sincronizzazione fra mysql e sqlite
« Risposta #1 il: 05 Luglio 2011, 08:51:23 CEST »
0
Buongiorno mi era venuta un'idea di prendere i resultset dei 2 db e crearmi 2 arraylist in modo che tramite una function gli passo i 2 array e me ne restituisce un terzo che contiene le differenze aggiornate.

Credo sia una buona idea ma bisogna vedere quanto tempo porta via

Grazie

Offline mrfalco

  • Utente junior
  • **
  • Post: 81
  • Respect: +2
    • Mostra profilo
    • www.falcodomingo.it
  • Dispositivo Android:
    Samsung Galazy S
  • Sistema operativo:
    Windows Vista
Re:Sincronizzazione fra mysql e sqlite
« Risposta #2 il: 05 Luglio 2011, 09:00:13 CEST »
0
oppure si potrebbe fare in questo modo recupero i dati sotto query da my sql e li inserisco in una tabella alias alla prima e poi di li ci vorrebbe un metodo che sincronizzasse le 2 tabelle in sqlite.

Offline denper

  • Utente normale
  • ***
  • Post: 290
  • Respect: +60
    • Mostra profilo
    • Anddenper
  • Dispositivo Android:
    Moto G
  • Play Store ID:
    denper
  • Sistema operativo:
    Window 7, Windows XP
Re:Sincronizzazione fra mysql e sqlite
« Risposta #3 il: 05 Luglio 2011, 09:07:29 CEST »
0
Ciao,
la sincronizzazione che logiche segue? Le modifiche posso avvenire in entrambi i db? In ogni caso ti consiglierei di aggiungere in tutte le tabelle un flag che indica se il record è già stato sincronizzato o meno. Ogni volta che viene eseguita la sincronizzazione, si selezionano solo i record con flag a false, una volta che i dati sono stati correttamente salvati sull'altro db, si fa un update di questo flag a true. Gestendo poi un campo id come chiave primaria nelle tabelle, nel caso in cui il record fosse presente in entrambe le tabelle e si provasse a sincronizzarle, avresti un eccezione di chiave duplicata che dovresti gestire come meglio preferisci. Il job di sincronizzazione potresti poi gestirlo tramite l'invio di Message con deley ad un handler. Se hai bisogno di un esempio fammi sapere.

denper.
Tutti sanno che una cosa è impossibile da realizzare, finché arriva uno sprovveduto che non lo sa e la inventa. [A.Einstein]

Proteggi la tua privacy! Utilizza GhostPhone! https://play.google.com/store/apps/details?id=com.denper.gp
Giochi a Winforlife e Superenalotto e sei stanco di controllare le tue schedine manualmente? Prova Checkwin: https://play.google.com/store/apps/details?id=com.denper.checkwintrial

Offline mrfalco

  • Utente junior
  • **
  • Post: 81
  • Respect: +2
    • Mostra profilo
    • www.falcodomingo.it
  • Dispositivo Android:
    Samsung Galazy S
  • Sistema operativo:
    Windows Vista
Re:Sincronizzazione fra mysql e sqlite
« Risposta #4 il: 05 Luglio 2011, 09:12:38 CEST »
0
Grazie per la tua risposta cerco di spiegarmi meglio.

in pratica ho un server mysql utilizzato da diverse postazioni e tra un po aggiungero anche android a me interessa sapere cio' che cambia in una tabella di mysql ogni 5/10 secondi per poi riflettere i cambiamenti nel db sqlite.
Attenzione il cambiamento puo' essere nuovo record record eliminato oppure record modificato.
Pensavo che se mi riprendo ogni tot secondi tramite json la query mysql ovviamente le colonne ordinate come sqlite table, potevo verificare cosa è cambiato.

Spero di essere stato chiaro grazie

Offline denper

  • Utente normale
  • ***
  • Post: 290
  • Respect: +60
    • Mostra profilo
    • Anddenper
  • Dispositivo Android:
    Moto G
  • Play Store ID:
    denper
  • Sistema operativo:
    Window 7, Windows XP
Re:Sincronizzazione fra mysql e sqlite
« Risposta #5 il: 05 Luglio 2011, 09:27:09 CEST »
0
Allora,
io gestirei questa cosa nel seguente modo:

nuovo record o modifica record: quando viene inserito un nuovo record o modificato uno esistente in mysql il flag sincronizzazione viene posto a false. In Android la sincronizzazione seleziona tutti i record con flag a false e li inserisce in sqlite, poi fa un update su mysql in modo da aggiornare questi record con flag a true.
record cancellato: lato mysql io creerei una tabella 'records_cancellati' che andrei a popolare ogni volta che un record viene cancellato. Anche in questa tablella utilizzerei il flag sincronizzazione. Poi la logica di sincronizzazione è uguale a prima solo che invece di inserire i record li cancello.

Ovviamente questo sistema va bene se hai un unica postazione android che deve essere sincronizzata con mysql, se le postazioni sono multiple la faccenda si complica. In questo caso, a mio avviso, dovresti utilizzare delle tabelle di appoggio dove inserisci che il record con id x è stato sincronizzato con il device android y.
Tutti sanno che una cosa è impossibile da realizzare, finché arriva uno sprovveduto che non lo sa e la inventa. [A.Einstein]

Proteggi la tua privacy! Utilizza GhostPhone! https://play.google.com/store/apps/details?id=com.denper.gp
Giochi a Winforlife e Superenalotto e sei stanco di controllare le tue schedine manualmente? Prova Checkwin: https://play.google.com/store/apps/details?id=com.denper.checkwintrial

Offline mrfalco

  • Utente junior
  • **
  • Post: 81
  • Respect: +2
    • Mostra profilo
    • www.falcodomingo.it
  • Dispositivo Android:
    Samsung Galazy S
  • Sistema operativo:
    Windows Vista
Re:Sincronizzazione fra mysql e sqlite
« Risposta #6 il: 05 Luglio 2011, 09:30:58 CEST »
0
Grazie per la risposta ,stavo pensando che l'applicativo server ogni volta che fa un crud mi aggiorna il campo ora nella tabella server potrei in android memorizzando l'ultima ora prendere tutti i rekord cambiati da quell'ora in poi?

che dici

grazie ciao

Offline mrfalco

  • Utente junior
  • **
  • Post: 81
  • Respect: +2
    • Mostra profilo
    • www.falcodomingo.it
  • Dispositivo Android:
    Samsung Galazy S
  • Sistema operativo:
    Windows Vista
Re:Sincronizzazione fra mysql e sqlite
« Risposta #7 il: 05 Luglio 2011, 09:36:24 CEST »
0
A prescindere dal modo che usero' per effettuare la sync volevo fare in android in questo modo all'apertura dell'applicativo android lanciare in background un thread che sta li in azione e ogni tot secondi effettua il giro.
In proposito hai qualche esempio su come strutturare il thread?

Offline denper

  • Utente normale
  • ***
  • Post: 290
  • Respect: +60
    • Mostra profilo
    • Anddenper
  • Dispositivo Android:
    Moto G
  • Play Store ID:
    denper
  • Sistema operativo:
    Window 7, Windows XP
Re:Sincronizzazione fra mysql e sqlite
« Risposta #8 il: 05 Luglio 2011, 09:57:01 CEST »
0
Ciao,
questo è un esempio che avevo utilizzato.

Codice (Java): [Seleziona]
public final class DbSynchronizer {

        private final ScheduledExecutorService synchronizerTimer = Executors.newSingleThreadScheduledExecutor(new DaemonThreadFactory());
        private ScheduledFuture<?> synchronizerFuture = null;

        private final DataHelper database;
        private final SharedPreferences prefs;

        public DbSynchronizer(DataHelper database, SharedPreferences prefs) {
                this.database = database;
                this.prefs = prefs;
                startSyncTimer();
        }

        public void startSyncTimer() {
                cancel();
                synchronizerFuture = synchronizerTimer.schedule(new DbSynchronizerListener(this, database), Long.parseLong(prefs.getString(PreferencesActivity.KEY_SYNCHRONIZER_DELAY_SECONDS,
                                PreferencesActivity.DEFAULT_SYNCHRONIZER_DELAY_MINUTES)) * 60, TimeUnit.SECONDS);
        }

        private void cancel() {
                if (synchronizerFuture != null) {
                        synchronizerFuture.cancel(true);
                        synchronizerFuture = null;
                }
        }

        public void shutdown() {
                cancel();
                synchronizerTimer.shutdown();
        }

        private static final class DaemonThreadFactory implements ThreadFactory {
                public Thread newThread(Runnable runnable) {
                        Thread thread = new Thread(runnable);
                        thread.setDaemon(true);
                        return thread;
                }
        }

}

public final class DbSynchronizerListener implements DialogInterface.OnClickListener, DialogInterface.OnCancelListener, Runnable {

        private final DbSynchronizer dbSynchronizer;
        private final DataHelper database;

        public DbSynchronizerListener(DbSynchronizer dbSynchronizer, DataHelper database) {
                this.dbSynchronizer = dbSynchronizer;
                this.database = database;
        }

        public void onCancel(DialogInterface dialogInterface) {
                run();
        }

        public void onClick(DialogInterface dialogInterface, int i) {
                run();
        }

        public void run() {
                database.sendJson();
                dbSynchronizer.startSyncTimer();
        }
}

questa potrebbe essere la struttura del metodo sendJson, io l'ho gestito sulla classe del db:

Codice (Java): [Seleziona]
synchronized protected void sendJson() {
                if (db.isOpen()) {
                        String serverReponse = "";
                        Log.i(TAG, "Sending data to server...");
                        try {
                                JSONObject jsonobj = null;
                                Map<String, String> kvPairs = new HashMap<String, String>();
                                // Normally I would pass two more JSONObjects.....
                                HttpResponse re = null;
                                Record record;
                                ArrayList<Record> records = getRecordsToSend();
                                if (records.size() == 0) {
                                        Log.i(TAG, "No data to synchronize with server");
                                }
                                for (int i = 0; i < records.size(); i++) {
                                        record = records.get(i);
                                        jsonobj = new JSONObject();
                                        jsonobj.put("id", records.id);
                                        jsonobj.put("field1", records.field1);
                                        jsonobj.put("field2", records.field2);
                                        ...
                                        kvPairs.put("action", "update");
                                        kvPairs.put("record", jsonobj.toString());
                                        re = HTTPPoster.doPost(remoteServerUrl, kvPairs);
                                        serverReponse = EntityUtils.toString(re.getEntity());
                                        long serverId = new Long(serverReponse.trim()).longValue();
                                        if (serverId > 0) {
                                                Log.v(TAG, "Record id " + Record.id + " synchronize with server");
                                        } else {
                                                Log.e(TAG, "Record id " + Record.id + " NOT synchronize with server");
                                        }
                                }
                        } catch (ClientProtocolException e) {
                                e.printStackTrace();
                        } catch (IOException e) {
                                e.printStackTrace();
                        } catch (JSONException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                        }
                }
}

nella activity principale dovresti poi

Codice (Java): [Seleziona]
DbSynchronizer dbSynchronizerTimer = new DbSynchronizer(database, prefs);
e nel metodo onDestroy()

Codice (Java): [Seleziona]
if (dbSynchronizerTimer != null) {
      dbSynchronizerTimer.shutdown();
}

Come vedi nel costruttore io ho passato le SharedPreferences dove ho gestito i valori dei timer per la sincronizzazione.

Ovviamente questo è solo un esempio e un modo di gestire un'attività di sincronizzazione tra db, a mio avviso non estremamente complicato.
« Ultima modifica: 05 Luglio 2011, 10:01:15 CEST da denper »
Tutti sanno che una cosa è impossibile da realizzare, finché arriva uno sprovveduto che non lo sa e la inventa. [A.Einstein]

Proteggi la tua privacy! Utilizza GhostPhone! https://play.google.com/store/apps/details?id=com.denper.gp
Giochi a Winforlife e Superenalotto e sei stanco di controllare le tue schedine manualmente? Prova Checkwin: https://play.google.com/store/apps/details?id=com.denper.checkwintrial

Offline mrfalco

  • Utente junior
  • **
  • Post: 81
  • Respect: +2
    • Mostra profilo
    • www.falcodomingo.it
  • Dispositivo Android:
    Samsung Galazy S
  • Sistema operativo:
    Windows Vista
Re:Sincronizzazione fra mysql e sqlite
« Risposta #9 il: 05 Luglio 2011, 11:18:30 CEST »
0
grazie per l'interessamento e scusa per la mia cocciutagine ma mi chiedevo questo perchè non mi è chiaro:

all'apertura dell'applicativo android io vorrei lanciare in background un thread che non interferisca con la ui principale e che fa un certo lavoro e cioè leggi la query tramite json e poi verifica i cambiamenti poi si ferma per tot secondi ad es 10 e poi riparte.

Alla chiusura dell'applicativo il thread deve andare in chiusura.

poi mi chiedevo se qui tra l'applicativo e la classe che si occupa del thread c'è la possibilità di condividere una variabile global in modo che posso sapere come farli comunicare.

Grazie e scusami se sono un pochino tonto.

Offline denper

  • Utente normale
  • ***
  • Post: 290
  • Respect: +60
    • Mostra profilo
    • Anddenper
  • Dispositivo Android:
    Moto G
  • Play Store ID:
    denper
  • Sistema operativo:
    Window 7, Windows XP
Re:Sincronizzazione fra mysql e sqlite
« Risposta #10 il: 05 Luglio 2011, 11:33:42 CEST »
0
Se tu istanzi nell'onCreate della tua activity il DbSynchronizer, questo parte esegue la sincronizzazione e poi si rischedula a partire nuovamente tra x secondi (PreferencesActivity.DEFAULT_SYNCHRONIZER_DELAY_MINUTES), questo avviene qui:

Codice (Java): [Seleziona]
public void startSyncTimer() {
                cancel();
                synchronizerFuture = synchronizerTimer.schedule(new DbSynchronizerListener(this, database), Long.parseLong(prefs.getString(PreferencesActivity.KEY_SYNCHRONIZER_DELAY_SECONDS,
                                PreferencesActivity.DEFAULT_SYNCHRONIZER_DELAY_MINUTES)) * 60, TimeUnit.SECONDS);
        }

In che senso devi fare comunicare l'activity principale con il DbSynchronizer? Una volta che tu hai istanziato il DbSynchronizer nell'activity principale poi stopparlo e avviarlo a tuo piacimento. Ciò non toglie che nel costruttore del DbSynchronizer puoi passargli l'activity...
Tutti sanno che una cosa è impossibile da realizzare, finché arriva uno sprovveduto che non lo sa e la inventa. [A.Einstein]

Proteggi la tua privacy! Utilizza GhostPhone! https://play.google.com/store/apps/details?id=com.denper.gp
Giochi a Winforlife e Superenalotto e sei stanco di controllare le tue schedine manualmente? Prova Checkwin: https://play.google.com/store/apps/details?id=com.denper.checkwintrial

Offline mrfalco

  • Utente junior
  • **
  • Post: 81
  • Respect: +2
    • Mostra profilo
    • www.falcodomingo.it
  • Dispositivo Android:
    Samsung Galazy S
  • Sistema operativo:
    Windows Vista
Re:Sincronizzazione fra mysql e sqlite
« Risposta #11 il: 05 Luglio 2011, 11:53:00 CEST »
0
In pratica io non in java sono abituato a lavorare in questo modo dalla main dichiaro un thread e poi gli passo tramite address of un metodo e prima di fare lo start gli dico is inbackground.

in un modulo ho delle variabili globali.

in questo modo posso dire ad esempio al metodo che gira nel thread se una variabile ad es è true fermati un attimo e riprendi quando è false perche' magari anche l'applicativo puo' fare degli aggiornamenti e allora il sync deve aspettare che l'applicativo finisca e non viceversa.

Grazie

Offline mrfalco

  • Utente junior
  • **
  • Post: 81
  • Respect: +2
    • Mostra profilo
    • www.falcodomingo.it
  • Dispositivo Android:
    Samsung Galazy S
  • Sistema operativo:
    Windows Vista
Re:Sincronizzazione fra mysql e sqlite
« Risposta #12 il: 05 Luglio 2011, 19:12:25 CEST »
0
Ciao volevo aggiornarti sulla situazione:
Sono riuscito a crearmi tramite un servizio una procedura che mediante dei metodi mi sincronizza le 2 tabelle di cui ti dicevo. In particolare ho fatto cosi mi sono creato una tabella alias specchio dell'altra e in questa alias ogni tot secondi mi prendo tutti i rekord ancora aperti in questo modo poi demando a sqlite tramite select * from tabella1 expect select * from tabella2 mi tira fuori subito le differenze poi faccio l'inverso cosi sono a posto per la sync. La cosa che non riesco a variare è l'INTERVAL del metodo

Codice (Java): [Seleziona]
                            timer.scheduleAtFixedRate( new TimerTask() {

                        public void run() {
                        //Do whatever you want to do every “INTERVAL”
                                if(wifiManager.isWifiEnabled()){
                        }else{
                                wifiManager.setWifiEnabled(true);
                        }
                                while (Update.getLocalIpAddress() == null){
                                        SystemClock.sleep(1000);
                                }
                                //metodi();
                        }
                       
                }, 0, INTERVAL);

puoi aiutarmi?
grazie

Offline denper

  • Utente normale
  • ***
  • Post: 290
  • Respect: +60
    • Mostra profilo
    • Anddenper
  • Dispositivo Android:
    Moto G
  • Play Store ID:
    denper
  • Sistema operativo:
    Window 7, Windows XP
Re:Sincronizzazione fra mysql e sqlite
« Risposta #13 il: 05 Luglio 2011, 22:10:12 CEST »
0
Sinceramente, io avrei usato il metodo che ti ho illustrato precedentemente, oppure tramite un Handler e un Message inviato ogni tot secondi. Immagino che la variabile INTERVAL tu l'abbia espressa in millisecs, giusto? Prova a dare un occhio qui, non so se può aiutarti.
« Ultima modifica: 05 Luglio 2011, 22:13:31 CEST da denper »
Tutti sanno che una cosa è impossibile da realizzare, finché arriva uno sprovveduto che non lo sa e la inventa. [A.Einstein]

Proteggi la tua privacy! Utilizza GhostPhone! https://play.google.com/store/apps/details?id=com.denper.gp
Giochi a Winforlife e Superenalotto e sei stanco di controllare le tue schedine manualmente? Prova Checkwin: https://play.google.com/store/apps/details?id=com.denper.checkwintrial

Offline mrfalco

  • Utente junior
  • **
  • Post: 81
  • Respect: +2
    • Mostra profilo
    • www.falcodomingo.it
  • Dispositivo Android:
    Samsung Galazy S
  • Sistema operativo:
    Windows Vista
Re:Sincronizzazione fra mysql e sqlite
« Risposta #14 il: 05 Luglio 2011, 22:15:33 CEST »
0
si l'ho espressa in millesecondi anche mettendo 10000 sempre piu' o meno 5 secondi ci mette
non te la prendere se non ho usato il tuo consiglio ma non sono pratica di handler in java
grazie lo stesso ciao