diff --git a/Realm/Realm/DatabaseTypes/RealmObjectBase.cs b/Realm/Realm/DatabaseTypes/RealmObjectBase.cs index 499285f6f5..a32a9cde79 100644 --- a/Realm/Realm/DatabaseTypes/RealmObjectBase.cs +++ b/Realm/Realm/DatabaseTypes/RealmObjectBase.cs @@ -30,6 +30,7 @@ using Realms.DataBinding; using Realms.Exceptions; using Realms.Helpers; +using Realms.Native; using Realms.Schema; using Realms.Weaving; @@ -255,7 +256,7 @@ public IQueryable GetBacklinks(string objectType, string property) Argument.Ensure(Realm.Metadata.TryGetValue(objectType, out var relatedMeta), $"Could not find schema for type {objectType}", nameof(objectType)); Argument.Ensure(relatedMeta.PropertyIndices.ContainsKey(property), $"Type {objectType} does not contain property {property}", nameof(property)); - var resultsHandle = ObjectHandle.GetBacklinksForType(relatedMeta.Table, relatedMeta.PropertyIndices[property]); + var resultsHandle = ObjectHandle.GetBacklinksForType(relatedMeta.TableKey, relatedMeta.PropertyIndices[property]); if (relatedMeta.Schema.IsEmbedded) { return new RealmResults(Realm, resultsHandle, relatedMeta); @@ -435,7 +436,7 @@ public TypeInfo GetTypeInfo() internal class Metadata { - internal readonly TableHandle Table; + internal readonly TableKey TableKey; internal readonly IRealmObjectHelper Helper; @@ -443,9 +444,9 @@ internal class Metadata internal readonly ObjectSchema Schema; - public Metadata(TableHandle table, IRealmObjectHelper helper, IDictionary propertyIndices, ObjectSchema schema) + public Metadata(TableKey tableKey, IRealmObjectHelper helper, IDictionary propertyIndices, ObjectSchema schema) { - Table = table; + TableKey = tableKey; Helper = helper; PropertyIndices = new ReadOnlyDictionary(propertyIndices); Schema = schema; diff --git a/Realm/Realm/Handles/ObjectHandle.cs b/Realm/Realm/Handles/ObjectHandle.cs index 23349d9a95..da3d41a487 100644 --- a/Realm/Realm/Handles/ObjectHandle.cs +++ b/Realm/Realm/Handles/ObjectHandle.cs @@ -69,7 +69,7 @@ private static class NativeMethods public static extern IntPtr get_backlinks(ObjectHandle objectHandle, IntPtr property_index, out NativeException nativeException); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "object_get_backlinks_for_type", CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr get_backlinks_for_type(ObjectHandle objectHandle, TableHandle source_table, IntPtr source_property_index, out NativeException nativeException); + public static extern IntPtr get_backlinks_for_type(ObjectHandle objectHandle, TableKey table_key, IntPtr source_property_index, out NativeException nativeException); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "object_get_thread_safe_reference", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr get_thread_safe_reference(ObjectHandle objectHandle, out NativeException ex); @@ -260,9 +260,9 @@ public ResultsHandle GetBacklinks(IntPtr propertyIndex) return new ResultsHandle(this, resultsPtr); } - public ResultsHandle GetBacklinksForType(TableHandle table, IntPtr propertyIndex) + public ResultsHandle GetBacklinksForType(TableKey tableKey, IntPtr propertyIndex) { - var resultsPtr = NativeMethods.get_backlinks_for_type(this, table, propertyIndex, out var nativeException); + var resultsPtr = NativeMethods.get_backlinks_for_type(this, tableKey, propertyIndex, out var nativeException); nativeException.ThrowIfNecessary(); return new ResultsHandle(this, resultsPtr); diff --git a/Realm/Realm/Handles/SharedRealmHandle.cs b/Realm/Realm/Handles/SharedRealmHandle.cs index 5bb88a1a18..3a54fa77cc 100644 --- a/Realm/Realm/Handles/SharedRealmHandle.cs +++ b/Realm/Realm/Handles/SharedRealmHandle.cs @@ -100,8 +100,8 @@ public static extern IntPtr open_with_sync_async(Configuration configuration, Sy [return: MarshalAs(UnmanagedType.U1)] public static extern bool refresh(SharedRealmHandle sharedRealm, out NativeException ex); - [DllImport(InteropConfig.DLL_NAME, EntryPoint = "shared_realm_get_table", CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr get_table(SharedRealmHandle sharedRealm, [MarshalAs(UnmanagedType.LPWStr)] string tableName, IntPtr tableNameLength, out NativeException ex); + [DllImport(InteropConfig.DLL_NAME, EntryPoint = "shared_realm_get_table_key", CallingConvention = CallingConvention.Cdecl)] + public static extern TableKey get_table_key(SharedRealmHandle sharedRealm, [MarshalAs(UnmanagedType.LPWStr)] string tableName, IntPtr tableNameLength, out NativeException ex); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "shared_realm_is_same_instance", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.U1)] @@ -124,10 +124,10 @@ public static extern IntPtr open_with_sync_async(Configuration configuration, Sy public static extern void write_copy(SharedRealmHandle sharedRealm, [MarshalAs(UnmanagedType.LPWStr)] string path, IntPtr path_len, byte[] encryptionKey, out NativeException ex); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "shared_realm_create_object", CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr create_object(SharedRealmHandle sharedRealm, TableHandle table, out NativeException ex); + public static extern IntPtr create_object(SharedRealmHandle sharedRealm, TableKey table_key, out NativeException ex); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "shared_realm_create_object_unique", CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr create_object_unique(SharedRealmHandle sharedRealm, TableHandle table, PrimitiveValue value, + public static extern IntPtr create_object_unique(SharedRealmHandle sharedRealm, TableKey table_key, PrimitiveValue value, [MarshalAs(UnmanagedType.U1)] bool update, [MarshalAs(UnmanagedType.U1)] out bool is_new, out NativeException ex); @@ -148,6 +148,12 @@ public static extern IntPtr create_object_unique(SharedRealmHandle sharedRealm, [DllImport(InteropConfig.DLL_NAME, EntryPoint = "shared_realm_freeze", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr freeze(SharedRealmHandle sharedRealm, out NativeException ex); + [DllImport(InteropConfig.DLL_NAME, EntryPoint = "shared_realm_get_object_for_primary_key", CallingConvention = CallingConvention.Cdecl)] + public static extern IntPtr get_object_for_primary_key(SharedRealmHandle realmHandle, TableKey table_key, PrimitiveValue value, out NativeException ex); + + [DllImport(InteropConfig.DLL_NAME, EntryPoint = "shared_realm_create_results", CallingConvention = CallingConvention.Cdecl)] + public static extern IntPtr create_results(SharedRealmHandle sharedRealm, TableKey table_key, out NativeException ex); + #pragma warning restore IDE1006 // Naming Styles } @@ -275,11 +281,11 @@ public bool Refresh() return result; } - public TableHandle GetTable(string tableName) + public TableKey GetTableKey(string tableName) { - var result = NativeMethods.get_table(this, tableName, (IntPtr)tableName.Length, out var nativeException); + var tableKey = NativeMethods.get_table_key(this, tableName, (IntPtr)tableName.Length, out var nativeException); nativeException.ThrowIfNecessary(); - return new TableHandle(this, result); + return tableKey; } public bool IsSameInstance(SharedRealmHandle other) @@ -331,14 +337,14 @@ public void GetSchema(Action callback) nativeException.ThrowIfNecessary(); } - public ObjectHandle CreateObject(TableHandle table) + public ObjectHandle CreateObject(TableKey tableKey) { - var result = NativeMethods.create_object(this, table, out NativeException ex); + var result = NativeMethods.create_object(this, tableKey, out NativeException ex); ex.ThrowIfNecessary(); return new ObjectHandle(this, result); } - public unsafe ObjectHandle CreateObjectWithPrimaryKey(Property pkProperty, object primaryKey, TableHandle table, string parentType, bool update, out bool isNew) + public unsafe ObjectHandle CreateObjectWithPrimaryKey(Property pkProperty, object primaryKey, TableKey tableKey, string parentType, bool update, out bool isNew) { if (primaryKey == null && !pkProperty.Type.IsNullable()) { @@ -355,7 +361,7 @@ public unsafe ObjectHandle CreateObjectWithPrimaryKey(Property pkProperty, objec }; var (primitiveValue, handles) = pkValue.ToNative(); - var result = NativeMethods.create_object_unique(this, table, primitiveValue, update, out isNew, out var ex); + var result = NativeMethods.create_object_unique(this, tableKey, primitiveValue, update, out isNew, out var ex); handles?.Dispose(); ex.ThrowIfNecessary(); return new ObjectHandle(this, result); @@ -373,6 +379,30 @@ public SharedRealmHandle Freeze() return new SharedRealmHandle(result); } + public unsafe bool TryFindObject(TableKey tableKey, in RealmValue id, out ObjectHandle objectHandle) + { + var (primitiveValue, handles) = id.ToNative(); + var result = NativeMethods.get_object_for_primary_key(this, tableKey, primitiveValue, out var ex); + handles?.Dispose(); + ex.ThrowIfNecessary(); + + if (result == IntPtr.Zero) + { + objectHandle = null; + return false; + } + + objectHandle = new ObjectHandle(this, result); + return true; + } + + public ResultsHandle CreateResults(TableKey tableKey) + { + var result = NativeMethods.create_results(this, tableKey, out var nativeException); + nativeException.ThrowIfNecessary(); + return new ResultsHandle(this, result); + } + [MonoPInvokeCallback(typeof(NativeMethods.GetNativeSchemaCallback))] private static void GetNativeSchema(Native.Schema schema, IntPtr managedCallbackPtr) { diff --git a/Realm/Realm/Handles/SortDescriptorHandle.cs b/Realm/Realm/Handles/SortDescriptorHandle.cs index f0985e1fb2..1fd77f1bdf 100644 --- a/Realm/Realm/Handles/SortDescriptorHandle.cs +++ b/Realm/Realm/Handles/SortDescriptorHandle.cs @@ -18,6 +18,7 @@ using System; using System.Runtime.InteropServices; +using Realms.Native; namespace Realms { @@ -29,7 +30,7 @@ private static class NativeMethods public static extern void destroy(IntPtr queryHandle); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "sort_descriptor_add_clause", CallingConvention = CallingConvention.Cdecl)] - public static extern void add_clause(SortDescriptorHandle descriptor, TableHandle query, SharedRealmHandle realm, + public static extern void add_clause(SortDescriptorHandle descriptor, TableKey table_key, SharedRealmHandle realm, [MarshalAs(UnmanagedType.LPArray), In] IntPtr[] property_index_chain, IntPtr column_keys_count, [MarshalAs(UnmanagedType.U1)] bool ascending, out NativeException ex); @@ -39,9 +40,9 @@ public SortDescriptorHandle(RealmHandle root, IntPtr handle) : base(root, handle { } - public void AddClause(TableHandle table, SharedRealmHandle realm, IntPtr[] propertyIndexChain, bool ascending) + public void AddClause(SharedRealmHandle realm, TableKey tableKey, IntPtr[] propertyIndexChain, bool ascending) { - NativeMethods.add_clause(this, table, realm, propertyIndexChain, (IntPtr)propertyIndexChain.Length, ascending, out var nativeException); + NativeMethods.add_clause(this, tableKey, realm, propertyIndexChain, (IntPtr)propertyIndexChain.Length, ascending, out var nativeException); nativeException.ThrowIfNecessary(); } diff --git a/Realm/Realm/Handles/TableHandle.cs b/Realm/Realm/Handles/TableHandle.cs deleted file mode 100644 index ec140816f5..0000000000 --- a/Realm/Realm/Handles/TableHandle.cs +++ /dev/null @@ -1,94 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2016 Realm Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -//////////////////////////////////////////////////////////////////////////// - -using System; -using System.Runtime.InteropServices; -using Realms.Native; - -namespace Realms -{ - internal class TableHandle : RealmHandle - { - private static class NativeMethods - { -#pragma warning disable IDE1006 // Naming Styles - - [DllImport(InteropConfig.DLL_NAME, EntryPoint = "table_destroy", CallingConvention = CallingConvention.Cdecl)] - public static extern void destroy(IntPtr tableHandle, out NativeException ex); - - [DllImport(InteropConfig.DLL_NAME, EntryPoint = "table_create_results", CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr create_results(TableHandle handle, SharedRealmHandle sharedRealm, out NativeException ex); - - [DllImport(InteropConfig.DLL_NAME, EntryPoint = "table_get_object", CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr get_object(TableHandle table, SharedRealmHandle realm, ObjectKey objectKey, out NativeException ex); - - [DllImport(InteropConfig.DLL_NAME, EntryPoint = "table_get_object_for_primarykey", CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr get_object_for_primarykey(TableHandle handle, SharedRealmHandle realmHandle, PrimitiveValue value, out NativeException ex); - -#pragma warning restore IDE1006 // Naming Styles - } - - [Preserve] - public TableHandle(RealmHandle root, IntPtr handle) : base(root, handle) - { - } - - protected override void Unbind() - { - NativeMethods.destroy(handle, out var nativeException); - nativeException.ThrowIfNecessary(); - } - - public ResultsHandle CreateResults(SharedRealmHandle sharedRealmHandle) - { - var result = NativeMethods.create_results(this, sharedRealmHandle, out var nativeException); - nativeException.ThrowIfNecessary(); - return new ResultsHandle(sharedRealmHandle, result); - } - - public ObjectHandle Get(SharedRealmHandle realmHandle, ObjectKey objectKey) - { - var result = NativeMethods.get_object(this, realmHandle, objectKey, out var nativeException); - nativeException.ThrowIfNecessary(); - - if (result == IntPtr.Zero) - { - return null; - } - - return new ObjectHandle(realmHandle, result); - } - - public unsafe bool TryFind(SharedRealmHandle realmHandle, in RealmValue id, out ObjectHandle objectHandle) - { - var (primitiveValue, handles) = id.ToNative(); - var result = NativeMethods.get_object_for_primarykey(this, realmHandle, primitiveValue, out var ex); - handles?.Dispose(); - ex.ThrowIfNecessary(); - - if (result == IntPtr.Zero) - { - objectHandle = null; - return false; - } - - objectHandle = new ObjectHandle(realmHandle, result); - return true; - } - } -} \ No newline at end of file diff --git a/Realm/Realm/Linq/RealmResults.cs b/Realm/Realm/Linq/RealmResults.cs index 6b2b34fafc..282883c986 100644 --- a/Realm/Realm/Linq/RealmResults.cs +++ b/Realm/Realm/Linq/RealmResults.cs @@ -51,7 +51,7 @@ internal RealmResults(Realm realm, ResultsHandle handle, RealmObjectBase.Metadat } internal RealmResults(Realm realm, RealmObjectBase.Metadata metadata) - : this(realm, metadata.Table.CreateResults(realm.SharedRealmHandle), metadata) + : this(realm, realm.SharedRealmHandle.CreateResults(metadata.TableKey), metadata) { } diff --git a/Realm/Realm/Linq/RealmResultsVisitor.cs b/Realm/Realm/Linq/RealmResultsVisitor.cs index af413fb032..b105914b7c 100644 --- a/Realm/Realm/Linq/RealmResultsVisitor.cs +++ b/Realm/Realm/Linq/RealmResultsVisitor.cs @@ -121,7 +121,7 @@ private void AddSort(LambdaExpression lambda, bool ascending) } var propertyChain = TraverseSort(body); - _sortDescriptor.AddClause(_metadata.Table, _realm.SharedRealmHandle, propertyChain, ascending); + _sortDescriptor.AddClause(_realm.SharedRealmHandle, _metadata.TableKey, propertyChain, ascending); } private IntPtr[] TraverseSort(MemberExpression expression) diff --git a/Realm/Realm/Native/ObjectKey.cs b/Realm/Realm/Native/TableKey.cs similarity index 58% rename from Realm/Realm/Native/ObjectKey.cs rename to Realm/Realm/Native/TableKey.cs index 0c394a3dfe..24608ced09 100644 --- a/Realm/Realm/Native/ObjectKey.cs +++ b/Realm/Realm/Native/TableKey.cs @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////// // -// Copyright 2020 Realm Inc. +// Copyright 2021 Realm Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -22,27 +22,18 @@ namespace Realms.Native { [StructLayout(LayoutKind.Sequential)] - internal struct ObjectKey : IEquatable + internal struct TableKey : IEquatable { - private Int64 value; + private UInt32 value; - public bool Equals(ObjectKey other) => value.Equals(other.value); + public bool Equals(TableKey other) => value.Equals(other.value); - public override bool Equals(object obj) - { - switch (obj) - { - case ObjectKey other: - return value.Equals(other.value); - default: - return false; - } - } + public override bool Equals(object obj) => obj is TableKey other && Equals(other); public override int GetHashCode() => value.GetHashCode(); - public static bool operator ==(ObjectKey left, ObjectKey right) => left.value == right.value; + public static bool operator ==(TableKey left, TableKey right) => left.value == right.value; - public static bool operator !=(ObjectKey left, ObjectKey right) => left.value != right.value; + public static bool operator !=(TableKey left, TableKey right) => left.value != right.value; } } diff --git a/Realm/Realm/Realm.cs b/Realm/Realm/Realm.cs index e596b6a16e..b943cc2c7e 100644 --- a/Realm/Realm/Realm.cs +++ b/Realm/Realm/Realm.cs @@ -202,7 +202,7 @@ private static bool IsRealmOpen(string path) private State _state; internal readonly SharedRealmHandle SharedRealmHandle; - internal readonly Dictionary Metadata; + internal readonly RealmMetadata Metadata; /// /// Gets an object encompassing the dynamic API for this Realm instance. @@ -271,7 +271,7 @@ internal Realm(SharedRealmHandle sharedRealmHandle, RealmConfigurationBase confi _state.AddRealm(this); SharedRealmHandle = sharedRealmHandle; - Metadata = schema.ToDictionary(t => t.Name, CreateRealmObjectMetadata); + Metadata = new RealmMetadata(schema.Select(CreateRealmObjectMetadata)); Schema = schema; IsFrozen = SharedRealmHandle.IsFrozen; DynamicApi = new Dynamic(this); @@ -279,7 +279,7 @@ internal Realm(SharedRealmHandle sharedRealmHandle, RealmConfigurationBase confi private RealmObjectBase.Metadata CreateRealmObjectMetadata(ObjectSchema schema) { - var tableHandle = SharedRealmHandle.GetTable(schema.Name); + var tableKey = SharedRealmHandle.GetTableKey(schema.Name); Weaving.IRealmObjectHelper helper; if (schema.Type != null && !Config.IsDynamic) @@ -309,7 +309,7 @@ private RealmObjectBase.Metadata CreateRealmObjectMetadata(ObjectSchema schema) initPropertyMap[prop.Name] = (IntPtr)index; } - return new RealmObjectBase.Metadata(tableHandle, helper, initPropertyMap, schema); + return new RealmObjectBase.Metadata(tableKey, helper, initPropertyMap, schema); } /// @@ -480,17 +480,6 @@ internal RealmObjectBase MakeObject(RealmObjectBase.Metadata metadata, ObjectHan return ret; } - internal RealmObjectBase MakeObject(RealmObjectBase.Metadata metadata, ObjectKey objectKey) - { - var objectHandle = metadata.Table.Get(SharedRealmHandle, objectKey); - if (objectHandle != null) - { - return MakeObject(metadata, objectHandle); - } - - return null; - } - /// /// This will start managing a which has been created as a standalone object. /// @@ -610,12 +599,12 @@ private void AddInternal(RealmObject obj, Type objectType, bool update) if (metadata.Helper.TryGetPrimaryKeyValue(obj, out var primaryKey)) { var pkProperty = metadata.Schema.PrimaryKeyProperty.Value; - objectHandle = SharedRealmHandle.CreateObjectWithPrimaryKey(pkProperty, primaryKey, metadata.Table, objectName, update, out isNew); + objectHandle = SharedRealmHandle.CreateObjectWithPrimaryKey(pkProperty, primaryKey, metadata.TableKey, objectName, update, out isNew); } else { isNew = true; // Objects without PK are always new - objectHandle = SharedRealmHandle.CreateObject(metadata.Table); + objectHandle = SharedRealmHandle.CreateObject(metadata.TableKey); } obj.SetOwner(this, objectHandle, metadata); @@ -1134,7 +1123,7 @@ private T FindCore(RealmValue primaryKey) ThrowIfDisposed(); var metadata = Metadata[typeof(T).GetTypeInfo().GetMappedOrOriginalName()]; - if (metadata.Table.TryFind(SharedRealmHandle, primaryKey, out var objectHandle)) + if (SharedRealmHandle.TryFindObject(metadata.TableKey, primaryKey, out var objectHandle)) { return (T)MakeObject(metadata, objectHandle); } @@ -1340,7 +1329,7 @@ public void RemoveAll() foreach (var metadata in Metadata.Values) { - using var resultsHandle = metadata.Table.CreateResults(SharedRealmHandle); + using var resultsHandle = SharedRealmHandle.CreateResults(metadata.TableKey); resultsHandle.Clear(SharedRealmHandle); } } @@ -1389,6 +1378,36 @@ internal void ExecuteOutsideTransaction(Action action) #endregion Transactions + internal class RealmMetadata + { + private readonly Dictionary stringToRealmObjectMetadataDict; + private readonly Dictionary tableKeyToRealmObjectMetadataDict; + + public IEnumerable Values => stringToRealmObjectMetadataDict.Values; + + public RealmMetadata(IEnumerable objectsMetadata) + { + stringToRealmObjectMetadataDict = new Dictionary(); + tableKeyToRealmObjectMetadataDict = new Dictionary(); + + foreach (var objectMetadata in objectsMetadata) + { + stringToRealmObjectMetadataDict[objectMetadata.Schema.Name] = objectMetadata; + tableKeyToRealmObjectMetadataDict[objectMetadata.TableKey] = objectMetadata; + } + } + + public bool TryGetValue(string objectType, out RealmObjectBase.Metadata metadata) => + stringToRealmObjectMetadataDict.TryGetValue(objectType, out metadata); + + public bool TryGetValue(TableKey tablekey, out RealmObjectBase.Metadata metadata) => + tableKeyToRealmObjectMetadataDict.TryGetValue(tablekey, out metadata); + + public RealmObjectBase.Metadata this[string objectType] => stringToRealmObjectMetadataDict[objectType]; + + public RealmObjectBase.Metadata this[TableKey tablekey] => tableKeyToRealmObjectMetadataDict[tablekey]; + } + internal class State : IDisposable { private readonly List> _weakRealms = new List>(); @@ -1531,11 +1550,11 @@ public dynamic CreateObject(string className, object primaryKey) var pkProperty = metadata.Schema.PrimaryKeyProperty; if (pkProperty.HasValue) { - objectHandle = _realm.SharedRealmHandle.CreateObjectWithPrimaryKey(pkProperty.Value, primaryKey, metadata.Table, className, update: false, isNew: out var _); + objectHandle = _realm.SharedRealmHandle.CreateObjectWithPrimaryKey(pkProperty.Value, primaryKey, metadata.TableKey, className, update: false, isNew: out var _); } else { - objectHandle = _realm.SharedRealmHandle.CreateObject(metadata.Table); + objectHandle = _realm.SharedRealmHandle.CreateObject(metadata.TableKey); } result.SetOwner(_realm, objectHandle, metadata); @@ -1773,7 +1792,7 @@ private dynamic FindCore(string className, RealmValue primaryKey) _realm.ThrowIfDisposed(); var metadata = _realm.Metadata[className]; - if (metadata.Table.TryFind(_realm.SharedRealmHandle, primaryKey, out var objectHandle)) + if (_realm.SharedRealmHandle.TryFindObject(metadata.TableKey, primaryKey, out var objectHandle)) { return _realm.MakeObject(metadata, objectHandle); } diff --git a/wrappers/src/CMakeLists.txt b/wrappers/src/CMakeLists.txt index 8de2a498a5..423e18100f 100644 --- a/wrappers/src/CMakeLists.txt +++ b/wrappers/src/CMakeLists.txt @@ -13,7 +13,6 @@ set(SOURCES scheduler_cs.cpp schema_cs.cpp shared_realm_cs.cpp - table_cs.cpp app_cs.cpp async_open_task_cs.cpp mongo_collection_cs.cpp diff --git a/wrappers/src/object_cs.cpp b/wrappers/src/object_cs.cpp index 84ec7e788c..ea23c8e764 100644 --- a/wrappers/src/object_cs.cpp +++ b/wrappers/src/object_cs.cpp @@ -16,12 +16,12 @@ // //////////////////////////////////////////////////////////////////////////// -#include "object_cs.hpp" -#include "timestamp_helpers.hpp" -#include "notifications_cs.hpp" #include "error_handling.hpp" #include "marshalling.hpp" +#include "notifications_cs.hpp" +#include "object_cs.hpp" #include "realm_export_decls.hpp" +#include "timestamp_helpers.hpp" #include #include @@ -30,16 +30,6 @@ using namespace realm; using namespace realm::binding; -template -inline void object_set(Object& object, size_t property_ndx, const T& value, NativeException::Marshallable& ex) -{ - return handle_errors(ex, [&]() { - verify_can_set(object); - - object.obj().set(get_column_key(object, property_ndx), value); - }); -} - extern "C" { REALM_EXPORT bool object_get_is_valid(const Object& object, NativeException::Marshallable& ex) { @@ -163,12 +153,14 @@ extern "C" { }); } - REALM_EXPORT Results* object_get_backlinks_for_type(Object& object, TableRef& source_table, size_t source_property_ndx, NativeException::Marshallable& ex) + REALM_EXPORT Results* object_get_backlinks_for_type(Object& object, TableKey table_key, size_t source_property_ndx, NativeException::Marshallable& ex) { return handle_errors(ex, [&] { verify_can_get(object); - const ObjectSchema& source_object_schema = *object.realm()->schema().find(ObjectStore::object_type_for_table_name(source_table->get_name())); + const TableRef source_table = get_table(object.realm(), table_key); + + const ObjectSchema& source_object_schema = *object.realm()->schema().find(table_key); const Property& source_property = source_object_schema.persisted_properties[source_property_ndx]; if (source_property.object_type != object.get_object_schema().name) { diff --git a/wrappers/src/object_cs.hpp b/wrappers/src/object_cs.hpp index f018a20dfb..dd79a834f9 100644 --- a/wrappers/src/object_cs.hpp +++ b/wrappers/src/object_cs.hpp @@ -16,10 +16,11 @@ // //////////////////////////////////////////////////////////////////////////// -#include #include "shared_realm_cs.hpp" #include "error_handling.hpp" +#include + using namespace realm; using namespace realm::binding; diff --git a/wrappers/src/shared_realm_cs.cpp b/wrappers/src/shared_realm_cs.cpp index 444872536b..ec73fff2bd 100644 --- a/wrappers/src/shared_realm_cs.cpp +++ b/wrappers/src/shared_realm_cs.cpp @@ -17,14 +17,14 @@ //////////////////////////////////////////////////////////////////////////// -#include "shared_realm_cs.hpp" #include "error_handling.hpp" -#include "realm_export_decls.hpp" #include "marshalling.hpp" +#include "realm_export_decls.hpp" +#include "shared_realm_cs.hpp" +#include #include #include -#include #include #include #include @@ -104,6 +104,8 @@ Realm::Config get_shared_realm_config(Configuration configuration, SyncConfigura extern "C" { +typedef uint32_t realm_table_key; + REALM_EXPORT void shared_realm_install_callbacks(decltype(s_realm_changed) realm_changed, decltype(s_get_native_schema) get_schema, decltype(s_open_realm_callback) open_callback, decltype(s_on_binding_context_destructed) on_binding_context_destructed) { s_realm_changed = realm_changed; @@ -247,11 +249,11 @@ REALM_EXPORT void shared_realm_close_realm(SharedRealm& realm, NativeException:: }); } -REALM_EXPORT TableRef* shared_realm_get_table(SharedRealm& realm, uint16_t* object_type_buf, size_t object_type_len, NativeException::Marshallable& ex) +REALM_EXPORT realm_table_key shared_realm_get_table_key(SharedRealm& realm, uint16_t* object_type_buf, size_t object_type_len, NativeException::Marshallable& ex) { return handle_errors(ex, [&]() { Utf16StringAccessor object_type(object_type_buf, object_type_len); - return new TableRef(ObjectStore::table_for_object_type(realm->read_group(), object_type)); + return ObjectStore::table_for_object_type(realm->read_group(), object_type)->get_key().value; }); } @@ -362,23 +364,22 @@ REALM_EXPORT void shared_realm_write_copy(SharedRealm* realm, uint16_t* path, si }); } -REALM_EXPORT Object* shared_realm_create_object(SharedRealm& realm, TableRef& table, NativeException::Marshallable& ex) +REALM_EXPORT Object* shared_realm_create_object(SharedRealm& realm, TableKey table_key, NativeException::Marshallable& ex) { return handle_errors(ex, [&]() { realm->verify_in_write(); - return new Object(realm, table->create_object()); + return new Object(realm, get_table(realm, table_key)->create_object()); }); } -REALM_EXPORT Object* shared_realm_create_object_unique(const SharedRealm& realm, TableRef& table, realm_value_t primitive, bool try_update, bool& is_new, NativeException::Marshallable& ex) +REALM_EXPORT Object* shared_realm_create_object_unique(const SharedRealm& realm, TableKey table_key, realm_value_t primitive, bool try_update, bool& is_new, NativeException::Marshallable& ex) { return handle_errors(ex, [&]() { realm->verify_in_write(); - realm->read_group(); - const StringData object_name(ObjectStore::object_type_for_table_name(table->get_name())); - const ObjectSchema& object_schema = *realm->schema().find(object_name); + const TableRef table = get_table(realm, table_key); + const ObjectSchema& object_schema = *realm->schema().find(table_key); const Property& primary_key_property = *object_schema.primary_key_property(); if (!primary_key_property.type_is_nullable() && primitive.is_null()) { @@ -452,4 +453,45 @@ REALM_EXPORT SharedRealm* shared_realm_freeze(const SharedRealm& realm, NativeEx }); } +REALM_EXPORT Object* shared_realm_get_object_for_primary_key(SharedRealm& realm, TableKey table_key, realm_value_t primitive, NativeException::Marshallable& ex) +{ + return handle_errors(ex, [&]() -> Object* { + realm->verify_thread(); + + const TableRef table = get_table(realm, table_key); + const ObjectSchema& object_schema = *realm->schema().find(table_key); + if (object_schema.primary_key.empty()) { + const std::string name(ObjectStore::object_type_for_table_name(table->get_name())); + throw MissingPrimaryKeyException(name); + } + + const Property& primary_key_property = *object_schema.primary_key_property(); + if (!primary_key_property.type_is_nullable() && primitive.is_null()) { + return nullptr; + } + + if (!primitive.is_null() && to_capi(primary_key_property.type) != primitive.type) { + throw PropertyTypeMismatchException(object_schema.name, primary_key_property.name, to_string(primary_key_property.type), to_string(primitive.type)); + } + + const ColKey column_key = object_schema.primary_key_property()->column_key; + const ObjKey obj_key = table->find_first(column_key, from_capi(primitive)); + if (!obj_key) { + return nullptr; + } + + return new Object(realm, object_schema, table->get_object(obj_key)); + }); +} + +REALM_EXPORT Results* shared_realm_create_results(SharedRealm& realm, TableKey table_key, NativeException::Marshallable& ex) +{ + return handle_errors(ex, [&]() { + realm->verify_thread(); + + const TableRef table = get_table(realm, table_key); + return new Results(realm, table); + }); +} + } diff --git a/wrappers/src/shared_realm_cs.hpp b/wrappers/src/shared_realm_cs.hpp index d74f81fa50..e51221665f 100644 --- a/wrappers/src/shared_realm_cs.hpp +++ b/wrappers/src/shared_realm_cs.hpp @@ -19,16 +19,16 @@ #ifndef SHARED_REALM_CS_HPP #define SHARED_REALM_CS_HPP -#include +#include "marshalling.hpp" #include "schema_cs.hpp" +#include "sync_session_cs.hpp" + +#include #include #include -#include "marshalling.hpp" - -#include "sync_session_cs.hpp" -#include #include #include +#include using SharedSyncUser = std::shared_ptr; @@ -75,6 +75,11 @@ struct SyncConfiguration SyncSessionStopPolicy session_stop_policy; }; +inline const TableRef get_table(const SharedRealm& realm, TableKey table_key) +{ + return realm->read_group().get_table(table_key); +} + namespace realm { namespace binding { diff --git a/wrappers/src/sort_descriptor_cs.cpp b/wrappers/src/sort_descriptor_cs.cpp index 36822d62b7..0ca9e31247 100644 --- a/wrappers/src/sort_descriptor_cs.cpp +++ b/wrappers/src/sort_descriptor_cs.cpp @@ -16,14 +16,15 @@ // //////////////////////////////////////////////////////////////////////////// -#include -#include "marshalling.hpp" #include "error_handling.hpp" +#include "marshalling.hpp" #include "realm_export_decls.hpp" +#include "shared_realm_cs.hpp" + +#include #include #include - using namespace realm; using namespace realm::binding; @@ -34,14 +35,13 @@ REALM_EXPORT void sort_descriptor_destroy(DescriptorOrdering* descriptor) delete descriptor; } -REALM_EXPORT void sort_descriptor_add_clause(DescriptorOrdering& descriptor, TableRef& table, SharedRealm& realm, size_t* property_chain, size_t properties_count, bool ascending, NativeException::Marshallable& ex) +REALM_EXPORT void sort_descriptor_add_clause(DescriptorOrdering& descriptor, TableKey table_key, SharedRealm& realm, size_t* property_chain, size_t properties_count, bool ascending, NativeException::Marshallable& ex) { handle_errors(ex, [&]() { std::vector column_keys; column_keys.reserve(properties_count); - const std::string object_name(ObjectStore::object_type_for_table_name(table->get_name())); - const std::vector* properties = &realm->schema().find(object_name)->persisted_properties; + const std::vector* properties = &realm->schema().find(table_key)->persisted_properties; for (size_t i = 0; i < properties_count; ++i) { const Property& property = properties->at(property_chain[i]); diff --git a/wrappers/src/table_cs.cpp b/wrappers/src/table_cs.cpp deleted file mode 100644 index ae432d728f..0000000000 --- a/wrappers/src/table_cs.cpp +++ /dev/null @@ -1,107 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2016 Realm Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -//////////////////////////////////////////////////////////////////////////// - -#include -#include "error_handling.hpp" -#include "marshalling.hpp" -#include "realm_export_decls.hpp" - -#include -#include "timestamp_helpers.hpp" -#include -#include -#include - -using namespace realm; -using namespace realm::binding; - -extern "C" { - -REALM_EXPORT void table_destroy(TableRef* table, NativeException::Marshallable& ex) -{ - return handle_errors(ex, [&]() { - delete table; - }); -} - -REALM_EXPORT Object* table_add_empty_object(TableRef& table, SharedRealm& realm, NativeException::Marshallable& ex) -{ - return handle_errors(ex, [&]() { - realm->verify_in_write(); - - Obj obj = table->create_object(); - const std::string object_name(ObjectStore::object_type_for_table_name(table->get_name())); - auto& object_schema = *realm->schema().find(object_name); - return new Object(realm, object_schema, obj); - }); -} - -REALM_EXPORT Results* table_create_results(TableRef& table, SharedRealm& realm, NativeException::Marshallable& ex) -{ - return handle_errors(ex, [&]() { - realm->verify_thread(); - - return new Results(realm, table); - }); -} - -REALM_EXPORT Object* table_get_object(TableRef& table, SharedRealm& realm, ObjKey object_key, NativeException::Marshallable& ex) -{ - return handle_errors(ex, [&]() -> Object* { - realm->verify_thread(); - - Obj obj = table->get_object(object_key); - if (!obj) { - return nullptr; - } - - return new Object(realm, obj); - }); -} - -REALM_EXPORT Object* table_get_object_for_primarykey(TableRef& table, SharedRealm& realm, realm_value_t primitive, NativeException::Marshallable& ex) -{ - return handle_errors(ex, [&]() -> Object* { - realm->verify_thread(); - - const std::string object_name(ObjectStore::object_type_for_table_name(table->get_name())); - auto& object_schema = *realm->schema().find(object_name); - if (object_schema.primary_key.empty()) { - const std::string name(table->get_name()); - throw MissingPrimaryKeyException(name); - } - - const Property& primary_key_property = *object_schema.primary_key_property(); - if (!primary_key_property.type_is_nullable() && primitive.is_null()) { - return nullptr; - } - - if (!primitive.is_null() && to_capi(primary_key_property.type) != primitive.type) { - throw PropertyTypeMismatchException(object_schema.name, primary_key_property.name, to_string(primary_key_property.type), to_string(primitive.type)); - } - - const ColKey column_key = object_schema.primary_key_property()->column_key; - const ObjKey obj_key = table->find_first(column_key, from_capi(primitive)); - if (!obj_key) - return nullptr; - - return new Object(realm, object_schema, table->get_object(obj_key)); - }); -} - -} // extern "C"