2015-09-24 105 views
1

這就是我想要的:如何在遷移時刪除領域?

public class CustomRealmMigration implements RealmMigration { 
    // Current version 
    private static final long SCHEMA_VERSION = 4; 

    private final Context mContext; 

    public CustomRealmMigration(Context context) { 
     mContext = context; 
    } 

    @Override 
    public long execute(Realm realm, long version) { 
     if (SCHEMA_VERSION < version) { 
      // Rollback, not allow 
      deleteRealm(); 
      return SCHEMA_VERSION; 
     } 
     return version; 
    } 

    private void deleteRealm() { 
     RealmConfiguration realmConfiguration = new RealmConfiguration.Builder(mContext) 
       .name(Realm.DEFAULT_REALM_NAME) 
       .build(); 
     Realm.deleteRealm(realmConfiguration); 
    } 
} 

錯誤:

Caused by: java.lang.IllegalStateException: It's not allowed to delete the file associated with an open Realm. Remember to close() all the instances of the Realm before deleting its file. 

如何刪除領域,而遷移?或者如何在其他地方獲得舊版Realm?

回答

0
public class Migration implements RealmMigration { 
    @Override 
    public long execute(Realm realm, long version) { 

     /* 
      // Version 0 
      class Person 
       String firstName; 
       String lastName; 
       int age; 

      // Version 1 
      class Person 
       String fullName;  // combine firstName and lastName into single field 
       int age; 
     */ 

     // Migrate from version 0 to version 1 
     if (version == 0) { 
      Table personTable = realm.getTable(Person.class); 

      long fistNameIndex = getIndexForProperty(personTable, "firstName"); 
      long lastNameIndex = getIndexForProperty(personTable, "lastName"); 
      long fullNameIndex = personTable.addColumn(ColumnType.STRING, "fullName"); 
      for (int i = 0; i < personTable.size(); i++) { 
       personTable.setString(fullNameIndex, i, personTable.getString(fistNameIndex, i) + " " + 
         personTable.getString(lastNameIndex, i)); 
      } 
      personTable.removeColumn(getIndexForProperty(personTable, "firstName")); 
      personTable.removeColumn(getIndexForProperty(personTable, "lastName")); 
      version++; 
     } 

     /* 
      // Version 2 
       class Pet     // add a new model class 
        String name; 
        String type; 

       class Person 
        String fullName; 
        int age; 
        RealmList<Pet> pets; // add an array property 

     */ 
     // Migrate from version 1 to version 2 
     if (version == 1) { 
      Table personTable = realm.getTable(Person.class); 
      Table petTable = realm.getTable(Pet.class); 
      petTable.addColumn(ColumnType.STRING, "name"); 
      petTable.addColumn(ColumnType.STRING, "type"); 
      long petsIndex = personTable.addColumnLink(ColumnType.LINK_LIST, "pets", petTable); 
      long fullNameIndex = getIndexForProperty(personTable, "fullName"); 

      for (int i = 0; i < personTable.size(); i++) { 
       if (personTable.getString(fullNameIndex, i).equals("JP McDonald")) { 
        personTable.getUncheckedRow(i).getLinkList(petsIndex).add(petTable.add("Jimbo", "dog")); 
       } 
      } 
      version++; 
     } 

     /* 
      // Version 3 
       class Pet 
        String name; 
        int type;    // type becomes int 

       class Person 
        String fullName; 
        RealmList<Pet> pets; // age and pets re-ordered 
        int age; 
     */ 
     // Migrate from version 2 to version 3 
     if (version == 2) { 
      Table petTable = realm.getTable(Pet.class); 
      long oldTypeIndex = getIndexForProperty(petTable, "type"); 
      long typeIndex = petTable.addColumn(ColumnType.INTEGER, "type"); 
      for (int i = 0; i < petTable.size(); i++) { 
       String type = petTable.getString(oldTypeIndex, i); 
       if (type.equals("dog")) { 
        petTable.setLong(typeIndex, i, 1); 
       } 
       else if (type.equals("cat")) { 
        petTable.setLong(typeIndex, i, 2); 
       } 
       else if (type.equals("hamster")) { 
        petTable.setLong(typeIndex, i, 3); 
       } 
      } 
      petTable.removeColumn(oldTypeIndex); 
      version++; 
     } 
     return version; 
    } 

    private long getIndexForProperty(Table table, String name) { 
     for (int i = 0; i < table.getColumnCount(); i++) { 
      if (table.getColumnName(i).equals(name)) { 
       return i; 
      } 
     } 
     return -1; 
    } 
} 



And in Activity 

copyBundledRealmFile(this.getResources().openRawResource(R.raw.default0), "default0"); 
     copyBundledRealmFile(this.getResources().openRawResource(R.raw.default1), "default1"); 
     copyBundledRealmFile(this.getResources().openRawResource(R.raw.default2), "default2"); 

     // When you create a RealmConfiguration you can specify the version of the schema. 
     // If the schema does not have that version a RealmMigrationNeededException will be thrown. 
     RealmConfiguration config0 = new RealmConfiguration.Builder(this) 
       .name("default0") 
       .schemaVersion(3) 
       .build(); 

     // You can then manually call Realm.migrateRealm(). 
     Realm.migrateRealm(config0, new Migration()); 
     realm = Realm.getInstance(config0); 
     showStatus("Default0"); 
     showStatus(realm); 
     realm.close(); 

     // Or you can add the migration code to the configuration. This will run the migration code without throwing 
     // a RealmMigrationNeededException. 
     RealmConfiguration config1 = new RealmConfiguration.Builder(this) 
       .name("default1") 
       .schemaVersion(3) 
       .migration(new Migration()) 
       .build(); 

     realm = Realm.getInstance(config1); // Automatically run migration if needed 
     showStatus("Default1"); 
     showStatus(realm); 
     realm.close(); 

     // or you can set .deleteRealmIfMigrationNeeded() if you don't want to bother with migrations. 
     // WARNING: This will delete all data in the Realm though. 
     RealmConfiguration config2 = new RealmConfiguration.Builder(this) 
       .name("default2") 
       .schemaVersion(3) 
       .deleteRealmIfMigrationNeeded() 
       .build(); 

     realm = Realm.getInstance(config2); 
     showStatus("default2"); 
     showStatus(realm); 
     realm.close(); 
1

如果你不想當架構更改遷移數據,但只是重置/清除數據庫,那麼你可以做到以下幾點:

RealmConfiguration realmConfiguration = new RealmConfiguration.Builder(mContext) 
       .name(Realm.DEFAULT_REALM_NAME) 
       .deleteRealmIfMigrationRequired() 
       .build(); 

這也意味着你不必提供任何遷移代碼。

+0

如果我當前的本地數據庫版本高於'schemaVersion':'由於:java.lang.IllegalArgumentException:磁盤上的Realm比指定的更新,在這種情況下,我想清除數據庫,否則,執行遷移,我該怎麼辦? – ebnbin

+0

在版本中反向指示語義錯誤。您的schemaVersions不應該減少,因爲它意味着您已經在新的應用程序之上安裝了「舊」應用程序。你在這種情況下發生了什麼? –

+0

嗯,我得到了你,只有一些設備允許用戶安裝一個老版本的應用程序,所以我想通過使用Realm的API來避免應用程序的關閉,如果可能的話......這個需求是否很奇怪?對不起,我只是不知道如何管理它... – ebnbin