Autore Topic: Upgrade db SqLite  (Letto 576 volte)

Offline wlf

  • Utente normale
  • ***
  • Post: 367
  • Respect: +8
    • Mostra profilo
  • Dispositivo Android:
    Xperia
Upgrade db SqLite
« il: 04 Luglio 2014, 16:19:30 CEST »
0
Salve,
esiste qualche tecnica per aggiornare il db facendo in modo che i dati presenti vengano aggiornati senza eliminarli completamente?

Codice (Java): [Seleziona]
  @Override
    public void onUpgrade( SQLiteDatabase database, int oldVersion, int newVersion ) {
        Log.w(DbHelper.class.getName(),
                                "Upgrading database from version " + oldVersion + " to "
                                                + newVersion + ", which will destroy all old data");
        database.execSQL("DROP TABLE IF EXISTS movdb");
        onCreate(database);    
    }

Aggiungendo uno o più campi ai record sarebbe possibile mantenere i dati salvati? In caso affermativo sapreste indicarmi un esempio dal quale prendere ispirazione?
Grazie.

Offline BlackJad

  • Utente junior
  • **
  • Post: 59
  • Respect: +6
    • Google+
    • michele-ziparo/4/825/a99/
    • blackjad82
    • Mostra profilo
    • Datawit Systems
  • Dispositivo Android:
    Samsung Galaxy S3
  • Play Store ID:
    Michele Ziparo
  • Sistema operativo:
    Windows 8.1
Re:Upgrade db SqLite
« Risposta #1 il: 05 Luglio 2014, 17:15:06 CEST »
0
La tecnica è semplice, nel metodo onUpgrade togli le ultime due righe, e poi fai semplicemente un confronto sulle versioni del DB.

Ad esempio, sicuramente avrai dichiarato una variabile che mantiene la versione corrente del DB

Codice (Java): [Seleziona]
public static final int DATABASE_VERSION = 1;
Una volta eseguita l'app e creato il DB, ogni qualvolta hai una modifica da apportare alla struttura ( o altre necessità ovviamente ) devi aggiornare il valore di DATABASE_VERSION.

Alla successiva esecuzione la tua app vedrà la nuova versione, e quando verrà eseguito onUpgrade un codice come questo

Codice (Java): [Seleziona]
@Override
public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource, int oldVersion, int newVersion) {
        try {
                Log.i(DatabaseHelper.class.getName(), "onUpgrade");

                switch(oldVersion)
                {
                        case 1:
                                switch(newVersion)
                                {
                                        case 2:
                                                // Fai qualcosa
                                                break;
                                }
                                break;
                }

        } catch (SQLException e) {
                Log.e(DatabaseHelper.class.getName(), "Can't upgrade databases", e);
        }
}

ti permette di eseguire le modifiche necessarie, senza ricreare il DB o cancellare le tabelle.

Il mio esempio si riferisce ad una situazione del tipo: se sto eseguendo l'app con DB alla versione 2 e provengo da DB alla versione 1, faccio questo ...

Quindi puoi implementare, come dicevo, i controlli necessari alla tua situazione specifica.

Offline wlf

  • Utente normale
  • ***
  • Post: 367
  • Respect: +8
    • Mostra profilo
  • Dispositivo Android:
    Xperia
Re:Upgrade db SqLite
« Risposta #2 il: 07 Luglio 2014, 09:41:53 CEST »
0
La tecnica è semplice, nel metodo onUpgrade togli le ultime due righe, e poi fai semplicemente un confronto sulle versioni del DB.
Ad esempio, sicuramente avrai dichiarato una variabile che mantiene la versione corrente del DB
Codice (Java): [Seleziona]
public static final int DATABASE_VERSION = 1;Una volta eseguita l'app e creato il DB, ogni qualvolta hai una modifica da apportare alla struttura ( o altre necessità ovviamente ) devi aggiornare il valore di DATABASE_VERSION.

Fino a qui era tutto chiaro; DATABASE_VERSION presente del DbHelper incrementandolo mi serviva appunto per aggiornare il DB con la DROP TABLE e la successiva chiamata alla onCreate.
Era ovvio che era necessario togliere la DROP e quindi anche la onCreate .... ;)

Citazione
Alla successiva esecuzione la tua app vedrà la nuova versione, e quando verrà eseguito onUpgrade un codice come questo
Codice (Java): [Seleziona]
@Override
public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource, int oldVersion, int newVersion) {
        try {
                Log.i(DatabaseHelper.class.getName(), "onUpgrade");

                switch(oldVersion)
                {
                        case 1:
                                switch(newVersion)
                                {
                                        case 2:
                                                // Fai qualcosa
                                                break;
                                }
                                break;
                }

        } catch (SQLException e) {
                Log.e(DatabaseHelper.class.getName(), "Can't upgrade databases", e);
        }
}
ti permette di eseguire le modifiche necessarie, senza ricreare il DB o cancellare le tabelle.
Il mio esempio si riferisce ad una situazione del tipo: se sto eseguendo l'app con DB alla versione 2 e provengo da DB alla versione 1, faccio questo ...
Quindi puoi implementare, come dicevo, i controlli necessari alla tua situazione specifica.

