diff --git a/framework/src/Volo.Abp.EntityFrameworkCore.MySQL/Volo/Abp/EntityFrameworkCore/ConnectionStrings/AbpEfCoreMySqlConnectionStringChecker.cs b/framework/src/Volo.Abp.EntityFrameworkCore.MySQL/Volo/Abp/EntityFrameworkCore/ConnectionStrings/AbpEfCoreMySqlConnectionStringChecker.cs new file mode 100644 index 0000000000..75713635fe --- /dev/null +++ b/framework/src/Volo.Abp.EntityFrameworkCore.MySQL/Volo/Abp/EntityFrameworkCore/ConnectionStrings/AbpEfCoreMySqlConnectionStringChecker.cs @@ -0,0 +1,37 @@ +using System; +using System.Threading.Tasks; +using MySqlConnector; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.EntityFrameworkCore.ConnectionStrings; + +[ExposeServices(typeof(IAbpConnectionStringChecker))] +public class AbpEfCoreMySqlConnectionStringChecker : IAbpConnectionStringChecker, ITransientDependency +{ + public virtual async Task CheckAsync(string connectionString) + { + var result = new AbpConnectionStringCheckResult(); + var connString = new MySqlConnectionStringBuilder(connectionString) + { + ConnectionLifeTime = 1 + }; + + var oldDatabaseName = connString.Database; + connString.Database = "mysql"; + + try + { + await using var conn = new MySqlConnection(connString.ConnectionString); + await conn.OpenAsync(); + result.Connected = true; + await conn.ChangeDatabaseAsync(oldDatabaseName); + await conn.CloseAsync(); + result.DatabaseExists = true; + return result; + } + catch (Exception e) + { + return result; + } + } +} diff --git a/framework/src/Volo.Abp.EntityFrameworkCore.Oracle.Devart/Volo/Abp/EntityFrameworkCore/ConnectionStrings/AbpEfCoreOracleDevartConnectionStringChecker.cs b/framework/src/Volo.Abp.EntityFrameworkCore.Oracle.Devart/Volo/Abp/EntityFrameworkCore/ConnectionStrings/AbpEfCoreOracleDevartConnectionStringChecker.cs new file mode 100644 index 0000000000..50441ac25e --- /dev/null +++ b/framework/src/Volo.Abp.EntityFrameworkCore.Oracle.Devart/Volo/Abp/EntityFrameworkCore/ConnectionStrings/AbpEfCoreOracleDevartConnectionStringChecker.cs @@ -0,0 +1,35 @@ +using System; +using System.Threading.Tasks; +using Devart.Data.Oracle; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.EntityFrameworkCore.ConnectionStrings; + +[ExposeServices(typeof(IAbpConnectionStringChecker))] +public class AbpEfCoreOracleDevartConnectionStringChecker : IAbpConnectionStringChecker, ITransientDependency +{ + public virtual async Task CheckAsync(string connectionString) + { + var result = new AbpConnectionStringCheckResult(); + var connString = new OracleConnectionStringBuilder(connectionString) + { + ConnectionTimeout = 1 + }; + + try + { + await using var conn = new OracleConnection(connString.ConnectionString); + await conn.OpenAsync(); + result.Connected = true; + result.DatabaseExists = true; + + await conn.CloseAsync(); + + return result; + } + catch (Exception e) + { + return result; + } + } +} diff --git a/framework/src/Volo.Abp.EntityFrameworkCore.Oracle/Volo/Abp/EntityFrameworkCore/ConnectionStrings/AbpEfCoreOracleConnectionStringChecker.cs b/framework/src/Volo.Abp.EntityFrameworkCore.Oracle/Volo/Abp/EntityFrameworkCore/ConnectionStrings/AbpEfCoreOracleConnectionStringChecker.cs new file mode 100644 index 0000000000..d8ce99f28b --- /dev/null +++ b/framework/src/Volo.Abp.EntityFrameworkCore.Oracle/Volo/Abp/EntityFrameworkCore/ConnectionStrings/AbpEfCoreOracleConnectionStringChecker.cs @@ -0,0 +1,35 @@ +using System; +using System.Threading.Tasks; +using Oracle.ManagedDataAccess.Client; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.EntityFrameworkCore.ConnectionStrings; + +[ExposeServices(typeof(IAbpConnectionStringChecker))] +public class AbpEfCoreOracleConnectionStringChecker : IAbpConnectionStringChecker, ITransientDependency +{ + public virtual async Task CheckAsync(string connectionString) + { + var result = new AbpConnectionStringCheckResult(); + var connString = new OracleConnectionStringBuilder(connectionString) + { + ConnectionTimeout = 1 + }; + + try + { + await using var conn = new OracleConnection(connString.ConnectionString); + await conn.OpenAsync(); + result.Connected = true; + result.DatabaseExists = true; + + await conn.CloseAsync(); + + return result; + } + catch (Exception e) + { + return result; + } + } +} diff --git a/framework/src/Volo.Abp.EntityFrameworkCore.PostgreSql/Volo/Abp/EntityFrameworkCore/ConnectionStrings/AbpEfCoreNpgsqlConnectionStringChecker.cs b/framework/src/Volo.Abp.EntityFrameworkCore.PostgreSql/Volo/Abp/EntityFrameworkCore/ConnectionStrings/AbpEfCoreNpgsqlConnectionStringChecker.cs new file mode 100644 index 0000000000..94f3a5ffee --- /dev/null +++ b/framework/src/Volo.Abp.EntityFrameworkCore.PostgreSql/Volo/Abp/EntityFrameworkCore/ConnectionStrings/AbpEfCoreNpgsqlConnectionStringChecker.cs @@ -0,0 +1,39 @@ +using System; +using System.Threading.Tasks; +using Npgsql; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.EntityFrameworkCore.ConnectionStrings; + +[ExposeServices(typeof(IAbpConnectionStringChecker))] +public class AbpEfCoreNpgsqlConnectionStringChecker : IAbpConnectionStringChecker, ITransientDependency +{ + public virtual async Task CheckAsync(string connectionString) + { + var result = new AbpConnectionStringCheckResult(); + var connString = new NpgsqlConnectionStringBuilder(connectionString) + { + Timeout = 1 + }; + + var oldDatabaseName = connString.Database; + connString.Database = "postgres"; + + try + { + await using var conn = new NpgsqlConnection(connString.ConnectionString); + await conn.OpenAsync(); + result.Connected = true; + await conn.ChangeDatabaseAsync(oldDatabaseName); + result.DatabaseExists = true; + + await conn.CloseAsync(); + + return result; + } + catch (Exception e) + { + return result; + } + } +} diff --git a/framework/src/Volo.Abp.EntityFrameworkCore.SqlServer/Volo/Abp/EntityFrameworkCore/ConnectionStrings/AbpEfCoreSqlServerConnectionStringChecker.cs b/framework/src/Volo.Abp.EntityFrameworkCore.SqlServer/Volo/Abp/EntityFrameworkCore/ConnectionStrings/AbpEfCoreSqlServerConnectionStringChecker.cs new file mode 100644 index 0000000000..4265193faa --- /dev/null +++ b/framework/src/Volo.Abp.EntityFrameworkCore.SqlServer/Volo/Abp/EntityFrameworkCore/ConnectionStrings/AbpEfCoreSqlServerConnectionStringChecker.cs @@ -0,0 +1,37 @@ +using System; +using System.Threading.Tasks; +using Microsoft.Data.SqlClient; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.EntityFrameworkCore.ConnectionStrings; + +[ExposeServices(typeof(IAbpConnectionStringChecker))] +public class AbpEfCoreSqlServerConnectionStringChecker : IAbpConnectionStringChecker, ITransientDependency +{ + public virtual async Task CheckAsync(string connectionString) + { + var result = new AbpConnectionStringCheckResult(); + var connString = new SqlConnectionStringBuilder(connectionString) + { + ConnectTimeout = 1 + }; + + var oldDatabaseName = connString.InitialCatalog; + connString.InitialCatalog = "master"; + + try + { + await using var conn = new SqlConnection(connString.ConnectionString); + await conn.OpenAsync(); + result.Connected = true; + await conn.ChangeDatabaseAsync(oldDatabaseName); + await conn.CloseAsync(); + result.DatabaseExists = true; + return result; + } + catch (Exception e) + { + return result; + } + } +} diff --git a/framework/src/Volo.Abp.EntityFrameworkCore.Sqlite/Volo/Abp/EntityFrameworkCore/ConnectionStrings/AbpEfCoreSqliteConnectionStringChecker.cs b/framework/src/Volo.Abp.EntityFrameworkCore.Sqlite/Volo/Abp/EntityFrameworkCore/ConnectionStrings/AbpEfCoreSqliteConnectionStringChecker.cs new file mode 100644 index 0000000000..c11b4357b8 --- /dev/null +++ b/framework/src/Volo.Abp.EntityFrameworkCore.Sqlite/Volo/Abp/EntityFrameworkCore/ConnectionStrings/AbpEfCoreSqliteConnectionStringChecker.cs @@ -0,0 +1,30 @@ +using System; +using System.Threading.Tasks; +using Microsoft.Data.Sqlite; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.EntityFrameworkCore.ConnectionStrings; + +[ExposeServices(typeof(IAbpConnectionStringChecker))] +public class AbpEfCoreSqliteConnectionStringChecker : IAbpConnectionStringChecker, ITransientDependency +{ + public virtual async Task CheckAsync(string connectionString) + { + var result = new AbpConnectionStringCheckResult(); + + try + { + await using var conn = new SqliteConnection(connectionString); + await conn.OpenAsync(); + result.Connected = true; + result.DatabaseExists = true; + await conn.CloseAsync(); + + return result; + } + catch (Exception e) + { + return result; + } + } +} diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/ConnectionStrings/AbpConnectionStringCheckResult.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/ConnectionStrings/AbpConnectionStringCheckResult.cs new file mode 100644 index 0000000000..53afc000fb --- /dev/null +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/ConnectionStrings/AbpConnectionStringCheckResult.cs @@ -0,0 +1,8 @@ +namespace Volo.Abp.EntityFrameworkCore.ConnectionStrings; + +public class AbpConnectionStringCheckResult +{ + public bool Connected { get; set; } + + public bool DatabaseExists { get; set; } +} diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/ConnectionStrings/IAbpConnectionStringChecker.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/ConnectionStrings/IAbpConnectionStringChecker.cs new file mode 100644 index 0000000000..2870c2103e --- /dev/null +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/ConnectionStrings/IAbpConnectionStringChecker.cs @@ -0,0 +1,8 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.EntityFrameworkCore.ConnectionStrings; + +public interface IAbpConnectionStringChecker +{ + Task CheckAsync(string connectionString); +} diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/ConnectionStrings/AbpConnectionStringChecker_Tests.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/ConnectionStrings/AbpConnectionStringChecker_Tests.cs new file mode 100644 index 0000000000..ef3e37df24 --- /dev/null +++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/ConnectionStrings/AbpConnectionStringChecker_Tests.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; +using Shouldly; +using Xunit; + +namespace Volo.Abp.EntityFrameworkCore.ConnectionStrings; + +public class AbpConnectionStringChecker_Tests : EntityFrameworkCoreTestBase +{ + [Fact] + public async Task IsValidAsync() + { + var connectionStringChecker = GetRequiredService(); + var result = await connectionStringChecker.CheckAsync(@"Data Source=:memory:"); + result.Connected.ShouldBeTrue(); + result.DatabaseExists.ShouldBeTrue(); + } +}