DeveelDB  20151217
complete SQL database system, primarly developed for .NET/Mono frameworks
DeveelDbFormatter.cs
Go to the documentation of this file.
1 using System;
2 using System.Collections.Generic;
3 using System.Linq.Expressions;
4 
5 using IQToolkit.Data.Common;
6 
7 namespace Deveel.Data.Linq {
8  class DeveelDbFormatter : SqlFormatter {
10  : base(language) {
11  }
12 
13  public static new string Format(Expression expression) {
14  return Format(expression, new DeveelDbLanguage());
15  }
16 
17  public static string Format(Expression expression, DeveelDbLanguage language) {
18  var formatter = new DeveelDbFormatter(language);
19  formatter.Visit(expression);
20  return formatter.ToString();
21  }
22 
23  protected override Expression VisitSelect(SelectExpression @select) {
24  AddAliases(select.From);
25 
26  Write("SELECT ");
27 
28  if (select.IsDistinct)
29  Write("DISTINCT ");
30 
31  WriteColumns(select.Columns);
32 
33  if (select.From != null) {
34  WriteLine(Indentation.Same);
35  Write("FROM ");
36  VisitSource(select.From);
37  }
38 
39  if (select.Where != null &&
40  (select.GroupBy == null || select.GroupBy.Count ==0)) {
41  WriteLine(Indentation.Same);
42  Write("WHERE ");
43  VisitPredicate(select.Where);
44  }
45 
46  if (select.GroupBy != null && select.GroupBy.Count > 0) {
47  WriteLine(Indentation.Same);
48  Write("GROUP BY ");
49 
50  for (int i = 0, n = select.GroupBy.Count; i < n; i++) {
51  if (i > 0) {
52  Write(", ");
53  }
54 
55  VisitValue(select.GroupBy[i]);
56  }
57 
58  if (select.Where != null) {
59  WriteLine(Indentation.Same);
60  Write("HAVING ");
61  VisitPredicate(select.Where);
62  }
63  }
64  if (select.OrderBy != null && select.OrderBy.Count > 0) {
65  WriteLine(Indentation.Same);
66  Write("ORDER BY ");
67 
68  for (int i = 0, n = select.OrderBy.Count; i < n; i++) {
69  OrderExpression exp = select.OrderBy[i];
70  if (i > 0) {
71  Write(", ");
72  }
73 
74  VisitValue(exp.Expression);
75 
76  if (exp.OrderType != OrderType.Ascending)
77  Write(" DESC");
78  }
79  }
80 
81  if (select.Take != null) {
82  WriteLine(Indentation.Same);
83  Write("LIMIT ");
84  if (select.Skip == null) {
85  Write("0");
86  } else {
87  Write(select.Skip);
88  }
89 
90  Write(", ");
91  Visit(select.Take);
92  }
93 
94  return select;
95  }
96 
97  protected override string GetOperator(BinaryExpression b) {
98  if (b.NodeType == ExpressionType.Add && b.Type == typeof (string))
99  return "||";
100 
101  return base.GetOperator(b);
102  }
103 
104  protected override Expression VisitMethodCall(MethodCallExpression m) {
105  var declaringType = m.Method.DeclaringType;
106 
107  if (declaringType == typeof (string)) {
108  switch (m.Method.Name) {
109  case "StartsWith": {
110  Visit(m.Object);
111  Write(" LIKE '");
112  Visit(m.Arguments[0]);
113  Write("%'");
114  return m;
115  }
116  case "EndsWith": {
117  Visit(m.Object);
118  Write(" LIKE '%");
119  Visit(m.Arguments[0]);
120  Write("'");
121  return m;
122  }
123  case "Contains": {
124  Visit(m.Object);
125  Write(" LIKE '%");
126  Visit(m.Arguments[0]);
127  Write("%'");
128  return m;
129  }
130  case "Concat": {
131  IList<Expression> args = m.Arguments;
132  if (args.Count == 1 && args[0].NodeType == ExpressionType.NewArrayInit) {
133  args = ((NewArrayExpression) args[0]).Expressions;
134  }
135  for (int i = 0, n = args.Count; i < n; i++) {
136  if (i > 0)
137  Write(" || ");
138 
139  Visit(args[i]);
140  }
141 
142  return m;
143  }
144  case "IsNullOrEmpty": {
145  Visit(m.Arguments[0]);
146  Write(" IS NULL OR ");
147  Visit(m.Arguments[0]);
148  Write(" = ''");
149  return m;
150  }
151  }
152  }
153 
154  return base.VisitMethodCall(m);
155  }
156 
157  protected override Expression VisitMemberAccess(MemberExpression m) {
158  var declaringType = m.Member.DeclaringType;
159  if (declaringType == typeof (string)) {
160  switch (m.Member.Name) {
161  case "Length": {
162  Write("LENGTH(");
163  Visit(m.Expression);
164  Write(")");
165  return m;
166  }
167  }
168  } else if (declaringType == typeof (DateTime) ||
169  declaringType == typeof (DateTimeOffset)) {
170  switch (m.Member.Name) {
171  case "Day": {
172  Write("DAY(");
173  Visit(m.Expression);
174  Write(")");
175  return m;
176  }
177  case "Year": {
178  Write("YEAR(");
179  Visit(m.Expression);
180  Write(")");
181  return m;
182  }
183  // TODO: Continue with date function
184  }
185  } else if (declaringType == typeof (TimeSpan)) {
186 
187  }
188 
189  return base.VisitMemberAccess(m);
190  }
191  }
192 }
override Expression VisitMethodCall(MethodCallExpression m)
static new string Format(Expression expression)
static string Format(Expression expression, DeveelDbLanguage language)
override string GetOperator(BinaryExpression b)
override Expression VisitMemberAccess(MemberExpression m)
DeveelDbFormatter(DeveelDbLanguage language)
override Expression VisitSelect(SelectExpression @select)