Skip to content

Instantly share code, notes, and snippets.

@creativepsyco
Created April 24, 2015 17:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save creativepsyco/c45789e59a943fc5bf78 to your computer and use it in GitHub Desktop.
Save creativepsyco/c45789e59a943fc5bf78 to your computer and use it in GitHub Desktop.
Realm Migration Example
package com.example.sample.orm.migration;
import com.google.common.base.Preconditions;
import com.example.sample.framework.base.ui.AppLogger;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import io.realm.Realm;
import io.realm.RealmMigration;
import io.realm.RealmObject;
import io.realm.internal.ColumnType;
import io.realm.internal.Table;
/**
* User: mohit
* Date: 13/4/15
*/
public abstract class BaseMigration implements RealmMigration {
protected Map<String, Long> columnMap = new HashMap<>();
protected Field[] fields;
protected Class<? extends RealmObject> klass;
protected Table migrationTable;
/**
* Need to call this method before anything else
*/
void prepareMigration(Realm realm, Class<? extends RealmObject> klass) {
this.migrationTable = realm.getTable(klass);
this.klass = klass;
this.fields = this.klass.getDeclaredFields();
}
void addColumns() {
Preconditions.checkNotNull(migrationTable);
Preconditions.checkNotNull(fields);
Preconditions.checkNotNull(klass);
for (Field field : fields) {
String fieldName = field.getName();
String type = field.getType().getSimpleName().toLowerCase();
ColumnType columnType = ColumnType.INTEGER;
switch (type) {
// Add more types here
case "long":
columnType = ColumnType.INTEGER;
break;
case "string":
columnType = ColumnType.STRING;
break;
}
long index = MigrationUtils.getIndexForProperty(migrationTable, fieldName);
if (index == -1) {
// Does not exist, add it
index = migrationTable.addColumn(columnType, fieldName);
}
columnMap.put(fieldName, index);
}
}
void removeColumns() {
long columnCount = migrationTable.getColumnCount();
HashMap<String, Integer> deleteableCols = new HashMap<>();
for (int i = 0; i < columnCount; i++) {
String columnName = migrationTable.getColumnName(i);
if (!columnMap.containsKey(columnName)) {
deleteableCols.put(columnName, i);
}
}
for (String column : deleteableCols.keySet()) {
long index = MigrationUtils.getIndexForProperty(migrationTable, column);
migrationTable.removeColumn(index);
}
}
void setString(String fieldName, String value, long index) {
migrationTable.setString(migrationTable.getColumnIndex(fieldName), index, value);
}
void setLong(String fieldName, Long value, long index) {
migrationTable.setLong(migrationTable.getColumnIndex(fieldName), index, value);
}
long getLong(String fieldName, long index) {
return migrationTable.getLong(migrationTable.getColumnIndex(fieldName), index);
}
}
package com.example.sample.orm.migration;
import android.text.TextUtils;
import com.google.common.base.Preconditions;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashSet;
import io.realm.Realm;
/**
* User: mohit
* Date: 13/4/15
*/
public class SampleDataMigration extends BaseMigration {
@Override
public long execute(Realm realm, long version) {
/**
* Sample of how to use the migration, you don't need to care about removal/addition of columns, that is handled.
*/
Preconditions.checkArgument(version == 0);
Preconditions.checkNotNull(realm);
prepareMigration(realm, Attachment.class);
removeNonUniqueData(realm);
addColumns();
migrationTable.setPrimaryKey("id");
removeColumns();
realm.refresh();
// Within a Realm Migration you cannot do a RealmQuery, because the migration
// is incomplete, therefore we need to access data using this way
// My model previously was storing non-structured data, JSON as string
// I changed it to same structure as the json
AppLogger.i("Migrating Existing data");
for (int i = 0; i < migrationTable.size(); i++) {
try {
JSONObject contentObj = new JSONObject(migrationTable.getString(columnMap.get("content"), i));
String type = contentObj.getString("tag")
contentObj.put("resolvedType", type);
if (contentObj.has("created_at")) {
contentObj.put("createTimestamp", DateUtils.getMiliEpochFromDate(contentObj.getString("created_at")));
} else {
contentObj.put("createTimeStamp", getLong("createTimestamp", i));
}
// Migrate each object
populateUsingJsonObject(contentObj, i);
} catch (Exception e) {
AppLogger.e(e);
}
}
version++;
return version;
}
/**
* This is for the preparation of primary key index
*/
private void removeNonUniqueData(Realm realm) {
// Remove duplicate data you think should not exist
}
void populateUsingJsonObject(JSONObject json, long index)
throws JSONException {
// Migrate Data here
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment