private static void AddQueryGreaterThanOrEqual(QueryHandle queryHandle, string columnName, object value) { var columnIndex = NativeQuery.get_column_index((QueryHandle)queryHandle, columnName, (IntPtr)columnName.Length); var valueType = value.GetType(); if (valueType == typeof(int)) { NativeQuery.int_greater_equal((QueryHandle)queryHandle, columnIndex, (IntPtr)((int)value)); } else if (valueType == typeof(float)) { NativeQuery.float_greater_equal((QueryHandle)queryHandle, columnIndex, (float)value); } else if (valueType == typeof(double)) { NativeQuery.double_greater_equal((QueryHandle)queryHandle, columnIndex, (double)value); } else if (valueType == typeof(DateTimeOffset)) { NativeQuery.datetime_seconds_greater_equal(queryHandle, columnIndex, ((DateTimeOffset)value).ToUnixTimeSeconds()); } else if (valueType == typeof(string) || valueType == typeof(bool)) { throw new Exception("Unsupported type " + valueType.Name); } else { throw new NotImplementedException(); } }
private static void AddQueryLessThan(QueryHandle queryHandle, string columnName, object value) { var columnIndex = NativeQuery.get_column_index((QueryHandle)queryHandle, columnName, (IntPtr)columnName.Length); var valueType = value.GetType(); if (valueType == typeof(int)) { NativeQuery.int_less((QueryHandle)queryHandle, columnIndex, (IntPtr)((int)value)); } else if (valueType == typeof(long)) { NativeQuery.long_less((QueryHandle)queryHandle, columnIndex, (long)value); } else if (valueType == typeof(float)) { NativeQuery.float_less((QueryHandle)queryHandle, columnIndex, (float)value); } else if (valueType == typeof(double)) { NativeQuery.double_less((QueryHandle)queryHandle, columnIndex, (double)value); } else if (valueType == typeof(DateTimeOffset)) { NativeQuery.timestamp_milliseconds_less(queryHandle, columnIndex, ((DateTimeOffset)value).ToRealmUnixTimeMilliseconds()); } else if (valueType == typeof(string) || valueType == typeof(bool)) { throw new Exception("Unsupported type " + valueType.Name); } else { throw new NotImplementedException(); } }
private static void AddQueryNotEqual(QueryHandle queryHandle, string columnName, object value) { var columnIndex = NativeQuery.get_column_index((QueryHandle)queryHandle, columnName, (IntPtr)columnName.Length); var valueType = value.GetType(); if (value.GetType() == typeof(string)) { string valueStr = (string)value; NativeQuery.string_not_equal((QueryHandle)queryHandle, columnIndex, valueStr, (IntPtr)valueStr.Length); } else if (valueType == typeof(bool)) { NativeQuery.bool_not_equal((QueryHandle)queryHandle, columnIndex, MarshalHelpers.BoolToIntPtr((bool)value)); } else if (valueType == typeof(int)) { NativeQuery.int_not_equal((QueryHandle)queryHandle, columnIndex, (IntPtr)((int)value)); } else if (valueType == typeof(long)) { NativeQuery.long_not_equal((QueryHandle)queryHandle, columnIndex, (long)value); } else if (valueType == typeof(float)) { NativeQuery.float_not_equal((QueryHandle)queryHandle, columnIndex, (float)value); } else if (valueType == typeof(double)) { NativeQuery.double_not_equal((QueryHandle)queryHandle, columnIndex, (double)value); } else if (valueType == typeof(DateTimeOffset)) { NativeQuery.timestamp_milliseconds_not_equal(queryHandle, columnIndex, ((DateTimeOffset)value).ToRealmUnixTimeMilliseconds()); } else if (valueType == typeof(byte[])) { var buffer = (byte[])value; if (buffer.Length == 0) { // see RealmObject.SetByteArrayValue NativeQuery.binary_not_equal(queryHandle, columnIndex, (IntPtr)0x1, IntPtr.Zero); return; } unsafe { fixed(byte *bufferPtr = (byte[])value) { NativeQuery.binary_not_equal(queryHandle, columnIndex, (IntPtr)bufferPtr, (IntPtr)buffer.LongLength); } } } else { throw new NotImplementedException(); } }
private static void AddQueryNotEqual(QueryHandle queryHandle, string columnName, object value) { var columnIndex = NativeQuery.get_column_index((QueryHandle)queryHandle, columnName, (IntPtr)columnName.Length); var valueType = value.GetType(); if (value.GetType() == typeof(string)) { string valueStr = (string)value; NativeQuery.string_not_equal((QueryHandle)queryHandle, columnIndex, valueStr, (IntPtr)valueStr.Length); } else if (valueType == typeof(bool)) { NativeQuery.bool_not_equal((QueryHandle)queryHandle, columnIndex, MarshalHelpers.BoolToIntPtr((bool)value)); } else if (valueType == typeof(int)) { NativeQuery.int_not_equal((QueryHandle)queryHandle, columnIndex, (IntPtr)((int)value)); } else if (valueType == typeof(float)) { NativeQuery.float_not_equal((QueryHandle)queryHandle, columnIndex, (float)value); } else if (valueType == typeof(double)) { NativeQuery.double_not_equal((QueryHandle)queryHandle, columnIndex, (double)value); } else if (valueType == typeof(DateTimeOffset)) { NativeQuery.datetime_seconds_not_equal(queryHandle, columnIndex, ((DateTimeOffset)value).ToUnixTimeSeconds()); } else { throw new NotImplementedException(); } }
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"); }