public IEnumerable <TRecord> GetPreviousExtended(KeyValue keyValue, FilterAnd filter, bool skipCurrentPosition = true, int limit = 0, LockBias lockBias = LockBias.None, ushort rejectCount = 0, bool overwrite = false) { if (keyValue == null) { throw new ArgumentNullException(); } return(this.OperateExtended(Operation.GetPreviousExtended, keyValue, filter, skipCurrentPosition, limit, lockBias, rejectCount, overwrite)); }
IEnumerable <TRecord> OperateExtended(Operation operation, KeyValue keyValue, FilterAnd filter, bool skipCurrentPosition, int limit, LockBias lockBias, ushort rejectCount, bool overwrite = false) { if (_positionBlock == null) { throw new InvalidOperationException(); } if (filter != null && !filter.Check(this.RecordInfo)) { throw new ArgumentException(); } if (keyValue != null && !overwrite) { keyValue = keyValue.DeepCopy(); } var useLimit = limit > 0; rejectCount = rejectCount == 0 ? this.RecordInfo.RejectCount : rejectCount; var isFirst = true; var bufferLength = Config.MaxBufferLength - Config.ExtendedOperationBufferMargin; for (; ;) { var dataBufferLength = (ushort)(filter == null ? 16 : filter.Length + 16); Array.Copy(BitConverter.GetBytes(dataBufferLength), 0, this.TemporaryBuffer, 0, 2); Array.Copy(Encoding.ASCII.GetBytes(!isFirst || skipCurrentPosition ? "EG" : "UC"), 0, this.TemporaryBuffer, 2, 2); isFirst = false; skipCurrentPosition = true; Array.Copy(BitConverter.GetBytes(rejectCount), 0, this.TemporaryBuffer, 4, 2); Array.Copy(BitConverter.GetBytes(filter == null ? 0 : filter.Count), 0, this.TemporaryBuffer, 6, 2); if (filter != null) { filter.SetDataBuffer(this.TemporaryBuffer); } var position = (ushort)(filter == null ? 8 : filter.Length + 8); var count = (ushort)(bufferLength / (this.RecordInfo.DataBufferCapacity + 6)); if (useLimit && count > limit) { count = (ushort)limit; } if (count == 0) { throw new InvalidOperationException(); } Array.Copy(BitConverter.GetBytes(count), 0, this.TemporaryBuffer, position, 2); position += 2; Array.Copy(BitConverter.GetBytes((ushort)(1)), 0, this.TemporaryBuffer, position, 2); position += 2; Array.Copy(BitConverter.GetBytes(this.RecordInfo.DataBufferCapacity), 0, this.TemporaryBuffer, position, 2); position += 2; Array.Copy(BitConverter.GetBytes((ushort)(0)), 0, this.TemporaryBuffer, position, 2); var isBreak = false; try { if (keyValue == null) { _nativeOperator.Operate(operation, _positionBlock, this.TemporaryBuffer, null, (sbyte)0, (ushort)lockBias); } else { _nativeOperator.Operate(operation, _positionBlock, this.TemporaryBuffer, keyValue.KeyBuffer, keyValue.Key.KeyNumber, (ushort)lockBias); } } catch (OperationException e) { if (e.StatusCode == 9 || e.StatusCode == 64) { isBreak = true; } else if (e.StatusCode != 60) { throw; } } if (keyValue != null) { keyValue.ComplementCount = 0; } count = BitConverter.ToUInt16(this.TemporaryBuffer, 0); position = 2; ushort length; TRecord record; for (var i = 0; i < count; i++) { length = BitConverter.ToUInt16(this.TemporaryBuffer, position); record = this.CreateRecord(); Array.Copy(this.TemporaryBuffer, position + 6, record.DataBuffer, 0, this.RecordInfo.DataBufferCapacity); record.HasPhysicalPosition = true; record.PhysicalPosition = BitConverter.ToUInt32(this.TemporaryBuffer, position + 2); yield return(record); position += (ushort)(length + 6); } if (isBreak) { yield break; } if (useLimit) { limit -= count; if (limit <= 0) { yield break; } } } }
public IEnumerable <TRecord> StepPreviousExtended(FilterAnd filter, bool skipCurrentPosition = true, int limit = 0, LockBias lockBias = LockBias.None, ushort rejectCount = 0) { return(this.OperateExtended(Operation.StepPreviousExtended, null, filter, skipCurrentPosition, limit, lockBias, rejectCount)); }
public ExpressionParser(Expression body, ParameterExpression argument, bool isIgnoreCase) { _argument = argument; this.Expressions = new List <Expression>(); FilterAnd filterAnd = new FilterAnd(); var map = body.ToFilterExpressionMap(); for (var i = 0; i < map.Length; i++) { var filters = map[i].Select(f => new ExpressionFilter(f, argument)).ToArray(); if (filters.Any(f => f.ComparisonType == FilterComparison.NotComparable) || filters.Any(ef => ef.Fields.Any(f => !f.IsFilterable))) { this.Expressions.Add(map[i].ToOrExpression()); } else { var isNotComparable = false; var filterOr = new FilterOr(); foreach (var filter in filters) { switch (filter.ComparisonType) { case FilterComparison.ToConstant: if (filter.Left.NullType == NullType.Nullable) { var isNull = filter.Value == null; switch (filter.FilterType) { case FilterType.Equal: if (isNull) { filterOr.Add(filter.Left.NullFlagField, FilterType.Equal, true); } else { if (map[i].Length == 1) { filterAnd.Add(new FilterOr().Add(filter.Left.NullFlagField, FilterType.Equal, false)); filterOr.Add(filter.Left, FilterType.Equal, filter.Value, isIgnoreCase: isIgnoreCase); } else if (filterOr.FilterAnd == null) { filterOr.FilterAnd = new FilterAnd() .Add(new FilterOr().Add(filter.Left.NullFlagField, FilterType.Equal, false)) .Add(new FilterOr().Add(filter.Left, FilterType.Equal, filter.Value, isIgnoreCase: isIgnoreCase)); } else { isNotComparable = true; } } break; case FilterType.NotEqual: if (isNull) { filterOr.Add(filter.Left.NullFlagField, FilterType.Equal, false); } else { filterOr .Add(filter.Left.NullFlagField, FilterType.Equal, false) .Add(filter.Left, FilterType.NotEqual, filter.Value, isIgnoreCase: isIgnoreCase); } break; case FilterType.GreaterThan: case FilterType.GreaterThanOrEqual: case FilterType.LessThan: case FilterType.LessThanOrEqual: if (map[i].Length == 1) { filterAnd.Add(new FilterOr().Add(filter.Left.NullFlagField, FilterType.Equal, false)); filterOr.Add(filter.Left, filter.FilterType, filter.Value, isIgnoreCase: isIgnoreCase); } else if (filterOr.FilterAnd == null) { filterOr.FilterAnd = new FilterAnd() .Add(new FilterOr().Add(filter.Left.NullFlagField, FilterType.Equal, false)) .Add(new FilterOr().Add(filter.Left, filter.FilterType, filter.Value, isIgnoreCase: isIgnoreCase)); } else { isNotComparable = true; } break; default: throw new NotSupportedException(); } } else { filterOr.Add(filter.Left, filter.FilterType, filter.Value, isIgnoreCase: isIgnoreCase); } break; case FilterComparison.ToField: var leftNullable = filter.Left.NullType == NullType.Nullable; var rightNullable = filter.Right.NullType == NullType.Nullable; if (leftNullable) { switch (filter.FilterType) { case FilterType.Equal: if (map[i].Length == 1) { filterAnd.Add(new FilterOr().Add(filter.Left.NullFlagField, FilterType.Equal, rightNullable ? (object)filter.Right.NullFlagField : (object)true)); filterOr.Add(filter.Left, FilterType.Equal, filter.Right, isIgnoreCase: isIgnoreCase); } else if (filterOr.FilterAnd == null) { filterOr.FilterAnd = new FilterAnd() .Add(new FilterOr().Add(filter.Left.NullFlagField, FilterType.Equal, rightNullable ? (object)filter.Right.NullFlagField : (object)true)) .Add(new FilterOr().Add(filter.Left, FilterType.Equal, filter.Right, isIgnoreCase: isIgnoreCase)); } else { isNotComparable = true; } break; case FilterType.NotEqual: if (rightNullable) { filterOr .Add(filter.Left.NullFlagField, FilterType.NotEqual, filter.Right.NullFlagField) .Add(filter.Left, FilterType.NotEqual, filter.Right, isIgnoreCase: isIgnoreCase); } else { filterOr .Add(filter.Left.NullFlagField, FilterType.Equal, false) .Add(filter.Left, FilterType.NotEqual, filter.Right, isIgnoreCase: isIgnoreCase); } break; case FilterType.GreaterThan: case FilterType.GreaterThanOrEqual: case FilterType.LessThan: case FilterType.LessThanOrEqual: if (map[i].Length == 1) { filterAnd.Add(new FilterOr().Add(filter.Left.NullFlagField, FilterType.Equal, true)); if (rightNullable) { filterAnd.Add(new FilterOr().Add(filter.Right.NullFlagField, FilterType.Equal, true)); } filterOr.Add(filter.Left, filter.FilterType, filter.Right, isIgnoreCase: isIgnoreCase); } else if (filterOr.FilterAnd == null) { filterOr.FilterAnd = new FilterAnd() .Add(new FilterOr().Add(filter.Left.NullFlagField, FilterType.Equal, true)); if (rightNullable) { filterOr.FilterAnd .Add(new FilterOr().Add(filter.Right.NullFlagField, FilterType.Equal, true)); } filterOr.FilterAnd .Add(new FilterOr().Add(filter.Left, filter.FilterType, filter.Value, isIgnoreCase: isIgnoreCase)); } else { isNotComparable = true; } break; default: throw new NotSupportedException(); } } else { filterOr.Add(filter.Left, filter.FilterType, filter.Right, isIgnoreCase: isIgnoreCase); } break; default: throw new NotSupportedException(); } if (isNotComparable) { break; } } if (isNotComparable) { this.Expressions.Add(map[i].ToOrExpression()); } else { if (filterOr.Count != 0 || filterOr.FilterAnd != null) { filterAnd.Add(filterOr); } } } } this.Filter = filterAnd; }