public Expression RunWithResult(SyneryParser.RequestSelectSingleContext context, QueryMemory memory)
        {
            // interpret single field (direct field reference or field expression)

            IExpressionValue fieldExpressionValue = null;
            string           fieldName            = null;

            try
            {
                if (context.requestFieldReference() != null)
                {
                    // single field
                    // Example: SELECT IdPerson
                    // Example: SELECT p.PersonName

                    KeyValuePair <string, IExpressionValue> field = Controller
                                                                    .Interpret <SyneryParser.RequestFieldReferenceContext, KeyValuePair <string, IExpressionValue>, QueryMemory>(context.requestFieldReference(), memory);

                    fieldName            = field.Key;
                    fieldExpressionValue = field.Value;
                }
                else if (context.requestSelectFieldAssignment() != null)
                {
                    // field assignment
                    // Example: SELECT Name = p.PersonFirstname

                    KeyValuePair <string, IExpressionValue> field = InterpretRequestSelectFieldAssignment(context.requestSelectFieldAssignment(), memory);
                    fieldName            = field.Key;
                    fieldExpressionValue = field.Value;
                }
            }
            catch (Exception ex)
            {
                if (ex is SyneryException)
                {
                    throw;
                }

                throw new SyneryInterpretationException(context, String.Format(
                                                            "Error while initializing the field '{1}' in '{2}' starting on line {3}. {0}Message: {4}",
                                                            Environment.NewLine,
                                                            fieldName,
                                                            context.GetText(),
                                                            context.Start.Line,
                                                            ExceptionHelper.GetNestedExceptionMessages(ex)), ex);
            }

            // append the field expression and field definition

            if (fieldExpressionValue != null && String.IsNullOrEmpty(fieldName) == false)
            {
                Expression selectItemExpresson = fieldExpressionValue.Expression;
                Expression objectExpression    = Expression.Convert(selectItemExpresson, typeof(object));

                memory.NewSchema.AddField(fieldName, fieldExpressionValue.ResultType.UnterlyingDotNetType);
                return(objectExpression);
            }

            throw new NotImplementedException("Unknown RequestSelectItem");
        }
        private KeyValuePair <string, IExpressionValue> InterpretRequestSelectFieldAssignment(SyneryParser.RequestSelectFieldAssignmentContext context, QueryMemory queryMemory)
        {
            // get the future fieldname from the user defined identifier
            SyneryParser.RequestExpressionContext expressionContext = context.requestExpression();
            string fieldName = context.Identifier().GetText();

            // get the LINQ expression for the Synery field expression
            IExpressionValue expressionValue = Controller
                                               .Interpret <SyneryParser.RequestExpressionContext, IExpressionValue, QueryMemory>(expressionContext, queryMemory);

            return(new KeyValuePair <string, IExpressionValue>(fieldName, expressionValue));
        }
        public ITable RunWithResult(SyneryParser.RequestWhereCommandContext context, QueryMemory queryMemory)
        {
            IExpressionValue expressionValue = Controller.Interpret <SyneryParser.RequestExpressionContext, IExpressionValue, QueryMemory>(context.requestExpression(), queryMemory);

            if (expressionValue.ResultType == typeof(bool))
            {
                // create a lambda expression that selects all fields as an object-array
                var body   = expressionValue.Expression;
                var lambda = Expression.Lambda <Func <object[], int, bool> >(body, queryMemory.RowExpression, queryMemory.IndexExpression);

                // run the LINQ select using the created object-arry select lambda expression
                IEnumerable <object[]> data = queryMemory.CurrentTable.Where(lambda.Compile());

                queryMemory.CurrentTable.SetData(data);

                return(queryMemory.CurrentTable);
            }
            else
            {
                throw new SyneryInterpretationException(context,
                                                        String.Format("The expression of a WHERE clause must result in a boolean value. The give value was of type '{0}'. Expression='{1}'",
                                                                      expressionValue.ResultType.PublicName, context.GetText()));
            }
        }
Пример #4
0
        public ITable RunWithResult(SyneryParser.RequestSelectCommandContext context, QueryMemory queryMemory)
        {
            List <Expression> listOfSelectItemExpressions = new List <Expression>();

            queryMemory.NewSchema = Memory.Database.NewSchema();

            // interpret all fields in the select list
            foreach (var item in context.requestSelectItem())
            {
                if (item.requestSelectSingle() != null)
                {
                    // get expression for select item
                    Expression selectItemExpression = Controller
                                                      .Interpret <SyneryParser.RequestSelectSingleContext, Expression, QueryMemory>(item.requestSelectSingle(), queryMemory);

                    Expression tryCatch = SorroundFieldExpressionWithTryCatch(item.requestSelectSingle(), selectItemExpression, queryMemory);

                    listOfSelectItemExpressions.Add(tryCatch);
                }
                else if (item.requestSelectMany() != null)
                {
                    try
                    {
                        // many fields
                        // Example: SELECT a.*
                        // Example: SELECT *

                        IDictionary <string, IExpressionValue> listOfFieldItems = Controller
                                                                                  .Interpret <SyneryParser.RequestSelectManyContext, IDictionary <string, IExpressionValue>, QueryMemory>(item.requestSelectMany(), queryMemory);

                        // loop threw all the field items (name and expression) and append them to the new Schema

                        foreach (var fieldItem in listOfFieldItems)
                        {
                            string           fieldName            = fieldItem.Key;
                            IExpressionValue fieldExpressionValue = fieldItem.Value;

                            Expression selectItemExpression = fieldExpressionValue.Expression;
                            Expression objectExpression     = Expression.Convert(selectItemExpression, typeof(object));

                            queryMemory.NewSchema.AddField(fieldName, fieldExpressionValue.ResultType.UnterlyingDotNetType);

                            Expression tryCatch = SorroundFieldExpressionWithTryCatch(item.requestSelectMany(), objectExpression, queryMemory);

                            listOfSelectItemExpressions.Add(tryCatch);
                        }
                    }
                    catch (Exception ex)
                    {
                        if (ex is SyneryException)
                        {
                            throw;
                        }

                        throw new SyneryInterpretationException(item.requestSelectSingle(), ex.Message, ex);
                    }
                }
            }

            // create a lambda expression that selects all fields as an object-array
            var body   = Expression.NewArrayInit(typeof(object), listOfSelectItemExpressions);
            var lambda = Expression.Lambda <Func <object[], int, object[]> >(body, queryMemory.RowExpression, queryMemory.IndexExpression);

            // run the LINQ select using the created object-array select lambda expression
            IEnumerable <object[]> data = queryMemory.CurrentTable.Select(lambda.Compile());

            // create a new table instance
            ITable newTable = Memory.Database.NewTable(queryMemory.NewSchema, data);

            return(newTable);
        }