/** * 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(); } }
@Override public void migrate(DynamicRealm realm, long oldVersion, long newVersion) { // During a migration, a DynamicRealm is exposed. A DynamicRealm is an untyped variant of a normal Realm, but // with the same object creation and query capabilities. // A DynamicRealm uses Strings instead of Class references because the Classes might not even exist or have been // renamed. // Access the Realm schema in order to create, modify or delete classes and their fields. RealmSchema schema = realm.getSchema(); // Migrate from version 0 to version 1 if (oldVersion == 0) { oldVersion++; } // Migrate from version 1 to version 2 if (oldVersion == 1) { RealmObjectSchema bloodGlucoseDataSchema = schema.get("BloodGlucoseData"); bloodGlucoseDataSchema .addField("timezoneOffsetInMinutes", int.class) .transform(timezoneTransformFunction); //oldVersion++; } }
@Override public void migrate(DynamicRealm realm, long oldVersion, long newVersion) { RealmSchema schema = realm.getSchema(); /* * Migrates to version 1 of the schema. * - Make uniqueId the primary key for the RBook class instead of the relative path. */ if (oldVersion == 0) { schema.get("RBook") .removePrimaryKey() // Remove @PrimaryKey from relPath. .addIndex("relPath") // Add @Index to relPath. .addPrimaryKey("uniqueId"); // Add @PrimaryKey to uniqueId. oldVersion++; } }
@Override public void migrate(DynamicRealm realm, long oldVersion, long newVersion) { // DynamicRealm exposes an editable schema RealmSchema schema = realm.getSchema(); // Migrate to version 1: Add a new class. // Example: // public Person extends RealmObject { // private String name; // private int age; // // getters and setters left out for brevity // } if (oldVersion == 0) { schema.create("UserScript") .addField("title", String.class) .addField("url", String.class); oldVersion++; } if (oldVersion == 1) { schema.get("UserScript") .addField("javascript", String.class); oldVersion++; } }
@Override public void migrate(DynamicRealm realm, long oldVersion, long newVersion) { // DynamicRealm exposes an editable schema RealmSchema schema = realm.getSchema(); // Migrate to version 1: Add a new class. // Example: // public Person extends RealmObject { // private String name; // private int age; // // getters and setters left out for brevity // } if (oldVersion == 0) { schema.get("RealmContact") .addPrimaryKey("idx"); // .addField("idx", String.class, FieldAttribute.PRIMARY_KEY); oldVersion++; } // Migrate to version 2: Add a primary key + object references // Example: // public Person extends RealmObject { // private String name; // @PrimaryKey // private int age; // private Dog favoriteDog; // private RealmList<Dog> dogs; // // getters and setters left out for brevity // } if (oldVersion == 1) { /*schema.get("RealmContact") .addField("idx", String.class, FieldAttribute.PRIMARY_KEY) .addField("name", String.class) .addField("phone", String.class); oldVersion++;*/ } }
@Override public void migrate(DynamicRealm realm, long oldVersion, long newVersion) { RealmSchema schema = realm.getSchema(); Log.i(TAG, "MIGRATING DATABASE from v%d to v%d", oldVersion, newVersion); // why < 2? because I forgot to assign a schema version until I wrote this migration, so the // oldVersion here will be whatever default is assigned by Realm if (oldVersion < 2) { if (!schema.get("Post").hasField("customExcerpt")) { Log.d(TAG, "ADDING CUSTOM EXCERPT FIELD TO POST TABLE"); schema.get("Post").addField("customExcerpt", String.class); } oldVersion = 2; } }
@Override public void migrate(DynamicRealm realm, long oldVersion, long newVersion) { if (newVersion > oldVersion) { RealmSchema realmSchema = realm.getSchema(); if (oldVersion == 1) { realmSchema.create("UpgradeModel") .addField("localId", String.class, FieldAttribute.PRIMARY_KEY) .addField("version", String.class) .addField("url", String.class) .addField("compulsive_upgrade", String.class) .addField("description", String.class); } updateLearningModel(realmSchema); } }
private void updateLearningModel(RealmSchema realmSchema) { realmSchema.get("RealmLearningModel") .addField("netId", String.class) .addField("learningState", boolean.class) .addField("start", String.class) .addField("end", String.class) .addField("repeat", String.class) .addField("nextDay", String.class); }
@Override public void migrate(DynamicRealm realm, long oldVersion, long newVersion) { RealmSchema schema = realm.getSchema(); if (oldVersion < 1) { schema.get("Devotional").addField("unread", boolean.class); } }
@Override public void migrate(final DynamicRealm realm, long oldVersion, long newVersion) { // During a migration, a DynamicRealm is exposed. A DynamicRealm is an untyped variant of a normal Realm, but // with the same object creation and query capabilities. // A DynamicRealm uses Strings instead of Class references because the Classes might not even exist or have been // renamed. // Access the Realm schema in order to create, modify or delete classes and their fields. RealmSchema schema = realm.getSchema(); if(oldVersion==1){ RealmObjectSchema settingSchema = schema.get("Setting"); settingSchema.addField("locale",String.class) .transform(new RealmObjectSchema.Function() { @Override public void apply(DynamicRealmObject obj) { obj.set("locale","Auto"); } }); oldVersion++; } if(oldVersion==2){ RealmObjectSchema cacheSchema = schema.get("NetWorkCache"); cacheSchema.removeField("record").addField("record",String.class); oldVersion++; } }
@Override public void migrate(@NonNull DynamicRealm realm, long oldVersion, long newVersion) { // DynamicRealm exposes an editable schema RealmSchema schema = realm.getSchema(); if (schema == null) return; // TODO: Check in future versions if schema.get() returns null at some point try { if (oldVersion == 1) { schema.get("Sample") .addField("version", int.class); oldVersion++; } if (oldVersion == 2) { schema.get("Device") .removeField("serialNumber"); schema.get("Sample") .addField("database", int.class); oldVersion++; } } catch (NullPointerException e) { LOGE(TAG, "Schema is null!"); e.printStackTrace(); } }
@Override public void migrate(DynamicRealm realm, long oldVersion, long newVersion) { RealmSchema schema = realm.getSchema(); Crashlytics.log(Log.INFO, TAG, "MIGRATING DATABASE from v" + oldVersion + " to v" + newVersion); // why < 2? because I forgot to assign a schema version until I wrote this migration, so the // oldVersion here will be whatever default is assigned by Realm if (oldVersion < 2) { if (!schema.get("Post").hasField("customExcerpt")) { Crashlytics.log(Log.DEBUG, TAG, "ADDING CUSTOM EXCERPT FIELD TO POST TABLE"); schema.get("Post").addField("customExcerpt", String.class); } oldVersion = 2; } }
@Override public void migrate(DynamicRealm realm, long oldVersion, long newVersion) { //Mengambil schema RealmSchema schema = realm.getSchema(); //membuat schema baru jika versi 0 if (oldVersion == 0) { //Profil schema.create("Profil") .addField("nama", String.class) .addField("email", String.class) .addField("instansi", String.class); //Tugas schema.create("Akademik") .addField("judul", String.class) .addField("jenis", String.class) .addField("option", String.class) .addField("deadline", String.class) .addField("deskripsi", String.class) .addField("done", String.class); //Organisasi schema.create("Organisasi") .addField("judul", String.class) .addField("jenis", String.class) .addField("deadline", String.class) .addField("deskripsi", String.class) .addField("option", String.class) .addField("sebagai", String.class) .addField("tugas", String.class) .addField("presensi", String.class) .addField("notulensi", String.class) .addField("done", String.class); //Lainnya schema.create("Lainnya") .addField("judul", String.class) .addField("deadline", String.class) .addField("deskripsi", String.class) .addField("done", String.class); oldVersion++; } }
@Override public void migrate(DynamicRealm realm, long oldVersion, long newVersion) { // DynamicRealm exposes an editable schema RealmSchema schema = realm.getSchema(); // Migrate to version 1: Add a new class. // Example: // public Person extends RealmObject { // private String name; // private int age; // // getters and setters left out for brevity // } if (oldVersion == 0) { // Make updates to the schema here. For example: // schema.create("Person") // .addField("name", String.class) // .addField("age", int.class); // Increment so that old versions multiple steps behind get all migrations oldVersion++; } // Migrate to version 2: Add a primary key + object references // Example: // public Person extends RealmObject { // private String name; // @PrimaryKey // private int age; // private Dog favoriteDog; // private RealmList<Dog> dogs; // // getters and setters left out for brevity // } if (oldVersion == 1) { // Make updates to the schema here. For example: //schema.get("Person") // .addField("id", long.class, FieldAttribute.PRIMARY_KEY) // .addRealmObjectField("favoriteDog", schema.get("Dog")) // .addRealmListField("dogs", schema.get("Dog")); // Increment so that old versions multiple steps behind get all migrations oldVersion++; } }
@Override public void migrate(DynamicRealm realm, long oldVersion, long newVersion) { // DynamicRealm exposes an editable schema RealmSchema schema = realm.getSchema(); if (oldVersion == 0) { schema.get("Trip") .addField("synced", boolean.class); oldVersion++; } if (oldVersion == 1) { schema.get("StationUse") .addField("manualEntry", boolean.class); oldVersion++; } if (oldVersion == 2) { schema.get("Trip") .addField("userConfirmed", boolean.class); oldVersion++; } if (oldVersion == 3) { schema.get("Trip") .addField("submitted", boolean.class); oldVersion++; } if (oldVersion == 4) { schema.create("Feedback") .addField("id", String.class) .addPrimaryKey("id") .addField("synced", boolean.class) .addField("timestamp", Date.class) .setRequired("timestamp", true) .addField("type", String.class) .setRequired("type", true) .addField("contents", String.class) .setRequired("contents", true); oldVersion++; } if (oldVersion == 5) { schema.get("Trip") .addField("syncFailures", int.class); oldVersion++; } if (oldVersion == 6) { schema.create("NotificationRule") .addField("name", String.class) .setRequired("name", true) .addField("enabled", boolean.class) .addField("startTime", long.class) .addField("endTime", long.class) .addRealmListField("weekDays", Integer.class) .setRequired("weekDays", true); oldVersion++; } if (oldVersion == 7) { schema.get("NotificationRule") .addField("id", String.class) .addPrimaryKey("id"); oldVersion++; } }
@Override public void migrate(DynamicRealm realm, long oldVersion, long newVersion) { RealmSchema schema = realm.getSchema(); }
@Override public void migrate(DynamicRealm realm, long oldVersion, long newVersion) { // DynamicRealm exposes an editable schema RealmSchema schema = realm.getSchema(); // Migrate to version 1: Add a new class. // Example: // public Person extends RealmObject { // private String name; // private int age; // // getters and setters left out for brevity // } if (oldVersion == 0) { /* schema.create("Person") .addField("name", String.class) .addField("age", int.class); */ oldVersion++; } // Migrate to version 2: Add a primary key + object references // Example: // public Person extends RealmObject { // private String name; // @PrimaryKey // private int age; // private Dog favoriteDog; // private RealmList<Dog> dogs; // // getters and setters left out for brevity // } if (oldVersion == 1) { /* schema.get("Person") .addField("id", long.class, FieldAttribute.PRIMARY_KEY) .addRealmObjectField("favoriteDog", schema.get("Dog")) .addRealmListField("dogs", schema.get("Dog")); */ oldVersion++; } }
@Override public void migrate(@NonNull final DynamicRealm realm, long oldVersion, long newVersion) { Log.d(TAG, "Starting migration from " + oldVersion + " to " + newVersion); // Migration from versions < 9 not supported, versions prior 9 were missing the // contentHash for items if(oldVersion < 9) { throw new IllegalStateException("Migration from Schema < 9 not supported"); } RealmSchema schema = realm.getSchema(); /* 9 -> 10 - Add primary key ID to TemporaryFeed - Rename TemporaryFeed id to treeItemId - add TemporaryFeed object for list and pager activities */ if(oldVersion == 9) { realm.delete("TemporaryFeed"); final RealmObjectSchema temporaryFeedSchema = schema.get("TemporaryFeed"); if(temporaryFeedSchema == null) throw new IllegalStateException("TemporaryFeed schema not found"); temporaryFeedSchema .renameField(TemporaryFeed.ID, TemporaryFeed.TREE_ITEM_ID) .addField(TemporaryFeed.ID, long.class, FieldAttribute.PRIMARY_KEY); realm.createObject("TemporaryFeed", TemporaryFeed.LIST_ID); realm.createObject("TemporaryFeed", TemporaryFeed.PAGER_ID); oldVersion++; } /* 10 -> 11 - Make sure every item has updatedAt != null, set updatedAt = pubDate if not */ if(oldVersion == 10) { for(DynamicRealmObject object: realm.where("Item").isNull(Item.UPDATED_AT).findAll()) { object.setDate(Item.UPDATED_AT, object.getDate(Item.PUB_DATE)); } oldVersion++; } /* 11 -> 12 - Add active property to Item */ if(oldVersion == 11) { final RealmObjectSchema itemSchema = schema.get("Item"); if(itemSchema == null) throw new IllegalStateException("Item schema not found"); itemSchema .addField(Item.ACTIVE, boolean.class, FieldAttribute.INDEXED); //noinspection UnusedAssignment oldVersion++; } }