0
|
1 using System;
|
|
2 using System.Collections.Generic;
|
|
3 using System.Text;
|
|
4
|
|
5 using BLToolkit.Mapping;
|
|
6 using BLToolkit.Reflection;
|
|
7
|
|
8 namespace BLToolkit.Data.Sql
|
|
9 {
|
|
10 public abstract class SqlValueBase: IValueContainer
|
|
11 {
|
|
12 [CLSCompliant(false)]
|
|
13 protected object _value;
|
|
14 public virtual object Value
|
|
15 {
|
|
16 get
|
|
17 {
|
|
18 var valueConverter = ValueConverter;
|
|
19 return valueConverter == null ? _value : valueConverter(_value);
|
|
20 }
|
|
21
|
|
22 set { _value = value; }
|
|
23 }
|
|
24
|
|
25 #region Value Converter
|
|
26
|
|
27 internal List<Type> EnumTypes;
|
|
28 internal List<int> TakeValues;
|
|
29 internal string LikeStart, LikeEnd;
|
|
30
|
|
31 private Converter<object,object> _valueConverter;
|
|
32 public Converter<object,object> ValueConverter
|
|
33 {
|
|
34 get
|
|
35 {
|
|
36 if (_valueConverter == null)
|
|
37 {
|
|
38 if (EnumTypes != null)
|
|
39 foreach (var type in EnumTypes.ToArray())
|
|
40 SetEnumConverter(type, Map.DefaultSchema);
|
|
41 else if (TakeValues != null)
|
|
42 foreach (var take in TakeValues.ToArray())
|
|
43 SetTakeConverter(take);
|
|
44 else if (LikeStart != null)
|
|
45 SetLikeConverter(LikeStart, LikeEnd);
|
|
46 }
|
|
47
|
|
48 return _valueConverter;
|
|
49 }
|
|
50
|
|
51 set { _valueConverter = value; }
|
|
52 }
|
|
53
|
|
54 bool _isEnumConverterSet;
|
|
55
|
|
56 internal void SetEnumConverter(Type type, MappingSchema ms)
|
|
57 {
|
|
58 if (!_isEnumConverterSet)
|
|
59 {
|
|
60 _isEnumConverterSet = true;
|
|
61
|
|
62 if (EnumTypes == null)
|
|
63 EnumTypes = new List<Type>();
|
|
64
|
|
65 EnumTypes.Add(type);
|
|
66
|
|
67 SetEnumConverterInternal(type, ms);
|
|
68 }
|
|
69 }
|
|
70
|
|
71 internal void SetEnumConverter(MemberAccessor ma, MappingSchema ms)
|
|
72 {
|
|
73 if (!_isEnumConverterSet)
|
|
74 {
|
|
75 _isEnumConverterSet = true;
|
|
76
|
|
77 if (EnumTypes == null)
|
|
78 EnumTypes = new List<Type>();
|
|
79
|
|
80 EnumTypes.Add(ma.Type);
|
|
81
|
|
82 SetEnumConverterInternal(ma, ms);
|
|
83 }
|
|
84 }
|
|
85
|
|
86 void SetEnumConverterInternal(MemberAccessor ma, MappingSchema ms)
|
|
87 {
|
|
88 if (_valueConverter == null)
|
|
89 {
|
|
90 _valueConverter = o => ms.MapEnumToValue(o, ma, true);
|
|
91 }
|
|
92 else
|
|
93 {
|
|
94 var converter = _valueConverter;
|
|
95 _valueConverter = o => ms.MapEnumToValue(converter(o), ma, true);
|
|
96 }
|
|
97 // update system type in SqlValue :-/
|
|
98 var tmp = Value;
|
|
99 }
|
|
100
|
|
101 void SetEnumConverterInternal(Type type, MappingSchema ms)
|
|
102 {
|
|
103 if (_valueConverter == null)
|
|
104 {
|
|
105 _valueConverter = o => ms.MapEnumToValue(o, type, true);
|
|
106 }
|
|
107 else
|
|
108 {
|
|
109 var converter = _valueConverter;
|
|
110 _valueConverter = o => ms.MapEnumToValue(converter(o), type, true);
|
|
111 }
|
|
112 // update system type in SqlValue :-/
|
|
113 var tmp = Value;
|
|
114 }
|
|
115
|
|
116 internal void SetTakeConverter(int take)
|
|
117 {
|
|
118 if (TakeValues == null)
|
|
119 TakeValues = new List<int>();
|
|
120
|
|
121 TakeValues.Add(take);
|
|
122
|
|
123 SetTakeConverterInternal(take);
|
|
124 }
|
|
125
|
|
126 void SetTakeConverterInternal(int take)
|
|
127 {
|
|
128 var conv = _valueConverter;
|
|
129
|
|
130 if (conv == null)
|
|
131 _valueConverter = v => v == null ? null : (object)((int)v + take);
|
|
132 else
|
|
133 _valueConverter = v => v == null ? null : (object)((int)conv(v) + take);
|
|
134 }
|
|
135
|
|
136 internal void SetLikeConverter(string start, string end)
|
|
137 {
|
|
138 LikeStart = start;
|
|
139 LikeEnd = end;
|
|
140 _valueConverter = GetLikeEscaper(start, end);
|
|
141 }
|
|
142
|
|
143 static Converter<object, object> GetLikeEscaper(string start, string end)
|
|
144 {
|
|
145 return value =>
|
|
146 {
|
|
147 if (value == null)
|
|
148 #if DEBUG
|
|
149 value = "";
|
|
150 #else
|
|
151 throw new SqlException("NULL cannot be used as a LIKE predicate parameter.");
|
|
152 #endif
|
|
153
|
|
154 var text = value.ToString();
|
|
155
|
|
156 if (text.IndexOfAny(new[] { '%', '_', '[' }) < 0)
|
|
157 return start + text + end;
|
|
158
|
|
159 var sb = new StringBuilder(start, text.Length + start.Length + end.Length);
|
|
160
|
|
161 foreach (var c in text)
|
|
162 {
|
|
163 if (c == '%' || c == '_' || c == '[')
|
|
164 {
|
|
165 sb.Append('[');
|
|
166 sb.Append(c);
|
|
167 sb.Append(']');
|
|
168 }
|
|
169 else
|
|
170 sb.Append(c);
|
|
171 }
|
|
172
|
|
173 return sb.ToString();
|
|
174 };
|
|
175 }
|
|
176
|
|
177 #endregion
|
|
178 }
|
|
179 }
|