1 #region MIT license 2 // 3 // MIT license 4 // 5 // Copyright (c) 2007-2008 Jiri Moudry, Pascal Craponne 6 // 7 // Permission is hereby granted, free of charge, to any person obtaining a copy 8 // of this software and associated documentation files (the "Software"), to deal 9 // in the Software without restriction, including without limitation the rights 10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 // copies of the Software, and to permit persons to whom the Software is 12 // furnished to do so, subject to the following conditions: 13 // 14 // The above copyright notice and this permission notice shall be included in 15 // all copies or substantial portions of the Software. 16 // 17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 // THE SOFTWARE. 24 // 25 #endregion 26 27 using System; 28 using System.Collections.Generic; 29 using System.Data; 30 using System.Linq; 31 using DbLinq.Schema; 32 using DbLinq.Schema.Dbml; 33 using DbLinq.Util; 34 using DbLinq.Vendor; 35 using DbLinq.Vendor.Implementation; 36 37 namespace DbLinq.MySql 38 { 39 partial class MySqlSchemaLoader : SchemaLoader 40 { 41 private readonly IVendor vendor = new MySqlVendor(); 42 public override IVendor Vendor { get { return vendor; } set { } } 43 CreateTableName(string dbTableName, string dbSchema, INameAliases nameAliases, NameFormat nameFormat)44 protected override TableName CreateTableName(string dbTableName, string dbSchema, INameAliases nameAliases, NameFormat nameFormat) 45 { 46 return CreateTableName(dbTableName, dbSchema, nameAliases, nameFormat, WordsExtraction.FromDictionary); 47 } 48 LoadStoredProcedures(Database schema, SchemaName schemaName, IDbConnection conn, NameFormat nameFormat)49 protected override void LoadStoredProcedures(Database schema, SchemaName schemaName, IDbConnection conn, NameFormat nameFormat) 50 { 51 var procs = ReadProcedures(conn, schemaName.DbName); 52 53 foreach (DataStoredProcedure proc in procs) 54 { 55 var procedureName = CreateProcedureName(proc.specific_name, proc.db, nameFormat); 56 57 var func = new Function(); 58 func.Name = procedureName.DbName; 59 func.Method = procedureName.MethodName; 60 func.IsComposable = string.Compare(proc.type, "FUNCTION") == 0; 61 func.BodyContainsSelectStatement = proc.body != null 62 && proc.body.IndexOf("select", StringComparison.OrdinalIgnoreCase) > -1; 63 ParseProcParams(proc, func); 64 65 schema.Functions.Add(func); 66 } 67 } 68 LoadConstraints(Database schema, SchemaName schemaName, IDbConnection conn, NameFormat nameFormat, Names names)69 protected override void LoadConstraints(Database schema, SchemaName schemaName, IDbConnection conn, NameFormat nameFormat, Names names) 70 { 71 var constraints = ReadConstraints(conn, schemaName.DbName); 72 73 //sort tables - parents first (this is moving to SchemaPostprocess) 74 //TableSorter.Sort(tables, constraints); 75 76 foreach (DataConstraint keyColRow in constraints) 77 { 78 //find my table: 79 string fullKeyDbName = GetFullDbName(keyColRow.TableName, keyColRow.TableSchema); 80 DbLinq.Schema.Dbml.Table table = schema.Tables.FirstOrDefault(t => fullKeyDbName == t.Name); 81 if (table == null) 82 { 83 bool ignoreCase = true; 84 table = schema.Tables.FirstOrDefault(t => 0 == string.Compare(fullKeyDbName, t.Name, ignoreCase)); 85 if (table == null) 86 { 87 WriteErrorLine("ERROR L46: Table '" + keyColRow.TableName + "' not found for column " + keyColRow.ColumnName); 88 continue; 89 } 90 } 91 92 bool isForeignKey = keyColRow.ConstraintName != "PRIMARY" 93 && keyColRow.ReferencedTableName != null; 94 95 if (isForeignKey) 96 { 97 LoadForeignKey(schema, table, keyColRow.ColumnName, keyColRow.TableName, keyColRow.TableSchema, 98 keyColRow.ReferencedColumnName, keyColRow.ReferencedTableName, keyColRow.ReferencedTableSchema, 99 keyColRow.ConstraintName, nameFormat, names); 100 } 101 102 } 103 } 104 ParseProcParams(DataStoredProcedure inputData, Function outputFunc)105 protected void ParseProcParams(DataStoredProcedure inputData, Function outputFunc) 106 { 107 string paramString = inputData.param_list; 108 if (string.IsNullOrEmpty(paramString)) 109 { 110 //nothing to parse 111 } 112 else 113 { 114 string[] parts = paramString.Split(','); 115 116 foreach (string part in parts) //part='OUT param1 int' 117 { 118 DbLinq.Schema.Dbml.Parameter paramObj = ParseParameterString(part); 119 if (paramObj != null) 120 outputFunc.Parameters.Add(paramObj); 121 } 122 } 123 124 if (!string.IsNullOrEmpty(inputData.returns)) 125 { 126 var paramRet = new Return(); 127 paramRet.DbType = inputData.returns; 128 paramRet.Type = ParseDbType(null, inputData.returns); 129 outputFunc.Return = paramRet; 130 } 131 } 132 133 /// <summary> 134 /// parse strings such as 'INOUT param2 INT' or 'param4 varchar ( 32 )' 135 /// </summary> 136 /// <param name="paramStr"></param> 137 /// <returns></returns> ParseParameterString(string param)138 protected DbLinq.Schema.Dbml.Parameter ParseParameterString(string param) 139 { 140 param = param.Trim(); 141 var inOut = DbLinq.Schema.Dbml.ParameterDirection.In; 142 143 if (param.StartsWith("IN", StringComparison.CurrentCultureIgnoreCase)) 144 { 145 inOut = DbLinq.Schema.Dbml.ParameterDirection.In; 146 param = param.Substring(2).Trim(); 147 } 148 if (param.StartsWith("INOUT", StringComparison.CurrentCultureIgnoreCase)) 149 { 150 inOut = DbLinq.Schema.Dbml.ParameterDirection.InOut; 151 param = param.Substring(5).Trim(); 152 } 153 if (param.StartsWith("OUT", StringComparison.CurrentCultureIgnoreCase)) 154 { 155 inOut = DbLinq.Schema.Dbml.ParameterDirection.Out; 156 param = param.Substring(3).Trim(); 157 } 158 159 int indxSpace = param.IndexOfAny(new char[] { ' ', '\t' }); 160 if (indxSpace == -1) 161 return null; //cannot find space between varName and varType 162 163 string varName = param.Substring(0, indxSpace); 164 string varType = param.Substring(indxSpace + 1); 165 166 var paramObj = new Parameter(); 167 paramObj.Direction = inOut; 168 paramObj.Name = varName; 169 paramObj.DbType = varType; 170 paramObj.Type = ParseDbType(varName, varType); 171 172 return paramObj; 173 } 174 175 static System.Text.RegularExpressions.Regex re_CHARSET = new System.Text.RegularExpressions.Regex(@" CHARSET \w+$"); 176 /// <summary> 177 /// given 'CHAR(30)', return 'string' 178 /// </summary> ParseDbType(string columnName, string dbType1)179 protected string ParseDbType(string columnName, string dbType1) 180 { 181 //strip 'CHARSET latin1' from the end 182 string dbType2 = re_CHARSET.Replace(dbType1, ""); 183 var dataType = new DataType(); 184 dataType.UnpackRawDbType(dbType2); 185 return MapDbType(columnName, dataType).ToString(); 186 } 187 } 188 } 189