Exemplo n.º 1
0
        public ITable RunWithResult(SyneryParser.RequestStatementContext context)
        {
            QueryMemory queryMemory = new QueryMemory
            {
                CurrentTable    = InterpretRequestFromCommand(context.requestFromCommand()),
                NewSchema       = Memory.Database.NewSchema(),
                RowExpression   = Expression.Parameter(typeof(object[]), "x"),
                IndexExpression = Expression.Parameter(typeof(int), "index"),
            };

            // loop threw the request commands and interpret them

            foreach (SyneryParser.RequestCommandContext command in context.requestCommand())
            {
                if (command.requestSelectCommand() != null)
                {
                    queryMemory.CurrentTable = Controller.Interpret <SyneryParser.RequestSelectCommandContext, ITable, QueryMemory>(command.requestSelectCommand(), queryMemory);
                }
                else if (command.requestWhereCommand() != null)
                {
                    queryMemory.CurrentTable = Controller.Interpret <SyneryParser.RequestWhereCommandContext, ITable, QueryMemory>(command.requestWhereCommand(), queryMemory);
                }
                else if (command.requestJoinCommand() != null)
                {
                    queryMemory.CurrentTable = Controller.Interpret <SyneryParser.RequestJoinCommandContext, ITable, QueryMemory>(command.requestJoinCommand(), queryMemory);
                }
                else if (command.requestLeftJoinCommand() != null)
                {
                    queryMemory.CurrentTable = Controller.Interpret <SyneryParser.RequestLeftJoinCommandContext, ITable, QueryMemory>(command.requestLeftJoinCommand(), queryMemory);
                }
                else if (command.requestOrderByCommand() != null)
                {
                    queryMemory.CurrentTable = Controller.Interpret <SyneryParser.RequestOrderByCommandContext, ITable, QueryMemory>(command.requestOrderByCommand(), queryMemory);
                }
                else if (command.requestDistinctCommand() != null)
                {
                    queryMemory.CurrentTable = Controller.Interpret <SyneryParser.RequestDistinctCommandContext, ITable, QueryMemory>(command.requestDistinctCommand(), queryMemory);
                }
            }

            //RemovePrimaryTableAliasesFromFieldNames(queryMemory.CurrentTable);
            CleanUpFieldNames(queryMemory.CurrentTable);

            return(queryMemory.CurrentTable);
        }
Exemplo n.º 2
0
 public static IEnumerable <IExpressionValue> GetListOfParameterExpressionValues(IInterpretationController controller, QueryMemory queryMemory, SyneryParser.RequestExpressionListContext context)
 {
     if (context != null)
     {
         return(controller.Interpret <SyneryParser.RequestExpressionListContext, IList <IExpressionValue>, QueryMemory>(context, queryMemory));
     }
     else
     {
         return(new List <IExpressionValue>());
     }
 }
