private CREFModel.DynamicRuleDynamicRuleCriteria TranslateCriteria(TranslationContext context, ASTNode condition)
		{
			var result = new CREFModel.DynamicRuleDynamicRuleCriteria();

			result.Item = context.TranslateNode(condition);

			return result;
		}
		private CREFModel.NamedExpression TranslateNamedExpression(TranslationContext context, ExpressionDef expression)
		{
			var result = new CREFModel.NamedExpression();

			result.Name = expression.Name;
			result.Item = context.TranslateNode(expression.Expression);

			return result;
		}
		protected object GetPropertyExpression(TranslationContext context, ASTNode node, string path)
		{
			var result = new SQLModel.PropertyExpression();
			result.Path = path;

			if (node.Children.Count > 0)
			{
				result.Item = context.TranslateNode(node.Children[0]);
			}

			return result;
		}
Beispiel #4
0
        public object Translate(TranslationContext context, ASTNode node)
        {
            var result = new CREFModel.BinaryExpression();
            result.Operator = GetOperator();
            result.OperatorSpecified = true;

            foreach (var child in node.Children)
            {
                result.Items.Add(context.TranslateNode(child));
            }

            return result;
        }
Beispiel #5
0
        public object Translate(TranslationContext context, ASTNode node)
        {
            // As long as this is list containment, it can be translated using an Exists(Filter(Source, Condition(Current = Value)));
            // TODO: Contains on a date interval could be translated as well
            var sourceNode = node.Children.FirstOrDefault(c => c.Name == "source");
            var elementNode = node.Children.FirstOrDefault(c => c.Name == "element");

            if (sourceNode.ResultType is IntervalType)
            {
                throw new NotImplementedException("Contains translation with Interval source is not yet supported.");
            }

            var filter = new CREFModel.FilterExpression();

            filter.Items.Add(context.TranslateNode(sourceNode));

            var condition = new CREFModel.BinaryExpression();
            condition.Operator = CREFModel.BinaryOperator.opEqual;
            condition.OperatorSpecified = true;

            // Assumption: A property expression with no path specified is equivalent to a "current" reference
            var property = new CREFModel.PropertyExpression();

            condition.Items.Add(property);
            condition.Items.Add(context.TranslateNode(elementNode));

            var exists = new CREFModel.UnaryExpression();
            exists.Operator = CREFModel.UnaryOperator.opExists;
            exists.OperatorSpecified = true;
            exists.Item = filter;

            return exists;
        }
Beispiel #6
0
        public object Translate(TranslationContext context, ASTNode node)
        {
            var result = new CREFModel.UnaryExpression();
            result.Operator = GetOperator();
            result.OperatorSpecified = true;

            result.Item = context.TranslateNode(node.Children[0]);

            return result;
        }
Beispiel #7
0
        public object Translate(TranslationContext context, ASTNode node)
        {
            // Model mapping
            var result = new CREFModel.RequestExpression();

            if (node.ResultType == null)
            {
                throw new InvalidOperationException("Clinical request expression has no result type.");
            }

            var cardinality = (RequestCardinality)Enum.Parse(typeof(RequestCardinality), node.Attributes["cardinality"].ToString(), true);
            result.Cardinality = cardinality == RequestCardinality.Single ? CREFModel.RequestCardinality.Single : CREFModel.RequestCardinality.Multiple;
            result.CardinalitySpecified = true;

            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));
            }

            result.Type = GetQueryType(context.TransformModelType(requestType));
            result.TypeSpecified = true;

            // Translate Codes
            var codes = node.Children.Where(n => n.Name == "codes").FirstOrDefault();
            if (codes != null)
            {
                var codesResult = context.TranslateNode(codes);
                result.Items.Add(codesResult);
            }

            // Translate DateRange
            var dateRange = node.Children.Where(n => n.Name == "dateRange").FirstOrDefault();
            if (dateRange != null)
            {
                var dateRangeResult = context.TranslateNode(dateRange);
                result.Items.Add(dateRangeResult);
            }

            // Validate idProperty, dateProperty, and codeProperty
            ValidateIdProperty(requestType, node.GetAttribute<string>("idProperty"));
            ValidateDateProperty(requestType, node.GetAttribute<string>("dateProperty"));
            ValidateCodeProperty(requestType, node.GetAttribute<string>("codeProperty"));

            // Add status filters if necessary
            var filterValue = GetStatusFilterValue(requestType);
            if (!String.IsNullOrEmpty(filterValue))
            {
                var filter = new CREFModel.FilterExpression();

                filter.Items.Add(result);

                var condition = new CREFModel.BinaryExpression();
                condition.Operator = CREFModel.BinaryOperator.opEqual;
                condition.OperatorSpecified = true;

                condition.Items.Add(new CREFModel.PropertyExpression() { Path = "Status" });
                condition.Items.Add(new CREFModel.ValueExpression() { Type = CREFModel.ValueType.String, TypeSpecified = true, Value = filterValue });

                filter.Items.Add(condition);

                return filter;
            }

            return result;
        }
