Fixes up the dbconnection checker to work with all supported db types.

This commit is contained in:
Shannon
2014-03-13 20:14:56 +11:00
parent d290ffa306
commit a907b5bdcd
7 changed files with 106 additions and 77 deletions

View File

@@ -0,0 +1,88 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Umbraco.Core.Persistence
{
internal static class DbConnectionExtensions
{
public static DatabaseProviders DetectProviderFromConnectionString(string connString)
{
var builder = new DbConnectionStringBuilder {ConnectionString = connString};
var allKeys = builder.Keys.Cast<string>();
var mySql = new[] {"Server", "Database", "Uid", "Pwd"};
if (mySql.All(x => allKeys.InvariantContains(x)))
{
return DatabaseProviders.MySql;
}
if (allKeys.InvariantContains("Data Source")
//this dictionary is case insensitive
&& builder["Data source"].ToString().InvariantContains(".sdf"))
{
return DatabaseProviders.SqlServerCE;
}
return DatabaseProviders.SqlServer;
}
public static bool IsConnectionAvailable(string connString, DatabaseProviders provider)
{
DbProviderFactory factory;
switch (provider)
{
case DatabaseProviders.SqlServer:
case DatabaseProviders.SqlAzure:
factory = DbProviderFactories.GetFactory("System.Data.SqlClient");
break;
case DatabaseProviders.SqlServerCE:
factory = DbProviderFactories.GetFactory("System.Data.SqlServerCe.4.0");
break;
case DatabaseProviders.MySql:
factory = DbProviderFactories.GetFactory("MySql.Data.MySqlClient");
break;
case DatabaseProviders.PostgreSQL:
case DatabaseProviders.Oracle:
case DatabaseProviders.SQLite:
default:
throw new NotSupportedException("The provider " + provider + " is not supported");
}
var conn = factory.CreateConnection();
if (conn == null)
{
throw new InvalidOperationException("Could not create a connection for provider " + provider);
}
conn.ConnectionString = connString;
using (var connection = conn)
{
return connection.IsAvailable();
}
}
public static bool IsAvailable(this IDbConnection connection)
{
try
{
connection.Open();
connection.Close();
}
catch (SqlException)
{
return false;
}
return true;
}
}
}

View File

@@ -1,38 +0,0 @@
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Umbraco.Core.Persistence
{
//TODO: check if any of this works and for what databse types it works for:
// ref: http://stackoverflow.com/questions/16171144/how-to-check-for-database-availability
internal static class SqlExtensions
{
public static bool IsConnectionAvailable(string connString)
{
using (var connection = new SqlConnection(connString))
{
return connection.IsAvailable();
}
}
public static bool IsAvailable(this SqlConnection connection)
{
try
{
connection.Open();
connection.Close();
}
catch (SqlException)
{
return false;
}
return true;
}
}
}

View File

@@ -358,7 +358,7 @@
<Compile Include="Persistence\Factories\MemberGroupFactory.cs" />
<Compile Include="Persistence\Mappers\MemberGroupMapper.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSixTwoZero\UpdateToNewMemberPropertyAliases.cs" />
<Compile Include="Persistence\SqlExtensions.cs" />
<Compile Include="Persistence\DbConnectionExtensions.cs" />
<Compile Include="PropertyEditors\DefaultPropertyValueConverterAttribute.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSeven\UpdateRelatedLinksData.cs" />
<Compile Include="PropertyEditors\IValueEditor.cs" />

View File

