@@ -15,20 +15,27 @@ namespace NHibernate.Dialect.Schema
15
15
/// <seealso cref="DbConnection.GetSchema()"/>
16
16
public abstract class AbstractDataBaseSchema : IDataBaseSchema
17
17
{
18
- private readonly DbConnection connection ;
18
+ private readonly Dialect _dialect ;
19
19
20
- protected AbstractDataBaseSchema ( DbConnection connection )
21
- {
22
- this . connection = connection ;
23
- }
20
+ protected AbstractDataBaseSchema ( DbConnection connection ) : this ( connection , null ) { }
24
21
25
- protected DbConnection Connection
22
+ protected AbstractDataBaseSchema ( DbConnection connection , Dialect dialect )
26
23
{
27
- get { return connection ; }
24
+ Connection = connection ;
25
+ _dialect = dialect ;
28
26
}
29
27
28
+ protected DbConnection Connection { get ; }
29
+
30
30
public virtual bool IncludeDataTypesInReservedWords => true ;
31
31
32
+ /// <summary>
33
+ /// Should <see cref="Dialect.Qualify"/> be used for searching tables instead of using separately
34
+ /// the table, schema and catalog names? If <see langword="true" />, dialect must be provided
35
+ /// with <see cref="AbstractDataBaseSchema(DbConnection, Dialect)"/>.
36
+ /// </summary>
37
+ public virtual bool UseDialectQualifyInsteadOfTableName => false ;
38
+
32
39
#region IDataBaseSchema Members
33
40
34
41
public virtual bool StoresMixedCaseQuotedIdentifiers
@@ -58,8 +65,36 @@ public virtual bool StoresLowerCaseIdentifiers
58
65
59
66
public virtual DataTable GetTables ( string catalog , string schemaPattern , string tableNamePattern , string [ ] types )
60
67
{
68
+ if ( UseDialectQualifyInsteadOfTableName )
69
+ {
70
+ var actualTablePattern = GetActualTableName ( catalog , schemaPattern , tableNamePattern ) ;
71
+ var tables = Connection . GetSchema ( "Tables" , new [ ] { null , null , actualTablePattern } ) ;
72
+
73
+ // Caller may check the table name of yielded results, we need to patch them
74
+ foreach ( DataRow tableRow in tables . Rows )
75
+ {
76
+ var tableName = Convert . ToString ( tableRow [ ColumnNameForTableName ] ) ;
77
+ if ( tableName . Equals ( actualTablePattern , StringComparison . InvariantCultureIgnoreCase ) )
78
+ {
79
+ tableRow [ ColumnNameForTableName ] = tableNamePattern ;
80
+ // Columns are looked-up according to the row table name, and schema and catalog data.
81
+ // We need to patch schema and catalog for being able to reconstruct the adequate table name.
82
+ if ( ! string . IsNullOrEmpty ( catalog ) )
83
+ {
84
+ tableRow [ "TABLE_CATALOG" ] = catalog ;
85
+ }
86
+ if ( ! string . IsNullOrEmpty ( schemaPattern ) )
87
+ {
88
+ tableRow [ "TABLE_SCHEMA" ] = schemaPattern ;
89
+ }
90
+ }
91
+ }
92
+
93
+ return tables ;
94
+ }
95
+
61
96
var restrictions = new [ ] { catalog , schemaPattern , tableNamePattern } ;
62
- return connection . GetSchema ( "Tables" , restrictions ) ;
97
+ return Connection . GetSchema ( "Tables" , restrictions ) ;
63
98
}
64
99
65
100
public virtual string ColumnNameForTableName
@@ -72,40 +107,64 @@ public virtual string ColumnNameForTableName
72
107
public virtual DataTable GetColumns ( string catalog , string schemaPattern , string tableNamePattern ,
73
108
string columnNamePattern )
74
109
{
110
+ if ( UseDialectQualifyInsteadOfTableName )
111
+ {
112
+ var actualTablePattern = GetActualTableName ( catalog , schemaPattern , tableNamePattern ) ;
113
+ return Connection . GetSchema ( "Columns" , new [ ] { null , null , actualTablePattern , columnNamePattern } ) ;
114
+ }
115
+
75
116
var restrictions = new [ ] { catalog , schemaPattern , tableNamePattern , columnNamePattern } ;
76
- return connection . GetSchema ( "Columns" , restrictions ) ;
117
+ return Connection . GetSchema ( "Columns" , restrictions ) ;
77
118
}
78
119
79
120
public virtual DataTable GetIndexInfo ( string catalog , string schemaPattern , string tableName )
80
121
{
122
+ if ( UseDialectQualifyInsteadOfTableName )
123
+ {
124
+ var actualTableName = GetActualTableName ( catalog , schemaPattern , tableName ) ;
125
+ return Connection . GetSchema ( "Indexes" , new [ ] { null , null , actualTableName , null } ) ;
126
+ }
127
+
81
128
var restrictions = new [ ] { catalog , schemaPattern , tableName , null } ;
82
- return connection . GetSchema ( "Indexes" , restrictions ) ;
129
+ return Connection . GetSchema ( "Indexes" , restrictions ) ;
83
130
}
84
131
85
132
public virtual DataTable GetIndexColumns ( string catalog , string schemaPattern , string tableName , string indexName )
86
133
{
134
+ if ( UseDialectQualifyInsteadOfTableName )
135
+ {
136
+ var actualTableName = GetActualTableName ( catalog , schemaPattern , tableName ) ;
137
+ return Connection . GetSchema ( "IndexColumns" , new [ ] { null , null , actualTableName , indexName , null } ) ;
138
+ }
139
+
87
140
var restrictions = new [ ] { catalog , schemaPattern , tableName , indexName , null } ;
88
- return connection . GetSchema ( "IndexColumns" , restrictions ) ;
141
+ return Connection . GetSchema ( "IndexColumns" , restrictions ) ;
89
142
}
90
143
91
144
public virtual DataTable GetForeignKeys ( string catalog , string schema , string table )
92
145
{
146
+ if ( UseDialectQualifyInsteadOfTableName )
147
+ {
148
+ var actualTableName = GetActualTableName ( catalog , schema , table ) ;
149
+ return Connection . GetSchema ( ForeignKeysSchemaName , new [ ] { null , null , actualTableName , null } ) ;
150
+ }
151
+
93
152
var restrictions = new [ ] { catalog , schema , table , null } ;
94
- return connection . GetSchema ( ForeignKeysSchemaName , restrictions ) ;
153
+ return Connection . GetSchema ( ForeignKeysSchemaName , restrictions ) ;
95
154
}
96
155
97
156
public virtual ISet < string > GetReservedWords ( )
98
157
{
99
158
var result = new HashSet < string > ( StringComparer . OrdinalIgnoreCase ) ;
100
- DataTable dtReservedWords = connection . GetSchema ( DbMetaDataCollectionNames . ReservedWords ) ;
159
+ DataTable dtReservedWords = Connection . GetSchema ( DbMetaDataCollectionNames . ReservedWords ) ;
101
160
foreach ( DataRow row in dtReservedWords . Rows )
102
161
{
103
162
result . Add ( row [ "ReservedWord" ] . ToString ( ) ) ;
104
163
}
105
164
106
165
if ( IncludeDataTypesInReservedWords )
107
166
{
108
- DataTable dtTypes = connection . GetSchema ( DbMetaDataCollectionNames . DataTypes ) ;
167
+ DataTable dtTypes = Connection . GetSchema ( DbMetaDataCollectionNames . DataTypes ) ;
109
168
foreach ( DataRow row in dtTypes . Rows )
110
169
{
111
170
result . Add ( row [ "TypeName" ] . ToString ( ) ) ;
@@ -120,6 +179,16 @@ protected virtual string ForeignKeysSchemaName
120
179
get { return "ForeignKeys" ; }
121
180
}
122
181
182
+ private string GetActualTableName ( string catalog , string schemaPattern , string tableNamePattern )
183
+ {
184
+ if ( _dialect == null )
185
+ throw new InvalidOperationException ( $ "{ this } : cannot qualify table name without the dialect") ;
186
+
187
+ // _dialect is supposed to concatenate catalog and schema with the table name as an
188
+ // unqualified name instead of actually qualifying it.
189
+ return _dialect . Qualify ( catalog , schemaPattern , tableNamePattern ) ;
190
+ }
191
+
123
192
#endregion
124
193
}
125
194
}
0 commit comments