2015-09-24 3 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 во время миграции? Или как получить старую версию 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':' Caused by: java.lang.IllegalArgumentException: Realm на диске новее, чем указанный, в этом случае я хочу очистить базу данных, в противном случае, выполнить миграцию, что мне делать? – ebnbin

+0

Возвращение назад в версиях указывает на семантическую ошибку. Ваш schemaVersions никогда не должен уменьшаться, поскольку это подразумевает, что вы установили «более старое» приложение поверх нового. Что вы используете, так как это происходит? –

+0

Ну, я понял, что некоторые устройства позволяют пользователям устанавливать более старую версию приложения, поэтому я хочу, если это возможно, избежать применения силы приложения, используя API-интерфейс Realm ... Это странное задание? Извините, я просто не знаю, как с этим справиться ... – ebnbin

Смежные вопросы