Skip to content

Commit eb7578c

Browse files
committed
Adding Schema Support
This commit adds schema support to Simple.Data.Ado providers via the new ISchemaConnectionProvider interface, and allows them to support a schema per instance of Database.Open(...). This is primarily used for Oracle databases. In order to use the schema, just add the schema name to the appropriate Database.Open call (e.g. Database.OpenNamedConnection("TestConnectionName", "TEST_SCHEMA_NAME") ).
1 parent 42f651e commit eb7578c

File tree

10 files changed

+123
-38
lines changed

10 files changed

+123
-38
lines changed

Simple.Data.Ado/AdoAdapter.cs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,17 @@ protected override void OnSetup()
105105
{
106106
if (settingsKeys.Contains("ProviderName"))
107107
{
108-
_connectionProvider = ProviderHelper.GetProviderByConnectionString(Settings.ConnectionString,
109-
Settings.ProviderName);
108+
if(settingsKeys.Contains("SchemaName"))
109+
{
110+
_connectionProvider = ProviderHelper.GetProviderByConnectionString(Settings.ConnectionString
111+
, Settings.ProviderName
112+
, Settings.SchemaName);
113+
}
114+
else
115+
{
116+
_connectionProvider = ProviderHelper.GetProviderByConnectionString(Settings.ConnectionString,
117+
Settings.ProviderName);
118+
}
110119
}
111120
else
112121
{
@@ -119,7 +128,14 @@ protected override void OnSetup()
119128
}
120129
else if (settingsKeys.Contains("ConnectionName"))
121130
{
122-
_connectionProvider = ProviderHelper.GetProviderByConnectionName(Settings.ConnectionName);
131+
if (settingsKeys.Contains("SchemaName"))
132+
{
133+
_connectionProvider = ProviderHelper.GetProviderByConnectionName(Settings.ConnectionName, Settings.SchemaName);
134+
}
135+
else
136+
{
137+
_connectionProvider = ProviderHelper.GetProviderByConnectionName(Settings.ConnectionName);
138+
}
123139
}
124140
_schema = DatabaseSchema.Get(_connectionProvider, _providerHelper);
125141
_relatedFinder = new Lazy<AdoAdapterRelatedFinder>(CreateRelatedFinder);
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace Simple.Data.Ado
2+
{
3+
public interface ISchemaConnectionProvider : IConnectionProvider
4+
{
5+
void SetSchema(string schema);
6+
string Schema { get; }
7+
string ConnectionProviderKey { get; }
8+
}
9+
}

Simple.Data.Ado/ProviderHelper.cs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,20 +82,20 @@ private static IConnectionProvider ComposeProvider(string extension)
8282
return Composer.Default.Compose<IConnectionProvider>(extension);
8383
}
8484

85-
public IConnectionProvider GetProviderByConnectionName(string connectionName)
85+
public IConnectionProvider GetProviderByConnectionName(string connectionName, string schemaName = null)
8686
{
8787
var connectionSettings = ConfigurationManager.ConnectionStrings[connectionName];
8888
if (connectionSettings == null)
8989
{
9090
throw new ArgumentOutOfRangeException("connectionName");
9191
}
9292

93-
return GetProviderByConnectionString(connectionSettings.ConnectionString, connectionSettings.ProviderName);
93+
return GetProviderByConnectionString(connectionSettings.ConnectionString, connectionSettings.ProviderName, schemaName);
9494
}
9595

96-
public IConnectionProvider GetProviderByConnectionString(string connectionString, string providerName)
96+
public IConnectionProvider GetProviderByConnectionString(string connectionString, string providerName, string schemaName = null)
9797
{
98-
return _connectionProviderCache.GetOrAdd(new ConnectionToken(connectionString, providerName),
98+
return _connectionProviderCache.GetOrAdd(new ConnectionToken(connectionString, providerName, schemaName),
9999
LoadProviderByConnectionToken);
100100
}
101101

@@ -115,6 +115,11 @@ private static IConnectionProvider LoadProviderByConnectionToken(ConnectionToken
115115
}
116116

117117
provider.SetConnectionString(token.ConnectionString);
118+
119+
var schemaConnectionProvider = provider as ISchemaConnectionProvider;
120+
if(schemaConnectionProvider != null)
121+
schemaConnectionProvider.SetSchema(token.SchemaName);
122+
118123
return provider;
119124

120125
}
@@ -272,7 +277,7 @@ public override int GetHashCode()
272277
{
273278
unchecked
274279
{
275-
return (ConnectionString.GetHashCode()*397) ^ ProviderName.GetHashCode();
280+
return (ConnectionString.GetHashCode()*397) ^ (ProviderName.GetHashCode() * 397) ^ SchemaName.GetHashCode();
276281
}
277282
}
278283

@@ -288,12 +293,14 @@ public override int GetHashCode()
288293

289294
private readonly string _connectionString;
290295
private readonly string _providerName;
296+
private readonly string _schemaName;
291297

292-
public ConnectionToken(string connectionString, string providerName)
298+
public ConnectionToken(string connectionString, string providerName, string schemaName = null)
293299
{
294300
if (connectionString == null) throw new ArgumentNullException("connectionString");
295301
_connectionString = connectionString;
296302
_providerName = providerName ?? string.Empty;
303+
_schemaName = schemaName ?? string.Empty;
297304
}
298305

299306
public string ConnectionString
@@ -305,6 +312,11 @@ public string ProviderName
305312
{
306313
get { return _providerName; }
307314
}
315+
316+
public string SchemaName
317+
{
318+
get { return _schemaName; }
319+
}
308320
}
309321
}
310322
}

Simple.Data.Ado/Schema/DatabaseSchema.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,11 @@ public string QuoteObjectName(ObjectName unquotedName)
125125

126126
public static DatabaseSchema Get(IConnectionProvider connectionProvider, ProviderHelper providerHelper)
127127
{
128-
return Instances.GetOrAdd(connectionProvider.ConnectionString,
129-
sp => new DatabaseSchema(connectionProvider.GetSchemaProvider(), providerHelper));
128+
var instance = connectionProvider is ISchemaConnectionProvider
129+
? Instances.GetOrAdd(((ISchemaConnectionProvider)connectionProvider).ConnectionProviderKey, sp => new DatabaseSchema(connectionProvider.GetSchemaProvider(), providerHelper))
130+
: Instances.GetOrAdd(connectionProvider.ConnectionString, sp => new DatabaseSchema(connectionProvider.GetSchemaProvider(), providerHelper));
131+
132+
return instance;
130133
}
131134

132135
public static void ClearCache()

Simple.Data.Ado/Simple.Data.Ado.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@
106106
<Compile Include="IFunctionNameConverter.cs" />
107107
<Compile Include="IObservableQueryRunner.cs" />
108108
<Compile Include="IQueryPager.cs" />
109+
<Compile Include="ISchemaConnectionProvider.cs" />
109110
<Compile Include="ISchemaGetter.cs" />
110111
<Compile Include="ISqlOptimizer.cs" />
111112
<Compile Include="Joiner.cs" />

Simple.Data/Database.Open.cs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ public partial class Database
99
/// specified in the 'Simple.Data.Properties.Settings.ConnectionString' config ConnectionStrings setting.
1010
/// </summary>
1111
/// <returns>A <see cref="Database"/> object as a dynamic type.</returns>
12-
public static dynamic Open()
12+
public static dynamic Open(string schemaName = null)
1313
{
14-
return DatabaseOpener.OpenDefault();
14+
return DatabaseOpener.OpenDefault(schemaName);
1515
}
1616

1717
/// <summary>
@@ -36,9 +36,19 @@ public static dynamic OpenFile(string filename)
3636
return DatabaseOpener.OpenFile(filename);
3737
}
3838

39-
public static dynamic OpenNamedConnection(string connectionName)
39+
public static dynamic OpenNamedConnection(string connectionName, string schemaName = null)
4040
{
41-
return DatabaseOpener.OpenNamedConnection(connectionName);
41+
return DatabaseOpener.OpenNamedConnection(connectionName, schemaName);
42+
}
43+
44+
public static dynamic OpenConnection(string connectionString,string providerName)
45+
{
46+
return DatabaseOpener.OpenConnection(connectionString, providerName);
47+
}
48+
49+
public static dynamic OpenConnection(string connectionString, string providerName, string schemaName)
50+
{
51+
return DatabaseOpener.OpenConnection(connectionString, providerName, schemaName);
4252
}
4353
}
4454
}

Simple.Data/DatabaseOpener.cs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ protected static DatabaseOpenerMethods OpenMethods
1313
get { return LocalOpenMethods.Value; }
1414
}
1515

16-
public dynamic OpenDefault()
16+
public dynamic OpenDefault(string schemaName = null)
1717
{
18-
return OpenMethods.OpenDefaultImpl();
18+
return OpenMethods.OpenDefaultImpl(schemaName);
1919
}
2020

2121
public dynamic OpenFile(string filename)
@@ -33,6 +33,11 @@ public dynamic OpenConnection(string connectionString, string providerName)
3333
return OpenMethods.OpenConnectionWithProviderImpl(connectionString, providerName);
3434
}
3535

