public object Translate(TranslationContext context, ASTNode node)
		{
			var result = new SQLModel.TableExpression();
			var sqlContext = (SQLTranslationContext)context;
			result.TableName = sqlContext.GetExpressionObjectName(String.Format("{0}.{1}", node.GetAttribute<string>("libraryName", sqlContext.ArtifactName), node.GetAttribute<string>("name")));

			// If the expression being referenced is scalar, it will be automatically promoted to a query by the expression def translation
			// In this case, it must be demoted back to a scalar expression with a subquery access.
			if (!(node.ResultType is ListType) && !(node.ResultType is ObjectType))
			{
				var selectExpression = new SQLModel.SelectExpression();
				selectExpression.SelectClause = new SQLModel.SelectClause();
				selectExpression.SelectClause.Columns.Add(new SQLModel.ColumnExpression(new SQLModel.QualifiedFieldExpression("value")));
				selectExpression.FromClause = new SQLModel.CalculusFromClause(new SQLModel.TableSpecifier(result));

				// If the result type is also boolean, the expression will be converted to a 1 or 0, so it must be demoted back to an actual boolean-valued expression
				if (DataTypes.Equal(node.ResultType, DataTypes.Boolean))
				{
					return SQLTranslationUtilities.DemoteBooleanValuedExpression(selectExpression);
				}

				return selectExpression;
			}

			return result;
		}
		public object Translate(TranslationContext context, ASTNode node)
		{
			var result = new SQLModel.TableExpression();

			// TODO: Handle Cardinality
			// TODO: Handle whether we are in a FromClause context.
			var sqlContext = (SQLTranslationContext)context;
			result.TableName = sqlContext.GetExpressionObjectName(String.Format("{0}.{1}", node.GetAttribute<string>("libraryName", sqlContext.ArtifactName), node.GetAttribute<string>("name")));

			return result;
		}
Example #3
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;
            }
        }