public bool TryGet(string key, RealmObjectBase.Metadata metadata, Realm realm, out RealmValue value) { RealmValue keyValue = key; var(primitiveKey, keyHandles) = keyValue.ToNative(); var containsValue = NativeMethods.try_get_value(this, primitiveKey, out var result, out var nativeException); keyHandles?.Dispose(); nativeException.ThrowIfNecessary(); if (!containsValue) { value = default; return(false); } if (result.Type != RealmValueType.Object) { value = new RealmValue(result); } else { var objectHandle = result.AsObject(Root); if (metadata == null) { throw new NotImplementedException("Mixed objects are not supported yet."); } value = new RealmValue(realm.MakeObject(metadata, objectHandle)); } return(true); }
public T this[int index] { get { if (index < 0) { throw new ArgumentOutOfRangeException(nameof(index)); } switch (_argumentType) { case PropertyType.Object | PropertyType.Nullable: var objectPtr = Handle.Value.GetObjectAtIndex(index); if (objectPtr == IntPtr.Zero) { throw new ArgumentOutOfRangeException(nameof(index)); } return(Operator.Convert <RealmObject, T>(Realm.MakeObject(Metadata, objectPtr))); case PropertyType.String: case PropertyType.String | PropertyType.Nullable: return(Operator.Convert <string, T>(Handle.Value.GetStringAtIndex(index))); case PropertyType.Data: case PropertyType.Data | PropertyType.Nullable: return(Operator.Convert <byte[], T>(Handle.Value.GetByteArrayAtIndex(index))); default: return(Handle.Value.GetPrimitiveAtIndex(index, _argumentType).Get <T>()); } } }
public T GetObject <T>(Realm realm, IntPtr propertyIndex, string objectType) where T : RealmObject { if (TryGetLink(propertyIndex, out var objectHandle)) { return((T)realm.MakeObject(realm.Metadata[objectType], objectHandle)); } return(null); }
public T GetObject <T>(Realm realm, IntPtr propertyIndex, string objectType) where T : RealmObject { var linkedObjectPtr = this.GetLink(propertyIndex); if (linkedObjectPtr == IntPtr.Zero) { return(null); } return((T)realm.MakeObject(objectType, linkedObjectPtr)); }
internal T this[int index] { get { if (index < 0) { throw new ArgumentOutOfRangeException(); } var objectPtr = ResultsHandle.GetObject(index); return((T)(object)_realm.MakeObject(_targetMetadata, objectPtr)); } }
public RealmValue GetValueAtIndex(int index, RealmObjectBase.Metadata metadata, Realm realm) { GetValueAtIndexCore((IntPtr)index, out var result, out var nativeException); nativeException.ThrowIfNecessary(); if (result.Type != RealmValueType.Object) { return(new RealmValue(result)); } var objectHandle = result.AsObject(Root); return(new RealmValue(realm.MakeObject(metadata, objectHandle))); }
protected RealmValue ToRealmValue(PrimitiveValue primitive, RealmObjectBase.Metadata metadata, Realm realm) { if (primitive.Type != RealmValueType.Object) { return(new RealmValue(primitive)); } var objectHandle = primitive.AsObject(Root); if (metadata == null) { throw new NotImplementedException("Mixed objects are not supported yet."); } return(new RealmValue(realm.MakeObject(metadata, objectHandle))); }
protected T GetObjectValue <T>(string propertyName) where T : RealmObject { Debug.Assert(IsManaged, "Object is not managed, but managed access was attempted"); var linkedObjectPtr = _objectHandle.GetLink(_metadata.PropertyIndices[propertyName]); if (linkedObjectPtr == IntPtr.Zero) { return(null); } Schema.Property property; _metadata.Schema.TryFindProperty(propertyName, out property); var objectType = property.ObjectType; return((T)_realm.MakeObject(objectType, linkedObjectPtr)); }
public RealmValue GetValue(string propertyName, RealmObjectBase.Metadata metadata, Realm realm) { var propertyIndex = metadata.PropertyIndices[propertyName]; NativeMethods.get_value(this, propertyIndex, out var result, out var nativeException); nativeException.ThrowIfNecessary(); if (result.Type != RealmValueType.Object) { return(new RealmValue(result, this, propertyIndex)); } var objectHandle = result.AsObject(Root); metadata.Schema.TryFindProperty(propertyName, out var property); return(new RealmValue(realm.MakeObject(realm.Metadata[property.ObjectType], objectHandle))); }
public T this[int index] { get { if (index < 0) { throw new ArgumentOutOfRangeException(); } var linkedObjectPtr = _listHandle.Get((IntPtr)index, _realm.SharedRealmHandle); return((T)_realm.MakeObject(_targetMetadata, linkedObjectPtr)); } set { throw new NotSupportedException("Setting items directly is not supported."); } }
public T this[int index] { get { if (index < 0) { throw new ArgumentOutOfRangeException(nameof(index)); } var objectPtr = Handle.Value.GetObjectAtIndex(index); if (objectPtr == IntPtr.Zero) { throw new ArgumentOutOfRangeException(nameof(index)); } return((T)(object)Realm.MakeObject(Metadata, objectPtr)); } }
/// <summary> /// Move the iterator to the next related object, starting "before" the first object. /// </summary> /// <remarks> /// Is a factory for RealmObjects, loading a new one and updating <c>Current</c>. /// </remarks> /// <returns>True only if can advance.</returns> public bool MoveNext() { if (_enumeratingResults == null) { return(false); } ++_index; var rowPtr = _enumeratingResults.GetObjectAtIndex(_index); if (rowPtr == IntPtr.Zero) { Current = (T)(object)null; return(false); } Current = (T)(object)_realm.MakeObject(_schema.Name, rowPtr); return(true); }
internal override Expression VisitMethodCall(MethodCallExpression m) { if (m.Method.DeclaringType == typeof(Queryable)) { if (m.Method.Name == nameof(Queryable.Where)) { Visit(m.Arguments[0]); var lambda = (LambdaExpression)StripQuotes(m.Arguments[1]); Visit(lambda.Body); return(m); } if (m.Method.Name == nameof(Queryable.OrderBy)) { Visit(m.Arguments[0]); AddSort((LambdaExpression)StripQuotes(m.Arguments[1]), true, true); return(m); } if (m.Method.Name == nameof(Queryable.OrderByDescending)) { Visit(m.Arguments[0]); AddSort((LambdaExpression)StripQuotes(m.Arguments[1]), true, false); return(m); } if (m.Method.Name == nameof(Queryable.ThenBy)) { Visit(m.Arguments[0]); AddSort((LambdaExpression)StripQuotes(m.Arguments[1]), false, true); return(m); } if (m.Method.Name == nameof(Queryable.ThenByDescending)) { Visit(m.Arguments[0]); AddSort((LambdaExpression)StripQuotes(m.Arguments[1]), false, false); return(m); } if (m.Method.Name == nameof(Queryable.Count)) { RecurseToWhereOrRunLambda(m); var foundCount = CoreQueryHandle.Count(); return(Expression.Constant(foundCount)); } if (m.Method.Name == nameof(Queryable.Any)) { RecurseToWhereOrRunLambda(m); var foundAny = CoreQueryHandle.FindDirect(_realm.SharedRealmHandle) != IntPtr.Zero; return(Expression.Constant(foundAny)); } if (m.Method.Name.StartsWith(nameof(Queryable.First))) { RecurseToWhereOrRunLambda(m); var firstObjectPtr = IntPtr.Zero; if (OptionalSortDescriptorBuilder == null) { firstObjectPtr = CoreQueryHandle.FindDirect(_realm.SharedRealmHandle); } else { using (ResultsHandle rh = _realm.MakeResultsForQuery(CoreQueryHandle, OptionalSortDescriptorBuilder)) { firstObjectPtr = rh.GetObjectAtIndex(0); } } if (firstObjectPtr != IntPtr.Zero) { return(Expression.Constant(_realm.MakeObject(_metadata, firstObjectPtr))); } if (m.Method.Name == nameof(Queryable.First)) { throw new InvalidOperationException("Sequence contains no matching element"); } Debug.Assert(m.Method.Name == nameof(Queryable.FirstOrDefault), $"The method {m.Method.Name} is not supported. We expected {nameof(Queryable.FirstOrDefault)}."); return(Expression.Constant(null)); } /* * // FIXME: See discussion in the test DefaultIfEmptyReturnsDefault * // kept because it shows part of what might be a viable implementation if can work out architectural issues * * if (m.Method.Name == nameof(Queryable.DefaultIfEmpty)) * { * RecurseToWhereOrRunLambda(m); * IntPtr firstObjectPtr = _coreQueryHandle.FindDirect(IntPtr.Zero); * if (firstObjectPtr != IntPtr.Zero) * return m; // as if just a "Where" * var innerType = m.Type.GetGenericArguments()[0]; * var listType = typeof(List<>).MakeGenericType(innerType); * var singleNullItemList = Activator.CreateInstance(listType); * ((IList)singleNullItemList).Add(null); * return Expression.Constant(singleNullItemList); * } */ if (m.Method.Name.StartsWith(nameof(Queryable.Single))) // same as unsorted First with extra checks { RecurseToWhereOrRunLambda(m); var firstObjectPtr = CoreQueryHandle.FindDirect(_realm.SharedRealmHandle); if (firstObjectPtr == IntPtr.Zero) { if (m.Method.Name == nameof(Queryable.Single)) { throw new InvalidOperationException("Sequence contains no matching element"); } Debug.Assert(m.Method.Name == nameof(Queryable.SingleOrDefault), $"The method {m.Method.Name} is not supported. We expected {nameof(Queryable.SingleOrDefault)}."); return(Expression.Constant(null)); } var firstObject = Realm.CreateObjectHandle(firstObjectPtr, _realm.SharedRealmHandle); var nextObjectPtr = CoreQueryHandle.FindNext(firstObject); if (nextObjectPtr != IntPtr.Zero) { throw new InvalidOperationException("Sequence contains more than one matching element"); } return(Expression.Constant(_realm.MakeObject(_metadata, firstObject))); } if (m.Method.Name.StartsWith(nameof(Queryable.Last))) { RecurseToWhereOrRunLambda(m); var lastObjectPtr = IntPtr.Zero; using (ResultsHandle rh = _realm.MakeResultsForQuery(CoreQueryHandle, OptionalSortDescriptorBuilder)) { var lastIndex = rh.Count() - 1; if (lastIndex >= 0) { lastObjectPtr = rh.GetObjectAtIndex(lastIndex); } } if (lastObjectPtr != IntPtr.Zero) { return(Expression.Constant(_realm.MakeObject(_metadata, lastObjectPtr))); } if (m.Method.Name == nameof(Queryable.Last)) { throw new InvalidOperationException("Sequence contains no matching element"); } Debug.Assert(m.Method.Name == nameof(Queryable.LastOrDefault), $"The method {m.Method.Name} is not supported. We expected {nameof(Queryable.LastOrDefault)}."); return(Expression.Constant(null)); } if (m.Method.Name.StartsWith(nameof(Queryable.ElementAt))) { Visit(m.Arguments.First()); object argument; if (!TryExtractConstantValue(m.Arguments.Last(), out argument) || argument.GetType() != typeof(int)) { throw new NotSupportedException($"The method '{m.Method}' has to be invoked with a single integer constant argument or closure variable"); } IntPtr objectPtr; var index = (int)argument; if (OptionalSortDescriptorBuilder == null) { objectPtr = CoreQueryHandle.FindDirect(_realm.SharedRealmHandle, (IntPtr)index); } else { using (var rh = _realm.MakeResultsForQuery(CoreQueryHandle, OptionalSortDescriptorBuilder)) { objectPtr = rh.GetObjectAtIndex(index); } } if (objectPtr != IntPtr.Zero) { var objectHandle = Realm.CreateObjectHandle(objectPtr, _realm.SharedRealmHandle); return(Expression.Constant(_realm.MakeObject(_metadata, objectHandle))); } if (m.Method.Name == nameof(Queryable.ElementAt)) { throw new ArgumentOutOfRangeException(); } Debug.Assert(m.Method.Name == nameof(Queryable.ElementAtOrDefault), $"The method {m.Method.Name} is not supported. We expected {nameof(Queryable.ElementAtOrDefault)}."); return(Expression.Constant(null)); } } if (m.Method.DeclaringType == typeof(string) || m.Method.DeclaringType == typeof(StringExtensions)) { QueryHandle.Operation <string> queryMethod = null; // For extension methods, member should be m.Arguments[0] as MemberExpression; MemberExpression member = null; // For extension methods, that should be 1 var stringArgumentIndex = 0; if (m.Method == Methods.String.Contains.Value) { queryMethod = (q, c, v) => q.StringContains(c, v, caseSensitive: true); } else if (m.Method == Methods.String.ContainsStringComparison.Value) { member = m.Arguments[0] as MemberExpression; stringArgumentIndex = 1; queryMethod = (q, c, v) => q.StringContains(c, v, GetComparisonCaseSensitive(m)); } else if (m.Method == Methods.String.StartsWith.Value) { queryMethod = (q, c, v) => q.StringStartsWith(c, v, caseSensitive: true); } else if (m.Method == Methods.String.StartsWithStringComparison.Value) { queryMethod = (q, c, v) => q.StringStartsWith(c, v, GetComparisonCaseSensitive(m)); } else if (m.Method == Methods.String.EndsWith.Value) { queryMethod = (q, c, v) => q.StringEndsWith(c, v, caseSensitive: true); } else if (m.Method == Methods.String.EndsWithStringComparison.Value) { queryMethod = (q, c, v) => q.StringEndsWith(c, v, GetComparisonCaseSensitive(m)); } else if (m.Method == Methods.String.IsNullOrEmpty.Value) { member = m.Arguments.SingleOrDefault() as MemberExpression; if (member == null) { throw new NotSupportedException($"The method '{m.Method}' has to be invoked with a RealmObject member"); } var columnIndex = CoreQueryHandle.GetColumnIndex(member.Member.Name); CoreQueryHandle.GroupBegin(); CoreQueryHandle.NullEqual(columnIndex); CoreQueryHandle.Or(); CoreQueryHandle.StringEqual(columnIndex, string.Empty, caseSensitive: true); CoreQueryHandle.GroupEnd(); return(m); } else if (m.Method == Methods.String.EqualsMethod.Value) { queryMethod = (q, c, v) => q.StringEqual(c, v, caseSensitive: true); } else if (m.Method == Methods.String.EqualsStringComparison.Value) { queryMethod = (q, c, v) => q.StringEqual(c, v, GetComparisonCaseSensitive(m)); } else if (m.Method == Methods.String.Like.Value) { member = m.Arguments[0] as MemberExpression; stringArgumentIndex = 1; object caseSensitive; if (!TryExtractConstantValue(m.Arguments.Last(), out caseSensitive) || !(caseSensitive is bool)) { throw new NotSupportedException($"The method '{m.Method}' has to be invoked with a string and boolean constant arguments."); } queryMethod = (q, c, v) => q.StringLike(c, v, (bool)caseSensitive); } if (queryMethod != null) { member = member ?? m.Object as MemberExpression; if (member == null) { throw new NotSupportedException($"The method '{m.Method}' has to be invoked on a RealmObject member"); } var columnIndex = CoreQueryHandle.GetColumnIndex(member.Member.Name); object argument; if (!TryExtractConstantValue(m.Arguments[stringArgumentIndex], out argument) || (argument != null && argument.GetType() != typeof(string))) { throw new NotSupportedException($"The method '{m.Method}' has to be invoked with a single string constant argument or closure variable"); } queryMethod(CoreQueryHandle, columnIndex, (string)argument); return(m); } } throw new NotSupportedException($"The method '{m.Method.Name}' is not supported"); }