Пример #1
0
        public object Translate(TranslationContext context, ASTNode node)
        {
            // Use LogicalConnective
            Model.Expression result = null;

            foreach (var child in node.Children)
            {
                var expression = (Model.Expression)context.TranslateNode(child);
                if (result == null)
                {
                    result = expression;
                }
                else
                {
                    var binaryExpression = new Model.BinaryExpression();
                    binaryExpression.Instruction = GetOperator();
                    binaryExpression.LeftExpression = result;
                    binaryExpression.RightExpression = expression;
                    result = binaryExpression;
                }
            }

            return result;
        }
Пример #2
0
        public object Translate(TranslationContext context, ASTNode node)
        {
            var result = new Model.BinaryExpression();
            result.Instruction = GetOperator();

            result.LeftExpression = (Model.Expression)context.TranslateNode(node.Children[0]);
            result.RightExpression = (Model.Expression)context.TranslateNode(node.Children[1]);

            return result;
        }
Пример #3
0
        public object Translate(TranslationContext context, ASTNode node)
        {
            // In(element, interval)...
            // In(element, list)
            // Translate as:
            // exists (select * from (<list>) T where <element equality condition>)

            // As long as this is list containment, it can be translated using an Exists(Filter(Collection, Condition(Current = Element)));
            var elementNode = node.Children[0];
            var collectionNode = node.Children[1];

            if (elementNode.ResultType is ListType)
            {
                throw new NotSupportedException("In translation with an element of type list is not supported because there is no equivalent SQL representation.");
            }

            if (collectionNode.ResultType is ListType)
            {
                var selectExpression = new SQLModel.SelectExpression();
                selectExpression.SelectClause = new SQLModel.SelectClause();
                selectExpression.SelectClause.NonProject = true;
                selectExpression.FromClause = new SQLModel.CalculusFromClause(new SQLModel.TableSpecifier(SQLTranslationUtilities.EnsureSelectStatementExpression(context.TranslateNode(collectionNode)), "T"));
                selectExpression.WhereClause = new SQLModel.WhereClause();

                Model.Expression condition = null;
                if (elementNode.ResultType is ObjectType)
                {
                    foreach (var property in ((ObjectType)elementNode.ResultType).Properties)
                    {
                        // TODO: O is an assumed alias here, need a way to establish the outer context for comparison of the element....
                        var propertyCondition = new Model.BinaryExpression(new SQLModel.QualifiedFieldExpression(property.Name, "T"), "iEqual", new SQLModel.QualifiedFieldExpression(property.Name, "O"));

                        if (condition == null)
                        {
                            condition = propertyCondition;
                        }
                        else
                        {
                            condition = new Model.BinaryExpression(condition, "iAnd", propertyCondition);
                        }
                    }
                }
                else
                {
                    condition = new Model.BinaryExpression(new SQLModel.QualifiedFieldExpression("value", "T"), "iEqual", (Model.Expression)context.TranslateNode(elementNode));
                }

                selectExpression.WhereClause.Expression = condition;
                return selectExpression;
            }
            else
            {
                var betweenExpression = new Model.BetweenExpression();
                betweenExpression.Expression = (Model.Expression)context.TranslateNode(elementNode);
                // TODO: Translate an interval selector....
                betweenExpression.LowerExpression = new Model.ValueExpression(1);
                betweenExpression.UpperExpression = new Model.ValueExpression(1);
                return betweenExpression;
            }
        }
Пример #4
0
        public object Translate(TranslationContext context, ASTNode node)
        {
            var selectExpression = new SQLModel.SelectExpression();
            selectExpression.SelectClause = new SQLModel.SelectClause();
            selectExpression.SelectClause.NonProject = true;
            selectExpression.FromClause = new SQLModel.CalculusFromClause(new SQLModel.TableSpecifier(new SQLModel.TableExpression("ValueSet"), "VS"));
            selectExpression.WhereClause = new SQLModel.WhereClause();

            var valueSetName = node.GetAttribute<String>("name");
            var valueSetLibraryName = node.GetAttribute<String>("libraryName", ((SQLTranslationContext)context).ArtifactName);
            var valueSetCondition =
                new Model.BinaryExpression
                (
                    new SQLModel.QualifiedFieldExpression("ValueSetName", "VS"),
                    "iEqual",
                    new Model.ValueExpression(String.Format("{0}.{1}", valueSetLibraryName, valueSetName), Model.TokenType.String)
                );

            selectExpression.WhereClause.Expression = valueSetCondition;

            return selectExpression;
        }
