forked from nhibernate/nhibernate-core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSQLExceptionConverterFactory.cs
118 lines (101 loc) · 3.88 KB
/
SQLExceptionConverterFactory.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
using System;
using System.Collections.Generic;
using System.Reflection;
using NHibernate.Util;
namespace NHibernate.Exceptions
{
/// <summary> A factory for building SQLExceptionConverter instances. </summary>
public static class SQLExceptionConverterFactory
{
private static readonly INHibernateLogger log = NHibernateLogger.For(typeof(SQLExceptionConverterFactory));
private class MinimalSQLExceptionConverter : ISQLExceptionConverter
{
#region ISQLExceptionConverter Members
public Exception Convert(AdoExceptionContextInfo exceptionContextInfo)
{
throw new GenericADOException(exceptionContextInfo.Message, exceptionContextInfo.SqlException, exceptionContextInfo.Sql);
}
#endregion
}
/// <summary> Build a SQLExceptionConverter instance. </summary>
/// <param name="dialect">The defined dialect. </param>
/// <param name="properties">The configuration properties. </param>
/// <returns> An appropriate <see cref="ISQLExceptionConverter"/> instance. </returns>
/// <remarks>
/// First, looks for a <see cref="Cfg.Environment.SqlExceptionConverter"/> property to see
/// if the configuration specified the class of a specific converter to use. If this
/// property is set, attempt to construct an instance of that class. If not set, or
/// if construction fails, the converter specific to the dialect will be used.
/// </remarks>
public static ISQLExceptionConverter BuildSQLExceptionConverter(Dialect.Dialect dialect, IDictionary<string, string> properties)
{
ISQLExceptionConverter converter = null;
string converterClassName;
properties.TryGetValue(Cfg.Environment.SqlExceptionConverter, out converterClassName);
if (!string.IsNullOrEmpty(converterClassName))
{
converter = ConstructConverter(converterClassName, dialect.ViolatedConstraintNameExtracter);
}
if (converter == null)
{
log.Info("Using dialect defined converter");
converter = dialect.BuildSQLExceptionConverter();
}
IConfigurable confConv = converter as IConfigurable;
if (confConv != null)
{
try
{
confConv.Configure(properties);
}
catch (HibernateException e)
{
log.Warn(e, "Unable to configure SQLExceptionConverter");
throw;
}
}
return converter;
}
/// <summary>
/// Builds a minimal converter. The instance returned here just always converts to <see cref="GenericADOException"/>.
/// </summary>
/// <returns> The minimal converter. </returns>
public static ISQLExceptionConverter BuildMinimalSQLExceptionConverter()
{
return new MinimalSQLExceptionConverter();
}
private static ISQLExceptionConverter ConstructConverter(string converterClassName, IViolatedConstraintNameExtracter violatedConstraintNameExtracter)
{
try
{
log.Debug("Attempting to construct instance of specified SQLExceptionConverter [{0}]", converterClassName);
System.Type converterClass = ReflectHelper.ClassForName(converterClassName);
// First, try to find a matching constructor accepting a ViolatedConstraintNameExtracter param...
ConstructorInfo[] ctors = converterClass.GetConstructors(ReflectHelper.AnyVisibilityInstance);
foreach (ConstructorInfo ctor in ctors)
{
ParameterInfo[] parameters = ctor.GetParameters();
if (parameters == null || parameters.Length != 1) continue;
if (typeof(IViolatedConstraintNameExtracter).IsAssignableFrom(parameters[0].ParameterType))
{
try
{
return (ISQLExceptionConverter)ctor.Invoke(new object[] { violatedConstraintNameExtracter });
}
catch (Exception)
{
// eat it and try next
}
}
}
// Otherwise, try to use the no-arg constructor
return (ISQLExceptionConverter) Cfg.Environment.ObjectsFactory.CreateInstance(converterClass);
}
catch (Exception t)
{
log.Warn(t, "Unable to construct instance of specified SQLExceptionConverter");
}
return null;
}
}
}