From 8696b0c701420f35576335604ce4ade290716807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kasper=20Overg=C3=A5rd=20Nielsen?= Date: Fri, 26 Apr 2024 11:14:22 +0200 Subject: [PATCH] More RealmHandle stuff --- .../realm_dart/lib/src/native/realm_core.dart | 115 +----------------- .../lib/src/native/realm_handle.dart | 115 ++++++++++++++++++ 2 files changed, 118 insertions(+), 112 deletions(-) diff --git a/packages/realm_dart/lib/src/native/realm_core.dart b/packages/realm_dart/lib/src/native/realm_core.dart index 80cd53575..d28c989a7 100644 --- a/packages/realm_dart/lib/src/native/realm_core.dart +++ b/packages/realm_dart/lib/src/native/realm_core.dart @@ -13,7 +13,6 @@ import 'package:crypto/crypto.dart'; import 'package:ffi/ffi.dart' hide StringUtf8Pointer, StringUtf16Pointer; import 'package:path/path.dart' as path; import 'package:pubspec_parse/pubspec_parse.dart'; -import 'package:realm_common/realm_common.dart' hide Decimal128; import '../app.dart'; import '../configuration.dart'; @@ -352,72 +351,7 @@ class _RealmCore { return AsyncOpenTaskProgressNotificationTokenHandle(tokenPtr); } - RealmSchema readSchema(Realm realm) { - return using((Arena arena) { - return _readSchema(realm.handle, arena); - }); - } - - RealmSchema _readSchema(RealmHandle realm, Arena arena, {int expectedSize = 10}) { - final classesPtr = arena(expectedSize); - final actualCount = arena(); - invokeGetBool(() => realmLib.realm_get_class_keys(realm.pointer, classesPtr, expectedSize, actualCount)); - if (expectedSize < actualCount.value) { - arena.free(classesPtr); - return _readSchema(realm, arena, expectedSize: actualCount.value); - } - - final schemas = []; - for (var i = 0; i < actualCount.value; i++) { - final classInfo = arena(); - final classKey = (classesPtr + i).value; - invokeGetBool(() => realmLib.realm_get_class(realm.pointer, classKey, classInfo)); - - final name = classInfo.ref.name.cast().toDartString(); - final baseType = ObjectType.values.firstWhere((element) => element.flags == classInfo.ref.flags, - orElse: () => throw RealmError('No object type found for flags ${classInfo.ref.flags}')); - final schema = - _getSchemaForClassKey(realm, classKey, name, baseType, arena, expectedSize: classInfo.ref.num_properties + classInfo.ref.num_computed_properties); - schemas.add(schema); - } - - return RealmSchema(schemas); - } - - SchemaObject _getSchemaForClassKey(RealmHandle realm, int classKey, String name, ObjectType baseType, Arena arena, {int expectedSize = 10}) { - final actualCount = arena(); - final propertiesPtr = arena(expectedSize); - invokeGetBool(() => realmLib.realm_get_class_properties(realm.pointer, classKey, propertiesPtr, expectedSize, actualCount)); - - if (expectedSize < actualCount.value) { - // The supplied array was too small - resize it - arena.free(propertiesPtr); - return _getSchemaForClassKey(realm, classKey, name, baseType, arena, expectedSize: actualCount.value); - } - - final result = []; - for (var i = 0; i < actualCount.value; i++) { - final property = (propertiesPtr + i).ref.toSchemaProperty(); - result.add(property); - } - - late Type type; - switch (baseType) { - case ObjectType.realmObject: - type = RealmObject; - break; - case ObjectType.embeddedObject: - type = EmbeddedObject; - break; - case ObjectType.asymmetricObject: - type = AsymmetricObject; - break; - default: - throw RealmError('$baseType is not supported yet'); - } - - return SchemaObject(baseType, type, name, result); - } + RealmSchema readSchema(Realm realm) => realm.handle.readSchema(); void deleteRealmFiles(String path) { using((Arena arena) { @@ -426,52 +360,9 @@ class _RealmCore { }); } - RealmObjectMetadata getObjectMetadata(Realm realm, SchemaObject schema) { - return using((Arena arena) { - final found = arena(); - final classInfo = arena(); - invokeGetBool(() => realmLib.realm_find_class(realm.handle.pointer, schema.name.toCharPtr(arena), found, classInfo), - "Error getting class ${schema.name} from realm at ${realm.config.path}"); - - if (!found.value) { - throwLastError("Class ${schema.name} not found in ${realm.config.path}"); - } - - final primaryKey = classInfo.ref.primary_key.cast().toRealmDartString(treatEmptyAsNull: true); - return RealmObjectMetadata(schema, classInfo.ref.key, _getPropertiesMetadata(realm, classInfo.ref.key, primaryKey, arena)); - }); - } - - Map getPropertiesMetadata(Realm realm, int classKey, String? primaryKeyName) { - return using((Arena arena) { - return _getPropertiesMetadata(realm, classKey, primaryKeyName, arena); - }); - } + RealmObjectMetadata getObjectMetadata(Realm realm, SchemaObject schema) => realm.handle.getObjectMetadata(schema); - Map _getPropertiesMetadata(Realm realm, int classKey, String? primaryKeyName, Arena arena) { - final propertyCountPtr = arena(); - invokeGetBool(() => realmLib.realm_get_property_keys(realm.handle.pointer, classKey, nullptr, 0, propertyCountPtr), "Error getting property count"); - - var propertyCount = propertyCountPtr.value; - final propertiesPtr = arena(propertyCount); - invokeGetBool(() => realmLib.realm_get_class_properties(realm.handle.pointer, classKey, propertiesPtr, propertyCount, propertyCountPtr), - "Error getting class properties."); - - propertyCount = propertyCountPtr.value; - Map result = {}; - for (var i = 0; i < propertyCount; i++) { - final property = propertiesPtr + i; - final propertyName = property.ref.name.cast().toRealmDartString()!; - final objectType = property.ref.link_target.cast().toRealmDartString(treatEmptyAsNull: true); - final linkOriginProperty = property.ref.link_origin_property_name.cast().toRealmDartString(treatEmptyAsNull: true); - final isNullable = property.ref.flags & realm_property_flags.RLM_PROPERTY_NULLABLE != 0; - final isPrimaryKey = propertyName == primaryKeyName; - final propertyMeta = RealmPropertyMetadata(property.ref.key, objectType, linkOriginProperty, RealmPropertyType.values.elementAt(property.ref.type), - isNullable, isPrimaryKey, RealmCollectionType.values.elementAt(property.ref.collection_type)); - result[propertyName] = propertyMeta; - } - return result; - } + Map getPropertiesMetadata(Realm realm, int classKey, String? primaryKeyName) => realm.handle.getPropertiesMetadata(classKey, primaryKeyName); // For debugging // ignore: unused_element diff --git a/packages/realm_dart/lib/src/native/realm_handle.dart b/packages/realm_dart/lib/src/native/realm_handle.dart index 1467cceea..2636c894e 100644 --- a/packages/realm_dart/lib/src/native/realm_handle.dart +++ b/packages/realm_dart/lib/src/native/realm_handle.dart @@ -6,9 +6,11 @@ import 'dart:ffi'; import 'package:cancellation_token/cancellation_token.dart'; import 'package:ffi/ffi.dart'; +import 'package:realm_common/realm_common.dart'; import '../logging.dart'; import '../realm_class.dart'; +import '../realm_object.dart'; import 'config_handle.dart'; import 'convert.dart'; import 'error_handling.dart'; @@ -321,6 +323,119 @@ class RealmHandle extends HandleBase { ); return CallbackTokenHandle(ptr, this); } + + RealmSchema readSchema() { + return using((Arena arena) { + return _readSchema(arena); + }); + } + + RealmSchema _readSchema(Arena arena, {int expectedSize = 10}) { + final classesPtr = arena(expectedSize); + final actualCount = arena(); + invokeGetBool(() => realmLib.realm_get_class_keys(pointer, classesPtr, expectedSize, actualCount)); + if (expectedSize < actualCount.value) { + arena.free(classesPtr); + return _readSchema(arena, expectedSize: actualCount.value); + } + + final schemas = []; + for (var i = 0; i < actualCount.value; i++) { + final classInfo = arena(); + final classKey = (classesPtr + i).value; + invokeGetBool(() => realmLib.realm_get_class(pointer, classKey, classInfo)); + + final name = classInfo.ref.name.cast().toDartString(); + final baseType = ObjectType.values.firstWhere((element) => element.flags == classInfo.ref.flags, + orElse: () => throw RealmError('No object type found for flags ${classInfo.ref.flags}')); + final schema = _getSchemaForClassKey(classKey, name, baseType, arena, expectedSize: classInfo.ref.num_properties + classInfo.ref.num_computed_properties); + schemas.add(schema); + } + + return RealmSchema(schemas); + } + + SchemaObject _getSchemaForClassKey(int classKey, String name, ObjectType baseType, Arena arena, {int expectedSize = 10}) { + final actualCount = arena(); + final propertiesPtr = arena(expectedSize); + invokeGetBool(() => realmLib.realm_get_class_properties(pointer, classKey, propertiesPtr, expectedSize, actualCount)); + + if (expectedSize < actualCount.value) { + // The supplied array was too small - resize it + arena.free(propertiesPtr); + return _getSchemaForClassKey(classKey, name, baseType, arena, expectedSize: actualCount.value); + } + + final result = []; + for (var i = 0; i < actualCount.value; i++) { + final property = (propertiesPtr + i).ref.toSchemaProperty(); + result.add(property); + } + + late Type type; + switch (baseType) { + case ObjectType.realmObject: + type = RealmObject; + break; + case ObjectType.embeddedObject: + type = EmbeddedObject; + break; + case ObjectType.asymmetricObject: + type = AsymmetricObject; + break; + default: + throw RealmError('$baseType is not supported yet'); + } + + return SchemaObject(baseType, type, name, result); + } + + Map getPropertiesMetadata(int classKey, String? primaryKeyName) { + return using((Arena arena) { + return _getPropertiesMetadata(classKey, primaryKeyName, arena); + }); + } + + RealmObjectMetadata getObjectMetadata(SchemaObject schema) { + return using((Arena arena) { + final found = arena(); + final classInfo = arena(); + invokeGetBool(() => realmLib.realm_find_class(pointer, schema.name.toCharPtr(arena), found, classInfo)); + // "Error getting class ${schema.name} from realm at ${realm.config.path}"); + + if (!found.value) { + throwLastError(); //"Class ${schema.name} not found in ${realm.config.path}"); + } + + final primaryKey = classInfo.ref.primary_key.cast().toRealmDartString(treatEmptyAsNull: true); + return RealmObjectMetadata(schema, classInfo.ref.key, _getPropertiesMetadata(classInfo.ref.key, primaryKey, arena)); + }); + } + + Map _getPropertiesMetadata(int classKey, String? primaryKeyName, Arena arena) { + final propertyCountPtr = arena(); + invokeGetBool(() => realmLib.realm_get_property_keys(pointer, classKey, nullptr, 0, propertyCountPtr), "Error getting property count"); + + var propertyCount = propertyCountPtr.value; + final propertiesPtr = arena(propertyCount); + invokeGetBool( + () => realmLib.realm_get_class_properties(pointer, classKey, propertiesPtr, propertyCount, propertyCountPtr), "Error getting class properties."); + + propertyCount = propertyCountPtr.value; + Map result = {}; + for (var i = 0; i < propertyCount; i++) { + final property = propertiesPtr + i; + final propertyName = property.ref.name.cast().toRealmDartString()!; + final objectType = property.ref.link_target.cast().toRealmDartString(treatEmptyAsNull: true); + final linkOriginProperty = property.ref.link_origin_property_name.cast().toRealmDartString(treatEmptyAsNull: true); + final isNullable = property.ref.flags & realm_property_flags.RLM_PROPERTY_NULLABLE != 0; + final isPrimaryKey = propertyName == primaryKeyName; + final propertyMeta = RealmPropertyMetadata(property.ref.key, objectType, linkOriginProperty, RealmPropertyType.values.elementAt(property.ref.type), + isNullable, isPrimaryKey, RealmCollectionType.values.elementAt(property.ref.collection_type)); + result[propertyName] = propertyMeta; + } + return result; + } } class CallbackTokenHandle extends RootedHandleBase {