Example #1
0
        public override BuiltinExpansion ExpandMacro(OracularConfig config, OracularTable parent, OracularTable child, Reference reference, AstNode nestedSpec)
        {
            var withTable = String.Format ("Annotated{0}{1}", parent.Table, nestedSpec.Id);

            var relationship = child.GetRelationshipTo (parent.Table);
            if (relationship == null)
            {
                var message = String.Format ("unable to find relationship from {0} to {1}", child.Table, parent.Table);
                throw new OracularException (message);
            }

            var mainJoin = String.Format ("LEFT JOIN [{0}] ON [{0}].[{1}] = [{2}].[{3}]",
                withTable,
                parent.Id,
                parent.Table,
                parent.Id
            );

            var macroField = String.Format ("{0}{1}{2}", Name, child.Table, nestedSpec.Id);

            var builder = new Sqlizer (child, config);

            var nestedWhere = nestedSpec == null ? "" : String.Format("\nWHERE {0}",
                (invertNested ? nestedSpec.Invert() : nestedSpec).Walk(builder)
            );

            var nestedJoins = builder.JoinTables.Count() == 0 ? "" : "\n" + String.Join("\n",
                builder.JoinTables
            );

            var nestedQuery = String.Format (@"[{0}] AS (
            SELECT DISTINCT [{1}].[{2}], 1 [{3}]
            FROM [{1}]
            LEFT JOIN [{4}] ON [{4}].[{5}] = [{1}].[{2}]{6}{7}
            )", withTable, parent.Table, parent.Id, macroField, child.Table, relationship.Id, nestedJoins, nestedWhere);

            var expansion = new BuiltinExpansion ();

            expansion.With.AddRange (builder.CommonTableExpressions);

            expansion.With.Add (nestedQuery);
            expansion.Join.Add (mainJoin);

            expansion.Where = String.Format ("[{0}].[{1}]{2}", withTable, macroField, suffix);

            return expansion;
        }