@@ -38,8 +38,9 @@ namespace Umbraco.Web.Install.Controllers
public ActionResult Index()
{
//if this is not an upgrade we will log in with the default user.
// It's not considered an upgrade if the ConfigurationStatus is missing or empty.
if (string.IsNullOrWhiteSpace(GlobalSettings.ConfigurationStatus) == false)
// It's not considered an upgrade if the ConfigurationStatus is missing or empty or if the db is not configured.
if (string.IsNullOrWhiteSpace(GlobalSettings.ConfigurationStatus) == false
&& ApplicationContext.Current.DatabaseContext.IsDatabaseConfigured)
{
Version current;
if (Version.TryParse(GlobalSettings.ConfigurationStatus, out current))

View File

@@ -14,11 +14,13 @@ namespace Umbraco.Web.Install
internal bool CheckConnection(DatabaseModel database, ApplicationContext applicationContext)
{
string connectionString;
DatabaseProviders provider;
var dbContext = applicationContext.DatabaseContext;
if (database.ConnectionString.IsNullOrWhiteSpace() == false)
{
connectionString = database.ConnectionString;
provider = DbConnectionExtensions.DetectProviderFromConnectionString(connectionString);
}
else if (database.DatabaseType == DatabaseType.SqlCe)
{
@@ -30,6 +32,7 @@ namespace Umbraco.Web.Install
{
connectionString = dbContext.GetIntegratedSecurityDatabaseConnectionString(
database.Server, database.DatabaseName);
provider = DatabaseProviders.SqlServer;;
}
else
{
@@ -38,9 +41,11 @@ namespace Umbraco.Web.Install
database.Server, database.DatabaseName, database.Login, database.Password,
database.DatabaseType.ToString(),
out providerName);
provider = database.DatabaseType == DatabaseType.MySql ? DatabaseProviders.MySql : DatabaseProviders.SqlServer;
}
return SqlExtensions.IsConnectionAvailable(connectionString);
return DbConnectionExtensions.IsConnectionAvailable(connectionString, provider);
}
}
}

View File

@@ -33,7 +33,9 @@ namespace Umbraco.Web.Install.InstallSteps
database = new DatabaseModel();
}
if (CheckConnection(database) == false)
var dbHelper = new DatabaseHelper();
if (dbHelper.CheckConnection(database, _applicationContext) == false)
{
throw new InvalidOperationException("Could not connect to the database");
}
@@ -41,37 +43,6 @@ namespace Umbraco.Web.Install.InstallSteps
return null;
}
private bool CheckConnection(DatabaseModel database)
{
string connectionString;
var dbContext = _applicationContext.DatabaseContext;
if (database.ConnectionString.IsNullOrWhiteSpace() == false)
{
connectionString = database.ConnectionString;
}
else if (database.DatabaseType == DatabaseType.SqlCe)
{
//we do not test this connection
return true;
//connectionString = dbContext.GetEmbeddedDatabaseConnectionString();
}
else if (database.IntegratedAuth)
{
connectionString = dbContext.GetIntegratedSecurityDatabaseConnectionString(
database.Server, database.DatabaseName);
}
else
{
string providerName;
connectionString = dbContext.GetDatabaseConnectionString(
database.Server, database.DatabaseName, database.Login, database.Password,
database.DatabaseType.ToString(),
out providerName);
}
return SqlExtensions.IsConnectionAvailable(connectionString);
}
private void ConfigureConnection(DatabaseModel database)
{
var dbContext = _applicationContext.DatabaseContext;

View File

@@ -4,6 +4,7 @@ using System.Configuration;
using System.Web.Security;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.Persistence;
using Umbraco.Web.Install.Models;
namespace Umbraco.Web.Install.InstallSteps
@@ -102,12 +103,13 @@ namespace Umbraco.Web.Install.InstallSteps
public override bool RequiresExecution(UserModel model)
{
//if there's already a version then there should def be a user
if (GlobalSettings.ConfigurationStatus.IsNullOrWhiteSpace() == false) return false;
//now we have to check if this is really a new install, the db might be configured and might contain data
var databaseSettings = ConfigurationManager.ConnectionStrings[GlobalSettings.UmbracoConnectionName];
//if there's already a version then there should def be a user but in some cases someone may have
// left a version number in there but cleared out their db conn string, in that case, it's really a new install.
if (GlobalSettings.ConfigurationStatus.IsNullOrWhiteSpace() == false && databaseSettings != null) return false;
if (_applicationContext.DatabaseContext.IsConnectionStringConfigured(databaseSettings)
&& _applicationContext.DatabaseContext.IsDatabaseConfigured)
{