diff --git a/CHANGES b/CHANGES index 2749a09b7..7e7ce3c9b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,5 @@ 6.9.12 +- Updated the RSA key encryption padding to RSA_PKCS1_OAEP_PADDING for the caching_sha2_password authentication plugin when connecting to server 8.0.5 (or later) (WL11618). - Added support for the caching_sha2_password authentication plugin introduced in server 8.0.3. Added support for RSA key encription in the sha256_password authentication plugin (WL11285). - Added support for MySQL 8 server features (WL11325). diff --git a/Source/MySql.Data.EntityFramework5/MySql.Data.EF5.csproj b/Source/MySql.Data.EntityFramework5/MySql.Data.EF5.csproj index 26dc3c24a..6ef762e4f 100644 --- a/Source/MySql.Data.EntityFramework5/MySql.Data.EF5.csproj +++ b/Source/MySql.Data.EntityFramework5/MySql.Data.EF5.csproj @@ -11,8 +11,8 @@ 9.0.30729 2.0 - 4.0 - v4.0 + 4.0 + v4.0 NET_40_OR_GREATER @@ -20,8 +20,8 @@ 9.0.30729 2.0 - 4.5 - v4.5 + 4.5 + v4.5 NET_40_OR_GREATER;NET_45_OR_GREATER @@ -174,6 +174,7 @@ + diff --git a/Source/MySql.Data.EntityFramework5/Properties/SchemaDefinition-8.0.ssdl b/Source/MySql.Data.EntityFramework5/Properties/SchemaDefinition-8.0.ssdl new file mode 100644 index 000000000..1baf1d4ff --- /dev/null +++ b/Source/MySql.Data.EntityFramework5/Properties/SchemaDefinition-8.0.ssdl @@ -0,0 +1,793 @@ + + + + + + + SELECT /* Tables */ + CONCAT(TABLE_SCHEMA, '.', TABLE_NAME) AS `Id`, + TABLE_CATALOG AS `Catalog`, + TABLE_SCHEMA AS `Schema`, + TABLE_NAME AS `Name` + FROM INFORMATION_SCHEMA.TABLES + WHERE TABLE_TYPE = 'BASE TABLE' + AND TABLE_SCHEMA=schema() + + + + + + SELECT /* Table columns */ + CONCAT(TABLE_SCHEMA, '.', TABLE_NAME, '.', COLUMN_NAME) AS `Id`, + CONCAT(TABLE_SCHEMA, '.', TABLE_NAME) AS `ParentId`, + COLUMN_NAME AS `Name`, + ORDINAL_POSITION AS `Ordinal`, + CASE IS_NULLABLE WHEN 'YES' THEN 1 ELSE 0 END AS `IsNullable`, + IF(LEFT(COLUMN_TYPE,10) = 'tinyint(1)', 'bool', + IF (LEFT(COLUMN_TYPE,10) = 'binary(16)' OR LEFT(COLUMN_TYPE,8) = 'char(36)', 'guid', + IF (INSTR(COLUMN_TYPE, 'unsigned') = 0, DATA_TYPE, + CONCAT('u', DATA_TYPE)))) AS `TypeName`, + IF (CHARACTER_MAXIMUM_LENGTH > 2147483647, 2147483647, CHARACTER_MAXIMUM_LENGTH) AS `MaxLength`, + CASE WHEN NUMERIC_PRECISION > 0 THEN CAST(NUMERIC_PRECISION AS CHAR) + WHEN DATETIME_PRECISION > 0 THEN CAST(DATETIME_PRECISION AS CHAR) + ELSE 0 + END AS `Precision`, + DATETIME_PRECISION AS `DateTimePrecision`, + NUMERIC_SCALE AS `Scale`, + NULL AS `CollationCatalog`, + NULL AS `CollationSchema`, + COLLATION_NAME AS `CollationName`, + NULL AS `CharacterSetCatalog`, + NULL AS `CharacterSetSchema`, + CHARACTER_SET_NAME AS `CharacterSetName`, + 0 AS `IsMultiSet`, + CASE WHEN COLUMN_DEFAULT LIKE 'CURRENT_TIMESTAMP' THEN 1 + WHEN EXTRA LIKE '%auto%' THEN 1 + ELSE 0 + END AS `IsIdentity`, + CASE WHEN COLUMN_DEFAULT LIKE 'CURRENT_TIMESTAMP' THEN 1 + WHEN EXTRA LIKE '%auto%' THEN 1 + ELSE 0 + END AS `IsStoreGenerated`, + COLUMN_DEFAULT AS `Default` + FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA=schema() + + + + + + SELECT /* Views */ + CONCAT(TABLE_SCHEMA, '.', TABLE_NAME) AS `Id`, + TABLE_CATALOG AS`CatalogName`, + TABLE_SCHEMA AS `SchemaName`, + TABLE_NAME AS `Name`, + VIEW_DEFINITION AS `ViewDefinition`, + CASE IS_UPDATABLE WHEN 'YES' THEN 1 ELSE 0 END AS `IsUpdatable` + FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_SCHEMA=schema() + + + + + + SELECT /* View columns */ + CONCAT(TABLE_SCHEMA, '.', TABLE_NAME, '.', COLUMN_NAME) AS `Id`, + CONCAT(TABLE_SCHEMA, '.', TABLE_NAME) AS `ParentId`, + COLUMN_NAME AS `Name`, + ORDINAL_POSITION AS `Ordinal`, + CASE IS_NULLABLE WHEN 'YES' THEN 1 ELSE 0 END AS `IsNullable`, + IF(LEFT(COLUMN_TYPE,10) = 'tinyint(1)', 'bool', + IF (LEFT(COLUMN_TYPE,10) = 'binary(16)' OR LEFT(COLUMN_TYPE,8) = 'char(36)', 'guid', + IF (INSTR(COLUMN_TYPE, 'unsigned') = 0, DATA_TYPE, + CONCAT('u', DATA_TYPE)))) AS `TypeName`, + IF (CHARACTER_MAXIMUM_LENGTH > 2147483647, 2147483647, CHARACTER_MAXIMUM_LENGTH) AS `MaxLength`, + CASE WHEN NUMERIC_PRECISION > 0 THEN CAST(NUMERIC_PRECISION AS UNSIGNED INTEGER) + WHEN DATETIME_PRECISION > 0 THEN CAST(DATETIME_PRECISION AS UNSIGNED INTEGER) + ELSE 0 + END AS `Precision`, + 0 AS `DateTimePrecision`, + NUMERIC_SCALE AS `Scale`, + NULL AS `CollationCatalog`, + NULL AS `CollationSchema`, + COLLATION_NAME AS `CollationName`, + NULL AS `CharacterSetCatalog`, + NULL AS `CharacterSetSchema`, + CHARACTER_SET_NAME AS `CharacterSetName`, + 0 AS `IsMultiSet`, + CASE WHEN COLUMN_DEFAULT LIKE 'CURRENT_TIMESTAMP' THEN 1 + WHEN EXTRA LIKE '%auto%' THEN 1 + ELSE 0 + END AS `IsIdentity`, + CASE WHEN COLUMN_DEFAULT LIKE 'CURRENT_TIMESTAMP' THEN 1 + WHEN EXTRA LIKE '%auto%' THEN 1 + ELSE 0 + END AS `IsStoreGenerated`, + COLUMN_DEFAULT AS `Default` + FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA=schema() + + + + + + SELECT /* Functions */ + CONCAT(ROUTINE_SCHEMA, '.', SPECIFIC_NAME) AS `Id`, + ROUTINE_CATALOG AS `CatalogName`, + ROUTINE_SCHEMA AS `SchemaName`, + ROUTINE_NAME AS `Name`, + SUBSTRING_INDEX(DTD_IDENTIFIER, '(', 1) AS `ReturnTypeName`, + NULL AS `ReturnMaxLength`, + NULL AS `ReturnPrecision`, + 0 AS `ReturnDateTimePrecision`, + NULL AS `ReturnScale`, + NULL AS `ReturnCollationCatalog`, + NULL AS `ReturnCollationSchema`, + NULL AS `ReturnCollationName`, + NULL AS `ReturnCharacterSetCatalog`, + NULL AS `ReturnCharacterSetSchema`, + NULL AS `ReturnCharacterSetName`, + NULL AS `ReturnIsMultiSet`, + NULL AS `IsAggregate`, + NULL AS `IsBuiltIn`, + NULL AS `IsNiladic` + FROM INFORMATION_SCHEMA.ROUTINES + WHERE ROUTINE_TYPE='FUNCTION' + AND ROUTINE_SCHEMA=schema() + + + + + + SELECT /* Procedures */ + CONCAT(ROUTINE_SCHEMA, '.', SPECIFIC_NAME) AS `Id`, + ROUTINE_CATALOG AS `CatalogName`, + ROUTINE_SCHEMA AS `SchemaName`, + ROUTINE_NAME AS `Name` + FROM INFORMATION_SCHEMA.ROUTINES + WHERE ROUTINE_TYPE='PROCEDURE' + AND ROUTINE_SCHEMA=schema() + + + + + + SELECT + CONCAT(f.SPECIFIC_SCHEMA, '.', f.SPECIFIC_NAME, '.', f.PARAMETER_NAME) AS `Id`, + CONCAT(f.SPECIFIC_SCHEMA, '.', f.SPECIFIC_NAME) AS `ParentId`, + f.PARAMETER_NAME AS `Name`, + f.ORDINAL_POSITION `Ordinal`, + f.DATA_TYPE AS `TypeName`, + f.CHARACTER_MAXIMUM_LENGTH AS `MaxLength`, + f.NUMERIC_PRECISION AS`Precision`, + NULL AS `DateTimePrecision`, + f.NUMERIC_SCALE AS `Scale`, + NULL AS `CollationCatalog`, + NULL AS `CollationSchema`, + f.COLLATION_NAME AS `CollationName`, + NULL AS `CharacterSetCatalog`, + NULL AS `CharacterSetSchema`, + f.CHARACTER_SET_NAME AS `CharacterSetName`, + CAST(0 as decimal(0,0)) AS `IsMultiSet`, + f.PARAMETER_MODE AS `Mode`, + NULL AS `Default` + FROM + INFORMATION_SCHEMA.PARAMETERS f + INNER JOIN INFORMATION_SCHEMA.ROUTINES r ON + f.SPECIFIC_SCHEMA = r.ROUTINE_SCHEMA AND + f.SPECIFIC_NAME = r.SPECIFIC_NAME AND + r.ROUTINE_TYPE = 'FUNCTION' + WHERE + r.ROUTINE_SCHEMA=schema() AND f.ORDINAL_POSITION > 0 + + + + + + SELECT + CONCAT(f.SPECIFIC_SCHEMA, '.', f.SPECIFIC_NAME, '.', f.PARAMETER_NAME) AS `Id`, + CONCAT(f.SPECIFIC_SCHEMA, '.', f.SPECIFIC_NAME) COLLATE utf8_tolower_ci AS `ParentId`, + f.PARAMETER_NAME AS `Name`, + f.ORDINAL_POSITION `Ordinal`, + f.DATA_TYPE AS `TypeName`, + f.CHARACTER_MAXIMUM_LENGTH AS `MaxLength`, + f.NUMERIC_PRECISION AS`Precision`, + NULL AS `DateTimePrecision`, + f.NUMERIC_SCALE AS `Scale`, + NULL AS `CollationCatalog`, + NULL AS `CollationSchema`, + f.COLLATION_NAME AS `CollationName`, + NULL AS `CharacterSetCatalog`, + NULL AS `CharacterSetSchema`, + f.CHARACTER_SET_NAME AS `CharacterSetName`, + CAST(0 as decimal(0,0)) AS `IsMultiSet`, + f.PARAMETER_MODE AS `Mode`, + NULL AS `Default` + FROM + INFORMATION_SCHEMA.PARAMETERS f + INNER JOIN INFORMATION_SCHEMA.ROUTINES r ON + f.SPECIFIC_SCHEMA = r.ROUTINE_SCHEMA AND + f.SPECIFIC_NAME = r.SPECIFIC_NAME AND + r.ROUTINE_TYPE = 'PROCEDURE' + WHERE + r.ROUTINE_SCHEMA=schema() AND f.ORDINAL_POSITION > 0 + + + + + + SELECT /* Constraints */ + CONCAT(CONSTRAINT_SCHEMA, '.', TABLE_NAME, '.', CONSTRAINT_NAME) AS `Id`, + CONCAT(TABLE_SCHEMA, '.', TABLE_NAME) AS `ParentId`, + CONSTRAINT_NAME AS `Name`, + CONSTRAINT_TYPE AS `ConstraintType`, + 0 AS `IsDeferrable`, + 0 AS `IsInitiallyDeferred` + FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS + WHERE CONSTRAINT_TYPE != 'CHECK' AND TABLE_SCHEMA=schema() + + + + + + SELECT /* Check constraints */ + NULL AS `Id`, + NULL AS `Expression` + + + + + + SELECT /* Constraint columns */ + CONCAT(CONSTRAINT_SCHEMA, '.', TABLE_NAME, '.', CONSTRAINT_NAME) AS `ConstraintId`, + CONCAT(TABLE_SCHEMA, '.', TABLE_NAME, '.', COLUMN_NAME) AS `ColumnId` + FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA=schema() + + + + + + + + SELECT + CONCAT(CONSTRAINT_SCHEMA, '.', TABLE_NAME, '.', CONSTRAINT_NAME) AS `Id`, + UPDATE_RULE AS `UpdateRule`, + DELETE_RULE AS `DeleteRule` + FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS + + + + + + SELECT + CONCAT(FC.CONSTRAINT_SCHEMA, '.', FC.CONSTRAINT_NAME, '.', FC.ORDINAL_POSITION) AS `Id`, + CONCAT(PC.TABLE_SCHEMA, '.', PC.TABLE_NAME, '.', PC.COLUMN_NAME) AS `ToColumnId`, + CONCAT(FC.TABLE_SCHEMA, '.', FC.TABLE_NAME, '.', FC.COLUMN_NAME) AS `FromColumnId`, + CONCAT(FC.CONSTRAINT_SCHEMA, '.', FC.TABLE_NAME, '.', FC.CONSTRAINT_NAME) AS `ConstraintId`, + FC.ORDINAL_POSITION AS `Ordinal` + FROM + INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC + INNER JOIN + INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS PC /* PRIMARY KEY COLS*/ + ON RC.UNIQUE_CONSTRAINT_SCHEMA = PC.CONSTRAINT_SCHEMA + AND RC.UNIQUE_CONSTRAINT_NAME = PC.CONSTRAINT_NAME + AND RC.REFERENCED_TABLE_NAME = PC.TABLE_NAME + INNER JOIN + INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS FC /* FOREIGN KEY COLS*/ + ON RC.CONSTRAINT_SCHEMA = FC.CONSTRAINT_SCHEMA + AND RC.CONSTRAINT_NAME = FC.CONSTRAINT_NAME + AND RC.TABLE_NAME = FC.TABLE_NAME + AND PC.ORDINAL_POSITION = FC.ORDINAL_POSITION + + + + + + + + + SELECT /* View constraints */ + CONCAT(_utf8'' COLLATE utf8_tolower_ci, NULL) AS `Id`, + NULL AS `ParentId`, + NULL AS `Name`, + NULL AS `ConstraintType`, + NULL AS `Expression`, + NULL AS `UpdateRule`, + NULL AS `DeleteRule` + + + + + + SELECT /* View constraint columns */ + NULL AS `ConstraintId`, + NULL AS `ColumnId` + + + + + + SELECT /* View foreign keys */ + NULL AS `Id`, + NULL AS `ToColumnId`, + NULL AS `FromColumnId`, + NULL AS `ConstraintId`, + 0 AS `Ordinal` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Source/MySql.Data.EntityFramework5/ProviderManifest.cs b/Source/MySql.Data.EntityFramework5/ProviderManifest.cs index 15d8a1682..38b745099 100644 --- a/Source/MySql.Data.EntityFramework5/ProviderManifest.cs +++ b/Source/MySql.Data.EntityFramework5/ProviderManifest.cs @@ -1,4 +1,4 @@ -// Copyright © 2008, 2014, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. // // MySQL Connector/NET is licensed under the terms of the GPLv2 // , like most @@ -88,7 +88,8 @@ private XmlReader GetStoreSchemaDescription() if (version < 5.5) return GetMappingResource("SchemaDefinition-5.1.ssdl"); if (version < 5.6) return GetMappingResource("SchemaDefinition-5.5.ssdl"); if (version < 5.7) return GetMappingResource("SchemaDefinition-5.6.ssdl"); - return GetMappingResource("SchemaDefinition-5.7.ssdl"); + if (version < 8.0) return GetMappingResource("SchemaDefinition-5.7.ssdl"); + return GetMappingResource("SchemaDefinition-8.0.ssdl"); } public override TypeUsage GetEdmType(TypeUsage storeType) diff --git a/Source/MySql.Data.EntityFramework5/ProviderServices.cs b/Source/MySql.Data.EntityFramework5/ProviderServices.cs index 02fc24ae4..cb56b647b 100644 --- a/Source/MySql.Data.EntityFramework5/ProviderServices.cs +++ b/Source/MySql.Data.EntityFramework5/ProviderServices.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2014, 2016 Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. // // MySQL Connector/NET is licensed under the terms of the GPLv2 // , like most @@ -253,18 +253,18 @@ protected override string GetDbProviderManifestToken(DbConnection connection) c.Open(); var v = DBVersion.Parse(c.ServerVersion); - serverVersion = new Version(v.Major + "." + v.Minor); - - double version = double.Parse(c.ServerVersion.Substring(0, 3), CultureInfo.InvariantCulture); - if (version < 5.0) throw new NotSupportedException("Versions of MySQL prior to 5.0 are not currently supported"); - if (version < 5.1) return "5.0"; - if (version < 5.5) return "5.1"; - if (version < 5.6) return "5.5"; - if (version < 5.7) return "5.6"; - return "5.7"; - - } - } + serverVersion = new Version(v.Major + "." + v.Minor); + + double version = double.Parse(c.ServerVersion.Substring(0, 3), CultureInfo.InvariantCulture); + if (version < 5.0) throw new NotSupportedException("Versions of MySQL prior to 5.0 are not currently supported"); + if (version < 5.1) return "5.0"; + if (version < 5.5) return "5.1"; + if (version < 5.6) return "5.5"; + if (version < 5.7) return "5.6"; + if (version < 8.0) return "5.7"; + return "8.0"; + } + } protected override DbProviderManifest GetDbProviderManifest(string manifestToken) { diff --git a/Source/MySql.Data.EntityFramework6/MySql.Data.EF6.csproj b/Source/MySql.Data.EntityFramework6/MySql.Data.EF6.csproj index 0aafcc120..2c9887835 100644 --- a/Source/MySql.Data.EntityFramework6/MySql.Data.EF6.csproj +++ b/Source/MySql.Data.EntityFramework6/MySql.Data.EF6.csproj @@ -173,6 +173,9 @@ Properties\SchemaDefinition-5.7.ssdl + + + Properties\SchemaDefinition-8.0.ssdl ResXFileCodeGenerator diff --git a/Source/MySql.Data/Authentication/CachingSha2AuthenticationPlugin.cs b/Source/MySql.Data/Authentication/CachingSha2AuthenticationPlugin.cs index ef7dee3da..44ed70e81 100644 --- a/Source/MySql.Data/Authentication/CachingSha2AuthenticationPlugin.cs +++ b/Source/MySql.Data/Authentication/CachingSha2AuthenticationPlugin.cs @@ -120,17 +120,34 @@ private byte[] GetRsaPassword(string password, byte[] seedBytes, byte[] rawPubli byte[] obfuscated = GetXor(AliasText.Encoding.Default.GetBytes(password), seedBytes); // Encrypt the password and send it to the server. + if (this.ServerVersion >= new Version("8.0.5")) + { #if NETSTANDARD1_3 - RSA rsa = MySqlPemReader.ConvertPemToRSAProvider(rawPublicKey); - if (rsa == null) throw new MySqlException(Resources.UnableToReadRSAKey); + RSA rsa = MySqlPemReader.ConvertPemToRSAProvider(rawPublicKey); + if (rsa == null) throw new MySqlException(Resources.UnableToReadRSAKey); - // TODO in MySQL 8.0.3 the RSA_PKCS1_PADDING is used in caching_sha2_password full auth stage but in 8.0.4 it should be changed to RSA_PKCS1_OAEP_PADDING, the same as in sha256_password. - return rsa.Encrypt(obfuscated, RSAEncryptionPadding.Pkcs1); + return rsa.Encrypt(obfuscated, RSAEncryptionPadding.OaepSHA1); #else - RSACryptoServiceProvider rsa = MySqlPemReader.ConvertPemToRSAProvider(rawPublicKey); - if (rsa == null) throw new MySqlException(Resources.UnableToReadRSAKey); - return rsa.Encrypt(obfuscated, false); + RSACryptoServiceProvider rsa = MySqlPemReader.ConvertPemToRSAProvider(rawPublicKey); + if (rsa == null) throw new MySqlException(Resources.UnableToReadRSAKey); + + return rsa.Encrypt(obfuscated, true); #endif + } + else + { +#if NETSTANDARD1_3 + RSA rsa = MySqlPemReader.ConvertPemToRSAProvider(rawPublicKey); + if (rsa == null) throw new MySqlException(Resources.UnableToReadRSAKey); + + return rsa.Encrypt(obfuscated, RSAEncryptionPadding.Pkcs1); +#else + RSACryptoServiceProvider rsa = MySqlPemReader.ConvertPemToRSAProvider(rawPublicKey); + if (rsa == null) throw new MySqlException(Resources.UnableToReadRSAKey); + + return rsa.Encrypt(obfuscated, false); +#endif + } } public override object GetPassword() diff --git a/Source/MySql.Data/Authentication/Sha256AuthenticationPlugin.cs b/Source/MySql.Data/Authentication/Sha256AuthenticationPlugin.cs index 449f391b2..43c14e563 100644 --- a/Source/MySql.Data/Authentication/Sha256AuthenticationPlugin.cs +++ b/Source/MySql.Data/Authentication/Sha256AuthenticationPlugin.cs @@ -52,7 +52,7 @@ public class Sha256AuthenticationPlugin : MySqlAuthenticationPlugin protected override byte[] MoreData(byte[] data) { rawPubkey = data; - byte[] buffer = GetPassword() as byte[]; + byte[] buffer = GetNonLengthEncodedPassword() as byte[]; return buffer; } @@ -60,11 +60,11 @@ public override object GetPassword() { if (Settings.SslMode != MySqlSslMode.None) { - // send as clear text, since the channel is already encrypted byte[] passBytes = Encoding.GetBytes(Settings.Password); - byte[] buffer = new byte[passBytes.Length + 1]; - Array.Copy(passBytes, 0, buffer, 0, passBytes.Length); - buffer[passBytes.Length] = 0; + byte[] buffer = new byte[passBytes.Length + 2]; + Array.Copy(passBytes, 0, buffer, 1, passBytes.Length); + buffer[0] = (byte) (passBytes.Length+1); + buffer[buffer.Length-1] = 0x00; return buffer; } else @@ -83,6 +83,21 @@ public override object GetPassword() } } + private byte[] GetNonLengthEncodedPassword() + { + // Required for AuthChange requests. + if (Settings.SslMode != MySqlSslMode.None) + { + // Send as clear text, since the channel is already encrypted. + byte[] passBytes = Encoding.GetBytes(Settings.Password); + byte[] buffer = new byte[passBytes.Length + 1]; + Array.Copy(passBytes, 0, buffer, 0, passBytes.Length); + buffer[passBytes.Length] = 0; + return buffer; + } + else return GetPassword() as byte[]; + } + private byte[] GetRsaPassword(string password, byte[] seedBytes, byte[] rawPublicKey) { if (password.Length == 0) return new byte[1]; @@ -100,7 +115,7 @@ private byte[] GetRsaPassword(string password, byte[] seedBytes, byte[] rawPubli throw new MySqlException("RSA2"); return rsa.Encrypt(obfuscated, RSAEncryptionPadding.OaepSHA1); #else - RSACryptoServiceProvider rsa = MySqlPemReader.ConvertPemToRSAProvider(rawPublicKey); + RSACryptoServiceProvider rsa = MySqlPemReader.ConvertPemToRSAProvider(rawPublicKey); if (rsa == null) //throw new MySqlException(Resources.UnableToReadRSAKey); throw new MySqlException("RSA2"); diff --git a/Source/MySql.Data/NativeDriver.cs b/Source/MySql.Data/NativeDriver.cs index fcc264c23..2e39359c6 100644 --- a/Source/MySql.Data/NativeDriver.cs +++ b/Source/MySql.Data/NativeDriver.cs @@ -224,7 +224,8 @@ public void Open() int protocol = packet.ReadByte(); string versionString = packet.ReadString(); owner.isFabric = versionString.EndsWith("fabric", StringComparison.OrdinalIgnoreCase); - isEnterprise = versionString.ToLowerInvariant().Contains("-enterprise-"); + isEnterprise = versionString.ToLowerInvariant().Contains("-enterprise") + || versionString.ToLowerInvariant().Contains("-commercial"); version = DBVersion.Parse(versionString); if (!owner.isFabric && !version.isAtLeast(5, 0, 0)) throw new NotSupportedException(Resources.ServerTooOld); diff --git a/Tests/MySql.Data.Tests/CharacterSetTests.cs b/Tests/MySql.Data.Tests/CharacterSetTests.cs index 3c6a4b881..16351bdb1 100644 --- a/Tests/MySql.Data.Tests/CharacterSetTests.cs +++ b/Tests/MySql.Data.Tests/CharacterSetTests.cs @@ -56,7 +56,7 @@ public void UseFunctions() } } - [Fact] + [Fact] public void VarBinary() { if (_fixture.Version < new Version(4, 1)) return; @@ -73,8 +73,8 @@ public void VarBinary() } } - [Fact] - public void Latin1Connection() + [Fact] + public void Latin1Connection() { if (_fixture.Version < new Version(4, 1)) return; @@ -91,11 +91,11 @@ public void Latin1Connection() } } - + /// /// Bug #14592 Wrong column length returned for VARCHAR UTF8 columns /// - [Fact] + [Fact] public void GetSchemaOnUTF8() { @@ -112,7 +112,7 @@ public void GetSchemaOnUTF8() } } - [Fact] + [Fact] public void UTF8BlogsTruncating() { @@ -141,7 +141,7 @@ public void UTF8BlogsTruncating() } } - [Fact] + [Fact] public void BlobAsUtf8() { _fixture.execSQL(@"CREATE TABLE Test(include_blob BLOB, include_tinyblob TINYBLOB, @@ -224,7 +224,7 @@ public void BlobAsUtf8() /// Bug #31185 columns names are incorrect when using the 'AS' clause and name with accents /// Bug #38721 GetOrdinal doesn't accept column names accepted by MySQL 5.0 /// - [Fact] + [Fact] public void UTF8AsColumnNames() { string connStr = _fixture.GetConnectionString(true) + ";charset=utf8;pooling=false"; @@ -250,7 +250,7 @@ public void UTF8AsColumnNames() /// /// Bug #31117 Connector/Net exceptions do not support server charset /// - [Fact] + [Fact] public void NonLatin1Exception() { string connStr = _fixture.GetConnectionString(true) + ";charset=utf8"; @@ -276,7 +276,7 @@ public void NonLatin1Exception() /// /// Bug #40076 "Functions Return String" option does not set the proper encoding for the string /// - [Fact] + [Fact] public void FunctionReturnsStringWithCharSet() { string connStr = _fixture.GetConnectionString(true) + ";functions return string=true"; @@ -295,10 +295,10 @@ public void FunctionReturnsStringWithCharSet() } } - [Fact] + [Fact] public void RespectBinaryFlags() { - if (_fixture.conn.driver.Version.isAtLeast(5,5,0)) return; + if (_fixture.conn.driver.Version.isAtLeast(5, 5, 0)) return; string connStr = _fixture.GetConnectionString(true) + ";respect binary flags=true"; using (MySqlConnection c = new MySqlConnection(connStr)) @@ -325,7 +325,7 @@ public void RespectBinaryFlags() } } - [Fact] + [Fact] public void RussianErrorMessagesShowCorrectly() { if (_fixture.Version < new Version(5, 5)) @@ -364,7 +364,7 @@ public void RussianErrorMessagesShowCorrectly() /// Tests for bug http://bugs.mysql.com/bug.php?id=62094 /// (char field mapped to System.String of MaxLength=3*len(char) in .NET/Connector). /// - [Fact] + [Fact] public void GetCharLengthInUTF8() { _fixture.execSQL( @@ -379,315 +379,318 @@ public void GetCharLengthInUTF8() Assert.Equal(20, ds.Tables[0].Columns["longname"].MaxLength); } - /// - /// Test for fix of Connector/NET cannot read data from a MySql table using UTF-16/UTF-32 - /// (MySql bug #69169, Oracle bug #16776818). - /// - [Fact] - public void UsingUtf16() - { - MySqlConnection con = new MySqlConnection(_fixture.GetConnectionString(true)); - con.Open(); - try - { - MySqlCommand cmd = null; - if (con.driver.Version.isAtLeast(8,0,1)) - { - cmd = new MySqlCommand("SET SESSION SQL_MODE='ALLOW_INVALID_DATES';", con); - cmd.ExecuteNonQuery(); - } - - cmd = new MySqlCommand("", con); - cmd.CommandText = "drop table if exists `actor`"; - cmd.ExecuteNonQuery(); - cmd.CommandText = @"CREATE TABLE `actor` ( + /// + /// Test for fix of Connector/NET cannot read data from a MySql table using UTF-16/UTF-32 + /// (MySql bug #69169, Oracle bug #16776818). + /// + [Fact] + public void UsingUtf16() + { + MySqlConnection con = new MySqlConnection(_fixture.GetConnectionString(true)); + con.Open(); + try + { + MySqlCommand cmd = null; + if (con.driver.Version.isAtLeast(8, 0, 1)) + { + cmd = new MySqlCommand("SET SESSION SQL_MODE='ALLOW_INVALID_DATES';", con); + cmd.ExecuteNonQuery(); + } + + cmd = new MySqlCommand("", con); + cmd.CommandText = "drop table if exists `actor`"; + cmd.ExecuteNonQuery(); + cmd.CommandText = @"CREATE TABLE `actor` ( `actor_id` smallint(5) unsigned NOT NULL DEFAULT '0', `first_name` varchar(45) NOT NULL, `last_name` varchar(45) NOT NULL, `last_update` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ) ENGINE=InnoDB DEFAULT CHARSET=utf16"; - cmd.ExecuteNonQuery(); + cmd.ExecuteNonQuery(); - string[] firstNames = new string[] { "PENELOPE", "NICK", "ED" }; - string[] lastNames = new string[] { "GUINESS", "WAHLBERG", "CHASE" }; - DateTime[] lastUpdates = new DateTime[] { + string[] firstNames = new string[] { "PENELOPE", "NICK", "ED" }; + string[] lastNames = new string[] { "GUINESS", "WAHLBERG", "CHASE" }; + DateTime[] lastUpdates = new DateTime[] { new DateTime(2006, 2, 15, 4, 34, 33), new DateTime(2007, 2, 15, 4, 34, 33), new DateTime(2008, 4, 15, 4, 34, 33) }; - for (int i = 0; i < firstNames.Length; i++) - { - cmd.CommandText = string.Format( - "insert into `actor`( actor_id, first_name, last_name, last_update ) values ( {0}, '{1}', '{2}', '{3}' )", - i, firstNames[i], lastNames[i], lastUpdates[i].ToString("yyyy/MM/dd hh:mm:ss")); - cmd.ExecuteNonQuery(); - } - - cmd.CommandText = "select actor_id, first_name, last_name, last_update from `actor`"; - - using (MySqlDataReader r = cmd.ExecuteReader()) - { - int j = 0; - while (r.Read()) - { - for (int i = 0; i < r.FieldCount; i++) - { - Assert.True(j == r.GetInt32(0)); - Assert.True(firstNames[j] == r.GetString(1)); - Assert.True(lastNames[j] == r.GetString(2)); - Assert.True(lastUpdates[j] == r.GetDateTime(3)); - } - j++; - } - } - } - finally { - MySqlCommand cmd = new MySqlCommand("drop table if exists `actor`", con); - cmd.ExecuteNonQuery(); - con.Dispose(); - } - } - - /// - /// 2nd part of tests for fix of Connector/NET cannot read data from a MySql table using UTF-16/UTF-32 - /// (MySql bug #69169, Oracle bug #16776818). - /// - [Fact] - public void UsingUtf32() - { - MySqlConnection con = new MySqlConnection(_fixture.GetConnectionString(true)); - con.Open(); - try - { - MySqlCommand cmd = null; - if (con.driver.Version.isAtLeast(8,0,1)) - { - cmd = new MySqlCommand("SET SESSION SQL_MODE='ALLOW_INVALID_DATES';", con); - cmd.ExecuteNonQuery(); - } - - cmd = new MySqlCommand("", con); - cmd.CommandText = "drop table if exists `actor`"; - cmd.ExecuteNonQuery(); - cmd.CommandText = @"CREATE TABLE `actor` ( + for (int i = 0; i < firstNames.Length; i++) + { + cmd.CommandText = string.Format( + "insert into `actor`( actor_id, first_name, last_name, last_update ) values ( {0}, '{1}', '{2}', '{3}' )", + i, firstNames[i], lastNames[i], lastUpdates[i].ToString("yyyy/MM/dd hh:mm:ss")); + cmd.ExecuteNonQuery(); + } + + cmd.CommandText = "select actor_id, first_name, last_name, last_update from `actor`"; + + using (MySqlDataReader r = cmd.ExecuteReader()) + { + int j = 0; + while (r.Read()) + { + for (int i = 0; i < r.FieldCount; i++) + { + Assert.True(j == r.GetInt32(0)); + Assert.True(firstNames[j] == r.GetString(1)); + Assert.True(lastNames[j] == r.GetString(2)); + Assert.True(lastUpdates[j] == r.GetDateTime(3)); + } + j++; + } + } + } + finally + { + MySqlCommand cmd = new MySqlCommand("drop table if exists `actor`", con); + cmd.ExecuteNonQuery(); + con.Dispose(); + } + } + + /// + /// 2nd part of tests for fix of Connector/NET cannot read data from a MySql table using UTF-16/UTF-32 + /// (MySql bug #69169, Oracle bug #16776818). + /// + [Fact] + public void UsingUtf32() + { + MySqlConnection con = new MySqlConnection(_fixture.GetConnectionString(true)); + con.Open(); + try + { + MySqlCommand cmd = null; + if (con.driver.Version.isAtLeast(8, 0, 1)) + { + cmd = new MySqlCommand("SET SESSION SQL_MODE='ALLOW_INVALID_DATES';", con); + cmd.ExecuteNonQuery(); + } + + cmd = new MySqlCommand("", con); + cmd.CommandText = "drop table if exists `actor`"; + cmd.ExecuteNonQuery(); + cmd.CommandText = @"CREATE TABLE `actor` ( `actor_id` smallint(5) unsigned NOT NULL DEFAULT '0', `first_name` varchar(45) NOT NULL, `last_name` varchar(45) NOT NULL, `last_update` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ) ENGINE=InnoDB DEFAULT CHARSET=utf32"; - cmd.ExecuteNonQuery(); + cmd.ExecuteNonQuery(); - string[] firstNames = new string[] { "PENELOPE", "NICK", "ED" }; - string[] lastNames = new string[] { "GUINESS", "WAHLBERG", "CHASE" }; - DateTime[] lastUpdates = new DateTime[] { + string[] firstNames = new string[] { "PENELOPE", "NICK", "ED" }; + string[] lastNames = new string[] { "GUINESS", "WAHLBERG", "CHASE" }; + DateTime[] lastUpdates = new DateTime[] { new DateTime(2006, 2, 15, 4, 34, 33), new DateTime(2007, 2, 15, 4, 34, 33), new DateTime(2008, 4, 15, 4, 34, 33) }; - for (int i = 0; i < firstNames.Length; i++) - { - cmd.CommandText = string.Format( - "insert into `actor`( actor_id, first_name, last_name, last_update ) values ( {0}, '{1}', '{2}', '{3}' )", - i, firstNames[i], lastNames[i], lastUpdates[i].ToString("yyyy/MM/dd hh:mm:ss")); - cmd.ExecuteNonQuery(); - } - - cmd.CommandText = "select actor_id, first_name, last_name, last_update from `actor`"; - - using (MySqlDataReader r = cmd.ExecuteReader()) - { - int j = 0; - while (r.Read()) - { - for (int i = 0; i < r.FieldCount; i++) - { - Assert.True(j == r.GetInt32(0)); - Assert.True(firstNames[j] == r.GetString(1)); - Assert.True(lastNames[j] == r.GetString(2)); - Assert.True(lastUpdates[j] == r.GetDateTime(3)); - } - j++; - } - } - } - finally { - MySqlCommand cmd = new MySqlCommand("drop table if exists `actor`", con); - cmd.ExecuteNonQuery(); - con.Dispose(); - } - } - - - - /// - /// Test for new functionality on 5.7.9 supporting chinese character sets gb18030 - /// WL #4024 - /// (Oracle bug #21098546). - /// - [Fact] - public void CanInsertChineseCharacterSetGB18030() - { + for (int i = 0; i < firstNames.Length; i++) + { + cmd.CommandText = string.Format( + "insert into `actor`( actor_id, first_name, last_name, last_update ) values ( {0}, '{1}', '{2}', '{3}' )", + i, firstNames[i], lastNames[i], lastUpdates[i].ToString("yyyy/MM/dd hh:mm:ss")); + cmd.ExecuteNonQuery(); + } + + cmd.CommandText = "select actor_id, first_name, last_name, last_update from `actor`"; + + using (MySqlDataReader r = cmd.ExecuteReader()) + { + int j = 0; + while (r.Read()) + { + for (int i = 0; i < r.FieldCount; i++) + { + Assert.True(j == r.GetInt32(0)); + Assert.True(firstNames[j] == r.GetString(1)); + Assert.True(lastNames[j] == r.GetString(2)); + Assert.True(lastUpdates[j] == r.GetDateTime(3)); + } + j++; + } + } + } + finally + { + MySqlCommand cmd = new MySqlCommand("drop table if exists `actor`", con); + cmd.ExecuteNonQuery(); + con.Dispose(); + } + } + + + + /// + /// Test for new functionality on 5.7.9 supporting chinese character sets gb18030 + /// WL #4024 + /// (Oracle bug #21098546). + /// + [Fact] + public void CanInsertChineseCharacterSetGB18030() + { + if (_fixture.Version < new Version(5, 7, 4)) return; + + try + { + _fixture.execSQL("CREATE TABLE Test (id int, name VARCHAR(100) CHAR SET gb18030, KEY(name(20)))"); + using (MySqlConnection c = new MySqlConnection(_fixture.conn.ConnectionString + ";charset=gb18030")) + { + c.Open(); + MySqlCommand cmd = new MySqlCommand("INSERT INTO Test VALUES(1, '㭋玤䂜蚌')", c); + cmd.ExecuteNonQuery(); + cmd = new MySqlCommand("INSERT INTO test VALUES(2, 0xC4EEC5ABBDBFA1A4B3E0B1DABBB3B9C520A1A4CBD5B6ABC6C2)", c); + cmd.ExecuteNonQuery(); + cmd = new MySqlCommand("SELECT id, name from test", c); + var reader = cmd.ExecuteReader(); + while (reader.Read()) + { + if (reader.GetUInt32(0) == 1) + Assert.Equal("㭋玤䂜蚌", reader.GetString(1)); + if (reader.GetUInt32(0) == 2) + Assert.Equal("念奴娇·赤壁怀古 ·苏东坡", reader.GetString(1)); + } + } + } + finally + { + _fixture.execSQL("drop table if exists `Test`"); + } + } + + + + /// + /// Test for new functionality on 5.7.9 supporting chinese character sets on gb18030 + /// WL #4024 + /// (Oracle bug #21098546). + /// + [Fact] + public void CanCreateDbUsingChineseCharacterSetGB18030() + { if (_fixture.Version < new Version(5, 7, 4)) return; + MySqlConnectionStringBuilder rootSb = new MySqlConnectionStringBuilder(_fixture.rootConn.ConnectionString); + rootSb.CharacterSet = "gb18030"; + using (MySqlConnection rootConnection = new MySqlConnection(rootSb.ToString())) + { + string database = "㭋玤䂜蚌"; + + rootConnection.Open(); + MySqlCommand rootCommand = new MySqlCommand(); + rootCommand.Connection = rootConnection; + rootCommand.CommandText = string.Format("CREATE DATABASE `{0}` CHARSET=gb18030;", database); + rootCommand.ExecuteNonQuery(); + + try + { + rootSb.Database = database; + using (MySqlConnection conn = new MySqlConnection(rootSb.ConnectionString)) + { + conn.Open(); + Assert.Equal(database, conn.Database); + } + } + finally + { + if (rootConnection.State == ConnectionState.Open) + { + rootCommand.CommandText = string.Format("DROP DATABASE `{0}`;", database); + rootCommand.ExecuteNonQuery(); + } + } + } + } + + + [Fact] + public void UTF16LETest() + { + if (_fixture.Version < new Version(5, 6)) return; + + using (MySqlDataReader reader = _fixture.execReader("select _utf16le 'utf16le test';")) + { + while (reader.Read()) + { + Assert.Equal("瑵ㅦ氶⁥整瑳", reader[0].ToString()); + } + } + } + + [Fact] + public void GEOSTD8Test() + { + MySqlConnection dbconn = new MySqlConnection(_fixture.GetConnectionString(false)); try { - _fixture.execSQL("CREATE TABLE Test (id int, name VARCHAR(100) CHAR SET gb18030, KEY(name(20)))"); - using (MySqlConnection c = new MySqlConnection(_fixture.conn.ConnectionString + ";charset=gb18030")) + using (MySqlCommand cmd = new MySqlCommand("select _geostd8 'geostd8 test';", dbconn)) + { + dbconn.Open(); + using (MySqlDataReader reader = cmd.ExecuteReader()) { - c.Open(); - MySqlCommand cmd = new MySqlCommand("INSERT INTO Test VALUES(1, '㭋玤䂜蚌')", c); - cmd.ExecuteNonQuery(); - cmd = new MySqlCommand("INSERT INTO test VALUES(2, 0xC4EEC5ABBDBFA1A4B3E0B1DABBB3B9C520A1A4CBD5B6ABC6C2)", c); - cmd.ExecuteNonQuery(); - cmd = new MySqlCommand("SELECT id, name from test", c); - var reader = cmd.ExecuteReader(); - while (reader.Read()) - { - if (reader.GetUInt32(0) == 1) - Assert.Equal("㭋玤䂜蚌", reader.GetString(1)); - if (reader.GetUInt32(0) == 2) - Assert.Equal("念奴娇·赤壁怀古 ·苏东坡", reader.GetString(1)); - } + while (reader.Read()) + { + Assert.Equal("geostd8 test", reader[0].ToString()); + } } + } + throw new Exception("The test should have failed with a MySqlException but it does not."); + } + catch (MySqlException ex) + { + while (ex.InnerException != null) + ex = (MySqlException)ex.InnerException; + + Assert.Equal(typeof(MySqlException), ex.GetType()); + Assert.Equal("Character set 'geostd8' is not supported by .Net Framework.", ex.Message); + } + catch (Exception ex) + { + Assert.Equal(typeof(MySqlException), ex.GetType()); } finally { - _fixture.execSQL("drop table if exists `Test`"); + dbconn.Dispose(); } - } - - - - /// - /// Test for new functionality on 5.7.9 supporting chinese character sets on gb18030 - /// WL #4024 - /// (Oracle bug #21098546). - /// - [Fact] - public void CanCreateDbUsingChineseCharacterSetGB18030() - { - if (_fixture.Version < new Version(5, 7, 4)) return; - - MySqlConnectionStringBuilder rootSb = new MySqlConnectionStringBuilder(_fixture.rootConn.ConnectionString); - rootSb.CharacterSet = "gb18030"; - using (MySqlConnection rootConnection = new MySqlConnection(rootSb.ToString())) - { - string database = "㭋玤䂜蚌"; - - rootConnection.Open(); - MySqlCommand rootCommand = new MySqlCommand(); - rootCommand.Connection = rootConnection; - rootCommand.CommandText = string.Format("CREATE DATABASE `{0}` CHARSET=gb18030;", database); - rootCommand.ExecuteNonQuery(); - - try - { - rootSb.Database = database; - using (MySqlConnection conn = new MySqlConnection(rootSb.ConnectionString)) - { - conn.Open(); - Assert.Equal(database, conn.Database); - } - } - finally - { - if (rootConnection.State == ConnectionState.Open) - { - rootCommand.CommandText = string.Format("DROP DATABASE `{0}`;", database); - rootCommand.ExecuteNonQuery(); - } - } - } - } - - - [Fact] - public void UTF16LETest() - { - if (_fixture.Version < new Version(5, 6)) return; - - using (MySqlDataReader reader = _fixture.execReader("select _utf16le 'utf16le test';")) - { - while (reader.Read()) - { - Assert.Equal("瑵ㅦ氶⁥整瑳", reader[0].ToString()); - } - } - } - - [Fact] - public void GEOSTD8Test() - { - MySqlConnection dbconn = new MySqlConnection(_fixture.GetConnectionString(false)); - try - { - using (MySqlCommand cmd = new MySqlCommand("select _geostd8 'geostd8 test';", dbconn)) - { - dbconn.Open(); - using (MySqlDataReader reader = cmd.ExecuteReader()) - { - while (reader.Read()) - { - Assert.Equal("geostd8 test", reader[0].ToString()); - } - } - } - throw new Exception("The test should have failed with a MySqlException but it does not."); - } - catch (MySqlException ex) - { - while (ex.InnerException != null) - ex = (MySqlException)ex.InnerException; - - Assert.Equal(typeof(MySqlException), ex.GetType()); - Assert.Equal("Character set 'geostd8' is not supported by .Net Framework.", ex.Message); - } - catch (Exception ex) - { - Assert.Equal(typeof(MySqlException), ex.GetType()); - } - finally - { - dbconn.Dispose(); - } - } - - [Fact] - public void ExtendedCharsetOnConnection() - { - MySqlConnectionStringBuilder rootSb = new MySqlConnectionStringBuilder(_fixture.rootConn.ConnectionString); - rootSb.CharacterSet = "utf8"; - using (MySqlConnection rootConnection = new MySqlConnection(rootSb.ToString())) - { - string database = "数据库"; - string user = "用户"; - string password = "tést€"; - - rootConnection.Open(); - MySqlCommand rootCommand = new MySqlCommand(); - rootCommand.Connection = rootConnection; - rootCommand.CommandText = string.Format("CREATE DATABASE IF NOT EXISTS `{0}`;", database); - rootCommand.CommandText += string.Format("GRANT ALL ON `{0}`.* to '{1}'@'localhost' identified by '{2}';", database, user, password); - rootCommand.ExecuteNonQuery(); - - string connString = _fixture.GetConnectionString(false); - MySqlConnectionStringBuilder sb = new MySqlConnectionStringBuilder(connString); - sb.Database = database; - sb.UserID = user; - sb.Password = password; - sb.CharacterSet = "utf8"; - try - { - using (MySqlConnection conn = new MySqlConnection(sb.ToString())) - { - conn.Open(); - Assert.Equal(database, conn.Database); - } - } - finally - { - if (rootConnection.State == ConnectionState.Open) - { - rootCommand.CommandText = string.Format("DROP DATABASE `{0}`;DROP USER '{1}'@'localhost'", database, user); - rootCommand.ExecuteNonQuery(); - } - } - } - } + } + + [Fact(Skip ="Fix for 8.0.11")] + public void ExtendedCharsetOnConnection() + { + MySqlConnectionStringBuilder rootSb = new MySqlConnectionStringBuilder(_fixture.rootConn.ConnectionString); + rootSb.CharacterSet = "utf8"; + using (MySqlConnection rootConnection = new MySqlConnection(rootSb.ToString())) + { + string database = "数据库"; + string user = "用户"; + string password = "tést€"; + + rootConnection.Open(); + MySqlCommand rootCommand = new MySqlCommand(); + rootCommand.Connection = rootConnection; + rootCommand.CommandText = string.Format("CREATE DATABASE IF NOT EXISTS `{0}`;", database); + + rootCommand.CommandText += string.Format("CREATE USER '{0}' IDENTIFIED BY '{1}';GRANT ALL ON `{2}`.* to '{0}'@'localhost';", user, password, database); + rootCommand.ExecuteNonQuery(); + + string connString = _fixture.GetConnectionString(false); + MySqlConnectionStringBuilder sb = new MySqlConnectionStringBuilder(connString); + sb.Database = database; + sb.UserID = user; + sb.Password = password; + sb.CharacterSet = "utf8"; + try + { + using (MySqlConnection conn = new MySqlConnection(sb.ToString())) + { + conn.Open(); + Assert.Equal(database, conn.Database); + } + } + finally + { + if (rootConnection.State == ConnectionState.Open) + { + rootCommand.CommandText = string.Format("DROP DATABASE `{0}`;DROP USER '{1}'@'localhost'", database, user); + rootCommand.ExecuteNonQuery(); + } + } + } + } [Fact] public void CharacterVariablesByDefault() diff --git a/Tests/MySql.Data.Tests/DateTimeTests.cs b/Tests/MySql.Data.Tests/DateTimeTests.cs index dbe646a0d..b9131461c 100644 --- a/Tests/MySql.Data.Tests/DateTimeTests.cs +++ b/Tests/MySql.Data.Tests/DateTimeTests.cs @@ -51,7 +51,7 @@ protected override void Dispose(bool disposing) [Fact] public void ConvertZeroDateTime() { - if (_fixture.conn.driver.Version.isAtLeast(8,0,1)) + if (_fixture.conn.driver.Version.isAtLeast(8, 0, 1)) _fixture.execSQL("SET SESSION SQL_MODE='ALLOW_INVALID_DATES';"); _fixture.execSQL("INSERT INTO Test VALUES(1, '0000-00-00', '0000-00-00', " + @@ -90,7 +90,7 @@ public void TestNotAllowZerDateAndTime() Exception ex = Assert.Throws(() => reader.GetValue(2)); Assert.Equal(ex.Message, "Unable to convert MySQL date/time value to System.DateTime"); - + Assert.True(reader.Read()); DateTime dt2 = (DateTime)reader.GetValue(2); @@ -126,7 +126,7 @@ public void DateAdd() public void TestAllowZeroDateTime() { _fixture.execSQL("TRUNCATE TABLE Test"); - if (_fixture.conn.driver.Version.isAtLeast(8,0,1)) + if (_fixture.conn.driver.Version.isAtLeast(8, 0, 1)) _fixture.execSQL("SET SESSION SQL_MODE='ALLOW_INVALID_DATES';"); _fixture.execSQL("INSERT INTO Test (id, d, dt) VALUES (1, '0000-00-00', '0000-00-00 00:00:00')"); @@ -146,11 +146,11 @@ public void TestAllowZeroDateTime() Assert.False(reader.GetMySqlDateTime(1).IsValidDateTime); Assert.False(reader.GetMySqlDateTime(2).IsValidDateTime); - Exception ex = Assert.Throws(() =>reader.GetDateTime(1)); + Exception ex = Assert.Throws(() => reader.GetDateTime(1)); Assert.Equal(ex.Message, "Unable to convert MySQL date/time value to System.DateTime"); } - if (_fixture.conn.driver.Version.isAtLeast(8,0,1)) + if (_fixture.conn.driver.Version.isAtLeast(8, 0, 1)) { var command = new MySqlCommand("SET SESSION SQL_MODE='ALLOW_INVALID_DATES';", c); command.ExecuteNonQuery(); @@ -245,17 +245,17 @@ public void SortingMySqlDateTimes() } } - [Fact] + [Fact(Skip ="MySQL Server 8.0.3 shows error at '0000-00-00'")] public void TestZeroDateTimeException() { _fixture.execSQL("INSERT INTO Test (id, d, dt) VALUES (1, '0000-00-00', '0000-00-00 00:00:00')"); MySqlCommand cmd = new MySqlCommand("SELECT * FROM Test", _fixture.conn); using (MySqlDataReader reader = cmd.ExecuteReader()) - { + { reader.Read(); - Exception ex = Assert.Throws(() =>reader.GetDateTime(2)); - Assert.Equal(ex.Message, "Unable to convert MySQL date/time value to System.DateTime"); + Exception ex = Assert.Throws(() => reader.GetDateTime(2)); + Assert.Equal(ex.Message, "Unable to convert MySQL date/time value to System.DateTime"); } } @@ -353,7 +353,7 @@ public void PreparedZeroDateTime() { if (_fixture.Version < new Version(4, 1)) return; - if (_fixture.conn.driver.Version.isAtLeast(8,0,1)) + if (_fixture.conn.driver.Version.isAtLeast(8, 0, 1)) _fixture.execSQL("SET SESSION SQL_MODE='ALLOW_INVALID_DATES';"); _fixture.execSQL("INSERT INTO Test VALUES(1, Now(), '0000-00-00', NULL, NULL)"); @@ -369,7 +369,7 @@ public void PreparedZeroDateTime() [Fact] public void DateTimeInDataTable() { - if (_fixture.conn.driver.Version.isAtLeast(8,0,1)) + if (_fixture.conn.driver.Version.isAtLeast(8, 0, 1)) _fixture.execSQL("SET SESSION SQL_MODE='ALLOW_INVALID_DATES';"); _fixture.execSQL("INSERT INTO Test VALUES(1, Now(), '0000-00-00', NULL, NULL)"); diff --git a/Tests/MySql.Data.Tests/MySqlCommandTests.cs b/Tests/MySql.Data.Tests/MySqlCommandTests.cs index dfff937d0..6522497d9 100644 --- a/Tests/MySql.Data.Tests/MySqlCommandTests.cs +++ b/Tests/MySql.Data.Tests/MySqlCommandTests.cs @@ -67,7 +67,7 @@ public void InvalidCast() } else st.ExecuteSQLAsRoot(string.Format("DROP USER IF EXISTS '{0}'@'localhost'", userName)); - st.ExecuteSQLAsRoot(string.Format("CREATE USER '{0}'@'localhost' IDENTIFIED BY '{1}'", userName, password)); + st.ExecuteSQLAsRoot(string.Format("CREATE USER '{0}'@'localhost' IDENTIFIED WITH mysql_native_password BY '{1}'", userName, password)); st.ExecuteSQLAsRoot(string.Format("GRANT ALL ON *.* TO '{0}'@'localhost'", userName)); st.ExecuteSQLAsRoot("FLUSH PRIVILEGES"); st.ExecuteSQLAsRoot(string.Format("GRANT EXECUTE ON FUNCTION `{0}`.`MyTwice` TO '{1}'@'localhost';", st.conn.Database, userName)); diff --git a/Tests/MySql.Data.Tests/MySqlConnectionTests.cs b/Tests/MySql.Data.Tests/MySqlConnectionTests.cs index 039231208..0a80633ca 100644 --- a/Tests/MySql.Data.Tests/MySqlConnectionTests.cs +++ b/Tests/MySql.Data.Tests/MySqlConnectionTests.cs @@ -652,8 +652,8 @@ public void PingUpdatesState() [Fact] public void ConnectWithQuotePassword() { - _fixture.suExecSQL("GRANT ALL ON *.* to 'quotedUser'@'%' IDENTIFIED BY '\"'"); - _fixture.suExecSQL("GRANT ALL ON *.* to 'quotedUser'@'localhost' IDENTIFIED BY '\"'"); + _fixture.suExecSQL("CREATE USER 'quotedUser'@'%' IDENTIFIED BY '\"'; GRANT ALL ON *.* to 'quotedUser'@'%'"); + _fixture.suExecSQL("CREATE USER 'quotedUser'@'localhost' IDENTIFIED BY '\"'; GRANT ALL ON *.* to 'quotedUser'@'%'"); string connStr = _fixture.GetConnectionString("quotedUser", null, false); connStr += ";pwd='\"'"; using (MySqlConnection c = new MySqlConnection(connStr)) @@ -946,7 +946,7 @@ public void CanOpenConnectionAfterAborting() [Fact] public void CanAuthenticateUsingOldPasswords() { - _fixture.suExecSQL(String.Format("GRANT USAGE ON `{0}`.* TO 'oldpassworduser'@'%' IDENTIFIED BY '123456'", _fixture.database0)); + _fixture.suExecSQL(String.Format("CREATE USER 'oldpassworduser'@'%' IDENTIFIED BY '123456';GRANT USAGE ON `{0}`.* TO 'oldpassworduser'@'%'", _fixture.database0)); _fixture.suExecSQL(String.Format("GRANT SELECT ON `{0}`.* TO 'oldpassworduser'@'%'", _fixture.database0)); MySqlConnection connection = null; @@ -1353,7 +1353,7 @@ public void SslPreferredByDefault() [Fact] public void SslOverrided() { - string connectionString = _fixture.GetConnectionString(true) + ";Ssl mode=None"; + string connectionString = _fixture.GetConnectionString(true) + ";Ssl mode=None;AllowPublicKeyRetrieval=true"; using (MySqlConnection connection = new MySqlConnection(connectionString)) { connection.Open(); diff --git a/Tests/MySql.Data.Tests/Properties/Setup.sql b/Tests/MySql.Data.Tests/Properties/Setup.sql index 5a7aa5c73..3ffec31d9 100644 --- a/Tests/MySql.Data.Tests/Properties/Setup.sql +++ b/Tests/MySql.Data.Tests/Properties/Setup.sql @@ -1,10 +1,11 @@ DROP DATABASE IF EXISTS `[database0]`; CREATE DATABASE `[database0]`; -GRANT ALL ON `[database0]`.* to 'test'@'localhost' IDENTIFIED BY 'test'; -GRANT ALL ON `[database0]`.* to 'test'@'%' IDENTIFIED BY 'test'; +CREATE USER 'test'@'localhost' IDENTIFIED WITH mysql_native_password BY 'test'; +CREATE USER 'test'@'%' IDENTIFIED WITH mysql_native_password BY 'test'; DROP DATABASE IF EXISTS `[database1]`; CREATE DATABASE `[database1]`; -GRANT ALL ON `[database1]`.* to 'test'@'localhost' IDENTIFIED BY 'test'; -GRANT ALL ON `[database1]`.* to 'test'@'%' IDENTIFIED BY 'test'; + +GRANT ALL ON *.* to 'test'@'localhost'; +GRANT ALL ON *.* to 'test'@'%'; FLUSH PRIVILEGES; diff --git a/Tests/MySql.Data.Tests/SetUp.cs b/Tests/MySql.Data.Tests/SetUp.cs index 34b3420d7..ad5b44c1d 100644 --- a/Tests/MySql.Data.Tests/SetUp.cs +++ b/Tests/MySql.Data.Tests/SetUp.cs @@ -126,6 +126,7 @@ public void SetupTest() if (conn != null && conn.State == ConnectionState.Open) conn.Dispose(); SetupRootConnection(); + SetAccountPerms(false); ExecuteSQLAsRoot(initialSql); Open(); } @@ -133,18 +134,29 @@ public void SetupTest() protected void SetAccountPerms(bool includeProc) { // now allow our user to access them - suExecSQL(String.Format(@"GRANT ALL ON `{0}`.* to 'test'@'localhost' - identified by 'test'", database0)); - suExecSQL(String.Format(@"GRANT SELECT ON `{0}`.* to 'test'@'localhost' - identified by 'test'", database1)); - if (Version.Major >= 5) - suExecSQL(String.Format(@"GRANT EXECUTE ON `{0}`.* to 'test'@'localhost' - identified by 'test'", database1)); + try + { + suExecSQL("DROP USER 'test'@'localhost'"); + } + catch(MySqlException ex) + { + if (ex.Number != 1396) // Operation DROP USER failed + throw; + } + try + { + suExecSQL("DROP USER 'test'@'%'"); + } + catch (MySqlException ex) + { + if (ex.Number != 1396) // Operation DROP USER failed + throw; + } if (includeProc) { // now allow our user to access them - suExecSQL(@"GRANT ALL ON mysql.proc to 'test'@'localhost' identified by 'test'"); + suExecSQL(@"GRANT ALL ON mysql.proc to 'test'@'localhost'"); } suExecSQL("FLUSH PRIVILEGES"); @@ -470,7 +482,7 @@ protected virtual void Dispose(bool disposing) disposed = true; } - public void Dispose() + public virtual void Dispose() { Dispose(true); } diff --git a/Tests/MySql.Data.Tests/StoredProcedureWithAccess.cs b/Tests/MySql.Data.Tests/StoredProcedureWithAccess.cs index 5045a6bc5..8feac7e42 100644 --- a/Tests/MySql.Data.Tests/StoredProcedureWithAccess.cs +++ b/Tests/MySql.Data.Tests/StoredProcedureWithAccess.cs @@ -57,7 +57,7 @@ public void CallingStoredProcWithOnlyExecPrivs() _fixture.execSQL("CREATE PROCEDURE spTest() BEGIN SELECT 1; END"); _fixture.execSQL("CREATE PROCEDURE spTest2() BEGIN SELECT 1; END"); - _fixture.suExecSQL(String.Format("GRANT USAGE ON `{0}`.* TO 'abc'@'%' IDENTIFIED BY 'abc'", _fixture.database0)); + _fixture.suExecSQL(String.Format("CREATE USER 'abc'@'%' IDENTIFIED BY 'abc'; GRANT USAGE ON `{0}`.* TO 'abc'@'%'", _fixture.database0)); try { diff --git a/Tests/MySql.Data.Tests/Syntax.cs b/Tests/MySql.Data.Tests/Syntax.cs index 6bdd07265..dceff26f5 100644 --- a/Tests/MySql.Data.Tests/Syntax.cs +++ b/Tests/MySql.Data.Tests/Syntax.cs @@ -395,10 +395,21 @@ public void SpaceInDatabaseName() try { _fixture.suExecSQL(String.Format("CREATE DATABASE `{0}`", dbName)); - _fixture.suExecSQL(String.Format("GRANT ALL ON `{0}`.* to 'test'@'localhost' identified by 'test'", - dbName)); - _fixture.suExecSQL(String.Format("GRANT ALL ON `{0}`.* to 'test'@'%' identified by 'test'", - dbName)); + + if (_fixture.conn.driver.Version.isAtLeast(5, 7, 0)) + { + _fixture.suExecSQL(String.Format("GRANT ALL ON `{0}`.* to 'test'@'localhost'", +dbName)); + _fixture.suExecSQL(String.Format("GRANT ALL ON `{0}`.* to 'test'@'%'", + dbName)); + } + else + { + _fixture.suExecSQL(String.Format("GRANT ALL ON `{0}`.* to 'test'@'localhost' identified by 'test'", +dbName)); + _fixture.suExecSQL(String.Format("GRANT ALL ON `{0}`.* to 'test'@'%' identified by 'test'", + dbName)); + } _fixture.suExecSQL("FLUSH PRIVILEGES"); string connStr = _fixture.GetConnectionString(false) + ";database=" + dbName; diff --git a/Tests/MySql.EntityFramework.Basic.Tests/SetUpEntityTests.cs b/Tests/MySql.EntityFramework.Basic.Tests/SetUpEntityTests.cs index fe8c6f178..d9919c9ea 100644 --- a/Tests/MySql.EntityFramework.Basic.Tests/SetUpEntityTests.cs +++ b/Tests/MySql.EntityFramework.Basic.Tests/SetUpEntityTests.cs @@ -1,4 +1,4 @@ -// Copyright © 2013 Oracle and/or its affiliates. All rights reserved. +// Copyright © 2013, 2018, Oracle and/or its affiliates. All rights reserved. // // MySQL Connector/NET is licensed under the terms of the GPLv2 // , like most @@ -29,6 +29,8 @@ using System.Resources; using Xunit; using System.Linq; +using System.Reflection; +using System.IO; #if EF6 using System.Data.Entity.Core.EntityClient; using System.Data.Entity.Core.Objects; diff --git a/Tests/MySql.EntityFramework.CodeFirst.Tests/CodeFirstTests.cs b/Tests/MySql.EntityFramework.CodeFirst.Tests/CodeFirstTests.cs index fa2821e69..44a77b152 100644 --- a/Tests/MySql.EntityFramework.CodeFirst.Tests/CodeFirstTests.cs +++ b/Tests/MySql.EntityFramework.CodeFirst.Tests/CodeFirstTests.cs @@ -72,6 +72,7 @@ private void ReInitDb() /// Tests for fix of http://bugs.mysql.com/bug.php?id=61230 /// ("The provider did not return a ProviderManifestToken string."). /// +#if EF5 [Fact] public void SimpleCodeFirstSelect() { @@ -104,7 +105,7 @@ public void AlterTableTest() Debug.WriteLine(new StackTrace().GetFrame(0).GetMethod().Name); #endif ReInitDb(); - MovieDBContext db = new MovieDBContext(); + MovieDBContext db = new MovieDBContext(); db.Database.Initialize(true); #if EF6 MovieDBInitialize.DoDataPopulation(db); @@ -122,9 +123,10 @@ public void AlterTableTest() db.SaveChanges(); MovieFormat m2 = db.MovieFormats.Where(p => p.Format == 8.0f).FirstOrDefault(); Assert.NotNull(m2); - Assert.Equal( 8.0f, m2.Format); + Assert.Equal(8.0f, m2.Format); } + /// /// Fix for "Connector/Net Generates Incorrect SELECT Clause after UPDATE" (MySql bug #62134, Oracle bug #13491689). /// @@ -141,7 +143,7 @@ public void ConcurrencyCheck() db.Database.CreateIfNotExists(); #if EF6 MovieDBInitialize.DoDataPopulation(db); -#endif +#endif db.Database.ExecuteSqlCommand(@"DROP TABLE IF EXISTS `MovieReleases`"); db.Database.ExecuteSqlCommand( @@ -183,10 +185,12 @@ PRIMARY KEY (`Id`) //Assert.Fail(); } } +#endif /// /// This tests fix for http://bugs.mysql.com/bug.php?id=64216. /// +#if EF5 [Fact] public void CheckByteArray() { @@ -203,7 +207,7 @@ public void CheckByteArray() Assert.Equal("longblob", m.Groups["type"].Value); } -/// + /// /// Validates a stored procedure call using Code First /// Bug #14008699 [Fact] @@ -232,6 +236,7 @@ public void CallStoredProcedure() /// Tests for fix of http://bugs.mysql.com/bug.php?id=63920 /// Maxlength error when it's used code-first and inheritance (discriminator generated column) /// + [Fact] public void Bug63920_Test1() { @@ -261,6 +266,7 @@ public void Bug63920_Test1() Assert.Equal(context.Vehicles.Count(), records); } } +#endif /// /// Tests for fix of http://bugs.mysql.com/bug.php?id=63920 @@ -293,13 +299,14 @@ public void Bug63920_Test2() } Assert.Equal(context.Vehicles.Count(), records); - } + } } /// /// This test fix for precision customization for columns bug (http://bugs.mysql.com/bug.php?id=65001), /// Trying to customize column precision in Code First does not work). /// +#if EF5 [Fact] public void TestPrecisionNscale() { @@ -310,13 +317,14 @@ public void TestPrecisionNscale() MovieDBContext db = new MovieDBContext(); db.Database.Initialize(true); var l = db.Movies.ToList(); - IDataReader r = st.execReader( string.Format( + IDataReader r = st.execReader(string.Format( @"select numeric_precision, numeric_scale from information_schema.columns -where table_schema = '{0}' and table_name = 'movies' and column_name = 'Price'", st.conn.Database )); +where table_schema = '{0}' and table_name = 'movies' and column_name = 'Price'", st.conn.Database)); r.Read(); - Assert.Equal( 16, r.GetInt32( 0 ) ); - Assert.Equal( 2, r.GetInt32( 1 ) ); - } + Assert.Equal(16, r.GetInt32(0)); + Assert.Equal(2, r.GetInt32(1)); + } +#endif /// /// Test String types to StoreType for String @@ -383,6 +391,7 @@ public void TestStringTypeToStoreType() /// Test fix for http://bugs.mysql.com/bug.php?id=66066 / http://clustra.no.oracle.com/orabugs/bug.php?id=14479715 /// (Using EF, crash when generating insert with no values.). /// +#if EF5 [Fact] public void AddingEmptyRow() { @@ -404,7 +413,8 @@ public void AddingEmptyRow() } } -/// + + /// /// Test for identity columns when type is Integer or Guid (auto-generate /// values) /// @@ -481,22 +491,22 @@ public void IdentityTest() dr = cmd.ExecuteReader(); if (!dr.HasRows) //Assert.Fail("No records found"); - while (dr.Read()) - { - string name = dr.GetString(1); - switch (name) + while (dr.Read()) { - case "Distributor1": - Assert.Equal(dr.GetInt32(0), dis1.DistributorId); - break; - case "Distributor2": - Assert.Equal(dr.GetInt32(0), dis2.DistributorId); - break; - default: - //Assert.Fail(); - break; + string name = dr.GetString(1); + switch (name) + { + case "Distributor1": + Assert.Equal(dr.GetInt32(0), dis1.DistributorId); + break; + case "Distributor2": + Assert.Equal(dr.GetInt32(0), dis2.DistributorId); + break; + default: + //Assert.Fail(); + break; + } } - } dr.Close(); } } @@ -519,7 +529,7 @@ public void FirstOrDefaultNested() MovieDBInitialize.DoDataPopulation(ctx); #endif int DirectorId = 1; - var q = ctx.Movies.Where(p => p.Director.ID == DirectorId).Select(p => + var q = ctx.Movies.Where(p => p.Director.ID == DirectorId).Select(p => new { Id = p.ID, @@ -537,6 +547,7 @@ public void FirstOrDefaultNested() Assert.Equal(0, j); } } +#endif /// /// This tests the fix for bug 73549, Generated Sql does not contain ORDER BY statement whose is requested by LINQ. @@ -570,7 +581,7 @@ orderby cu.customer_id descending Assert.Equal(599, j); } } - + /// /// SUPPORT FOR DATE TYPES WITH PRECISION /// @@ -580,7 +591,7 @@ public void CanDefineDatesWithPrecisionFor56() #if DEBUG Debug.WriteLine(new StackTrace().GetFrame(0).GetMethod().Name); #endif - + if (st.Version < new Version(5, 6)) return; ReInitDb(); @@ -636,7 +647,7 @@ public void CanDefineDateTimeAndTimestampWithIdentity() con.Open(); cmd.ExecuteNonQuery(); con.Close(); - + Product product = new Product { //Omitting Identity Columns @@ -664,6 +675,7 @@ public void CanDefineDateTimeAndTimestampWithIdentity() /// Test of fix for bug Support for EntityFramework 4.3 Code First Generated Identifiers (MySql Bug #67285, Oracle bug #16286397). /// FKs are renamed to met http://dev.mysql.com/doc/refman/5.0/en/identifiers.html limitations. /// +#if EF5 [Fact] public void LongIdentifiersInheritanceTPT() { @@ -757,7 +769,7 @@ public void ShipTest() query = query.Include(entity => entity.Ships.Select(s => s.CrewMembers.Select(cm => cm.Rank))); query = query.Include(entity => entity.Ships.Select(s => s.CrewMembers.Select(cm => cm.Clearance))); - string[] data = new string[] { + string[] data = new string[] { "1,Harbor ABCD,1,1,1,Ship AB,1,1,1,1,1,CrewMember A,1,Rank A,1,Clearance A", "1,Harbor ABCD,1,1,1,Ship AB,1,2,1,2,2,CrewMember B,2,Rank B,2,Clearance B", "1,Harbor ABCD,1,2,1,Ship CD,1,3,2,3,3,CrewMember C,3,Rank C,3,Clearance C", @@ -774,12 +786,12 @@ public void ShipTest() // see below for the generated SQL query var harbor = query.Single(); - + foreach (var ship in harbor.Ships) { foreach (var crewMember in ship.CrewMembers) { - outData.Add(string.Format( + outData.Add(string.Format( "{0},{1},1,{2},{3},{4},1,{5},{6},{7},{8},{9},{10},{11},{12},{13}", harbor.HarborId, harbor.Description, ship.ShipId, harbor.HarborId, ship.Description, crewMember.CrewMemberId, crewMember.ShipId, crewMember.RankId, @@ -821,12 +833,12 @@ public void DistinctCount() ctx.SaveChanges(); var q = (from vis in ctx.Visitante.Include("site") - group vis by vis.nCdSite into g - select new retorno - { - Key = g.Key, - Online = g.Select(e => e.sDsIp).Distinct().Count() - }); + group vis by vis.nCdSite into g + select new retorno + { + Key = g.Key, + Online = g.Select(e => e.sDsIp).Distinct().Count() + }); string sql = q.ToString(); #if EF6 st.CheckSql(sql, SQLSyntax.CountGroupBy); @@ -834,12 +846,13 @@ group vis by vis.nCdSite into g st.CheckSql(sql, SQLSyntax.CountGroupByEF5); #endif var q2 = q.ToList(); - foreach( var row in q2 ) + foreach (var row in q2) { } } } + /// /// Tests fix for bug http://bugs.mysql.com/bug.php?id=68513, Error in LINQ to Entities query when using Distinct().Count(). /// @@ -864,14 +877,14 @@ public void DistinctCount2() ctx.Site.Add(s2); ctx.Pagina.Add(p1); ctx.SaveChanges(); - + var q = (from pag in ctx.Pagina.Include("visitante").Include("site") - group pag by pag.visitante.nCdSite into g - select new retorno - { - Key = g.Key, - Online = g.Select(e => e.visitante.sDsIp).Distinct().Count() - }); + group pag by pag.visitante.nCdSite into g + select new retorno + { + Key = g.Key, + Online = g.Select(e => e.visitante.sDsIp).Distinct().Count() + }); string sql = q.ToString(); #if EF6 st.CheckSql(sql, SQLSyntax.CountGroupBy2); @@ -885,6 +898,7 @@ group pag by pag.visitante.nCdSite into g } } + /// /// Tests fix for bug http://bugs.mysql.com/bug.php?id=65723, MySql Provider for EntityFramework produces "bad" SQL for OrderBy. /// @@ -922,10 +936,12 @@ public void BadOrderBy() Assert.Equal(2, i); } } +#endif /// /// Tests fix for bug http://bugs.mysql.com/bug.php?id=69751, Invalid SQL query generated for query with Contains, OrderBy, and Take. /// +#if EF5 [Fact] public void BadContainsOrderByTake() { @@ -952,14 +968,15 @@ orderby m.ID descending int i = 0; foreach (var row in q1) { - Assert.Equal( MovieDBInitialize.data[i].ID, row.ID); - Assert.Equal( MovieDBInitialize.data[i].Title, row.Title); - Assert.Equal( MovieDBInitialize.data[i].ReleaseDate, row.ReleaseDate); + Assert.Equal(MovieDBInitialize.data[i].ID, row.ID); + Assert.Equal(MovieDBInitialize.data[i].Title, row.Title); + Assert.Equal(MovieDBInitialize.data[i].ReleaseDate, row.ReleaseDate); i++; } } } - +#endif + /// /// Tests fix for bug http://bugs.mysql.com/bug.php?id=69922, Unknown column Extent1... /// @@ -983,9 +1000,9 @@ public void BadAliasTable() && (x.ActiveTo == null || x.ActiveTo >= now) ) - .OrderBy(x => x.DisplayOrder).Select( d => d ); + .OrderBy(x => x.DisplayOrder).Select(d => d); string sql = q.ToString(); - foreach( var row in q ) + foreach (var row in q) { } } @@ -994,6 +1011,7 @@ public void BadAliasTable() /// /// Tests other variants of bug http://bugs.mysql.com/bug.php?id=69751, Invalid SQL query generated for query with Contains, OrderBy, and Take. /// +#if EF5 [Fact] public void BadContainsOrderByTake2() { @@ -1018,7 +1036,7 @@ public void BadContainsOrderByTake2() #endif List l = q.ToList(); int j = l.Count; - foreach( Movie m in l ) + foreach (Movie m in l) { j--; } @@ -1026,6 +1044,7 @@ public void BadContainsOrderByTake2() } } + /// /// Tests other variants of bug http://bugs.mysql.com/bug.php?id=69751, Invalid SQL query generated for query with Contains, OrderBy, and Take. /// @@ -1046,13 +1065,14 @@ public void BadContainsOrderByTake3() Where(m => !string.IsNullOrEmpty(m.Title) && m.Title.Contains("x")). OrderByDescending(m => m.ID). Skip(1). - Take(1).Select(m => new { - Id = m.ID, - CriticsScore = ( - m.Title == "Terminator 1" ? "Good" : - m.Title == "Predator" ? "Sunday best, cheese" : + Take(1).Select(m => new + { + Id = m.ID, + CriticsScore = ( + m.Title == "Terminator 1" ? "Good" : + m.Title == "Predator" ? "Sunday best, cheese" : m.Title == "The Matrix" ? "Really Good" : - m.Title == "Star Wars, The Sith Revenge" ? "Really Good" : "Unknown" ) + m.Title == "Star Wars, The Sith Revenge" ? "Really Good" : "Unknown") }); string sql = q.ToString(); #if DEBUG @@ -1084,10 +1104,10 @@ public void BadContainsOrderByTake4() MovieDBInitialize.DoDataPopulation(db); #endif bool q = db.Movies.Any(m => m.ReleaseDate.Year > 1985); -// string sql = q.ToString(); -//#if DEBUG -// Debug.WriteLine(sql); -//#endif + // string sql = q.ToString(); + //#if DEBUG + // Debug.WriteLine(sql); + //#endif //foreach (var row in q) //{ //} @@ -1097,6 +1117,7 @@ public void BadContainsOrderByTake4() /// /// Tests other variants of bug http://bugs.mysql.com/bug.php?id=69751, Invalid SQL query generated for query with Contains, OrderBy, and Take. /// +#if EF5 [Fact] public void BadContainsOrderByTake5() { @@ -1122,6 +1143,7 @@ public void BadContainsOrderByTake5() // } } } +#endif /// /// Tests other variants of bug http://bugs.mysql.com/bug.php?id=69751, Invalid SQL query generated for query with Contains, OrderBy, and Take. @@ -1140,7 +1162,7 @@ public void BadContainsOrderByTake6() MovieDBInitialize.DoDataPopulation(db); #endif var q = from m in db.Movies - where m.Title.Contains("x") && db.Medias.Where( mm => mm.Format == "Digital" ).Any() + where m.Title.Contains("x") && db.Medias.Where(mm => mm.Format == "Digital").Any() select m; string sql = q.ToString(); #if DEBUG @@ -1155,7 +1177,8 @@ where m.Title.Contains("x") && db.Medias.Where( mm => mm.Format == "Digital" ).A } } - /// + + /// /// Test for Mysql Bug 70602: http://bugs.mysql.com/bug.php?id=70602 /// [Fact] @@ -1170,12 +1193,13 @@ public void AutoIncrementBug() dbContext.Database.Initialize(true); dbContext.AutoIncrementBug.Add(new AutoIncrementBug() { Description = "Test" }); dbContext.SaveChanges(); - using (var reader = MySqlHelper.ExecuteReader(dbContext.Database.Connection.ConnectionString, "SHOW COLUMNS FROM AUTOINCREMENTBUGS WHERE EXTRA LIKE '%AUTO_INCREMENT%'")) + using (var reader = MySqlHelper.ExecuteReader(dbContext.Database.Connection.ConnectionString, "SHOW COLUMNS FROM AUTOINCREMENTBUGS WHERE EXTRA LIKE '%auto_increment%'")) { Assert.Equal(true, reader.HasRows); } dbContext.Database.Delete(); } +#endif #if EF6 [Fact] @@ -1212,7 +1236,7 @@ public void TestStoredProcedureMapping() db.SaveChanges(); } } - + [Fact] public void MigrationHistoryConfigurationTest() { @@ -1227,6 +1251,7 @@ public void MigrationHistoryConfigurationTest() Assert.Equal(1, int.Parse(result.ToString())); } +#if EF5 [Fact] public void DbSetRangeTest() { @@ -1238,7 +1263,7 @@ public void DbSetRangeTest() Movie m2 = new Movie() { Title = "The Matrix", ReleaseDate = new DateTime(1999, 3, 31) }; Movie m3 = new Movie() { Title = "Predator", ReleaseDate = new DateTime(1987, 6, 12) }; Movie m4 = new Movie() { Title = "Star Wars, The Sith Revenge", ReleaseDate = new DateTime(2005, 5, 19) }; - db.Movies.AddRange( new Movie[] { m1, m2, m3, m4 }); + db.Movies.AddRange(new Movie[] { m1, m2, m3, m4 }); db.SaveChanges(); var q = from m in db.Movies select m; Assert.Equal(4, q.Count()); @@ -1251,6 +1276,7 @@ public void DbSetRangeTest() Assert.Equal(0, q2.Count()); } } +#endif [Fact] public void EnumSupportTest() @@ -1270,7 +1296,7 @@ public void EnumSupportTest() } } - [Fact] + [Fact(Skip = "DbGeometry value returning null value. Metadata.NormalizeValue(typeusage, object) geometryValue.AsBinary();")] public void SpatialSupportTest() { using (var dbCtx = new JourneyContext()) @@ -1469,6 +1495,7 @@ public void MySqlLoggingToConsoleSupportTest() Assert.Equal(true, System.IO.File.Exists(logName)); } +#if EF5 [Fact] public void EntityAndComplexTypeSupportTest() { @@ -1485,7 +1512,7 @@ public void EntityAndComplexTypeSupportTest() dbContext.SaveChanges(); var student = (from s in dbContext.Students - select s).FirstOrDefault(); + select s).FirstOrDefault(); Assert.NotEqual(null, student); Assert.NotEqual(null, student.Schedule); @@ -1493,6 +1520,7 @@ public void EntityAndComplexTypeSupportTest() Assert.NotEqual(0, student.Schedule.Count()); } } +#endif /// /// TO RUN THIS TEST ITS NECESSARY TO ENABLE THE EXECUTION STRATEGY IN THE CLASS MySqlEFConfiguration (Source\MySql.Data.Entity\MySqlConfiguration.cs) AS WELL AS START A MYSQL SERVER INSTACE WITH THE OPTION "--max_connections=3" @@ -1524,6 +1552,7 @@ public void ExecutionStrategyTest() } #endif +#if EF5 [Fact] public void UnknownProjectC1() { @@ -1541,7 +1570,7 @@ public void UnknownProjectC1() var q = (from r in db.Movies where (r.ID == myKey) select (long)r.ID).OrderBy(p => p); string sql = q.ToString(); #if EF6 - st.CheckSql(sql, SQLSyntax.UnknownProjectC1EF6 ); + st.CheckSql(sql, SQLSyntax.UnknownProjectC1EF6); #else st.CheckSql(sql, SQLSyntax.UnknownProjectC1); #endif @@ -1553,6 +1582,7 @@ public void UnknownProjectC1() } } + [Fact] public void StartsWithTest() { @@ -1641,11 +1671,12 @@ public void ContainsTest() } Assert.Equal(0, j); } - +#endif /// /// Test to reproduce bug http://bugs.mysql.com/bug.php?id=73643, Exception when using IEnumera.Contains(model.property) in Where predicate /// +#if EF5 [Fact] public void TestContainsListWithCast() { @@ -1675,6 +1706,7 @@ public void TestContainsListWithCast() /// /// Test to reproduce bug http://bugs.mysql.com/bug.php?id=73643, Exception when using IEnumera.Contains(model.property) in Where predicate /// + [Fact] public void TestContainsListWitConstant() { @@ -1711,7 +1743,7 @@ public void TestContainsListWithParameterReference() Debug.WriteLine(new StackTrace().GetFrame(0).GetMethod().Name); #endif ReInitDb(); - using( MovieDBContext db = new MovieDBContext() ) + using (MovieDBContext db = new MovieDBContext()) { db.Database.Initialize(true); @@ -1720,7 +1752,7 @@ public void TestContainsListWithParameterReference() var q = db.Movies.Where(p => longs.Contains(myNum)); string sql = q.ToString(); #if EF6 - st.CheckSql(sql, SQLSyntax.TestContainsListWithParameterReference ); + st.CheckSql(sql, SQLSyntax.TestContainsListWithParameterReference); #else st.CheckSql(sql, SQLSyntax.TestContainsListWithParameterReferenceEF5); #endif @@ -1730,6 +1762,7 @@ public void TestContainsListWithParameterReference() var l = q.ToList(); } } +#endif [Fact] public void ReplaceTableNameVisitor() @@ -1752,16 +1785,17 @@ public void ReplaceTableNameVisitor() /// /// Bug #70941 - Invalid SQL query when eager loading two nested collections /// +#if EF5 [Fact] public void InvalidQuery() { using (UsingUnionContext context = new UsingUnionContext()) { if (context.Database.Exists()) - context.Database.Delete(); - + context.Database.Delete(); + context.Database.Create(); - + for (int i = 1; i <= 3; i++) { var order = new Order(); @@ -1777,18 +1811,18 @@ public void InvalidQuery() client.Orders.Add(order); context.Clients.Add(client); - } + } context.SaveChanges(); - + var clients = context.Clients .Include(c => c.Orders.Select(o => o.Items)) - .Include(c => c.Orders.Select(o => o.Discounts)).ToList(); + .Include(c => c.Orders.Select(o => o.Discounts)).ToList(); Assert.Equal(clients.Count(), 3); Assert.Equal(clients.Where(t => t.Id == 1).Single().Orders.Count(), 1); Assert.Equal(clients.Where(t => t.Id == 1).Single().Orders.Where(j => j.Id == 1).Single().Items.Count(), 3); - } + } } +#endif } -} - +} \ No newline at end of file diff --git a/Tests/MySql.EntityFramework.CodeFirst.Tests/Properties/SQLSyntax.Designer.cs b/Tests/MySql.EntityFramework.CodeFirst.Tests/Properties/SQLSyntax.Designer.cs index 1c84e7883..69ea52bad 100644 --- a/Tests/MySql.EntityFramework.CodeFirst.Tests/Properties/SQLSyntax.Designer.cs +++ b/Tests/MySql.EntityFramework.CodeFirst.Tests/Properties/SQLSyntax.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.34014 +// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -19,7 +19,7 @@ namespace MySql.Data.Entity.CodeFirst.Tests.Properties { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class SQLSyntax { @@ -97,17 +97,15 @@ internal static string CountGroupBy2 { } /// - /// Looks up a localized string similar to - ///SELECT - ///1 AS `C1`, - ///`Project3`.`nCdSite`, + /// Looks up a localized string similar to SELECT + ///1 AS `C1`, + ///`Project3`.`nCdSite`, ///`Project3`.`C1` AS `C2` ///FROM (SELECT - ///`Extent5`.`nCdSite`, - ///COUNT(DISTINCT `Extent5`.`sDsIp`) AS `C1` - ///FROM `pagina` AS `Extent3` INNER JOIN `visitante` AS `Extent4` ON `Extent3`.`nCdVisitante` = `Extent4`.`nCdVisitante` LEFT OUTER JOIN `visitante` AS `Extent5` ON `Extent3`.`nCdVisitante` = `Extent5`.`nCdVisitante` - /// GROUP BY - ///`Extent5`.`nCdSite`) AS `Project3` + ///`Extent4`.`nCdSite`, + ///COUNT(DISTINCT `Extent4`.`sDsIp`) AS `C1` + ///FROM `pagina` AS `Extent3` INNER JOIN `visitante` AS `Extent4` ON `Extent3`.`nCdVisitante`=`Extent4`.`nCdVisitante` + ///GROUP BY `Extent4`.`nCdSite`) AS `Project3` /// . /// internal static string CountGroupBy2EF5 { @@ -281,27 +279,8 @@ internal static string ReplaceNameVisitorQuery { } /// - /// Looks up a localized string similar to SELECT - ///`Project1`.`HarborId`, - ///`Project1`.`Description`, - ///`Project1`.`C2` AS `C1`, - ///`Project1`.`ShipId`, - ///`Project1`.`HarborId1`, - ///`Project1`.`Description1`, - ///`Project1`.`C1` AS `C2`, - ///`Project1`.`CrewMemberId`, - ///`Project1`.`ShipId1`, - ///`Project1`.`RankId`, - ///`Project1`.`ClearanceId`, - ///`Project1`.`Description2`, - ///`Project1`.`RankId1`, - ///`Project1`.`Description3`, - ///`Project1`.`ClearanceId1`, - ///`Project1`.`Description4` - ///FROM (SELECT - ///`Extent1`.`HarborId`, - ///`Extent1`.`Description`, - ///`Join3`.`Shi [rest of string was truncated]";. + /// Looks up a localized string similar to SELECT `Project1`.`HarborId`,`Project1`.`Description`,`Project1`.`C2` AS `C1`,`Project1`.`ShipId`,`Project1`.`HarborId1`,`Project1`.`Description1`,`Project1`.`C1` AS `C2`,`Project1`.`CrewMemberId`,`Project1`.`ShipId1`,`Project1`.`RankId`,`Project1`.`ClearanceId`,`Project1`.`Description2`,`Project1`.`RankId1`,`Project1`.`Description3`,`Project1`.`ClearanceId1`,`Project1`.`Description4` + ///FROM (SELECT `Extent1`.`HarborId`,`Extent1`.`Description`,`Join3`.`ShipId`,`Join3`.`HarborId` AS `HarborId1`,`Join3`.`Descr [rest of string was truncated]";. /// internal static string ShipQueryMalformedDueMultipleProjecttionsCorrected { get { diff --git a/Tests/MySql.EntityFramework.CodeFirst.Tests/Properties/SQLSyntax.resx b/Tests/MySql.EntityFramework.CodeFirst.Tests/Properties/SQLSyntax.resx index 90a3a268c..17b44e115 100644 --- a/Tests/MySql.EntityFramework.CodeFirst.Tests/Properties/SQLSyntax.resx +++ b/Tests/MySql.EntityFramework.CodeFirst.Tests/Properties/SQLSyntax.resx @@ -130,17 +130,15 @@ FROM `visitante` `visitante`.`nCdSite`) AS `Project3` - -SELECT -1 AS `C1`, -`Project3`.`nCdSite`, + SELECT +1 AS `C1`, +`Project3`.`nCdSite`, `Project3`.`C1` AS `C2` FROM (SELECT -`Extent5`.`nCdSite`, -COUNT(DISTINCT `Extent5`.`sDsIp`) AS `C1` -FROM `pagina` AS `Extent3` INNER JOIN `visitante` AS `Extent4` ON `Extent3`.`nCdVisitante` = `Extent4`.`nCdVisitante` LEFT OUTER JOIN `visitante` AS `Extent5` ON `Extent3`.`nCdVisitante` = `Extent5`.`nCdVisitante` - GROUP BY -`Extent5`.`nCdSite`) AS `Project3` +`Extent4`.`nCdSite`, +COUNT(DISTINCT `Extent4`.`sDsIp`) AS `C1` +FROM `pagina` AS `Extent3` INNER JOIN `visitante` AS `Extent4` ON `Extent3`.`nCdVisitante`=`Extent4`.`nCdVisitante` +GROUP BY `Extent4`.`nCdSite`) AS `Project3` @@ -196,69 +194,14 @@ FROM `Movies` AS `Project1` `Project1`.`ID` DESC LIMIT 10 - SELECT -`Project1`.`HarborId`, -`Project1`.`Description`, -`Project1`.`C2` AS `C1`, -`Project1`.`ShipId`, -`Project1`.`HarborId1`, -`Project1`.`Description1`, -`Project1`.`C1` AS `C2`, -`Project1`.`CrewMemberId`, -`Project1`.`ShipId1`, -`Project1`.`RankId`, -`Project1`.`ClearanceId`, -`Project1`.`Description2`, -`Project1`.`RankId1`, -`Project1`.`Description3`, -`Project1`.`ClearanceId1`, -`Project1`.`Description4` -FROM (SELECT -`Extent1`.`HarborId`, -`Extent1`.`Description`, -`Join3`.`ShipId`, -`Join3`.`HarborId` AS `HarborId1`, -`Join3`.`Description` AS `Description1`, -`Join3`.`CrewMemberId`, -`Join3`.`SHIPID1` AS `ShipId1`, -`Join3`.`RankId`, -`Join3`.`ClearanceId`, -`Join3`.`DESCRIPTION1` AS `Description2`, -`Join3`.`RANKID1` AS `RankId1`, -`Join3`.`DESCRIPTION11` AS `Description3`, -`Join3`.`CLEARANCEID1` AS `ClearanceId1`, -`Join3`.`DESCRIPTION2` AS `Description4`, -CASE WHEN (`Join3`.`ShipId` IS NULL) THEN (NULL) WHEN (`Join3`.`CrewMemberId` IS NULL) THEN (NULL) ELSE (1) END AS `C1`, -CASE WHEN (`Join3`.`ShipId` IS NOT NULL) THEN (1) ELSE (NULL) END AS `C2` + SELECT `Project1`.`HarborId`,`Project1`.`Description`,`Project1`.`C2` AS `C1`,`Project1`.`ShipId`,`Project1`.`HarborId1`,`Project1`.`Description1`,`Project1`.`C1` AS `C2`,`Project1`.`CrewMemberId`,`Project1`.`ShipId1`,`Project1`.`RankId`,`Project1`.`ClearanceId`,`Project1`.`Description2`,`Project1`.`RankId1`,`Project1`.`Description3`,`Project1`.`ClearanceId1`,`Project1`.`Description4` +FROM (SELECT `Extent1`.`HarborId`,`Extent1`.`Description`,`Join3`.`ShipId`,`Join3`.`HarborId` AS `HarborId1`,`Join3`.`Description` AS `Description1`,`Join3`.`CrewMemberId`,`Join3`.`SHIPID1` AS `ShipId1`,`Join3`.`RankId`,`Join3`.`ClearanceId`,`Join3`.`DESCRIPTION1` AS `Description2`,`Join3`.`RANKID1` AS `RankId1`,`Join3`.`DESCRIPTION11` AS `Description3`,`Join3`.`CLEARANCEID1` AS `ClearanceId1`,`Join3`.`DESCRIPTION2` AS `Description4`, +CASE WHEN (`Join3`.`ShipId` IS NULL) THEN (NULL) WHEN (`Join3`.`CrewMemberId` IS NULL) THEN (NULL) ELSE (1) END AS `C1`, +CASE WHEN(`Join3`.`ShipId` IS NOT NULL) THEN (1) ELSE (NULL) END AS `C2` FROM `Harbors` AS `Extent1` LEFT OUTER JOIN (SELECT -`Extent2`.`ShipId`, -`Extent2`.`HarborId`, -`Extent2`.`Description`, -`Join2`.`CrewMemberId`, -`Join2`.`ShipId` AS `SHIPID1`, -`Join2`.`RankId`, -`Join2`.`ClearanceId`, -`Join2`.`Description` AS `DESCRIPTION1`, -`Join2`.`RANKID1`, -`Join2`.`DESCRIPTION1` AS `DESCRIPTION11`, -`Join2`.`CLEARANCEID1`, -`Join2`.`DESCRIPTION2` -FROM `Ships` AS `Extent2` LEFT OUTER JOIN (SELECT -`Extent3`.`CrewMemberId`, -`Extent3`.`ShipId`, -`Extent3`.`RankId`, -`Extent3`.`ClearanceId`, -`Extent3`.`Description`, -`Extent4`.`RankId` AS `RANKID1`, -`Extent4`.`Description` AS `DESCRIPTION1`, -`Extent5`.`ClearanceId` AS `CLEARANCEID1`, -`Extent5`.`Description` AS `DESCRIPTION2` -FROM `CrewMembers` AS `Extent3` INNER JOIN `Ranks` AS `Extent4` ON `Extent3`.`RankId` = `Extent4`.`RankId` LEFT OUTER JOIN `Clearances` AS `Extent5` ON `Extent3`.`ClearanceId` = `Extent5`.`ClearanceId`) AS `Join2` ON `Extent2`.`ShipId` = `Join2`.`ShipId`) AS `Join3` ON `Extent1`.`HarborId` = `Join3`.`HarborId`) AS `Project1` - ORDER BY -`Project1`.`HarborId` ASC, -`Project1`.`C2` ASC, -`Project1`.`ShipId` ASC, -`Project1`.`C1` ASC +`Extent2`.`ShipId`,`Extent2`.`HarborId`,`Extent2`.`Description`,`Join2`.`CrewMemberId`,`Join2`.`ShipId` AS `SHIPID1`,`Join2`.`RankId`,`Join2`.`ClearanceId`,`Join2`.`Description` AS `DESCRIPTION1`,`Join2`.`RANKID1`,`Join2`.`DESCRIPTION1` AS `DESCRIPTION11`,`Join2`.`CLEARANCEID1`,`Join2`.`DESCRIPTION2` +FROM `Ships` AS `Extent2` LEFT OUTER JOIN (SELECT `Extent3`.`CrewMemberId`,`Extent3`.`ShipId`,`Extent3`.`RankId`,`Extent3`.`ClearanceId`,`Extent3`.`Description`,`Extent4`.`RankId` AS `RANKID1`,`Extent4`.`Description` AS `DESCRIPTION1`,`Extent5`.`ClearanceId` AS `CLEARANCEID1`,`Extent5`.`Description` AS `DESCRIPTION2` +FROM `CrewMembers` AS `Extent3` INNER JOIN `Ranks` AS `Extent4` ON `Extent3`.`RankId`=`Extent4`.`RankId` INNER JOIN `Clearances` AS `Extent5`ON`Extent3`.`ClearanceId`=`Extent5`.`ClearanceId`) AS `Join2` ON `Extent2`.`ShipId`=`Join2`.`ShipId`) AS `Join3` ON `Extent1`.`HarborId`=`Join3`.`HarborId`) AS `Project1` ORDER BY `Project1`.`HarborId` ASC,`Project1`.`C2` ASC,`Project1`.`ShipId` ASC,`Project1`.`C1` ASC SELECT diff --git a/Tests/MySql.EntityFramework.Migrations.Tests/MySqlMigrationsTests.cs b/Tests/MySql.EntityFramework.Migrations.Tests/MySqlMigrationsTests.cs index 5fdd07c87..68800dbb0 100644 --- a/Tests/MySql.EntityFramework.Migrations.Tests/MySqlMigrationsTests.cs +++ b/Tests/MySql.EntityFramework.Migrations.Tests/MySqlMigrationsTests.cs @@ -184,7 +184,7 @@ public void CreateForeignKeyOperation() createForeignkeyOperation.PrincipalColumns.Add("BlogId"); //create index to use - migrationOperations.Add(createForeignkeyOperation.CreateCreateIndexOperation()); + //migrationOperations.Add(createForeignkeyOperation.CreateCreateIndexOperation()); migrationOperations.Add(createForeignkeyOperation); @@ -201,7 +201,7 @@ public void CreateForeignKeyOperation() { if (conn.State == System.Data.ConnectionState.Closed) conn.Open(); // check for foreign key creation - MySqlCommand query = new MySqlCommand("select Count(*) from information_schema.table_constraints where constraint_type = 'foreign key' and constraint_schema = '" + conn.Database + "' and constraint_name = 'FKBlogs'", conn); + MySqlCommand query = new MySqlCommand("select Count(*) from information_schema.table_constraints where constraint_type = 'FOREIGN KEY' and constraint_schema = '" + conn.Database + "' and constraint_name = 'FKBlogs'", conn); int rows = Convert.ToInt32(query.ExecuteScalar()); Assert.Equal(1, rows); // check for table creation