2012-05-19 12 views
14

Sto lavorando a un'applicazione Android in cui ho utilizzato il database sqlite esistente nella cartella delle risorse. Quindi in realtà copio il database da quella cartella. L'utente può anche salvare i propri dati (contrassegnare qualsiasi contenuto come preferito).Il database Sqlite onUpgrade() non viene chiamato

Ho caricato una versione sul mercato. Ora voglio aggiungere alcuni nuovi dati nel database e ho caricato una nuova versione. Se l'utente aggiorna l'app dal mercato, voglio mantenere i dati dell'utente (dalla versione precedente) e aggiungere anche i nuovi dati. Ho fatto un po 'di google e ho scoperto che il metodo di aggiornamento dovrebbe fare il trucco. Ma sto cambiando il DATABASE_VERSION dal codice, ma il metodo di upgrade on non riceve chiamate. Mi sto chiedendo di aver perso qualcosa. Qui è il mio codice:

public class DataBaseHelper extends SQLiteOpenHelper { 

private static String DB_PATH = "/data/data/riskycoder.login/databases/"; 
public static String DB_NAME = "datenbank_EN.sqlite"; 
private SQLiteDatabase myDataBase; 
private final Context myContext; 
private static final int DATABASE_VERSION = 1; 





public DataBaseHelper(Context context) { 
    super(context, DB_NAME, null, DATABASE_VERSION); 
    this.myContext = context; 
} 

public void createDataBase() throws IOException { 
    boolean dbExist = checkDataBase(); 
    if (dbExist) { 
    } else { 
     this.getWritableDatabase(); 
     try { 
      this.close(); 
      copyDataBase(); 
     } catch (IOException e) { 
      throw new Error("Error copying 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[2048]; 
    int length; 
    while ((length = myInput.read(buffer)) > 0) { 
     myOutput.write(buffer, 0, length); 
    } 
    myOutput.flush(); 
    myOutput.close(); 
    myInput.close(); 

    //myDataBase.setVersion(DATABASE_VERSION); 
} 

public void openDataBase() throws SQLException { 
    String myPath = DB_PATH + DB_NAME; 
    myDataBase = SQLiteDatabase.openDatabase(myPath, null,SQLiteDatabase.OPEN_READWRITE); 
    Log.d("Test", "Database version: " +myDataBase.getVersion()); 
} 

@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) { 
    Log.d("Test", "in onUpgrade. Old is: " + oldVersion + " New is: " + newVersion); 


} 

}

+0

* Sto cambiando il Database_Version dal codice .. *, cosa fa esattamente questo significa? Vedo che chiami il super costruttore di 'SQLiteOpenHelper' con un campo costante' DATABASE_VERSION' (che ovviamente non può essere modificato), quindi come cambi esattamente la versione del database? – Luksprog

+0

Nella nuova versione dell'applicazione ho cambiato DATABASE_VERSION in 2. Quindi durante l'installazione della nuova versione dovrebbe essere chiamato il metodo onUpgrade. O mi manca qualcosa? – rawcoder064

+0

Per prima cosa, il codice che hai postato mostra DATABASE_VERSION è 1, quindi onUpgrade non verrebbe chiamato.In secondo luogo, anche se era 2, il tuo onUpgrade non ha codice per fare anythign per aggiornare il database. Non accade automagicamente, devi farlo. – Barak

risposta

18

onUpgrade() viene chiamato solo se un cambiamento nella base di dati il numero di versione è rilevato. Incremento della versione del database come segue:

private static final int DATABASE_VERSION = 2; 
+0

Non lo farà molto bene dato che tutto su onUpgrade fa sputare un messaggio di log (almeno con il codice postato) – Barak

+1

L'OP ha chiesto "perché non viene chiamato il metodo 'onUpgrade'." Ovviamente sputerà solo un messaggio di log in quanto non ha ancora implementato 'onUpgrade'. –

+0

@ AlexLockwood-> Ho modificato DATABASE_VERSION su 2 come hai detto, ma non viene mostrato nulla nell'output del logcat. Ho creato il database dal browser sqlite. Dovrei fare il versioning durante la creazione del database? – rawcoder064

2

Prova questa (aumentare la Database_Version) & l'onUpdate() sarà chiamato:

private static final int DATABASE_VERSION = 2; 
+0

Verrà chiamato e non fare nulla ... – Barak

+0

@ Barak-> Ho inserito l'istruzione log.d in onUpgrade() per testare. Ma non vedo nulla nell'output del logcat. Ciò significa che onUpgrade non viene chiamato. Nel metodo openDataBase() ho messo un'istruzione log.d. Posso vedere che la versione del database è sempre 1 anche se cambio DATABASE_VERSION a 2. – rawcoder064

2

Supponendo che è stato modificato il Database_Version, si devono ancora mettere il codice in ONUPGRADE per farlo accadere. Non è magico, devi dirgli cosa fare.

Nel tuo caso è necessario:

1) copiare il vecchio database (dare un nuovo nome)
2) copiare nel nuovo database
3) leggere i dati dal vecchio database
4) copiare qualsiasi differenza nel nuovo database
5) eliminare il vecchio database

