Mercurial > pub > bltoolkit
comparison Source/Templates/MySql.ttinclude @ 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 <# | |
2 ConnectionType = "MySql.Data.MySqlClient.MySqlConnection, MySql.Data"; | |
3 #><#+ | |
4 | |
5 private void LoadServerMetadata() | |
6 { | |
7 var tables = CreateList(new { ID = "", Table = new Table() }); | |
8 var columns = CreateList(new { ID = "", Column = new Column() }); | |
9 | |
10 using (var conn = GetConnection()) | |
11 using (var cmd = conn.CreateCommand()) | |
12 { | |
13 string schemasToSkip = "'information_schema', 'cr_debug', 'mysql'"; | |
14 | |
15 // Load tables & views. | |
16 // | |
17 | |
18 cmd.CommandText = "SELECT DATABASE()"; | |
19 _databaseName = Convert.ToString(cmd.ExecuteScalar()); | |
20 | |
21 cmd.CommandText = string.Format(@" | |
22 SELECT | |
23 CONCAT(TABLE_SCHEMA, '.', TABLE_NAME), | |
24 TABLE_SCHEMA, | |
25 TABLE_NAME, | |
26 TABLE_TYPE | |
27 FROM | |
28 INFORMATION_SCHEMA.tables | |
29 WHERE | |
30 TABLE_SCHEMA NOT IN ({0}) AND | |
31 TABLE_TYPE IN ('BASE TABLE', 'VIEW') | |
32 {1}", | |
33 schemasToSkip, | |
34 GetDatabaseSqlFilter("")); | |
35 | |
36 using (var rd = cmd.ExecuteReader()) | |
37 { | |
38 while (rd.Read()) | |
39 { | |
40 var t = new | |
41 { | |
42 ID = Convert.ToString(rd[0]), | |
43 Table = new Table | |
44 { | |
45 Owner = null, // there is no concept of table owner in MySql | |
46 TableName = rd[2].ToString(), | |
47 ClassName = rd[2].ToString(), | |
48 DataContextPropertyName = rd[2].ToString(), | |
49 IsView = rd[3].ToString() == "VIEW", | |
50 BaseClassName = BaseEntityClass, | |
51 } | |
52 }; | |
53 | |
54 tables.Add(t); | |
55 } | |
56 } | |
57 | |
58 cmd.CommandText = "SELECT @@session.sql_mode"; | |
59 string sqlMode = Convert.ToString(cmd.ExecuteScalar()); | |
60 | |
61 // Load columns. | |
62 // | |
63 cmd.CommandText = string.Format(@" | |
64 SELECT | |
65 CONCAT(TABLE_SCHEMA, '.', TABLE_NAME) as id, | |
66 CASE WHEN IS_NULLABLE = 'YES' THEN 1 ELSE 0 END as isNullable, | |
67 ORDINAL_POSITION as colid, | |
68 COLUMN_NAME as name, | |
69 c.DATA_TYPE as dataType, | |
70 CHARACTER_MAXIMUM_LENGTH as length, | |
71 NUMERIC_PRECISION as prec, | |
72 NUMERIC_SCALE as scale, | |
73 EXTRA = 'auto_increment' as isIdentity, | |
74 c.COLUMN_TYPE as columnType, | |
75 COLUMN_DEFAULT as columnDefault, | |
76 EXTRA as extra | |
77 FROM | |
78 INFORMATION_SCHEMA.COLUMNS c | |
79 WHERE | |
80 TABLE_SCHEMA NOT IN ({0}) | |
81 {1}", | |
82 schemasToSkip, | |
83 GetDatabaseSqlFilter("")); | |
84 | |
85 using (var rd = cmd.ExecuteReader()) | |
86 { | |
87 while (rd.Read()) | |
88 { | |
89 var col = new | |
90 { | |
91 ID = Convert.ToString(rd["id"]), | |
92 Column = new Column | |
93 { | |
94 ID = Convert.ToInt16 (rd["colid"]), | |
95 ColumnName = Convert.ToString (rd["name"]), | |
96 MemberName = Convert.ToString (rd["name"]), | |
97 ColumnType = Convert.ToString (rd["dataType"]), | |
98 IsNullable = Convert.ToBoolean(rd["isNullable"]), | |
99 IsIdentity = Convert.ToBoolean(rd["isIdentity"]), | |
100 Length = rd.IsDBNull(rd.GetOrdinal("length")) ? 0 : Convert.ToInt64(rd["length"]), | |
101 Precision = rd.IsDBNull(rd.GetOrdinal("prec")) ? 0 : Convert.ToInt32(rd["prec"]), | |
102 Scale = rd.IsDBNull(rd.GetOrdinal("scale")) ? 0 : Convert.ToInt32(rd["scale"]), | |
103 ColumnDefault = Convert.ToString(rd["columnDefault"]), | |
104 Extra = Convert.ToString(rd["extra"]).ToUpper() | |
105 } | |
106 }; | |
107 | |
108 var c = col.Column; | |
109 var columnType = Convert.ToString(rd["columnType"]).ToLower(); | |
110 var unsigned = columnType.Contains("unsigned"); | |
111 var realAsFloat = sqlMode.ToLower().Contains("real_as_float"); | |
112 | |
113 switch (c.ColumnType) | |
114 { | |
115 case "longtext" : | |
116 case "mediumtext" : | |
117 case "tinytext" : | |
118 case "text" : c.Type = "string"; c.DbType = DbType.String; c.SqlDbType = SqlDbType.Text; break; | |
119 case "binary" : c.Type = "byte[]"; c.DbType = DbType.Binary; c.SqlDbType = SqlDbType.Binary; break; | |
120 case "date" : c.Type = "DateTime"; c.DbType = DbType.Date; c.SqlDbType = SqlDbType.Date; break; | |
121 case "time" : c.Type = "DateTime"; c.DbType = DbType.Time; c.SqlDbType = SqlDbType.Time; break; | |
122 case "bit" : c.Type = "bool"; c.DbType = DbType.Boolean; c.SqlDbType = SqlDbType.Bit; break; | |
123 case "numeric" : | |
124 case "decimal" : | |
125 case "dec" : | |
126 case "fixed" : c.Type = "decimal"; c.DbType = DbType.Decimal; c.SqlDbType = SqlDbType.Decimal; break; | |
127 case "datetime" : c.Type = "DateTime"; c.DbType = DbType.DateTime; c.SqlDbType = SqlDbType.DateTime; break; | |
128 case "float" : c.Type = "float"; c.DbType = DbType.Single; c.SqlDbType = SqlDbType.Float; break; | |
129 case "double" : c.Type = "double"; c.DbType = DbType.Double; c.SqlDbType = SqlDbType.Float; break; | |
130 case "varbinary" : c.Type = "byte[]"; c.DbType = DbType.Binary; c.SqlDbType = SqlDbType.VarBinary; break; | |
131 case "varchar" : c.Type = "string"; c.DbType = DbType.String; c.SqlDbType = SqlDbType.VarChar; break; | |
132 case "year" : c.Type = "DateTime"; c.DbType = DbType.Date; c.SqlDbType = SqlDbType.Date; break; | |
133 case "enum" : | |
134 case "set" : c.Type = "string"; c.DbType = DbType.String; c.SqlDbType = SqlDbType.VarChar; break; | |
135 case "bool" : | |
136 case "boolean" : c.Type = "bool"; c.DbType = DbType.Boolean; c.SqlDbType = SqlDbType.Bit; break; | |
137 case "serial" : c.Type = "ulong"; c.DbType = DbType.UInt64; c.SqlDbType = SqlDbType.BigInt; break; | |
138 case "mediumblob" : | |
139 case "longblob" : | |
140 case "blob" : c.Type = "byte[]"; c.DbType = DbType.Binary; c.SqlDbType = SqlDbType.Image; break; | |
141 case "tinyblob" : c.Type = "byte[]"; c.DbType = DbType.Binary; c.SqlDbType = SqlDbType.Binary; break; | |
142 | |
143 case "smallint" : c.Type = unsigned ? "ushort" : "short"; c.DbType = unsigned ? DbType.UInt16 : DbType.Int16; c.SqlDbType = SqlDbType.SmallInt; break; | |
144 case "mediumint" : | |
145 case "int" : | |
146 case "integer" : c.Type = unsigned ? "uint" : "int"; c.DbType = unsigned ? DbType.UInt32 : DbType.Int32; c.SqlDbType = SqlDbType.Int; break; | |
147 case "real" : c.Type = realAsFloat ? "float" : "double"; c.DbType = realAsFloat ? DbType.Single : DbType.Double; c.SqlDbType = SqlDbType.Real; break; | |
148 case "bigint" : c.Type = unsigned ? "ulong" : "long"; c.DbType = unsigned ? DbType.UInt64 : DbType.Int64; c.SqlDbType = SqlDbType.BigInt; break; | |
149 case "char" : c.Type = "string"; c.DbType = DbType.StringFixedLength; c.SqlDbType = SqlDbType.Char; break; | |
150 case "timestamp" : | |
151 c.Type = "DateTime"; | |
152 c.DbType = DbType.DateTime; | |
153 c.SqlDbType = SqlDbType.Timestamp; | |
154 | |
155 if(c.ColumnDefault == "CURRENT_TIMESTAMP" || c.Extra.Contains("ON UPDATE CURRENT_TIMESTAMP")) | |
156 { | |
157 c.Attributes.Add(string.Format( | |
158 "NonUpdatable(OnInsert = {0}, OnUpdate = {1})", | |
159 c.ColumnDefault == "CURRENT_TIMESTAMP" ? "true" : "false", | |
160 c.Extra.Contains("ON UPDATE CURRENT_TIMESTAMP") ? "true" : "false")); | |
161 } | |
162 break; | |
163 case "tinyint" : | |
164 if(columnType == "tinyint(1)") | |
165 { | |
166 c.Type = "bool"; | |
167 c.DbType = DbType.Boolean; | |
168 c.SqlDbType = SqlDbType.Bit; | |
169 } | |
170 else | |
171 { | |
172 c.Type = unsigned ? "byte" : "sbyte"; | |
173 c.DbType = unsigned ? DbType.Byte : DbType.SByte; | |
174 c.SqlDbType = SqlDbType.TinyInt; | |
175 } | |
176 break; | |
177 default : | |
178 throw new System.IO.InvalidDataException(string.Format("Unknown column type: {0}.", c.ColumnType)); | |
179 } | |
180 | |
181 switch (c.Type) | |
182 { | |
183 case "string" : | |
184 case "byte[]" : c.IsClass = true; break; | |
185 } | |
186 | |
187 if (c.IsNullable && !c.IsClass) | |
188 c.Type += "?"; | |
189 | |
190 columns.Add(col); | |
191 } | |
192 } | |
193 | |
194 // Load PKs. | |
195 // | |
196 cmd.CommandText = string.Format(@" | |
197 SELECT | |
198 CONCAT(k.TABLE_SCHEMA, '.', k.TABLE_NAME) as id, | |
199 k.CONSTRAINT_NAME as name, | |
200 k.COLUMN_NAME as colname, | |
201 k.ORDINAL_POSITION as colid | |
202 FROM | |
203 INFORMATION_SCHEMA.KEY_COLUMN_USAGE k | |
204 JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS c ON k.CONSTRAINT_NAME = c.CONSTRAINT_NAME | |
205 WHERE | |
206 c.CONSTRAINT_TYPE='PRIMARY KEY' AND | |
207 k.TABLE_SCHEMA NOT IN ({0}) | |
208 {1} | |
209 GROUP BY id, colid", | |
210 schemasToSkip, | |
211 GetDatabaseSqlFilter("k")); | |
212 | |
213 using (var rd = cmd.ExecuteReader()) | |
214 { | |
215 while (rd.Read()) | |
216 { | |
217 var id = Convert.ToString(rd["id"]); | |
218 var colid = Convert.ToInt32 (rd["colid"]); | |
219 var colname = Convert.ToString(rd["colname"]); | |
220 | |
221 columns.Single(_ => _.ID == id && _.Column.ColumnName == colname).Column.PKIndex = colid; | |
222 } | |
223 } | |
224 | |
225 // Load FKs. | |
226 // | |
227 cmd.CommandText = string.Format(@" | |
228 SELECT | |
229 CONSTRAINT_NAME as Name, | |
230 CONCAT(TABLE_SCHEMA, '.', TABLE_NAME) as ThisTable, | |
231 COLUMN_NAME as ThisColumn, | |
232 CONCAT(REFERENCED_TABLE_SCHEMA, '.', REFERENCED_TABLE_NAME) as OtherTable, | |
233 REFERENCED_COLUMN_NAME as OtherColumn, | |
234 ORDINAL_POSITION as Ordinal | |
235 FROM | |
236 INFORMATION_SCHEMA.key_column_usage | |
237 WHERE | |
238 TABLE_SCHEMA NOT IN ({0}) AND | |
239 REFERENCED_TABLE_NAME IS NOT NULL AND | |
240 REFERENCED_COLUMN_NAME IS NOT NULL | |
241 {1} | |
242 ORDER BY | |
243 ThisTable, | |
244 Ordinal", | |
245 schemasToSkip, | |
246 GetDatabaseSqlFilter("")); | |
247 | |
248 if(!string.IsNullOrEmpty(DatabaseName)) | |
249 cmd.CommandText += string.Format(" AND TABLE_SCHEMA = '{0}' ", DatabaseName); | |
250 | |
251 using (var rd = cmd.ExecuteReader()) | |
252 { | |
253 while (rd.Read()) | |
254 { | |
255 var name = Convert.ToString(rd["Name"]); | |
256 var thisTableID = Convert.ToString(rd["ThisTable"]); | |
257 var otherTableID = Convert.ToString(rd["OtherTable"]); | |
258 var thisColumnName = Convert.ToString(rd["ThisColumn"]); | |
259 var otherColumnName = Convert.ToString(rd["OtherColumn"]); | |
260 | |
261 var thisTable = (from t in tables where t.ID == thisTableID select t.Table).Single(); | |
262 var otherTable = (from t in tables where t.ID == otherTableID select t.Table).Single(); | |
263 var thisColumn = (from c in columns where c.ID == thisTableID && c.Column.ColumnName == thisColumnName select c.Column).Single(); | |
264 var otherColumn = (from c in columns where c.ID == otherTableID && c.Column.ColumnName == otherColumnName select c.Column).Single(); | |
265 | |
266 if (thisTable.ForeignKeys.ContainsKey(name) == false) | |
267 thisTable.ForeignKeys.Add(name, new ForeignKey { KeyName = name, MemberName = name, OtherTable = otherTable }); | |
268 | |
269 var key = thisTable.ForeignKeys[name]; | |
270 | |
271 key.ThisColumns. Add(thisColumn); | |
272 key.OtherColumns.Add(otherColumn); | |
273 } | |
274 } | |
275 } | |
276 | |
277 var qc = | |
278 from c in columns | |
279 group c by c.ID into gr | |
280 join t in tables on gr.Key equals t.ID | |
281 select new { t.Table, gr }; | |
282 | |
283 foreach (var c in qc) | |
284 { | |
285 foreach (var col in from col in c.gr orderby col.Column.ID select col.Column) | |
286 c.Table.Columns.Add(col.ColumnName, col); | |
287 | |
288 // there is no concept of table owner in MySql so we just use table name | |
289 Tables.Add(c.Table.TableName, c.Table); | |
290 } | |
291 } | |
292 | |
293 private string _databaseName; | |
294 private string GetDatabaseSqlFilter(string optionalTablePrefix) | |
295 { | |
296 if(string.IsNullOrEmpty(_databaseName)) return ""; | |
297 string tablePrefix = string.IsNullOrEmpty(optionalTablePrefix) ? "" : optionalTablePrefix + "."; | |
298 return string.Format(" AND {0}TABLE_SCHEMA = '{1}' ", tablePrefix, _databaseName); | |
299 } | |
300 | |
301 public partial class Column | |
302 { | |
303 public string ColumnDefault; | |
304 public string Extra; | |
305 } | |
306 | |
307 #> |