internal T this[int index] { get { var row = NativeResults.get_row(ResultsHandle, (IntPtr)index); var rowHandle = Realm.CreateRowHandle(row, _realm.SharedRealmHandle); return((T)(object)_realm.MakeObjectForRow(typeof(T), rowHandle)); } }
public static T GetObject <T>(Realm realm, TableHandle table, IntPtr columnIndex, IntPtr rowIndex, string objectType) where T : RealmObject { var linkedRowPtr = NativeTable.GetLink(table, columnIndex, rowIndex); if (linkedRowPtr == IntPtr.Zero) { return(null); } return((T)realm.MakeObjectForRow(objectType, linkedRowPtr)); }
internal T this[int index] { get { if (index < 0) { throw new ArgumentOutOfRangeException(); } var rowPtr = ResultsHandle.GetRow(index); return((T)(object)_realm.MakeObjectForRow(_targetMetadata, rowPtr)); } }
public T this[int index] { get { if (index < 0) { throw new ArgumentOutOfRangeException(); } var linkedRowPtr = _listHandle.Get((IntPtr)index); return((T)_realm.MakeObjectForRow(_targetMetadata, linkedRowPtr)); } set { throw new NotImplementedException(); } }
protected T GetObjectValue <T>(string propertyName) where T : RealmObject { Debug.Assert(_realm != null, "Object is not managed, but managed access was attempted"); var rowIndex = _rowHandle.RowIndex; var linkedRowPtr = NativeTable.GetLink(_metadata.Table, _metadata.ColumnIndices[propertyName], rowIndex); if (linkedRowPtr == IntPtr.Zero) { return(null); } Schema.Property property; _metadata.Schema.TryFindProperty(propertyName, out property); var objectType = property.ObjectType; return((T)_realm.MakeObjectForRow(objectType, linkedRowPtr)); }
/// <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.GetRow(_index); if (rowPtr == IntPtr.Zero) { Current = (T)(object)null; return(false); } Current = (T)(object)_realm.MakeObjectForRow(_schema.Name, rowPtr); return(true); }
/// <summary> /// Move the iterator to the next related object, starting "before" the first object. /// </summary> /// <returns>True only if can advance.</returns> public bool MoveNext() { if (_enumeratingResults == null) { return(false); } ++_index; var rowPtr = NativeResults.get_row(_enumeratingResults, (IntPtr)_index); var rowHandle = Realm.CreateRowHandle(rowPtr, _realm.SharedRealmHandle); object nextObj = null; if (!rowHandle.IsInvalid) { nextObj = _realm.MakeObjectForRow(_retType, rowHandle); } Current = (T)nextObj; return(nextObj != null); }
internal override Expression VisitMethodCall(MethodCallExpression m) { if (m.Method.DeclaringType == typeof(Queryable)) { if (m.Method.Name == nameof(Queryable.Where)) { this.Visit(m.Arguments[0]); LambdaExpression lambda = (LambdaExpression)StripQuotes(m.Arguments[1]); this.Visit(lambda.Body); return(m); } if (m.Method.Name == nameof(Queryable.OrderBy)) { this.Visit(m.Arguments[0]); AddSort((LambdaExpression)StripQuotes(m.Arguments[1]), true, true); return(m); } if (m.Method.Name == nameof(Queryable.OrderByDescending)) { this.Visit(m.Arguments[0]); AddSort((LambdaExpression)StripQuotes(m.Arguments[1]), true, false); return(m); } if (m.Method.Name == nameof(Queryable.ThenBy)) { this.Visit(m.Arguments[0]); AddSort((LambdaExpression)StripQuotes(m.Arguments[1]), false, true); return(m); } if (m.Method.Name == nameof(Queryable.ThenByDescending)) { this.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); bool foundAny = _coreQueryHandle.FindDirect(IntPtr.Zero) != IntPtr.Zero; return(Expression.Constant(foundAny)); } if (m.Method.Name.StartsWith(nameof(Queryable.First))) { RecurseToWhereOrRunLambda(m); IntPtr firstRowPtr = IntPtr.Zero; if (OptionalSortDescriptorBuilder == null) { firstRowPtr = _coreQueryHandle.FindDirect(IntPtr.Zero); } else { using (ResultsHandle rh = _realm.MakeResultsForQuery(_coreQueryHandle, OptionalSortDescriptorBuilder)) { firstRowPtr = rh.GetRow(0); } } if (firstRowPtr != IntPtr.Zero) { return(Expression.Constant(_realm.MakeObjectForRow(_metadata, firstRowPtr))); } if (m.Method.Name == nameof(Queryable.First)) { throw new InvalidOperationException("Sequence contains no matching element"); } Debug.Assert(m.Method.Name == 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 firstRowPtr = _coreQueryHandle.FindDirect(IntPtr.Zero); * if (firstRowPtr != 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 firstRowPtr = _coreQueryHandle.FindDirect(IntPtr.Zero); if (firstRowPtr == 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)); return(Expression.Constant(null)); } var firstRow = Realm.CreateRowHandle(firstRowPtr, _realm.SharedRealmHandle); IntPtr nextIndex = (IntPtr)(firstRow.RowIndex + 1); var nextRowPtr = _coreQueryHandle.FindDirect(nextIndex); if (nextRowPtr != IntPtr.Zero) { throw new InvalidOperationException("Sequence contains more than one matching element"); } return(Expression.Constant(_realm.MakeObjectForRow(_metadata, firstRow))); } if (m.Method.Name.StartsWith(nameof(Queryable.Last))) { RecurseToWhereOrRunLambda(m); var lastRowPtr = IntPtr.Zero; using (ResultsHandle rh = _realm.MakeResultsForQuery(_coreQueryHandle, OptionalSortDescriptorBuilder)) { var lastIndex = rh.Count() - 1; if (lastIndex >= 0) { lastRowPtr = rh.GetRow(lastIndex); } } if (lastRowPtr != IntPtr.Zero) { return(Expression.Constant(_realm.MakeObjectForRow(_metadata, lastRowPtr))); } if (m.Method.Name == nameof(Queryable.Last)) { throw new InvalidOperationException("Sequence contains no matching element"); } Debug.Assert(m.Method.Name == nameof(Queryable.LastOrDefault)); return(Expression.Constant(null)); } if (m.Method.Name.StartsWith(nameof(Queryable.ElementAt))) { var row = VisitElementAt(m); if (row == null || row.IsInvalid) { if (m.Method.Name == nameof(Queryable.ElementAt)) { throw new ArgumentOutOfRangeException(); } Debug.Assert(m.Method.Name == nameof(Queryable.ElementAtOrDefault)); return(Expression.Constant(null)); } return(Expression.Constant(_realm.MakeObjectForRow(_metadata, row))); } } if (m.Method.DeclaringType == typeof(string)) { QueryHandle.Operation <string> queryMethod = null; if (m.Method == Methods.String.Contains.Value) { queryMethod = (q, c, v) => q.StringContains(c, v); } else if (m.Method == Methods.String.StartsWith.Value) { queryMethod = (q, c, v) => q.StringStartsWith(c, v); } else if (m.Method == Methods.String.EndsWith.Value) { queryMethod = (q, c, v) => q.StringEndsWith(c, v); } else if (m.Method == Methods.String.IsNullOrEmpty.Value) { var 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); _coreQueryHandle.GroupEnd(); return(m); } if (queryMethod != null) { var 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.SingleOrDefault(), out argument) || 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"); }
internal override Expression VisitMethodCall(MethodCallExpression m) { if (m.Method.DeclaringType == typeof(Queryable)) { if (m.Method.Name == "Where") { this.Visit(m.Arguments[0]); LambdaExpression lambda = (LambdaExpression)StripQuotes(m.Arguments[1]); this.Visit(lambda.Body); return(m); } if (m.Method.Name == "OrderBy") { this.Visit(m.Arguments[0]); AddSort((LambdaExpression)StripQuotes(m.Arguments[1]), true, true); return(m); } if (m.Method.Name == "OrderByDescending") { this.Visit(m.Arguments[0]); AddSort((LambdaExpression)StripQuotes(m.Arguments[1]), true, false); return(m); } if (m.Method.Name == "ThenBy") { this.Visit(m.Arguments[0]); AddSort((LambdaExpression)StripQuotes(m.Arguments[1]), false, true); return(m); } if (m.Method.Name == "ThenByDescending") { this.Visit(m.Arguments[0]); AddSort((LambdaExpression)StripQuotes(m.Arguments[1]), false, false); return(m); } if (m.Method.Name == "Count") { RecurseToWhereOrRunLambda(m); int foundCount = (int)NativeQuery.count(_coreQueryHandle); return(Expression.Constant(foundCount)); } if (m.Method.Name == "Any") { RecurseToWhereOrRunLambda(m); var rowPtr = NativeQuery.findDirect(_coreQueryHandle, IntPtr.Zero); var firstRow = Realm.CreateRowHandle(rowPtr, _realm.SharedRealmHandle); bool foundAny = !firstRow.IsInvalid; return(Expression.Constant(foundAny)); } if (m.Method.Name == "First") { RecurseToWhereOrRunLambda(m); RowHandle firstRow = null; if (_optionalSortOrderHandle == null) { var rowPtr = NativeQuery.findDirect(_coreQueryHandle, IntPtr.Zero); firstRow = Realm.CreateRowHandle(rowPtr, _realm.SharedRealmHandle); } else { using (ResultsHandle rh = _realm.MakeResultsForQuery(_retType, _coreQueryHandle, _optionalSortOrderHandle)) { var rowPtr = NativeResults.get_row(rh, IntPtr.Zero); firstRow = Realm.CreateRowHandle(rowPtr, _realm.SharedRealmHandle); } } if (firstRow == null || firstRow.IsInvalid) { throw new InvalidOperationException("Sequence contains no matching element"); } return(Expression.Constant(_realm.MakeObjectForRow(_retType, firstRow))); } if (m.Method.Name == "Single") // same as unsorted First with extra checks { RecurseToWhereOrRunLambda(m); var rowPtr = NativeQuery.findDirect(_coreQueryHandle, IntPtr.Zero); var firstRow = Realm.CreateRowHandle(rowPtr, _realm.SharedRealmHandle); if (firstRow.IsInvalid) { throw new InvalidOperationException("Sequence contains no matching element"); } IntPtr nextIndex = (IntPtr)(firstRow.RowIndex + 1); var nextRowPtr = NativeQuery.findDirect(_coreQueryHandle, nextIndex); var nextRow = Realm.CreateRowHandle(nextRowPtr, _realm.SharedRealmHandle); if (!nextRow.IsInvalid) { throw new InvalidOperationException("Sequence contains more than one matching element"); } return(Expression.Constant(_realm.MakeObjectForRow(_retType, firstRow))); } } if (m.Method.DeclaringType == typeof(string)) { NativeQuery.Operation <string> queryMethod = null; if (m.Method == Methods.String.Contains.Value) { queryMethod = (q, c, v) => NativeQuery.string_contains(q, c, v, (IntPtr)v.Length); } else if (m.Method == Methods.String.StartsWith.Value) { queryMethod = (q, c, v) => NativeQuery.string_starts_with(q, c, v, (IntPtr)v.Length); } else if (m.Method == Methods.String.EndsWith.Value) { queryMethod = (q, c, v) => NativeQuery.string_ends_with(q, c, v, (IntPtr)v.Length); } if (queryMethod != null) { var 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 = NativeQuery.get_column_index(_coreQueryHandle, member.Member.Name, (IntPtr)member.Member.Name.Length); var argument = ExtractConstantValue(m.Arguments.SingleOrDefault()); if (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"); }