2009-06-19 07:39:16 +00:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Umbraco Data Layer
* MIT Licensed work
* <EFBFBD> 2008 Ruben Verborgh
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
using System ;
2013-01-08 16:46:56 -01:00
using System.Configuration ;
2009-06-19 07:39:16 +00:00
using System.Data.Common ;
using System.Reflection ;
namespace umbraco.DataLayer
{
/// <summary>
/// The DataLayerHelper class is the main interface to the data layer.
/// </summary>
public class DataLayerHelper
{
#region Private Constants
/// <summary>Name of the property that identifies the SQL helper type.</summary>
private const string ConnectionStringDataLayerIdentifier = "datalayer" ;
/// <summary>Name of the default data layer, that is used when nothing is specified.</summary>
private const string DefaultDataHelperName = "SqlServer" ;
/// <summary>Format used when the SQL helper is qualified by its simple name, instead of the full class name.</summary>
2013-01-08 16:46:56 -01:00
private const string DefaultDataHelperFormat = "umbraco.DataLayer.SqlHelpers.{0}.{0}Helper" ;
2009-06-19 07:39:16 +00:00
2013-01-09 05:08:05 -01:00
private static string _dataHelperTypeName ;
private static string _dataHelperAssemblyName ;
private static string _connectionString ;
2009-06-19 07:39:16 +00:00
#endregion
#region Public Methods
/// <summary>
/// Creates a SQL helper for the specified connection string.
/// </summary>
/// <param name="connectionString">The connection string containing the SQL helper type.</param>
/// <returns>A new SQL helper.</returns>
/// <remarks>This method will change to allow the addition of external SQL helpers.</remarks>
public static ISqlHelper CreateSqlHelper ( string connectionString )
2013-01-14 15:06:23 -01:00
{
return CreateSqlHelper ( connectionString , true ) ;
}
public static ISqlHelper CreateSqlHelper ( string connectionString , bool forceLegacyConnection )
2009-06-19 07:39:16 +00:00
{
/* check arguments */
2013-01-08 16:46:56 -01:00
if ( string . IsNullOrEmpty ( connectionString ) )
2009-06-19 07:39:16 +00:00
throw new ArgumentNullException ( "connectionString" ) ;
2013-01-14 15:06:23 -01:00
if ( forceLegacyConnection = = false & & IsEmbeddedDatabase ( connectionString ) & & connectionString . ToLower ( ) . Contains ( "SQLCE4Umbraco" . ToLower ( ) ) = = false )
2013-01-02 07:08:02 -01:00
{
// Input is : Datasource=|DataDirectory|Umbraco.sdf
// Should be: datalayer=SQLCE4Umbraco.SqlCEHelper,SQLCE4Umbraco;data source=|DataDirectory|\Umbraco.sdf
2012-12-31 13:57:29 -01:00
2013-01-02 07:08:02 -01:00
connectionString = connectionString . Replace ( "Datasource" , "data source" ) ;
connectionString = connectionString . Insert ( connectionString . LastIndexOf ( '|' ) + 1 , "\\" ) ;
connectionString = string . Format ( "datalayer=SQLCE4Umbraco.SqlCEHelper,SQLCE4Umbraco;{0}" , connectionString ) ;
}
2013-01-08 16:46:56 -01:00
2009-06-19 07:39:16 +00:00
/* try to parse connection string */
2013-01-08 16:46:56 -01:00
var connectionStringBuilder = new DbConnectionStringBuilder ( ) ;
2009-06-19 07:39:16 +00:00
try
{
connectionStringBuilder . ConnectionString = connectionString ;
}
catch ( Exception ex )
{
throw new ArgumentException ( "Bad connection string." , "connectionString" , ex ) ;
}
2013-01-14 15:06:23 -01:00
var connectionStringSettings = ConfigurationManager . ConnectionStrings [ Umbraco . Core . Configuration . GlobalSettings . UmbracoConnectionName ] ;
if ( forceLegacyConnection = = false & & connectionStringSettings ! = null )
SetDataHelperNames ( connectionStringSettings ) ;
2013-01-08 16:46:56 -01:00
else
SetDataHelperNamesLegacyConnectionString ( connectionStringBuilder ) ;
2009-06-19 07:39:16 +00:00
2013-01-08 16:46:56 -01:00
/* create the helper */
2009-06-19 07:39:16 +00:00
// find the right assembly
2013-01-08 16:46:56 -01:00
var helperAssembly = Assembly . GetExecutingAssembly ( ) ;
if ( string . IsNullOrWhiteSpace ( _dataHelperAssemblyName ) = = false )
2009-06-19 07:39:16 +00:00
{
try
{
2013-01-08 16:46:56 -01:00
helperAssembly = Assembly . Load ( _dataHelperAssemblyName ) ;
2009-06-19 07:39:16 +00:00
}
catch ( Exception exception )
{
2013-01-08 16:46:56 -01:00
throw new UmbracoException ( String . Format ( "Could not load assembly {0}." , _dataHelperAssemblyName ) , exception ) ;
2009-06-19 07:39:16 +00:00
}
}
// find the right type
Type helperType ;
2013-01-09 10:43:12 -01:00
if ( string . IsNullOrWhiteSpace ( _dataHelperTypeName ) )
2013-01-08 16:46:56 -01:00
_dataHelperTypeName = DefaultDataHelperName ;
if ( _dataHelperTypeName . Contains ( "." ) = = false )
_dataHelperTypeName = string . Format ( DefaultDataHelperFormat , _dataHelperTypeName ) ;
2009-06-19 07:39:16 +00:00
try
{
2013-01-08 16:46:56 -01:00
helperType = helperAssembly . GetType ( _dataHelperTypeName , true , true ) ;
2009-06-19 07:39:16 +00:00
}
catch ( Exception exception )
{
2013-01-08 16:46:56 -01:00
throw new UmbracoException ( String . Format ( "Could not load type {0} ({1})." , _dataHelperTypeName , helperAssembly . FullName ) , exception ) ;
2009-06-19 07:39:16 +00:00
}
// find the right constructor
2013-01-08 16:46:56 -01:00
var constructor = helperType . GetConstructor ( new [ ] { typeof ( string ) } ) ;
2009-06-19 07:39:16 +00:00
if ( constructor = = null )
2013-01-08 16:46:56 -01:00
throw new UmbracoException ( String . Format ( "Could not find constructor that takes a connection string as parameter. ({0}, {1})." , _dataHelperTypeName , helperAssembly . FullName ) ) ;
2009-06-19 07:39:16 +00:00
// finally, return the helper
try
{
2013-01-09 05:08:05 -01:00
return constructor . Invoke ( new object [ ] { _connectionString } ) as ISqlHelper ;
2009-06-19 07:39:16 +00:00
}
catch ( Exception exception )
{
2013-01-08 16:46:56 -01:00
throw new UmbracoException ( String . Format ( "Could not execute constructor of type {0} ({1})." , _dataHelperTypeName , helperAssembly . FullName ) , exception ) ;
}
}
2013-01-09 05:08:05 -01:00
private static void SetDataHelperNames ( ConnectionStringSettings connectionStringSettings )
2013-01-08 16:46:56 -01:00
{
2013-01-09 05:08:05 -01:00
_connectionString = connectionStringSettings . ConnectionString ;
var provider = connectionStringSettings . ProviderName ;
if ( provider . StartsWith ( "MySql" ) )
2013-01-08 16:46:56 -01:00
{
_dataHelperTypeName = "MySql" ;
2009-06-19 07:39:16 +00:00
}
2013-01-09 05:08:05 -01:00
if ( provider . StartsWith ( "System.Data.SqlServerCe" ) )
2013-01-08 16:46:56 -01:00
{
_dataHelperTypeName = "SQLCE4Umbraco.SqlCEHelper" ;
_dataHelperAssemblyName = "SQLCE4Umbraco" ;
}
}
private static void SetDataHelperNamesLegacyConnectionString ( DbConnectionStringBuilder connectionStringBuilder )
{
// get the data layer type and parse it
var datalayerType = String . Empty ;
if ( connectionStringBuilder . ContainsKey ( ConnectionStringDataLayerIdentifier ) )
{
datalayerType = connectionStringBuilder [ ConnectionStringDataLayerIdentifier ] . ToString ( ) ;
connectionStringBuilder . Remove ( ConnectionStringDataLayerIdentifier ) ;
}
2013-01-09 05:08:05 -01:00
_connectionString = connectionStringBuilder . ConnectionString ;
2013-01-08 16:46:56 -01:00
var datalayerTypeParts = datalayerType . Split ( "," . ToCharArray ( ) ) ;
_dataHelperTypeName = datalayerTypeParts [ 0 ] . Trim ( ) ;
_dataHelperAssemblyName = datalayerTypeParts . Length < 2
? string . Empty
: datalayerTypeParts [ 1 ] . Trim ( ) ;
if ( datalayerTypeParts . Length > 2 | | ( _dataHelperTypeName . Length = = 0 & & _dataHelperAssemblyName . Length > 0 ) )
throw new ArgumentException ( "Illegal format of data layer property. Should be 'DataLayer = Full_Type_Name [, Assembly_Name]'." , "connectionString" ) ;
2009-06-19 07:39:16 +00:00
}
2011-09-06 07:43:36 -02:00
public static bool IsEmbeddedDatabase ( string connectionString )
{
2012-12-31 13:57:29 -01:00
return connectionString . ToLower ( ) . Contains ( "|DataDirectory|" . ToLower ( ) ) ;
2011-09-06 07:43:36 -02:00
}
2009-06-19 07:39:16 +00:00
#endregion
2013-01-08 16:46:56 -01:00
}
2009-06-19 07:39:16 +00:00
}