2012-05-19 20 views
14

Estoy trabajando en una aplicación de Android donde utilicé la base de datos sqlite existente en la carpeta de activos. Así que en realidad copio la base de datos de esa carpeta. El usuario también puede guardar sus propios datos (marque cualquier contenido como favorito).Base de datos sqlite onUpgrade() no se llama

He subido una versión en el mercado. Ahora quiero agregar algunos datos nuevos en la base de datos y cargar una nueva versión. Si el usuario actualiza la aplicación desde el mercado, quiero conservar los datos del usuario (de la versión anterior) y agregar los nuevos datos también. He hecho un poco de google y descubrí que el método de actualización debería ser el truco. Pero estoy cambiando el DATABASE_VERSION del código, pero el método de actualización no recibe la llamada. Me pregunto si me he perdido algo. Aquí está mi código:

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

* Estoy cambiando la Database_Version de código .. *, ¿qué exactamente significa esto? Veo que llamas al superconstructor del 'SQLiteOpenHelper' con un campo constante' DATABASE_VERSION' (que obviamente no se puede cambiar), entonces, ¿cómo cambias exactamente la versión de la base de datos? – Luksprog

+0

En la nueva versión de la aplicación, he cambiado DATABASE_VERSION a 2. Por lo tanto, al instalar la nueva versión, se debe llamar al método onUpgrade. ¿O me falta algo? – rawcoder064

+0

Primero, el código que publicaste showa DATABASE_VERSION es 1, por lo que no se llamaría a OnUpgrade.En segundo lugar, incluso si fuera 2, su actualización no tiene código para hacer nada para actualizar la base de datos. No sucede automágicamente, tienes que hacerlo. – Barak

Respuesta

18

onUpgrade() sólo se le llama si un cambio en la base de datos número de versión es detectado. Incrementar la versión de la base de datos de la siguiente manera:

private static final int DATABASE_VERSION = 2; 
+0

No le hará mucho bien ya que todo lo que OnUpgrade hace es escupir un mensaje de registro (al menos con el código publicado) – Barak

+1

El OP preguntó "por qué no se llama al método 'onUpgrade'. Por supuesto, solo escupirá un mensaje de registro ya que aún no ha implementado 'onUpgrade'. –

+0

@ AlexLockwood-> He cambiado la DATABASE_VERSION a 2 como dijo, pero no se muestra nada en la salida de logcat. He creado la base de datos por el navegador sqlite. ¿Debería hacer algún control de versiones mientras creo la base de datos? – rawcoder064

2

probar este (aumentar la Database_Version) & la onUpdate() se llamará:

private static final int DATABASE_VERSION = 2; 
+0

Se llamará y no hará nada ... – Barak

+0

@ Barak-> He puesto declaración log.d en onUpgrade() para probar. Pero no veo nada en la salida de logcat. Eso significa que no se llama a onUpgrade. En el método openDataBase() he puesto una declaración log.d. Puedo ver que la versión de la base de datos siempre es 1 incluso si cambio el DATABASE_VERSION a 2. – rawcoder064

2

Asumiendo que ha cambiado el Database_Version, usted todavía tiene que poner el código en el ONUPGRADE para que esto ocurra. No es mágico, tienes que decirle qué hacer.

En el caso de que necesite:

1) copiar la base de datos de edad (darle un nuevo nombre)
2) copia en su nueva base de datos
3) leer los datos de la base de datos antigua
4) copiar cualquier diferencia en la nueva base de datos
5) eliminar la antigua base de datos

EDITAR

Suponiendo que usted envía el DB en el activo carpeta que copiarlo para su uso, así:

@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

Lo siento, no te entiendo. En mi caso, ¿cómo copio la nueva base de datos? ¿Puede por favor publicar un código? ¿Cómo lo hago? ... lo siento por mi pregunta tonta ... – rawcoder064

+0

@Barak me puede ayudar mi método onUpgrade no se llama – Erum

6

Cambiar la ONUPGRADE a la siguiente

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

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

Y también cambiar su CreateDatabase(), como a continuación,

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"); 

       } 
      } 

     } 

Al final, aumente la versión de su base de datos y vuelva a ejecutarla. onUpgrade no se llama hasta que llame al getReadableDatabase() o funciones similares.

Esperanza esto ayuda

+0

he seguido su respuesta, pero aún mi onUpgrade método no se está llamando ¿me pueden ayudar? – Erum

Cuestiones relacionadas