Beispiel #8
0
        // Children
        // date
        // granularity
        // numberOfPeriods
        public object Translate(TranslationContext context, ASTNode node)
        {
            var result = new Model.CallExpression("DateAdd", new Model.Expression[] { }); // TODO: This is a T-SQL specific translation

            var granularity = node.Children[1];
            if (granularity.NodeType == "urn:hl7-org:v3:knowledgeartifact:r1:Literal") // TODO: Better story for this type of thing....
            {
                result.Expressions.Add(new Model.IdentifierExpression(granularity.GetAttribute<string>("value")));
            }
            else
            {
                throw new NotSupportedException("Date granularity argument to a DateAdd expression must be a literal because CREF does not support granularity as an argument, only as an attribute of the target DateAdd expression.");
            }

            var numberOfPeriods = node.Children[2];
            result.Expressions.Add(context.TranslateNode(numberOfPeriods));

            var date = node.Children[0];
            result.Expressions.Add(context.TranslateNode(date));

            return result;
        }
Beispiel #9
0
        public object Translate(TranslationContext context, ASTNode node)
        {
            var result = new CREFModel.Choice();

            var comparand = node.Children.FirstOrDefault(n => n.Name == "comparand");

            foreach (var caseItem in ((Node)node).Children.Where(n => n.Name == "caseItem"))
            {
                var whenNode = caseItem.Children[0] as ASTNode;
                var thenNode = caseItem.Children[1] as ASTNode;

                var condition = new CREFModel.Condition();
                if (comparand == null)
                {
                    condition.Items.Add(context.TranslateNode(whenNode));
                }
                else
                {
                    var equal = new CREFModel.BinaryExpression();
                    equal.Operator = CREFModel.BinaryOperator.opEqual;
                    equal.OperatorSpecified = true;
                    equal.Items.Add(context.TranslateNode(comparand));
                    equal.Items.Add(context.TranslateNode(whenNode));
                    condition.Items.Add(equal);
                }

                condition.Items.Add(context.TranslateNode(thenNode));

                result.Items.Add(condition);
            }

            var elseNode = node.Children.FirstOrDefault(n => n.Name == "else") as ASTNode;

            result.Items.Add(context.TranslateNode(elseNode));

            return result;
        }
Beispiel #10
0
 public object Translate(TranslationContext context, ASTNode node)
 {
     var child = node.Children[0];
     return context.TranslateNode(child);
 }
Beispiel #11
0
        public object Translate(TranslationContext context, ASTNode node)
        {
            // As long as this is list containment, it can be translated using an Exists(Filter(Collection, Condition(Current = Element)));
            var collectionNode = node.Children.FirstOrDefault(c => c.Name == "collection");
            var elementNode = node.Children.FirstOrDefault(c => c.Name == "element");

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

            var filter = new CREFModel.FilterExpression();

            filter.Items.Add(context.TranslateNode(collectionNode));

            var condition = new CREFModel.BinaryExpression();
            condition.Operator = CREFModel.BinaryOperator.opEqual;
            condition.OperatorSpecified = true;

            // Assumption: A property expression with no path specified is equivalent to a "current" reference
            var property = new CREFModel.PropertyExpression();

            condition.Items.Add(property);
            condition.Items.Add(context.TranslateNode(elementNode));

            var exists = new CREFModel.UnaryExpression();
            exists.Operator = CREFModel.UnaryOperator.opExists;
            exists.OperatorSpecified = true;
            exists.Item = filter;

            return exists;
        }
Beispiel #12
0
        public object Translate(TranslationContext context, ASTNode node)
        {
            var unaryExpression = new Model.UnaryExpression();
            unaryExpression.Instruction = "iExists";
            unaryExpression.Expression = SQLTranslationUtilities.EnsureSelectStatementExpression(context.TranslateNode(node.Children[0]));

            return unaryExpression;
        }
Beispiel #13
0
 public object Translate(TranslationContext context, ASTNode node)
 {
     return new Model.UnaryExpression("iIsNull", (Model.Expression)context.TranslateNode(node.Children[0]));
 }
Beispiel #14
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;
            }
        }
