Mercurial > pub > bltoolkit
comparison Source/Data/Sql/SqlTable.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.Generic; | |
3 using System.Linq; | |
4 using System.Text; | |
5 using System.Threading; | |
6 | |
7 namespace BLToolkit.Data.Sql | |
8 { | |
9 using DataAccess; | |
10 using Mapping; | |
11 using Reflection.Extension; | |
12 using SqlProvider; | |
13 | |
14 public class SqlTable : ISqlTableSource | |
15 { | |
16 #region Init | |
17 | |
18 public SqlTable() | |
19 { | |
20 _sourceID = Interlocked.Increment(ref SqlQuery.SourceIDCounter); | |
21 _fields = new ChildContainer<ISqlTableSource,SqlField>(this); | |
22 } | |
23 | |
24 internal SqlTable( | |
25 int id, string name, string alias, string database, string owner, string physicalName, Type objectType, | |
26 SequenceNameAttribute[] sequenceAttributes, | |
27 SqlField[] fields, | |
28 SqlTableType sqlTableType, ISqlExpression[] tableArguments) | |
29 { | |
30 _sourceID = id; | |
31 Name = name; | |
32 Alias = alias; | |
33 Database = database; | |
34 Owner = owner; | |
35 PhysicalName = physicalName; | |
36 ObjectType = objectType; | |
37 _sequenceAttributes = sequenceAttributes; | |
38 | |
39 _fields = new ChildContainer<ISqlTableSource,SqlField>(this); | |
40 _fields.AddRange(fields); | |
41 | |
42 foreach (var field in fields) | |
43 { | |
44 if (field.Name == "*") | |
45 { | |
46 _all = field; | |
47 _fields.Remove("*"); | |
48 ((IChild<ISqlTableSource>)_all).Parent = this; | |
49 break; | |
50 } | |
51 } | |
52 | |
53 SqlTableType = sqlTableType; | |
54 TableArguments = tableArguments; | |
55 } | |
56 | |
57 #endregion | |
58 | |
59 #region Init from type | |
60 | |
61 public SqlTable([JetBrains.Annotations.NotNull] MappingSchema mappingSchema, Type objectType) : this() | |
62 { | |
63 if (mappingSchema == null) throw new ArgumentNullException("mappingSchema"); | |
64 | |
65 bool isSet; | |
66 Database = mappingSchema.MetadataProvider.GetDatabaseName(objectType, mappingSchema.Extensions, out isSet); | |
67 Owner = mappingSchema.MetadataProvider.GetOwnerName (objectType, mappingSchema.Extensions, out isSet); | |
68 Name = mappingSchema.MetadataProvider.GetTableName (objectType, mappingSchema.Extensions, out isSet); | |
69 ObjectType = objectType; | |
70 PhysicalName = Name; | |
71 | |
72 var typeExt = TypeExtension.GetTypeExtension(objectType, mappingSchema.Extensions); | |
73 | |
74 foreach (MemberMapper mm in mappingSchema.GetObjectMapper(objectType)) | |
75 if (mm.MapMemberInfo.SqlIgnore == false) | |
76 { | |
77 var ua = | |
78 mappingSchema.MetadataProvider.GetNonUpdatableAttribute(objectType, typeExt, mm.MapMemberInfo.MemberAccessor, out isSet); | |
79 | |
80 var order = mappingSchema.MetadataProvider.GetPrimaryKeyOrder(objectType, typeExt, mm.MapMemberInfo.MemberAccessor, out isSet); | |
81 | |
82 Fields.Add(new SqlField( | |
83 mm.Type, | |
84 mm.MemberName, | |
85 mm.Name, | |
86 mm.MapMemberInfo.Nullable, | |
87 isSet ? order : int.MinValue, | |
88 ua, | |
89 mm)); | |
90 } | |
91 | |
92 var identityField = GetIdentityField(); | |
93 | |
94 if (identityField != null) | |
95 { | |
96 var om = mappingSchema.GetObjectMapper(ObjectType); | |
97 var mm = om[identityField.Name, true]; | |
98 | |
99 _sequenceAttributes = mm.MapMemberInfo.MemberAccessor.GetAttributes<SequenceNameAttribute>(); | |
100 } | |
101 } | |
102 | |
103 public SqlTable(Type objectType) | |
104 : this(Map.DefaultSchema, objectType) | |
105 { | |
106 } | |
107 | |
108 #endregion | |
109 | |
110 #region Init from Table | |
111 | |
112 public SqlTable(SqlTable table) : this() | |
113 { | |
114 Alias = table.Alias; | |
115 Database = table.Database; | |
116 Owner = table.Owner; | |
117 Name = table.Name; | |
118 PhysicalName = table.PhysicalName; | |
119 ObjectType = table.ObjectType; | |
120 _sequenceAttributes = table._sequenceAttributes; | |
121 | |
122 foreach (var field in table.Fields.Values) | |
123 Fields.Add(new SqlField(field)); | |
124 | |
125 foreach (var join in table.Joins) | |
126 Joins.Add(join.Clone()); | |
127 | |
128 SqlTableType = table.SqlTableType; | |
129 TableArguments = table.TableArguments; | |
130 } | |
131 | |
132 public SqlTable(SqlTable table, IEnumerable<SqlField> fields, IEnumerable<Join> joins, ISqlExpression[] tableArguments) : this() | |
133 { | |
134 Alias = table.Alias; | |
135 Database = table.Database; | |
136 Owner = table.Owner; | |
137 Name = table.Name; | |
138 PhysicalName = table.PhysicalName; | |
139 ObjectType = table.ObjectType; | |
140 _sequenceAttributes = table._sequenceAttributes; | |
141 | |
142 Fields.AddRange(fields); | |
143 Joins. AddRange(joins); | |
144 | |
145 SqlTableType = table.SqlTableType; | |
146 TableArguments = tableArguments; | |
147 } | |
148 | |
149 #endregion | |
150 | |
151 #region Init from XML | |
152 | |
153 public SqlTable(ExtensionList extensions, string name) | |
154 : this(Map.DefaultSchema, extensions, name) | |
155 { | |
156 } | |
157 | |
158 public SqlTable([JetBrains.Annotations.NotNull] MappingSchema mappingSchema, ExtensionList extensions, string name) : this() | |
159 { | |
160 if (mappingSchema == null) throw new ArgumentNullException("mappingSchema"); | |
161 if (extensions == null) throw new ArgumentNullException("extensions"); | |
162 if (name == null) throw new ArgumentNullException("name"); | |
163 | |
164 var te = extensions[name]; | |
165 | |
166 if (te == TypeExtension.Null) | |
167 throw new ArgumentException(string.Format("Table '{0}' not found.", name)); | |
168 | |
169 Name = te.Name; | |
170 Alias = (string)te.Attributes["Alias"]. Value; | |
171 Database = (string)te.Attributes["Database"]. Value; | |
172 Owner = (string)te.Attributes["Owner"]. Value; | |
173 PhysicalName = (string)te.Attributes["PhysicalName"].Value ?? te.Name; | |
174 | |
175 foreach (var me in te.Members.Values) | |
176 Fields.Add(new SqlField( | |
177 (Type)me["Type"].Value, | |
178 me.Name, | |
179 (string)me["MapField"].Value ?? (string)me["PhysicalName"].Value, | |
180 (bool?)me["Nullable"].Value ?? false, | |
181 -1, | |
182 (bool?)me["Identity"].Value == true ? new IdentityAttribute() : null, | |
183 null)); | |
184 | |
185 foreach (var ae in te.Attributes["Join"]) | |
186 Joins.Add(new Join(ae)); | |
187 | |
188 var baseExtension = (string)te.Attributes["BaseExtension"].Value; | |
189 | |
190 if (!string.IsNullOrEmpty(baseExtension)) | |
191 InitFromBase(new SqlTable(mappingSchema, extensions, baseExtension)); | |
192 | |
193 var baseTypeName = (string)te.Attributes["BaseType"].Value; | |
194 | |
195 if (!string.IsNullOrEmpty(baseTypeName)) | |
196 InitFromBase(new SqlTable(mappingSchema, Type.GetType(baseTypeName, true, true))); | |
197 } | |
198 | |
199 void InitFromBase(SqlTable baseTable) | |
200 { | |
201 if (Alias == null) Alias = baseTable.Alias; | |
202 if (Database == null) Database = baseTable.Database; | |
203 if (Owner == null) Owner = baseTable.Owner; | |
204 if (PhysicalName == null) PhysicalName = baseTable.PhysicalName; | |
205 | |
206 foreach (var field in baseTable.Fields.Values) | |
207 if (!Fields.ContainsKey(field.Name)) | |
208 Fields.Add(new SqlField(field)); | |
209 | |
210 foreach (var join in baseTable.Joins) | |
211 if (Joins.FirstOrDefault(j => j.TableName == join.TableName) == null) | |
212 Joins.Add(join); | |
213 } | |
214 | |
215 #endregion | |
216 | |
217 #region Overrides | |
218 | |
219 #if OVERRIDETOSTRING | |
220 | |
221 public override string ToString() | |
222 { | |
223 return ((IQueryElement)this).ToString(new StringBuilder(), new Dictionary<IQueryElement,IQueryElement>()).ToString(); | |
224 } | |
225 | |
226 #endif | |
227 | |
228 #endregion | |
229 | |
230 #region Public Members | |
231 | |
232 public SqlField this[string fieldName] | |
233 { | |
234 get | |
235 { | |
236 SqlField field; | |
237 Fields.TryGetValue(fieldName, out field); | |
238 return field; | |
239 } | |
240 } | |
241 | |
242 public string Name { get; set; } | |
243 public string Alias { get; set; } | |
244 public string Database { get; set; } | |
245 public string Owner { get; set; } | |
246 public Type ObjectType { get; set; } | |
247 public string PhysicalName { get; set; } | |
248 | |
249 private SqlTableType _sqlTableType = SqlTableType.Table; | |
250 public SqlTableType SqlTableType { get { return _sqlTableType; } set { _sqlTableType = value; } } | |
251 | |
252 public ISqlExpression[] TableArguments { get; set; } | |
253 | |
254 readonly ChildContainer<ISqlTableSource,SqlField> _fields; | |
255 public ChildContainer<ISqlTableSource,SqlField> Fields { get { return _fields; } } | |
256 | |
257 readonly List<Join> _joins = new List<Join>(); | |
258 public List<Join> Joins { get { return _joins; } } | |
259 | |
260 private SequenceNameAttribute[] _sequenceAttributes; | |
261 public SequenceNameAttribute[] SequenceAttributes | |
262 { | |
263 get { return _sequenceAttributes; } | |
264 } | |
265 | |
266 private SqlField _all; | |
267 public SqlField All | |
268 { | |
269 get | |
270 { | |
271 if (_all == null) | |
272 { | |
273 _all = new SqlField(null, "*", "*", true, -1, null, null); | |
274 ((IChild<ISqlTableSource>)_all).Parent = this; | |
275 } | |
276 | |
277 return _all; | |
278 } | |
279 } | |
280 | |
281 public SqlField GetIdentityField() | |
282 { | |
283 foreach (var field in Fields) | |
284 if (field.Value.IsIdentity) | |
285 return field.Value; | |
286 | |
287 var keys = GetKeys(true); | |
288 | |
289 if (keys != null && keys.Count == 1) | |
290 return (SqlField)keys[0]; | |
291 | |
292 return null; | |
293 } | |
294 | |
295 #endregion | |
296 | |
297 #region ISqlTableSource Members | |
298 | |
299 readonly int _sourceID; | |
300 public int SourceID { get { return _sourceID; } } | |
301 | |
302 List<ISqlExpression> _keyFields; | |
303 | |
304 public IList<ISqlExpression> GetKeys(bool allIfEmpty) | |
305 { | |
306 if (_keyFields == null) | |
307 { | |
308 _keyFields = ( | |
309 from f in Fields.Values | |
310 where f.IsPrimaryKey | |
311 orderby f.PrimaryKeyOrder | |
312 select f as ISqlExpression | |
313 ).ToList(); | |
314 } | |
315 | |
316 if (_keyFields.Count == 0 && allIfEmpty) | |
317 return Fields.Values.Select(f => f as ISqlExpression).ToList(); | |
318 | |
319 return _keyFields; | |
320 } | |
321 | |
322 #endregion | |
323 | |
324 #region ICloneableElement Members | |
325 | |
326 public ICloneableElement Clone(Dictionary<ICloneableElement, ICloneableElement> objectTree, Predicate<ICloneableElement> doClone) | |
327 { | |
328 if (!doClone(this)) | |
329 return this; | |
330 | |
331 ICloneableElement clone; | |
332 | |
333 if (!objectTree.TryGetValue(this, out clone)) | |
334 { | |
335 var table = new SqlTable | |
336 { | |
337 Name = Name, | |
338 Alias = Alias, | |
339 Database = Database, | |
340 Owner = Owner, | |
341 PhysicalName = PhysicalName, | |
342 ObjectType = ObjectType, | |
343 SqlTableType = SqlTableType, | |
344 _sequenceAttributes = _sequenceAttributes, | |
345 }; | |
346 | |
347 table._fields.Clear(); | |
348 | |
349 foreach (var field in _fields) | |
350 { | |
351 var fc = new SqlField(field.Value); | |
352 | |
353 objectTree. Add(field.Value, fc); | |
354 table._fields.Add(field.Key, fc); | |
355 } | |
356 | |
357 table._joins.AddRange(_joins.ConvertAll(j => j.Clone())); | |
358 | |
359 if (TableArguments != null) | |
360 TableArguments = TableArguments.Select(e => (ISqlExpression)e.Clone(objectTree, doClone)).ToArray(); | |
361 | |
362 objectTree.Add(this, table); | |
363 objectTree.Add(All, table.All); | |
364 | |
365 clone = table; | |
366 } | |
367 | |
368 return clone; | |
369 } | |
370 | |
371 #endregion | |
372 | |
373 #region IQueryElement Members | |
374 | |
375 public QueryElementType ElementType { get { return QueryElementType.SqlTable; } } | |
376 | |
377 StringBuilder IQueryElement.ToString(StringBuilder sb, Dictionary<IQueryElement,IQueryElement> dic) | |
378 { | |
379 return sb.Append(Name); | |
380 } | |
381 | |
382 #endregion | |
383 | |
384 #region ISqlExpression Members | |
385 | |
386 bool ISqlExpression.CanBeNull() | |
387 { | |
388 return true; | |
389 } | |
390 | |
391 public bool Equals(ISqlExpression other, Func<ISqlExpression, ISqlExpression, bool> comparer) | |
392 { | |
393 return this == other; | |
394 } | |
395 | |
396 int ISqlExpression.Precedence | |
397 { | |
398 get { return Precedence.Unknown; } | |
399 } | |
400 | |
401 Type ISqlExpression.SystemType | |
402 { | |
403 get { return ObjectType; } | |
404 } | |
405 | |
406 #endregion | |
407 | |
408 #region IEquatable<ISqlExpression> Members | |
409 | |
410 bool IEquatable<ISqlExpression>.Equals(ISqlExpression other) | |
411 { | |
412 return this == other; | |
413 } | |
414 | |
415 #endregion | |
416 | |
417 #region ISqlExpressionWalkable Members | |
418 | |
419 ISqlExpression ISqlExpressionWalkable.Walk(bool skipColumns, Func<ISqlExpression,ISqlExpression> func) | |
420 { | |
421 if (TableArguments != null) | |
422 for (var i = 0; i < TableArguments.Length; i++) | |
423 TableArguments[i] = TableArguments[i].Walk(skipColumns, func); | |
424 | |
425 return func(this); | |
426 } | |
427 | |
428 #endregion | |
429 } | |
430 } |