Пример #5
0
        public object Translate(TranslationContext context, ASTNode node)
        {
            var requestListType = node.ResultType as ListType;
            var requestType = (requestListType == null ? node.ResultType : requestListType.ElementType) as ObjectType;
            if (requestType == null)
            {
                throw new InvalidOperationException(String.Format("Unable to determine request type from source type: '{0}'.", node.ResultType.Name));
            }

            Model.Expression condition = null;

            // Translate Codes
            var codes = node.Children.Where(n => n.Name == "codes").FirstOrDefault();
            if (codes != null)
            {
                var codesResult = context.TranslateNode(codes);
                // codesResult will be a select statement returning the list of codes
                // So the retrieve must include a where condition limiting the code property to the set of codes (same as InValueSet translation)

                var codeExpression = SQLTranslationUtilities.ResolvePath(node.GetAttribute<string>("codeProperty"), "T");
                var selectExpression = (SQLModel.SelectExpression)codesResult; // This assumes the codes element is a ValueSetRef...
                selectExpression.WhereClause.Expression =
                    new Model.BinaryExpression
                    (
                        selectExpression.WhereClause.Expression,
                        "iAnd",
                        new Model.BinaryExpression(codeExpression, "iEqual", new SQLModel.QualifiedFieldExpression("Code", "VS"))
                    );

                var codeCondition = new Model.UnaryExpression("iExists", selectExpression);
                if (condition != null)
                {
                    condition = new Model.BinaryExpression(condition, "iAnd", codeCondition);
                }
                else
                {
                    condition = codeCondition;
                }
            }

            // Translate DateRange
            var dateRange = node.Children.Where(n => n.Name == "dateRange").FirstOrDefault();
            if (dateRange != null)
            {
                var dateRangeResult = context.TranslateNode(dateRange);
                var dateExpression = SQLTranslationUtilities.ResolvePath(node.GetAttribute<string>("dateProperty"), "T");
                // dateRangeResult will be an interval-valued expression
                // So the retrieve must include a where condition limiting the date range property to the interval (same as In(date, interval) translation)
                var dateRangeCondition = new Model.BetweenExpression();
                dateRangeCondition.Expression = dateExpression;
                // TODO:
                //dateRangeCondition.LowerExpression = // dateRangeResult.Low...
                //dateRangeCondition.UpperExpression = // dateRangeResult.High...

                //if (condition != null)
                //{
                //	condition = new Model.BinaryExpression(condition, "iAnd", dateRangeCondition);
                //}
                //else
                //{
                //	condition = codeCondition;
                //}
            }

            // For FHIR, there will also potentially need to be profile filters...
            // This depends on how the FHIR model is realized within the SQL structures...

            var inQueryContext = ((SQLTranslationContext)context).InQueryContext();
            // Within a Query Context, a retrieve is part of a FromClause
            var tableExpression = new SQLModel.TableExpression(requestType.Name);
            if (inQueryContext && (condition == null))
            {
                return tableExpression;
            }
            else
            {
                var selectExpression = new SQLModel.SelectExpression();
                selectExpression.SelectClause = new SQLModel.SelectClause();
                selectExpression.SelectClause.Distinct = false;
                selectExpression.SelectClause.NonProject = true;
                selectExpression.FromClause = new SQLModel.CalculusFromClause(new SQLModel.TableSpecifier(tableExpression, "T"));
                if (condition != null)
                {
                    selectExpression.WhereClause = new SQLModel.WhereClause();
                    selectExpression.WhereClause.Expression = condition;
                }
                return selectExpression;
            }
        }
Пример #6
0
        public object Translate(TranslationContext context, ASTNode node)
        {
            var selectExpression = new SQLModel.SelectExpression();

            var fromClause = new SQLModel.CalculusFromClause();
            selectExpression.FromClause = fromClause;

            var queryExpression = new SQLModel.QueryExpression();
            queryExpression.SelectExpression = selectExpression;

            var selectStatement = new SQLModel.SelectStatement();
            selectStatement.QueryExpression = queryExpression;

            // 1..* source: AliasedQuerySource
            foreach (var child in ((Node)node).Children.Where(n => n.Name == "source"))
            {
                var tableSpecifier = TranslateAliasedQuerySource(context, child);
                fromClause.TableSpecifiers.Add(tableSpecifier);
            }

            // 0..* define: DefineClause
            foreach (var child in ((Node)node).Children.Where(n => n.Name == "define"))
            {
                // TODO: This would need to be nested to be accessible within context in the SQL query
                throw new NotImplementedException("Define clause translation is not yet implemented");
            }

            // 0..* relationship: With | Without
            Model.Expression relationshipConditions = null;
            foreach (var child in ((Node)node).Children.Where(n => n.Name == "relationship"))
            {
                var relationshipCondition = TranslateRelationshipClause(context, child);
                if (relationshipConditions != null)
                {
                    relationshipConditions = new Model.BinaryExpression(relationshipConditions, "iAnd", relationshipCondition);
                }
                else
                {
                    relationshipConditions = relationshipCondition;
                }
            }

            // 0..1 where: Expression
            Model.Expression whereCondition = null;
            var whereConditionNode = node.Children.SingleOrDefault(n => n.Name == "where");
            if (whereConditionNode != null)
            {
                whereCondition = (Model.Expression)context.TranslateNode(whereConditionNode);
            }

            // 0..1 return: ReturnClause
            var returnClause = ((Node)node).Children.SingleOrDefault(n => n.Name == "return");
            if (returnClause != null)
            {
                var selectClause = TranslateReturnClause(context, returnClause);
                selectExpression.SelectClause = selectClause;
            }

            if (selectExpression.SelectClause == null)
            {
                selectExpression.SelectClause = new SQLModel.SelectClause();
                selectExpression.SelectClause.NonProject = true;
            }

            // 0..1 sort: SortClause
            var sortClause = ((Node)node).Children.SingleOrDefault(n => n.Name == "sort");
            if (sortClause != null)
            {
                var orderClause = TranslateSortClause(context, sortClause);
                selectStatement.OrderClause = orderClause;
            }

            return selectStatement;
        }