From fe6cada7558e55388f29ffca1f1780d3cf2882f7 Mon Sep 17 00:00:00 2001 From: Mike Alhayek Date: Mon, 5 Sep 2022 17:40:56 -0700 Subject: [PATCH 01/15] Fix #12334 --- .../Services/TenantValidator.cs | 3 ++- .../DbConnectionValidatorResult.cs | 19 ++++++++------- .../DbConnectionValidator.cs | 24 ++++++++++++------- .../DatabaseShellsStorageOptions.cs | 4 +++- .../DatabaseShellContextFactoryExtensions.cs | 5 ++-- .../OrchardCore.Setup.Core/SetupService.cs | 2 +- 6 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/OrchardCore.Modules/OrchardCore.Tenants/Services/TenantValidator.cs b/src/OrchardCore.Modules/OrchardCore.Tenants/Services/TenantValidator.cs index b323c9b651e..931787130ed 100644 --- a/src/OrchardCore.Modules/OrchardCore.Tenants/Services/TenantValidator.cs +++ b/src/OrchardCore.Modules/OrchardCore.Tenants/Services/TenantValidator.cs @@ -117,7 +117,8 @@ private async Task AssertConnectionValidityAndApplyErrorsAsync(string databasePr case DbConnectionValidatorResult.InvalidConnection: errors.Add(new ModelError(nameof(TenantViewModel.ConnectionString), S["The provided connection string is invalid or server is unreachable."])); break; - case DbConnectionValidatorResult.DocumentFound: + case DbConnectionValidatorResult.ShellDescriptorDocumentFound: + case DbConnectionValidatorResult.DocumentTableFound: errors.Add(new ModelError(nameof(TenantViewModel.TablePrefix), S["The provided table prefix already exists."])); break; } diff --git a/src/OrchardCore/OrchardCore.Data.YesSql.Abstractions/DbConnectionValidatorResult.cs b/src/OrchardCore/OrchardCore.Data.YesSql.Abstractions/DbConnectionValidatorResult.cs index 6a6fe06a02f..9e90c6c12d2 100644 --- a/src/OrchardCore/OrchardCore.Data.YesSql.Abstractions/DbConnectionValidatorResult.cs +++ b/src/OrchardCore/OrchardCore.Data.YesSql.Abstractions/DbConnectionValidatorResult.cs @@ -2,21 +2,24 @@ namespace OrchardCore.Data; public enum DbConnectionValidatorResult { - // Unknown indicates that the connection string status is unknown or was not yet validated + // 'Unknown' indicates that the connection string status is unknown or was not yet validated. Unknown, - // NoProvider indicated that the provider is missing + // 'NoProvider' indicated that the provider is missing. NoProvider, - // DocumentNotFound indicates that the connection string was valid, yet the Document table does not exist - DocumentNotFound, + // 'DocumentTableNotFound' indicates that the connection string was valid, yet the Document table does not exist. + DocumentTableNotFound, - // DocumentFound indicates that the connection string was valid, yet the Document table exist - DocumentFound, + // 'DocumentFound' indicates that the connection string was valid, yet the Document table exist. + DocumentTableFound, - // InvalidConnection unable to open a connection to the given connection string + // 'ShellDescriptorDocumentFound' indicates that the connection string was valid and the document table exists with at least one entry of shell-descriptor document. + ShellDescriptorDocumentFound, + + // 'InvalidConnection' unable to open a connection to the given connection string. InvalidConnection, - // UnsupportedProvider indicated invalid or unsupported database provider + // 'UnsupportedProvider' indicated invalid or unsupported database provider. UnsupportedProvider } diff --git a/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs b/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs index 1ee7a2aa9b6..45e16ffcd10 100644 --- a/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs +++ b/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs @@ -50,7 +50,7 @@ public async Task ValidateAsync(string databaseProv if (provider != null && !provider.HasConnectionString) { - return DbConnectionValidatorResult.DocumentNotFound; + return DbConnectionValidatorResult.DocumentTableNotFound; } if (String.IsNullOrWhiteSpace(connectionString)) @@ -80,25 +80,31 @@ public async Task ValidateAsync(string databaseProv using var result = await selectCommand.ExecuteReaderAsync(); - // at this point the query succeeded and the table exists - return DbConnectionValidatorResult.DocumentFound; + // At this point, the query work and the 'Document' table exists. + if (result.HasRows) + { + // At this point we know that the Document table and the ShellDescriptor record exists. + return DbConnectionValidatorResult.ShellDescriptorDocumentFound; + } + + // At this point the Document table exists with no ShellDescriptor document. + return DbConnectionValidatorResult.DocumentTableFound; } catch { - // at this point we know that the document table does not exist - - return DbConnectionValidatorResult.DocumentNotFound; + // At this point we know that the document table does not exist. + return DbConnectionValidatorResult.DocumentTableNotFound; } } private ISqlBuilder GetSelectBuilderForDocumentTable(string tablePrefix, DatabaseProviderName providerName) { var selectBuilder = GetSqlBuilder(providerName, tablePrefix); - selectBuilder.Select(); selectBuilder.AddSelector("*"); selectBuilder.Table(_tableNameConvention.GetDocumentTable()); selectBuilder.Take("1"); + selectBuilder.WhereAnd("Type = 'OrchardCore.Shells.Database.Models.DatabaseShellsSettings, OrchardCore.Infrastructure'"); return selectBuilder; } @@ -111,7 +117,7 @@ private static IConnectionFactory GetFactory(DatabaseProviderName providerName, DatabaseProviderName.MySql => new DbConnectionFactory(connectionString), DatabaseProviderName.Sqlite => new DbConnectionFactory(connectionString), DatabaseProviderName.Postgres => new DbConnectionFactory(connectionString), - _ => throw new ArgumentOutOfRangeException("Unsupported Database Provider"), + _ => throw new ArgumentOutOfRangeException(nameof(providerName), "Unsupported Database Provider"), }; } @@ -123,7 +129,7 @@ private ISqlBuilder GetSqlBuilder(DatabaseProviderName providerName, string tabl DatabaseProviderName.MySql => new MySqlDialect(), DatabaseProviderName.Sqlite => new SqliteDialect(), DatabaseProviderName.Postgres => new PostgreSqlDialect(), - _ => throw new ArgumentOutOfRangeException("Unsupported Database Provider"), + _ => throw new ArgumentOutOfRangeException(nameof(providerName), "Unsupported Database Provider"), }; var prefix = String.Empty; diff --git a/src/OrchardCore/OrchardCore.Infrastructure/Shells.Database/Configuration/DatabaseShellsStorageOptions.cs b/src/OrchardCore/OrchardCore.Infrastructure/Shells.Database/Configuration/DatabaseShellsStorageOptions.cs index 7e6ef02305b..a6b6c0ea45f 100644 --- a/src/OrchardCore/OrchardCore.Infrastructure/Shells.Database/Configuration/DatabaseShellsStorageOptions.cs +++ b/src/OrchardCore/OrchardCore.Infrastructure/Shells.Database/Configuration/DatabaseShellsStorageOptions.cs @@ -1,9 +1,11 @@ +using OrchardCore.Data; + namespace OrchardCore.Shells.Database.Configuration { public class DatabaseShellsStorageOptions { public bool MigrateFromFiles { get; set; } - public string DatabaseProvider { get; set; } + public DatabaseProviderName DatabaseProvider { get; set; } public string ConnectionString { get; set; } public string TablePrefix { get; set; } } diff --git a/src/OrchardCore/OrchardCore.Infrastructure/Shells.Database/Extensions/DatabaseShellContextFactoryExtensions.cs b/src/OrchardCore/OrchardCore.Infrastructure/Shells.Database/Extensions/DatabaseShellContextFactoryExtensions.cs index 78ff11d4a32..4997bf81abd 100644 --- a/src/OrchardCore/OrchardCore.Infrastructure/Shells.Database/Extensions/DatabaseShellContextFactoryExtensions.cs +++ b/src/OrchardCore/OrchardCore.Infrastructure/Shells.Database/Extensions/DatabaseShellContextFactoryExtensions.cs @@ -1,5 +1,6 @@ using System; using System.Threading.Tasks; +using OrchardCore.Data; using OrchardCore.Environment.Shell; using OrchardCore.Environment.Shell.Builders; using OrchardCore.Environment.Shell.Descriptor.Models; @@ -12,7 +13,7 @@ public static class DatabaseShellContextFactoryExtensions { internal static Task GetDatabaseContextAsync(this IShellContextFactory shellContextFactory, DatabaseShellsStorageOptions options) { - if (options.DatabaseProvider == null) + if (options.DatabaseProvider == DatabaseProviderName.None) { throw new ArgumentNullException(nameof(options.DatabaseProvider), "The 'OrchardCore.Shells.Database' configuration section should define a 'DatabaseProvider'"); @@ -24,7 +25,7 @@ internal static Task GetDatabaseContextAsync(this IShellContextFac State = TenantState.Running }; - settings["DatabaseProvider"] = options.DatabaseProvider; + settings["DatabaseProvider"] = options.DatabaseProvider.ToString(); settings["ConnectionString"] = options.ConnectionString; settings["TablePrefix"] = options.TablePrefix; diff --git a/src/OrchardCore/OrchardCore.Setup.Core/SetupService.cs b/src/OrchardCore/OrchardCore.Setup.Core/SetupService.cs index 81bb363cd6c..fa1a5d3cead 100644 --- a/src/OrchardCore/OrchardCore.Setup.Core/SetupService.cs +++ b/src/OrchardCore/OrchardCore.Setup.Core/SetupService.cs @@ -181,7 +181,7 @@ private async Task SetupInternalAsync(SetupContext context) case DbConnectionValidatorResult.InvalidConnection: context.Errors.Add(String.Empty, S["The provided connection string is invalid or server is unreachable."]); break; - case DbConnectionValidatorResult.DocumentFound: + case DbConnectionValidatorResult.DocumentTableFound: context.Errors.Add(String.Empty, S["The provided database table is already in use."]); break; } From 001d717938ef4054056f3cfbc71cb2ec7aa8a476 Mon Sep 17 00:00:00 2001 From: Mike Alhayek Date: Mon, 5 Sep 2022 18:58:54 -0700 Subject: [PATCH 02/15] Update DbConnectionValidatorResult comments --- .../DbConnectionValidatorResult.cs | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/OrchardCore/OrchardCore.Data.YesSql.Abstractions/DbConnectionValidatorResult.cs b/src/OrchardCore/OrchardCore.Data.YesSql.Abstractions/DbConnectionValidatorResult.cs index 9e90c6c12d2..bfd1a4a998a 100644 --- a/src/OrchardCore/OrchardCore.Data.YesSql.Abstractions/DbConnectionValidatorResult.cs +++ b/src/OrchardCore/OrchardCore.Data.YesSql.Abstractions/DbConnectionValidatorResult.cs @@ -1,25 +1,21 @@ namespace OrchardCore.Data; +/// +/// 'Unknown' indicates that the connection string status is unknown or was not validated. +/// 'NoProvider' indicated that the database provider is missing. +/// 'DocumentTableNotFound' indicates that the connection string was valid, while the Document table does not exists. +/// 'DocumentFound' indicates that the connection string was valid, while the Document table exists. +/// 'ShellDescriptorDocumentFound' indicates that the connection string was valid and the document table exists with at least one shell-descriptor document. +/// 'InvalidConnection' unable to open a connection to the given connection string. +/// 'UnsupportedProvider' indicates invalid or unsupported database provider. +/// public enum DbConnectionValidatorResult { - // 'Unknown' indicates that the connection string status is unknown or was not yet validated. Unknown, - - // 'NoProvider' indicated that the provider is missing. NoProvider, - - // 'DocumentTableNotFound' indicates that the connection string was valid, yet the Document table does not exist. DocumentTableNotFound, - - // 'DocumentFound' indicates that the connection string was valid, yet the Document table exist. DocumentTableFound, - - // 'ShellDescriptorDocumentFound' indicates that the connection string was valid and the document table exists with at least one entry of shell-descriptor document. ShellDescriptorDocumentFound, - - // 'InvalidConnection' unable to open a connection to the given connection string. InvalidConnection, - - // 'UnsupportedProvider' indicated invalid or unsupported database provider. UnsupportedProvider } From 19cd9bb7253bcd503648d0818597d10984a6dff6 Mon Sep 17 00:00:00 2001 From: Mike Alhayek Date: Tue, 6 Sep 2022 08:20:09 -0700 Subject: [PATCH 03/15] Update the Validator logic --- .../DbConnectionValidatorResult.cs | 37 ++++++++++++++----- .../DbConnectionValidator.cs | 5 ++- .../OrchardCore.Setup.Core/SetupService.cs | 2 +- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/OrchardCore/OrchardCore.Data.YesSql.Abstractions/DbConnectionValidatorResult.cs b/src/OrchardCore/OrchardCore.Data.YesSql.Abstractions/DbConnectionValidatorResult.cs index bfd1a4a998a..82d5ab8f8a3 100644 --- a/src/OrchardCore/OrchardCore.Data.YesSql.Abstractions/DbConnectionValidatorResult.cs +++ b/src/OrchardCore/OrchardCore.Data.YesSql.Abstractions/DbConnectionValidatorResult.cs @@ -1,21 +1,40 @@ namespace OrchardCore.Data; -/// -/// 'Unknown' indicates that the connection string status is unknown or was not validated. -/// 'NoProvider' indicated that the database provider is missing. -/// 'DocumentTableNotFound' indicates that the connection string was valid, while the Document table does not exists. -/// 'DocumentFound' indicates that the connection string was valid, while the Document table exists. -/// 'ShellDescriptorDocumentFound' indicates that the connection string was valid and the document table exists with at least one shell-descriptor document. -/// 'InvalidConnection' unable to open a connection to the given connection string. -/// 'UnsupportedProvider' indicates invalid or unsupported database provider. -/// public enum DbConnectionValidatorResult { + /// + /// 'Unknown' indicates that the connection string status is unknown or was not validated. + /// Unknown, + + /// + /// 'NoProvider' indicated that the database provider is missing. + /// NoProvider, + + /// + /// 'DocumentTableNotFound' indicates that the connection string was valid, while the Document table does not exists. + /// DocumentTableNotFound, + + /// + /// 'DocumentTableFound' indicates that the connection string was valid, while the Document table exists. + /// DocumentTableFound, + + /// + /// 'ShellDescriptorDocumentFound' indicates that the connection string was valid and the document table exists with at least one shell-descriptor document. + /// This also means that the Document table is used by a tenant. + /// ShellDescriptorDocumentFound, + + /// + /// 'InvalidConnection' unable to open a connection to the given connection string. + /// InvalidConnection, + + /// + /// 'UnsupportedProvider' indicates invalid or unsupported database provider. + /// UnsupportedProvider } diff --git a/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs b/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs index 45e16ffcd10..ab5edc2d62a 100644 --- a/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs +++ b/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs @@ -8,6 +8,7 @@ using MySqlConnector; using Npgsql; using OrchardCore.Data.YesSql.Abstractions; +using OrchardCore.Environment.Shell.Descriptor.Models; using YesSql; using YesSql.Provider.MySql; using YesSql.Provider.PostgreSql; @@ -84,10 +85,12 @@ public async Task ValidateAsync(string databaseProv if (result.HasRows) { // At this point we know that the Document table and the ShellDescriptor record exists. + // This also means that this table is used for a tenant. return DbConnectionValidatorResult.ShellDescriptorDocumentFound; } // At this point the Document table exists with no ShellDescriptor document. + // This also means that this table is used for other purposes that a tenant (ex., Database Shells Configuration.) return DbConnectionValidatorResult.DocumentTableFound; } catch @@ -103,8 +106,8 @@ private ISqlBuilder GetSelectBuilderForDocumentTable(string tablePrefix, Databas selectBuilder.Select(); selectBuilder.AddSelector("*"); selectBuilder.Table(_tableNameConvention.GetDocumentTable()); + selectBuilder.WhereAnd($"Type = '{typeof(ShellDescriptor).FullName}, {typeof(ShellDescriptor).Assembly.GetName().Name}'"); selectBuilder.Take("1"); - selectBuilder.WhereAnd("Type = 'OrchardCore.Shells.Database.Models.DatabaseShellsSettings, OrchardCore.Infrastructure'"); return selectBuilder; } diff --git a/src/OrchardCore/OrchardCore.Setup.Core/SetupService.cs b/src/OrchardCore/OrchardCore.Setup.Core/SetupService.cs index fa1a5d3cead..c40eab81f19 100644 --- a/src/OrchardCore/OrchardCore.Setup.Core/SetupService.cs +++ b/src/OrchardCore/OrchardCore.Setup.Core/SetupService.cs @@ -181,7 +181,7 @@ private async Task SetupInternalAsync(SetupContext context) case DbConnectionValidatorResult.InvalidConnection: context.Errors.Add(String.Empty, S["The provided connection string is invalid or server is unreachable."]); break; - case DbConnectionValidatorResult.DocumentTableFound: + case DbConnectionValidatorResult.ShellDescriptorDocumentFound: context.Errors.Add(String.Empty, S["The provided database table is already in use."]); break; } From 7afd13bb7f650d4ecee43b0f10b4f042bf8fbbb2 Mon Sep 17 00:00:00 2001 From: Mike Alhayek Date: Tue, 6 Sep 2022 10:55:59 -0700 Subject: [PATCH 04/15] Update comment blocks for DbConnectionValidatorResult --- .../DbConnectionValidatorResult.cs | 16 ++++++++-------- .../DbConnectionValidator.cs | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/OrchardCore/OrchardCore.Data.YesSql.Abstractions/DbConnectionValidatorResult.cs b/src/OrchardCore/OrchardCore.Data.YesSql.Abstractions/DbConnectionValidatorResult.cs index 82d5ab8f8a3..b0de5817956 100644 --- a/src/OrchardCore/OrchardCore.Data.YesSql.Abstractions/DbConnectionValidatorResult.cs +++ b/src/OrchardCore/OrchardCore.Data.YesSql.Abstractions/DbConnectionValidatorResult.cs @@ -3,38 +3,38 @@ namespace OrchardCore.Data; public enum DbConnectionValidatorResult { /// - /// 'Unknown' indicates that the connection string status is unknown or was not validated. + /// The connection string status is unknown or was not validated. /// Unknown, /// - /// 'NoProvider' indicated that the database provider is missing. + /// The database provider is missing. /// NoProvider, /// - /// 'DocumentTableNotFound' indicates that the connection string was valid, while the Document table does not exists. + /// The connection string is valid. But, the Document table does not exists. /// DocumentTableNotFound, /// - /// 'DocumentTableFound' indicates that the connection string was valid, while the Document table exists. + /// The connection string is valid and the Document table exists. /// DocumentTableFound, /// - /// 'ShellDescriptorDocumentFound' indicates that the connection string was valid and the document table exists with at least one shell-descriptor document. - /// This also means that the Document table is used by a tenant. + /// The connection string is valid and the Document table exists with at least one shell-descriptor document. + /// This also means that the Document table is used by an existing tenant. /// ShellDescriptorDocumentFound, /// - /// 'InvalidConnection' unable to open a connection to the given connection string. + /// Unable to open a connection to the given database connection string. /// InvalidConnection, /// - /// 'UnsupportedProvider' indicates invalid or unsupported database provider. + /// Invalid or unsupported database provider. /// UnsupportedProvider } diff --git a/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs b/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs index ab5edc2d62a..00132f7ca2b 100644 --- a/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs +++ b/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs @@ -120,7 +120,7 @@ private static IConnectionFactory GetFactory(DatabaseProviderName providerName, DatabaseProviderName.MySql => new DbConnectionFactory(connectionString), DatabaseProviderName.Sqlite => new DbConnectionFactory(connectionString), DatabaseProviderName.Postgres => new DbConnectionFactory(connectionString), - _ => throw new ArgumentOutOfRangeException(nameof(providerName), "Unsupported Database Provider"), + _ => throw new ArgumentOutOfRangeException(nameof(providerName), "Unsupported database provider"), }; } @@ -132,7 +132,7 @@ private ISqlBuilder GetSqlBuilder(DatabaseProviderName providerName, string tabl DatabaseProviderName.MySql => new MySqlDialect(), DatabaseProviderName.Sqlite => new SqliteDialect(), DatabaseProviderName.Postgres => new PostgreSqlDialect(), - _ => throw new ArgumentOutOfRangeException(nameof(providerName), "Unsupported Database Provider"), + _ => throw new ArgumentOutOfRangeException(nameof(providerName), "Unsupported database provider"), }; var prefix = String.Empty; From 2b690a263cfece68d60bc0d966382827cf903837 Mon Sep 17 00:00:00 2001 From: Mike Alhayek Date: Tue, 6 Sep 2022 10:57:59 -0700 Subject: [PATCH 05/15] Update the comment block --- .../DbConnectionValidatorResult.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OrchardCore/OrchardCore.Data.YesSql.Abstractions/DbConnectionValidatorResult.cs b/src/OrchardCore/OrchardCore.Data.YesSql.Abstractions/DbConnectionValidatorResult.cs index b0de5817956..33f435b46f7 100644 --- a/src/OrchardCore/OrchardCore.Data.YesSql.Abstractions/DbConnectionValidatorResult.cs +++ b/src/OrchardCore/OrchardCore.Data.YesSql.Abstractions/DbConnectionValidatorResult.cs @@ -34,7 +34,7 @@ public enum DbConnectionValidatorResult InvalidConnection, /// - /// Invalid or unsupported database provider. + /// Unsupported database provider. /// UnsupportedProvider } From c4a2b9c2b59336dc28afd940bc923941e3e8db0f Mon Sep 17 00:00:00 2001 From: Mike Alhayek Date: Wed, 7 Sep 2022 09:37:25 -0700 Subject: [PATCH 06/15] Add database provider exception check --- .../DbConnectionValidatorResult.cs | 3 ++ .../DbConnectionValidator.cs | 46 ++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/OrchardCore/OrchardCore.Data.YesSql.Abstractions/DbConnectionValidatorResult.cs b/src/OrchardCore/OrchardCore.Data.YesSql.Abstractions/DbConnectionValidatorResult.cs index 33f435b46f7..0fe67a1ac08 100644 --- a/src/OrchardCore/OrchardCore.Data.YesSql.Abstractions/DbConnectionValidatorResult.cs +++ b/src/OrchardCore/OrchardCore.Data.YesSql.Abstractions/DbConnectionValidatorResult.cs @@ -1,5 +1,8 @@ namespace OrchardCore.Data; +/// +/// The result from validating a database connection using +/// public enum DbConnectionValidatorResult { /// diff --git a/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs b/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs index 00132f7ca2b..09ceb5cb734 100644 --- a/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs +++ b/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs @@ -93,6 +93,48 @@ public async Task ValidateAsync(string databaseProv // This also means that this table is used for other purposes that a tenant (ex., Database Shells Configuration.) return DbConnectionValidatorResult.DocumentTableFound; } + catch (SqlException e) + { + for (var i = 0; i < e.Errors.Count; i++) + { + if (e.Errors[i].Number == 207) + { + // This means that the table exists but some expected columns do not exists. + // This likely to mean that the the table was not created using YesSql. + return DbConnectionValidatorResult.DocumentTableFound; + } + else if (e.Errors[i].Number == 208) + { + return DbConnectionValidatorResult.DocumentTableNotFound; + } + } + + return DbConnectionValidatorResult.InvalidConnection; + } + catch (MySqlException e) + { + return e.ErrorCode switch + { + MySqlErrorCode.NoSuchTable => DbConnectionValidatorResult.DocumentTableNotFound, + // This means that the table exists but some expected columns do not exists. + // This likely to mean that the the table was not created using YesSql. + MySqlErrorCode.BadFieldError => DbConnectionValidatorResult.DocumentTableFound, + _ => DbConnectionValidatorResult.InvalidConnection, + }; + } + catch (PostgresException e) + { + return e.SqlState switch + { + //https://www.postgresql.org/docs/current/errcodes-appendix.html + // 'undefined_table' + "42P01" => DbConnectionValidatorResult.DocumentTableNotFound, + + // 'undefined_column' this likely to mean that the the table was not created using YesSql. + "42703" => DbConnectionValidatorResult.DocumentTableFound, + _ => DbConnectionValidatorResult.InvalidConnection + }; + } catch { // At this point we know that the document table does not exist. @@ -104,7 +146,9 @@ private ISqlBuilder GetSelectBuilderForDocumentTable(string tablePrefix, Databas { var selectBuilder = GetSqlBuilder(providerName, tablePrefix); selectBuilder.Select(); - selectBuilder.AddSelector("*"); + // Here we explicitly select the expected column used by YesSql instead of '*' + // to ensure that this table can be consumed by YesSql. + selectBuilder.AddSelector("Id, Type, Content, Version"); selectBuilder.Table(_tableNameConvention.GetDocumentTable()); selectBuilder.WhereAnd($"Type = '{typeof(ShellDescriptor).FullName}, {typeof(ShellDescriptor).Assembly.GetName().Name}'"); selectBuilder.Take("1"); From b12df41dc0b8a04a3062b63c21da4db3110fb2c9 Mon Sep 17 00:00:00 2001 From: jtkech Date: Thu, 8 Sep 2022 03:26:00 +0200 Subject: [PATCH 07/15] Updates and tweaks --- .../Services/TenantValidator.cs | 11 ++- .../DbConnectionValidatorResult.cs | 13 ++- .../IDbConnectionValidator.cs | 2 +- .../DbConnectionValidator.cs | 90 ++++++++----------- .../OrchardCore.Setup.Core/SetupService.cs | 6 +- 5 files changed, 54 insertions(+), 68 deletions(-) diff --git a/src/OrchardCore.Modules/OrchardCore.Tenants/Services/TenantValidator.cs b/src/OrchardCore.Modules/OrchardCore.Tenants/Services/TenantValidator.cs index 931787130ed..6cf29de18ef 100644 --- a/src/OrchardCore.Modules/OrchardCore.Tenants/Services/TenantValidator.cs +++ b/src/OrchardCore.Modules/OrchardCore.Tenants/Services/TenantValidator.cs @@ -91,7 +91,7 @@ public async Task> ValidateAsync(TenantViewModel model) } } - await AssertConnectionValidityAndApplyErrorsAsync(model.DatabaseProvider, model.ConnectionString, model.TablePrefix, errors); + await AssertConnectionValidityAndApplyErrorsAsync(model.DatabaseProvider, model.ConnectionString, model.TablePrefix, errors, shellSettings?.IsDefaultShell() == true); } else { @@ -100,16 +100,16 @@ public async Task> ValidateAsync(TenantViewModel model) // While the tenant is in Uninitialized state, we still are able to change the database settings. // Let's validate the database for assurance. - await AssertConnectionValidityAndApplyErrorsAsync(model.DatabaseProvider, model.ConnectionString, model.TablePrefix, errors); + await AssertConnectionValidityAndApplyErrorsAsync(model.DatabaseProvider, model.ConnectionString, model.TablePrefix, errors, shellSettings?.IsDefaultShell() == true); } } return errors; } - private async Task AssertConnectionValidityAndApplyErrorsAsync(string databaseProvider, string connectionString, string tablePrefix, List errors) + private async Task AssertConnectionValidityAndApplyErrorsAsync(string databaseProvider, string connectionString, string tablePrefix, List errors, bool isDefaultShell) { - switch (await _dbConnectionValidator.ValidateAsync(databaseProvider, connectionString, tablePrefix)) + switch (await _dbConnectionValidator.ValidateAsync(databaseProvider, connectionString, tablePrefix, isDefaultShell)) { case DbConnectionValidatorResult.UnsupportedProvider: errors.Add(new ModelError(nameof(TenantViewModel.DatabaseProvider), S["The provided database provider is not supported."])); @@ -117,9 +117,8 @@ private async Task AssertConnectionValidityAndApplyErrorsAsync(string databasePr case DbConnectionValidatorResult.InvalidConnection: errors.Add(new ModelError(nameof(TenantViewModel.ConnectionString), S["The provided connection string is invalid or server is unreachable."])); break; - case DbConnectionValidatorResult.ShellDescriptorDocumentFound: case DbConnectionValidatorResult.DocumentTableFound: - errors.Add(new ModelError(nameof(TenantViewModel.TablePrefix), S["The provided table prefix already exists."])); + errors.Add(new ModelError(nameof(TenantViewModel.TablePrefix), S["The provided database and table prefix are already in use."])); break; } } diff --git a/src/OrchardCore/OrchardCore.Data.YesSql.Abstractions/DbConnectionValidatorResult.cs b/src/OrchardCore/OrchardCore.Data.YesSql.Abstractions/DbConnectionValidatorResult.cs index 0fe67a1ac08..88c49d244f1 100644 --- a/src/OrchardCore/OrchardCore.Data.YesSql.Abstractions/DbConnectionValidatorResult.cs +++ b/src/OrchardCore/OrchardCore.Data.YesSql.Abstractions/DbConnectionValidatorResult.cs @@ -1,7 +1,7 @@ namespace OrchardCore.Data; /// -/// The result from validating a database connection using +/// The result from validating a database connection using . /// public enum DbConnectionValidatorResult { @@ -16,23 +16,22 @@ public enum DbConnectionValidatorResult NoProvider, /// - /// The connection string is valid. But, the Document table does not exists. + /// The connection string is valid and the 'Document' table does not exists. /// DocumentTableNotFound, /// - /// The connection string is valid and the Document table exists. + /// The connection string is valid and the 'Document' table exists. /// DocumentTableFound, /// - /// The connection string is valid and the Document table exists with at least one shell-descriptor document. - /// This also means that the Document table is used by an existing tenant. + /// The 'Document' table exists with no 'ShellDescriptor' document. /// - ShellDescriptorDocumentFound, + ShellDescriptorDocumentNotFound, /// - /// Unable to open a connection to the given database connection string. + /// Unable to open a connection with the given database connection string. /// InvalidConnection, diff --git a/src/OrchardCore/OrchardCore.Data.YesSql.Abstractions/IDbConnectionValidator.cs b/src/OrchardCore/OrchardCore.Data.YesSql.Abstractions/IDbConnectionValidator.cs index 6e4f42716b7..070a4ea02e3 100644 --- a/src/OrchardCore/OrchardCore.Data.YesSql.Abstractions/IDbConnectionValidator.cs +++ b/src/OrchardCore/OrchardCore.Data.YesSql.Abstractions/IDbConnectionValidator.cs @@ -4,5 +4,5 @@ namespace OrchardCore.Data; public interface IDbConnectionValidator { - Task ValidateAsync(string databaseProvider, string connectionString, string tablePrefix); + Task ValidateAsync(string databaseProvider, string connectionString, string tablePrefix, bool isDefaultShell); } diff --git a/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs b/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs index 09ceb5cb734..bae3198f2b9 100644 --- a/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs +++ b/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs @@ -35,7 +35,7 @@ IOptions yesSqlOptions _yesSqlOptions = yesSqlOptions.Value; } - public async Task ValidateAsync(string databaseProvider, string connectionString, string tablePrefix) + public async Task ValidateAsync(string databaseProvider, string connectionString, string tablePrefix, bool isDefaultShell) { if (String.IsNullOrWhiteSpace(databaseProvider)) { @@ -73,82 +73,70 @@ public async Task ValidateAsync(string databaseProv } var selectBuilder = GetSelectBuilderForDocumentTable(tablePrefix, providerName); - try { var selectCommand = connection.CreateCommand(); selectCommand.CommandText = selectBuilder.ToSqlString(); using var result = await selectCommand.ExecuteReaderAsync(); - - // At this point, the query work and the 'Document' table exists. - if (result.HasRows) + if (!isDefaultShell) { - // At this point we know that the Document table and the ShellDescriptor record exists. - // This also means that this table is used for a tenant. - return DbConnectionValidatorResult.ShellDescriptorDocumentFound; + // The 'Document' table exists. + return DbConnectionValidatorResult.DocumentTableFound; } - // At this point the Document table exists with no ShellDescriptor document. - // This also means that this table is used for other purposes that a tenant (ex., Database Shells Configuration.) - return DbConnectionValidatorResult.DocumentTableFound; - } - catch (SqlException e) - { - for (var i = 0; i < e.Errors.Count; i++) + var columns = Enumerable.Range(0, result.FieldCount).Select(result.GetName); + if (!columns.Any(c => c == "Type") || !columns.Any(c => c == "Content") || !columns.Any(c => c == "Version")) { - if (e.Errors[i].Number == 207) - { - // This means that the table exists but some expected columns do not exists. - // This likely to mean that the the table was not created using YesSql. - return DbConnectionValidatorResult.DocumentTableFound; - } - else if (e.Errors[i].Number == 208) - { - return DbConnectionValidatorResult.DocumentTableNotFound; - } + // The 'Document' table exists with another schema. + return DbConnectionValidatorResult.DocumentTableFound; } - - return DbConnectionValidatorResult.InvalidConnection; } - catch (MySqlException e) + catch { - return e.ErrorCode switch - { - MySqlErrorCode.NoSuchTable => DbConnectionValidatorResult.DocumentTableNotFound, - // This means that the table exists but some expected columns do not exists. - // This likely to mean that the the table was not created using YesSql. - MySqlErrorCode.BadFieldError => DbConnectionValidatorResult.DocumentTableFound, - _ => DbConnectionValidatorResult.InvalidConnection, - }; + // The 'Document' table does not exist. + return DbConnectionValidatorResult.DocumentTableNotFound; } - catch (PostgresException e) + + selectBuilder = GetSelectBuilderForShellDescriptorDocument(tablePrefix, providerName); + try { - return e.SqlState switch + var selectCommand = connection.CreateCommand(); + selectCommand.CommandText = selectBuilder.ToSqlString(); + + using var result = await selectCommand.ExecuteReaderAsync(); + if (!result.HasRows) { - //https://www.postgresql.org/docs/current/errcodes-appendix.html - // 'undefined_table' - "42P01" => DbConnectionValidatorResult.DocumentTableNotFound, - - // 'undefined_column' this likely to mean that the the table was not created using YesSql. - "42703" => DbConnectionValidatorResult.DocumentTableFound, - _ => DbConnectionValidatorResult.InvalidConnection - }; + // The 'Document' table exists with no 'ShellDescriptor' document. + return DbConnectionValidatorResult.ShellDescriptorDocumentNotFound; + } } catch { - // At this point we know that the document table does not exist. - return DbConnectionValidatorResult.DocumentTableNotFound; } + + // The 'Document' table exists. + return DbConnectionValidatorResult.DocumentTableFound; } private ISqlBuilder GetSelectBuilderForDocumentTable(string tablePrefix, DatabaseProviderName providerName) { var selectBuilder = GetSqlBuilder(providerName, tablePrefix); + + selectBuilder.Select(); + selectBuilder.Selector("*"); + selectBuilder.Table(_tableNameConvention.GetDocumentTable()); + selectBuilder.Take("1"); + + return selectBuilder; + } + + private ISqlBuilder GetSelectBuilderForShellDescriptorDocument(string tablePrefix, DatabaseProviderName providerName) + { + var selectBuilder = GetSqlBuilder(providerName, tablePrefix); + selectBuilder.Select(); - // Here we explicitly select the expected column used by YesSql instead of '*' - // to ensure that this table can be consumed by YesSql. - selectBuilder.AddSelector("Id, Type, Content, Version"); + selectBuilder.Selector("*"); selectBuilder.Table(_tableNameConvention.GetDocumentTable()); selectBuilder.WhereAnd($"Type = '{typeof(ShellDescriptor).FullName}, {typeof(ShellDescriptor).Assembly.GetName().Name}'"); selectBuilder.Take("1"); diff --git a/src/OrchardCore/OrchardCore.Setup.Core/SetupService.cs b/src/OrchardCore/OrchardCore.Setup.Core/SetupService.cs index c40eab81f19..db3c6ac3f8a 100644 --- a/src/OrchardCore/OrchardCore.Setup.Core/SetupService.cs +++ b/src/OrchardCore/OrchardCore.Setup.Core/SetupService.cs @@ -170,7 +170,7 @@ private async Task SetupInternalAsync(SetupContext context) shellSettings["TablePrefix"] = context.Properties.TryGetValue(SetupConstants.DatabaseTablePrefix, out var databaseTablePrefix) ? databaseTablePrefix?.ToString() : String.Empty; } - switch (await _dbConnectionValidator.ValidateAsync(shellSettings["DatabaseProvider"], shellSettings["ConnectionString"], shellSettings["TablePrefix"])) + switch (await _dbConnectionValidator.ValidateAsync(shellSettings["DatabaseProvider"], shellSettings["ConnectionString"], shellSettings["TablePrefix"], shellSettings.IsDefaultShell())) { case DbConnectionValidatorResult.NoProvider: context.Errors.Add(String.Empty, S["DatabaseProvider setting is required."]); @@ -181,8 +181,8 @@ private async Task SetupInternalAsync(SetupContext context) case DbConnectionValidatorResult.InvalidConnection: context.Errors.Add(String.Empty, S["The provided connection string is invalid or server is unreachable."]); break; - case DbConnectionValidatorResult.ShellDescriptorDocumentFound: - context.Errors.Add(String.Empty, S["The provided database table is already in use."]); + case DbConnectionValidatorResult.DocumentTableFound: + context.Errors.Add(String.Empty, S["The provided database and table prefix are already in use."]); break; } From 5b6a5fdeb9185685f7daae76702f495759b6fa84 Mon Sep 17 00:00:00 2001 From: jtkech Date: Thu, 8 Sep 2022 03:38:43 +0200 Subject: [PATCH 08/15] Fix CI Build --- .../OrchardCore.Tenants/Services/TenantValidatorTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/OrchardCore.Tests/Modules/OrchardCore.Tenants/Services/TenantValidatorTests.cs b/test/OrchardCore.Tests/Modules/OrchardCore.Tenants/Services/TenantValidatorTests.cs index ddae5327993..a40db947ba0 100644 --- a/test/OrchardCore.Tests/Modules/OrchardCore.Tenants/Services/TenantValidatorTests.cs +++ b/test/OrchardCore.Tests/Modules/OrchardCore.Tenants/Services/TenantValidatorTests.cs @@ -122,7 +122,7 @@ private static TenantValidator CreateTenantValidator(bool defaultTenant = true) : new ShellSettings(); var connectionFactory = new Mock(); - connectionFactory.Setup(l => l.ValidateAsync(shellSettings["ProviderName"], shellSettings["ConnectionName"], shellSettings["TablePrefix"])); + connectionFactory.Setup(l => l.ValidateAsync(shellSettings["ProviderName"], shellSettings["ConnectionName"], shellSettings["TablePrefix"], shellSettings.IsDefaultShell())); return new TenantValidator( ShellHost, From cfb5a5b22484dd0acf483f5e379137cf429ad04c Mon Sep 17 00:00:00 2001 From: jtkech Date: Thu, 8 Sep 2022 04:42:00 +0200 Subject: [PATCH 09/15] Tweak --- .../OrchardCore.Data.YesSql/DbConnectionValidator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs b/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs index bae3198f2b9..7487299eac4 100644 --- a/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs +++ b/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs @@ -86,7 +86,7 @@ public async Task ValidateAsync(string databaseProv } var columns = Enumerable.Range(0, result.FieldCount).Select(result.GetName); - if (!columns.Any(c => c == "Type") || !columns.Any(c => c == "Content") || !columns.Any(c => c == "Version")) + if (!columns.Any(c => c == "Type"|| c == "Content" || c == "Version")) { // The 'Document' table exists with another schema. return DbConnectionValidatorResult.DocumentTableFound; From 5b8d965f959bc69539a34789b267f151f852c526 Mon Sep 17 00:00:00 2001 From: jtkech Date: Thu, 8 Sep 2022 04:44:28 +0200 Subject: [PATCH 10/15] Revert last change --- .../OrchardCore.Data.YesSql/DbConnectionValidator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs b/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs index 7487299eac4..bae3198f2b9 100644 --- a/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs +++ b/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs @@ -86,7 +86,7 @@ public async Task ValidateAsync(string databaseProv } var columns = Enumerable.Range(0, result.FieldCount).Select(result.GetName); - if (!columns.Any(c => c == "Type"|| c == "Content" || c == "Version")) + if (!columns.Any(c => c == "Type") || !columns.Any(c => c == "Content") || !columns.Any(c => c == "Version")) { // The 'Document' table exists with another schema. return DbConnectionValidatorResult.DocumentTableFound; From 128c4161ca943cdf75af9c6351049c5068369360 Mon Sep 17 00:00:00 2001 From: jtkech Date: Thu, 8 Sep 2022 05:57:58 +0200 Subject: [PATCH 11/15] Only one lookup. --- .../OrchardCore.Data.YesSql/DbConnectionValidator.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs b/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs index bae3198f2b9..f1e00864d3c 100644 --- a/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs +++ b/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs @@ -85,8 +85,11 @@ public async Task ValidateAsync(string databaseProv return DbConnectionValidatorResult.DocumentTableFound; } - var columns = Enumerable.Range(0, result.FieldCount).Select(result.GetName); - if (!columns.Any(c => c == "Type") || !columns.Any(c => c == "Content") || !columns.Any(c => c == "Version")) + var columns = Enumerable.Range(0, result.FieldCount) + .Select(result.GetName) + .Where(c => c == "Type" || c == "Content" || c == "Version"); + + if (columns.Count() != 3) { // The 'Document' table exists with another schema. return DbConnectionValidatorResult.DocumentTableFound; From cda0d699460c5cb233bf8b5faa6ff8f23107b911 Mon Sep 17 00:00:00 2001 From: jtkech Date: Thu, 8 Sep 2022 06:43:37 +0200 Subject: [PATCH 12/15] Also check the Id column --- .../OrchardCore.Data.YesSql/DbConnectionValidator.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs b/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs index f1e00864d3c..69a152714d2 100644 --- a/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs +++ b/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs @@ -20,6 +20,8 @@ namespace OrchardCore.Data; public class DbConnectionValidator : IDbConnectionValidator { + private static readonly string[] _requiredDocumentTableColumns = new[] { "Id", "Type", "Content", "Version" }; + private readonly IEnumerable _databaseProviders; private readonly ITableNameConvention _tableNameConvention; private readonly YesSqlOptions _yesSqlOptions; @@ -85,11 +87,12 @@ public async Task ValidateAsync(string databaseProv return DbConnectionValidatorResult.DocumentTableFound; } - var columns = Enumerable.Range(0, result.FieldCount) + var requiredColumnsCount = Enumerable.Range(0, result.FieldCount) .Select(result.GetName) - .Where(c => c == "Type" || c == "Content" || c == "Version"); + .Where(c => _requiredDocumentTableColumns.Contains(c)) + .Count(); - if (columns.Count() != 3) + if (requiredColumnsCount != _requiredDocumentTableColumns.Length) { // The 'Document' table exists with another schema. return DbConnectionValidatorResult.DocumentTableFound; From 917e128a2bf734c66b4ef44848c9a3be36c76cc5 Mon Sep 17 00:00:00 2001 From: jtkech Date: Thu, 8 Sep 2022 22:14:19 +0200 Subject: [PATCH 13/15] Use YesSql 'TypeService' for 'Type' column value --- .../OrchardCore.Data.YesSql/DbConnectionValidator.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs b/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs index 69a152714d2..ae92dd42851 100644 --- a/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs +++ b/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs @@ -14,6 +14,7 @@ using YesSql.Provider.PostgreSql; using YesSql.Provider.Sqlite; using YesSql.Provider.SqlServer; +using YesSql.Services; using YesSql.Sql; namespace OrchardCore.Data; @@ -144,7 +145,7 @@ private ISqlBuilder GetSelectBuilderForShellDescriptorDocument(string tablePrefi selectBuilder.Select(); selectBuilder.Selector("*"); selectBuilder.Table(_tableNameConvention.GetDocumentTable()); - selectBuilder.WhereAnd($"Type = '{typeof(ShellDescriptor).FullName}, {typeof(ShellDescriptor).Assembly.GetName().Name}'"); + selectBuilder.WhereAnd($"Type = '{new TypeService()[typeof(ShellDescriptor)]}'"); selectBuilder.Take("1"); return selectBuilder; From 6b45ab10d8d9533f97d1fae2fbe2885ac5c21ec7 Mon Sep 17 00:00:00 2001 From: jtkech Date: Thu, 8 Sep 2022 22:24:29 +0200 Subject: [PATCH 14/15] Use static variable --- .../OrchardCore.Data.YesSql/DbConnectionValidator.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs b/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs index ae92dd42851..9bffdf0d836 100644 --- a/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs +++ b/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs @@ -22,6 +22,7 @@ namespace OrchardCore.Data; public class DbConnectionValidator : IDbConnectionValidator { private static readonly string[] _requiredDocumentTableColumns = new[] { "Id", "Type", "Content", "Version" }; + private static readonly string _shellDescriptorTypeColumnValue = new TypeService()[typeof(ShellDescriptor)]; private readonly IEnumerable _databaseProviders; private readonly ITableNameConvention _tableNameConvention; @@ -145,7 +146,7 @@ private ISqlBuilder GetSelectBuilderForShellDescriptorDocument(string tablePrefi selectBuilder.Select(); selectBuilder.Selector("*"); selectBuilder.Table(_tableNameConvention.GetDocumentTable()); - selectBuilder.WhereAnd($"Type = '{new TypeService()[typeof(ShellDescriptor)]}'"); + selectBuilder.WhereAnd($"Type = '{_shellDescriptorTypeColumnValue}'"); selectBuilder.Take("1"); return selectBuilder; From a88dcbaf764c2559d12998fae2f8ed7fca93a438 Mon Sep 17 00:00:00 2001 From: jtkech Date: Thu, 8 Sep 2022 22:57:45 +0200 Subject: [PATCH 15/15] Case insensitive check for column names --- .../OrchardCore.Data.YesSql/DbConnectionValidator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs b/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs index 9bffdf0d836..374659aa138 100644 --- a/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs +++ b/src/OrchardCore/OrchardCore.Data.YesSql/DbConnectionValidator.cs @@ -91,7 +91,7 @@ public async Task ValidateAsync(string databaseProv var requiredColumnsCount = Enumerable.Range(0, result.FieldCount) .Select(result.GetName) - .Where(c => _requiredDocumentTableColumns.Contains(c)) + .Where(c => _requiredDocumentTableColumns.Contains(c, StringComparer.OrdinalIgnoreCase)) .Count(); if (requiredColumnsCount != _requiredDocumentTableColumns.Length)