Exemplo n.º 1
0
        /// <summary>
        /// prase the filter collection and get an execution plan.
        /// </summary>
        /// <returns></returns>
        public static ExecutionPlan GetExecutionPlan(Query query)
        {
            ExecutionPlan executionplan = new ExecutionPlan();

            ITableIndex startindex = null;

            if (!string.IsNullOrEmpty(query.OrderByFieldName))
            {
                startindex = query.table.Indexs.Find(o => o.FieldName == query.OrderByFieldName);
                if (startindex == null)
                {
                    executionplan.RequireOrderBy = true;
                }
            }

            // find other where fields......
            if (startindex == null)
            {
                startindex = query.table.Indexs.Find(o => o.IsSystem);
            }

            if (!string.IsNullOrEmpty(query.OrderByFieldName) && !executionplan.RequireOrderBy)
            {
                Range <byte[]> range = getRange(query.OrderByFieldName, query.items);
                if (range != null)
                {
                    executionplan.startCollection = startindex.GetCollection(range.lower, range.upper, range.lowerOpen, range.upperOpen, query.Ascending);
                }
                else
                {
                    executionplan.startCollection = startindex.AllItems(query.Ascending);
                }
            }
            else
            {
                executionplan.startCollection = startindex.AllItems(query.Ascending);
            }

            // check all index fields that has been used in the filter.
            foreach (var item in query.table.Indexs)
            {
                if (item.FieldName != startindex.FieldName)
                {
                    Range <byte[]> indexrange = getRange(item.FieldName, query.items);
                    if (indexrange != null)
                    {
                        executionplan.indexRanges.Add(item.FieldName, indexrange);
                    }
                }
            }

            // now the left columns..
            foreach (var item in query.items)
            {
                var column = query.table.ObjectConverter.Fields.Find(o => o.FieldName == item.FieldOrProperty);

                if (column != null)
                {
                    ColumnScan colplan = new ColumnScan();

                    colplan.ColumnName            = column.FieldName;
                    colplan.relativeStartPosition = column.RelativePosition;
                    colplan.length    = column.Length;
                    colplan.Evaluator = ColumnEvaluator.GetEvaluator(column.ClrType, item.Compare, item.Value, column.Length);

                    executionplan.scanColumns.Add(colplan);
                }
                else
                {
                    throw new Exception("filter field must be  column with fixed len");
                }
            }

            // the left column query.
            foreach (var item in query.InItems)
            {
                var column = query.table.ObjectConverter.Fields.Find(o => o.FieldName == item.Key);

                if (column != null)
                {
                    ColumnScan colplan = new ColumnScan();

                    colplan.ColumnName            = column.FieldName;
                    colplan.relativeStartPosition = column.RelativePosition;
                    colplan.length    = column.Length;
                    colplan.Evaluator = ColumnInEvaluator.GetInEvaluator(column.ClrType, item.Value, column.Length);

                    executionplan.scanColumns.Add(colplan);
                }
                else
                {
                    throw new Exception("filter field must be a column with fixed length");
                }
            }

            /// for the methods calls.
            foreach (var item in query.calls)
            {
                MemberExpression memberaccess = null;
                foreach (var xitem in item.Arguments)
                {
                    if (xitem.NodeType == ExpressionType.MemberAccess)
                    {
                        memberaccess = xitem as MemberExpression;
                    }
                }
                if (memberaccess == null)
                {
                    throw new Exception("Method call require use one of the Fields or Property as parameters");
                }

                string fieldname = memberaccess.Member.Name;


                var column = query.table.ObjectConverter.Fields.Find(o => o.FieldName == fieldname);

                if (column != null)
                {
                    ColumnScan colplan = new ColumnScan();

                    colplan.ColumnName            = column.FieldName;
                    colplan.relativeStartPosition = column.RelativePosition;
                    colplan.length = column.Length;

                    colplan.Evaluator = ColumnMethodCallEvaluator.GetMethodEvaluator(column.ClrType, column.Length, item);

                    executionplan.scanColumns.Add(colplan);
                }
                else
                {
                    throw new Exception("methed call parameter must be a column, add the field to colomn creating creating the store, otherwise use the fullscan option");
                }
            }

            return(executionplan);
        }