GetColumnIndex() public method

public GetColumnIndex ( string columnName ) : IntPtr
columnName string
return System.IntPtr
コード例 #1
0
        private static void AddQueryNotEqual(QueryHandle queryHandle, string columnName, object value, Type columnType)
        {
            var columnIndex = queryHandle.GetColumnIndex(columnName);

            switch (value)
            {
            case null:
                queryHandle.NullNotEqual(columnIndex);
                break;

            case string stringValue:
                queryHandle.StringNotEqual(columnIndex, stringValue, caseSensitive: true);
                break;

            case bool boolValue:
                queryHandle.BoolNotEqual(columnIndex, boolValue);
                break;

            case DateTimeOffset date:
                queryHandle.TimestampTicksNotEqual(columnIndex, date);
                break;

            case byte[] buffer:
                if (buffer.Length == 0)
                {
                    // see RealmObject.SetByteArrayValue
                    queryHandle.BinaryNotEqual(columnIndex, (IntPtr)0x1, IntPtr.Zero);
                    return;
                }

                unsafe
                {
                    fixed(byte *bufferPtr = (byte[])value)
                    {
                        queryHandle.BinaryNotEqual(columnIndex, (IntPtr)bufferPtr, (IntPtr)buffer.LongCount());
                    }
                }
                break;

            case RealmObject obj:
                queryHandle.Not();
                queryHandle.ObjectEqual(columnIndex, obj.ObjectHandle);
                break;

            default:
                // The other types aren't handled by the switch because of potential compiler applied conversions
                AddQueryForConvertibleTypes(columnIndex, value, columnType, queryHandle.NumericNotEqualMethods);
                break;
            }
        }
コード例 #2
0
        private static void AddQueryGreaterThanOrEqual(QueryHandle queryHandle, string columnName, object value, Type columnType)
        {
            var columnIndex = queryHandle.GetColumnIndex(columnName);

            switch (value)
            {
            case DateTimeOffset date:
                queryHandle.TimestampTicksGreaterEqual(columnIndex, 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(columnIndex, value, columnType, queryHandle.NumericGreaterEqualMethods);
                break;
            }
        }
コード例 #3
0
        private static void AddQueryGreaterThanOrEqual(QueryHandle queryHandle, string columnName, object value)
        {
            var columnIndex = queryHandle.GetColumnIndex(columnName);

            if (value is char)
            {
                queryHandle.IntGreaterEqual(columnIndex, (int)value);
            }
            else if (value is int)
            {
                queryHandle.IntGreaterEqual(columnIndex, (int)value);
            }
            else if (value is long)
            {
                queryHandle.LongGreaterEqual(columnIndex, (long)value);
            }
            else if (value is float)
            {
                queryHandle.FloatGreaterEqual(columnIndex, (float)value);
            }
            else if (value is double)
            {
                queryHandle.DoubleGreaterEqual(columnIndex, (double)value);
            }
            else if (value is DateTimeOffset)
            {
                queryHandle.TimestampTicksGreaterEqual(columnIndex, (DateTimeOffset)value);
            }
            else if (value is string || value is bool)
            {
                throw new Exception($"Unsupported type {value.GetType().Name}");
            }
            else
            {
                throw new NotImplementedException();
            }
        }
コード例 #4
0
        private static void AddQueryNotEqual(QueryHandle queryHandle, string columnName, object value)
        {
            var columnIndex = queryHandle.GetColumnIndex(columnName);

            if (value == null)
            {
                queryHandle.NullNotEqual(columnIndex);
            }
            else if (value is string)
            {
                queryHandle.StringNotEqual(columnIndex, (string)value, caseSensitive: true);
            }
            else if (value is bool)
            {
                queryHandle.BoolNotEqual(columnIndex, (bool)value);
            }
            else if (value is char)
            {
                queryHandle.IntNotEqual(columnIndex, (int)value);
            }
            else if (value is int)
            {
                queryHandle.IntNotEqual(columnIndex, (int)value);
            }
            else if (value is long)
            {
                queryHandle.LongNotEqual(columnIndex, (long)value);
            }
            else if (value is float)
            {
                queryHandle.FloatNotEqual(columnIndex, (float)value);
            }
            else if (value is double)
            {
                queryHandle.DoubleNotEqual(columnIndex, (double)value);
            }
            else if (value is DateTimeOffset)
            {
                queryHandle.TimestampTicksNotEqual(columnIndex, (DateTimeOffset)value);
            }
            else if (value is byte[])
            {
                var buffer = (byte[])value;
                if (buffer.Length == 0)
                {
                    // see RealmObject.SetByteArrayValue
                    queryHandle.BinaryNotEqual(columnIndex, (IntPtr)0x1, IntPtr.Zero);
                    return;
                }

                unsafe
                {
                    fixed(byte *bufferPtr = (byte[])value)
                    {
                        queryHandle.BinaryNotEqual(columnIndex, (IntPtr)bufferPtr, (IntPtr)buffer.LongCount());
                    }
                }
            }
            else if (value is RealmObject)
            {
                queryHandle.Not();
                queryHandle.ObjectEqual(columnIndex, ((RealmObject)value).ObjectHandle);
            }
            else
            {
                throw new NotImplementedException();
            }
        }
コード例 #5
0
        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");
        }
