Skip to content

Commit

Permalink
After rebase fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
nirinchev committed Apr 8, 2022
1 parent d6c84f9 commit 13ccf15
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 96 deletions.
10 changes: 2 additions & 8 deletions lib/src/configuration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,14 @@ import 'realm_class.dart';
/// Configuration used to create a [Realm] instance
/// {@category Configuration}
class Configuration {
Function(Realm realm)? _initialDataCallback;

static String? _defaultPath;

/// The [RealmSchema] for this [Configuration]
final RealmSchema schema;

/// Creates a [Configuration] with schema objects for opening a [Realm].
Configuration(List<SchemaObject> schemaObjects,
{this.fifoFilesFallbackPath, this.isReadOnly = false, this.isInMemory = false, this.schemaVersion = 0, String? path})
{this.fifoFilesFallbackPath, this.isReadOnly = false, this.isInMemory = false, this.schemaVersion = 0, String? path, this.initialDataCallback})
: schema = RealmSchema(schemaObjects),
path = path ?? defaultPath;

Expand Down Expand Up @@ -101,11 +99,7 @@ class Configuration {
/// by the [path] you property. This property is ignored if the directory defined by [path] allow FIFO special files.
final String? fifoFilesFallbackPath;

Function(Realm realm)? get initialDataCallback => _initialDataCallback;
set initialDataCallback(Function(Realm realm)? value) {
_initialDataCallback = value;
realmCore.setConfigInitialDataCallback(this);
}
final Function(Realm realm)? initialDataCallback;
}

/// A collection of properties describing the underlying schema of a [RealmObject].
Expand Down
12 changes: 4 additions & 8 deletions lib/src/native/realm_core.dart
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@ class _RealmCore {
_realmLib.realm_config_set_path(configHandle._pointer, config.path.toUtf8Ptr(arena));
_realmLib.realm_config_set_scheduler(configHandle._pointer, schedulerHandle._pointer);

if (config.initialDataCallback != null) {
_realmLib.realm_dart_realm_config_set_initial_data_callback(configHandle._pointer, config, Pointer.fromFunction(initial_data_callback, FALSE));
}

return configHandle;
});
}
Expand All @@ -176,14 +180,6 @@ class _RealmCore {
return FALSE;
}

void setConfigInitialDataCallback(Configuration config) {
if (config.initialDataCallback == null) {
_realmLib.realm_dart_realm_config_set_initial_data_callback(config.handle._pointer, nullptr, nullptr);
} else {
_realmLib.realm_dart_realm_config_set_initial_data_callback(config.handle._pointer, config, Pointer.fromFunction(initial_data_callback, FALSE));
}
}

