use of io.realm.DynamicRealm in project toshi-android-client by toshiapp.
the class DbMigration method migrate.
@Override
public void migrate(final DynamicRealm realm, long oldVersion, final long newVersion) {
final RealmSchema schema = realm.getSchema();
// Add a new field on User.
if (oldVersion == 0) {
schema.get("User").addField("cacheTimestamp", long.class);
oldVersion++;
}
// Add PendingMessage table
if (oldVersion == 1) {
schema.create("PendingMessage").addField("privateKey", String.class, FieldAttribute.PRIMARY_KEY).addRealmObjectField("receiver", schema.get("User")).addRealmObjectField("sofaMessage", schema.get("SofaMessage"));
oldVersion++;
}
// Add attachmentFilename to SofaMessage table
if (oldVersion == 2) {
schema.get("SofaMessage").addField("attachmentFilename", String.class);
oldVersion++;
}
// Add support for reputation to User.
if (oldVersion == 3) {
schema.get("User").addField("reputation_score", Double.class).addField("review_count", int.class);
oldVersion++;
}
// Move the custom data to top level on a User
if (oldVersion == 4) {
final RealmObjectSchema userSchema = schema.get("User");
userSchema.addField("about", String.class).addField("avatar", String.class).addField("location", String.class).addField("name", String.class).transform(obj -> {
final DynamicRealmObject customUserInfo = obj.getObject("customUserInfo");
obj.set("about", customUserInfo.getString("about"));
obj.set("avatar", customUserInfo.getString("avatar"));
obj.set("location", customUserInfo.getString("location"));
obj.set("name", customUserInfo.getString("name"));
}).removeField("customUserInfo");
oldVersion++;
}
// Rename attachmentFilename to attachmentFilePath
if (oldVersion == 5) {
final RealmObjectSchema sofaMessageSchema = schema.get("SofaMessage");
sofaMessageSchema.renameField("attachmentFilename", "attachmentFilePath");
oldVersion++;
}
// Migration is too much effort considering we're yet to go live.
if (oldVersion == 6) {
final RealmObjectSchema sofaMessageSchema = schema.get("SofaMessage");
sofaMessageSchema.removeField("sentByLocal").addRealmObjectField("sender", schema.get("User"));
oldVersion++;
}
// Encrypt and shard
if (oldVersion == 7) {
realm.writeEncryptedCopyTo(new File(realm.getPath(), this.wallet.getOwnerAddress()), this.wallet.generateDatabaseEncryptionKey());
oldVersion++;
}
if (oldVersion == 8) {
if (schema.contains("BlockedUser")) {
schema.remove("BlockedUser");
}
final RealmObjectSchema blockedUserSchema = schema.create("BlockedUser");
blockedUserSchema.addField("owner_address", String.class, FieldAttribute.PRIMARY_KEY);
oldVersion++;
}
if (oldVersion == 9) {
final RealmObjectSchema userSchema = schema.get("User");
if (userSchema.hasField("customAppInfo")) {
userSchema.removeField("customAppInfo");
}
if (!userSchema.hasField("is_app")) {
userSchema.addField("is_app", boolean.class);
}
if (schema.contains("CustomAppInformation")) {
schema.remove("CustomAppInformation");
}
oldVersion++;
}
// Rename "Conversation" to "ContactThread"
if (oldVersion == 10) {
final RealmObjectSchema conversationSchema = schema.get("Conversation");
if (conversationSchema != null) {
conversationSchema.renameField("conversationId", "threadId");
schema.rename("Conversation", "ContactThread");
}
oldVersion++;
}
// Split out recipient into seperate table
if (oldVersion == 11) {
if (schema.get("Group") == null) {
schema.create("Group").addField("id", String.class, FieldAttribute.PRIMARY_KEY).addField("title", String.class).addRealmListField("members", schema.get("User"));
}
if (schema.get("Recipient") == null) {
schema.create("Recipient").addField("id", String.class, FieldAttribute.PRIMARY_KEY).addRealmObjectField("user", schema.get("User")).addRealmObjectField("group", schema.get("Group"));
}
schema.rename("ContactThread", "Conversation").addRealmObjectField("recipient", schema.get("Recipient")).transform(obj -> {
final String primaryKey = UUID.randomUUID().toString();
final DynamicRealmObject newRecipient = realm.createObject("Recipient", primaryKey);
newRecipient.setObject("user", obj.getObject("member"));
obj.set("recipient", newRecipient);
}).removeField("member");
oldVersion++;
}
if (oldVersion == 12) {
final RealmObjectSchema userSchema = schema.get("User");
if (!userSchema.hasField("is_public")) {
userSchema.addField("is_public", boolean.class);
}
oldVersion++;
}
// Port Recipient ids to be threadIds
if (oldVersion == 13) {
schema.get("Conversation").transform(obj -> {
// Get existing recipient object
final DynamicRealmObject recipient = obj.getObject("recipient");
final String threadId = obj.getString("threadId");
final DynamicRealmObject user = recipient.getObject("user");
final DynamicRealmObject group = recipient.getObject("group");
// Create new object with correct PK
final DynamicRealmObject newRecipient = realm.createObject("Recipient", threadId);
newRecipient.setObject("user", user);
newRecipient.setObject("group", group);
// Delete old recipient
recipient.deleteFromRealm();
// Set new recipient
obj.set("recipient", newRecipient);
});
oldVersion++;
}
// Port PendingMessageStore to using Recipient
if (oldVersion == 14) {
schema.get("PendingMessage").addRealmObjectField("tempReceiver", schema.get("Recipient")).transform(obj -> {
final DynamicRealmObject oldUser = obj.getObject("receiver");
final String primaryKey = oldUser.getString("owner_address");
final DynamicRealmObject newRecipient = realm.createObject("Recipient", primaryKey);
newRecipient.setObject("user", oldUser);
obj.set("tempReceiver", newRecipient);
}).removeField("receiver").renameField("tempReceiver", "receiver");
oldVersion++;
}
if (oldVersion == 15) {
schema.get("User").addField("average_rating", Double.class);
oldVersion++;
}
if (oldVersion == 16) {
if (schema.get("SofaError") == null) {
schema.create("SofaError").addField("id", String.class, FieldAttribute.PRIMARY_KEY).addField("message", String.class);
}
if (!schema.get("SofaMessage").hasField("errorMessage")) {
schema.get("SofaMessage").addRealmObjectField("errorMessage", schema.get("SofaError"));
}
oldVersion++;
}
if (oldVersion == 17) {
final RealmObjectSchema mutedConversationSchema = schema.create("MutedConversation");
mutedConversationSchema.addField("threadId", String.class, FieldAttribute.PRIMARY_KEY);
oldVersion++;
}
if (oldVersion == 18) {
if (schema.contains("MutedConversation")) {
schema.rename("MutedConversation", "ConversationStatus").addField("isMuted", boolean.class).addField("isAccepted", boolean.class).transform(obj -> obj.set("isMuted", true));
}
schema.get("Conversation").addRealmObjectField("conversationStatus", schema.get("ConversationStatus"));
final List<DynamicRealmObject> conversations = realm.where("Conversation").findAll();
for (final DynamicRealmObject conversation : conversations) {
final String conversationThreadId = conversation.getString("threadId");
DynamicRealmObject conversationStatus = realm.where("ConversationStatus").equalTo("threadId", conversationThreadId).findFirst();
conversationStatus = conversationStatus != null ? conversationStatus : realm.createObject("ConversationStatus", conversationThreadId);
conversationStatus.set("isAccepted", true);
conversation.set("conversationStatus", conversationStatus);
}
oldVersion++;
}
if (oldVersion == 19) {
if (schema.get("Avatar") == null) {
schema.create("Avatar").addField("bytes", byte[].class);
}
if (!schema.get("Group").hasField("avatar")) {
schema.get("Group").addRealmObjectField("avatar", schema.get("Avatar"));
}
oldVersion++;
}
if (oldVersion == 20) {
final RealmResults<DynamicRealmObject> contacts = realm.where("Contact").findAll();
contacts.deleteAllFromRealm();
if (schema.contains("Contact")) {
schema.remove("Contact");
}
oldVersion++;
}
}
use of io.realm.DynamicRealm in project xabber-android by redsolution.
the class MessageDatabaseManager method createRealmConfiguration.
private RealmConfiguration createRealmConfiguration() {
return new RealmConfiguration.Builder().name(REALM_MESSAGE_DATABASE_NAME).schemaVersion(REALM_MESSAGE_DATABASE_VERSION).modules(new MessageRealmDatabaseModule()).migration(new RealmMigration() {
@Override
public void migrate(DynamicRealm realm1, long oldVersion, long newVersion) {
RealmSchema schema = realm1.getSchema();
if (oldVersion == 1) {
schema.create(SyncInfo.class.getSimpleName()).addField(SyncInfo.FIELD_ACCOUNT, String.class, FieldAttribute.INDEXED).addField(SyncInfo.FIELD_USER, String.class, FieldAttribute.INDEXED).addField(SyncInfo.FIELD_FIRST_MAM_MESSAGE_MAM_ID, String.class).addField(SyncInfo.FIELD_FIRST_MAM_MESSAGE_STANZA_ID, String.class).addField(SyncInfo.FIELD_LAST_MESSAGE_MAM_ID, String.class).addField(SyncInfo.FIELD_REMOTE_HISTORY_COMPLETELY_LOADED, boolean.class);
oldVersion++;
}
if (oldVersion == 2) {
schema.create(MessageItem.class.getSimpleName()).addField(MessageItem.Fields.UNIQUE_ID, String.class, FieldAttribute.PRIMARY_KEY).addField(MessageItem.Fields.ACCOUNT, String.class, FieldAttribute.INDEXED).addField(MessageItem.Fields.USER, String.class, FieldAttribute.INDEXED).addField(MessageItem.Fields.RESOURCE, String.class).addField(MessageItem.Fields.ACTION, String.class).addField(MessageItem.Fields.TEXT, String.class).addField(MessageItem.Fields.TIMESTAMP, Long.class, FieldAttribute.INDEXED).addField(MessageItem.Fields.DELAY_TIMESTAMP, Long.class).addField(MessageItem.Fields.STANZA_ID, String.class).addField(MessageItem.Fields.INCOMING, boolean.class).addField(MessageItem.Fields.UNENCRYPTED, boolean.class).addField(MessageItem.Fields.SENT, boolean.class).addField(MessageItem.Fields.READ, boolean.class).addField(MessageItem.Fields.DELIVERED, boolean.class).addField(MessageItem.Fields.OFFLINE, boolean.class).addField(MessageItem.Fields.ERROR, boolean.class).addField(MessageItem.Fields.IS_RECEIVED_FROM_MAM, boolean.class).addField(MessageItem.Fields.FILE_PATH, String.class).addField(MessageItem.Fields.FILE_SIZE, Long.class);
oldVersion++;
}
if (oldVersion == 3) {
schema.get(MessageItem.class.getSimpleName()).addIndex(MessageItem.Fields.SENT);
oldVersion++;
}
if (oldVersion == 4) {
schema.get(MessageItem.class.getSimpleName()).addField(MessageItem.Fields.FORWARDED, boolean.class);
oldVersion++;
}
if (oldVersion == 5) {
schema.get(MessageItem.class.getSimpleName()).addField(MessageItem.Fields.ACKNOWLEDGED, boolean.class);
oldVersion++;
}
if (oldVersion == 6) {
schema.create("LogMessage").addField("level", int.class).addField("tag", Date.class).addField("message", String.class).addField("datetime", String.class);
oldVersion++;
}
if (oldVersion == 7) {
schema.remove("LogMessage");
oldVersion++;
}
if (oldVersion == 8) {
schema.get(MessageItem.class.getSimpleName()).addField(MessageItem.Fields.FILE_URL, String.class);
oldVersion++;
}
if (oldVersion == 9) {
schema.remove("BlockedContactsForAccount");
schema.remove("BlockedContact");
oldVersion++;
}
if (oldVersion == 10) {
schema.get(MessageItem.class.getSimpleName()).addField(MessageItem.Fields.IS_IN_PROGRESS, boolean.class);
oldVersion++;
}
if (oldVersion == 11) {
schema.get(MessageItem.class.getSimpleName()).addField(MessageItem.Fields.IS_IMAGE, boolean.class);
oldVersion++;
}
if (oldVersion == 12) {
schema.get(MessageItem.class.getSimpleName()).addField(MessageItem.Fields.IMAGE_WIDTH, Integer.class).addField(MessageItem.Fields.IMAGE_HEIGHT, Integer.class);
oldVersion++;
}
if (oldVersion == 13) {
schema.get(MessageItem.class.getSimpleName()).removeField(MessageItem.Fields.UNENCRYPTED).addField(MessageItem.Fields.ENCRYPTED, boolean.class);
oldVersion++;
}
if (oldVersion == 14) {
schema.get(MessageItem.class.getSimpleName()).addField(MessageItem.Fields.ERROR_DESCR, String.class);
oldVersion++;
}
if (oldVersion == 15) {
schema.create(Attachment.class.getSimpleName()).addField("uniqueId", String.class, FieldAttribute.PRIMARY_KEY, FieldAttribute.REQUIRED).addField("title", String.class).addField("filePath", String.class).addField("fileUrl", String.class).addField("fileSize", Long.class).addField("isImage", boolean.class).addField("imageWidth", Integer.class).addField("imageHeight", Integer.class).addField("duration", Long.class).addField("mimeType", String.class);
schema.get(MessageItem.class.getSimpleName()).addRealmListField(MessageItem.Fields.ATTACHMENTS, schema.get(Attachment.class.getSimpleName()));
oldVersion++;
}
if (oldVersion == 16) {
schema.create(ForwardId.class.getSimpleName()).addField("id", String.class, FieldAttribute.PRIMARY_KEY, FieldAttribute.REQUIRED).addField("forwardMessageId", String.class);
schema.get(MessageItem.class.getSimpleName()).addField(MessageItem.Fields.ORIGINAL_STANZA, String.class).addField(MessageItem.Fields.ORIGINAL_FROM, String.class).addField(MessageItem.Fields.PARENT_MESSAGE_ID, String.class).addField(MessageItem.Fields.FROM_MUC, boolean.class).addRealmListField(MessageItem.Fields.FORWARDED_IDS, schema.get(ForwardId.class.getSimpleName()));
oldVersion++;
}
if (oldVersion == 17) {
schema.get(MessageItem.class.getSimpleName()).addField(MessageItem.Fields.DISPLAYED, boolean.class);
oldVersion++;
}
if (oldVersion == 18) {
schema.get(MessageItem.class.getSimpleName()).transform(new RealmObjectSchema.Function() {
@Override
public void apply(DynamicRealmObject obj) {
obj.setBoolean(MessageItem.Fields.READ, true);
}
});
oldVersion++;
}
if (oldVersion == 19) {
schema.get(MessageItem.class.getSimpleName()).addField(MessageItem.Fields.PREVIOUS_ID, String.class).addField(MessageItem.Fields.ARCHIVED_ID, String.class).transform(new RealmObjectSchema.Function() {
@Override
public void apply(DynamicRealmObject obj) {
obj.setString(MessageItem.Fields.PREVIOUS_ID, "legacy");
}
});
oldVersion++;
}
if (oldVersion == 20) {
schema.create(ContactGroup.class.getSimpleName()).addField(ContactGroup.Fields.GROUP_NAME, String.class, FieldAttribute.PRIMARY_KEY, FieldAttribute.REQUIRED);
schema.create(ContactRealm.class.getSimpleName()).addField(ContactRealm.Fields.ID, String.class, FieldAttribute.PRIMARY_KEY, FieldAttribute.REQUIRED).addField(ContactRealm.Fields.ACCOUNT, String.class).addField(ContactRealm.Fields.USER, String.class).addField(ContactRealm.Fields.NAME, String.class).addField(ContactRealm.Fields.ACCOUNT_RESOURCE, String.class).addRealmObjectField(ContactRealm.Fields.LAST_MESSAGE, schema.get(MessageItem.class.getSimpleName())).addRealmListField(ContactRealm.Fields.GROUPS, schema.get(ContactGroup.class.getSimpleName()));
oldVersion++;
}
if (oldVersion == 21) {
schema.get(MessageItem.class.getSimpleName()).addField(MessageItem.Fields.MARKUP_TEXT, String.class);
oldVersion++;
}
if (oldVersion == 22) {
schema.get(MessageItem.class.getSimpleName()).addField(MessageItem.Fields.GROUPCHAT_USER_ID, String.class);
oldVersion++;
}
}
}).build();
}
use of io.realm.DynamicRealm in project realm-java by realm.
the class PrimaryKeyTests method removingPrimaryKeyRemovesConstraint_typeSetters.
/**
* This test surfaces a bunch of problems, most of them seem to be around caching of the schema
* during a transaction
*
* 1) Removing the primary key do not invalidate the cache in RealmSchema and those cached
* are ImmutableRealmObjectSchema so do not change when the primary key is removed.
*
* 2) Addding `schema.refresh()` to RealmObjectSchema.removePrimaryKey()` causes
* RealmPrimaryKeyConstraintException anyway. Unclear why.
*/
@Test
public void removingPrimaryKeyRemovesConstraint_typeSetters() {
RealmConfiguration config = configFactory.createConfigurationBuilder().name("removeConstraints").build();
DynamicRealm realm = DynamicRealm.getInstance(config);
RealmSchema realmSchema = realm.getSchema();
realm.beginTransaction();
RealmObjectSchema tableSchema = realmSchema.create("Employee").addField("name", String.class, FieldAttribute.PRIMARY_KEY);
realm.createObject("Employee", "Foo");
DynamicRealmObject obj = realm.createObject("Employee", "Foo2");
try {
// Tries to create 2nd entry with name Foo.
obj.setString("name", "Foo");
} catch (IllegalArgumentException e) {
tableSchema.removePrimaryKey();
obj.setString("name", "Foo");
} finally {
realm.close();
}
}
use of io.realm.DynamicRealm in project realm-java by realm.
the class RealmObservableFactory method changesetsFrom.
@Override
public Observable<ObjectChange<DynamicRealmObject>> changesetsFrom(DynamicRealm realm, final DynamicRealmObject object) {
if (realm.isFrozen()) {
return Observable.just(new ObjectChange<DynamicRealmObject>(object, null));
}
final RealmConfiguration realmConfig = realm.getConfiguration();
Scheduler scheduler = getScheduler();
return Observable.create(new ObservableOnSubscribe<ObjectChange<DynamicRealmObject>>() {
@Override
public void subscribe(final ObservableEmitter<ObjectChange<DynamicRealmObject>> emitter) {
// If the Realm has been closed, just create an empty Observable because we assume it is going to be disposed shortly.
if (!RealmObject.isValid(object))
return;
// Gets instance to make sure that the Realm is open for as long as the
// Observable is subscribed to it.
final DynamicRealm observableRealm = DynamicRealm.getInstance(realmConfig);
objectRefs.get().acquireReference(object);
final RealmObjectChangeListener<DynamicRealmObject> listener = new RealmObjectChangeListener<DynamicRealmObject>() {
@Override
public void onChange(DynamicRealmObject obj, ObjectChangeSet changeSet) {
if (!emitter.isDisposed()) {
emitter.onNext(new ObjectChange<>(returnFrozenObjects ? RealmObject.freeze(obj) : obj, changeSet));
}
}
};
object.addChangeListener(listener);
// Cleanup when stream is disposed
emitter.setDisposable(Disposables.fromRunnable(new Runnable() {
@Override
public void run() {
if (!observableRealm.isClosed()) {
RealmObject.removeChangeListener(object, listener);
observableRealm.close();
}
objectRefs.get().releaseReference(object);
}
}));
// Emit current value immediately
emitter.onNext(new ObjectChange<>(returnFrozenObjects ? RealmObject.freeze(object) : object, null));
}
}).subscribeOn(scheduler).unsubscribeOn(scheduler);
}
use of io.realm.DynamicRealm in project realm-java by realm.
the class RealmObservableFactory method from.
@Override
public <E> Flowable<RealmResults<E>> from(DynamicRealm realm, final RealmResults<E> results) {
if (realm.isFrozen()) {
return Flowable.just(results);
}
final RealmConfiguration realmConfig = realm.getConfiguration();
Scheduler scheduler = getScheduler();
return Flowable.create(new FlowableOnSubscribe<RealmResults<E>>() {
@Override
public void subscribe(final FlowableEmitter<RealmResults<E>> emitter) {
// If the Realm has been closed, just create an empty Observable because we assume it is going to be disposed shortly.
if (!results.isValid())
return;
// Gets instance to make sure that the Realm is open for as long as the
// Observable is subscribed to it.
final DynamicRealm observableRealm = DynamicRealm.getInstance(realmConfig);
resultsRefs.get().acquireReference(results);
final RealmChangeListener<RealmResults<E>> listener = new RealmChangeListener<RealmResults<E>>() {
@Override
public void onChange(RealmResults<E> results) {
if (!emitter.isCancelled()) {
emitter.onNext(returnFrozenObjects ? results.freeze() : results);
}
}
};
results.addChangeListener(listener);
// Cleanup when stream is disposed
emitter.setDisposable(Disposables.fromRunnable(new Runnable() {
@Override
public void run() {
if (!observableRealm.isClosed()) {
results.removeChangeListener(listener);
observableRealm.close();
}
resultsRefs.get().releaseReference(results);
}
}));
// Emit current value immediately
emitter.onNext(returnFrozenObjects ? results.freeze() : results);
}
}, BACK_PRESSURE_STRATEGY).subscribeOn(scheduler).unsubscribeOn(scheduler);
}
Aggregations