Beispiel #15
0
        public object Translate(TranslationContext context, ASTNode node)
        {
            // Translates to a table-based solution
            // exists ( select * from ValueSets where ValueSetName = X and ValueSetVersion = Y and Code = Z )

            var codeExpression = (Model.Expression)context.TranslateNode(node.Children[0]);
            var selectExpression = (SQLModel.SelectExpression)context.TranslateNode(node.Children[1]);
            selectExpression.WhereClause.Expression =
                new Model.BinaryExpression
                (
                    selectExpression.WhereClause.Expression,
                    "iAnd",
                    new Model.BinaryExpression(codeExpression, "iEqual", new SQLModel.QualifiedFieldExpression("Code", "VS"))
                );

            return new Model.UnaryExpression("iExists", selectExpression);
        }
Beispiel #16
0
 public object Translate(TranslationContext context, ASTNode node)
 {
     var result = new Model.CallExpression();
     result.Identifier = "IsNull"; // TODO: This is T-SQL dialect specific...
     result.Expressions.Add(context.TranslateNode(node.Children[0]));
     result.Expressions.Add(context.TranslateNode(node.Children[1]));
     return result;
 }
Beispiel #17
0
 public object Translate(TranslationContext context, ASTNode node)
 {
     var precision = node.GetAttribute<string>("precision");
     var startDate = (Model.Expression)context.TranslateNode(node.Children[0]);
     var endDate = (Model.Expression)context.TranslateNode(node.Children[1]);
     return
         new Model.CallExpression
         (
             "DateDiff",
             new Model.Expression[]
             {
                 new Model.ValueExpression(SQLTranslationUtilities.DateTimePrecisionToDatePartSpecifier(precision), Model.TokenType.String),
                 startDate,
                 endDate
             }
         );
 }
Beispiel #18
0
        public object Translate(TranslationContext context, ASTNode node)
        {
            // TODO: This is a T-SQL specific call
            var result =
                new Model.CallExpression
                (
                    "Convert",
                    new Model.Expression[]
                    {
                        new Model.IdentifierExpression("dateTime"),
                        new Model.CallExpression
                        (
                            "Floor",
                            new Model.Expression[]
                            {
                                new Model.CallExpression
                                (
                                    "Convert",
                                    new Model.Expression[]
                                    {
                                        new Model.IdentifierExpression("float"),
                                        SQLTranslationUtilities.EnsureExpression(context.TranslateNode(node.Children[0]))
                                    }
                                )
                            }
                        )
                    }
                );

            return result;
        }
Beispiel #19
0
        // Children
        // date
        // granularity
        // numberOfPeriods
        public object Translate(TranslationContext context, ASTNode node)
        {
            var result = new CREFModel.DateAdd();

            var date = node.Children[0];
            result.Items.Add(context.TranslateNode(date));

            var granularity = node.Children[1];
            if (granularity.NodeType == "urn:hl7-org:v3:knowledgeartifact:r1:Literal") // TODO: Better story for this type of thing....
            {
                result.Granularity = (CREFModel.DateGranularity)Enum.Parse(typeof(CREFModel.DateGranularity), granularity.GetAttribute<string>("value"));
                result.GranularitySpecified = true;
            }
            else
            {
                throw new NotSupportedException("Date granularity argument to a DateAdd expression must be a literal because CREF does not support granularity as an argument, only as an attribute of the target DateAdd expression.");
            }

            var numberOfPeriods = node.Children[2];
            result.Items.Add(context.TranslateNode(numberOfPeriods));

            return result;
        }
Beispiel #20
0
        public object Translate(TranslationContext context, ASTNode node)
        {
            // Ideally, this would be expressed as an InValueSet expression within CREF, but in the absence of such an operator, the translation
            // Can be supporting using: Exists(Filter(ValueSet(ValueSetId), Condition(Current = Operand)))
            var valueSetId = node.GetAttribute<string>("id");
            var valueSetVersion = node.GetAttribute<string>("version");
            var valueSetAuthority = node.GetAttribute<string>("authority"); // TODO: Authority resolution?

            var operand = node.Children.FirstOrDefault(c => c.Name == "operand");

            var valueSetExpression = new CREFModel.ValueSetExpression();
            valueSetExpression.ValueSetID = valueSetId;
            if (!String.IsNullOrEmpty(valueSetVersion))
            {
                valueSetExpression.Version = Convert.ToInt32(valueSetVersion);
                valueSetExpression.VersionSpecified = true;
            }

            var filter = new CREFModel.FilterExpression();

            filter.Items.Add(valueSetExpression);

            var condition = new CREFModel.BinaryExpression();
            condition.Operator = CREFModel.BinaryOperator.opEqual;
            condition.OperatorSpecified = true;

            // Assumption: A property expression with no path specified is equivalent to a "current" reference
            var property = new CREFModel.PropertyExpression();

            condition.Items.Add(property);
            condition.Items.Add(context.TranslateNode(operand));

            var exists = new CREFModel.UnaryExpression();
            exists.Operator = CREFModel.UnaryOperator.opExists;
            exists.OperatorSpecified = true;
            exists.Item = filter;

            return exists;
        }
