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();
如果我當前的本地數據庫版本高於'schemaVersion':'由於:java.lang.IllegalArgumentException:磁盤上的Realm比指定的更新,在這種情況下,我想清除數據庫,否則,執行遷移,我該怎麼辦? – ebnbin
在版本中反向指示語義錯誤。您的schemaVersions不應該減少,因爲它意味着您已經在新的應用程序之上安裝了「舊」應用程序。你在這種情況下發生了什麼? –
嗯,我得到了你,只有一些設備允許用戶安裝一個老版本的應用程序,所以我想通過使用Realm的API來避免應用程序的關閉,如果可能的話......這個需求是否很奇怪?對不起,我只是不知道如何管理它... – ebnbin