use of io.realm.exceptions.RealmMigrationNeededException in project realm-java by realm.
the class RealmMigrationTests method notSettingRequiredForNotNullableThrows.
// If a required field was nullable before, a RealmMigrationNeededException should be thrown.
@Test
public void notSettingRequiredForNotNullableThrows() {
String[] notNullableFields = { NullTypes.FIELD_STRING_NOT_NULL, NullTypes.FIELD_BYTES_NOT_NULL, NullTypes.FIELD_BOOLEAN_NOT_NULL, NullTypes.FIELD_BYTE_NOT_NULL, NullTypes.FIELD_SHORT_NOT_NULL, NullTypes.FIELD_INTEGER_NOT_NULL, NullTypes.FIELD_LONG_NOT_NULL, NullTypes.FIELD_FLOAT_NOT_NULL, NullTypes.FIELD_DOUBLE_NOT_NULL, NullTypes.FIELD_DATE_NOT_NULL };
for (final String field : notNullableFields) {
final RealmMigration migration = new RealmMigration() {
@Override
public void migrate(DynamicRealm realm, long oldVersion, long newVersion) {
if (oldVersion == 0) {
// 0 after initNullTypesTableExcludes
// No @Required for not nullable field
RealmObjectSchema nullTypesSchema = realm.getSchema().getSchemaForClass(NullTypes.CLASS_NAME);
if (field.equals(NullTypes.FIELD_STRING_NOT_NULL)) {
// 1 String
nullTypesSchema.addField(field, String.class);
} else if (field.equals(NullTypes.FIELD_BYTES_NOT_NULL)) {
// 2 Bytes
nullTypesSchema.addField(field, byte[].class);
} else if (field.equals(NullTypes.FIELD_BOOLEAN_NOT_NULL)) {
// 3 Boolean
nullTypesSchema.addField(field, Boolean.class);
//table.addColumn(RealmFieldType.BOOLEAN, field, Table.NULLABLE);
} else if (field.equals(NullTypes.FIELD_BYTE_NOT_NULL) || field.equals(NullTypes.FIELD_SHORT_NOT_NULL) || field.equals(NullTypes.FIELD_INTEGER_NOT_NULL) || field.equals(NullTypes.FIELD_LONG_NOT_NULL)) {
// 4 Byte 5 Short 6 Integer 7 Long
nullTypesSchema.addField(field, Integer.class);
} else if (field.equals(NullTypes.FIELD_FLOAT_NOT_NULL)) {
// 8 Float
nullTypesSchema.addField(field, Float.class);
} else if (field.equals(NullTypes.FIELD_DOUBLE_NOT_NULL)) {
// 9 Double
nullTypesSchema.addField(field, Double.class);
} else if (field.equals(NullTypes.FIELD_DATE_NOT_NULL)) {
// 10 Date
nullTypesSchema.addField(field, Date.class);
}
// 11 Object skipped
}
}
};
@SuppressWarnings("unchecked") RealmConfiguration realmConfig = configFactory.createConfigurationBuilder().schemaVersion(1).schema(NullTypes.class).migration(migration).build();
Realm.deleteRealm(realmConfig);
// Prepares the version 0 db.
DynamicRealm dynamicRealm = DynamicRealm.getInstance(realmConfig);
TestHelper.initNullTypesTableExcludes(dynamicRealm, field);
dynamicRealm.close();
try {
realm = Realm.getInstance(realmConfig);
fail("Failed on " + field);
} catch (RealmMigrationNeededException e) {
assertEquals("Field '" + field + "' does support null values in the existing Realm file." + " Remove @Required or @PrimaryKey from field '" + field + "' " + "or migrate using RealmObjectSchema.setNullable().", e.getMessage());
}
}
}
use of io.realm.exceptions.RealmMigrationNeededException in project realm-java by realm.
the class RealmMigrationTests method migrationException_getPath.
@Test
public void migrationException_getPath() throws IOException {
configFactory.copyRealmFromAssets(context, "default0.realm", Realm.DEFAULT_REALM_NAME);
File realm = new File(configFactory.getRoot(), Realm.DEFAULT_REALM_NAME);
try {
Realm.getInstance(configFactory.createConfiguration());
fail();
} catch (RealmMigrationNeededException expected) {
assertEquals(expected.getPath(), realm.getCanonicalPath());
}
}
use of io.realm.exceptions.RealmMigrationNeededException in project realm-java by realm.
the class BaseRealm method migrateRealm.
/**
* Migrates the Realm file defined by the given configuration using the provided migration block.
*
* @param configuration configuration for the Realm that should be migrated. If this is a SyncConfiguration this
* method does nothing.
* @param migration if set, this migration block will override what is set in {@link RealmConfiguration}.
* @param callback callback for specific Realm type behaviors.
* @param cause which triggers this migration.
* @throws FileNotFoundException if the Realm file doesn't exist.
* @throws IllegalArgumentException if the provided configuration is a {@link SyncConfiguration}.
*/
protected static void migrateRealm(final RealmConfiguration configuration, final RealmMigration migration, final MigrationCallback callback, final RealmMigrationNeededException cause) throws FileNotFoundException {
if (configuration == null) {
throw new IllegalArgumentException("RealmConfiguration must be provided");
}
if (configuration.isSyncConfiguration()) {
throw new IllegalArgumentException("Manual migrations are not supported for synced Realms");
}
if (migration == null && configuration.getMigration() == null) {
throw new RealmMigrationNeededException(configuration.getPath(), "RealmMigration must be provided", cause);
}
final AtomicBoolean fileNotFound = new AtomicBoolean(false);
RealmCache.invokeWithGlobalRefCount(configuration, new RealmCache.Callback() {
@Override
public void onResult(int count) {
if (count != 0) {
throw new IllegalStateException("Cannot migrate a Realm file that is already open: " + configuration.getPath());
}
File realmFile = new File(configuration.getPath());
if (!realmFile.exists()) {
fileNotFound.set(true);
return;
}
RealmMigration realmMigration = (migration == null) ? configuration.getMigration() : migration;
DynamicRealm realm = null;
try {
realm = DynamicRealm.getInstance(configuration);
realm.beginTransaction();
long currentVersion = realm.getVersion();
realmMigration.migrate(realm, currentVersion, configuration.getSchemaVersion());
realm.setVersion(configuration.getSchemaVersion());
realm.commitTransaction();
} catch (RuntimeException e) {
if (realm != null) {
realm.cancelTransaction();
}
throw e;
} finally {
if (realm != null) {
realm.close();
callback.migrationComplete();
}
}
}
});
if (fileNotFound.get()) {
throw new FileNotFoundException("Cannot migrate a Realm file which doesn't exist: " + configuration.getPath());
}
}
use of io.realm.exceptions.RealmMigrationNeededException in project realm-java by realm.
the class Realm method createAndValidate.
private static Realm createAndValidate(RealmConfiguration configuration, ColumnIndices[] globalCacheArray) {
Realm realm = new Realm(configuration);
final long currentVersion = realm.getVersion();
final long requiredVersion = configuration.getSchemaVersion();
final ColumnIndices columnIndices = RealmCache.findColumnIndices(globalCacheArray, requiredVersion);
if (columnIndices != null) {
// Copies global cache as a Realm local indices cache.
realm.schema.columnIndices = columnIndices.clone();
} else {
final boolean syncingConfig = configuration.isSyncConfiguration();
if (!syncingConfig && (currentVersion != UNVERSIONED)) {
if (currentVersion < requiredVersion) {
realm.doClose();
throw new RealmMigrationNeededException(configuration.getPath(), String.format("Realm on disk need to migrate from v%s to v%s", currentVersion, requiredVersion));
}
if (requiredVersion < currentVersion) {
realm.doClose();
throw new IllegalArgumentException(String.format("Realm on disk is newer than the one specified: v%s vs. v%s", currentVersion, requiredVersion));
}
}
// Initializes Realm schema if needed.
try {
if (!syncingConfig) {
initializeRealm(realm);
} else {
initializeSyncedRealm(realm);
}
} catch (RuntimeException e) {
realm.doClose();
throw e;
}
}
return realm;
}
use of io.realm.exceptions.RealmMigrationNeededException in project realm-java by realm.
the class Realm method updateSchemaCache.
/**
* Updates own schema cache.
*
* @param globalCacheArray global cache of column indices. If it contains an entry for current
* schema version, this method only copies the indices information in the entry.
* @return newly created indices information for current schema version. Or {@code null} if {@code globalCacheArray}
* already contains the entry for current schema version.
*/
ColumnIndices updateSchemaCache(ColumnIndices[] globalCacheArray) {
final long currentSchemaVersion = sharedRealm.getSchemaVersion();
final long cacheSchemaVersion = schema.columnIndices.getSchemaVersion();
if (currentSchemaVersion == cacheSchemaVersion) {
return null;
}
ColumnIndices createdGlobalCache = null;
final RealmProxyMediator mediator = getConfiguration().getSchemaMediator();
ColumnIndices cacheForCurrentVersion = RealmCache.findColumnIndices(globalCacheArray, currentSchemaVersion);
if (cacheForCurrentVersion == null) {
// Not found in global cache. create it.
final Set<Class<? extends RealmModel>> modelClasses = mediator.getModelClasses();
final Map<Class<? extends RealmModel>, ColumnInfo> map;
map = new HashMap<Class<? extends RealmModel>, ColumnInfo>(modelClasses.size());
try {
for (Class<? extends RealmModel> clazz : modelClasses) {
final ColumnInfo columnInfo = mediator.validateTable(clazz, sharedRealm, true);
map.put(clazz, columnInfo);
}
} catch (RealmMigrationNeededException e) {
throw e;
}
cacheForCurrentVersion = createdGlobalCache = new ColumnIndices(currentSchemaVersion, map);
}
schema.columnIndices.copyFrom(cacheForCurrentVersion, mediator);
return createdGlobalCache;
}
Aggregations