SchedulerHandle createScheduler(int isolateId, int sendPort) {
final schedulerPtr = _realmLib.realm_dart_create_scheduler(isolateId, sendPort);
return SchedulerHandle._(schedulerPtr);
Expand Down
8 changes: 2 additions & 6 deletions src/realm_dart.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,8 @@ RLM_API void realm_dart_realm_config_set_initial_data_callback(realm_config_t* c
Dart_Handle managed_config,
realm_dart_data_initialization_func_t on_data_initialization)
{
if (managed_config && on_data_initialization) {
auto initial_data_callback_data = new InitialDataCallbackData(managed_config, on_data_initialization);
realm_config_set_data_initialization_function(config, on_initial_data_callback, initial_data_callback_data);
} else {
realm_config_set_data_initialization_function(config, nullptr, nullptr);
}
auto initial_data_callback_data = new InitialDataCallbackData(managed_config, on_data_initialization);
realm_config_set_data_initialization_function(config, on_initial_data_callback, initial_data_callback_data);
}

#if (ANDROID)
Expand Down
104 changes: 30 additions & 74 deletions test/configuration_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,12 @@ Future<void> main([List<String>? args]) async {

test('Configuration.initialDataCallback invoked', () {
var invoked = false;
var config = Configuration([Dog.schema, Person.schema]);
config.initialDataCallback = (realm) {
var config = Configuration([Dog.schema, Person.schema], initialDataCallback: (realm) {
invoked = true;
realm.add(Dog('fido', owner: Person('john')));
};
});

final realm = Realm(config);
final realm = getRealm(config);
expect(invoked, true);

final people = realm.all<Person>();
Expand All @@ -162,132 +161,95 @@ Future<void> main([List<String>? args]) async {
final dogs = realm.all<Dog>();
expect(dogs.length, 1);
expect(dogs[0].name, 'fido');

realm.close();
});

test('Configuration.initialDataCallback can be unset', () {
var invoked = false;
var config = Configuration([Dog.schema, Person.schema]);
config.initialDataCallback = (realm) {
invoked = true;
realm.add(Dog('fido', owner: Person('john')));
};
config.initialDataCallback = null;

final realm = Realm(config);

expect(invoked, false);

final people = realm.all<Person>();
expect(people.length, 0);

final dogs = realm.all<Dog>();
expect(dogs.length, 0);

realm.close();
});

test('Configuration.initialDataCallback not invoked for existing realm', () {
var invoked = false;
final config = Configuration([Person.schema]);
config.initialDataCallback = (realm) {
final config = Configuration([Person.schema], initialDataCallback: (realm) {
invoked = true;
realm.add(Person('peter'));
};
});

final realm = Realm(config);
final realm = getRealm(config);
expect(invoked, true);
expect(realm.all<Person>().length, 1);
realm.close();

var invokedAgain = false;
final configAgain = Configuration([Person.schema]);
configAgain.initialDataCallback = (realm) {
final configAgain = Configuration([Person.schema], initialDataCallback: (realm) {
invokedAgain = true;
realm.add(Person('p1'));
realm.add(Person('p2'));
};
});

final realmAgain = Realm(config);
final realmAgain = getRealm(config);
expect(invokedAgain, false);
expect(realmAgain.all<Person>().length, 1);
realmAgain.close();
});

test('Configuration.initialDataCallback with error', () {
var invoked = false;
var config = Configuration([Person.schema]);
config.initialDataCallback = (realm) {
var config = Configuration([Person.schema], initialDataCallback: (realm) {
invoked = true;
realm.add(Person('p1'));
throw Exception('very careless developer');
};
});

expect(() => Realm(config), throws<RealmException>("User-provided callback failed"));
expect(() => getRealm(config), throws<RealmException>("User-provided callback failed"));
expect(invoked, true);

// No data should have been written to the Realm
config.initialDataCallback = null;
final realm = Realm(config);
config = Configuration([Person.schema]);
final realm = getRealm(config);

expect(realm.all<Person>().length, 0);

realm.close();
}, skip: 'TODO: fails to delete Realm - https://github.com/realm/realm-core/issues/5363');

test('Configuration.initialDataCallback with error, invoked on second attempt', () {
var invoked = false;
var config = Configuration([Person.schema]);
config.initialDataCallback = (realm) {
var config = Configuration([Person.schema], initialDataCallback: (realm) {
invoked = true;
realm.add(Person('p1'));
throw Exception('very careless developer');
};
});

expect(() => Realm(config), throws<RealmException>("User-provided callback failed"));
expect(() => getRealm(config), throws<RealmException>("User-provided callback failed"));
expect(invoked, true);

var secondInvoked = false;
config.initialDataCallback = (realm) {
config = Configuration([Person.schema], initialDataCallback: (realm) {
invoked = true;
realm.add(Person('p1'));
};
});

final realm = Realm(config);
final realm = getRealm(config);
expect(secondInvoked, true);
expect(realm.all<Person>().length, 1);

realm.close();
}, skip: 'TODO: Realm gets created even though it errors out on open - https://github.com/realm/realm-core/issues/5364');

test('Configuration.initialDataCallback is a no-op when opening an empty existing Realm', () {
var config = Configuration([Person.schema]);

// Create the Realm and close it
Realm(config).close();
getRealm(config).close();

var invoked = false;
config.initialDataCallback = (realm) {
config = Configuration([Person.schema], initialDataCallback: (realm) {
invoked = true;
realm.add(Person("john"));
};
});

// Even though the Realm was empty, since we're not creating it,
// we expect initialDataCallback not to be invoked.
final realm = Realm(config);
final realm = getRealm(config);

expect(invoked, false);
expect(realm.all<Person>().length, 0);

realm.close();
});

test('Configuration.initialDataCallback can use non-add API in callback', () {
var config = Configuration([Person.schema]);

Exception? callbackEx;
config.initialDataCallback = (realm) {
final config = Configuration([Person.schema], initialDataCallback: (realm) {
try {
final george = realm.add(Person("George"));

Expand All @@ -297,33 +259,27 @@ Future<void> main([List<String>? args]) async {
} on Exception catch (ex) {
callbackEx = ex;
}
};
});

final realm = Realm(config);
final realm = getRealm(config);

expect(callbackEx, null);
expect(realm.all<Person>().length, 0);

realm.close();
});

test('Configuration.initialDataCallback realm.write fails', () {
var config = Configuration([Person.schema]);

Exception? callbackEx;
config.initialDataCallback = (realm) {
final config = Configuration([Person.schema], initialDataCallback: (realm) {
try {
realm.write(() => null);
} on RealmException catch (ex) {
callbackEx = ex;
}
};
});

final realm = Realm(config);
final realm = getRealm(config);

expect(callbackEx, isNotNull);
expect(callbackEx.toString(), contains('The Realm is already in a write transaction'));

realm.close();
});
}

0 comments on commit 13ccf15

Please sign in to comment.