EDIT

Supponendo di spedire il DB nelle attività cartella scelta copiarlo per l'uso in questo modo:

@Override 
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
    // First copy old db 
    InputStream bakInput = getActivity().getAssets().open(dbname); 
    String bakFileName = getActivity().getAssets() + "YourDB.old"; 
    OutputStream bakOutput = new FileOutputStream(bakFileName); 
    byte[] buffer = new byte[1024]; 
    int length; 
    while ((length = bakInput.read(buffer)) > 0) { 
     bakOutput.write(buffer, 0, length); 
    } 
    myOutput.flush(); 
    myOutput.close(); 
    myInput.close(); 

    // delete the old db 
    File delDB = new File(getActivity().getAssets() + "YourDB"); 
    boolean deleted = file.delete(); 

    // Copy in the new db 
    InputStream myInput = getActivity().getAssets().open("YourDB"); 
    String outFileName = MAIN_DB_PATH + dbname; 
    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(); 

    // add code here to get changes user has made to db and move them to updated db 

    // delete the old db copy 
    File delDB = new File(getActivity().getAssets() + "YourDB.old"); 
    boolean deleted = file.delete(); 
} 
+0

Scusa se non ti capisco. Nel mio caso come faccio a copiare un nuovo database. puoi per favore postare del codice come faccio a farlo ....... scusa per la mia stupida domanda ... – rawcoder064

+0

@Barak puoi aiutarmi il mio metodo onUpgrade non viene chiamato – Erum

6

Cambia la tua ONUPGRADE al seguente

@Override 
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 

      if(newVersion > oldVersion){      
        myContext.deleteDatabase(DB_NAME); 
      } 
     } 

E anche cambiare la vostra CreateDatabase() come qui di seguito,

public void createDataBase() throws IOException{ 

      boolean dbExist = checkDataBase(); 

      if(dbExist){ 
       // By calling this method here onUpgrade will be called on a 
       // writable database, but only if the version number has been increased 

       this.getWritableDatabase(); 
      } 

      dbExist = checkDataBase(); 

      if(!dbExist){ 

       //By calling this method an empty database will be created into the      default system path 
        //of the application so we will be able to overwrite that database with our database. 
       this.getReadableDatabase(); 

       try { 

        copyDataBase(); 

       } catch (IOException e) { 

        throw new Error("Error copying database"); 

       } 
      } 

     } 

Alla fine aumentare la versione del database ed eseguirla di nuovo. onUpgrade non viene chiamato finché non si chiama getReadableDatabase() o funzioni simili.

Spero che questo aiuti

+0

ho seguito la tua risposta ma ancora il mio onUpgrade il metodo non viene chiamato può aiutarmi – Erum

Problemi correlati