DeveelDB  20151217
complete SQL database system, primarly developed for .NET/Mono frameworks
SqlExpressionSerializers.cs
Go to the documentation of this file.
1 //
2 // Copyright 2010-2015 Deveel
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 using System;
18 using System.Collections.Generic;
19 using System.IO;
20 using System.Linq;
21 
23 
24 namespace Deveel.Data.Sql.Expressions {
25  static class SqlExpressionSerializers {
27  Resolver = new SqlExpressionSerializerResolver();
28  }
29 
30  public static IObjectSerializerResolver Resolver { get; private set; }
31 
32  public static void Serialize(SqlExpression expression, BinaryWriter writer) {
33  if (expression == null) {
34  writer.Write((byte)0);
35  return;
36  }
37 
38  var expType = expression.GetType();
39  var expTypeName = expType.FullName;
40 
41  var serializer = Resolver.ResolveSerializer(expType) as IObjectBinarySerializer;
42  if (serializer == null)
43  throw new InvalidOperationException(String.Format("Cannot find a valid binary serializer for expression of type '{0}'", expType));
44 
45  writer.Write((byte)1);
46  writer.Write(expTypeName);
47 
48  serializer.Serialize(expression, writer);
49  }
50 
51  public static SqlExpression Deserialize(BinaryReader reader) {
52  var status = reader.ReadByte();
53  if (status == 0)
54  return null;
55 
56  var typeName = reader.ReadString();
57 #if PCL
58  var type = Type.GetType(typeName, true);
59 #else
60  var type = Type.GetType(typeName, true, true);
61 #endif
62 
63  var serializer = Resolver.ResolveSerializer(type) as IObjectBinarySerializer;
64  if (serializer == null)
65  throw new InvalidOperationException(String.Format("Cannot find a valid binary serializer for expression of type '{0}'", type));
66 
67  return (SqlExpression) serializer.Deserialize(reader);
68  }
69 
70  #region SqlExpressionSerializerResolver
71 
73  protected override void Init() {
74  Register<SqlConstantExpression, SqlConstantExpressionSerializer>();
75  Register<SqlReferenceExpression, SqlReferenceExpressionSerializer>();
76  Register<SqlVariableReferenceExpression, SqlVariableReferenceExpressionSerializer>();
77  Register<SqlAssignExpression, SqlAssignExpressionSerializer>();
78  Register<SqlFunctionCallExpression, SqlFunctionCallExpressionSerializer>();
79  Register<SqlUnaryExpression, SqlUnaryExpressionSerializer>();
80  Register<SqlBinaryExpression, SqlBinaryExpressionSerializer>();
81  Register<SqlQueryExpression, SqlQueryExpressionSerializer>();
82  Register<SqlConditionalExpression, SqlConditionalExpressionSerializer>();
83  Register<SqlTupleExpression, SqlTupleExpressionSerializer>();
84  }
85  }
86 
87  #endregion
88 
89  #region SqlExpressionSerializer
90 
91  abstract class SqlExpressionSerializer<TExpression> : ObjectBinarySerializer<TExpression> where TExpression : SqlExpression {
92  protected static void WriteExpression(SqlExpression expression, BinaryWriter writer) {
93  SqlExpressionSerializers.Serialize(expression, writer);
94  }
95 
96  protected static void WriteExpressions(SqlExpression[] expressions, BinaryWriter writer) {
97  var expCount = expressions == null ? 0 : expressions.Length;
98 
99  writer.Write(expCount);
100 
101  if (expressions != null) {
102  for (int i = 0; i < expCount; i++) {
103  WriteExpression(expressions[i], writer);
104  }
105  }
106  }
107 
108  protected static SqlExpression ReadExpression(BinaryReader reader) {
109  return SqlExpressionSerializers.Deserialize(reader);
110  }
111 
112  protected static SqlExpression[] ReadExpressions(BinaryReader reader) {
113  var expCount = reader.ReadInt32();
114 
115  var exps = new SqlExpression[expCount];
116  for (int i = 0; i < expCount; i++) {
117  exps[i] = ReadExpression(reader);
118  }
119 
120  return exps;
121  }
122  }
123 
124  #endregion
125 
126  #region SqlConstantExpressionSerializer
127 
129  public override void Serialize(SqlConstantExpression expression, BinaryWriter writer) {
130  DataObject.Serialize(expression.Value, writer);
131  }
132 
133  public override SqlConstantExpression Deserialize(BinaryReader reader) {
134  var value = DataObject.Deserialize(reader, null);
135  return SqlExpression.Constant(value);
136  }
137  }
138 
139  #endregion
140 
141  #region SqlReferenceExpressionSerializer
142 
144  public override void Serialize(SqlReferenceExpression expression, BinaryWriter writer) {
145  ObjectName.Serialize(expression.ReferenceName, writer);
146  }
147 
148  public override SqlReferenceExpression Deserialize(BinaryReader reader) {
149  var name = ObjectName.Deserialize(reader);
150  return SqlExpression.Reference(name);
151  }
152  }
153 
154  #endregion
155 
156  #region SqlVariableReferenceExpressionSerializer
157 
158  class SqlVariableReferenceExpressionSerializer : SqlExpressionSerializer<SqlVariableReferenceExpression> {
159  public override void Serialize(SqlVariableReferenceExpression expression, BinaryWriter writer) {
160  writer.Write(expression.VariableName);
161  }
162 
163  public override SqlVariableReferenceExpression Deserialize(BinaryReader reader) {
164  var varName = reader.ReadString();
165  return SqlExpression.VariableReference(varName);
166  }
167  }
168 
169  #endregion
170 
171  #region SqlAssignExpressionSerializer
172 
174  public override void Serialize(SqlAssignExpression expression, BinaryWriter writer) {
177  }
178 
179  public override SqlAssignExpression Deserialize(BinaryReader reader) {
180  var reference = SqlExpressionSerializers.Deserialize(reader);
181  var value = SqlExpressionSerializers.Deserialize(reader);
182 
183  return SqlExpression.Assign(reference, value);
184  }
185  }
186 
187  #endregion
188 
189  #region SqlFunctionCallExpressionSerializer
190 
192  public override void Serialize(SqlFunctionCallExpression expression, BinaryWriter writer) {
193  ObjectName.Serialize(expression.FunctioName, writer);
194  WriteExpressions(expression.Arguments, writer);
195 
196  }
197 
198  public override SqlFunctionCallExpression Deserialize(BinaryReader reader) {
199  var functionName = ObjectName.Deserialize(reader);
200  var args = ReadExpressions(reader);
201 
202  return SqlExpression.FunctionCall(functionName, args);
203  }
204  }
205 
206  #endregion
207 
208  #region SqlUnaryExpressionSerializer
209 
211  public override void Serialize(SqlUnaryExpression expression, BinaryWriter writer) {
212  writer.Write((byte)expression.ExpressionType);
213  WriteExpression(expression.Operand, writer);
214  }
215 
216  public override SqlUnaryExpression Deserialize(BinaryReader reader) {
217  var expType = (SqlExpressionType) reader.ReadByte();
218  var exp = ReadExpression(reader);
219 
220  return SqlExpression.Unary(expType, exp);
221  }
222  }
223 
224  #endregion
225 
226  #region SqlBinaryExpressionSerializer
227 
229  public override void Serialize(SqlBinaryExpression expression, BinaryWriter writer) {
230  WriteExpression(expression.Left, writer);
231  writer.Write((byte)expression.ExpressionType);
232  WriteExpression(expression.Right, writer);
233  }
234 
235  public override SqlBinaryExpression Deserialize(BinaryReader reader) {
236  var left = ReadExpression(reader);
237  var exptype = (SqlExpressionType) reader.ReadByte();
238  var right = ReadExpression(reader);
239 
240  return SqlExpression.Binary(left, exptype, right);
241  }
242  }
243 
244  #endregion
245 
246  #region SqlQueryExpressionSerializer
247 
249  public override void Serialize(SqlQueryExpression expression, BinaryWriter writer) {
250  SerializeSelectColumns(expression.SelectColumns, writer);
251 
252  writer.Write(expression.Distinct ? (byte)1 : (byte)0);
253 
254  if (expression.FromClause != null) {
255  writer.Write((byte) 1);
256  FromClause.Serialize(expression.FromClause, writer);
257  } else {
258  writer.Write((byte)0);
259  }
260 
261  if (expression.WhereExpression != null) {
262  writer.Write((byte) 1);
263  SqlExpression.Serialize(expression.WhereExpression, writer);
264  } else {
265  writer.Write((byte)0);
266  }
267 
268  if (expression.GroupBy != null) {
269  throw new NotImplementedException();
270  }
271 
272  if (expression.GroupMax != null) {
273  writer.Write((byte) 1);
274  ObjectName.Serialize(expression.GroupMax, writer);
275  } else {
276  writer.Write((byte)0);
277  }
278 
279  if (expression.HavingExpression != null) {
280  writer.Write((byte) 1);
281  SqlExpression.Serialize(expression.HavingExpression, writer);
282  } else {
283  writer.Write((byte)0);
284  }
285 
286  // TODO: Composites!!
287  }
288 
289  private void SerializeSelectColumns(IEnumerable<SelectColumn> selectColumns, BinaryWriter writer) {
290  var list = selectColumns == null ? new List<SelectColumn>() : selectColumns.ToList();
291  writer.Write(list.Count);
292  for (int i = 0; i < list.Count; i++) {
293  var column = list[i];
294  SelectColumn.Serialize(column, writer);
295  }
296  }
297 
298  public override SqlQueryExpression Deserialize(BinaryReader reader) {
299  var selectColumns = DeserializeSelectColumns(reader);
300 
301  var queryExp = new SqlQueryExpression(selectColumns);
302 
303  var isDistinct = reader.ReadByte() == 1;
304  queryExp.Distinct = isDistinct;
305 
306  var hasFrom = reader.ReadByte() == 1;
307  if (hasFrom) {
308  queryExp.FromClause = FromClause.Deserialize(reader);
309  }
310 
311  var hasWhere = reader.ReadByte() == 1;
312  if (hasWhere)
313  queryExp.WhereExpression = SqlExpression.Deserialize(reader);
314 
315  var hasGroupMax = reader.ReadByte() == 1;
316  if (hasGroupMax)
317  queryExp.GroupMax = ObjectName.Deserialize(reader);
318 
319  var hasHaving = reader.ReadByte() == 1;
320  if (hasHaving)
321  queryExp.HavingExpression = SqlExpression.Deserialize(reader);
322 
323  return queryExp;
324  }
325 
326  private IEnumerable<SelectColumn> DeserializeSelectColumns(BinaryReader reader) {
327  var count = reader.ReadInt32();
328  var columns = new SelectColumn[count];
329  for (int i = 0; i < count; i++) {
330  columns[i] = SelectColumn.Deserialize(reader);
331  }
332 
333  return columns;
334  }
335  }
336 
337  #endregion
338 
339  #region SqlConditionalExpressionSerializer
340 
342  public override void Serialize(SqlConditionalExpression expression, BinaryWriter writer) {
343  WriteExpression(expression.TestExpression, writer);
344  WriteExpression(expression.TrueExpression, writer);
345  WriteExpression(expression.FalseExpression, writer);
346  }
347 
348  public override SqlConditionalExpression Deserialize(BinaryReader reader) {
349  var testExp = ReadExpression(reader);
350  var trueExp = ReadExpression(reader);
351  var falseExp = ReadExpression(reader);
352 
353  return SqlExpression.Conditional(testExp, trueExp, falseExp);
354  }
355  }
356 
357  #endregion
358 
359  #region SqlTupleExpressionSerializer
360 
362  public override void Serialize(SqlTupleExpression expression, BinaryWriter writer) {
363  WriteExpressions(expression.Expressions, writer);
364  }
365 
366  public override SqlTupleExpression Deserialize(BinaryReader reader) {
367  var exps = ReadExpressions(reader);
368  return SqlExpression.Tuple(exps);
369  }
370  }
371 
372  #endregion
373  }
374 }
static void Serialize(SqlExpression expression, BinaryWriter writer)
ObjectName ReferenceName
Gets the name of the object referenced by the expression.
SqlExpression Operand
Gets the operand expression that is computed.
An expression that references an object within a context.
Handles expressions computed against an unary operator.
override void Serialize(SqlQueryExpression expression, BinaryWriter writer)
override void Serialize(SqlConstantExpression expression, BinaryWriter writer)
static void Serialize(ObjectName objectName, Stream stream)
Definition: ObjectName.cs:287
override void Serialize(SqlAssignExpression expression, BinaryWriter writer)
override void Serialize(SqlConditionalExpression expression, BinaryWriter writer)
static SqlTupleExpression Tuple(SqlExpression[] expressions)
static SqlVariableReferenceExpression VariableReference(string varName)
Describes the name of an object within a database.
Definition: ObjectName.cs:44
static void Serialize(DataObject obj, BinaryWriter writer)
Definition: DataObject.cs:924
static ObjectName Deserialize(Stream stream)
Definition: ObjectName.cs:311
static SqlAssignExpression Assign(SqlExpression reference, SqlExpression valueExpression)
static SqlConditionalExpression Conditional(SqlExpression testExpression, SqlExpression ifTrue)
static void Serialize(SqlExpression expression, BinaryWriter writer)
SqlExpressionType
All the possible type of SqlExpression supported
static void WriteExpressions(SqlExpression[] expressions, BinaryWriter writer)
DataObject Value
Gets the constant value of the expression.
override void Serialize(SqlFunctionCallExpression expression, BinaryWriter writer)
A user-defined TYPE that holds complex objects in a database column.
static SqlExpression Deserialize(BinaryReader reader)
A container for the FROM clause of a select statement.
Definition: FromClause.cs:32
static SqlExpression Deserialize(BinaryReader reader)
Represents a dynamic object that encapsulates a defined SqlType and a compatible constant ISqlObject ...
Definition: DataObject.cs:35
override void Serialize(SqlReferenceExpression expression, BinaryWriter writer)
Represents a column selected to be in the output of a select statement.
Definition: SelectColumn.cs:31
override void Serialize(SqlBinaryExpression expression, BinaryWriter writer)
void Serialize(object obj, BinaryWriter writer)
An expression that holds a constant value.
static SqlReferenceExpression Reference(ObjectName objectName)
override void Serialize(SqlTupleExpression expression, BinaryWriter writer)
static DataObject Deserialize(BinaryReader reader, ITypeResolver resolver)
Definition: DataObject.cs:935
void SerializeSelectColumns(IEnumerable< SelectColumn > selectColumns, BinaryWriter writer)
static SqlBinaryExpression Binary(SqlExpression left, SqlExpressionType expressionType, SqlExpression right)
Defines the base class for instances that represent SQL expression tree nodes.
override void Serialize(SqlVariableReferenceExpression expression, BinaryWriter writer)
static SqlConstantExpression Constant(object value)
static SqlFunctionCallExpression FunctionCall(ObjectName functionName)
override void Serialize(SqlUnaryExpression expression, BinaryWriter writer)
static void WriteExpression(SqlExpression expression, BinaryWriter writer)
static SqlUnaryExpression Unary(SqlExpressionType expressionType, SqlExpression operand)