コード例 #6
0
        private static void AddQueryEqual(QueryHandle queryHandle, string columnName, object value)
        {
            var columnIndex = queryHandle.GetColumnIndex(columnName);

            if (value == null)
            {
                queryHandle.NullEqual(columnIndex);
            }
            else if (value is string)
            {
                queryHandle.StringEqual(columnIndex, (string)value);
            }
            else if (value is bool)
            {
                queryHandle.BoolEqual(columnIndex, (bool)value);
            }
            else if (value is char)
            {
                queryHandle.IntEqual(columnIndex, (int)value);
            }
            else if (value is int)
            {
                queryHandle.IntEqual(columnIndex, (int)value);
            }
            else if (value is long)
            {
                queryHandle.LongEqual(columnIndex, (long)value);
            }
            else if (value is float)
            {
                queryHandle.FloatEqual(columnIndex, (float)value);
            }
            else if (value is double)
            {
                queryHandle.DoubleEqual(columnIndex, (double)value);
            }
            else if (value is DateTimeOffset)
            {
                queryHandle.TimestampTicksEqual(columnIndex, (DateTimeOffset)value);
            }
            else if (value.GetType() == typeof(byte[]))
            {
                var buffer = (byte[])value;
                if (buffer.Length == 0)
                {
                    // see RealmObject.SetByteArrayValue
                    queryHandle.BinaryEqual(columnIndex, (IntPtr)0x1, IntPtr.Zero);
                    return;
                }

                unsafe
                {
                    fixed(byte *bufferPtr = (byte[])value)
                    {
                        queryHandle.BinaryEqual(columnIndex, (IntPtr)bufferPtr, (IntPtr)buffer.LongLength);
                    }
                }
            }
            else
            {
                throw new NotImplementedException();
            }
        }
コード例 #7
0
        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");
        }
コード例 #8
0
        private static void AddQueryGreaterThan(QueryHandle queryHandle, string columnName, object value)
        {
            var columnIndex = queryHandle.GetColumnIndex(columnName);

            switch (value)
            {
            case char charValue:
                queryHandle.IntGreater(columnIndex, charValue);
                break;

            case byte byteValue:
                queryHandle.IntGreater(columnIndex, byteValue);
                break;

            case short shortValue:
                queryHandle.IntGreater(columnIndex, shortValue);
                break;

            case int intValue:
                queryHandle.IntGreater(columnIndex, intValue);
                break;

            case long longValue:
                queryHandle.LongGreater(columnIndex, longValue);
                break;

            case float floatValue:
                queryHandle.FloatGreater(columnIndex, floatValue);
                break;

            case double doubleValue:
                queryHandle.DoubleGreater(columnIndex, doubleValue);
                break;

            case DateTimeOffset date:
                queryHandle.TimestampTicksGreater(columnIndex, date);
                break;

            case string _:
            case bool _:
                throw new Exception($"Unsupported type {value.GetType().Name}");

            case RealmInteger <byte> byteValue:
                queryHandle.IntGreater(columnIndex, byteValue);
                break;

            case RealmInteger <short> shortValue:
                queryHandle.IntGreater(columnIndex, shortValue);
                break;

            case RealmInteger <int> intValue:
                queryHandle.IntGreater(columnIndex, intValue);
                break;

            case RealmInteger <long> longValue:
                queryHandle.LongGreater(columnIndex, longValue);
                break;

            default:
                throw new NotImplementedException();
            }
        }
コード例 #9
0
        private static void AddQueryNotEqual(QueryHandle queryHandle, string columnName, object value)
        {
            var columnIndex = queryHandle.GetColumnIndex(columnName);

            switch (value)
            {
            case null:
                queryHandle.NullNotEqual(columnIndex);
                break;

            case string stringValue:
                queryHandle.StringNotEqual(columnIndex, stringValue, caseSensitive: true);
                break;

            case bool boolValue:
                queryHandle.BoolNotEqual(columnIndex, boolValue);
                break;

            case char charValue:
                queryHandle.IntNotEqual(columnIndex, charValue);
                break;

            case byte byteValue:
                queryHandle.IntNotEqual(columnIndex, byteValue);
                break;

            case short shortValue:
                queryHandle.IntNotEqual(columnIndex, shortValue);
                break;

            case int intValue:
                queryHandle.IntNotEqual(columnIndex, intValue);
                break;

            case long longValue:
                queryHandle.LongNotEqual(columnIndex, longValue);
                break;

            case float floatValue:
                queryHandle.FloatNotEqual(columnIndex, floatValue);
                break;

            case double doubleValue:
                queryHandle.DoubleNotEqual(columnIndex, doubleValue);
                break;

            case DateTimeOffset date:
                queryHandle.TimestampTicksNotEqual(columnIndex, date);
                break;

            case byte[] buffer:
                if (buffer.Length == 0)
                {
                    // see RealmObject.SetByteArrayValue
                    queryHandle.BinaryNotEqual(columnIndex, (IntPtr)0x1, IntPtr.Zero);
                    return;
                }

                unsafe
                {
                    fixed(byte *bufferPtr = (byte[])value)
                    {
                        queryHandle.BinaryNotEqual(columnIndex, (IntPtr)bufferPtr, (IntPtr)buffer.LongCount());
                    }
                }
                break;

            case RealmObject obj:
                queryHandle.Not();
                queryHandle.ObjectEqual(columnIndex, obj.ObjectHandle);
                break;

            case RealmInteger <byte> byteValue:
                queryHandle.IntNotEqual(columnIndex, byteValue);
                break;

            case RealmInteger <short> shortValue:
                queryHandle.IntNotEqual(columnIndex, shortValue);
                break;

            case RealmInteger <int> intValue:
                queryHandle.IntNotEqual(columnIndex, intValue);
                break;

            case RealmInteger <long> longValue:
                queryHandle.LongNotEqual(columnIndex, longValue);
                break;

            default:
                throw new NotImplementedException();
            }
        }