Created
April 24, 2015 17:51
-
-
Save creativepsyco/c45789e59a943fc5bf78 to your computer and use it in GitHub Desktop.
Realm Migration Example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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