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 }