Skip to content

Commit 306f40a

Browse files
NH-4062 - Refactoring ODP.Net drivers for eliminating code duplication.
1 parent f4c2764 commit 306f40a

File tree

3 files changed

+130
-236
lines changed

3 files changed

+130
-236
lines changed
Lines changed: 3 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -1,134 +1,19 @@
1-
using System;
2-
using System.Data;
3-
using System.Data.Common;
4-
using System.Reflection;
5-
using NHibernate.AdoNet;
6-
using NHibernate.Engine.Query;
7-
using NHibernate.SqlTypes;
8-
using NHibernate.Util;
9-
101
namespace NHibernate.Driver
112
{
123
/// <summary>
13-
/// A NHibernate Driver for using the Oracle.DataAccess DataProvider
4+
/// A NHibernate Driver for using the Oracle.DataAccess (unmanaged) DataProvider
145
/// </summary>
15-
/// <remarks>
16-
/// Code was contributed by <a href="http://sourceforge.net/users/jemcalgary/">James Mills</a>
17-
/// on the NHibernate forums in this
18-
/// <a href="http://sourceforge.net/forum/message.php?msg_id=2952662">post</a>.
19-
/// </remarks>
20-
public class OracleDataClientDriver : ReflectionBasedDriver, IEmbeddedBatcherFactoryProvider
6+
public class OracleDataClientDriver : OracleDataClientDriverBase
217
{
22-
private const string driverAssemblyName = "Oracle.DataAccess";
23-
private const string connectionTypeName = "Oracle.DataAccess.Client.OracleConnection";
24-
private const string commandTypeName = "Oracle.DataAccess.Client.OracleCommand";
25-
private static readonly SqlType GuidSqlType = new SqlType(DbType.Binary, 16);
26-
private readonly PropertyInfo oracleCommandBindByName;
27-
private readonly PropertyInfo oracleDbType;
28-
private readonly object oracleDbTypeRefCursor;
29-
private readonly object oracleDbTypeXmlType;
30-
318
/// <summary>
329
/// Initializes a new instance of <see cref="OracleDataClientDriver"/>.
3310
/// </summary>
3411
/// <exception cref="HibernateException">
3512
/// Thrown when the <c>Oracle.DataAccess</c> assembly can not be loaded.
3613
/// </exception>
3714
public OracleDataClientDriver()
38-
: base(
39-
"Oracle.DataAccess.Client",
40-
driverAssemblyName,
41-
connectionTypeName,
42-
commandTypeName)
15+
: base("Oracle.DataAccess")
4316
{
44-
System.Type oracleCommandType = ReflectHelper.TypeFromAssembly("Oracle.DataAccess.Client.OracleCommand", driverAssemblyName, false);
45-
oracleCommandBindByName = oracleCommandType.GetProperty("BindByName");
46-
47-
System.Type parameterType = ReflectHelper.TypeFromAssembly("Oracle.DataAccess.Client.OracleParameter", driverAssemblyName, false);
48-
oracleDbType = parameterType.GetProperty("OracleDbType");
49-
50-
System.Type oracleDbTypeEnum = ReflectHelper.TypeFromAssembly("Oracle.DataAccess.Client.OracleDbType", driverAssemblyName, false);
51-
oracleDbTypeRefCursor = Enum.Parse(oracleDbTypeEnum, "RefCursor");
52-
oracleDbTypeXmlType = Enum.Parse(oracleDbTypeEnum, "XmlType");
53-
}
54-
55-
/// <summary></summary>
56-
public override bool UseNamedPrefixInSql
57-
{
58-
get { return true; }
59-
}
60-
61-
/// <summary></summary>
62-
public override bool UseNamedPrefixInParameter
63-
{
64-
get { return true; }
65-
}
66-
67-
/// <summary></summary>
68-
public override string NamedPrefix
69-
{
70-
get { return ":"; }
71-
}
72-
73-
/// <remarks>
74-
/// This adds logic to ensure that a DbType.Boolean parameter is not created since
75-
/// ODP.NET doesn't support it.
76-
/// </remarks>
77-
protected override void InitializeParameter(DbParameter dbParam, string name, SqlType sqlType)
78-
{
79-
// if the parameter coming in contains a boolean then we need to convert it
80-
// to another type since ODP.NET doesn't support DbType.Boolean
81-
switch (sqlType.DbType)
82-
{
83-
case DbType.Boolean:
84-
base.InitializeParameter(dbParam, name, SqlTypeFactory.Int16);
85-
break;
86-
case DbType.Guid:
87-
base.InitializeParameter(dbParam, name, GuidSqlType);
88-
break;
89-
case DbType.Xml:
90-
this.InitializeParameter(dbParam, name, oracleDbTypeXmlType);
91-
break;
92-
default:
93-
base.InitializeParameter(dbParam, name, sqlType);
94-
break;
95-
}
96-
}
97-
98-
private void InitializeParameter(DbParameter dbParam, string name, object sqlType)
99-
{
100-
dbParam.ParameterName = FormatNameForParameter(name);
101-
oracleDbType.SetValue(dbParam, sqlType, null);
102-
}
103-
104-
protected override void OnBeforePrepare(DbCommand command)
105-
{
106-
base.OnBeforePrepare(command);
107-
108-
// need to explicitly turn on named parameter binding
109-
// http://tgaw.wordpress.com/2006/03/03/ora-01722-with-odp-and-command-parameters/
110-
oracleCommandBindByName.SetValue(command, true, null);
111-
112-
CallableParser.Detail detail = CallableParser.Parse(command.CommandText);
113-
114-
if (!detail.IsCallable)
115-
return;
116-
117-
command.CommandType = CommandType.StoredProcedure;
118-
command.CommandText = detail.FunctionName;
119-
oracleCommandBindByName.SetValue(command, false, null);
120-
121-
var outCursor = command.CreateParameter();
122-
oracleDbType.SetValue(outCursor, oracleDbTypeRefCursor, null);
123-
124-
outCursor.Direction = detail.HasReturn ? ParameterDirection.ReturnValue : ParameterDirection.Output;
125-
126-
command.Parameters.Insert(0, outCursor);
127-
}
128-
129-
System.Type IEmbeddedBatcherFactoryProvider.BatcherFactoryClass
130-
{
131-
get { return typeof (OracleDataClientBatchingBatcherFactory); }
13217
}
13318
}
13419
}
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
using System;
2+
using System.Data;
3+
using System.Data.Common;
4+
using System.Reflection;
5+
using NHibernate.AdoNet;
6+
using NHibernate.Engine.Query;
7+
using NHibernate.SqlTypes;
8+
using NHibernate.Util;
9+
10+
namespace NHibernate.Driver
11+
{
12+
/// <summary>
13+
/// A NHibernate driver base for using ODP.Net.
14+
/// </summary>
15+
/// <remarks>
16+
/// Original code was contributed by <a href="http://sourceforge.net/users/jemcalgary/">James Mills</a>
17+
/// on the NHibernate forums in this
18+
/// <a href="http://sourceforge.net/forum/message.php?msg_id=2952662">post</a>.
19+
/// </remarks>
20+
public abstract class OracleDataClientDriverBase : ReflectionBasedDriver, IEmbeddedBatcherFactoryProvider
21+
{
22+
private const string _commandClassName = "OracleCommand";
23+
24+
private static readonly SqlType _guidSqlType = new SqlType(DbType.Binary, 16);
25+
private readonly PropertyInfo _oracleCommandBindByName;
26+
private readonly PropertyInfo _oracleDbType;
27+
private readonly object _oracleDbTypeRefCursor;
28+
private readonly object _oracleDbTypeXmlType;
29+
30+
/// <summary>
31+
/// Default constructor.
32+
/// </summary>
33+
/// <param name="assemblyName">The assembly name of the managed or unmanage driver. Namespaces will be derived from it.</param>
34+
/// <exception cref="HibernateException">
35+
/// Thrown when the requested assembly can not be loaded.
36+
/// </exception>
37+
protected OracleDataClientDriverBase(string assemblyName)
38+
: this(assemblyName, assemblyName + ".Client")
39+
{
40+
}
41+
42+
private OracleDataClientDriverBase(string driverAssemblyName, string clientNamespace)
43+
: base(clientNamespace, driverAssemblyName, clientNamespace + ".OracleConnection", clientNamespace + "." + _commandClassName)
44+
{
45+
var oracleCommandType = ReflectHelper.TypeFromAssembly(clientNamespace + "." + _commandClassName, driverAssemblyName, true);
46+
_oracleCommandBindByName = oracleCommandType.GetProperty("BindByName");
47+
48+
var parameterType = ReflectHelper.TypeFromAssembly(clientNamespace + ".OracleParameter", driverAssemblyName, true);
49+
_oracleDbType = parameterType.GetProperty("OracleDbType");
50+
51+
var oracleDbTypeEnum = ReflectHelper.TypeFromAssembly(clientNamespace + ".OracleDbType", driverAssemblyName, true);
52+
_oracleDbTypeRefCursor = Enum.Parse(oracleDbTypeEnum, "RefCursor");
53+
_oracleDbTypeXmlType = Enum.Parse(oracleDbTypeEnum, "XmlType");
54+
}
55+
56+
/// <inheritdoc/>
57+
public override bool UseNamedPrefixInSql => true;
58+
59+
/// <inheritdoc/>
60+
public override bool UseNamedPrefixInParameter => true;
61+
62+
/// <inheritdoc/>
63+
public override string NamedPrefix => ":";
64+
65+
/// <remarks>
66+
/// Add logic to ensure that a <see cref="DbType.Boolean"/> parameter is not created since
67+
/// ODP.NET doesn't support it. Handle <see cref="DbType.Guid"/> and <see cref="DbType.Xml"/> cases too.
68+
/// Adjust <see cref="DbType.String"/> resulting type if needed.
69+
/// </remarks>
70+
protected override void InitializeParameter(DbParameter dbParam, string name, SqlType sqlType)
71+
{
72+
switch (sqlType.DbType)
73+
{
74+
case DbType.Boolean:
75+
// if the parameter coming in contains a boolean then we need to convert it
76+
// to another type since ODP.NET doesn't support DbType.Boolean
77+
base.InitializeParameter(dbParam, name, SqlTypeFactory.Int16);
78+
break;
79+
case DbType.Guid:
80+
base.InitializeParameter(dbParam, name, _guidSqlType);
81+
break;
82+
case DbType.Xml:
83+
InitializeParameter(dbParam, name, _oracleDbTypeXmlType);
84+
break;
85+
default:
86+
base.InitializeParameter(dbParam, name, sqlType);
87+
break;
88+
}
89+
}
90+
91+
private void InitializeParameter(DbParameter dbParam, string name, object sqlType)
92+
{
93+
dbParam.ParameterName = FormatNameForParameter(name);
94+
_oracleDbType.SetValue(dbParam, sqlType, null);
95+
}
96+
97+
protected override void OnBeforePrepare(DbCommand command)
98+
{
99+
base.OnBeforePrepare(command);
100+
101+
// need to explicitly turn on named parameter binding
102+
// http://tgaw.wordpress.com/2006/03/03/ora-01722-with-odp-and-command-parameters/
103+
_oracleCommandBindByName.SetValue(command, true, null);
104+
105+
var detail = CallableParser.Parse(command.CommandText);
106+
107+
if (!detail.IsCallable)
108+
return;
109+
110+
command.CommandType = CommandType.StoredProcedure;
111+
command.CommandText = detail.FunctionName;
112+
_oracleCommandBindByName.SetValue(command, false, null);
113+
114+
var outCursor = command.CreateParameter();
115+
_oracleDbType.SetValue(outCursor, _oracleDbTypeRefCursor, null);
116+
117+
outCursor.Direction = detail.HasReturn ? ParameterDirection.ReturnValue : ParameterDirection.Output;
118+
119+
command.Parameters.Insert(0, outCursor);
120+
}
121+
122+
System.Type IEmbeddedBatcherFactoryProvider.BatcherFactoryClass => typeof(OracleDataClientBatchingBatcherFactory);
123+
}
124+
}

0 commit comments

Comments
 (0)