/Rhino.Etl.Dsl/Macros/GroupByMacro.cs

http://github.com/ayende/rhino-etl · C# · 68 lines · 48 code · 8 blank · 12 comment · 2 complexity · 938f2ef7408d5f07fff22bd40de48479 MD5 · raw file

  1. namespace Rhino.Etl.Dsl.Macros
  2. {
  3. using System.Collections.Generic;
  4. using Boo.Lang.Compiler;
  5. using Boo.Lang.Compiler.Ast;
  6. using Rhino.Etl.Core.Operations;
  7. /// <summary>
  8. /// Creates the <see cref="AbstractAggregationOperation.GetColumnsToGroupBy"/> method from the reference
  9. /// expressions
  10. /// </summary>
  11. public class GroupByMacro : AbstractChildMacro
  12. {
  13. /// <summary>
  14. /// Initializes a new instance of the <see cref="GroupByMacro"/> class.
  15. /// </summary>
  16. public GroupByMacro() : base("aggregate")
  17. {
  18. }
  19. /// <summary>
  20. /// Perform the actual expansion of the macro
  21. /// </summary>
  22. /// <param name="macro">The macro.</param>
  23. /// <returns></returns>
  24. protected override Statement DoExpand(MacroStatement macro)
  25. {
  26. List<string> columns = new List<string>();
  27. if(!macro.Body.IsEmpty)
  28. {
  29. Errors.Add(CompilerErrorFactory.CustomError(macro.LexicalInfo, "GroupBy cannot contain statements"));
  30. return null;
  31. }
  32. foreach (Expression argument in macro.Arguments)
  33. {
  34. ReferenceExpression expr = argument as ReferenceExpression;
  35. if(expr==null)
  36. {
  37. Errors.Add(CompilerErrorFactory.CustomError(macro.LexicalInfo, "GroupBy arguments must be refernce expressions. Example: groupBy name, surname"));
  38. return null;
  39. }
  40. columns.Add(expr.Name);
  41. }
  42. Method method = CreateGetColumnsToGroupByMethod(macro, columns);
  43. ParentMethods.Add(method);
  44. return null;
  45. }
  46. private Method CreateGetColumnsToGroupByMethod(MacroStatement macro, IEnumerable<string> columns)
  47. {
  48. Method method = new Method("GetColumnsToGroupBy");
  49. method.Modifiers = TypeMemberModifiers.Override;
  50. ArrayLiteralExpression ale = new ArrayLiteralExpression(macro.LexicalInfo);
  51. ale.Type = new ArrayTypeReference(CodeBuilder.CreateTypeReference(typeof(string)));
  52. foreach (string column in columns)
  53. {
  54. ale.Items.Add(new StringLiteralExpression(column));
  55. }
  56. method.Body.Statements.Add(new ReturnStatement(ale));
  57. return method;
  58. }
  59. }
  60. }