36+
public dynamic OpenConnection(string connectionString, string providerName, string schemaName)
37+
{
38+
return OpenMethods.OpenConnectionWithProviderAndSchemaImpl(connectionString, providerName, schemaName);
39+
}
40+
3641
public dynamic Open(string adapterName, object settings)
3742
{
3843
return OpenMethods.OpenImpl(adapterName, settings);
@@ -43,6 +48,11 @@ public dynamic OpenNamedConnection(string connectionName)
4348
return OpenMethods.OpenNamedConnectionImpl(connectionName);
4449
}
4550

51+
public dynamic OpenNamedConnection(string connectionName, string schemaName)
52+
{
53+
return OpenMethods.OpenNamedConnectionAndSchemaImpl(connectionName, schemaName);
54+
}
55+
4656
public void ClearAdapterCache()
4757
{
4858
((CachingAdapterFactory) AdapterFactory).Reset();
@@ -68,9 +78,9 @@ public static void UseMockAdapter(Func<Adapter> adapterCreator)
6878
OpenMethods.UseMockAdapter(adapterCreator);
6979
}
7080

71-
internal static Database OpenDefaultMethod()
81+
internal static Database OpenDefaultMethod(string schemaName = null)
7282
{
73-
return new Database(AdapterFactory.Create("Ado", new { ConnectionName = "Simple.Data.Properties.Settings.DefaultConnectionString" }));
83+
return new Database(AdapterFactory.Create("Ado", new { ConnectionName = "Simple.Data.Properties.Settings.DefaultConnectionString", SchemaName = schemaName }));
7484
}
7585

7686
internal static Database OpenFileMethod(string filename)
@@ -88,11 +98,21 @@ internal static Database OpenConnectionMethod(string connectionString, string pr
8898
return new Database(AdapterFactory.Create("Ado", new { ConnectionString = connectionString, ProviderName = providerName }));
8999
}
90100

101+
internal static Database OpenConnectionAndSchemaMethod(string connectionString, string providerName, string schemaName)
102+
{
103+
return new Database(AdapterFactory.Create("Ado", new { ConnectionString = connectionString, ProviderName = providerName, SchemaName = schemaName }));
104+
}
105+
91106
internal static Database OpenNamedConnectionMethod(string connectionName)
92107
{
93108
return new Database(AdapterFactory.Create("Ado", new { ConnectionName = connectionName }));
94109
}
95110

