예제 #1
0
 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));
 }
예제 #2
0
        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;
                    }
                }
            }
        }
예제 #3
0
 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));
 }
예제 #4
0
        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;
        }