diff --git a/Realm/Realm/Dynamic/MetaRealmObject.cs b/Realm/Realm/Dynamic/MetaRealmObject.cs index 6aa525553a..981e219c13 100644 --- a/Realm/Realm/Dynamic/MetaRealmObject.cs +++ b/Realm/Realm/Dynamic/MetaRealmObject.cs @@ -66,13 +66,13 @@ public override DynamicMetaObject BindGetMember(GetMemberBinder binder) MethodInfo getter = null; if (property.Type.UnderlyingType() == PropertyType.LinkingObjects) { - arguments.Add(Expression.Constant(_metadata.ComputedProperties[property.Name])); + arguments.Add(Expression.Constant(_metadata.PropertyIndices[property.Name])); getter = GetGetMethod(DummyHandle.GetBacklinks); } else if (property.Type.IsArray()) { arguments.Add(Expression.Field(GetLimitedSelf(), RealmObjectRealmField)); - arguments.Add(Expression.Constant(_metadata.ColumnKeys[property.Name])); + arguments.Add(Expression.Constant(_metadata.PropertyIndices[property.Name])); arguments.Add(Expression.Constant(property.ObjectType, typeof(string))); switch (property.Type.UnderlyingType()) { @@ -144,7 +144,7 @@ public override DynamicMetaObject BindGetMember(GetMemberBinder binder) } else { - arguments.Add(Expression.Constant(_metadata.ColumnKeys[property.Name])); + arguments.Add(Expression.Constant(_metadata.PropertyIndices[property.Name])); switch (property.Type.UnderlyingType()) { case PropertyType.Int: @@ -186,7 +186,6 @@ public override DynamicMetaObject BindGetMember(GetMemberBinder binder) else { expression = Expression.Call(self, RealmObjectGetBacklinksForHandle_RealmObject, Expression.Constant(binder.Name), expression); - } } @@ -214,7 +213,7 @@ public override DynamicMetaObject BindSetMember(SetMemberBinder binder, DynamicM var arguments = new List { - Expression.Constant(_metadata.ColumnKeys[property.Name]) + Expression.Constant(_metadata.PropertyIndices[property.Name]) }; MethodInfo setter = null; @@ -306,24 +305,22 @@ private bool IsTargetEmbedded(Property property) return metadata.Schema.IsEmbedded; } - // GetString(colKey) - // GetByteArray(colKey) - private static MethodInfo GetGetMethod(Func @delegate) => @delegate.GetMethodInfo(); - - // GetPrimitive(colKey, propertyType) - private static MethodInfo GetGetMethod(Func @delegate) => @delegate.GetMethodInfo(); - + // GetString(propertyIndex) + // GetByteArray(propertyIndex) // GetBacklinks(propertyIndex) private static MethodInfo GetGetMethod(Func @delegate) => @delegate.GetMethodInfo(); - // GetList(realm, colKey, objectType) - // GetObject(realm, colKey, objectType) - private static MethodInfo GetGetMethod(Func @delegate) => @delegate.GetMethodInfo(); + // GetPrimitive(propertyIndex, propertyType) + private static MethodInfo GetGetMethod(Func @delegate) => @delegate.GetMethodInfo(); + + // GetList(realm, propertyIndex, objectType) + // GetObject(realm, propertyIndex, objectType) + private static MethodInfo GetGetMethod(Func @delegate) => @delegate.GetMethodInfo(); - // SetXXX(colKey) - private static MethodInfo GetSetMethod(Action @delegate) => @delegate.GetMethodInfo(); + // SetXXX(propertyIndex) + private static MethodInfo GetSetMethod(Action @delegate) => @delegate.GetMethodInfo(); - // SetObject(this, colKey) - private static MethodInfo GetSetMethod(Action @delegate) => @delegate.GetMethodInfo(); + // SetObject(this, propertyIndex) + private static MethodInfo GetSetMethod(Action @delegate) => @delegate.GetMethodInfo(); } } \ No newline at end of file diff --git a/Realm/Realm/Handles/ObjectHandle.cs b/Realm/Realm/Handles/ObjectHandle.cs index 66bdf72d0d..4c22c12185 100644 --- a/Realm/Realm/Handles/ObjectHandle.cs +++ b/Realm/Realm/Handles/ObjectHandle.cs @@ -43,48 +43,48 @@ private static class NativeMethods public static extern void destroy(IntPtr objectHandle); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "object_get_primitive", CallingConvention = CallingConvention.Cdecl)] - public static extern void get_primitive(ObjectHandle handle, ColumnKey columnKey, ref PrimitiveValue value, out NativeException ex); + public static extern void get_primitive(ObjectHandle handle, IntPtr propertyIndex, ref PrimitiveValue value, out NativeException ex); // value is IntPtr rather than PrimitiveValue due to a bug in .NET Core on Linux and Mac // that causes incorrect marshalling of the struct. [DllImport(InteropConfig.DLL_NAME, EntryPoint = "object_set_primitive", CallingConvention = CallingConvention.Cdecl)] - public static extern void set_primitive(ObjectHandle handle, ColumnKey columnKey, IntPtr value, out NativeException ex); + public static extern void set_primitive(ObjectHandle handle, IntPtr propertyIndex, IntPtr value, out NativeException ex); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "object_set_string", CallingConvention = CallingConvention.Cdecl)] - public static extern void set_string(ObjectHandle handle, ColumnKey columnKey, + public static extern void set_string(ObjectHandle handle, IntPtr propertyIndex, [MarshalAs(UnmanagedType.LPWStr)] string value, IntPtr valueLen, out NativeException ex); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "object_get_string", CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr get_string(ObjectHandle handle, ColumnKey columnKey, + public static extern IntPtr get_string(ObjectHandle handle, IntPtr propertyIndex, IntPtr buffer, IntPtr bufsize, [MarshalAs(UnmanagedType.U1)] out bool isNull, out NativeException ex); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "object_set_link", CallingConvention = CallingConvention.Cdecl)] - public static extern void set_link(ObjectHandle handle, ColumnKey columnKey, ObjectHandle targetHandle, out NativeException ex); + public static extern void set_link(ObjectHandle handle, IntPtr propertyIndex, ObjectHandle targetHandle, out NativeException ex); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "object_get_link", CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr get_link(ObjectHandle handle, ColumnKey columnKey, out NativeException ex); + public static extern IntPtr get_link(ObjectHandle handle, IntPtr propertyIndex, out NativeException ex); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "object_create_embedded", CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr create_embedded_link(ObjectHandle handle, ColumnKey columnKey, out NativeException ex); + public static extern IntPtr create_embedded_link(ObjectHandle handle, IntPtr propertyIndex, out NativeException ex); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "object_clear_link", CallingConvention = CallingConvention.Cdecl)] - public static extern void clear_link(ObjectHandle handle, ColumnKey columnKey, out NativeException ex); + public static extern void clear_link(ObjectHandle handle, IntPtr propertyIndex, out NativeException ex); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "object_get_list", CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr get_list(ObjectHandle handle, ColumnKey columnKey, out NativeException ex); + public static extern IntPtr get_list(ObjectHandle handle, IntPtr propertyIndex, out NativeException ex); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "object_set_null", CallingConvention = CallingConvention.Cdecl)] - public static extern void set_null(ObjectHandle handle, ColumnKey columnKey, out NativeException ex); + public static extern void set_null(ObjectHandle handle, IntPtr propertyIndex, out NativeException ex); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "object_add_int64", CallingConvention = CallingConvention.Cdecl)] - public static extern void add_int64(ObjectHandle handle, ColumnKey columnKey, Int64 value, out NativeException ex); + public static extern void add_int64(ObjectHandle handle, IntPtr propertyIndex, Int64 value, out NativeException ex); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "object_set_binary", CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr set_binary(ObjectHandle handle, ColumnKey columnKey, + public static extern IntPtr set_binary(ObjectHandle handle, IntPtr propertyIndex, IntPtr buffer, IntPtr bufferLength, out NativeException ex); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "object_get_binary", CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr get_binary(ObjectHandle handle, ColumnKey columnKey, + public static extern IntPtr get_binary(ObjectHandle handle, IntPtr propertyIndex, IntPtr buffer, IntPtr bufferLength, [MarshalAs(UnmanagedType.U1)] out bool is_null, out NativeException ex); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "object_remove", CallingConvention = CallingConvention.Cdecl)] @@ -98,7 +98,7 @@ public static extern IntPtr get_binary(ObjectHandle handle, ColumnKey columnKey, 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, ColumnKey source_column_key, out NativeException nativeException); + public static extern IntPtr get_backlinks_for_type(ObjectHandle objectHandle, TableHandle source_table, 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); @@ -175,71 +175,71 @@ protected override void Unbind() NativeMethods.destroy(handle); } - public PrimitiveValue GetPrimitive(ColumnKey columnKey, PropertyType type) + public PrimitiveValue GetPrimitive(IntPtr propertyIndex, PropertyType type) { var result = new PrimitiveValue { Type = type }; - NativeMethods.get_primitive(this, columnKey, ref result, out var nativeException); + NativeMethods.get_primitive(this, propertyIndex, ref result, out var nativeException); nativeException.ThrowIfNecessary(); return result; } - public unsafe void SetPrimitive(ColumnKey columnKey, PrimitiveValue value) + public unsafe void SetPrimitive(IntPtr propertyIndex, PrimitiveValue value) { PrimitiveValue* valuePtr = &value; - NativeMethods.set_primitive(this, columnKey, new IntPtr(valuePtr), out var nativeException); + NativeMethods.set_primitive(this, propertyIndex, new IntPtr(valuePtr), out var nativeException); nativeException.ThrowIfNecessary(); } - public void SetString(ColumnKey columnKey, string value) + public void SetString(IntPtr propertyIndex, string value) { NativeException nativeException; if (value != null) { - NativeMethods.set_string(this, columnKey, value, (IntPtr)value.Length, out nativeException); + NativeMethods.set_string(this, propertyIndex, value, (IntPtr)value.Length, out nativeException); } else { - NativeMethods.set_null(this, columnKey, out nativeException); + NativeMethods.set_null(this, propertyIndex, out nativeException); } nativeException.ThrowIfNecessary(); } - public void SetStringUnique(ColumnKey columnKey, string value) + public void SetStringUnique(IntPtr propertyIndex, string value) { if (value == null) { throw new ArgumentNullException(nameof(value), "Object identifiers cannot be null"); } - if (GetString(columnKey) != value) + if (GetString(propertyIndex) != value) { throw new InvalidOperationException("Once set, primary key properties may not be modified."); } } - public string GetString(ColumnKey columnKey) + public string GetString(IntPtr propertyIndex) { - return MarshalHelpers.GetString((IntPtr buffer, IntPtr length, out bool isNull, out NativeException ex) => NativeMethods.get_string(this, columnKey, buffer, length, out isNull, out ex)); + return MarshalHelpers.GetString((IntPtr buffer, IntPtr length, out bool isNull, out NativeException ex) => NativeMethods.get_string(this, propertyIndex, buffer, length, out isNull, out ex)); } - public void SetLink(ColumnKey columnKey, ObjectHandle targetHandle) + public void SetLink(IntPtr propertyIndex, ObjectHandle targetHandle) { - NativeMethods.set_link(this, columnKey, targetHandle, out var nativeException); + NativeMethods.set_link(this, propertyIndex, targetHandle, out var nativeException); nativeException.ThrowIfNecessary(); } - public void ClearLink(ColumnKey columnKey) + public void ClearLink(IntPtr propertyIndex) { - NativeMethods.clear_link(this, columnKey, out var nativeException); + NativeMethods.clear_link(this, propertyIndex, out var nativeException); nativeException.ThrowIfNecessary(); } - public bool TryGetLink(ColumnKey columnKey, out ObjectHandle objectHandle) + public bool TryGetLink(IntPtr propertyIndex, out ObjectHandle objectHandle) { - var result = NativeMethods.get_link(this, columnKey, out var nativeException); + var result = NativeMethods.get_link(this, propertyIndex, out var nativeException); nativeException.ThrowIfNecessary(); if (result == IntPtr.Zero) @@ -252,46 +252,46 @@ public bool TryGetLink(ColumnKey columnKey, out ObjectHandle objectHandle) return true; } - public IntPtr GetLinklist(ColumnKey columnKey) + public IntPtr GetLinklist(IntPtr propertyIndex) { - var result = NativeMethods.get_list(this, columnKey, out var nativeException); + var result = NativeMethods.get_list(this, propertyIndex, out var nativeException); nativeException.ThrowIfNecessary(); return result; } - public void AddInt64(ColumnKey columnKey, long value) + public void AddInt64(IntPtr propertyIndex, long value) { - NativeMethods.add_int64(this, columnKey, value, out var nativeException); + NativeMethods.add_int64(this, propertyIndex, value, out var nativeException); nativeException.ThrowIfNecessary(); } - public void SetPrimitiveUnique(ColumnKey columnKey, PrimitiveValue value) + public void SetPrimitiveUnique(IntPtr propertyIndex, PrimitiveValue value) { - if (!GetPrimitive(columnKey, value.Type).Equals(value)) + if (!GetPrimitive(propertyIndex, value.Type).Equals(value)) { throw new InvalidOperationException("Once set, primary key properties may not be modified."); } } - public unsafe void SetByteArray(ColumnKey columnKey, byte[] value) + public unsafe void SetByteArray(IntPtr propertyIndex, byte[] value) { MarshalHelpers.SetByteArray(value, (IntPtr buffer, IntPtr bufferSize, bool hasValue, out NativeException ex) => { if (hasValue) { - NativeMethods.set_binary(this, columnKey, buffer, bufferSize, out ex); + NativeMethods.set_binary(this, propertyIndex, buffer, bufferSize, out ex); } else { - NativeMethods.set_null(this, columnKey, out ex); + NativeMethods.set_null(this, propertyIndex, out ex); } }); } - public byte[] GetByteArray(ColumnKey columnKey) + public byte[] GetByteArray(IntPtr propertyIndex) { return MarshalHelpers.GetByteArray((IntPtr buffer, IntPtr bufferLength, out bool isNull, out NativeException ex) => - NativeMethods.get_binary(this, columnKey, buffer, bufferLength, out isNull, out ex)); + NativeMethods.get_binary(this, propertyIndex, buffer, bufferLength, out isNull, out ex)); } public void RemoveFromRealm(SharedRealmHandle realmHandle) @@ -300,18 +300,18 @@ public void RemoveFromRealm(SharedRealmHandle realmHandle) nativeException.ThrowIfNecessary(); } - public RealmList GetList(Realm realm, ColumnKey columnKey, string objectType) + public RealmList GetList(Realm realm, IntPtr propertyIndex, string objectType) { - var listHandle = new ListHandle(Root, GetLinklist(columnKey)); + var listHandle = new ListHandle(Root, GetLinklist(propertyIndex)); var metadata = objectType == null ? null : realm.Metadata[objectType]; return new RealmList(realm, listHandle, metadata); } [SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "The RealmObjectBase instance will own its handle.")] - public T GetObject(Realm realm, ColumnKey columnKey, string objectType) + public T GetObject(Realm realm, IntPtr propertyIndex, string objectType) where T : RealmObjectBase { - if (TryGetLink(columnKey, out var objectHandle)) + if (TryGetLink(propertyIndex, out var objectHandle)) { return (T)realm.MakeObject(realm.Metadata[objectType], objectHandle); } @@ -319,11 +319,11 @@ public T GetObject(Realm realm, ColumnKey columnKey, string objectType) return null; } - public void SetObject(Realm realm, ColumnKey columnKey, RealmObjectBase @object) + public void SetObject(Realm realm, IntPtr propertyIndex, RealmObjectBase @object) { if (@object == null) { - ClearLink(columnKey); + ClearLink(propertyIndex); } else if (@object is RealmObject realmObj) { @@ -332,7 +332,7 @@ public void SetObject(Realm realm, ColumnKey columnKey, RealmObjectBase @object) realm.Add(realmObj); } - SetLink(columnKey, realmObj.ObjectHandle); + SetLink(propertyIndex, realmObj.ObjectHandle); } else if (@object is EmbeddedObject embeddedObj) { @@ -341,7 +341,7 @@ public void SetObject(Realm realm, ColumnKey columnKey, RealmObjectBase @object) throw new RealmException("Can't link to an embedded object that is already managed."); } - var handle = CreateEmbeddedObjectForProperty(columnKey); + var handle = CreateEmbeddedObjectForProperty(propertyIndex); realm.ManageEmbedded(embeddedObj, handle); } else @@ -350,9 +350,9 @@ public void SetObject(Realm realm, ColumnKey columnKey, RealmObjectBase @object) } } - public ObjectHandle CreateEmbeddedObjectForProperty(ColumnKey columnKey) + public ObjectHandle CreateEmbeddedObjectForProperty(IntPtr propertyIndex) { - var objPtr = NativeMethods.create_embedded_link(this, columnKey, out var ex); + var objPtr = NativeMethods.create_embedded_link(this, propertyIndex, out var ex); ex.ThrowIfNecessary(); return new ObjectHandle(Root, objPtr); } @@ -365,9 +365,9 @@ public ResultsHandle GetBacklinks(IntPtr propertyIndex) return new ResultsHandle(this, resultsPtr); } - public ResultsHandle GetBacklinksForType(TableHandle table, ColumnKey columnKey) + public ResultsHandle GetBacklinksForType(TableHandle table, IntPtr propertyIndex) { - var resultsPtr = NativeMethods.get_backlinks_for_type(this, table, columnKey, out var nativeException); + var resultsPtr = NativeMethods.get_backlinks_for_type(this, table, propertyIndex, out var nativeException); nativeException.ThrowIfNecessary(); return new ResultsHandle(this, resultsPtr); diff --git a/Realm/Realm/Handles/QueryHandle.cs b/Realm/Realm/Handles/QueryHandle.cs index ffc2ea7a92..7e7a71fc18 100644 --- a/Realm/Realm/Handles/QueryHandle.cs +++ b/Realm/Realm/Handles/QueryHandle.cs @@ -31,7 +31,7 @@ namespace Realms internal class QueryHandle : RealmHandle { // This is a delegate type meant to represent one of the "query operator" methods such as float_less and bool_equal - internal delegate void Operation(QueryHandle queryPtr, ColumnKey columnKey, T value); + internal delegate void Operation(QueryHandle queryPtr, SharedRealmHandle realm, IntPtr propertyIndex, T value); private static class NativeMethods { @@ -39,63 +39,63 @@ private static class NativeMethods #pragma warning disable SA1121 // Use built-in type alias [DllImport(InteropConfig.DLL_NAME, EntryPoint = "query_binary_equal", CallingConvention = CallingConvention.Cdecl)] - public static extern void binary_equal(QueryHandle queryPtr, ColumnKey columnKey, IntPtr buffer, IntPtr bufferLength, out NativeException ex); + public static extern void binary_equal(QueryHandle queryPtr, SharedRealmHandle realm, IntPtr property_ndx, IntPtr buffer, IntPtr bufferLength, out NativeException ex); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "query_binary_not_equal", CallingConvention = CallingConvention.Cdecl)] - public static extern void binary_not_equal(QueryHandle queryPtr, ColumnKey columnKey, IntPtr buffer, IntPtr bufferLength, out NativeException ex); + public static extern void binary_not_equal(QueryHandle queryPtr, SharedRealmHandle realm, IntPtr property_ndx, IntPtr buffer, IntPtr bufferLength, out NativeException ex); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "query_string_contains", CallingConvention = CallingConvention.Cdecl)] - public static extern void string_contains(QueryHandle queryPtr, ColumnKey columnKey, + public static extern void string_contains(QueryHandle queryPtr, SharedRealmHandle realm, IntPtr property_ndx, [MarshalAs(UnmanagedType.LPWStr)] string value, IntPtr valueLen, [MarshalAs(UnmanagedType.U1)] bool caseSensitive, out NativeException ex); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "query_string_starts_with", CallingConvention = CallingConvention.Cdecl)] - public static extern void string_starts_with(QueryHandle queryPtr, ColumnKey columnKey, + public static extern void string_starts_with(QueryHandle queryPtr, SharedRealmHandle realm, IntPtr property_ndx, [MarshalAs(UnmanagedType.LPWStr)] string value, IntPtr valueLen, [MarshalAs(UnmanagedType.U1)] bool caseSensitive, out NativeException ex); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "query_string_ends_with", CallingConvention = CallingConvention.Cdecl)] - public static extern void string_ends_with(QueryHandle queryPtr, ColumnKey columnKey, + public static extern void string_ends_with(QueryHandle queryPtr, SharedRealmHandle realm, IntPtr property_ndx, [MarshalAs(UnmanagedType.LPWStr)] string value, IntPtr valueLen, [MarshalAs(UnmanagedType.U1)] bool caseSensitive, out NativeException ex); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "query_string_equal", CallingConvention = CallingConvention.Cdecl)] - public static extern void string_equal(QueryHandle queryPtr, ColumnKey columnKey, + public static extern void string_equal(QueryHandle queryPtr, SharedRealmHandle realm, IntPtr property_ndx, [MarshalAs(UnmanagedType.LPWStr)] string value, IntPtr valueLen, [MarshalAs(UnmanagedType.U1)] bool caseSensitive, out NativeException ex); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "query_string_not_equal", CallingConvention = CallingConvention.Cdecl)] - public static extern void string_not_equal(QueryHandle queryPtr, ColumnKey columnKey, + public static extern void string_not_equal(QueryHandle queryPtr, SharedRealmHandle realm, IntPtr property_ndx, [MarshalAs(UnmanagedType.LPWStr)] string value, IntPtr valueLen, [MarshalAs(UnmanagedType.U1)] bool caseSensitive, out NativeException ex); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "query_string_like", CallingConvention = CallingConvention.Cdecl)] - public static extern void string_like(QueryHandle queryPtr, ColumnKey columnKey, + public static extern void string_like(QueryHandle queryPtr, SharedRealmHandle realm, IntPtr property_ndx, [MarshalAs(UnmanagedType.LPWStr)] string value, IntPtr valueLen, [MarshalAs(UnmanagedType.U1)] bool caseSensitive, out NativeException ex); // primitive is IntPtr rather than PrimitiveValue due to a bug in .NET Core on Linux and Mac // that causes incorrect marshalling of the struct. [DllImport(InteropConfig.DLL_NAME, EntryPoint = "query_primitive_equal", CallingConvention = CallingConvention.Cdecl)] - public static extern void primitive_equal(QueryHandle queryPtr, ColumnKey columnKey, IntPtr primitive, out NativeException ex); + public static extern void primitive_equal(QueryHandle queryPtr, SharedRealmHandle realm, IntPtr property_ndx, IntPtr primitive, out NativeException ex); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "query_primitive_not_equal", CallingConvention = CallingConvention.Cdecl)] - public static extern void primitive_not_equal(QueryHandle queryPtr, ColumnKey columnKey, IntPtr primitive, out NativeException ex); + public static extern void primitive_not_equal(QueryHandle queryPtr, SharedRealmHandle realm, IntPtr property_ndx, IntPtr primitive, out NativeException ex); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "query_primitive_less", CallingConvention = CallingConvention.Cdecl)] - public static extern void primitive_less(QueryHandle queryPtr, ColumnKey columnKey, IntPtr primitive, out NativeException ex); + public static extern void primitive_less(QueryHandle queryPtr, SharedRealmHandle realm, IntPtr property_ndx, IntPtr primitive, out NativeException ex); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "query_primitive_less_equal", CallingConvention = CallingConvention.Cdecl)] - public static extern void primitive_less_equal(QueryHandle queryPtr, ColumnKey columnKey, IntPtr primitive, out NativeException ex); + public static extern void primitive_less_equal(QueryHandle queryPtr, SharedRealmHandle realm, IntPtr property_ndx, IntPtr primitive, out NativeException ex); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "query_primitive_greater", CallingConvention = CallingConvention.Cdecl)] - public static extern void primitive_greater(QueryHandle queryPtr, ColumnKey columnKey, IntPtr primitive, out NativeException ex); + public static extern void primitive_greater(QueryHandle queryPtr, SharedRealmHandle realm, IntPtr property_ndx, IntPtr primitive, out NativeException ex); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "query_primitive_greater_equal", CallingConvention = CallingConvention.Cdecl)] - public static extern void primitive_greater_equal(QueryHandle queryPtr, ColumnKey columnKey, IntPtr primitive, out NativeException ex); + public static extern void primitive_greater_equal(QueryHandle queryPtr, SharedRealmHandle realm, IntPtr property_ndx, IntPtr primitive, out NativeException ex); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "query_object_equal", CallingConvention = CallingConvention.Cdecl)] - public static extern void query_object_equal(QueryHandle queryPtr, ColumnKey columnKey, ObjectHandle objectHandle, out NativeException ex); + public static extern void query_object_equal(QueryHandle queryPtr, SharedRealmHandle realm, IntPtr property_ndx, ObjectHandle objectHandle, out NativeException ex); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "query_null_equal", CallingConvention = CallingConvention.Cdecl)] - public static extern void null_equal(QueryHandle queryPtr, ColumnKey columnKey, out NativeException ex); + public static extern void null_equal(QueryHandle queryPtr, SharedRealmHandle realm, IntPtr property_ndx, out NativeException ex); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "query_null_not_equal", CallingConvention = CallingConvention.Cdecl)] - public static extern void null_not_equal(QueryHandle queryPtr, ColumnKey columnKey, out NativeException ex); + public static extern void null_not_equal(QueryHandle queryPtr, SharedRealmHandle realm, IntPtr property_ndx, out NativeException ex); [DllImport(InteropConfig.DLL_NAME, EntryPoint = "query_not", CallingConvention = CallingConvention.Cdecl)] public static extern void not(QueryHandle queryHandle, out NativeException ex); @@ -131,135 +131,135 @@ protected override void Unbind() NativeMethods.destroy(handle); } - public void BinaryEqual(ColumnKey columnKey, IntPtr buffer, IntPtr bufferLength) + public void BinaryEqual(SharedRealmHandle realm, IntPtr propertyIndex, IntPtr buffer, IntPtr bufferLength) { - NativeMethods.binary_equal(this, columnKey, buffer, bufferLength, out var nativeException); + NativeMethods.binary_equal(this, realm, propertyIndex, buffer, bufferLength, out var nativeException); nativeException.ThrowIfNecessary(); } - public void BinaryNotEqual(ColumnKey columnKey, IntPtr buffer, IntPtr bufferLength) + public void BinaryNotEqual(SharedRealmHandle realm, IntPtr propertyIndex, IntPtr buffer, IntPtr bufferLength) { - NativeMethods.binary_not_equal(this, columnKey, buffer, bufferLength, out var nativeException); + NativeMethods.binary_not_equal(this, realm, propertyIndex, buffer, bufferLength, out var nativeException); nativeException.ThrowIfNecessary(); } /// /// If the user hasn't specified it, should be caseSensitive=true. /// - public void StringContains(ColumnKey columnKey, string value, bool caseSensitive) + public void StringContains(SharedRealmHandle realm, IntPtr propertyIndex, string value, bool caseSensitive) { - NativeMethods.string_contains(this, columnKey, value, (IntPtr)value.Length, caseSensitive, out var nativeException); + NativeMethods.string_contains(this, realm, propertyIndex, value, (IntPtr)value.Length, caseSensitive, out var nativeException); nativeException.ThrowIfNecessary(); } /// /// If the user hasn't specified it, should be caseSensitive = true. /// - public void StringStartsWith(ColumnKey columnKey, string value, bool caseSensitive) + public void StringStartsWith(SharedRealmHandle realm, IntPtr propertyIndex, string value, bool caseSensitive) { - NativeMethods.string_starts_with(this, columnKey, value, (IntPtr)value.Length, caseSensitive, out var nativeException); + NativeMethods.string_starts_with(this, realm, propertyIndex, value, (IntPtr)value.Length, caseSensitive, out var nativeException); nativeException.ThrowIfNecessary(); } /// /// If the user hasn't specified it, should be caseSensitive = true. /// - public void StringEndsWith(ColumnKey columnKey, string value, bool caseSensitive) + public void StringEndsWith(SharedRealmHandle realm, IntPtr propertyIndex, string value, bool caseSensitive) { - NativeMethods.string_ends_with(this, columnKey, value, (IntPtr)value.Length, caseSensitive, out var nativeException); + NativeMethods.string_ends_with(this, realm, propertyIndex, value, (IntPtr)value.Length, caseSensitive, out var nativeException); nativeException.ThrowIfNecessary(); } /// /// If the user hasn't specified it, should be caseSensitive = true. /// - public void StringEqual(ColumnKey columnKey, string value, bool caseSensitive) + public void StringEqual(SharedRealmHandle realm, IntPtr propertyIndex, string value, bool caseSensitive) { - NativeMethods.string_equal(this, columnKey, value, (IntPtr)value.Length, caseSensitive, out var nativeException); + NativeMethods.string_equal(this, realm, propertyIndex, value, (IntPtr)value.Length, caseSensitive, out var nativeException); nativeException.ThrowIfNecessary(); } /// /// If the user hasn't specified it, should be caseSensitive = true. /// - public void StringNotEqual(ColumnKey columnKey, string value, bool caseSensitive) + public void StringNotEqual(SharedRealmHandle realm, IntPtr propertyIndex, string value, bool caseSensitive) { - NativeMethods.string_not_equal(this, columnKey, value, (IntPtr)value.Length, caseSensitive, out var nativeException); + NativeMethods.string_not_equal(this, realm, propertyIndex, value, (IntPtr)value.Length, caseSensitive, out var nativeException); nativeException.ThrowIfNecessary(); } - public void StringLike(ColumnKey columnKey, string value, bool caseSensitive) + public void StringLike(SharedRealmHandle realm, IntPtr propertyIndex, string value, bool caseSensitive) { NativeException nativeException; if (value == null) { - NativeMethods.null_equal(this, columnKey, out nativeException); + NativeMethods.null_equal(this, realm, propertyIndex, out nativeException); } else { - NativeMethods.string_like(this, columnKey, value, (IntPtr)value.Length, caseSensitive, out nativeException); + NativeMethods.string_like(this, realm, propertyIndex, value, (IntPtr)value.Length, caseSensitive, out nativeException); } nativeException.ThrowIfNecessary(); } - public unsafe void PrimitiveEqual(ColumnKey columnKey, PrimitiveValue value) + public unsafe void PrimitiveEqual(SharedRealmHandle realm, IntPtr propertyIndex, PrimitiveValue value) { PrimitiveValue* valuePtr = &value; - NativeMethods.primitive_equal(this, columnKey, new IntPtr(valuePtr), out var nativeException); + NativeMethods.primitive_equal(this, realm, propertyIndex, new IntPtr(valuePtr), out var nativeException); nativeException.ThrowIfNecessary(); } - public unsafe void PrimitiveNotEqual(ColumnKey columnKey, PrimitiveValue value) + public unsafe void PrimitiveNotEqual(SharedRealmHandle realm, IntPtr propertyIndex, PrimitiveValue value) { PrimitiveValue* valuePtr = &value; - NativeMethods.primitive_not_equal(this, columnKey, new IntPtr(valuePtr), out var nativeException); + NativeMethods.primitive_not_equal(this, realm, propertyIndex, new IntPtr(valuePtr), out var nativeException); nativeException.ThrowIfNecessary(); } - public unsafe void PrimitiveLess(ColumnKey columnKey, PrimitiveValue value) + public unsafe void PrimitiveLess(SharedRealmHandle realm, IntPtr propertyIndex, PrimitiveValue value) { PrimitiveValue* valuePtr = &value; - NativeMethods.primitive_less(this, columnKey, new IntPtr(valuePtr), out var nativeException); + NativeMethods.primitive_less(this, realm, propertyIndex, new IntPtr(valuePtr), out var nativeException); nativeException.ThrowIfNecessary(); } - public unsafe void PrimitiveLessEqual(ColumnKey columnKey, PrimitiveValue value) + public unsafe void PrimitiveLessEqual(SharedRealmHandle realm, IntPtr propertyIndex, PrimitiveValue value) { PrimitiveValue* valuePtr = &value; - NativeMethods.primitive_less_equal(this, columnKey, new IntPtr(valuePtr), out var nativeException); + NativeMethods.primitive_less_equal(this, realm, propertyIndex, new IntPtr(valuePtr), out var nativeException); nativeException.ThrowIfNecessary(); } - public unsafe void PrimitiveGreater(ColumnKey columnKey, PrimitiveValue value) + public unsafe void PrimitiveGreater(SharedRealmHandle realm, IntPtr propertyIndex, PrimitiveValue value) { PrimitiveValue* valuePtr = &value; - NativeMethods.primitive_greater(this, columnKey, new IntPtr(valuePtr), out var nativeException); + NativeMethods.primitive_greater(this, realm, propertyIndex, new IntPtr(valuePtr), out var nativeException); nativeException.ThrowIfNecessary(); } - public unsafe void PrimitiveGreaterEqual(ColumnKey columnKey, PrimitiveValue value) + public unsafe void PrimitiveGreaterEqual(SharedRealmHandle realm, IntPtr propertyIndex, PrimitiveValue value) { PrimitiveValue* valuePtr = &value; - NativeMethods.primitive_greater_equal(this, columnKey, new IntPtr(valuePtr), out var nativeException); + NativeMethods.primitive_greater_equal(this, realm, propertyIndex, new IntPtr(valuePtr), out var nativeException); nativeException.ThrowIfNecessary(); } - public void ObjectEqual(ColumnKey columnKey, ObjectHandle objectHandle) + public void ObjectEqual(SharedRealmHandle realm, IntPtr propertyIndex, ObjectHandle objectHandle) { - NativeMethods.query_object_equal(this, columnKey, objectHandle, out var nativeException); + NativeMethods.query_object_equal(this, realm, propertyIndex, objectHandle, out var nativeException); nativeException.ThrowIfNecessary(); } - public void NullEqual(ColumnKey columnKey) + public void NullEqual(SharedRealmHandle realm, IntPtr propertyIndex) { - NativeMethods.null_equal(this, columnKey, out var nativeException); + NativeMethods.null_equal(this, realm, propertyIndex, out var nativeException); nativeException.ThrowIfNecessary(); } - public void NullNotEqual(ColumnKey columnKey) + public void NullNotEqual(SharedRealmHandle realm, IntPtr propertyIndex) { - NativeMethods.null_not_equal(this, columnKey, out var nativeException); + NativeMethods.null_not_equal(this, realm, propertyIndex, out var nativeException); nativeException.ThrowIfNecessary(); } @@ -300,25 +300,5 @@ public ResultsHandle CreateResults(SharedRealmHandle sharedRealm, SortDescriptor nativeException.ThrowIfNecessary(); return new ResultsHandle(sharedRealm, result); } - - public struct NumericQueryMethods - { - public readonly Action Int; - - public readonly Action Long; - - public readonly Action Float; - - public readonly Action Double; - - public NumericQueryMethods(Action intQuery, Action longQuery, - Action floatQuery, Action doubleQuery) - { - Int = intQuery; - Long = longQuery; - Float = floatQuery; - Double = doubleQuery; - } - } } } diff --git a/Realm/Realm/Handles/SharedRealmHandle.cs b/Realm/Realm/Handles/SharedRealmHandle.cs index 7e020388af..42ef2ef722 100644 --- a/Realm/Realm/Handles/SharedRealmHandle.cs +++ b/Realm/Realm/Handles/SharedRealmHandle.cs @@ -76,8 +76,8 @@ public static extern IntPtr open(Configuration configuration, [return: MarshalAs(UnmanagedType.U1)] public static extern bool refresh(SharedRealmHandle sharedRealm, out NativeException ex); - [DllImport(InteropConfig.DLL_NAME, EntryPoint = "shared_realm_get_table_info", CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr get_table_info(SharedRealmHandle sharedRealm, [MarshalAs(UnmanagedType.LPWStr)] string tableName, IntPtr tableNameLength, [Out] ColumnKey[] column_keys, 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_is_same_instance", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.U1)] @@ -242,12 +242,11 @@ public bool Refresh() return result; } - public (TableHandle TableHandle, ColumnKey[] ColumnKeys) GetTableInfo(string tableName, int propertiesCount) + public TableHandle GetTable(string tableName) { - var columnKeys = new ColumnKey[propertiesCount]; - var result = NativeMethods.get_table_info(this, tableName, (IntPtr)tableName.Length, columnKeys, out var nativeException); + var result = NativeMethods.get_table(this, tableName, (IntPtr)tableName.Length, out var nativeException); nativeException.ThrowIfNecessary(); - return (new TableHandle(this, result), columnKeys); + return new TableHandle(this, result); } public bool IsSameInstance(SharedRealmHandle other) diff --git a/Realm/Realm/Handles/SortDescriptorHandle.cs b/Realm/Realm/Handles/SortDescriptorHandle.cs index bcfaa87155..f0985e1fb2 100644 --- a/Realm/Realm/Handles/SortDescriptorHandle.cs +++ b/Realm/Realm/Handles/SortDescriptorHandle.cs @@ -18,15 +18,11 @@ using System; using System.Runtime.InteropServices; -using Realms.Native; namespace Realms { internal class SortDescriptorHandle : RealmHandle { - // This is a delegate type meant to represent one of the "query operator" methods such as float_less and bool_equal - internal delegate void Operation(QueryHandle queryPtr, ColumnKey columnKey, T value); - private static class NativeMethods { [DllImport(InteropConfig.DLL_NAME, EntryPoint = "sort_descriptor_destroy", CallingConvention = CallingConvention.Cdecl)] @@ -34,7 +30,7 @@ private static class NativeMethods [DllImport(InteropConfig.DLL_NAME, EntryPoint = "sort_descriptor_add_clause", CallingConvention = CallingConvention.Cdecl)] public static extern void add_clause(SortDescriptorHandle descriptor, TableHandle query, SharedRealmHandle realm, - [MarshalAs(UnmanagedType.LPArray), In] ColumnKey[] column_key_chain, IntPtr column_keys_count, + [MarshalAs(UnmanagedType.LPArray), In] IntPtr[] property_index_chain, IntPtr column_keys_count, [MarshalAs(UnmanagedType.U1)] bool ascending, out NativeException ex); } @@ -43,9 +39,9 @@ public SortDescriptorHandle(RealmHandle root, IntPtr handle) : base(root, handle { } - public void AddClause(TableHandle table, SharedRealmHandle realm, ColumnKey[] columnKeyChain, bool ascending) + public void AddClause(TableHandle table, SharedRealmHandle realm, IntPtr[] propertyIndexChain, bool ascending) { - NativeMethods.add_clause(this, table, realm, columnKeyChain, (IntPtr)columnKeyChain.Length, ascending, out var nativeException); + NativeMethods.add_clause(this, table, realm, propertyIndexChain, (IntPtr)propertyIndexChain.Length, ascending, out var nativeException); nativeException.ThrowIfNecessary(); } diff --git a/Realm/Realm/Linq/RealmResultsVisitor.cs b/Realm/Realm/Linq/RealmResultsVisitor.cs index b2c58af48f..2258d0346e 100644 --- a/Realm/Realm/Linq/RealmResultsVisitor.cs +++ b/Realm/Realm/Linq/RealmResultsVisitor.cs @@ -119,13 +119,13 @@ private void AddSort(LambdaExpression lambda, bool ascending) throw new NotSupportedException($"The expression {lambda} cannot be used in an Order clause"); } - var columnChain = TraverseSort(body); - _sortDescriptor.AddClause(_metadata.Table, _realm.SharedRealmHandle, columnChain, ascending); + var propertyChain = TraverseSort(body); + _sortDescriptor.AddClause(_metadata.Table, _realm.SharedRealmHandle, propertyChain, ascending); } - private ColumnKey[] TraverseSort(MemberExpression expression) + private IntPtr[] TraverseSort(MemberExpression expression) { - var chain = new List(); + var chain = new List(); while (expression != null) { @@ -137,7 +137,7 @@ private ColumnKey[] TraverseSort(MemberExpression expression) } var columnName = GetColumnName(expression); - if (!metadata.ColumnKeys.TryGetValue(columnName, out var index)) + if (!metadata.PropertyIndices.TryGetValue(columnName, out var index)) { throw new NotSupportedException($"The property {columnName} is not a persisted property on {type.Name} so sorting by it is not allowed."); } @@ -330,29 +330,29 @@ protected override Expression VisitMethodCall(MethodCallExpression node) if (AreMethodsSame(node.Method, Methods.String.Contains.Value)) { - queryMethod = (q, c, v) => q.StringContains(c, v, caseSensitive: true); + queryMethod = (q, r, p, v) => q.StringContains(r, p, v, caseSensitive: true); } else if (IsStringContainsWithComparison(node.Method, out var index)) { member = node.Arguments[0] as MemberExpression; stringArgumentIndex = index; - queryMethod = (q, c, v) => q.StringContains(c, v, GetComparisonCaseSensitive(node)); + queryMethod = (q, r, p, v) => q.StringContains(r, p, v, GetComparisonCaseSensitive(node)); } else if (AreMethodsSame(node.Method, Methods.String.StartsWith.Value)) { - queryMethod = (q, c, v) => q.StringStartsWith(c, v, caseSensitive: true); + queryMethod = (q, r, p, v) => q.StringStartsWith(r, p, v, caseSensitive: true); } else if (AreMethodsSame(node.Method, Methods.String.StartsWithStringComparison.Value)) { - queryMethod = (q, c, v) => q.StringStartsWith(c, v, GetComparisonCaseSensitive(node)); + queryMethod = (q, r, p, v) => q.StringStartsWith(r, p, v, GetComparisonCaseSensitive(node)); } else if (AreMethodsSame(node.Method, Methods.String.EndsWith.Value)) { - queryMethod = (q, c, v) => q.StringEndsWith(c, v, caseSensitive: true); + queryMethod = (q, r, p, v) => q.StringEndsWith(r, p, v, caseSensitive: true); } else if (AreMethodsSame(node.Method, Methods.String.EndsWithStringComparison.Value)) { - queryMethod = (q, c, v) => q.StringEndsWith(c, v, GetComparisonCaseSensitive(node)); + queryMethod = (q, r, p, v) => q.StringEndsWith(r, p, v, GetComparisonCaseSensitive(node)); } else if (AreMethodsSame(node.Method, Methods.String.IsNullOrEmpty.Value)) { @@ -363,22 +363,22 @@ protected override Expression VisitMethodCall(MethodCallExpression node) } var columnName = GetColumnName(member, node.NodeType); - var columnKey = _metadata.ColumnKeys[columnName]; + var propertyIndex = _metadata.PropertyIndices[columnName]; _coreQueryHandle.GroupBegin(); - _coreQueryHandle.NullEqual(columnKey); + _coreQueryHandle.NullEqual(_realm.SharedRealmHandle, propertyIndex); _coreQueryHandle.Or(); - _coreQueryHandle.StringEqual(columnKey, string.Empty, caseSensitive: true); + _coreQueryHandle.StringEqual(_realm.SharedRealmHandle, propertyIndex, string.Empty, caseSensitive: true); _coreQueryHandle.GroupEnd(); return node; } else if (AreMethodsSame(node.Method, Methods.String.EqualsMethod.Value)) { - queryMethod = (q, c, v) => q.StringEqual(c, v, caseSensitive: true); + queryMethod = (q, r, p, v) => q.StringEqual(r, p, v, caseSensitive: true); } else if (AreMethodsSame(node.Method, Methods.String.EqualsStringComparison.Value)) { - queryMethod = (q, c, v) => q.StringEqual(c, v, GetComparisonCaseSensitive(node)); + queryMethod = (q, r, p, v) => q.StringEqual(r, p, v, GetComparisonCaseSensitive(node)); } else if (AreMethodsSame(node.Method, Methods.String.Like.Value)) { @@ -389,7 +389,7 @@ protected override Expression VisitMethodCall(MethodCallExpression node) throw new NotSupportedException($"The method '{node.Method}' has to be invoked with a string and boolean constant arguments."); } - queryMethod = (q, c, v) => q.StringLike(c, v, (bool)caseSensitive); + queryMethod = (q, r, p, v) => q.StringLike(r, p, v, (bool)caseSensitive); } if (queryMethod != null) @@ -402,7 +402,7 @@ protected override Expression VisitMethodCall(MethodCallExpression node) } var columnName = GetColumnName(member, node.NodeType); - var columnKey = _metadata.ColumnKeys[columnName]; + var propertyIndex = _metadata.PropertyIndices[columnName]; if (!TryExtractConstantValue(node.Arguments[stringArgumentIndex], out object argument) || (argument != null && argument.GetType() != typeof(string))) @@ -410,7 +410,7 @@ protected override Expression VisitMethodCall(MethodCallExpression node) throw new NotSupportedException($"The method '{node.Method}' has to be invoked with a single string constant argument or closure variable"); } - queryMethod(_coreQueryHandle, columnKey, (string)argument); + queryMethod(_coreQueryHandle, _realm.SharedRealmHandle, propertyIndex, (string)argument); return node; } } @@ -622,27 +622,27 @@ protected override Expression VisitBinary(BinaryExpression node) private void AddQueryEqual(QueryHandle queryHandle, string columnName, object value, Type columnType) { - var columnKey = _metadata.ColumnKeys[columnName]; + var propertyIndex = _metadata.PropertyIndices[columnName]; switch (value) { case null: - queryHandle.NullEqual(columnKey); + queryHandle.NullEqual(_realm.SharedRealmHandle, propertyIndex); break; case string stringValue: - queryHandle.StringEqual(columnKey, stringValue, caseSensitive: true); + queryHandle.StringEqual(_realm.SharedRealmHandle, propertyIndex, stringValue, caseSensitive: true); break; case bool boolValue: - queryHandle.PrimitiveEqual(columnKey, PrimitiveValue.Bool(boolValue)); + queryHandle.PrimitiveEqual(_realm.SharedRealmHandle, propertyIndex, PrimitiveValue.Bool(boolValue)); break; case DateTimeOffset dateValue: - queryHandle.PrimitiveEqual(columnKey, PrimitiveValue.Date(dateValue)); + queryHandle.PrimitiveEqual(_realm.SharedRealmHandle, propertyIndex, PrimitiveValue.Date(dateValue)); break; case byte[] buffer: if (buffer.Length == 0) { // see RealmObjectBase.SetByteArrayValue - queryHandle.BinaryEqual(columnKey, (IntPtr)0x1, IntPtr.Zero); + queryHandle.BinaryEqual(_realm.SharedRealmHandle, propertyIndex, (IntPtr)0x1, IntPtr.Zero); return; } @@ -650,43 +650,43 @@ private void AddQueryEqual(QueryHandle queryHandle, string columnName, object va { fixed (byte* bufferPtr = (byte[])value) { - queryHandle.BinaryEqual(columnKey, (IntPtr)bufferPtr, (IntPtr)buffer.Length); + queryHandle.BinaryEqual(_realm.SharedRealmHandle, propertyIndex, (IntPtr)bufferPtr, (IntPtr)buffer.Length); } } break; case RealmObjectBase obj: - queryHandle.ObjectEqual(columnKey, obj.ObjectHandle); + queryHandle.ObjectEqual(_realm.SharedRealmHandle, propertyIndex, obj.ObjectHandle); break; default: // The other types aren't handled by the switch because of potential compiler applied conversions - AddQueryForConvertibleTypes(columnKey, value, columnType, queryHandle.PrimitiveEqual); + AddQueryForConvertibleTypes(_realm.SharedRealmHandle, propertyIndex, value, columnType, queryHandle.PrimitiveEqual); break; } } private void AddQueryNotEqual(QueryHandle queryHandle, string columnName, object value, Type columnType) { - var columnKey = _metadata.ColumnKeys[columnName]; + var propertyIndex = _metadata.PropertyIndices[columnName]; switch (value) { case null: - queryHandle.NullNotEqual(columnKey); + queryHandle.NullNotEqual(_realm.SharedRealmHandle, propertyIndex); break; case string stringValue: - queryHandle.StringNotEqual(columnKey, stringValue, caseSensitive: true); + queryHandle.StringNotEqual(_realm.SharedRealmHandle, propertyIndex, stringValue, caseSensitive: true); break; case bool boolValue: - queryHandle.PrimitiveNotEqual(columnKey, PrimitiveValue.Bool(boolValue)); + queryHandle.PrimitiveNotEqual(_realm.SharedRealmHandle, propertyIndex, PrimitiveValue.Bool(boolValue)); break; case DateTimeOffset date: - queryHandle.PrimitiveNotEqual(columnKey, PrimitiveValue.Date(date)); + queryHandle.PrimitiveNotEqual(_realm.SharedRealmHandle, propertyIndex, PrimitiveValue.Date(date)); break; case byte[] buffer: if (buffer.Length == 0) { // see RealmObjectBase.SetByteArrayValue - queryHandle.BinaryNotEqual(columnKey, (IntPtr)0x1, IntPtr.Zero); + queryHandle.BinaryNotEqual(_realm.SharedRealmHandle, propertyIndex, (IntPtr)0x1, IntPtr.Zero); return; } @@ -694,95 +694,95 @@ private void AddQueryNotEqual(QueryHandle queryHandle, string columnName, object { fixed (byte* bufferPtr = (byte[])value) { - queryHandle.BinaryNotEqual(columnKey, (IntPtr)bufferPtr, (IntPtr)buffer.Length); + queryHandle.BinaryNotEqual(_realm.SharedRealmHandle, propertyIndex, (IntPtr)bufferPtr, (IntPtr)buffer.Length); } } break; case RealmObjectBase obj: queryHandle.Not(); - queryHandle.ObjectEqual(columnKey, obj.ObjectHandle); + queryHandle.ObjectEqual(_realm.SharedRealmHandle, propertyIndex, obj.ObjectHandle); break; default: // The other types aren't handled by the switch because of potential compiler applied conversions - AddQueryForConvertibleTypes(columnKey, value, columnType, queryHandle.PrimitiveNotEqual); + AddQueryForConvertibleTypes(_realm.SharedRealmHandle, propertyIndex, value, columnType, queryHandle.PrimitiveNotEqual); break; } } private void AddQueryLessThan(QueryHandle queryHandle, string columnName, object value, Type columnType) { - var columnKey = _metadata.ColumnKeys[columnName]; + var propertyIndex = _metadata.PropertyIndices[columnName]; switch (value) { case DateTimeOffset date: - queryHandle.PrimitiveLess(columnKey, PrimitiveValue.Date(date)); + queryHandle.PrimitiveLess(_realm.SharedRealmHandle, propertyIndex, PrimitiveValue.Date(date)); break; case string _: case bool _: throw new Exception($"Unsupported type {value.GetType().Name}"); default: // The other types aren't handled by the switch because of potential compiler applied conversions - AddQueryForConvertibleTypes(columnKey, value, columnType, queryHandle.PrimitiveLess); + AddQueryForConvertibleTypes(_realm.SharedRealmHandle, propertyIndex, value, columnType, queryHandle.PrimitiveLess); break; } } private void AddQueryLessThanOrEqual(QueryHandle queryHandle, string columnName, object value, Type columnType) { - var columnKey = _metadata.ColumnKeys[columnName]; + var propertyIndex = _metadata.PropertyIndices[columnName]; switch (value) { case DateTimeOffset date: - queryHandle.PrimitiveLessEqual(columnKey, PrimitiveValue.Date(date)); + queryHandle.PrimitiveLessEqual(_realm.SharedRealmHandle, propertyIndex, PrimitiveValue.Date(date)); break; case string _: case bool _: throw new Exception($"Unsupported type {value.GetType().Name}"); default: // The other types aren't handled by the switch because of potential compiler applied conversions - AddQueryForConvertibleTypes(columnKey, value, columnType, queryHandle.PrimitiveLessEqual); + AddQueryForConvertibleTypes(_realm.SharedRealmHandle, propertyIndex, value, columnType, queryHandle.PrimitiveLessEqual); break; } } private void AddQueryGreaterThan(QueryHandle queryHandle, string columnName, object value, Type columnType) { - var columnKey = _metadata.ColumnKeys[columnName]; + var propertyIndex = _metadata.PropertyIndices[columnName]; switch (value) { case DateTimeOffset date: - queryHandle.PrimitiveGreater(columnKey, PrimitiveValue.Date(date)); + queryHandle.PrimitiveGreater(_realm.SharedRealmHandle, propertyIndex, PrimitiveValue.Date(date)); break; case string _: case bool _: throw new Exception($"Unsupported type {value.GetType().Name}"); default: // The other types aren't handled by the switch because of potential compiler applied conversions - AddQueryForConvertibleTypes(columnKey, value, columnType, queryHandle.PrimitiveGreater); + AddQueryForConvertibleTypes(_realm.SharedRealmHandle, propertyIndex, value, columnType, queryHandle.PrimitiveGreater); break; } } private void AddQueryGreaterThanOrEqual(QueryHandle queryHandle, string columnName, object value, Type columnType) { - var columnKey = _metadata.ColumnKeys[columnName]; + var propertyIndex = _metadata.PropertyIndices[columnName]; switch (value) { case DateTimeOffset date: - queryHandle.PrimitiveGreaterEqual(columnKey, PrimitiveValue.Date(date)); + queryHandle.PrimitiveGreaterEqual(_realm.SharedRealmHandle, propertyIndex, PrimitiveValue.Date(date)); break; case string _: case bool _: throw new Exception($"Unsupported type {value.GetType().Name}"); default: // The other types aren't handled by the switch because of potential compiler applied conversions - AddQueryForConvertibleTypes(columnKey, value, columnType, queryHandle.PrimitiveGreaterEqual); + AddQueryForConvertibleTypes(_realm.SharedRealmHandle, propertyIndex, value, columnType, queryHandle.PrimitiveGreaterEqual); break; } } - private static void AddQueryForConvertibleTypes(ColumnKey columnKey, object value, Type columnType, Action action) + private static void AddQueryForConvertibleTypes(SharedRealmHandle realm, IntPtr propertyIndex, object value, Type columnType, Action action) { if (columnType.IsConstructedGenericType && columnType.GetGenericTypeDefinition() == typeof(Nullable<>)) { @@ -799,15 +799,15 @@ private static void AddQueryForConvertibleTypes(ColumnKey columnKey, object valu columnType == typeof(RealmInteger) || columnType == typeof(RealmInteger)) { - action(columnKey, PrimitiveValue.Int((long)Convert.ChangeType(value, typeof(long)))); + action(realm, propertyIndex, PrimitiveValue.Int((long)Convert.ChangeType(value, typeof(long)))); } else if (columnType == typeof(float)) { - action(columnKey, PrimitiveValue.Float((float)Convert.ChangeType(value, typeof(float)))); + action(realm, propertyIndex, PrimitiveValue.Float((float)Convert.ChangeType(value, typeof(float)))); } else if (columnType == typeof(double)) { - action(columnKey, PrimitiveValue.Double((double)Convert.ChangeType(value, typeof(double)))); + action(realm, propertyIndex, PrimitiveValue.Double((double)Convert.ChangeType(value, typeof(double)))); } else if (columnType == typeof(Decimal128)) { @@ -817,15 +817,15 @@ private static void AddQueryForConvertibleTypes(ColumnKey columnKey, object valu decimalValue = (Decimal128)Convert.ChangeType(value, typeof(Decimal128)); } - action(columnKey, PrimitiveValue.Decimal(decimalValue)); + action(realm, propertyIndex, PrimitiveValue.Decimal(decimalValue)); } else if (columnType == typeof(decimal)) { - action(columnKey, PrimitiveValue.Decimal((decimal)Convert.ChangeType(value, typeof(decimal)))); + action(realm, propertyIndex, PrimitiveValue.Decimal((decimal)Convert.ChangeType(value, typeof(decimal)))); } else if (columnType == typeof(ObjectId)) { - action(columnKey, PrimitiveValue.ObjectId((ObjectId)Convert.ChangeType(value, typeof(ObjectId)))); + action(realm, propertyIndex, PrimitiveValue.ObjectId((ObjectId)Convert.ChangeType(value, typeof(ObjectId)))); } else { diff --git a/Realm/Realm/Native/ColumnKey.cs b/Realm/Realm/Native/ColumnKey.cs deleted file mode 100644 index ce43a62283..0000000000 --- a/Realm/Realm/Native/ColumnKey.cs +++ /dev/null @@ -1,29 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2020 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; - -namespace Realms.Native -{ - [StructLayout(LayoutKind.Sequential, Pack = 8)] - internal struct ColumnKey - { - private Int64 value; - } -} diff --git a/Realm/Realm/Realm.cs b/Realm/Realm/Realm.cs index a6ebb2ed20..3d9746a52b 100644 --- a/Realm/Realm/Realm.cs +++ b/Realm/Realm/Realm.cs @@ -279,7 +279,7 @@ internal Realm(SharedRealmHandle sharedRealmHandle, RealmConfigurationBase confi private RealmObjectBase.Metadata CreateRealmObjectMetadata(ObjectSchema schema) { - var (tableHandle, columnKeys) = SharedRealmHandle.GetTableInfo(schema.Name, schema.Count(p => !p.Type.IsComputed())); + var tableHandle = SharedRealmHandle.GetTable(schema.Name); Weaving.IRealmObjectHelper helper; if (schema.Type != null && !Config.IsDynamic) @@ -297,24 +297,19 @@ private RealmObjectBase.Metadata CreateRealmObjectMetadata(ObjectSchema schema) helper = DynamicRealmObjectHelper.Instance(schema.IsEmbedded); } - var columnKeysDict = new Dictionary(schema.Count); - var computedProperiesMap = new Dictionary(); + var initPropertyMap = new Dictionary(schema.Count); + var persistedProperties = -1; + var computedProperties = -1; // We're taking advantage of the fact OS keeps property indices aligned // with the property indices in ObjectSchema foreach (var prop in schema) { - if (prop.Type.IsComputed()) - { - computedProperiesMap[prop.Name] = (IntPtr)computedProperiesMap.Count; - } - else - { - columnKeysDict[prop.Name] = columnKeys[columnKeysDict.Count]; - } + var index = prop.Type.IsComputed() ? ++computedProperties : ++persistedProperties; + initPropertyMap[prop.Name] = (IntPtr)index; } - return new RealmObjectBase.Metadata(tableHandle, helper, columnKeysDict, computedProperiesMap, schema); + return new RealmObjectBase.Metadata(tableHandle, helper, initPropertyMap, schema); } /// @@ -1278,7 +1273,7 @@ public dynamic CreateEmbeddedObjectForProperty(RealmObjectBase parent, string pr Argument.Ensure(metadata.Schema.IsEmbedded, $"The class {property.ObjectType} linked to by {parent.GetType().Name}.{propertyName} is not embedded", nameof(propertyName)); var obj = metadata.Helper.CreateInstance(); - var handle = parent.ObjectHandle.CreateEmbeddedObjectForProperty(parent.ObjectMetadata.ColumnKeys[propertyName]); + var handle = parent.ObjectHandle.CreateEmbeddedObjectForProperty(parent.ObjectMetadata.PropertyIndices[propertyName]); obj.SetOwner(_realm, handle, metadata); obj.OnManaged(); diff --git a/Realm/Realm/RealmInteger.cs b/Realm/Realm/RealmInteger.cs index 26013df5a5..9e1584c5aa 100644 --- a/Realm/Realm/RealmInteger.cs +++ b/Realm/Realm/RealmInteger.cs @@ -52,7 +52,7 @@ public struct RealmInteger : { private readonly T _value; private readonly ObjectHandle _objectHandle; - private readonly ColumnKey _columnKey; + private readonly IntPtr _propertyIndex; private bool IsManaged => _objectHandle != null; @@ -60,14 +60,14 @@ internal RealmInteger(T value) { _value = value; _objectHandle = null; - _columnKey = default; + _propertyIndex = default; } - internal RealmInteger(T value, ObjectHandle objectHandle, ColumnKey columnKey) + internal RealmInteger(T value, ObjectHandle objectHandle, IntPtr propertyIndex) { _value = value; _objectHandle = objectHandle; - _columnKey = columnKey; + _propertyIndex = propertyIndex; } /// @@ -97,9 +97,9 @@ public RealmInteger Increment(T value) { if (IsManaged) { - _objectHandle.AddInt64(_columnKey, value.ToLong()); - var result = _objectHandle.GetPrimitive(_columnKey, Schema.PropertyType.Int).ToIntegral(); - return new RealmInteger(result, _objectHandle, _columnKey); + _objectHandle.AddInt64(_propertyIndex, value.ToLong()); + var result = _objectHandle.GetPrimitive(_propertyIndex, Schema.PropertyType.Int).ToIntegral(); + return new RealmInteger(result, _objectHandle, _propertyIndex); } throw new NotSupportedException("Increment should only be called on RealmInteger properties of managed objects."); @@ -325,7 +325,7 @@ public int CompareTo(T other) /// /// /// The provider to use to format the value. -or- A null reference to obtain the numeric format - /// information from the current locale setting of the operating system + /// information from the current locale setting of the operating system. /// The value of the current instance in the specified format. public string ToString(string format, IFormatProvider formatProvider) => _value.ToString(format, formatProvider); diff --git a/Realm/Realm/RealmObjectBase.cs b/Realm/Realm/RealmObjectBase.cs index 47e58cfb84..f9c3565380 100644 --- a/Realm/Realm/RealmObjectBase.cs +++ b/Realm/Realm/RealmObjectBase.cs @@ -210,14 +210,14 @@ protected string GetStringValue(string propertyName) { Debug.Assert(IsManaged, "Object is not managed, but managed access was attempted"); - return _objectHandle.GetString(_metadata.ColumnKeys[propertyName]); + return _objectHandle.GetString(_metadata.PropertyIndices[propertyName]); } protected T GetPrimitiveValue(string propertyName, PropertyType propertyType) { Debug.Assert(IsManaged, "Object is not managed, but managed access was attempted"); - return _objectHandle.GetPrimitive(_metadata.ColumnKeys[propertyName], propertyType).Get(); + return _objectHandle.GetPrimitive(_metadata.PropertyIndices[propertyName], propertyType).Get(); } protected internal IList GetListValue(string propertyName) @@ -225,7 +225,7 @@ protected internal IList GetListValue(string propertyName) Debug.Assert(IsManaged, "Object is not managed, but managed access was attempted"); _metadata.Schema.TryFindProperty(propertyName, out var property); - return _objectHandle.GetList(_realm, _metadata.ColumnKeys[propertyName], property.ObjectType); + return _objectHandle.GetList(_realm, _metadata.PropertyIndices[propertyName], property.ObjectType); } [SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "The RealmObjectBase instance will own its handle.")] @@ -234,7 +234,7 @@ protected T GetObjectValue(string propertyName) { Debug.Assert(IsManaged, "Object is not managed, but managed access was attempted"); - if (_objectHandle.TryGetLink(_metadata.ColumnKeys[propertyName], out var objectHandle)) + if (_objectHandle.TryGetLink(_metadata.PropertyIndices[propertyName], out var objectHandle)) { _metadata.Schema.TryFindProperty(propertyName, out var property); return (T)_realm.MakeObject(_realm.Metadata[property.ObjectType], objectHandle); @@ -247,7 +247,7 @@ protected byte[] GetByteArrayValue(string propertyName) { Debug.Assert(IsManaged, "Object is not managed, but managed access was attempted"); - return _objectHandle.GetByteArray(_metadata.ColumnKeys[propertyName]); + return _objectHandle.GetByteArray(_metadata.PropertyIndices[propertyName]); } protected IQueryable GetBacklinks(string propertyName) @@ -255,7 +255,7 @@ protected IQueryable GetBacklinks(string propertyName) { Debug.Assert(IsManaged, "Object is not managed, but managed access was attempted"); - var resultsHandle = _objectHandle.GetBacklinks(_metadata.ComputedProperties[propertyName]); + var resultsHandle = _objectHandle.GetBacklinks(_metadata.PropertyIndices[propertyName]); return GetBacklinksForHandle(propertyName, resultsHandle); } @@ -271,20 +271,20 @@ internal RealmResults GetBacklinksForHandle(string propertyName, ResultsHa protected RealmInteger GetRealmIntegerValue(string propertyName) where T : struct, IFormattable, IComparable { - var columnKey = _metadata.ColumnKeys[propertyName]; - var result = _objectHandle.GetPrimitive(columnKey, PropertyType.Int).ToIntegral(); - return new RealmInteger(result, ObjectHandle, columnKey); + var propertyIndex = _metadata.PropertyIndices[propertyName]; + var result = _objectHandle.GetPrimitive(propertyIndex, PropertyType.Int).ToIntegral(); + return new RealmInteger(result, ObjectHandle, propertyIndex); } protected RealmInteger? GetNullableRealmIntegerValue(string propertyName) where T : struct, IFormattable, IComparable { - var columnKey = _metadata.ColumnKeys[propertyName]; - var result = _objectHandle.GetPrimitive(columnKey, PropertyType.NullableInt).ToNullableIntegral(); + var propertyIndex = _metadata.PropertyIndices[propertyName]; + var result = _objectHandle.GetPrimitive(propertyIndex, PropertyType.NullableInt).ToNullableIntegral(); if (result.HasValue) { - return new RealmInteger(result.Value, ObjectHandle, columnKey); + return new RealmInteger(result.Value, ObjectHandle, propertyIndex); } return null; @@ -298,28 +298,28 @@ protected void SetPrimitiveValue(string propertyName, T value, PropertyType p { Debug.Assert(IsManaged, "Object is not managed, but managed access was attempted"); - _objectHandle.SetPrimitive(_metadata.ColumnKeys[propertyName], PrimitiveValue.Create(value, propertyType)); + _objectHandle.SetPrimitive(_metadata.PropertyIndices[propertyName], PrimitiveValue.Create(value, propertyType)); } protected void SetPrimitiveValueUnique(string propertyName, T value, PropertyType propertyType) { Debug.Assert(IsManaged, "Object is not managed, but managed access was attempted"); - _objectHandle.SetPrimitiveUnique(_metadata.ColumnKeys[propertyName], PrimitiveValue.Create(value, propertyType)); + _objectHandle.SetPrimitiveUnique(_metadata.PropertyIndices[propertyName], PrimitiveValue.Create(value, propertyType)); } protected void SetStringValue(string propertyName, string value) { Debug.Assert(IsManaged, "Object is not managed, but managed access was attempted"); - _objectHandle.SetString(_metadata.ColumnKeys[propertyName], value); + _objectHandle.SetString(_metadata.PropertyIndices[propertyName], value); } protected void SetStringValueUnique(string propertyName, string value) { Debug.Assert(IsManaged, "Object is not managed, but managed access was attempted"); - _objectHandle.SetStringUnique(_metadata.ColumnKeys[propertyName], value); + _objectHandle.SetStringUnique(_metadata.PropertyIndices[propertyName], value); } // Originally a generic fallback, now used only for RealmObjectBase To-One relationship properties @@ -329,14 +329,14 @@ protected void SetObjectValue(string propertyName, T value) { Debug.Assert(IsManaged, "Object is not managed, but managed access was attempted"); - _objectHandle.SetObject(this.Realm, _metadata.ColumnKeys[propertyName], value); + _objectHandle.SetObject(Realm, _metadata.PropertyIndices[propertyName], value); } protected void SetByteArrayValue(string propertyName, byte[] value) { Debug.Assert(IsManaged, "Object is not managed, but managed access was attempted"); - _objectHandle.SetByteArray(_metadata.ColumnKeys[propertyName], value); + _objectHandle.SetByteArray(_metadata.PropertyIndices[propertyName], value); } protected void SetRealmIntegerValue(string propertyName, RealmInteger value) @@ -344,7 +344,7 @@ protected void SetRealmIntegerValue(string propertyName, RealmInteger valu { Debug.Assert(IsManaged, "Object is not managed, but managed access was attempted"); - _objectHandle.SetPrimitive(_metadata.ColumnKeys[propertyName], PrimitiveValue.Int(value.ToLong())); + _objectHandle.SetPrimitive(_metadata.PropertyIndices[propertyName], PrimitiveValue.Int(value.ToLong())); } protected void SetNullableRealmIntegerValue(string propertyName, RealmInteger? value) @@ -352,7 +352,7 @@ protected void SetNullableRealmIntegerValue(string propertyName, RealmInteger { Debug.Assert(IsManaged, "Object is not managed, but managed access was attempted"); - _objectHandle.SetPrimitive(_metadata.ColumnKeys[propertyName], PrimitiveValue.NullableInt(value?.ToLong())); + _objectHandle.SetPrimitive(_metadata.PropertyIndices[propertyName], PrimitiveValue.NullableInt(value?.ToLong())); } protected void SetRealmIntegerValueUnique(string propertyName, RealmInteger value) @@ -360,7 +360,7 @@ protected void SetRealmIntegerValueUnique(string propertyName, RealmInteger(string propertyName, RealmInteger? value) @@ -368,7 +368,7 @@ protected void SetNullableRealmIntegerValueUnique(string propertyName, RealmI { Debug.Assert(IsManaged, "Object is not managed, but managed access was attempted"); - _objectHandle.SetPrimitiveUnique(_metadata.ColumnKeys[propertyName], PrimitiveValue.NullableInt(value?.ToLong())); + _objectHandle.SetPrimitiveUnique(_metadata.PropertyIndices[propertyName], PrimitiveValue.NullableInt(value?.ToLong())); } #endregion @@ -384,9 +384,9 @@ protected void SetNullableRealmIntegerValueUnique(string propertyName, RealmI 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.ColumnKeys.ContainsKey(property), $"Type {objectType} does not contain property {property}", nameof(property)); + Argument.Ensure(relatedMeta.PropertyIndices.ContainsKey(property), $"Type {objectType} does not contain property {property}", nameof(property)); - var resultsHandle = ObjectHandle.GetBacklinksForType(relatedMeta.Table, relatedMeta.ColumnKeys[property]); + var resultsHandle = ObjectHandle.GetBacklinksForType(relatedMeta.Table, relatedMeta.PropertyIndices[property]); if (relatedMeta.Schema.IsEmbedded) { return new RealmResults(Realm, relatedMeta, resultsHandle); @@ -569,19 +569,15 @@ internal class Metadata internal readonly IRealmObjectHelper Helper; - internal readonly IReadOnlyDictionary ColumnKeys; - - internal readonly IReadOnlyDictionary ComputedProperties; + internal readonly IReadOnlyDictionary PropertyIndices; internal readonly ObjectSchema Schema; - - public Metadata(TableHandle table, IRealmObjectHelper helper, IDictionary columnKeys, IDictionary computedProperties, ObjectSchema schema) + public Metadata(TableHandle table, IRealmObjectHelper helper, IDictionary propertyIndices, ObjectSchema schema) { Table = table; Helper = helper; - ColumnKeys = new ReadOnlyDictionary(columnKeys); - ComputedProperties = new ReadOnlyDictionary(computedProperties); + PropertyIndices = new ReadOnlyDictionary(propertyIndices); Schema = schema; } } diff --git a/wrappers/src/object_cs.cpp b/wrappers/src/object_cs.cpp index 868dd91eec..74406729f1 100644 --- a/wrappers/src/object_cs.cpp +++ b/wrappers/src/object_cs.cpp @@ -31,22 +31,22 @@ using namespace realm; using namespace realm::binding; template -inline T object_get(const Object& object, ColKey column_key, NativeException::Marshallable& ex) +inline T object_get(const Object& object, size_t property_ndx, NativeException::Marshallable& ex) { return handle_errors(ex, [&]() { verify_can_get(object); - return object.obj().get(column_key); + return object.obj().get(get_column_key(object, property_ndx)); }); } template -inline void object_set(Object& object, ColKey column_key, const T& value, NativeException::Marshallable& ex) +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(column_key, value); + object.obj().set(get_column_key(object, property_ndx), value); }); } @@ -70,12 +70,12 @@ extern "C" { }); } - REALM_EXPORT Object* object_get_link(const Object& object, ColKey column_key, NativeException::Marshallable& ex) + REALM_EXPORT Object* object_get_link(const Object& object, size_t property_ndx, NativeException::Marshallable& ex) { return handle_errors(ex, [&]() -> Object* { verify_can_get(object); - const Obj link_obj = object.obj().get_linked_object(column_key); + const Obj link_obj = object.obj().get_linked_object(get_column_key(object, property_ndx)); if (!link_obj) return nullptr; @@ -85,76 +85,78 @@ extern "C" { }); } - REALM_EXPORT List* object_get_list(const Object& object, ColKey column_key, NativeException::Marshallable& ex) + REALM_EXPORT List* object_get_list(const Object& object, size_t property_ndx, NativeException::Marshallable& ex) { return handle_errors(ex, [&]() -> List* { verify_can_get(object); - return new List(object.realm(), object.obj(), column_key); + return new List(object.realm(), object.obj(), get_column_key(object, property_ndx)); }); } - REALM_EXPORT void object_get_primitive(const Object& object, ColKey column_key, PrimitiveValue& value, NativeException::Marshallable& ex) + REALM_EXPORT void object_get_primitive(const Object& object, size_t property_ndx, PrimitiveValue& value, NativeException::Marshallable& ex) { handle_errors(ex, [&]() { verify_can_get(object); value.has_value = true; + auto column_key = get_column_key(object, property_ndx); + #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wswitch" switch (value.type) { case realm::PropertyType::Bool: - value.value.bool_value = object.obj().get(column_key); + value.value.bool_value = object.obj().get(std::move(column_key)); break; case realm::PropertyType::Bool | realm::PropertyType::Nullable: { - auto result = object.obj().get>(column_key); + auto result = object.obj().get>(std::move(column_key)); value.has_value = !!result; value.value.bool_value = result.value_or(false); break; } case realm::PropertyType::Int: - value.value.int_value = object.obj().get(column_key); + value.value.int_value = object.obj().get(std::move(column_key)); break; case realm::PropertyType::Int | realm::PropertyType::Nullable: { - auto result = object.obj().get>(column_key); + auto result = object.obj().get>(std::move(column_key)); value.has_value = !!result; value.value.int_value = result.value_or(0); break; } case realm::PropertyType::Float: - value.value.float_value = object.obj().get(column_key); + value.value.float_value = object.obj().get(std::move(column_key)); break; case realm::PropertyType::Float | realm::PropertyType::Nullable: { - auto result = object.obj().get>(column_key); + auto result = object.obj().get>(std::move(column_key)); value.has_value = !!result; value.value.float_value = result.value_or((float)0); break; } case realm::PropertyType::Double: - value.value.double_value = object.obj().get(column_key); + value.value.double_value = object.obj().get(std::move(column_key)); break; case realm::PropertyType::Double | realm::PropertyType::Nullable: { - auto result = object.obj().get>(column_key); + auto result = object.obj().get>(std::move(column_key)); value.has_value = !!result; value.value.double_value = result.value_or((double)0); break; } case realm::PropertyType::Date: - value.value.int_value = to_ticks(object.obj().get(column_key)); + value.value.int_value = to_ticks(object.obj().get(std::move(column_key))); break; case realm::PropertyType::Date | realm::PropertyType::Nullable: { - auto result = object.obj().get(column_key); + auto result = object.obj().get(std::move(column_key)); value.has_value = !result.is_null(); value.value.int_value = result.is_null() ? 0 : to_ticks(result); break; } case realm::PropertyType::Decimal: { - auto result = object.obj().get(column_key); + auto result = object.obj().get(std::move(column_key)); value.value.decimal_bits = *result.raw(); break; } case realm::PropertyType::Decimal | realm::PropertyType::Nullable: { - auto result = object.obj().get(column_key); + auto result = object.obj().get(std::move(column_key)); value.has_value = !result.is_null(); if (value.has_value) { value.value.decimal_bits = *result.raw(); @@ -162,7 +164,7 @@ extern "C" { break; } case realm::PropertyType::ObjectId: { - auto result = object.obj().get(column_key); + auto result = object.obj().get(std::move(column_key)); auto bytes = result.to_bytes(); for (int i = 0; i < 12; i++) { @@ -171,7 +173,7 @@ extern "C" { break; } case realm::PropertyType::ObjectId | realm::PropertyType::Nullable: { - auto result = object.obj().get>(column_key); + auto result = object.obj().get>(std::move(column_key)); value.has_value = !!result; if (value.has_value) { auto bytes = result.value().to_bytes(); @@ -189,59 +191,61 @@ extern "C" { }); } - REALM_EXPORT void object_set_primitive(const Object& object, ColKey column_key, PrimitiveValue& value, NativeException::Marshallable& ex) + REALM_EXPORT void object_set_primitive(const Object& object, size_t property_ndx, PrimitiveValue& value, NativeException::Marshallable& ex) { handle_errors(ex, [&]() { verify_can_set(object); + auto column_key = get_column_key(object, property_ndx); + #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wswitch" switch (value.type) { case realm::PropertyType::Bool: - object.obj().set(column_key, value.value.bool_value); + object.obj().set(std::move(column_key), value.value.bool_value); break; case realm::PropertyType::Bool | realm::PropertyType::Nullable: - object.obj().set(column_key, value.has_value ? util::Optional(value.value.bool_value) : util::Optional(none)); + object.obj().set(std::move(column_key), value.has_value ? util::Optional(value.value.bool_value) : util::Optional(none)); break; case realm::PropertyType::Int: - object.obj().set(column_key, value.value.int_value); + object.obj().set(std::move(column_key), value.value.int_value); break; case realm::PropertyType::Int | realm::PropertyType::Nullable: - object.obj().set(column_key, value.has_value ? util::Optional(value.value.int_value) : util::Optional(none)); + object.obj().set(std::move(column_key), value.has_value ? util::Optional(value.value.int_value) : util::Optional(none)); break; case realm::PropertyType::Float: - object.obj().set(column_key, value.value.float_value); + object.obj().set(std::move(column_key), value.value.float_value); break; case realm::PropertyType::Float | realm::PropertyType::Nullable: - object.obj().set(column_key, value.has_value ? util::Optional(value.value.float_value) : util::Optional(none)); + object.obj().set(std::move(column_key), value.has_value ? util::Optional(value.value.float_value) : util::Optional(none)); break; case realm::PropertyType::Double: - object.obj().set(column_key, value.value.double_value); + object.obj().set(std::move(column_key), value.value.double_value); break; case realm::PropertyType::Double | realm::PropertyType::Nullable: - object.obj().set(column_key, value.has_value ? util::Optional(value.value.double_value) : util::Optional(none)); + object.obj().set(std::move(column_key), value.has_value ? util::Optional(value.value.double_value) : util::Optional(none)); break; case realm::PropertyType::Date: - object.obj().set(column_key, from_ticks(value.value.int_value)); + object.obj().set(std::move(column_key), from_ticks(value.value.int_value)); break; case realm::PropertyType::Date | realm::PropertyType::Nullable: - object.obj().set(column_key, value.has_value ? from_ticks(value.value.int_value) : Timestamp()); + object.obj().set(std::move(column_key), value.has_value ? from_ticks(value.value.int_value) : Timestamp()); break; case realm::PropertyType::Decimal: { - object.obj().set(column_key, realm::Decimal128(value.value.decimal_bits)); + object.obj().set(std::move(column_key), realm::Decimal128(value.value.decimal_bits)); break; } case realm::PropertyType::Decimal | realm::PropertyType::Nullable: { auto decimal = value.has_value ? realm::Decimal128(value.value.decimal_bits) : Decimal128(null()); - object.obj().set(column_key, decimal); + object.obj().set(std::move(column_key), decimal); break; } case realm::PropertyType::ObjectId: { - object.obj().set(column_key, to_object_id(value)); + object.obj().set(std::move(column_key), to_object_id(value)); break; } case realm::PropertyType::ObjectId | realm::PropertyType::Nullable: { - object.obj().set(column_key, value.has_value ? util::Optional(to_object_id(value)) : util::Optional()); + object.obj().set(std::move(column_key), value.has_value ? util::Optional(to_object_id(value)) : util::Optional()); break; } default: @@ -251,9 +255,9 @@ extern "C" { }); } - REALM_EXPORT size_t object_get_string(const Object& object, ColKey column_key, uint16_t* string_buffer, size_t buffer_size, bool& is_null, NativeException::Marshallable& ex) + REALM_EXPORT size_t object_get_string(const Object& object, size_t property_ndx, uint16_t* string_buffer, size_t buffer_size, bool& is_null, NativeException::Marshallable& ex) { - StringData field_data = object_get(object, column_key, ex); + StringData field_data = object_get(object, property_ndx, ex); if (ex.type != RealmErrorType::NoError) { return -1; } @@ -265,9 +269,9 @@ extern "C" { return stringdata_to_csharpstringbuffer(field_data, string_buffer, buffer_size); } - REALM_EXPORT size_t object_get_binary(const Object& object, ColKey column_key, char* return_buffer, size_t buffer_size, bool& is_null, NativeException::Marshallable& ex) + REALM_EXPORT size_t object_get_binary(const Object& object, size_t property_ndx, char* return_buffer, size_t buffer_size, bool& is_null, NativeException::Marshallable& ex) { - BinaryData field_data = object_get(object, column_key, ex); + BinaryData field_data = object_get(object, property_ndx, ex); if (ex.type != RealmErrorType::NoError) { return -1; } @@ -302,49 +306,48 @@ extern "C" { }); } - REALM_EXPORT Results* object_get_backlinks_for_type(Object& object, TableRef& source_table, ColKey source_column_key, NativeException::Marshallable& ex) + REALM_EXPORT Results* object_get_backlinks_for_type(Object& object, TableRef& source_table, 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 Property& source_property = *std::find_if(source_object_schema.persisted_properties.begin(), source_object_schema.persisted_properties.end(), [&](Property p) { - return p.column_key == source_column_key; - }); + const Property& source_property = source_object_schema.persisted_properties[source_property_ndx]; if (source_property.object_type != object.get_object_schema().name) { throw std::logic_error(util::format("'%1.%2' is not a relationship to '%3'", source_object_schema.name, source_property.name, object.get_object_schema().name)); } - TableView backlink_view = object.obj().get_backlink_view(source_table, source_column_key); + TableView backlink_view = object.obj().get_backlink_view(source_table, source_property.column_key); return new Results(object.realm(), std::move(backlink_view)); }); } - REALM_EXPORT void object_set_link(Object& object, ColKey column_key, const Object& target_object, NativeException::Marshallable& ex) + REALM_EXPORT void object_set_link(Object& object, size_t property_ndx, const Object& target_object, NativeException::Marshallable& ex) { - return object_set(object, column_key, target_object.obj().get_key(), ex); + return object_set(object, property_ndx, target_object.obj().get_key(), ex); } - REALM_EXPORT Object* object_create_embedded(Object& parent, ColKey column_key, NativeException::Marshallable& ex) + REALM_EXPORT Object* object_create_embedded(Object& parent, size_t property_ndx, NativeException::Marshallable& ex) { return handle_errors(ex, [&]() { verify_can_set(parent); - return new Object(parent.realm(), parent.obj().create_and_set_linked_object(column_key)); + return new Object(parent.realm(), parent.obj().create_and_set_linked_object(get_column_key(parent, property_ndx))); }); } - REALM_EXPORT void object_clear_link(Object& object, ColKey column_key, NativeException::Marshallable& ex) + REALM_EXPORT void object_clear_link(Object& object, size_t property_ndx, NativeException::Marshallable& ex) { - return object_set(object, column_key, null_key, ex); + return object_set(object, property_ndx, null_key, ex); } - REALM_EXPORT void object_set_null(Object& object, ColKey column_key, NativeException::Marshallable& ex) + REALM_EXPORT void object_set_null(Object& object, size_t property_ndx, NativeException::Marshallable& ex) { return handle_errors(ex, [&]() { verify_can_set(object); + auto column_key = get_column_key(object, property_ndx); if (!object.obj().get_table()->is_nullable(column_key)) throw std::invalid_argument("Column is not nullable"); @@ -352,15 +355,15 @@ extern "C" { }); } - REALM_EXPORT void object_set_string(Object& object, ColKey column_key, uint16_t* value, size_t value_len, NativeException::Marshallable& ex) + REALM_EXPORT void object_set_string(Object& object, size_t property_ndx, uint16_t* value, size_t value_len, NativeException::Marshallable& ex) { Utf16StringAccessor str(value, value_len); - return object_set(object, column_key, str, ex); + return object_set(object, property_ndx, str, ex); } - REALM_EXPORT void object_set_binary(Object& object, ColKey column_key, char* value, size_t value_len, NativeException::Marshallable& ex) + REALM_EXPORT void object_set_binary(Object& object, size_t property_ndx, char* value, size_t value_len, NativeException::Marshallable& ex) { - return object_set(object, column_key, BinaryData(value, value_len), ex); + return object_set(object, property_ndx, BinaryData(value, value_len), ex); } REALM_EXPORT void object_remove(Object& object, SharedRealm& realm, NativeException::Marshallable& ex) @@ -411,12 +414,12 @@ extern "C" { }); } - REALM_EXPORT void object_add_int64(Object& object, ColKey column_key, int64_t value, NativeException::Marshallable& ex) + REALM_EXPORT void object_add_int64(Object& object, size_t property_ndx, int64_t value, NativeException::Marshallable& ex) { return handle_errors(ex, [&]() { verify_can_set(object); - object.obj().add_int(column_key, value); + object.obj().add_int(get_column_key(object, property_ndx), value); }); } diff --git a/wrappers/src/object_cs.hpp b/wrappers/src/object_cs.hpp index a7d0646e94..63cfad52cd 100644 --- a/wrappers/src/object_cs.hpp +++ b/wrappers/src/object_cs.hpp @@ -27,20 +27,24 @@ namespace realm { inline void verify_can_get(const Object& object) { if (object.realm()->is_closed()) throw RealmClosedException(); - + if (!object.is_valid()) throw RowDetachedException(); - + object.realm()->verify_thread(); } - + inline void verify_can_set(const Object& object) { if (object.realm()->is_closed()) throw RealmClosedException(); - + if (!object.is_valid()) throw RowDetachedException(); - + object.realm()->verify_in_write(); } + + inline const ColKey get_column_key(const Object& object, const size_t property_index) { + return object.get_object_schema().persisted_properties[property_index].column_key; + } } diff --git a/wrappers/src/query_cs.cpp b/wrappers/src/query_cs.cpp index c733c74371..e5d18632f4 100644 --- a/wrappers/src/query_cs.cpp +++ b/wrappers/src/query_cs.cpp @@ -30,6 +30,10 @@ using namespace realm; using namespace realm::binding; +inline ColKey get_key_for_prop(Query& query, SharedRealm& realm, size_t property_index) { + return realm->schema().find(ObjectStore::object_type_for_table_name(query.get_table()->get_name()))->persisted_properties[property_index].column_key; +} + extern "C" { REALM_EXPORT void query_destroy(Query* query) @@ -72,91 +76,92 @@ REALM_EXPORT void query_or(Query& query, NativeException::Marshallable& ex) }); } -REALM_EXPORT void query_string_contains(Query& query, ColKey column_key, uint16_t* value, size_t value_len, bool case_sensitive, NativeException::Marshallable& ex) +REALM_EXPORT void query_string_contains(Query& query, SharedRealm& realm, size_t property_index, uint16_t* value, size_t value_len, bool case_sensitive, NativeException::Marshallable& ex) { handle_errors(ex, [&]() { Utf16StringAccessor str(value, value_len); - query.contains(column_key, str, case_sensitive); + query.contains(get_key_for_prop(query, realm, property_index), str, case_sensitive); }); } -REALM_EXPORT void query_string_starts_with(Query& query, ColKey column_key, uint16_t* value, size_t value_len, bool case_sensitive, NativeException::Marshallable& ex) +REALM_EXPORT void query_string_starts_with(Query& query, SharedRealm& realm, size_t property_index, uint16_t* value, size_t value_len, bool case_sensitive, NativeException::Marshallable& ex) { handle_errors(ex, [&]() { Utf16StringAccessor str(value, value_len); - query.begins_with(column_key, str, case_sensitive); + query.begins_with(get_key_for_prop(query, realm, property_index), str, case_sensitive); }); } -REALM_EXPORT void query_string_ends_with(Query& query, ColKey column_key, uint16_t* value, size_t value_len, bool case_sensitive, NativeException::Marshallable& ex) +REALM_EXPORT void query_string_ends_with(Query& query, SharedRealm& realm, size_t property_index, uint16_t* value, size_t value_len, bool case_sensitive, NativeException::Marshallable& ex) { handle_errors(ex, [&]() { Utf16StringAccessor str(value, value_len); - query.ends_with(column_key, str, case_sensitive); + query.ends_with(get_key_for_prop(query, realm, property_index), str, case_sensitive); }); } -REALM_EXPORT void query_string_equal(Query& query, ColKey column_key, uint16_t* value, size_t value_len, bool case_sensitive, NativeException::Marshallable& ex) +REALM_EXPORT void query_string_equal(Query& query, SharedRealm& realm, size_t property_index, uint16_t* value, size_t value_len, bool case_sensitive, NativeException::Marshallable& ex) { handle_errors(ex, [&]() { Utf16StringAccessor str(value, value_len); - query.equal(column_key, str, case_sensitive); + query.equal(get_key_for_prop(query, realm, property_index), str, case_sensitive); }); } -REALM_EXPORT void query_string_not_equal(Query& query, ColKey column_key, uint16_t* value, size_t value_len, bool case_sensitive, NativeException::Marshallable& ex) +REALM_EXPORT void query_string_not_equal(Query& query, SharedRealm& realm, size_t property_index, uint16_t* value, size_t value_len, bool case_sensitive, NativeException::Marshallable& ex) { handle_errors(ex, [&]() { Utf16StringAccessor str(value, value_len); - query.not_equal(column_key, str, case_sensitive); + query.not_equal(get_key_for_prop(query, realm, property_index), str, case_sensitive); }); } -REALM_EXPORT void query_string_like(Query& query, ColKey column_key, uint16_t* value, size_t value_len, bool case_sensitive, NativeException::Marshallable& ex) +REALM_EXPORT void query_string_like(Query& query, SharedRealm& realm, size_t property_index, uint16_t* value, size_t value_len, bool case_sensitive, NativeException::Marshallable& ex) { handle_errors(ex, [&]() { Utf16StringAccessor str(value, value_len); - query.like(column_key, str, case_sensitive); + query.like(get_key_for_prop(query, realm, property_index), str, case_sensitive); }); } -REALM_EXPORT void query_primitive_equal(Query& query, ColKey column_key, PrimitiveValue& primitive, NativeException::Marshallable& ex) +REALM_EXPORT void query_primitive_equal(Query& query, SharedRealm& realm, size_t property_index, PrimitiveValue& primitive, NativeException::Marshallable& ex) { handle_errors(ex, [&]() { if (!primitive.has_value) { throw std::runtime_error("Comparing null values should be done via query_null_equal. If you get this error, please report it to help@realm.io."); } + auto col_key = get_key_for_prop(query, realm, property_index); #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wswitch" switch (primitive.type) { case realm::PropertyType::Bool: case realm::PropertyType::Bool | realm::PropertyType::Nullable: - query.equal(column_key, primitive.value.bool_value); + query.equal(std::move(col_key), primitive.value.bool_value); break; case realm::PropertyType::Int: case realm::PropertyType::Int | realm::PropertyType::Nullable: - query.equal(column_key, primitive.value.int_value); + query.equal(std::move(col_key), primitive.value.int_value); break; case realm::PropertyType::Float: case realm::PropertyType::Float | realm::PropertyType::Nullable: - query.equal(column_key, primitive.value.float_value); + query.equal(std::move(col_key), primitive.value.float_value); break; case realm::PropertyType::Double: case realm::PropertyType::Double | realm::PropertyType::Nullable: - query.equal(column_key, primitive.value.double_value); + query.equal(std::move(col_key), primitive.value.double_value); break; case realm::PropertyType::Date: case realm::PropertyType::Date | realm::PropertyType::Nullable: - query.equal(column_key, from_ticks(primitive.value.int_value)); + query.equal(std::move(col_key), from_ticks(primitive.value.int_value)); break; case realm::PropertyType::Decimal: case realm::PropertyType::Decimal | realm::PropertyType::Nullable: - query.equal(column_key, realm::Decimal128(primitive.value.decimal_bits)); + query.equal(std::move(col_key), realm::Decimal128(primitive.value.decimal_bits)); break; case realm::PropertyType::ObjectId: case realm::PropertyType::ObjectId | realm::PropertyType::Nullable: - query.equal(column_key, to_object_id(primitive)); + query.equal(std::move(col_key), to_object_id(primitive)); break; default: REALM_UNREACHABLE(); @@ -165,43 +170,45 @@ REALM_EXPORT void query_primitive_equal(Query& query, ColKey column_key, Primiti }); } -REALM_EXPORT void query_primitive_not_equal(Query& query, ColKey column_key, PrimitiveValue& primitive, NativeException::Marshallable& ex) +REALM_EXPORT void query_primitive_not_equal(Query& query, SharedRealm& realm, size_t property_index, PrimitiveValue& primitive, NativeException::Marshallable& ex) { handle_errors(ex, [&]() { if (!primitive.has_value) { throw std::runtime_error("Comparing null values should be done via query_null_not_equal. If you get this error, please report it to help@realm.io."); } + auto col_key = get_key_for_prop(query, realm, property_index); + #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wswitch" switch (primitive.type) { case realm::PropertyType::Bool: case realm::PropertyType::Bool | realm::PropertyType::Nullable: - query.not_equal(column_key, primitive.value.bool_value); + query.not_equal(std::move(col_key), primitive.value.bool_value); break; case realm::PropertyType::Int: case realm::PropertyType::Int | realm::PropertyType::Nullable: - query.not_equal(column_key, primitive.value.int_value); + query.not_equal(std::move(col_key), primitive.value.int_value); break; case realm::PropertyType::Float: case realm::PropertyType::Float | realm::PropertyType::Nullable: - query.not_equal(column_key, primitive.value.float_value); + query.not_equal(std::move(col_key), primitive.value.float_value); break; case realm::PropertyType::Double: case realm::PropertyType::Double | realm::PropertyType::Nullable: - query.not_equal(column_key, primitive.value.double_value); + query.not_equal(std::move(col_key), primitive.value.double_value); break; case realm::PropertyType::Date: case realm::PropertyType::Date | realm::PropertyType::Nullable: - query.not_equal(column_key, from_ticks(primitive.value.int_value)); + query.not_equal(std::move(col_key), from_ticks(primitive.value.int_value)); break; case realm::PropertyType::Decimal: case realm::PropertyType::Decimal | realm::PropertyType::Nullable: - query.not_equal(column_key, realm::Decimal128(primitive.value.decimal_bits)); + query.not_equal(std::move(col_key), realm::Decimal128(primitive.value.decimal_bits)); break; case realm::PropertyType::ObjectId: case realm::PropertyType::ObjectId | realm::PropertyType::Nullable: - query.not_equal(column_key, to_object_id(primitive)); + query.not_equal(std::move(col_key), to_object_id(primitive)); break; default: REALM_UNREACHABLE(); @@ -210,13 +217,15 @@ REALM_EXPORT void query_primitive_not_equal(Query& query, ColKey column_key, Pri }); } -REALM_EXPORT void query_primitive_less(Query& query, ColKey column_key, PrimitiveValue& primitive, NativeException::Marshallable& ex) +REALM_EXPORT void query_primitive_less(Query& query, SharedRealm& realm, size_t property_index, PrimitiveValue& primitive, NativeException::Marshallable& ex) { handle_errors(ex, [&]() { if (!primitive.has_value) { throw std::runtime_error("Using primitive_less with null is not supported. If you get this error, please report it to help@realm.io."); } + auto col_key = get_key_for_prop(query, realm, property_index); + #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wswitch" switch (primitive.type) { @@ -225,27 +234,27 @@ REALM_EXPORT void query_primitive_less(Query& query, ColKey column_key, Primitiv throw std::runtime_error("Using primitive_less with bool value is not supported. If you get this error, please report it to help@realm.io"); case realm::PropertyType::Int: case realm::PropertyType::Int | realm::PropertyType::Nullable: - query.less(column_key, primitive.value.int_value); + query.less(std::move(col_key), primitive.value.int_value); break; case realm::PropertyType::Float: case realm::PropertyType::Float | realm::PropertyType::Nullable: - query.less(column_key, primitive.value.float_value); + query.less(std::move(col_key), primitive.value.float_value); break; case realm::PropertyType::Double: case realm::PropertyType::Double | realm::PropertyType::Nullable: - query.less(column_key, primitive.value.double_value); + query.less(std::move(col_key), primitive.value.double_value); break; case realm::PropertyType::Date: case realm::PropertyType::Date | realm::PropertyType::Nullable: - query.less(column_key, from_ticks(primitive.value.int_value)); + query.less(std::move(col_key), from_ticks(primitive.value.int_value)); break; case realm::PropertyType::Decimal: case realm::PropertyType::Decimal | realm::PropertyType::Nullable: - query.less(column_key, realm::Decimal128(primitive.value.decimal_bits)); + query.less(std::move(col_key), realm::Decimal128(primitive.value.decimal_bits)); break; case realm::PropertyType::ObjectId: case realm::PropertyType::ObjectId | realm::PropertyType::Nullable: - query.less(column_key, to_object_id(primitive)); + query.less(std::move(col_key), to_object_id(primitive)); break; default: REALM_UNREACHABLE(); @@ -254,13 +263,15 @@ REALM_EXPORT void query_primitive_less(Query& query, ColKey column_key, Primitiv }); } -REALM_EXPORT void query_primitive_less_equal(Query& query, ColKey column_key, PrimitiveValue& primitive, NativeException::Marshallable& ex) +REALM_EXPORT void query_primitive_less_equal(Query& query, SharedRealm& realm, size_t property_index, PrimitiveValue& primitive, NativeException::Marshallable& ex) { handle_errors(ex, [&]() { if (!primitive.has_value) { throw std::runtime_error("Using primitive_less_equal with null is not supported. If you get this error, please report it to help@realm.io."); } + auto col_key = get_key_for_prop(query, realm, property_index); + #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wswitch" switch (primitive.type) { @@ -269,27 +280,27 @@ REALM_EXPORT void query_primitive_less_equal(Query& query, ColKey column_key, Pr throw std::runtime_error("Using primitive_less_equal with bool value is not supported. If you get this error, please report it to help@realm.io"); case realm::PropertyType::Int: case realm::PropertyType::Int | realm::PropertyType::Nullable: - query.less_equal(column_key, primitive.value.int_value); + query.less_equal(std::move(col_key), primitive.value.int_value); break; case realm::PropertyType::Float: case realm::PropertyType::Float | realm::PropertyType::Nullable: - query.less_equal(column_key, primitive.value.float_value); + query.less_equal(std::move(col_key), primitive.value.float_value); break; case realm::PropertyType::Double: case realm::PropertyType::Double | realm::PropertyType::Nullable: - query.less_equal(column_key, primitive.value.double_value); + query.less_equal(std::move(col_key), primitive.value.double_value); break; case realm::PropertyType::Date: case realm::PropertyType::Date | realm::PropertyType::Nullable: - query.less_equal(column_key, from_ticks(primitive.value.int_value)); + query.less_equal(std::move(col_key), from_ticks(primitive.value.int_value)); break; case realm::PropertyType::Decimal: case realm::PropertyType::Decimal | realm::PropertyType::Nullable: - query.less_equal(column_key, realm::Decimal128(primitive.value.decimal_bits)); + query.less_equal(std::move(col_key), realm::Decimal128(primitive.value.decimal_bits)); break; case realm::PropertyType::ObjectId: case realm::PropertyType::ObjectId | realm::PropertyType::Nullable: - query.less_equal(column_key, to_object_id(primitive)); + query.less_equal(std::move(col_key), to_object_id(primitive)); break; default: REALM_UNREACHABLE(); @@ -298,13 +309,15 @@ REALM_EXPORT void query_primitive_less_equal(Query& query, ColKey column_key, Pr }); } -REALM_EXPORT void query_primitive_greater(Query& query, ColKey column_key, PrimitiveValue& primitive, NativeException::Marshallable& ex) +REALM_EXPORT void query_primitive_greater(Query& query, SharedRealm& realm, size_t property_index, PrimitiveValue& primitive, NativeException::Marshallable& ex) { handle_errors(ex, [&]() { if (!primitive.has_value) { throw std::runtime_error("Using primitive_greater with null is not supported. If you get this error, please report it to help@realm.io."); } + auto col_key = get_key_for_prop(query, realm, property_index); + #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wswitch" switch (primitive.type) { @@ -313,27 +326,27 @@ REALM_EXPORT void query_primitive_greater(Query& query, ColKey column_key, Primi throw std::runtime_error("Using primitive_greater with bool value is not supported. If you get this error, please report it to help@realm.io"); case realm::PropertyType::Int: case realm::PropertyType::Int | realm::PropertyType::Nullable: - query.greater(column_key, primitive.value.int_value); + query.greater(std::move(col_key), primitive.value.int_value); break; case realm::PropertyType::Float: case realm::PropertyType::Float | realm::PropertyType::Nullable: - query.greater(column_key, primitive.value.float_value); + query.greater(std::move(col_key), primitive.value.float_value); break; case realm::PropertyType::Double: case realm::PropertyType::Double | realm::PropertyType::Nullable: - query.greater(column_key, primitive.value.double_value); + query.greater(std::move(col_key), primitive.value.double_value); break; case realm::PropertyType::Date: case realm::PropertyType::Date | realm::PropertyType::Nullable: - query.greater(column_key, from_ticks(primitive.value.int_value)); + query.greater(std::move(col_key), from_ticks(primitive.value.int_value)); break; case realm::PropertyType::Decimal: case realm::PropertyType::Decimal | realm::PropertyType::Nullable: - query.greater(column_key, realm::Decimal128(primitive.value.decimal_bits)); + query.greater(std::move(col_key), realm::Decimal128(primitive.value.decimal_bits)); break; case realm::PropertyType::ObjectId: case realm::PropertyType::ObjectId | realm::PropertyType::Nullable: - query.greater(column_key, to_object_id(primitive)); + query.greater(std::move(col_key), to_object_id(primitive)); break; default: REALM_UNREACHABLE(); @@ -342,13 +355,15 @@ REALM_EXPORT void query_primitive_greater(Query& query, ColKey column_key, Primi }); } -REALM_EXPORT void query_primitive_greater_equal(Query& query, ColKey column_key, PrimitiveValue& primitive, NativeException::Marshallable& ex) +REALM_EXPORT void query_primitive_greater_equal(Query& query, SharedRealm& realm, size_t property_index, PrimitiveValue& primitive, NativeException::Marshallable& ex) { handle_errors(ex, [&]() { if (!primitive.has_value) { throw std::runtime_error("Using primitive_greater_equal with null is not supported. If you get this error, please report it to help@realm.io."); } + auto col_key = get_key_for_prop(query, realm, property_index); + #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wswitch" switch (primitive.type) { @@ -357,27 +372,27 @@ REALM_EXPORT void query_primitive_greater_equal(Query& query, ColKey column_key, throw std::runtime_error("Using primitive_greater_equal with bool value is not supported. If you get this error, please report it to help@realm.io"); case realm::PropertyType::Int: case realm::PropertyType::Int | realm::PropertyType::Nullable: - query.greater_equal(column_key, primitive.value.int_value); + query.greater_equal(std::move(col_key), primitive.value.int_value); break; case realm::PropertyType::Float: case realm::PropertyType::Float | realm::PropertyType::Nullable: - query.greater_equal(column_key, primitive.value.float_value); + query.greater_equal(std::move(col_key), primitive.value.float_value); break; case realm::PropertyType::Double: case realm::PropertyType::Double | realm::PropertyType::Nullable: - query.greater_equal(column_key, primitive.value.double_value); + query.greater_equal(std::move(col_key), primitive.value.double_value); break; case realm::PropertyType::Date: case realm::PropertyType::Date | realm::PropertyType::Nullable: - query.greater_equal(column_key, from_ticks(primitive.value.int_value)); + query.greater_equal(std::move(col_key), from_ticks(primitive.value.int_value)); break; case realm::PropertyType::Decimal: case realm::PropertyType::Decimal | realm::PropertyType::Nullable: - query.greater_equal(column_key, realm::Decimal128(primitive.value.decimal_bits)); + query.greater_equal(std::move(col_key), realm::Decimal128(primitive.value.decimal_bits)); break; case realm::PropertyType::ObjectId: case realm::PropertyType::ObjectId | realm::PropertyType::Nullable: - query.greater_equal(column_key, to_object_id(primitive)); + query.greater_equal(std::move(col_key), to_object_id(primitive)); break; default: REALM_UNREACHABLE(); @@ -386,47 +401,49 @@ REALM_EXPORT void query_primitive_greater_equal(Query& query, ColKey column_key, }); } -REALM_EXPORT void query_binary_equal(Query& query, ColKey column_key, char* buffer, size_t buffer_length, NativeException::Marshallable& ex) +REALM_EXPORT void query_binary_equal(Query& query, SharedRealm& realm, size_t property_index, char* buffer, size_t buffer_length, NativeException::Marshallable& ex) { handle_errors(ex, [&]() { - query.equal(column_key, BinaryData(buffer, buffer_length)); + query.equal(get_key_for_prop(query, realm, property_index), BinaryData(buffer, buffer_length)); }); } -REALM_EXPORT void query_binary_not_equal(Query& query, ColKey column_key, char* buffer, size_t buffer_length, NativeException::Marshallable& ex) +REALM_EXPORT void query_binary_not_equal(Query& query, SharedRealm& realm, size_t property_index, char* buffer, size_t buffer_length, NativeException::Marshallable& ex) { handle_errors(ex, [&]() { - query.not_equal(column_key, BinaryData(buffer, buffer_length)); + query.not_equal(get_key_for_prop(query, realm, property_index), BinaryData(buffer, buffer_length)); }); } -REALM_EXPORT void query_object_equal(Query& query, ColKey column_key, Object& object, NativeException::Marshallable& ex) +REALM_EXPORT void query_object_equal(Query& query, SharedRealm& realm, size_t property_index, Object& object, NativeException::Marshallable& ex) { handle_errors(ex, [&]() { - query.links_to(column_key, object.obj().get_key()); + query.links_to(get_key_for_prop(query, realm, property_index), object.obj().get_key()); }); } -REALM_EXPORT void query_null_equal(Query& query, ColKey column_key, NativeException::Marshallable& ex) +REALM_EXPORT void query_null_equal(Query& query, SharedRealm& realm, size_t property_index, NativeException::Marshallable& ex) { handle_errors(ex, [&]() { - if (query.get_table()->get_column_type(column_key) == DataType::type_Link) { - query.and_query(query.get_table()->column(column_key).is_null()); + auto col_key = get_key_for_prop(query, realm, property_index); + if (query.get_table()->get_column_type(col_key) == DataType::type_Link) { + query.and_query(query.get_table()->column(col_key).is_null()); } else { - query.equal(column_key, null()); + query.equal(col_key, null()); } }); } -REALM_EXPORT void query_null_not_equal(Query& query, ColKey column_key, NativeException::Marshallable& ex) +REALM_EXPORT void query_null_not_equal(Query& query, SharedRealm& realm, size_t property_index, NativeException::Marshallable& ex) { handle_errors(ex, [&]() { - if (query.get_table()->get_column_type(column_key) == DataType::type_Link) { - query.and_query(query.get_table()->column(column_key).is_not_null()); + auto col_key = get_key_for_prop(query, realm, property_index); + if (query.get_table()->get_column_type(col_key) == DataType::type_Link) { + query.and_query(query.get_table()->column(col_key).is_not_null()); } else { - query.not_equal(column_key, null()); + query.not_equal(col_key, null()); } }); } diff --git a/wrappers/src/shared_realm_cs.cpp b/wrappers/src/shared_realm_cs.cpp index 734bb05099..6cc20744aa 100644 --- a/wrappers/src/shared_realm_cs.cpp +++ b/wrappers/src/shared_realm_cs.cpp @@ -166,15 +166,10 @@ REALM_EXPORT void shared_realm_close_realm(SharedRealm& realm, NativeException:: }); } -REALM_EXPORT TableRef* shared_realm_get_table_info(SharedRealm& realm, uint16_t* object_type_buf, size_t object_type_len, ColKey* columns_buffer, NativeException::Marshallable& ex) +REALM_EXPORT TableRef* shared_realm_get_table(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); - - auto properties = realm->schema().find(object_type)->persisted_properties; - for (size_t i = 0; i < properties.size(); i++) { - columns_buffer[i] = properties.at(i).column_key; - } return new TableRef(ObjectStore::table_for_object_type(realm->read_group(), object_type)); }); } diff --git a/wrappers/src/sort_descriptor_cs.cpp b/wrappers/src/sort_descriptor_cs.cpp index 71703795fa..94fe60f3af 100644 --- a/wrappers/src/sort_descriptor_cs.cpp +++ b/wrappers/src/sort_descriptor_cs.cpp @@ -34,19 +34,25 @@ REALM_EXPORT void sort_descriptor_destroy(DescriptorOrdering* descriptor) delete descriptor; } -REALM_EXPORT void sort_descriptor_add_clause(DescriptorOrdering& descriptor, TableRef& table, SharedRealm& realm, ColKey* col_keys_chain, size_t col_keys_count, bool ascending, NativeException::Marshallable& ex) +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) { 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; - for (auto i = 0; i < col_keys_count; ++i) { - column_keys.push_back(col_keys_chain[i]); + for (auto i = 0; i < properties_count; ++i) { + const Property& property = properties->at(property_chain[i]); + column_keys.push_back(property.column_key); + + if (property.type == PropertyType::Object) { + properties = &realm->schema().find(property.object_type)->persisted_properties; + } } - descriptor.append_sort(SortDescriptor({column_keys}, {ascending}), SortDescriptor::MergeMode::append); + descriptor.append_sort(SortDescriptor({ column_keys }, { ascending }), SortDescriptor::MergeMode::append); }); }