comparison Source/ServiceModel/LinqServiceSerializer.cs @ 0:f990fcb411a9

Копия текущей версии из github
author cin
date Thu, 27 Mar 2014 21:46:09 +0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:f990fcb411a9
1 using System;
2 using System.Collections;
3 using System.Collections.Generic;
4 using System.Data;
5 using System.Diagnostics;
6 using System.Globalization;
7 using System.Linq;
8 using System.Text;
9
10 namespace BLToolkit.ServiceModel
11 {
12 using Data.Sql;
13 using Data.Sql.SqlProvider;
14 using Mapping;
15 using Reflection;
16
17 static class LinqServiceSerializer
18 {
19 #region Public Members
20
21 public static string Serialize(SqlQuery query, SqlParameter[] parameters)
22 {
23 return new QuerySerializer().Serialize(query, parameters);
24 }
25
26 public static LinqServiceQuery Deserialize(string str)
27 {
28 return new QueryDeserializer().Deserialize(str);
29 }
30
31 public static string Serialize(LinqServiceResult result)
32 {
33 return new ResultSerializer().Serialize(result);
34 }
35
36 public static LinqServiceResult DeserializeResult(string str)
37 {
38 return new ResultDeserializer().DeserializeResult(str);
39 }
40
41 public static string Serialize(string[] data)
42 {
43 return new StringArraySerializer().Serialize(data);
44 }
45
46 public static string[] DeserializeStringArray(string str)
47 {
48 return new StringArrayDeserializer().Deserialize(str);
49 }
50
51 #endregion
52
53 #region SerializerBase
54
55 const int _paramIndex = -1;
56 const int _typeIndex = -2;
57 const int _typeArrayIndex = -3;
58
59 class SerializerBase
60 {
61 protected readonly StringBuilder Builder = new StringBuilder();
62 protected readonly Dictionary<object,int> Dic = new Dictionary<object,int>();
63 protected int Index;
64
65 string ConvertToString(Type type, object value)
66 {
67 switch (Type.GetTypeCode(type))
68 {
69 case TypeCode.Decimal : return ((decimal) value).ToString(CultureInfo.InvariantCulture);
70 case TypeCode.Double : return ((double) value).ToString(CultureInfo.InvariantCulture);
71 case TypeCode.Single : return ((float) value).ToString(CultureInfo.InvariantCulture);
72 case TypeCode.DateTime : return ((DateTime)value).ToString("o");
73 }
74
75 if (type == typeof(DateTimeOffset))
76 return ((DateTimeOffset)value).ToString("o");
77
78 return Common.Convert.ToString(value);
79 }
80
81 protected void Append(Type type, object value)
82 {
83 Append(type);
84
85 if (value == null)
86 Append((string)null);
87 else if (!type.IsArray)
88 {
89 Append(ConvertToString(type, value));
90 }
91 else
92 {
93 var elementType = type.GetElementType();
94
95 Builder.Append(' ');
96
97 var len = Builder.Length;
98 var cnt = 0;
99
100 if (elementType.IsArray)
101 foreach (var val in (IEnumerable)value)
102 {
103 Append(elementType, val);
104 cnt++;
105 }
106 else
107 foreach (var val in (IEnumerable)value)
108 {
109 if (val == null)
110 Append((string)null);
111 else
112 Append(ConvertToString(val.GetType(), val));
113 cnt++;
114 }
115
116 Builder.Insert(len, cnt.ToString(CultureInfo.CurrentCulture));
117 }
118 }
119
120 protected void Append(int value)
121 {
122 Builder.Append(' ').Append(value);
123 }
124
125 protected void Append(Type value)
126 {
127 Builder.Append(' ').Append(value == null ? 0 : GetType(value));
128 }
129
130 protected void Append(bool value)
131 {
132 Builder.Append(' ').Append(value ? '1' : '0');
133 }
134
135 protected void Append(IQueryElement element)
136 {
137 Builder.Append(' ').Append(element == null ? 0 : Dic[element]);
138 }
139
140 protected void Append(string str)
141 {
142 Builder.Append(' ');
143
144 if (str == null)
145 {
146 Builder.Append('-');
147 }
148 else if (str.Length == 0)
149 {
150 Builder.Append('0');
151 }
152 else
153 {
154 Builder
155 .Append(str.Length)
156 .Append(':')
157 .Append(str);
158 }
159 }
160
161 protected int GetType(Type type)
162 {
163 if (type == null)
164 return 0;
165
166 int idx;
167
168 if (!Dic.TryGetValue(type, out idx))
169 {
170 if (type.IsArray)
171 {
172 var elementType = GetType(type.GetElementType());
173
174 Dic.Add(type, idx = ++Index);
175
176 Builder
177 .Append(idx)
178 .Append(' ')
179 .Append(_typeArrayIndex)
180 .Append(' ')
181 .Append(elementType);
182 }
183 else
184 {
185 Dic.Add(type, idx = ++Index);
186
187 Builder
188 .Append(idx)
189 .Append(' ')
190 .Append(_typeIndex);
191
192 Append(type.FullName);
193 }
194
195 Builder.AppendLine();
196 }
197
198 return idx;
199 }
200 }
201
202 #endregion
203
204 #region DeserializerBase
205
206 public class DeserializerBase
207 {
208 protected readonly Dictionary<int,object> Dic = new Dictionary<int,object>();
209
210 protected string Str;
211 protected int Pos;
212
213 protected char Peek()
214 {
215 return Str[Pos];
216 }
217
218 char Next()
219 {
220 return Str[++Pos];
221 }
222
223 protected bool Get(char c)
224 {
225 if (Peek() == c)
226 {
227 Pos++;
228 return true;
229 }
230
231 return false;
232 }
233
234 protected int ReadInt()
235 {
236 Get(' ');
237
238 var minus = Get('-');
239 var value = 0;
240
241 for (var c = Peek(); char.IsDigit(c); c = Next())
242 value = value * 10 + (c - '0');
243
244 return minus ? -value : value;
245 }
246
247 protected int? ReadCount()
248 {
249 Get(' ');
250
251 if (Get('-'))
252 return null;
253
254 var value = 0;
255
256 for (var c = Peek(); char.IsDigit(c); c = Next())
257 value = value * 10 + (c - '0');
258
259 return value;
260 }
261
262 protected string ReadString()
263 {
264 Get(' ');
265
266 var c = Peek();
267
268 if (c == '-')
269 {
270 Pos++;
271 return null;
272 }
273
274 if (c == '0')
275 {
276 Pos++;
277 return string.Empty;
278 }
279
280 var len = ReadInt();
281 var value = Str.Substring(++Pos, len);
282
283 Pos += len;
284
285 return value;
286 }
287
288 protected bool ReadBool()
289 {
290 Get(' ');
291
292 var value = Peek() == '1';
293
294 Pos++;
295
296 return value;
297 }
298
299 protected T Read<T>()
300 where T : class
301 {
302 var idx = ReadInt();
303 return idx == 0 ? null : (T)Dic[idx];
304 }
305
306 protected T[] ReadArray<T>()
307 where T : class
308 {
309 var count = ReadCount();
310
311 if (count == null)
312 return null;
313
314 var items = new T[count.Value];
315
316 for (var i = 0; i < count; i++)
317 items[i] = Read<T>();
318
319 return items;
320 }
321
322 protected List<T> ReadList<T>()
323 where T : class
324 {
325 var count = ReadCount();
326
327 if (count == null)
328 return null;
329
330 var items = new List<T>(count.Value);
331
332 for (var i = 0; i < count; i++)
333 items.Add(Read<T>());
334
335 return items;
336 }
337
338 protected void NextLine()
339 {
340 while (Pos < Str.Length && (Peek() == '\n' || Peek() == '\r'))
341 Pos++;
342 }
343
344 interface IDeserializerHelper
345 {
346 object GetArray(DeserializerBase deserializer);
347 }
348
349 class DeserializerHelper<T> : IDeserializerHelper
350 {
351 public object GetArray(DeserializerBase deserializer)
352 {
353 var count = deserializer.ReadCount();
354
355 if (count == null)
356 return null;
357
358 var arr = new T[count.Value];
359 var type = typeof(T);
360
361 for (var i = 0; i < count.Value; i++)
362 arr[i] = (T)deserializer.ReadValue(type);
363
364 return arr;
365 }
366 }
367
368 static readonly Dictionary<Type,Func<DeserializerBase,object>> _arrayDeserializers =
369 new Dictionary<Type,Func<DeserializerBase,object>>();
370
371 protected object ReadValue(Type type)
372 {
373 if (type == null)
374 return ReadString();
375
376 if (type.IsArray)
377 {
378 var elem = type.GetElementType();
379
380 Func<DeserializerBase,object> deserializer;
381
382 lock (_arrayDeserializers)
383 {
384 if (!_arrayDeserializers.TryGetValue(elem, out deserializer))
385 {
386 var helper = (IDeserializerHelper)Activator.CreateInstance(typeof(DeserializerHelper<>).MakeGenericType(elem));
387 _arrayDeserializers.Add(elem, deserializer = helper.GetArray);
388 }
389 }
390
391 return deserializer(this);
392 }
393
394 var str = ReadString();
395
396 switch (Type.GetTypeCode(type))
397 {
398 case TypeCode.Decimal : return decimal. Parse(str, CultureInfo.InvariantCulture);
399 case TypeCode.Double : return double. Parse(str, CultureInfo.InvariantCulture);
400 case TypeCode.Single : return float. Parse(str, CultureInfo.InvariantCulture);
401 case TypeCode.DateTime : return DateTime.ParseExact(str, "o", CultureInfo.InvariantCulture);
402 }
403
404 if (type == typeof(DateTimeOffset))
405 return DateTimeOffset.ParseExact(str, "o", CultureInfo.InvariantCulture);
406
407 return Common.Convert.ChangeTypeFromString(str, type);
408 }
409
410 protected readonly List<string> UnresolvedTypes = new List<string>();
411
412 protected Type ResolveType(string str)
413 {
414 if (str == null)
415 return null;
416
417 var type = Type.GetType(str, false);
418
419 if (type == null)
420 {
421 if (str == "System.Data.Linq.Binary")
422 return typeof(System.Data.Linq.Binary);
423
424 #if !SILVERLIGHT
425
426 type = LinqService.TypeResolver(str);
427
428 #endif
429
430 if (type == null)
431 {
432 UnresolvedTypes.Add(str);
433
434 Debug.WriteLine(
435 string.Format("Type '{0}' cannot be resolved. Use LinqService.TypeResolver to resolve unknown types.", str),
436 "LinqServiceSerializer");
437 }
438 }
439
440 return type;
441 }
442 }
443
444 #endregion
445
446 #region QuerySerializer
447
448 class QuerySerializer : SerializerBase
449 {
450 public string Serialize(SqlQuery query, SqlParameter[] parameters)
451 {
452 var visitor = new QueryVisitor();
453
454 visitor.Visit(query, Visit);
455
456 foreach (var parameter in parameters)
457 if (!Dic.ContainsKey(parameter))
458 Visit(parameter);
459
460 Builder
461 .Append(++Index)
462 .Append(' ')
463 .Append(_paramIndex);
464
465 Append(parameters.Length);
466
467 foreach (var parameter in parameters)
468 Append(parameter);
469
470 Builder.AppendLine();
471
472 return Builder.ToString();
473 }
474
475 void Visit(IQueryElement e)
476 {
477 switch (e.ElementType)
478 {
479 case QueryElementType.SqlField :
480 {
481 var fld = (SqlField)e;
482
483 if (fld != fld.Table.All)
484 {
485 GetType(fld.SystemType);
486
487 if (fld.MemberMapper != null)
488 GetType(fld.MemberMapper.MemberAccessor.TypeAccessor.OriginalType);
489 }
490
491 break;
492 }
493
494 case QueryElementType.SqlParameter :
495 {
496 var p = (SqlParameter)e;
497 var t = p.Value == null ? p.SystemType : p.Value.GetType();
498
499 if (p.Value == null || t.IsArray || t == typeof(string) || !(p.Value is IEnumerable))
500 {
501 GetType(t);
502 }
503 else
504 {
505 var elemType = TypeHelper.GetElementType(t);
506 GetType(GetArrayType(elemType));
507 }
508
509 //if (p.EnumTypes != null)
510 // foreach (var type in p.EnumTypes)
511 // GetType(type);
512
513 break;
514 }
515
516 case QueryElementType.SqlFunction : GetType(((SqlFunction) e).SystemType); break;
517 case QueryElementType.SqlExpression : GetType(((SqlExpression) e).SystemType); break;
518 case QueryElementType.SqlBinaryExpression : GetType(((SqlBinaryExpression)e).SystemType); break;
519 case QueryElementType.SqlDataType : GetType(((SqlDataType) e).Type); break;
520 case QueryElementType.SqlValue : GetType(((SqlValue) e).SystemType); break;
521 case QueryElementType.SqlTable : GetType(((SqlTable) e).ObjectType); break;
522 }
523
524 Dic.Add(e, ++Index);
525
526 Builder
527 .Append(Index)
528 .Append(' ')
529 .Append((int)e.ElementType);
530
531 switch (e.ElementType)
532 {
533 case QueryElementType.SqlField :
534 {
535 var elem = (SqlField)e;
536
537 Append(elem.SystemType);
538 Append(elem.Name);
539 Append(elem.PhysicalName);
540 Append(elem.Nullable);
541 Append(elem.PrimaryKeyOrder);
542 Append(elem.IsIdentity);
543 Append(elem.IsUpdatable);
544 Append(elem.IsInsertable);
545 Append(elem.MemberMapper == null ? null : elem.MemberMapper.MemberAccessor.TypeAccessor.OriginalType);
546 Append(elem.MemberMapper == null ? null : elem.MemberMapper.Name);
547
548 break;
549 }
550
551 case QueryElementType.SqlFunction :
552 {
553 var elem = (SqlFunction)e;
554
555 Append(elem.SystemType);
556 Append(elem.Name);
557 Append(elem.Precedence);
558 Append(elem.Parameters);
559
560 break;
561 }
562
563 case QueryElementType.SqlParameter :
564 {
565 var elem = (SqlParameter)e;
566
567 Append(elem.Name);
568 Append(elem.IsQueryParameter);
569 Append((int)elem.DbType);
570 Append(elem.DbSize);
571
572 var type = elem.Value == null ? elem.SystemType : elem.Value.GetType();
573
574 if (elem.Value == null || type.IsArray || type == typeof(string) || !(elem.Value is IEnumerable))
575 {
576 Append(type, elem.Value);
577 }
578 else
579 {
580 var elemType = TypeHelper.GetElementType(type);
581 var value = ConvertIEnumerableToArray(elem.Value, elemType);
582
583 Append(GetArrayType(elemType), value);
584 }
585
586 break;
587 }
588
589 case QueryElementType.SqlExpression :
590 {
591 var elem = (SqlExpression)e;
592
593 Append(elem.SystemType);
594 Append(elem.Expr);
595 Append(elem.Precedence);
596 Append(elem.Parameters);
597
598 break;
599 }
600
601 case QueryElementType.SqlBinaryExpression :
602 {
603 var elem = (SqlBinaryExpression)e;
604
605 Append(elem.SystemType);
606 Append(elem.Expr1);
607 Append(elem.Operation);
608 Append(elem.Expr2);
609 Append(elem.Precedence);
610
611 break;
612 }
613
614 case QueryElementType.SqlValue :
615 {
616 var elem = (SqlValue)e;
617 Append(elem.SystemType, elem.Value);
618 break;
619 }
620
621 case QueryElementType.SqlDataType :
622 {
623 var elem = (SqlDataType)e;
624
625 Append((int)elem.SqlDbType);
626 Append(elem.Type);
627 Append(elem.Length);
628 Append(elem.Precision);
629 Append(elem.Scale);
630
631 break;
632 }
633
634 case QueryElementType.SqlTable :
635 {
636 var elem = (SqlTable)e;
637
638 Append(elem.SourceID);
639 Append(elem.Name);
640 Append(elem.Alias);
641 Append(elem.Database);
642 Append(elem.Owner);
643 Append(elem.PhysicalName);
644 Append(elem.ObjectType);
645
646 if (elem.SequenceAttributes == null)
647 Builder.Append(" -");
648 else
649 {
650 Append(elem.SequenceAttributes.Length);
651
652 foreach (var a in elem.SequenceAttributes)
653 {
654 Append(a.ProviderName);
655 Append(a.SequenceName);
656 }
657 }
658
659 Append(Dic[elem.All]);
660 Append(elem.Fields.Count);
661
662 foreach (var field in elem.Fields)
663 Append(Dic[field.Value]);
664
665 Append((int)elem.SqlTableType);
666
667 if (elem.SqlTableType != SqlTableType.Table)
668 {
669 if (elem.TableArguments == null)
670 Append(0);
671 else
672 {
673 Append(elem.TableArguments.Length);
674
675 foreach (var expr in elem.TableArguments)
676 Append(Dic[expr]);
677 }
678 }
679
680 break;
681 }
682
683 case QueryElementType.ExprPredicate :
684 {
685 var elem = (SqlQuery.Predicate.Expr)e;
686
687 Append(elem.Expr1);
688 Append(elem.Precedence);
689
690 break;
691 }
692
693 case QueryElementType.NotExprPredicate :
694 {
695 var elem = (SqlQuery.Predicate.NotExpr)e;
696
697 Append(elem.Expr1);
698 Append(elem.IsNot);
699 Append(elem.Precedence);
700
701 break;
702 }
703
704 case QueryElementType.ExprExprPredicate :
705 {
706 var elem = (SqlQuery.Predicate.ExprExpr)e;
707
708 Append(elem.Expr1);
709 Append((int)elem.Operator);
710 Append(elem.Expr2);
711
712 break;
713 }
714
715 case QueryElementType.LikePredicate :
716 {
717 var elem = (SqlQuery.Predicate.Like)e;
718
719 Append(elem.Expr1);
720 Append(elem.IsNot);
721 Append(elem.Expr2);
722 Append(elem.Escape);
723
724 break;
725 }
726
727 case QueryElementType.BetweenPredicate :
728 {
729 var elem = (SqlQuery.Predicate.Between)e;
730
731 Append(elem.Expr1);
732 Append(elem.IsNot);
733 Append(elem.Expr2);
734 Append(elem.Expr3);
735
736 break;
737 }
738
739 case QueryElementType.IsNullPredicate :
740 {
741 var elem = (SqlQuery.Predicate.IsNull)e;
742
743 Append(elem.Expr1);
744 Append(elem.IsNot);
745
746 break;
747 }
748
749 case QueryElementType.InSubQueryPredicate :
750 {
751 var elem = (SqlQuery.Predicate.InSubQuery)e;
752
753 Append(elem.Expr1);
754 Append(elem.IsNot);
755 Append(elem.SubQuery);
756
757 break;
758 }
759
760 case QueryElementType.InListPredicate :
761 {
762 var elem = (SqlQuery.Predicate.InList)e;
763
764 Append(elem.Expr1);
765 Append(elem.IsNot);
766 Append(elem.Values);
767
768 break;
769 }
770
771 case QueryElementType.FuncLikePredicate :
772 {
773 var elem = (SqlQuery.Predicate.FuncLike)e;
774 Append(elem.Function);
775 break;
776 }
777
778 case QueryElementType.SqlQuery :
779 {
780 var elem = (SqlQuery)e;
781
782 Append(elem.SourceID);
783 Append((int)elem.QueryType);
784 Append(elem.From);
785
786 var appendInsert = false;
787 var appendUpdate = false;
788 var appendDelete = false;
789 var appendSelect = false;
790
791 switch (elem.QueryType)
792 {
793 case QueryType.InsertOrUpdate :
794 appendUpdate = true;
795 appendInsert = true;
796 break;
797
798 case QueryType.Update :
799 appendUpdate = true;
800 break;
801
802 case QueryType.Delete :
803 appendDelete = true;
804 appendSelect = true;
805 break;
806
807 case QueryType.Insert :
808 appendInsert = true;
809 if (elem.From.Tables.Count != 0)
810 appendSelect = true;
811 break;
812
813 default :
814 appendSelect = true;
815 break;
816 }
817
818 Append(appendInsert); if (appendInsert) Append(elem.Insert);
819 Append(appendUpdate); if (appendUpdate) Append(elem.Update);
820 Append(appendDelete); if (appendDelete) Append(elem.Delete);
821 Append(appendSelect); if (appendSelect) Append(elem.Select);
822
823 Append(elem.Where);
824 Append(elem.GroupBy);
825 Append(elem.Having);
826 Append(elem.OrderBy);
827 Append(elem.ParentSql == null ? 0 : elem.ParentSql.SourceID);
828 Append(elem.IsParameterDependent);
829
830 if (!elem.HasUnion)
831 Builder.Append(" -");
832 else
833 Append(elem.Unions);
834
835 Append(elem.Parameters);
836
837 if (Dic.ContainsKey(elem.All))
838 Append(Dic[elem.All]);
839 else
840 Builder.Append(" -");
841
842 break;
843 }
844
845 case QueryElementType.Column :
846 {
847 var elem = (SqlQuery.Column) e;
848
849 Append(elem.Parent.SourceID);
850 Append(elem.Expression);
851 Append(elem._alias);
852
853 break;
854 }
855
856 case QueryElementType.SearchCondition :
857 Append(((SqlQuery.SearchCondition)e).Conditions);
858 break;
859
860 case QueryElementType.Condition :
861 {
862 var elem = (SqlQuery.Condition)e;
863
864 Append(elem.IsNot);
865 Append(elem.Predicate);
866 Append(elem.IsOr);
867
868 break;
869 }
870
871 case QueryElementType.TableSource :
872 {
873 var elem = (SqlQuery.TableSource)e;
874
875 Append(elem.Source);
876 Append(elem._alias);
877 Append(elem.Joins);
878
879 break;
880 }
881
882 case QueryElementType.JoinedTable :
883 {
884 var elem = (SqlQuery.JoinedTable)e;
885
886 Append((int)elem.JoinType);
887 Append(elem.Table);
888 Append(elem.IsWeak);
889 Append(elem.Condition);
890
891 break;
892 }
893
894 case QueryElementType.SelectClause :
895 {
896 var elem = (SqlQuery.SelectClause)e;
897
898 Append(elem.IsDistinct);
899 Append(elem.SkipValue);
900 Append(elem.TakeValue);
901 Append(elem.Columns);
902
903 break;
904 }
905
906 case QueryElementType.InsertClause :
907 {
908 var elem = (SqlQuery.InsertClause)e;
909
910 Append(elem.Items);
911 Append(elem.Into);
912 Append(elem.WithIdentity);
913
914 break;
915 }
916
917 case QueryElementType.UpdateClause :
918 {
919 var elem = (SqlQuery.UpdateClause)e;
920
921 Append(elem.Items);
922 Append(elem.Keys);
923 Append(elem.Table);
924
925 break;
926 }
927
928 case QueryElementType.DeleteClause :
929 {
930 var elem = (SqlQuery.DeleteClause)e;
931 Append(elem.Table);
932 break;
933 }
934
935 case QueryElementType.SetExpression :
936 {
937 var elem = (SqlQuery.SetExpression)e;
938
939 Append(elem.Column);
940 Append(elem.Expression);
941
942 break;
943 }
944
945 case QueryElementType.FromClause : Append(((SqlQuery.FromClause) e).Tables); break;
946 case QueryElementType.WhereClause : Append(((SqlQuery.WhereClause) e).SearchCondition); break;
947 case QueryElementType.GroupByClause : Append(((SqlQuery.GroupByClause)e).Items); break;
948 case QueryElementType.OrderByClause : Append(((SqlQuery.OrderByClause)e).Items); break;
949
950 case QueryElementType.OrderByItem :
951 {
952 var elem = (SqlQuery.OrderByItem)e;
953
954 Append(elem.Expression);
955 Append(elem.IsDescending);
956
957 break;
958 }
959
960 case QueryElementType.Union :
961 {
962 var elem = (SqlQuery.Union)e;
963
964 Append(elem.SqlQuery);
965 Append(elem.IsAll);
966
967 break;
968 }
969 }
970
971 Builder.AppendLine();
972 }
973
974 void Append<T>(ICollection<T> exprs)
975 where T : IQueryElement
976 {
977 if (exprs == null)
978 Builder.Append(" -");
979 else
980 {
981 Append(exprs.Count);
982
983 foreach (var e in exprs)
984 Append(Dic[e]);
985 }
986 }
987 }
988
989 #endregion
990
991 #region QueryDeserializer
992
993 public class QueryDeserializer : DeserializerBase
994 {
995 SqlQuery _query;
996 SqlParameter[] _parameters;
997
998 readonly Dictionary<int,SqlQuery> _queries = new Dictionary<int,SqlQuery>();
999 readonly List<Action> _actions = new List<Action>();
1000
1001 public LinqServiceQuery Deserialize(string str)
1002 {
1003 Str = str;
1004
1005 while (Parse()) {}
1006
1007 foreach (var action in _actions)
1008 action();
1009
1010 return new LinqServiceQuery { Query = _query, Parameters = _parameters };
1011 }
1012
1013 bool Parse()
1014 {
1015 NextLine();
1016
1017 if (Pos >= Str.Length)
1018 return false;
1019
1020 var obj = null as object;
1021 var idx = ReadInt(); Pos++;
1022 var type = ReadInt(); Pos++;
1023
1024 switch ((QueryElementType)type)
1025 {
1026 case (QueryElementType)_paramIndex : obj = _parameters = ReadArray<SqlParameter>(); break;
1027 case (QueryElementType)_typeIndex : obj = ResolveType(ReadString()); break;
1028 case (QueryElementType)_typeArrayIndex : obj = GetArrayType(Read<Type>()); break;
1029
1030 case QueryElementType.SqlField :
1031 {
1032 var systemType = Read<Type>();
1033 var name = ReadString();
1034 var physicalName = ReadString();
1035 var nullable = ReadBool();
1036 var primaryKeyOrder = ReadInt();
1037 var isIdentity = ReadBool();
1038 var isUpdatable = ReadBool();
1039 var isInsertable = ReadBool();
1040 var memberMapperType = Read<Type>();
1041 var memberMapperName = ReadString();
1042 var memberMapper = memberMapperType == null ? null : Map.GetObjectMapper(memberMapperType)[memberMapperName];
1043
1044 obj = new SqlField(
1045 systemType,
1046 name,
1047 physicalName,
1048 nullable,
1049 primaryKeyOrder,
1050 isIdentity
1051 ? new DataAccess.IdentityAttribute()
1052 : isInsertable || isUpdatable
1053 ? new DataAccess.NonUpdatableAttribute(isInsertable, isUpdatable, false)
1054 : null,
1055 memberMapper);
1056
1057 break;
1058 }
1059
1060 case QueryElementType.SqlFunction :
1061 {
1062 var systemType = Read<Type>();
1063 var name = ReadString();
1064 var precedence = ReadInt();
1065 var parameters = ReadArray<ISqlExpression>();
1066
1067 obj = new SqlFunction(systemType, name, precedence, parameters);
1068
1069 break;
1070 }
1071
1072 case QueryElementType.SqlParameter :
1073 {
1074 var name = ReadString();
1075 var isQueryParameter = ReadBool();
1076 var dbType = (DbType)ReadInt();
1077 var dbSize = ReadInt();
1078 var systemType = Read<Type>();
1079 var value = ReadValue(systemType);
1080 //var enumTypes = ReadList<Type>();
1081 //var takeValues = null as List<int>;
1082
1083 /*
1084 var count = ReadCount();
1085
1086 if (count != null)
1087 {
1088 takeValues = new List<int>(count.Value);
1089
1090 for (var i = 0; i < count; i++)
1091 takeValues.Add(ReadInt());
1092 }
1093
1094 var likeStart = ReadString();
1095 var likeEnd = ReadString();
1096 */
1097
1098 obj = new SqlParameter(systemType, name, value, (MappingSchema)null)
1099 {
1100 IsQueryParameter = isQueryParameter,
1101 DbType = dbType,
1102 DbSize = dbSize,
1103 //EnumTypes = enumTypes,
1104 //TakeValues = takeValues,
1105 //LikeStart = likeStart,
1106 //LikeEnd = likeEnd,
1107 };
1108
1109 /*
1110 if (enumTypes != null && UnresolvedTypes.Count > 0)
1111 foreach (var et in enumTypes)
1112 if (et == null)
1113 throw new LinqException(
1114 "Query cannot be deserialized. The possible reason is that the deserializer could not resolve the following types: {0}. Use LinqService.TypeResolver to resolve types.",
1115 string.Join(", ", UnresolvedTypes.Select(_ => "'" + _ + "'").ToArray()));
1116 */
1117
1118 break;
1119 }
1120
1121 case QueryElementType.SqlExpression :
1122 {
1123 var systemType = Read<Type>();
1124 var expr = ReadString();
1125 var precedence = ReadInt();
1126 var parameters = ReadArray<ISqlExpression>();
1127
1128 obj = new SqlExpression(systemType, expr, precedence, parameters);
1129
1130 break;
1131 }
1132
1133 case QueryElementType.SqlBinaryExpression :
1134 {
1135 var systemType = Read<Type>();
1136 var expr1 = Read<ISqlExpression>();
1137 var operation = ReadString();
1138 var expr2 = Read<ISqlExpression>();
1139 var precedence = ReadInt();
1140
1141 obj = new SqlBinaryExpression(systemType, expr1, operation, expr2, precedence);
1142
1143 break;
1144 }
1145
1146 case QueryElementType.SqlValue :
1147 {
1148 var systemType = Read<Type>();
1149 var value = ReadValue(systemType);
1150
1151 obj = new SqlValue(systemType, value);
1152
1153 break;
1154 }
1155
1156 case QueryElementType.SqlDataType :
1157 {
1158 var dbType = (SqlDbType)ReadInt();
1159 var systemType = Read<Type>();
1160 var length = ReadInt();
1161 var precision = ReadInt();
1162 var scale = ReadInt();
1163
1164 obj = new SqlDataType(dbType, systemType, length, precision, scale);
1165
1166 break;
1167 }
1168
1169 case QueryElementType.SqlTable :
1170 {
1171 var sourceID = ReadInt();
1172 var name = ReadString();
1173 var alias = ReadString();
1174 var database = ReadString();
1175 var owner = ReadString();
1176 var physicalName = ReadString();
1177 var objectType = Read<Type>();
1178 var sequenceAttributes = null as SequenceNameAttribute[];
1179
1180 var count = ReadCount();
1181
1182 if (count != null)
1183 {
1184 sequenceAttributes = new SequenceNameAttribute[count.Value];
1185
1186 for (var i = 0; i < count.Value; i++)
1187 sequenceAttributes[i] = new SequenceNameAttribute(ReadString(), ReadString());
1188 }
1189
1190 var all = Read<SqlField>();
1191 var fields = ReadArray<SqlField>();
1192 var flds = new SqlField[fields.Length + 1];
1193
1194 flds[0] = all;
1195 Array.Copy(fields, 0, flds, 1, fields.Length);
1196
1197 var sqlTableType = (SqlTableType)ReadInt();
1198 var tableArgs = sqlTableType == SqlTableType.Table ? null : ReadArray<ISqlExpression>();
1199
1200 obj = new SqlTable(
1201 sourceID, name, alias, database, owner, physicalName, objectType, sequenceAttributes, flds,
1202 sqlTableType, tableArgs);
1203
1204 break;
1205 }
1206
1207 case QueryElementType.ExprPredicate :
1208 {
1209 var expr1 = Read<ISqlExpression>();
1210 var precedence = ReadInt();
1211
1212 obj = new SqlQuery.Predicate.Expr(expr1, precedence);
1213
1214 break;
1215 }
1216
1217 case QueryElementType.NotExprPredicate :
1218 {
1219 var expr1 = Read<ISqlExpression>();
1220 var isNot = ReadBool();
1221 var precedence = ReadInt();
1222
1223 obj = new SqlQuery.Predicate.NotExpr(expr1, isNot, precedence);
1224
1225 break;
1226 }
1227
1228 case QueryElementType.ExprExprPredicate :
1229 {
1230 var expr1 = Read<ISqlExpression>();
1231 var @operator = (SqlQuery.Predicate.Operator)ReadInt();
1232 var expr2 = Read<ISqlExpression>();
1233
1234 obj = new SqlQuery.Predicate.ExprExpr(expr1, @operator, expr2);
1235
1236 break;
1237 }
1238
1239 case QueryElementType.LikePredicate :
1240 {
1241 var expr1 = Read<ISqlExpression>();
1242 var isNot = ReadBool();
1243 var expr2 = Read<ISqlExpression>();
1244 var escape = Read<ISqlExpression>();
1245
1246 obj = new SqlQuery.Predicate.Like(expr1, isNot, expr2, escape);
1247
1248 break;
1249 }
1250
1251 case QueryElementType.BetweenPredicate :
1252 {
1253 var expr1 = Read<ISqlExpression>();
1254 var isNot = ReadBool();
1255 var expr2 = Read<ISqlExpression>();
1256 var expr3 = Read<ISqlExpression>();
1257
1258 obj = new SqlQuery.Predicate.Between(expr1, isNot, expr2, expr3);
1259
1260 break;
1261 }
1262
1263 case QueryElementType.IsNullPredicate :
1264 {
1265 var expr1 = Read<ISqlExpression>();
1266 var isNot = ReadBool();
1267
1268 obj = new SqlQuery.Predicate.IsNull(expr1, isNot);
1269
1270 break;
1271 }
1272
1273 case QueryElementType.InSubQueryPredicate :
1274 {
1275 var expr1 = Read<ISqlExpression>();
1276 var isNot = ReadBool();
1277 var subQuery = Read<SqlQuery>();
1278
1279 obj = new SqlQuery.Predicate.InSubQuery(expr1, isNot, subQuery);
1280
1281 break;
1282 }
1283
1284 case QueryElementType.InListPredicate :
1285 {
1286 var expr1 = Read<ISqlExpression>();
1287 var isNot = ReadBool();
1288 var values = ReadList<ISqlExpression>();
1289
1290 obj = new SqlQuery.Predicate.InList(expr1, isNot, values);
1291
1292 break;
1293 }
1294
1295 case QueryElementType.FuncLikePredicate :
1296 {
1297 var func = Read<SqlFunction>();
1298 obj = new SqlQuery.Predicate.FuncLike(func);
1299 break;
1300 }
1301
1302 case QueryElementType.SqlQuery :
1303 {
1304 var sid = ReadInt();
1305 var queryType = (QueryType)ReadInt();
1306 var from = Read<SqlQuery.FromClause>();
1307 var readInsert = ReadBool();
1308 var insert = readInsert ? Read<SqlQuery.InsertClause>() : null;
1309 var readUpdate = ReadBool();
1310 var update = readUpdate ? Read<SqlQuery.UpdateClause>() : null;
1311 var readDelete = ReadBool();
1312 var delete = readDelete ? Read<SqlQuery.DeleteClause>() : null;
1313 var readSelect = ReadBool();
1314 var select = readSelect ? Read<SqlQuery.SelectClause>() : new SqlQuery.SelectClause(null);
1315 var where = Read<SqlQuery.WhereClause>();
1316 var groupBy = Read<SqlQuery.GroupByClause>();
1317 var having = Read<SqlQuery.WhereClause>();
1318 var orderBy = Read<SqlQuery.OrderByClause>();
1319 var parentSql = ReadInt();
1320 var parameterDependent = ReadBool();
1321 var unions = ReadArray<SqlQuery.Union>();
1322 var parameters = ReadArray<SqlParameter>();
1323
1324 var query = _query = new SqlQuery(sid) { QueryType = queryType };
1325
1326 query.Init(
1327 insert,
1328 update,
1329 delete,
1330 select,
1331 from,
1332 where,
1333 groupBy,
1334 having,
1335 orderBy,
1336 unions == null ? null : unions.ToList(),
1337 null,
1338 parameterDependent,
1339 parameters.ToList());
1340
1341 _queries.Add(sid, _query);
1342
1343 if (parentSql != 0)
1344 _actions.Add(() =>
1345 {
1346 SqlQuery sql;
1347 if (_queries.TryGetValue(parentSql, out sql))
1348 query.ParentSql = sql;
1349 });
1350
1351 query.All = Read<SqlField>();
1352
1353 obj = query;
1354
1355 break;
1356 }
1357
1358 case QueryElementType.Column :
1359 {
1360 var sid = ReadInt();
1361 var expression = Read<ISqlExpression>();
1362 var alias = ReadString();
1363
1364 var col = new SqlQuery.Column(null, expression, alias);
1365
1366 _actions.Add(() => col.Parent = _queries[sid]);
1367
1368 obj = col;
1369
1370 break;
1371 }
1372
1373 case QueryElementType.SearchCondition :
1374 obj = new SqlQuery.SearchCondition(ReadArray<SqlQuery.Condition>());
1375 break;
1376
1377 case QueryElementType.Condition :
1378 obj = new SqlQuery.Condition(ReadBool(), Read<ISqlPredicate>(), ReadBool());
1379 break;
1380
1381 case QueryElementType.TableSource :
1382 {
1383 var source = Read<ISqlTableSource>();
1384 var alias = ReadString();
1385 var joins = ReadArray<SqlQuery.JoinedTable>();
1386
1387 obj = new SqlQuery.TableSource(source, alias, joins);
1388
1389 break;
1390 }
1391
1392 case QueryElementType.JoinedTable :
1393 {
1394 var joinType = (SqlQuery.JoinType)ReadInt();
1395 var table = Read<SqlQuery.TableSource>();
1396 var isWeak = ReadBool();
1397 var condition = Read<SqlQuery.SearchCondition>();
1398
1399 obj = new SqlQuery.JoinedTable(joinType, table, isWeak, condition);
1400
1401 break;
1402 }
1403
1404 case QueryElementType.SelectClause :
1405 {
1406 var isDistinct = ReadBool();
1407 var skipValue = Read<ISqlExpression>();
1408 var takeValue = Read<ISqlExpression>();
1409 var columns = ReadArray<SqlQuery.Column>();
1410
1411 obj = new SqlQuery.SelectClause(isDistinct, takeValue, skipValue, columns);
1412
1413 break;
1414 }
1415
1416 case QueryElementType.InsertClause :
1417 {
1418 var items = ReadArray<SqlQuery.SetExpression>();
1419 var into = Read<SqlTable>();
1420 var wid = ReadBool();
1421
1422 var c = new SqlQuery.InsertClause { Into = into, WithIdentity = wid };
1423
1424 c.Items.AddRange(items);
1425 obj = c;
1426
1427 break;
1428 }
1429
1430 case QueryElementType.UpdateClause :
1431 {
1432 var items = ReadArray<SqlQuery.SetExpression>();
1433 var keys = ReadArray<SqlQuery.SetExpression>();
1434 var table = Read<SqlTable>();
1435 //var wid = ReadBool();
1436
1437 var c = new SqlQuery.UpdateClause { Table = table };
1438
1439 c.Items.AddRange(items);
1440 c.Keys. AddRange(keys);
1441 obj = c;
1442
1443 break;
1444 }
1445
1446 case QueryElementType.DeleteClause :
1447 {
1448 var table = Read<SqlTable>();
1449 obj = new SqlQuery.DeleteClause { Table = table };
1450 break;
1451 }
1452
1453 case QueryElementType.SetExpression : obj = new SqlQuery.SetExpression(Read<ISqlExpression>(), Read<ISqlExpression>()); break;
1454 case QueryElementType.FromClause : obj = new SqlQuery.FromClause(ReadArray<SqlQuery.TableSource>()); break;
1455 case QueryElementType.WhereClause : obj = new SqlQuery.WhereClause(Read<SqlQuery.SearchCondition>()); break;
1456 case QueryElementType.GroupByClause : obj = new SqlQuery.GroupByClause(ReadArray<ISqlExpression>()); break;
1457 case QueryElementType.OrderByClause : obj = new SqlQuery.OrderByClause(ReadArray<SqlQuery.OrderByItem>()); break;
1458
1459 case QueryElementType.OrderByItem :
1460 {
1461 var expression = Read<ISqlExpression>();
1462 var isDescending = ReadBool();
1463
1464 obj = new SqlQuery.OrderByItem(expression, isDescending);
1465
1466 break;
1467 }
1468
1469 case QueryElementType.Union :
1470 {
1471 var sqlQuery = Read<SqlQuery>();
1472 var isAll = ReadBool();
1473
1474 obj = new SqlQuery.Union(sqlQuery, isAll);
1475
1476 break;
1477 }
1478 }
1479
1480 Dic.Add(idx, obj);
1481
1482 return true;
1483 }
1484 }
1485
1486 #endregion
1487
1488 #region ResultSerializer
1489
1490 class ResultSerializer : SerializerBase
1491 {
1492 public string Serialize(LinqServiceResult result)
1493 {
1494 Append(result.FieldCount);
1495 Append(result.VaryingTypes.Length);
1496 Append(result.RowCount);
1497 Append(result.QueryID.ToString());
1498
1499 Builder.AppendLine();
1500
1501 foreach (var name in result.FieldNames)
1502 {
1503 Append(name);
1504 Builder.AppendLine();
1505 }
1506
1507 foreach (var type in result.FieldTypes)
1508 {
1509 Append(type.FullName);
1510 Builder.AppendLine();
1511 }
1512
1513 foreach (var type in result.VaryingTypes)
1514 {
1515 Append(type.FullName);
1516 Builder.AppendLine();
1517 }
1518
1519 foreach (var data in result.Data)
1520 {
1521 foreach (var str in data)
1522 {
1523 if (result.VaryingTypes.Length > 0 && !string.IsNullOrEmpty(str) && str[0] == '\0')
1524 {
1525 Builder.Append('*');
1526 Append((int)str[1]);
1527 Append(str.Substring(2));
1528 }
1529 else
1530 Append(str);
1531 }
1532
1533 Builder.AppendLine();
1534 }
1535
1536 return Builder.ToString();
1537 }
1538 }
1539
1540 #endregion
1541
1542 #region ResultDeserializer
1543
1544 class ResultDeserializer : DeserializerBase
1545 {
1546 public LinqServiceResult DeserializeResult(string str)
1547 {
1548 Str = str;
1549
1550 var fieldCount = ReadInt();
1551 var varTypesLen = ReadInt();
1552
1553 var result = new LinqServiceResult
1554 {
1555 FieldCount = fieldCount,
1556 RowCount = ReadInt(),
1557 VaryingTypes = new Type[varTypesLen],
1558 QueryID = new Guid(ReadString()),
1559 FieldNames = new string[fieldCount],
1560 FieldTypes = new Type [fieldCount],
1561 Data = new List<string[]>(),
1562 };
1563
1564 NextLine();
1565
1566 for (var i = 0; i < fieldCount; i++) { result.FieldNames [i] = ReadString(); NextLine(); }
1567 for (var i = 0; i < fieldCount; i++) { result.FieldTypes [i] = ResolveType(ReadString()); NextLine(); }
1568 for (var i = 0; i < varTypesLen; i++) { result.VaryingTypes[i] = ResolveType(ReadString()); NextLine(); }
1569
1570 for (var n = 0; n < result.RowCount; n++)
1571 {
1572 var data = new string[fieldCount];
1573
1574 for (var i = 0; i < fieldCount; i++)
1575 {
1576 if (varTypesLen > 0)
1577 {
1578 Get(' ');
1579
1580 if (Get('*'))
1581 {
1582 var idx = ReadInt();
1583 data[i] = "\0" + (char)idx + ReadString();
1584 }
1585 else
1586 data[i] = ReadString();
1587 }
1588 else
1589 data[i] = ReadString();
1590 }
1591
1592 result.Data.Add(data);
1593
1594 NextLine();
1595 }
1596
1597 return result;
1598 }
1599 }
1600
1601 #endregion
1602
1603 #region StringArraySerializer
1604
1605 class StringArraySerializer : SerializerBase
1606 {
1607 public string Serialize(string[] data)
1608 {
1609 Append(data.Length);
1610
1611 foreach (var str in data)
1612 Append(str);
1613
1614 Builder.AppendLine();
1615
1616 return Builder.ToString();
1617 }
1618 }
1619
1620 #endregion
1621
1622 #region StringArrayDeserializer
1623
1624 class StringArrayDeserializer : DeserializerBase
1625 {
1626 public string[] Deserialize(string str)
1627 {
1628 Str = str;
1629
1630 var data = new string[ReadInt()];
1631
1632 for (var i = 0; i < data.Length; i++)
1633 data[i] = ReadString();
1634
1635 return data;
1636 }
1637 }
1638
1639 #endregion
1640
1641 #region Helpers
1642
1643 interface IArrayHelper
1644 {
1645 Type GetArrayType();
1646 object ConvertToArray(object list);
1647 }
1648
1649 class ArrayHelper<T> : IArrayHelper
1650 {
1651 public Type GetArrayType()
1652 {
1653 return typeof(T[]);
1654 }
1655
1656 public object ConvertToArray(object list)
1657 {
1658 return ((IEnumerable<T>)list).ToArray();
1659 }
1660 }
1661
1662 static readonly Dictionary<Type,Type> _arrayTypes = new Dictionary<Type,Type>();
1663 static readonly Dictionary<Type,Func<object,object>> _arrayConverters = new Dictionary<Type,Func<object,object>>();
1664
1665 static Type GetArrayType(Type elementType)
1666 {
1667 Type arrayType;
1668
1669 lock (_arrayTypes)
1670 {
1671 if (!_arrayTypes.TryGetValue(elementType, out arrayType))
1672 {
1673 var helper = (IArrayHelper)Activator.CreateInstance(typeof(ArrayHelper<>).MakeGenericType(elementType));
1674 _arrayTypes.Add(elementType, arrayType = helper.GetArrayType());
1675 }
1676 }
1677
1678 return arrayType;
1679 }
1680
1681 static object ConvertIEnumerableToArray(object list, Type elementType)
1682 {
1683 Func<object,object> converter;
1684
1685 lock (_arrayConverters)
1686 {
1687 if (!_arrayConverters.TryGetValue(elementType, out converter))
1688 {
1689 var helper = (IArrayHelper)Activator.CreateInstance(typeof(ArrayHelper<>).MakeGenericType(elementType));
1690 _arrayConverters.Add(elementType, converter = helper.ConvertToArray);
1691 }
1692 }
1693
1694 return converter(list);
1695 }
1696
1697 #endregion
1698 }
1699 }