Datei: NDODLL/SchemaTransitionGenerator.cs

Last Commit (2a2e7ba)
1 //
2 // Copyright (c) 2002-2016 Mirko Matytschak
3 // (www.netdataobjects.de)
4 //
5 // Author: Mirko Matytschak
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
8 // documentation files (the "Software"), to deal in the Software without restriction, including without limitation
9 // the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
10 // Software, and to permit persons to whom the Software is furnished to do so, subject to the following
11 // conditions:
12
13 // The above copyright notice and this permission notice shall be included in all copies or substantial portions
14 // of the Software.
15 //
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
17 // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
19 // CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 // DEALINGS IN THE SOFTWARE.
21
22
23 using System;
24 using System.Text;
25 using System.IO;
26 using System.Collections.Generic;
27 using System.Data;
28 using System.Linq;
29 using System.Xml.Linq;
30 using NDO.Mapping;
31 using NDO;
32 using NDOInterfaces;
33 using System.Globalization;
34
35 namespace NDO
36 {
37 ····/// <summary>
38 ····/// Zusammenfassung für GenericDiffGenerator.
39 ····/// </summary>
40 ····internal class SchemaTransitionGenerator
41 ····{
42 ········IProvider provider;
43 ········ISqlGenerator concreteGenerator;
44 ········//MessageAdapter messages;
45 ········NDO.Mapping.NDOMapping mappings;
46 ········public SchemaTransitionGenerator(ISqlGenerator concreteGenerator, NDO.Mapping.NDOMapping mappings)
47 ········{
48 ············provider = NDOProviderFactory.Instance[concreteGenerator.ProviderName];
49 ············this.concreteGenerator = concreteGenerator;
50 ············this.mappings = mappings;
51 ········}
52
53 ········public string Generate(XElement transElement)
54 ········{
55 ············StringBuilder sb = new StringBuilder();
56 ············foreach(XElement actionElement in transElement.Elements())
57 ············{
58 ················if (actionElement.Name == "DropTable")
59 ················{
60 ····················sb.Append( DropTable( actionElement ) );
61 ················}
62 ················else if (actionElement.Name=="CreateTable")
63 ················{
64 ····················sb.Append( CreateTable( actionElement ) );
65 ················}
66 ················else if (actionElement.Name=="AlterTable")
67 ················{
68 ····················sb.Append( ChangeTable( actionElement ) );
69 ················}
70
71 ············}
72 ············return sb.ToString();
73 ········}
74
75 ········string ChangeTable(XElement actionElement)
76 ········{
77 ············List<XElement> addedColumns = actionElement.Elements("AddColumn").ToList();
78 ············List<XElement> removedColumns = actionElement.Elements("DropColumn").ToList();
79 ············List<XElement> changedColumns = actionElement.Elements("AlterColumn").ToList();
80
81 ············if (addedColumns.Count == 0 && removedColumns.Count == 0 && changedColumns.Count == 0)
82 ················return String.Empty;
83
84 ············StringBuilder sb = new StringBuilder();
85
86 ············string rawTableName = actionElement.Attribute( "name" ).Value;
87 ············string tableName = this.provider.GetQualifiedTableName(rawTableName);
88 ············string alterString = "ALTER TABLE " + tableName + ' ';
89
90 ············foreach(XElement columnElement in addedColumns)
91 ············{
92 ················sb.Append(alterString);
93 ················sb.Append(concreteGenerator.AddColumn());
94 ················sb.Append(' ');
95 ················sb.Append(CreateColumn(columnElement, GetClassForTable(rawTableName, this.mappings), this.provider, false));
96 ················sb.Append(";\n");
97 ············}
98
99 ············foreach(XElement columnElement in removedColumns)
100 ············{
101 ················sb.Append(alterString);
102 ················sb.Append( concreteGenerator.RemoveColumn( provider.GetQuotedName( columnElement.Attribute( "name" ).Value ) ) );
103 ················sb.Append(";\n");
104 ············}
105
106 ············foreach(XElement columnElement in changedColumns)
107 ············{
108 ················sb.Append(alterString);
109 ················sb.Append(concreteGenerator.AlterColumnType());
110 ················sb.Append(' ');
111 ················sb.Append(CreateColumn(columnElement, GetClassForTable(rawTableName, this.mappings), this.provider, false));
112 ················sb.Append(";\n");
113 ············}
114
115 ············return sb.ToString();
116 ········}
117
118 ········string RenameColumn(string tableName, string oldColumn, string newColumn, string typeString)
119 ········{
120 ············string s = concreteGenerator.RenameColumn(tableName, oldColumn, newColumn, typeString);
121 ············
122 ············if (s != string.Empty)
123 ············return s;
124 ········
125 ············string alterString = "ALTER TABLE " + tableName + ' ';
126
127 ············StringBuilder sb = new StringBuilder(alterString);
128 ············sb.Append(concreteGenerator.AddColumn());
129 ············sb.Append(' ');
130 ············sb.Append(newColumn);
131 ············sb.Append(' ');
132 ············sb.Append(typeString);
133 ············sb.Append(";\n");
134
135 ············sb.Append("UPDATE ");
136 ············sb.Append(tableName);
137 ············sb.Append(" SET ");············
138 ············sb.Append(newColumn);
139 ············sb.Append(" = ");
140 ············sb.Append(oldColumn);
141 ············sb.Append(";\n");
142
143 ············sb.Append(alterString);
144 ············sb.Append(concreteGenerator.RemoveColumn(oldColumn));
145 ············sb.Append(';');
146 ············return sb.ToString();
147 ········}
148
149 ········protected string DropTable(XElement actionElement)
150 ········{
151 ············string tableName = this.provider .GetQualifiedTableName( actionElement.Attribute( "name" ).Value );
152 ············return concreteGenerator.DropTable( tableName );
153 ········}
154
155 ········protected string CreateTable(XElement actionElement)
156 ········{
157 ············StringBuilder sb = new StringBuilder();
158 ············IProvider provider = NDOProviderFactory.Instance[concreteGenerator.ProviderName];
159 ············if (provider == null)
160 ················throw new Exception("Can't find NDO provider '" + concreteGenerator.ProviderName + "'.");
161
162 ············string dtTableName = actionElement.Attribute( "name" ).Value;
163
164 ············string tableName = this.provider.GetQualifiedTableName( dtTableName );
165
166 ············Class cl = FindClass(dtTableName, mappings);
167
168 ············if (cl != null)
169 ············{
170 ················Connection conn = mappings.FindConnection(cl);
171 ················if (conn != null)
172 ····················concreteGenerator.ConnectToDatabase(conn.Name);
173 ············}
174
175 ············sb.Append(concreteGenerator.BeginnTable(tableName));
176 ············sb.Append('\n');
177
178 ············List<XElement> columnElements = actionElement.Elements( "CreateColumn" ).ToList();
179
180 ············int vorletzterIndex = columnElements.Count - 1;
181 ············List<XElement> primaryKeyColumns = columnElements.Where( e =>
182 ············{
183 ················XAttribute attr;
184 ················return (attr = e.Attribute( "isPrimary" )) != null && String.Compare( attr.Value, "true", true ) == 0;
185 ············} ).ToList();
186
187 ············bool hasPrimaryKeyColumns = primaryKeyColumns.Count > 0;
188
189 ············for (int i = 0; i < columnElements.Count; i++)
190 ············{
191 ················XElement columnElement = columnElements[i];
192 ················string columnName = columnElement.Attribute("name").Value;
193
194 ················bool isPrimary = primaryKeyColumns.Any( e => e.Attribute( "name" ).Value == columnName );
195
196 ················sb.Append(CreateColumn(columnElement, cl, provider, isPrimary));
197 ················if (i < vorletzterIndex)
198 ················{
199 ····················sb.Append(",");
200 ····················sb.Append('\n');
201 ················}
202 ············}
203
204 ············if(concreteGenerator.PrimaryConstraintPlacement == PrimaryConstraintPlacement.InTable
205 ················&& hasPrimaryKeyColumns)
206 ············{
207 ················sb.Append(",");
208 ················sb.Append('\n');
209 ············}
210
211 ············if (hasPrimaryKeyColumns && concreteGenerator.PrimaryConstraintPlacement == PrimaryConstraintPlacement.InTable)
212 ············{
213 ················sb.Append(CreatePrimaryKeyConstraint(primaryKeyColumns, dtTableName, provider));
214 ············}
215 ············else
216 ············{
217 ················sb.Append('\n');
218 ············}
219 ············sb.Append(concreteGenerator.EndTable(tableName));
220 ············sb.Append('\n');
221
222 ············//············CreateIndex(primaryKeyColumns, sb, dt, provider);
223
224 ············if (hasPrimaryKeyColumns && concreteGenerator.PrimaryConstraintPlacement == PrimaryConstraintPlacement.AfterTable)
225 ············{
226 ················sb.Append(CreatePrimaryKeyConstraint(primaryKeyColumns, dtTableName, provider));
227 ············}
228
229 ············sb.Append('\n');
230
231 ············return sb.ToString();
232 ········}
233
234 ········protected NDO.Mapping.Class FindClass(string tableName, NDOMapping mappings)
235 ········{
236 ············Class result = null;
237 ············foreach(Class cl in mappings.Classes)
238 ············{
239 ················if (cl.TableName == tableName)
240 ················{
241 ····················result = cl;
242 ····················break;
243 ················}
244 ············}
245 ············return result;
246 ········}
247
248 ········static bool IsNumeric( Type type )
249 ········{
250 ············switch (Type.GetTypeCode( type ))
251 ············{
252 ················case TypeCode.Byte:
253 ················case TypeCode.SByte:
254 ················case TypeCode.UInt16:
255 ················case TypeCode.UInt32:
256 ················case TypeCode.UInt64:
257 ················case TypeCode.Int16:
258 ················case TypeCode.Int32:
259 ················case TypeCode.Int64:
260 ················case TypeCode.Decimal:
261 ················case TypeCode.Double:
262 ················case TypeCode.Single:
263 ····················return true;
264 ················case TypeCode.Object:
265 ····················if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof( Nullable<> ))
266 ····················{
267 ························return IsNumeric(Nullable.GetUnderlyingType( type ));
268 ····················}
269 ····················return false;
270 ················default:
271 ····················return false;
272 ············}
273 ········}
274
275 ········protected string CreateColumn(XElement columnElement, Class cl, IProvider provider, bool isPrimary)
276 ········{
277 ············string rawName = columnElement.Attribute( "name" ).Value;
278 ············Type dcDataType = Type.GetType( columnElement.Attribute( "type" ).Value );
279 ············string name = provider.GetQuotedName(rawName);
280 ············string columnType = columnElement.Attribute( "dbtype" )?.Value;
281 ············if (columnType == String.Empty)··// Make sure the column type will be infered, if it is an empty string
282 ················columnType = null;
283 ············string width = columnElement.Attribute("size") == null ? null : columnElement.Attribute("size").Value;
284 ············string precision = null;
285 ············bool autoIncrement = false;
286 ············StringBuilder sb = new StringBuilder();
287 ············bool allowNull = true;
288 ············string defaultValue = columnElement.Attribute( "default" )?.Value;
289
290 ············if (cl != null)
291 ············{
292 ················Field field = FindField(rawName, cl);
293
294 ················if (null != field)
295 ················{
296 ····················if ( !String.IsNullOrEmpty(columnType) && null != field.Column.DbType)
297 ························columnType = field.Column.DbType;
298 ····················if (0 != field.Column.Size && !field.Column.IgnoreColumnSizeInDDL)
299 ····················{
300 ························int dl = field.Column.Size;
301 ························if (dl == -1)
302 ····························width = "max";
303 ························else
304 ····························width = dl.ToString();
305 ····················}
306 ····················if (0 != field.Column.Precision && !field.Column.IgnoreColumnSizeInDDL)
307 ························precision = field.Column.Precision.ToString();
308 ····················allowNull = field.Column.AllowDbNull;
309 ················}
310 ················else if (cl.TimeStampColumn == rawName)
311 ················{
312 ····················if (!provider.SupportsNativeGuidType)
313 ························width = "36";
314 ················}
315 ················else if (isPrimary && columnElement.Attribute( "autoIncrement" ) != null && String.Compare(columnElement.Attribute( "autoIncrement" ).Value, "true", true) == 0)
316 ················{
317 ····················autoIncrement = true;
318 ················}
319 ············}
320 ············if (null == columnType)
321 ············{
322 ················try
323 ················{
324 ····················columnType = concreteGenerator.DbTypeFromType(dcDataType);
325 ················}
326 ················catch
327 ················{
328 ····················System.Diagnostics.Debug.Write("");
329 ················}
330 ············}
331
332 ············if (null == width)
333 ············{
334 ················int dl = provider.GetDefaultLength(dcDataType);
335 ················if (dl != 0)
336 ················{
337 ····················if (dl == -1)
338 ························width = "max";
339 ····················else
340 ························width = dl.ToString();
341 ················}
342 ············}
343 ············
344 ············// Because there is no GetDefaultPrecision in the provider...
345 ············// We assume the field to represent currency data
346 ············if (precision == null && dcDataType == typeof(decimal))
347 ············{
348 ················precision = "2";
349 ············}
350
351 ············if (columnType != null)
352 ············{
353 ················if (!concreteGenerator.LengthAllowed(columnType))
354 ····················width = null;
355 ············}
356 ············else
357 ············{
358 ················if (!concreteGenerator.LengthAllowed(dcDataType))
359 ····················width = null;
360 ············}
361
362
363 ············if (autoIncrement && concreteGenerator.HasSpecialAutoIncrementColumnFormat)
364 sb. Append( concreteGenerator. AutoIncrementColumn( name, dcDataType, columnType, width) ) ;
365 ············else if(isPrimary && concreteGenerator.PrimaryConstraintPlacement == PrimaryConstraintPlacement.InColumn)
366 ················sb.Append(concreteGenerator.PrimaryKeyColumn(name, dcDataType, columnType, width));
367 ············else if (width != null && precision != null)
368 ················sb.Append(name + " " + columnType + "(" + width + "," + precision + ")");
369 ············else if (width != null)
370 ················sb.Append(name + " " + columnType + "(" + width + ")");············
371 ············else
372 ················sb.Append(name + " " + columnType);
373
374 ············sb.Append(" ");
375
376 ············if (defaultValue != null)
377 ············{
378 ················sb.Append( "DEFAULT " );
379 ················if (IsNumeric( dcDataType ))
380 ····················sb.Append( defaultValue);
381 ················else
382 ················{
383 ····················sb.Append( '\'' );
384 ····················sb.Append( defaultValue.Replace( "'", "''" ) );
385 ····················sb.Append( '\'' );
386 ················}
387 ················sb.Append( ' ' );
388 ············}
389
390 ············sb.Append( concreteGenerator.NullExpression( allowNull && columnElement.Attribute( "allowNull" ) != null && String.Compare( columnElement.Attribute( "allowNull" ).Value, "true", true ) == 0 ) );
391 ············return sb.ToString();
392 ········}
393
394 ········protected string CreatePrimaryKeyConstraint(List<XElement> primaryKeyColumns, string tableName, IProvider provider)
395 ········{
396 ············if (primaryKeyColumns.Count == 0)
397 ················return string.Empty;
398 ············string[] strArr = tableName.Split('.');
399 ············string constraintName = provider.GetQuotedName("PK_" + strArr[strArr.Length - 1]);
400 ············DataColumn[] pkColumns = (from pk in primaryKeyColumns select new DataColumn( pk.Attribute( "name" ).Value )).ToArray();
401 ············return concreteGenerator.CreatePrimaryKeyConstraint(pkColumns, constraintName, provider.GetQualifiedTableName(tableName)) + '\n';
402 ········}
403
404 ········protected Field FindField (string columnName, Class cl)
405 ········{
406 ············Field result = null;
407 ············foreach (Field field in cl.Fields)
408 ············{
409 ················if (field.Column.Name == columnName)
410 ················{
411 ····················result = field;
412 ····················break;
413 ················}
414 ············}
415 ············return result;
416 ········}
417
418 ········protected Class GetClassForTable(string tableName, NDOMapping mapping)
419 ········{
420 ············foreach(Class cl in mapping.Classes)
421 ················if (cl.TableName == tableName)
422 ····················return cl;
423 ············return null;
424 ········}
425 ····}
426 }
427
New Commit (1e68dc7)
1 //
2 // Copyright (c) 2002-2016 Mirko Matytschak
3 // (www.netdataobjects.de)
4 //
5 // Author: Mirko Matytschak
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
8 // documentation files (the "Software"), to deal in the Software without restriction, including without limitation
9 // the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
10 // Software, and to permit persons to whom the Software is furnished to do so, subject to the following
11 // conditions:
12
13 // The above copyright notice and this permission notice shall be included in all copies or substantial portions
14 // of the Software.
15 //
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
17 // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
19 // CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 // DEALINGS IN THE SOFTWARE.
21
22
23 using System;
24 using System.Text;
25 using System.IO;
26 using System.Collections.Generic;
27 using System.Data;
28 using System.Linq;
29 using System.Xml.Linq;
30 using NDO.Mapping;
31 using NDO;
32 using NDOInterfaces;
33 using System.Globalization;
34
35 namespace NDO
36 {
37 ····/// <summary>
38 ····/// Zusammenfassung für GenericDiffGenerator.
39 ····/// </summary>
40 ····internal class SchemaTransitionGenerator
41 ····{
42 ········IProvider provider;
43 ········ISqlGenerator concreteGenerator;
44 ········//MessageAdapter messages;
45 ········NDO.Mapping.NDOMapping mappings;
46 ········public SchemaTransitionGenerator(ISqlGenerator concreteGenerator, NDO.Mapping.NDOMapping mappings)
47 ········{
48 ············provider = NDOProviderFactory.Instance[concreteGenerator.ProviderName];
49 ············this.concreteGenerator = concreteGenerator;
50 ············this.mappings = mappings;
51 ········}
52
53 ········public string Generate(XElement transElement)
54 ········{
55 ············StringBuilder sb = new StringBuilder();
56 ············foreach(XElement actionElement in transElement.Elements())
57 ············{
58 ················if (actionElement.Name == "DropTable")
59 ················{
60 ····················sb.Append( DropTable( actionElement ) );
61 ················}
62 ················else if (actionElement.Name=="CreateTable")
63 ················{
64 ····················sb.Append( CreateTable( actionElement ) );
65 ················}
66 ················else if (actionElement.Name=="AlterTable")
67 ················{
68 ····················sb.Append( ChangeTable( actionElement ) );
69 ················}
70
71 ············}
72 ············return sb.ToString();
73 ········}
74
75 ········string ChangeTable(XElement actionElement)
76 ········{
77 ············List<XElement> addedColumns = actionElement.Elements("AddColumn").ToList();
78 ············List<XElement> removedColumns = actionElement.Elements("DropColumn").ToList();
79 ············List<XElement> changedColumns = actionElement.Elements("AlterColumn").ToList();
80
81 ············if (addedColumns.Count == 0 && removedColumns.Count == 0 && changedColumns.Count == 0)
82 ················return String.Empty;
83
84 ············StringBuilder sb = new StringBuilder();
85
86 ············string rawTableName = actionElement.Attribute( "name" ).Value;
87 ············string tableName = this.provider.GetQualifiedTableName(rawTableName);
88 ············string alterString = "ALTER TABLE " + tableName + ' ';
89
90 ············foreach(XElement columnElement in addedColumns)
91 ············{
92 ················sb.Append(alterString);
93 ················sb.Append(concreteGenerator.AddColumn());
94 ················sb.Append(' ');
95 ················sb.Append(CreateColumn(columnElement, GetClassForTable(rawTableName, this.mappings), this.provider, false));
96 ················sb.Append(";\n");
97 ············}
98
99 ············foreach(XElement columnElement in removedColumns)
100 ············{
101 ················sb.Append(alterString);
102 ················sb.Append( concreteGenerator.RemoveColumn( provider.GetQuotedName( columnElement.Attribute( "name" ).Value ) ) );
103 ················sb.Append(";\n");
104 ············}
105
106 ············foreach(XElement columnElement in changedColumns)
107 ············{
108 ················sb.Append(alterString);
109 ················sb.Append(concreteGenerator.AlterColumnType());
110 ················sb.Append(' ');
111 ················sb.Append(CreateColumn(columnElement, GetClassForTable(rawTableName, this.mappings), this.provider, false));
112 ················sb.Append(";\n");
113 ············}
114
115 ············return sb.ToString();
116 ········}
117
118 ········string RenameColumn(string tableName, string oldColumn, string newColumn, string typeString)
119 ········{
120 ············string s = concreteGenerator.RenameColumn(tableName, oldColumn, newColumn, typeString);
121 ············
122 ············if (s != string.Empty)
123 ············return s;
124 ········
125 ············string alterString = "ALTER TABLE " + tableName + ' ';
126
127 ············StringBuilder sb = new StringBuilder(alterString);
128 ············sb.Append(concreteGenerator.AddColumn());
129 ············sb.Append(' ');
130 ············sb.Append(newColumn);
131 ············sb.Append(' ');
132 ············sb.Append(typeString);
133 ············sb.Append(";\n");
134
135 ············sb.Append("UPDATE ");
136 ············sb.Append(tableName);
137 ············sb.Append(" SET ");············
138 ············sb.Append(newColumn);
139 ············sb.Append(" = ");
140 ············sb.Append(oldColumn);
141 ············sb.Append(";\n");
142
143 ············sb.Append(alterString);
144 ············sb.Append(concreteGenerator.RemoveColumn(oldColumn));
145 ············sb.Append(';');
146 ············return sb.ToString();
147 ········}
148
149 ········protected string DropTable(XElement actionElement)
150 ········{
151 ············string tableName = this.provider .GetQualifiedTableName( actionElement.Attribute( "name" ).Value );
152 ············return concreteGenerator.DropTable( tableName );
153 ········}
154
155 ········protected string CreateTable(XElement actionElement)
156 ········{
157 ············StringBuilder sb = new StringBuilder();
158 ············IProvider provider = NDOProviderFactory.Instance[concreteGenerator.ProviderName];
159 ············if (provider == null)
160 ················throw new Exception("Can't find NDO provider '" + concreteGenerator.ProviderName + "'.");
161
162 ············string dtTableName = actionElement.Attribute( "name" ).Value;
163
164 ············string tableName = this.provider.GetQualifiedTableName( dtTableName );
165
166 ············Class cl = FindClass(dtTableName, mappings);
167
168 ············if (cl != null)
169 ············{
170 ················Connection conn = mappings.FindConnection(cl);
171 ················if (conn != null)
172 ····················concreteGenerator.ConnectToDatabase(conn.Name);
173 ············}
174
175 ············sb.Append(concreteGenerator.BeginnTable(tableName));
176 ············sb.Append('\n');
177
178 ············List<XElement> columnElements = actionElement.Elements( "CreateColumn" ).ToList();
179
180 ············int vorletzterIndex = columnElements.Count - 1;
181 ············List<XElement> primaryKeyColumns = columnElements.Where( e =>
182 ············{
183 ················XAttribute attr;
184 ················return (attr = e.Attribute( "isPrimary" )) != null && String.Compare( attr.Value, "true", true ) == 0;
185 ············} ).ToList();
186
187 ············bool hasPrimaryKeyColumns = primaryKeyColumns.Count > 0;
188
189 ············for (int i = 0; i < columnElements.Count; i++)
190 ············{
191 ················XElement columnElement = columnElements[i];
192 ················string columnName = columnElement.Attribute("name").Value;
193
194 ················bool isPrimary = primaryKeyColumns.Any( e => e.Attribute( "name" ).Value == columnName );
195
196 ················sb.Append(CreateColumn(columnElement, cl, provider, isPrimary));
197 ················if (i < vorletzterIndex)
198 ················{
199 ····················sb.Append(",");
200 ····················sb.Append('\n');
201 ················}
202 ············}
203
204 ············if(concreteGenerator.PrimaryConstraintPlacement == PrimaryConstraintPlacement.InTable
205 ················&& hasPrimaryKeyColumns)
206 ············{
207 ················sb.Append(",");
208 ················sb.Append('\n');
209 ············}
210
211 ············if (hasPrimaryKeyColumns && concreteGenerator.PrimaryConstraintPlacement == PrimaryConstraintPlacement.InTable)
212 ············{
213 ················sb.Append(CreatePrimaryKeyConstraint(primaryKeyColumns, dtTableName, provider));
214 ············}
215 ············else
216 ············{
217 ················sb.Append('\n');
218 ············}
219 ············sb.Append(concreteGenerator.EndTable(tableName));
220 ············sb.Append('\n');
221
222 ············//············CreateIndex(primaryKeyColumns, sb, dt, provider);
223
224 ············if (hasPrimaryKeyColumns && concreteGenerator.PrimaryConstraintPlacement == PrimaryConstraintPlacement.AfterTable)
225 ············{
226 ················sb.Append(CreatePrimaryKeyConstraint(primaryKeyColumns, dtTableName, provider));
227 ············}
228
229 ············sb.Append('\n');
230
231 ············return sb.ToString();
232 ········}
233
234 ········protected NDO.Mapping.Class FindClass(string tableName, NDOMapping mappings)
235 ········{
236 ············Class result = null;
237 ············foreach(Class cl in mappings.Classes)
238 ············{
239 ················if (cl.TableName == tableName)
240 ················{
241 ····················result = cl;
242 ····················break;
243 ················}
244 ············}
245 ············return result;
246 ········}
247
248 ········static bool IsNumeric( Type type )
249 ········{
250 ············switch (Type.GetTypeCode( type ))
251 ············{
252 ················case TypeCode.Byte:
253 ················case TypeCode.SByte:
254 ················case TypeCode.UInt16:
255 ················case TypeCode.UInt32:
256 ················case TypeCode.UInt64:
257 ················case TypeCode.Int16:
258 ················case TypeCode.Int32:
259 ················case TypeCode.Int64:
260 ················case TypeCode.Decimal:
261 ················case TypeCode.Double:
262 ················case TypeCode.Single:
263 ····················return true;
264 ················case TypeCode.Object:
265 ····················if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof( Nullable<> ))
266 ····················{
267 ························return IsNumeric(Nullable.GetUnderlyingType( type ));
268 ····················}
269 ····················return false;
270 ················default:
271 ····················return false;
272 ············}
273 ········}
274
275 ········protected string CreateColumn(XElement columnElement, Class cl, IProvider provider, bool isPrimary)
276 ········{
277 ············string rawName = columnElement.Attribute( "name" ).Value;
278 ············Type dcDataType = Type.GetType( columnElement.Attribute( "type" ).Value );
279 ············string name = provider.GetQuotedName(rawName);
280 ············string columnType = columnElement.Attribute( "dbtype" )?.Value;
281 ············if (columnType == String.Empty)··// Make sure the column type will be infered, if it is an empty string
282 ················columnType = null;
283 ············string width = columnElement.Attribute("size") == null ? null : columnElement.Attribute("size").Value;
284 ············string precision = null;
285 ············bool autoIncrement = false;
286 ············StringBuilder sb = new StringBuilder();
287 ············bool allowNull = true;
288 ············string defaultValue = columnElement.Attribute( "default" )?.Value;
289
290 ············if (cl != null)
291 ············{
292 ················Field field = FindField(rawName, cl);
293
294 ················if (null != field)
295 ················{
296 ····················if ( !String.IsNullOrEmpty(columnType) && null != field.Column.DbType)
297 ························columnType = field.Column.DbType;
298 ····················if (0 != field.Column.Size && !field.Column.IgnoreColumnSizeInDDL)
299 ····················{
300 ························int dl = field.Column.Size;
301 ························if (dl == -1)
302 ····························width = "max";
303 ························else
304 ····························width = dl.ToString();
305 ····················}
306 ····················if (0 != field.Column.Precision && !field.Column.IgnoreColumnSizeInDDL)
307 ························precision = field.Column.Precision.ToString();
308 ····················allowNull = field.Column.AllowDbNull;
309 ················}
310 ················else if (cl.TimeStampColumn == rawName)
311 ················{
312 ····················if (!provider.SupportsNativeGuidType)
313 ························width = "36";
314 ················}
315 ················else if (isPrimary && columnElement.Attribute( "autoIncrement" ) != null && String.Compare(columnElement.Attribute( "autoIncrement" ).Value, "true", true) == 0)
316 ················{
317 ····················autoIncrement = true;
318 ················}
319 ············}
320 ············if (null == columnType)
321 ············{
322 ················try
323 ················{
324 ····················columnType = concreteGenerator.DbTypeFromType(dcDataType);
325 ················}
326 ················catch
327 ················{
328 ····················System.Diagnostics.Debug.Write("");
329 ················}
330 ············}
331
332 ············if (null == width)
333 ············{
334 ················int dl = provider.GetDefaultLength(dcDataType);
335 ················if (dl != 0)
336 ················{
337 ····················if (dl == -1)
338 ························width = "max";
339 ····················else
340 ························width = dl.ToString();
341 ················}
342 ············}
343 ············
344 ············// Because there is no GetDefaultPrecision in the provider...
345 ············// We assume the field to represent currency data
346 ············if (precision == null && dcDataType == typeof(decimal))
347 ············{
348 ················precision = "2";
349 ············}
350
351 ············if (columnType != null)
352 ············{
353 ················if (!concreteGenerator.LengthAllowed(columnType))
354 ····················width = null;
355 ············}
356 ············else
357 ············{
358 ················if (!concreteGenerator.LengthAllowed(dcDataType))
359 ····················width = null;
360 ············}
361
362
363 ············if (autoIncrement && concreteGenerator.HasSpecialAutoIncrementColumnFormat)
364 sb. Append( concreteGenerator. AutoIncrementColumn( name, dcDataType, columnType, width, isPrimary) ) ;
365 ············else if(isPrimary && concreteGenerator.PrimaryConstraintPlacement == PrimaryConstraintPlacement.InColumn)
366 ················sb.Append(concreteGenerator.PrimaryKeyColumn(name, dcDataType, columnType, width));
367 ············else if (width != null && precision != null)
368 ················sb.Append(name + " " + columnType + "(" + width + "," + precision + ")");
369 ············else if (width != null)
370 ················sb.Append(name + " " + columnType + "(" + width + ")");············
371 ············else
372 ················sb.Append(name + " " + columnType);
373
374 ············sb.Append(" ");
375
376 ············if (defaultValue != null)
377 ············{
378 ················sb.Append( "DEFAULT " );
379 ················if (IsNumeric( dcDataType ))
380 ····················sb.Append( defaultValue);
381 ················else
382 ················{
383 ····················sb.Append( '\'' );
384 ····················sb.Append( defaultValue.Replace( "'", "''" ) );
385 ····················sb.Append( '\'' );
386 ················}
387 ················sb.Append( ' ' );
388 ············}
389
390 ············sb.Append( concreteGenerator.NullExpression( allowNull && columnElement.Attribute( "allowNull" ) != null && String.Compare( columnElement.Attribute( "allowNull" ).Value, "true", true ) == 0 ) );
391 ············return sb.ToString();
392 ········}
393
394 ········protected string CreatePrimaryKeyConstraint(List<XElement> primaryKeyColumns, string tableName, IProvider provider)
395 ········{
396 ············if (primaryKeyColumns.Count == 0)
397 ················return string.Empty;
398 ············string[] strArr = tableName.Split('.');
399 ············string constraintName = provider.GetQuotedName("PK_" + strArr[strArr.Length - 1]);
400 ············DataColumn[] pkColumns = (from pk in primaryKeyColumns select new DataColumn( pk.Attribute( "name" ).Value )).ToArray();
401 ············return concreteGenerator.CreatePrimaryKeyConstraint(pkColumns, constraintName, provider.GetQualifiedTableName(tableName)) + '\n';
402 ········}
403
404 ········protected Field FindField (string columnName, Class cl)
405 ········{
406 ············Field result = null;
407 ············foreach (Field field in cl.Fields)
408 ············{
409 ················if (field.Column.Name == columnName)
410 ················{
411 ····················result = field;
412 ····················break;
413 ················}
414 ············}
415 ············return result;
416 ········}
417
418 ········protected Class GetClassForTable(string tableName, NDOMapping mapping)
419 ········{
420 ············foreach(Class cl in mapping.Classes)
421 ················if (cl.TableName == tableName)
422 ····················return cl;
423 ············return null;
424 ········}
425 ····}
426 }
427