Mercurial > pub > bltoolkit
diff Source/Templates/MySql.ttinclude @ 0:f990fcb411a9
Копия текущей версии из github
author | cin |
---|---|
date | Thu, 27 Mar 2014 21:46:09 +0400 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Templates/MySql.ttinclude Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,307 @@ +<# + ConnectionType = "MySql.Data.MySqlClient.MySqlConnection, MySql.Data"; +#><#+ + +private void LoadServerMetadata() +{ + var tables = CreateList(new { ID = "", Table = new Table() }); + var columns = CreateList(new { ID = "", Column = new Column() }); + + using (var conn = GetConnection()) + using (var cmd = conn.CreateCommand()) + { + string schemasToSkip = "'information_schema', 'cr_debug', 'mysql'"; + + // Load tables & views. + // + + cmd.CommandText = "SELECT DATABASE()"; + _databaseName = Convert.ToString(cmd.ExecuteScalar()); + + cmd.CommandText = string.Format(@" + SELECT + CONCAT(TABLE_SCHEMA, '.', TABLE_NAME), + TABLE_SCHEMA, + TABLE_NAME, + TABLE_TYPE + FROM + INFORMATION_SCHEMA.tables + WHERE + TABLE_SCHEMA NOT IN ({0}) AND + TABLE_TYPE IN ('BASE TABLE', 'VIEW') + {1}", + schemasToSkip, + GetDatabaseSqlFilter("")); + + using (var rd = cmd.ExecuteReader()) + { + while (rd.Read()) + { + var t = new + { + ID = Convert.ToString(rd[0]), + Table = new Table + { + Owner = null, // there is no concept of table owner in MySql + TableName = rd[2].ToString(), + ClassName = rd[2].ToString(), + DataContextPropertyName = rd[2].ToString(), + IsView = rd[3].ToString() == "VIEW", + BaseClassName = BaseEntityClass, + } + }; + + tables.Add(t); + } + } + + cmd.CommandText = "SELECT @@session.sql_mode"; + string sqlMode = Convert.ToString(cmd.ExecuteScalar()); + + // Load columns. + // + cmd.CommandText = string.Format(@" + SELECT + CONCAT(TABLE_SCHEMA, '.', TABLE_NAME) as id, + CASE WHEN IS_NULLABLE = 'YES' THEN 1 ELSE 0 END as isNullable, + ORDINAL_POSITION as colid, + COLUMN_NAME as name, + c.DATA_TYPE as dataType, + CHARACTER_MAXIMUM_LENGTH as length, + NUMERIC_PRECISION as prec, + NUMERIC_SCALE as scale, + EXTRA = 'auto_increment' as isIdentity, + c.COLUMN_TYPE as columnType, + COLUMN_DEFAULT as columnDefault, + EXTRA as extra + FROM + INFORMATION_SCHEMA.COLUMNS c + WHERE + TABLE_SCHEMA NOT IN ({0}) + {1}", + schemasToSkip, + GetDatabaseSqlFilter("")); + + using (var rd = cmd.ExecuteReader()) + { + while (rd.Read()) + { + var col = new + { + ID = Convert.ToString(rd["id"]), + Column = new Column + { + ID = Convert.ToInt16 (rd["colid"]), + ColumnName = Convert.ToString (rd["name"]), + MemberName = Convert.ToString (rd["name"]), + ColumnType = Convert.ToString (rd["dataType"]), + IsNullable = Convert.ToBoolean(rd["isNullable"]), + IsIdentity = Convert.ToBoolean(rd["isIdentity"]), + Length = rd.IsDBNull(rd.GetOrdinal("length")) ? 0 : Convert.ToInt64(rd["length"]), + Precision = rd.IsDBNull(rd.GetOrdinal("prec")) ? 0 : Convert.ToInt32(rd["prec"]), + Scale = rd.IsDBNull(rd.GetOrdinal("scale")) ? 0 : Convert.ToInt32(rd["scale"]), + ColumnDefault = Convert.ToString(rd["columnDefault"]), + Extra = Convert.ToString(rd["extra"]).ToUpper() + } + }; + + var c = col.Column; + var columnType = Convert.ToString(rd["columnType"]).ToLower(); + var unsigned = columnType.Contains("unsigned"); + var realAsFloat = sqlMode.ToLower().Contains("real_as_float"); + + switch (c.ColumnType) + { + case "longtext" : + case "mediumtext" : + case "tinytext" : + case "text" : c.Type = "string"; c.DbType = DbType.String; c.SqlDbType = SqlDbType.Text; break; + case "binary" : c.Type = "byte[]"; c.DbType = DbType.Binary; c.SqlDbType = SqlDbType.Binary; break; + case "date" : c.Type = "DateTime"; c.DbType = DbType.Date; c.SqlDbType = SqlDbType.Date; break; + case "time" : c.Type = "DateTime"; c.DbType = DbType.Time; c.SqlDbType = SqlDbType.Time; break; + case "bit" : c.Type = "bool"; c.DbType = DbType.Boolean; c.SqlDbType = SqlDbType.Bit; break; + case "numeric" : + case "decimal" : + case "dec" : + case "fixed" : c.Type = "decimal"; c.DbType = DbType.Decimal; c.SqlDbType = SqlDbType.Decimal; break; + case "datetime" : c.Type = "DateTime"; c.DbType = DbType.DateTime; c.SqlDbType = SqlDbType.DateTime; break; + case "float" : c.Type = "float"; c.DbType = DbType.Single; c.SqlDbType = SqlDbType.Float; break; + case "double" : c.Type = "double"; c.DbType = DbType.Double; c.SqlDbType = SqlDbType.Float; break; + case "varbinary" : c.Type = "byte[]"; c.DbType = DbType.Binary; c.SqlDbType = SqlDbType.VarBinary; break; + case "varchar" : c.Type = "string"; c.DbType = DbType.String; c.SqlDbType = SqlDbType.VarChar; break; + case "year" : c.Type = "DateTime"; c.DbType = DbType.Date; c.SqlDbType = SqlDbType.Date; break; + case "enum" : + case "set" : c.Type = "string"; c.DbType = DbType.String; c.SqlDbType = SqlDbType.VarChar; break; + case "bool" : + case "boolean" : c.Type = "bool"; c.DbType = DbType.Boolean; c.SqlDbType = SqlDbType.Bit; break; + case "serial" : c.Type = "ulong"; c.DbType = DbType.UInt64; c.SqlDbType = SqlDbType.BigInt; break; + case "mediumblob" : + case "longblob" : + case "blob" : c.Type = "byte[]"; c.DbType = DbType.Binary; c.SqlDbType = SqlDbType.Image; break; + case "tinyblob" : c.Type = "byte[]"; c.DbType = DbType.Binary; c.SqlDbType = SqlDbType.Binary; break; + + case "smallint" : c.Type = unsigned ? "ushort" : "short"; c.DbType = unsigned ? DbType.UInt16 : DbType.Int16; c.SqlDbType = SqlDbType.SmallInt; break; + case "mediumint" : + case "int" : + case "integer" : c.Type = unsigned ? "uint" : "int"; c.DbType = unsigned ? DbType.UInt32 : DbType.Int32; c.SqlDbType = SqlDbType.Int; break; + case "real" : c.Type = realAsFloat ? "float" : "double"; c.DbType = realAsFloat ? DbType.Single : DbType.Double; c.SqlDbType = SqlDbType.Real; break; + case "bigint" : c.Type = unsigned ? "ulong" : "long"; c.DbType = unsigned ? DbType.UInt64 : DbType.Int64; c.SqlDbType = SqlDbType.BigInt; break; + case "char" : c.Type = "string"; c.DbType = DbType.StringFixedLength; c.SqlDbType = SqlDbType.Char; break; + case "timestamp" : + c.Type = "DateTime"; + c.DbType = DbType.DateTime; + c.SqlDbType = SqlDbType.Timestamp; + + if(c.ColumnDefault == "CURRENT_TIMESTAMP" || c.Extra.Contains("ON UPDATE CURRENT_TIMESTAMP")) + { + c.Attributes.Add(string.Format( + "NonUpdatable(OnInsert = {0}, OnUpdate = {1})", + c.ColumnDefault == "CURRENT_TIMESTAMP" ? "true" : "false", + c.Extra.Contains("ON UPDATE CURRENT_TIMESTAMP") ? "true" : "false")); + } + break; + case "tinyint" : + if(columnType == "tinyint(1)") + { + c.Type = "bool"; + c.DbType = DbType.Boolean; + c.SqlDbType = SqlDbType.Bit; + } + else + { + c.Type = unsigned ? "byte" : "sbyte"; + c.DbType = unsigned ? DbType.Byte : DbType.SByte; + c.SqlDbType = SqlDbType.TinyInt; + } + break; + default : + throw new System.IO.InvalidDataException(string.Format("Unknown column type: {0}.", c.ColumnType)); + } + + switch (c.Type) + { + case "string" : + case "byte[]" : c.IsClass = true; break; + } + + if (c.IsNullable && !c.IsClass) + c.Type += "?"; + + columns.Add(col); + } + } + + // Load PKs. + // + cmd.CommandText = string.Format(@" + SELECT + CONCAT(k.TABLE_SCHEMA, '.', k.TABLE_NAME) as id, + k.CONSTRAINT_NAME as name, + k.COLUMN_NAME as colname, + k.ORDINAL_POSITION as colid + FROM + INFORMATION_SCHEMA.KEY_COLUMN_USAGE k + JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS c ON k.CONSTRAINT_NAME = c.CONSTRAINT_NAME + WHERE + c.CONSTRAINT_TYPE='PRIMARY KEY' AND + k.TABLE_SCHEMA NOT IN ({0}) + {1} + GROUP BY id, colid", + schemasToSkip, + GetDatabaseSqlFilter("k")); + + using (var rd = cmd.ExecuteReader()) + { + while (rd.Read()) + { + var id = Convert.ToString(rd["id"]); + var colid = Convert.ToInt32 (rd["colid"]); + var colname = Convert.ToString(rd["colname"]); + + columns.Single(_ => _.ID == id && _.Column.ColumnName == colname).Column.PKIndex = colid; + } + } + + // Load FKs. + // + cmd.CommandText = string.Format(@" + SELECT + CONSTRAINT_NAME as Name, + CONCAT(TABLE_SCHEMA, '.', TABLE_NAME) as ThisTable, + COLUMN_NAME as ThisColumn, + CONCAT(REFERENCED_TABLE_SCHEMA, '.', REFERENCED_TABLE_NAME) as OtherTable, + REFERENCED_COLUMN_NAME as OtherColumn, + ORDINAL_POSITION as Ordinal + FROM + INFORMATION_SCHEMA.key_column_usage + WHERE + TABLE_SCHEMA NOT IN ({0}) AND + REFERENCED_TABLE_NAME IS NOT NULL AND + REFERENCED_COLUMN_NAME IS NOT NULL + {1} + ORDER BY + ThisTable, + Ordinal", + schemasToSkip, + GetDatabaseSqlFilter("")); + + if(!string.IsNullOrEmpty(DatabaseName)) + cmd.CommandText += string.Format(" AND TABLE_SCHEMA = '{0}' ", DatabaseName); + + using (var rd = cmd.ExecuteReader()) + { + while (rd.Read()) + { + var name = Convert.ToString(rd["Name"]); + var thisTableID = Convert.ToString(rd["ThisTable"]); + var otherTableID = Convert.ToString(rd["OtherTable"]); + var thisColumnName = Convert.ToString(rd["ThisColumn"]); + var otherColumnName = Convert.ToString(rd["OtherColumn"]); + + var thisTable = (from t in tables where t.ID == thisTableID select t.Table).Single(); + var otherTable = (from t in tables where t.ID == otherTableID select t.Table).Single(); + var thisColumn = (from c in columns where c.ID == thisTableID && c.Column.ColumnName == thisColumnName select c.Column).Single(); + var otherColumn = (from c in columns where c.ID == otherTableID && c.Column.ColumnName == otherColumnName select c.Column).Single(); + + if (thisTable.ForeignKeys.ContainsKey(name) == false) + thisTable.ForeignKeys.Add(name, new ForeignKey { KeyName = name, MemberName = name, OtherTable = otherTable }); + + var key = thisTable.ForeignKeys[name]; + + key.ThisColumns. Add(thisColumn); + key.OtherColumns.Add(otherColumn); + } + } + } + + var qc = + from c in columns + group c by c.ID into gr + join t in tables on gr.Key equals t.ID + select new { t.Table, gr }; + + foreach (var c in qc) + { + foreach (var col in from col in c.gr orderby col.Column.ID select col.Column) + c.Table.Columns.Add(col.ColumnName, col); + + // there is no concept of table owner in MySql so we just use table name + Tables.Add(c.Table.TableName, c.Table); + } +} + +private string _databaseName; +private string GetDatabaseSqlFilter(string optionalTablePrefix) +{ + if(string.IsNullOrEmpty(_databaseName)) return ""; + string tablePrefix = string.IsNullOrEmpty(optionalTablePrefix) ? "" : optionalTablePrefix + "."; + return string.Format(" AND {0}TABLE_SCHEMA = '{1}' ", tablePrefix, _databaseName); +} + +public partial class Column +{ + public string ColumnDefault; + public string Extra; +} + +#> \ No newline at end of file