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; }
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; }
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; }
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; }
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; }
// 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; }
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; }
public object Translate(TranslationContext context, ASTNode node) { var child = node.Children[0]; return context.TranslateNode(child); }
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; }
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; }
public object Translate(TranslationContext context, ASTNode node) { return new Model.UnaryExpression("iIsNull", (Model.Expression)context.TranslateNode(node.Children[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; } }
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); }
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; }
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 } ); }
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; }
// 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; }
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; }
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; }
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; }
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."); } }
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; }
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; }
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; }
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; }
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; }
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; }
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; }