Exemplo n.º 3
0
        public IList <IExpressionValue> RunWithResult(SyneryParser.RequestExpressionListContext context, QueryMemory queryMemory)
        {
            List <IExpressionValue> listOfExpressions = new List <IExpressionValue>();

            foreach (var requestExpressionContext in context.requestExpression())
            {
                IExpressionValue expressionValue = Controller
                                                   .Interpret <SyneryParser.RequestExpressionContext, IExpressionValue, QueryMemory>(requestExpressionContext, queryMemory);

                // Convert all values to objects to avoid problems when initializing an array of objects.
                // Otherwise an exception may be thrown. For example:
                // "An expression of type 'System.Int32' cannot be used to initialize an array of type 'System.Object'"
                expressionValue.Expression = Expression.Convert(expressionValue.Expression, typeof(object));

                listOfExpressions.Add(expressionValue);
            }

            return(listOfExpressions);
        }
        public IDictionary <string, IExpressionValue> RunWithResult(SyneryParser.RequestSelectManyContext context, QueryMemory queryMemory)
        {
            string fieldNamePrefix = null;
            Dictionary <string, IExpressionValue> listOfFields = new Dictionary <string, IExpressionValue>();

            // A Select-Many expression can look like this: a.* or *
            // get the field prefix if one is given
            if (context.Identifier() != null)
            {
                fieldNamePrefix = String.Format("{0}.", context.Identifier().GetText());
            }

            // loop threw all fields
            for (int i = 0; i < queryMemory.CurrentTable.Schema.Fields.Count; i++)
            {
                IField field = queryMemory.CurrentTable.Schema.Fields[i];

                // add the field if there is no table prefix or the name of the current field starts with the given prefix
                if (fieldNamePrefix == null || field.Name.StartsWith(fieldNamePrefix))
                {
                    string newFieldName = field.Name.Substring(field.Name.IndexOf('.') + 1);

                    // create the array selector based on the position of the current field
                    Expression arraySelectorExpression = Expression.ArrayIndex(queryMemory.RowExpression, Expression.Constant(i));

                    ExpressionValue expressionValue = new ExpressionValue(
                        expression: arraySelectorExpression,
                        resultType: TypeHelper.GetSyneryType(field.Type)
                        );

                    listOfFields.Add(newFieldName, expressionValue);
                }
            }

            return(listOfFields);
        }
        private KeyValuePair <string, IExpressionValue> InterpretComplexReference(SyneryParser.ComplexReferenceContext context, QueryMemory queryMemory)
        {
            // get the future fieldname from it's old name by removing the alias
            string complexIdentifier = context.GetText();

            string[] path      = IdentifierHelper.ParseComplexIdentifier(complexIdentifier);
            string   fieldName = path[path.Length - 1];

            // get the LINQ expression for the field reference
            IField schemaField   = queryMemory.CurrentTable.Schema.GetField(complexIdentifier);
            int    fieldPosition = queryMemory.CurrentTable.Schema.GetFieldPosition(complexIdentifier);

            if (fieldPosition != -1)
            {
                // the field was found - create an array index Expression to access the field value

                Expression arraySelectorExpression = Expression.ArrayIndex(queryMemory.RowExpression, Expression.Constant(fieldPosition));

                ExpressionValue expressionValue = new ExpressionValue(
                    expression: arraySelectorExpression,
                    resultType: TypeHelper.GetSyneryType(schemaField.Type)
                    );

                return(new KeyValuePair <string, IExpressionValue>(fieldName, expressionValue));
            }

            // search for an other kind of complex references

            IValue value = Controller.Interpret <SyneryParser.ComplexReferenceContext, IValue>(context);

            if (value != null)
            {
                // the value could be resolved
                // create a constant LINQ expression for the value

                // check whether it's a primitive type

                if (value.Type != typeof(IRecord))
                {
                    Expression expression;

                    if (value.Type != null)
                    {
                        expression = Expression.Constant(value.Value, value.Type.UnterlyingDotNetType);
                    }
                    else
                    {
                        expression = Expression.Constant(null);
                    }

                    ExpressionValue expressionValue = new ExpressionValue(
                        expression: expression,
                        resultType: value.Type
                        );

                    return(new KeyValuePair <string, IExpressionValue>(fieldName, expressionValue));
                }
                else
                {
                    throw new SyneryInterpretationException(context, String.Format(
                                                                "Cannot use the reference to the record (name='{0}') inside of a query. Only primitve types are allowed."
                                                                , fieldName));
                }
            }

            throw new SyneryInterpretationException(context, String.Format("A field or variable with the name '{0}' wan't found.", complexIdentifier));
        }
        /// <summary>
        /// Creates an Expression that either accesses the array index of the referenced field or a Constand for a variable value.
        /// If the referenced field or variable wasn't found it throws a SyneryException.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="queryMemory"></param>
        /// <returns></returns>
        public KeyValuePair <string, IExpressionValue> RunWithResult(SyneryParser.RequestFieldReferenceContext context, QueryMemory queryMemory)
        {
            if (context.complexReference() != null)
            {
                // a ComplexReference could either be a field reference from a FROM or a JOIN statement or a real reference of an external variable
                // the field reference has priority over variable reference
                return(InterpretComplexReference(context.complexReference(), queryMemory));
            }
            else if (context.variableReference() != null)
            {
                // a VariableReference could either be a field reference from a prior SELECT statement or a real reference of a variable
                // the field reference has priority over variable reference
                return(InterpretVariableReference(context.variableReference(), queryMemory));
            }

            throw new SyneryInterpretationException(context,
                                                    string.Format("Unknown field reference expression in {0}: '{1}'", this.GetType().Name, context.GetText()));
        }
        private KeyValuePair <string, IExpressionValue> InterpretVariableReference(SyneryParser.VariableReferenceContext context, QueryMemory queryMemory)
        {
            // get the field name from the reference text
            string fieldName = context.GetText();

            IField schemaField   = queryMemory.CurrentTable.Schema.GetField(fieldName);
            int    fieldPosition = queryMemory.CurrentTable.Schema.GetFieldPosition(fieldName);

            if (fieldPosition != -1)
            {
                // the field was found in the current table - create an array index Expression to access the field value

                Expression arraySelectorExpression = Expression.ArrayIndex(queryMemory.RowExpression, Expression.Constant(fieldPosition));

                ExpressionValue expressionValue = new ExpressionValue(
                    expression: arraySelectorExpression,
                    resultType: TypeHelper.GetSyneryType(schemaField.Type)
                    );

                return(new KeyValuePair <string, IExpressionValue>(fieldName, expressionValue));
            }
            else
            {
                // no table field found - search for a variable with the given name

                Expression expression;
                IValue     value = null;

                try
                {
                    value = Memory.CurrentScope.ResolveVariable(fieldName);
                }
                catch (Exception) { /* throw exception later */ }

                // check whether the variable has been resolved

                if (value != null)
                {
                    // the variable is available - create a Constant expression from the value

                    if (value.Type != null)
                    {
                        expression = Expression.Constant(value.Value, value.Type.UnterlyingDotNetType);
                    }
                    else
                    {
                        expression = Expression.Constant(null);
                    }

                    ExpressionValue expressionValue = new ExpressionValue(
                        expression: expression,
                        resultType: value.Type
                        );

                    return(new KeyValuePair <string, IExpressionValue>(fieldName, expressionValue));
                }
            }

            throw new SyneryInterpretationException(context, String.Format("A field or variable with the name '{0}' wasn't found.", fieldName));
        }