Ok, quindi qui posso inserire una ALTER TABLE come nell'esempio sottostante?

Codice (Java): [Seleziona]
    @Override
    public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion) {
                try {
                Log.i(DbHelper.class.getName(), "onUpgrade");
                switch(oldVersion) {
                    case 1:
                        switch(newVersion) {
                                case 2:
                                        database.execSQL("ALTER TABLE movdb ADD movflag integer default 0");
                                        break;
                        }
                        break;
                }
       
            } catch (SQLException e) {
            Log.e(DbHelper.class.getName(), "Can't upgrade databases", e);
            }
    }

Perché nel tuo esempio la onUpgrade ha ance un ConnectionSource mentre invece guardando nella documentazione il metodo è definito:
Codice (Java): [Seleziona]
public abstract void onUpgrade (SQLiteDatabase db, int oldVersion, int newVersion)

Offline BlackJad

  • Utente junior
  • **
  • Post: 59
  • Respect: +6
    • Google+
    • michele-ziparo/4/825/a99/
    • blackjad82
    • Mostra profilo
    • Datawit Systems
  • Dispositivo Android:
    Samsung Galaxy S3
  • Play Store ID:
    Michele Ziparo
  • Sistema operativo:
    Windows 8.1
Re:Upgrade db SqLite
« Risposta #3 il: 07 Luglio 2014, 14:29:35 CEST »
+1
Esatto se usi quella tecnica sei a posto.

I miei parametri non corrispondono ai tuoi perchè uso qualcosa di personalizzato, ma la sostanza non cambia  :-)

Offline wlf

  • Utente normale
  • ***
  • Post: 367
  • Respect: +8
    • Mostra profilo
  • Dispositivo Android:
    Xperia
Re:Upgrade db SqLite
« Risposta #4 il: 01 Agosto 2014, 18:06:57 CEST »
0
Dopo la alter table sottostante è possibile fare un ciclo for per tutte le righe inserite nel db?

Codice (Java): [Seleziona]
database.execSQL("ALTER TABLE movdb ADD movflag integer default 0");
Nello specifico avrei bisogno di ricalcolare un checksum del DB; inserendo un campo nuovo il checksum del DB non mi torna più! :(
Sarebbe quindi possibile eseguire una query che ritorna un cursor per ricalcolare il checksum di tutte le righe facendo un update?

Grazie. ;)

Offline BlackJad

  • Utente junior
  • **
  • Post: 59
  • Respect: +6
    • Google+
    • michele-ziparo/4/825/a99/
    • blackjad82
    • Mostra profilo
    • Datawit Systems
  • Dispositivo Android:
    Samsung Galaxy S3
  • Play Store ID:
    Michele Ziparo
  • Sistema operativo:
    Windows 8.1
Re:Upgrade db SqLite
« Risposta #5 il: 01 Agosto 2014, 18:33:15 CEST »
0
Scusa ma non ho capito bene cosa vorresti fare :)

Offline wlf

  • Utente normale
  • ***
  • Post: 367
  • Respect: +8
    • Mostra profilo
  • Dispositivo Android:
    Xperia
Re:Upgrade db SqLite
« Risposta #6 il: 02 Agosto 2014, 14:38:41 CEST »
0
Dopo aver aggiunto un campo nella tabella del DB avrei la necessità di scorrere tutti i record facendo un ricalcolo del checksum di riga. Praticamente ho un campo che mi dice se il record è corretto oppure è stato "manomesso"; aggiungendo un campo nel DB il checksum mi risulta errato, quindi avrei la necessità di ricalcolare il checksum di ogni riga della tabella del DB modificata.
Praticamente, dopo la ALTER TABLE potre aggiungere qualcosa del tipo:

Codice (Java): [Seleziona]
        Cursor cursor;

        //Faccio una SELECT * FROM DATABASE_TABLE ordinata per MOVID
        cursor = database.query(DATABASE_TABLE, new String[] {"*"}, null,
                                null, null, null, DbHelper.COLUMN_MOVID + " ASC");
                cursor.moveToFirst();
                while (!cursor.isAfterLast()) {

                        //Calcolo il mio checksum
                        String strchk = cursor.getLong(0) + cursor.getString(1) + cursor.getString(2) + cursor.getDouble(3);

                        ContentValues args = new ContentValues();
                    args.put(COLUMN_CHECK, strchk);
                    database.update(DATABASE_TABLE, args, COLUMN_MOVID + "=" + cursor.getLong(0), null);                                                               
                        cursor.moveToNext();
                }

                cursor.close();