111+
internal static Database OpenNamedConnectionAndSchemaMethod(string connectionName, string schemaName)
112+
{
113+
return new Database(AdapterFactory.Create("Ado", new { ConnectionName = connectionName, SchemaName = schemaName }));
114+
}
115+
96116
internal static Database OpenMethod(string adapterName, object settings)
97117
{
98118
return new Database(AdapterFactory.Create(adapterName, settings));

Simple.Data/DatabaseOpenerMethods.cs

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@ namespace Simple.Data
44

55
internal class DatabaseOpenerMethods
66
{
7-
private Func<Database> _openDefault;
7+
private Func<string, Database> _openDefault;
88
private Func<string, Database> _openFile;
99
private Func<string, Database> _openConnection;
1010
private Func<string, string, Database> _openConnectionWithProvider;
11+
private Func<string, string, string, Database> _openConnectionWithProviderAndSchema;
1112
private Func<string, Database> _openNamedConnection;
13+
private Func<string, string, Database> _openNamedConnectionAndSchema;
1214
private Func<string, object, Database> _open;
1315

14-
public Func<Database> OpenDefaultImpl
16+
public Func<string, Database> OpenDefaultImpl
1517
{
1618
get { return _openDefault ?? DatabaseOpener.OpenDefaultMethod; }
1719
}
@@ -31,54 +33,64 @@ public Func<string, string, Database> OpenConnectionWithProviderImpl
3133
get { return _openConnectionWithProvider ?? DatabaseOpener.OpenConnectionMethod; }
3234
}
3335

36+
public Func<string, string, string, Database> OpenConnectionWithProviderAndSchemaImpl
37+
{
38+
get { return _openConnectionWithProviderAndSchema ?? DatabaseOpener.OpenConnectionAndSchemaMethod; }
39+
}
40+
3441
public Func<string, Database> OpenNamedConnectionImpl
3542
{
3643
get { return _openNamedConnection ?? DatabaseOpener.OpenNamedConnectionMethod; }
3744
}
3845

46+
public Func<string, string, Database> OpenNamedConnectionAndSchemaImpl
47+
{
48+
get { return _openNamedConnectionAndSchema ?? DatabaseOpener.OpenNamedConnectionAndSchemaMethod; }
49+
}
50+
3951
public Func<string, object, Database> OpenImpl
4052
{
4153
get { return _open ?? DatabaseOpener.OpenMethod; }
4254
}
4355

4456
public void UseMockDatabase(Database database)
4557
{
46-
_openDefault = () => database;
47-
_openFile = _openConnection = _openNamedConnection = ignore => database;
58+
_openDefault = _openFile = _openConnection = _openNamedConnection = ignore => database;
4859
_open = (ignore1, ignore2) => database;
49-
_openConnectionWithProvider = (ignore1, ignore2) => database;
60+
_openNamedConnectionAndSchema = _openConnectionWithProvider = (ignore1, ignore2) => database;
61+
_openConnectionWithProviderAndSchema = (ignore1, ignore2, ignore3) => database;
5062
}
5163

5264
public void UseMockAdapter(Adapter adapter)
5365
{
54-
_openDefault = () => new Database(adapter);
55-
_openFile = _openConnection = _openNamedConnection = ignore => new Database(adapter);
66+
_openDefault = _openFile = _openConnection = _openNamedConnection = ignore => new Database(adapter);
5667
_open = (ignore1, ignore2) => new Database(adapter);
57-
_openConnectionWithProvider = (ignore1, ignore2) => new Database(adapter);
68+
_openNamedConnectionAndSchema = _openConnectionWithProvider = (ignore1, ignore2) => new Database(adapter);
69+
_openConnectionWithProviderAndSchema = (ignore1, ignore2, ignore3) => new Database(adapter);
5870
}
5971

6072
public void UseMockDatabase(Func<Database> databaseCreator)
6173
{
62-
_openDefault = databaseCreator;
63-
_openFile = _openConnection = _openNamedConnection = ignore => databaseCreator();
74+
_openDefault = _openFile = _openConnection = _openNamedConnection = ignore => databaseCreator();
6475
_open = (ignore1, ignore2) => databaseCreator();
65-
_openConnectionWithProvider = (ignore1, ignore2) => databaseCreator();
76+
_openNamedConnectionAndSchema = _openConnectionWithProvider = (ignore1, ignore2) => databaseCreator();
77+
_openConnectionWithProviderAndSchema = (ignore1, ignore2, ignore3) => databaseCreator();
6678
}
6779

6880
public void UseMockAdapter(Func<Adapter> adapterCreator)
6981
{
70-
_openDefault = () => new Database(adapterCreator());
71-
_openFile = _openConnection = _openNamedConnection = ignore => new Database(adapterCreator());
82+
_openDefault = _openFile = _openConnection = _openNamedConnection = ignore => new Database(adapterCreator());
7283
_open = (ignore1, ignore2) => new Database(adapterCreator());
73-
_openConnectionWithProvider = (ignore1, ignore2) => new Database(adapterCreator());
84+
_openNamedConnectionAndSchema = _openConnectionWithProvider = (ignore1, ignore2) => new Database(adapterCreator());
85+
_openConnectionWithProviderAndSchema = (ignore1, ignore2, ignore3) => new Database(adapterCreator());
7486
}
7587

7688
public void StopUsingMock()
7789
{
78-
_openDefault = null;
79-
_openFile = _openConnection = _openNamedConnection = null;
90+
_openDefault = _openFile = _openConnection = _openNamedConnection = null;
8091
_open = null;
81-
_openConnectionWithProvider = null;
92+
_openNamedConnectionAndSchema = _openConnectionWithProvider = null;
93+
_openConnectionWithProviderAndSchema = null;
8294
}
8395
}
8496
}

Simple.Data/IDatabaseOpener.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@ namespace Simple.Data
22
{
33
public interface IDatabaseOpener
44
{
5-
dynamic OpenDefault();
5+
dynamic OpenDefault(string schemaName = null);
66
dynamic OpenFile(string filename);
77
dynamic OpenConnection(string connectionString);
88
dynamic OpenConnection(string connectionString, string providerName);
99
dynamic Open(string adapterName, object settings);
1010
dynamic OpenNamedConnection(string connectionName);
11+
dynamic OpenNamedConnection(string connectionName, string schemaName);
1112
void ClearAdapterCache();
13+
dynamic OpenConnection(string connectionString, string providerName, string schemaName);
1214
}
1315
}

Simple.Data/PropertySetterBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ internal static object SafeConvert(object source, Type targetType)
359359
{
360360
if (ReferenceEquals(source, null)) return null;
361361
if (targetType.IsInstanceOfType(source)) return source;
362-
362+
363363
if (source is string && targetType == typeof(Guid)) return TypeDescriptor.GetConverter(typeof(Guid)).ConvertFromInvariantString(source.ToString());
364364
return Convert.ChangeType(source, targetType);
365365
}

0 commit comments

Comments
 (0)