2012-06-14 4 views
1

내 앱에서 assets 폴더를 통해 데이터베이스의 최신 버전을 제공하고 있습니다. 간단히하기 위해 내 DB 체계가 PRIM KEY INTEGER _id, TEXT 이름 및 INTEGER 수량이라고 가정 해 보겠습니다. 수량은 사용자가 앱에서 편집 할 수있는 유일한 것입니다. 그 외 모든 것은 정적 데이터입니다. 여기에 0onUpgrade를 사용하여 이전 데이터베이스 백업, 데이터베이스 교체 및 데이터 복원

에서 수량 기본값 나는 현재 onUpgrade을 무엇을 시도하고있다 :

1.) 양> 0이 항목을 찾을 수 있습니다, 모든 테이블을 통해 반복하고있는 해당 항목을 저장 ID W 수량 값과 원래 테이블 이름을 보유하는 오브젝트 목록.

2 ) 난 그냥

3을 통해 반복 이전 데이터베이스) 정적 정보를 업데이트 포함 자산에서 새 데이터베이스를 복사를 삭제합니다.

4. 단계 1의 목록을 반복하고 해당 ID를 해당 테이블의 수량으로 업데이트하십시오.

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

    Log.w("TaskDBAdapter", "Upgrading from version " + oldVersion + " to " + newVersion); 


    ArrayList<backupKey> bak = new ArrayList<backupKey>(); 

    Cursor cursor = null; 
     for(int i = 0; i < titleArray.length; i++) 
     { 
      cursor = db.rawQuery("SELECT * FROM " + titleArray[i] + " WHERE quantity > 0", null); 
      if (cursor.moveToFirst()){ 
        do{ 
         backupKey key = new backupKey(titleArray[i], 
           cursor.getInt(cursor.getColumnIndex("_id")), 
           cursor.getInt(cursor.getColumnIndex("quantity"))); 
         bak.add(key); 

        }while(cursor.moveToNext()); 
       } 

     } 
     cursor.close(); 

     myContext.deleteDatabase(DB_NAME); 

     try 
     { 
      InputStream myInput = myContext.getAssets().open(DB_NAME); 

      String outFileName = DB_PATH + DB_NAME; 

      OutputStream myOutput = new FileOutputStream(outFileName, false); 


      byte[] buffer = new byte[1024]; 
      int length; 
      while ((length = myInput.read(buffer))>0){ 
       myOutput.write(buffer, 0, length); 
      } 

      myOutput.flush(); 
      myOutput.close(); 
      myInput.close(); 

     } catch (IOException e) 
     { 
      Log.w("TaskDBAdapter", "failed"); 
      throw new Error("Error copying database"); 

     } 

    for (int i = 0; i < bak.size(); i++) 
    { 

     ContentValues args = new ContentValues(); 
     args.put("quantity", bak.get(i).quantity); 
     String where = "_id = ?"; 
     String[] whereArgs = {Integer.toString(bak.get(i).id)}; 
     db.update(bak.get(i).range, args, where, whereArgs); 
    } 

} //End of onUpgrade 

I의 ArrayList를 성공적 적절한 데이터로 채워지는 것을 확인할 수

여기 내 방법의 onUpdate (titleArray 내 테이블의 이름을 포함하는 문자열의 배열). 전에 데이터베이스를 덮어 쓰려고했지만 작동하지 못했습니다. myContext.deleteDatabase (DB_NAME)를 추가해야했습니다. 데이터베이스가 성공적으로 대체 될 파일 쓰기 조작이 이루어지기 전에. 최종 업데이트 반복에서 이상한 데이터가 생성되지 않는다는 것을 확인할 수 있습니다.이 테이블에는 테이블 이름, ID 및 수량에 대한 올바른 값이 있습니다.

문제는 내 onUpgrade 이후에 수량이 업데이트되지 않는다는 것입니다. 정적 데이터는 자산 폴더에 포함 된 최신 버전으로 업데이트되지만 수량 데이터는 업데이트되지 않습니다. 이것은 원래 메서드 ("db"매개 변수,이 경우)에 제공된 데이터베이스를 파괴했기 때문입니까? 심지어 매개 변수가 무엇입니까? 새 데이터베이스에서 데이터를 어떻게 업데이트 할 수 있습니까?

또한 : 이것에 대해 갈 수있는 더 좋은 방법이 있다면, 나는 모든 귀 =)

답변

2

onUpgarde()는 등, 열 이름을 변경/(데이터베이스 구조를 업데이트 추가하는 의미)가 아닌 실제 데이터를 해요. 처음 시작할 때 실제 앱에서이 작업을 수행 할 수 있습니다. 또한 사용자 입력 데이터를 제 위치에서 업그레이드하는 것이 가장 좋은 방법은 아닙니다. 두 개의 테이블 (또는 데이터베이스도)을 가져야합니다. 하나는 공급하는 데이터이고 다른 하나는 사용자가 입력 한 데이터입니까? 사용자가 편집 한 행을 복사하고 원본 데이터를 읽기 전용으로 남겨 둘 수 있습니다.

+0

구조를 업데이트하는 것이지만 이전 질문에서 스키마 업데이트뿐만 아니라 데이터 업데이트도 처리 할 수있는 적절한 곳이라고 들었습니다. 계획 – Brett

+0

참조 문서 : '데이터베이스를 업그레이드해야 할 때 호출됩니다. 구현시이 메소드를 사용하여 테이블 삭제, 테이블 추가 또는 새 스키마 버전으로 업그레이드하는 데 필요한 작업을 수행해야합니다. ' 확실히 아무것도 할 수는 있지만, 앱이 DB를 처음 사용할 때 자동으로 호출되기 때문에 DB를 많이 제어 할 필요가 없습니다. 긴 데이터 업데이트가 필요한 경우 앱이 안정된 상태에있을 때 사용자에게 알리고 (옵션을 제공하는 것이 좋습니다) –

관련 문제