Beispiel #21
0
        public object Translate(TranslationContext context, ASTNode node)
        {
            var scope = node.GetAttribute<string>("scope", VerificationContext.Current);
            if (scope != VerificationContext.Current)
            {
                throw new NotSupportedException("Translation of filter expression is not supported because it involves a named scope reference, which is not supported in CREF.");
            }

            var source = node.Children[0];
            var condition = node.Children[1];

            var result = new CREFModel.FilterExpression();
            result.Items.Add(context.TranslateNode(source));
            result.Items.Add(context.TranslateNode(condition));

            return result;
        }
Beispiel #22
0
        public object Translate(TranslationContext context, ASTNode node)
        {
            var result = new CREFModel.ListExpression();

            foreach (var child in node.Children)
            {
                result.Items.Add(context.TranslateNode(child));
            }

            return result;
        }
Beispiel #23
0
        public object Translate(TranslationContext context, ASTNode node)
        {
            if (DataTypes.Equal(node.ResultType, DataTypes.TimestampInterval))
            {
                var result = new CREFModel.DateRange();

                var beginOpen = Convert.ToBoolean(node.GetAttribute<string>("beginOpen"));
                var endOpen = Convert.ToBoolean(node.GetAttribute<string>("endOpen"));
                if (beginOpen || endOpen)
                {
                    throw new NotSupportedException("Translation for open intervals is not supported because CREF only supports closed interval values.");
                }

                foreach (var child in node.Children)
                {
                    result.Items.Add(context.TranslateNode(child));
                }

                return result;
            }
            else
            {
                throw new NotSupportedException("Translation for intervals with point types other than Timestamp is not supported because CREF does not support generic interval values.");
            }
        }
Beispiel #24
0
        public object Translate(TranslationContext context, ASTNode node)
        {
            var result = new Model.CallExpression();
            result.Identifier = "Coalesce";

            foreach (var child in node.Children)
            {
                result.Expressions.Add(context.TranslateNode(child));
            }

            return result;
        }
Beispiel #25
0
        public object Translate(TranslationContext context, ASTNode node)
        {
            var selectStatement = SQLTranslationUtilities.EnsureSelectStatement(context.TranslateNode(node.Children[0]));

            selectStatement.TopClause = new TSQLModel.TopClause();
            selectStatement.TopClause.Quota = 1;

            // TODO: If OrderClause is not null...
            if (selectStatement.OrderClause == null)
            {
                selectStatement.OrderClause = new SQLModel.OrderClause();
                // TODO: If ResultType is not a tuple type...
                foreach (var element in ((ObjectType)node.ResultType).Properties)
                {
                    selectStatement.OrderClause.Columns.Add(new SQLModel.OrderFieldExpression(element.Name, null, false));
                }
            }

            return selectStatement;
        }
Beispiel #26
0
        public object Translate(TranslationContext context, ASTNode node)
        {
            var result = new Model.CaseExpression();
            var resultItem = new Model.CaseItemExpression();
            resultItem.WhenExpression = (Model.Expression)context.TranslateNode(node.Children[0]);
            resultItem.ThenExpression = (Model.Expression)context.TranslateNode(node.Children[1]);
            result.CaseItems.Add(resultItem);
            result.ElseExpression = (Model.Expression)context.TranslateNode(node.Children[2]);

            return result;
        }
Beispiel #27
0
        public object Translate(TranslationContext context, ASTNode node)
        {
            var unaryExpression = new CREFModel.UnaryExpression();
            unaryExpression.Operator = CREFModel.UnaryOperator.opExists;
            unaryExpression.OperatorSpecified = true;
            unaryExpression.Item = context.TranslateNode(node.Children[0]);

            return unaryExpression;
        }
Beispiel #28
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;
        }
Beispiel #29
0
        public object Translate(TranslationContext context, ASTNode node)
        {
            // Use LogicalConnective
            var result = new CREFModel.LogicalConnective();

            result.Operator = GetOperator();
            result.OperatorSpecified = true;

            foreach (var child in node.Children)
            {
                var childResult = context.TranslateNode(child);
                result.Items.Add(childResult);
            }

            return result;
        }
Beispiel #30
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;
        }