Autore Topic: Aggiornamento database esistente a nuova versione  (Letto 648 volte)

Offline E.Musso

  • Utente junior
  • **
  • Post: 82
  • Respect: +17
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy GT-S5660
  • Play Store ID:
    Emiliano Musso
  • Sistema operativo:
    Windows 7
Aggiornamento database esistente a nuova versione
« il: 17 Gennaio 2012, 16:25:44 CET »
0
Buongiorno a tutti,
avrei necessità di un aiuto relativo all'aggiornamento di database, una volta che si è già rilasciata un'app ma si ha il bisogno di variare la struttura del DB, per implementare, ad esempio, nuove tabelle.

Incollo qui sotto due snippet: il primo è relativo alla mia classe-tipo di gestione database, mentre il secondo riguarda l'inizializzazione della classe DatabaseHelper, che sostanzialmente eseguo alla prima occasione utile nell'Activity principale

Codice (Java): [Seleziona]
public class DatabaseHelper extends SQLiteOpenHelper{
         
    private static String DB_PATH = "/data/data/MIO_PACKAGE/databases/";
    private static String DB_NAME = "dbase.db";
    private static SQLiteDatabase myDataBase;
 
    private final Context myContext;

    public DatabaseHelper(Context context) {
        super(context, DB_NAME, null, 1);
        this.myContext = context;
    }  
 
    public void createDataBase() throws IOException{
        boolean dbExist = checkDataBase();
        if(!dbExist){
                this.getReadableDatabase();
                try {
                        copyDataBase();
                } catch (IOException e) {
                        throw new Error("Errore nella copia del database");
                }
        }
     }
 
    private boolean checkDataBase(){
        SQLiteDatabase checkDB = null;
        try{
                String myPath = DB_PATH + DB_NAME;
                checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
        }catch(SQLiteException e){
        }
        if(checkDB != null){
                checkDB.close();
        }
        return checkDB != null ? true : false;
    }
 
    private void copyDataBase() throws IOException{
        InputStream myInput = myContext.getAssets().open(DB_NAME);
        String outFileName = DB_PATH + DB_NAME;
        OutputStream myOutput = new FileOutputStream(outFileName);
        byte[] buffer = new byte[1024];
        int length;
        while ((length = myInput.read(buffer))>0){
                myOutput.write(buffer, 0, length);
        }
        myOutput.flush();
        myOutput.close();
        myInput.close();
    }
 
    public void openDataBase() throws SQLException{
        String myPath = DB_PATH + DB_NAME;
        myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
    }
 
    @Override
        public synchronized void close() {
        if(myDataBase != null) myDataBase.close();
        super.close();
        }
 
        @Override
        public void onCreate(SQLiteDatabase db) {       }
 
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {      }
 
   
}

Codice (Java): [Seleziona]
        DatabaseHelper helper    = new DatabaseHelper( this );
        try {
           helper.createDataBase();
           helper.openDataBase();
        } catch (Exception e) { }    

Praticamente, anche se nell'assets ho aggiornato il database, nel modo in cui faccio di solito, per rendere fruibile il nuovo database lato app sul device è necessario andare in gestione applicazioni, e cancellare i dati dell'app: soltanto allora, l'app genererà un nuovo db con le ultime caratteristiche.

Vorrei però che questo potesse avvenire quando l'utente lancia la nuova versione dell'app: il programma dovrebbe accorgersi che ha davanti una nuova versione, e quindi dovrebbe sovrascrivere il database esistente. All'esecuzione successiva, invece, e fino a che non rilascerò successive modifiche, non dovrebbe toccarlo, ma limitarsi all'apertura.

Qualche consiglio su come posso fare?
Anticipatamente grazie.
Bollettazione Interventi - Un taglio ai costi di tipografia per professionisti!
--
È stata trovata una soluzione al tuo problema?Evidenzia il post più utile premendo . È un ottimo modo per ringraziare chi ti ha aiutato

Offline Sakazaki

  • Utente normale
  • ***
  • Post: 396
  • Respect: +74
    • Mostra profilo
  • Dispositivo Android:
    Sony xperia Z
  • Play Store ID:
    Saka Labs
  • Sistema operativo:
    Windows 8
Re:Aggiornamento database esistente a nuova versione
« Risposta #1 il: 06 Marzo 2012, 17:36:25 CET »
0
Il trucco sta nell'usare in modo accorto l'ultimo parametro che passi al super nel costruttore della tuo DatabaseHelper:

Codice (Java): [Seleziona]
public DatabaseHelper(Context context) {
        super(context, DB_NAME, null, 1);
        this.myContext = context;
}

Verifica la documentazione del SQLiteOpenHelper, in particolare il costruttore e il metodo onUpgrade.

Indicazioni le puoi trovare anche tra i sorgenti dell'applicazione d'esempio NotePad fornita col SDK, in particolare nella classe NotePadProvider.

Sostanzialmente: se vari la struttura del tuo database devi incrementare il numero di versione quando il tuo DatabaseHelper invoca il super. In questo modo il sistema riesce a capire che c'è una variazione rispetto alle esecuzioni precedenti (perché il numero di versione è diverso) ed invoca il metodo onUpgrade passandogli la versione del database sul dispositivo e la versione aggiornata.
E' compito dello sviluppatore sovrascrivere il metodo onUpgrade gestendo le variazioni che intercorrono tra le due versioni (nel più semplice degli scenari come fa NotePadProvider: cancella il database e lo ricrea).