Skip to content

Commit 1c3ce42

Browse files
committed
NH-1285 - Drop/Create script with default_schema/default_catalog fix(SqlServer)
1 parent 378be39 commit 1c3ce42

File tree

13 files changed

+308
-50
lines changed

13 files changed

+308
-50
lines changed

src/NHibernate.Test/DialectTest/MsSql2005DialectFixture.cs

Lines changed: 115 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,120 @@ public void GetIfExistsDropConstraintTest_For_Schema_other_than_dbo()
218218
Assert.AreEqual(expected, ifExistsDropConstraint);
219219
}
220220

221+
222+
[Test]
223+
public void GetIfExistsDropConstraintTest_without_schema_with_schemaName_overload()
224+
{
225+
MsSql2005Dialect dialect = new MsSql2005Dialect();
226+
Table foo = new Table("Foo");
227+
string expected = "if exists (select 1 from sys.objects" +
228+
" where object_id = OBJECT_ID(N'[Bar]')" +
229+
" AND parent_object_id = OBJECT_ID('Foo'))";
230+
string ifExistsDropConstraint = dialect.GetIfExistsDropConstraint(foo, "Bar", null, null);
231+
System.Console.WriteLine(ifExistsDropConstraint);
232+
Assert.AreEqual(expected, ifExistsDropConstraint);
233+
}
234+
235+
[Test]
236+
public void GetIfExistsDropConstraintTest_For_Schema_other_than_dbo_with_schemaName_overload()
237+
{
238+
MsSql2005Dialect dialect = new MsSql2005Dialect();
239+
Table foo = new Table("Foo");
240+
foo.Schema = "Other";
241+
string expected = "if exists (select 1 from sys.objects" +
242+
" where object_id = OBJECT_ID(N'Other.[Bar]')" +
243+
" AND parent_object_id = OBJECT_ID('Other.Foo'))";
244+
string ifExistsDropConstraint = dialect.GetIfExistsDropConstraint(foo, "Bar", null, null);
245+
System.Console.WriteLine(ifExistsDropConstraint);
246+
Assert.AreEqual(expected, ifExistsDropConstraint);
247+
}
248+
249+
[Test]
250+
public void GetIfExistsDropConstraintTest_For_Schema_other_than_dbo_AndInGlobalConfiguration_with_schemaName_overload()
251+
{
252+
MsSql2005Dialect dialect = new MsSql2005Dialect();
253+
Table foo = new Table("Foo");
254+
string defaultSchema = "Other";
255+
string expected = "if exists (select 1 from sys.objects" +
256+
" where object_id = OBJECT_ID(N'Other.[Bar]')" +
257+
" AND parent_object_id = OBJECT_ID('Other.Foo'))";
258+
string ifExistsDropConstraint = dialect.GetIfExistsDropConstraint(foo, "Bar", null, defaultSchema);
259+
System.Console.WriteLine(ifExistsDropConstraint);
260+
Assert.AreEqual(expected, ifExistsDropConstraint);
261+
}
262+
263+
[Test]
264+
public void GetIfExistsDropConstraintTest_For_Catalog_other_than_dbo_with_catalogName_overload()
265+
{
266+
MsSql2005Dialect dialect = new MsSql2005Dialect();
267+
Table foo = new Table("Foo");
268+
foo.Catalog = "Other";
269+
string expected = "if exists (select 1 from sys.objects" +
270+
" where object_id = OBJECT_ID(N'Other.[Bar]')" +
271+
" AND parent_object_id = OBJECT_ID('Other.Foo'))";
272+
string ifExistsDropConstraint = dialect.GetIfExistsDropConstraint(foo, "Bar", null, null);
273+
System.Console.WriteLine(ifExistsDropConstraint);
274+
Assert.AreEqual(expected, ifExistsDropConstraint);
275+
}
276+
277+
[Test]
278+
public void GetIfExistsDropConstraintTest_For_Schema_other_than_dbo_with_catalogName()
279+
{
280+
MsSql2005Dialect dialect = new MsSql2005Dialect();
281+
Table foo = new Table("Foo");
282+
foo.Schema = "Schema";
283+
foo.Catalog = "Catalog";
284+
string expected = "if exists (select 1 from sys.objects" +
285+
" where object_id = OBJECT_ID(N'Catalog.Schema.[Bar]')" +
286+
" AND parent_object_id = OBJECT_ID('Catalog.Schema.Foo'))";
287+
string ifExistsDropConstraint = dialect.GetIfExistsDropConstraint(foo, "Bar", null, null);
288+
System.Console.WriteLine(ifExistsDropConstraint);
289+
Assert.AreEqual(expected, ifExistsDropConstraint);
290+
}
291+
292+
[Test]
293+
public void GetIfExistsDropConstraintTest_For_TableQuoted_SchemaQuoted_CatalogQuoted()
294+
{
295+
MsSql2005Dialect dialect = new MsSql2005Dialect();
296+
Table foo = new Table("`Foo`");
297+
foo.Schema = "`Schema`";
298+
foo.Catalog = "`Catalog`";
299+
string expected = "if exists (select 1 from sys.objects" +
300+
" where object_id = OBJECT_ID(N'[Catalog].[Schema].[Bar]')" +
301+
" AND parent_object_id = OBJECT_ID('[Catalog].[Schema].[Foo]'))";
302+
string ifExistsDropConstraint = dialect.GetIfExistsDropConstraint(foo, "Bar", null, null);
303+
System.Console.WriteLine(ifExistsDropConstraint);
304+
Assert.AreEqual(expected, ifExistsDropConstraint);
305+
}
306+
307+
[Test]
308+
public void GetIfExistsDropConstraintTest_For_TableNotQuoted_SchemaNotQuoted_CatalogNotQuoted()
309+
{
310+
MsSql2005Dialect dialect = new MsSql2005Dialect();
311+
Table foo = new Table("Foo");
312+
foo.Schema = "Schema";
313+
foo.Catalog = "Catalog";
314+
string expected = "if exists (select 1 from sys.objects" +
315+
" where object_id = OBJECT_ID(N'Catalog.Schema.[Bar]')" +
316+
" AND parent_object_id = OBJECT_ID('Catalog.Schema.Foo'))";
317+
string ifExistsDropConstraint = dialect.GetIfExistsDropConstraint(foo, "Bar", null, null);
318+
System.Console.WriteLine(ifExistsDropConstraint);
319+
Assert.AreEqual(expected, ifExistsDropConstraint);
320+
}
321+
322+
[Test]
323+
public void GetIfExistsDropConstraintTest_For_GlobalSchemaQuoted_other_than_dbo_with_GlocalCatalogQuotedName()
324+
{
325+
MsSql2005Dialect dialect = new MsSql2005Dialect();
326+
Table foo = new Table("Foo");
327+
string expected = "if exists (select 1 from sys.objects" +
328+
" where object_id = OBJECT_ID(N'Catalog.Schema.[Bar]')" +
329+
" AND parent_object_id = OBJECT_ID('Catalog.Schema.Foo'))";
330+
string ifExistsDropConstraint = dialect.GetIfExistsDropConstraint(foo, "Bar", "Catalog", "Schema");
331+
System.Console.WriteLine(ifExistsDropConstraint);
332+
Assert.AreEqual(expected, ifExistsDropConstraint);
333+
}
334+
221335
[Test]
222336
public void GetLimitStringWithSqlComments()
223337
{
@@ -303,4 +417,4 @@ private static void VerifyLimitStringForStoredProcedureCalls(string sql)
303417
Assert.That(limitSql, Is.Null, "Limit and Offset: {0}", sql);
304418
}
305419
}
306-
}
420+
}

src/NHibernate.Test/NHSpecificTest/NH2288/Fixture.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ private static void AssertThatCheckOnTableExistenceIsCorrect(Configuration confi
2121
var sb = new StringBuilder(500);
2222
su.Execute(x => sb.AppendLine(x), false, false);
2323
string script = sb.ToString();
24-
Assert.That(script, Is.StringContaining("if exists (select 1 from sys.objects where object_id = OBJECT_ID(N'dbo.[Aclasses_Id_FK]') AND parent_object_id = OBJECT_ID('dbo.Aclass'))"));
24+
Assert.That(script, Is.StringContaining("if exists (select 1 from sys.objects where object_id = OBJECT_ID(N'nhibernate.dbo.[Aclasses_Id_FK]') AND parent_object_id = OBJECT_ID('nhibernate.dbo.Aclass'))"));
2525
}
2626

2727
[Test]
@@ -79,4 +79,4 @@ public class Bclass
7979
public int Id { get; set; }
8080
public ICollection Aclasses { get; set; }
8181
}
82-
}
82+
}

src/NHibernate/Cfg/Configuration.cs

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -816,8 +816,9 @@ public string[] GenerateDropSchemaScript(Dialect.Dialect dialect)
816816
{
817817
SecondPassCompile();
818818

819-
string defaultCatalog = PropertiesHelper.GetString(Environment.DefaultCatalog, properties, null);
820-
string defaultSchema = PropertiesHelper.GetString(Environment.DefaultSchema, properties, null);
819+
// we should quote catalog and schema if needed
820+
string defaultCatalog = GetQuotedName(PropertiesHelper.GetString(Environment.DefaultCatalog, properties, null), dialect);
821+
string defaultSchema = GetQuotedName(PropertiesHelper.GetString(Environment.DefaultSchema, properties, null), dialect);
821822

822823
var script = new List<string>();
823824

@@ -891,8 +892,9 @@ public string[] GenerateSchemaCreationScript(Dialect.Dialect dialect)
891892
{
892893
SecondPassCompile();
893894

894-
string defaultCatalog = PropertiesHelper.GetString(Environment.DefaultCatalog, properties, null);
895-
string defaultSchema = PropertiesHelper.GetString(Environment.DefaultSchema, properties, null);
895+
// we should quote catalog and schema if needed
896+
string defaultCatalog = GetQuotedName(PropertiesHelper.GetString(Environment.DefaultCatalog, properties, null), dialect);
897+
string defaultSchema = GetQuotedName(PropertiesHelper.GetString(Environment.DefaultSchema, properties, null), dialect);
896898

897899
var script = new List<string>();
898900

@@ -2323,8 +2325,9 @@ public string[] GenerateSchemaUpdateScript(Dialect.Dialect dialect, DatabaseMeta
23232325
{
23242326
SecondPassCompile();
23252327

2326-
string defaultCatalog = PropertiesHelper.GetString(Environment.DefaultCatalog, properties, null);
2327-
string defaultSchema = PropertiesHelper.GetString(Environment.DefaultSchema, properties, null);
2328+
// we should quote catalog and schema if needed
2329+
string defaultCatalog = GetQuotedName(PropertiesHelper.GetString(Environment.DefaultCatalog, properties, null), dialect);
2330+
string defaultSchema = GetQuotedName(PropertiesHelper.GetString(Environment.DefaultSchema, properties, null), dialect);
23282331

23292332
var script = new List<string>(50);
23302333
foreach (var table in TableMappings)
@@ -2443,8 +2446,8 @@ public void ValidateSchema(Dialect.Dialect dialect, DatabaseMetadata databaseMet
24432446
private IEnumerable<IPersistentIdentifierGenerator> IterateGenerators(Dialect.Dialect dialect)
24442447
{
24452448
var generators = new Dictionary<string, IPersistentIdentifierGenerator>();
2446-
string defaultCatalog = PropertiesHelper.GetString(Environment.DefaultCatalog, properties, null);
2447-
string defaultSchema = PropertiesHelper.GetString(Environment.DefaultSchema, properties, null);
2449+
string defaultCatalog = GetQuotedName(PropertiesHelper.GetString(Environment.DefaultCatalog, properties, null), dialect);
2450+
string defaultSchema = GetQuotedName(PropertiesHelper.GetString(Environment.DefaultSchema, properties, null), dialect);
24482451

24492452
foreach (var pc in classes.Values)
24502453
{
@@ -2479,6 +2482,25 @@ private IEnumerable<IPersistentIdentifierGenerator> IterateGenerators(Dialect.Di
24792482
return generators.Values;
24802483
}
24812484

2485+
/// <summary>
2486+
/// Returns a quoted name(schema/catalog) if needed
2487+
/// </summary>
2488+
/// <param name="name">The schema name</param>
2489+
/// <param name="dialect">The instance of dicalect to use</param>
2490+
/// <returns></returns>
2491+
private string GetQuotedName(string name, Dialect.Dialect dialect)
2492+
{
2493+
if (name == null)
2494+
{
2495+
return null;
2496+
}
24822497

2498+
if (StringHelper.IsBackticksEnclosed(name))
2499+
{
2500+
return dialect.QuoteForSchemaName(StringHelper.PurgeBackticksEnclosing(name));
2501+
}
2502+
2503+
return name;
2504+
}
24832505
}
24842506
}

src/NHibernate/Cfg/Mappings.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -630,7 +630,7 @@ private string GetLogicalTableName(string schema, string catalog, string physica
630630

631631
public string GetLogicalTableName(Table table)
632632
{
633-
return GetLogicalTableName(table.GetQuotedSchema(), table.Catalog, table.GetQuotedName());
633+
return GetLogicalTableName(table.GetQuotedSchema(), table.GetQuotedCatalog(), table.GetQuotedName());
634634
}
635635

636636
public ResultSetMappingDefinition GetResultSetMapping(string name)

src/NHibernate/Dialect/Dialect.cs

Lines changed: 67 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public abstract class Dialect
3939

4040
/// <summary> Characters used for closing quoted sql identifiers </summary>
4141
public const string PossibleClosedQuoteChars = "`'\"]";
42-
42+
4343
private readonly TypeNames _typeNames = new TypeNames();
4444
private readonly TypeNames _hibernateTypeNames = new TypeNames();
4545
private readonly IDictionary<string, string> _properties = new Dictionary<string, string>();
@@ -81,7 +81,7 @@ protected Dialect()
8181
Log.Info("Using dialect: " + this);
8282

8383
_sqlFunctions = CollectionHelper.CreateCaseInsensitiveHashtable(StandardAggregateFunctions);
84-
84+
8585
// standard sql92 functions (can be overridden by subclasses)
8686
RegisterFunction("substring", new AnsiSubstringFunction());
8787
RegisterFunction("locate", new StandardSQLFunction("locate", NHibernateUtil.Int32));
@@ -204,7 +204,8 @@ public virtual string GetTypeName(SqlType sqlType)
204204
if (sqlType.LengthDefined || sqlType.PrecisionDefined)
205205
{
206206
string resultWithLength = _typeNames.Get(sqlType.DbType, sqlType.Length, sqlType.Precision, sqlType.Scale);
207-
if (resultWithLength != null) return resultWithLength;
207+
if (resultWithLength != null)
208+
return resultWithLength;
208209
}
209210

210211
string result = _typeNames.Get(sqlType.DbType);
@@ -711,15 +712,17 @@ public virtual string GetDropForeignKeyConstraintString(string constraintName)
711712
return " drop constraint " + constraintName;
712713
}
713714

715+
714716
/// <summary>
715717
/// The syntax that is used to check if a constraint does not exists before creating it
716718
/// </summary>
717719
/// <param name="table">The table.</param>
718720
/// <param name="name">The name.</param>
719721
/// <returns></returns>
722+
[Obsolete("Can cause issues when a custom schema is defined(https://nhibernate.jira.com/browse/NH-1285). The new overload with the defaultSchema parameter should be used instead")]
720723
public virtual string GetIfNotExistsCreateConstraint(Table table, string name)
721724
{
722-
return "";
725+
return GetIfNotExistsCreateConstraint(table, name, null, null);
723726
}
724727

725728
/// <summary>
@@ -729,9 +732,10 @@ public virtual string GetIfNotExistsCreateConstraint(Table table, string name)
729732
/// <param name="table">The table.</param>
730733
/// <param name="name">The name.</param>
731734
/// <returns></returns>
735+
[Obsolete("Can cause issues when a custom schema is defined(https://nhibernate.jira.com/browse/NH-1285). The new overload with the defaultSchema parameter should be used instead")]
732736
public virtual string GetIfNotExistsCreateConstraintEnd(Table table, string name)
733737
{
734-
return "";
738+
return GetIfNotExistsCreateConstraintEnd(table, name, null, null);
735739
}
736740

737741
/// <summary>
@@ -740,9 +744,10 @@ public virtual string GetIfNotExistsCreateConstraintEnd(Table table, string name
740744
/// <param name="table">The table.</param>
741745
/// <param name="name">The name.</param>
742746
/// <returns></returns>
747+
[Obsolete("Can cause issues when a custom schema is defined(https://nhibernate.jira.com/browse/NH-1285). The new overload with the defaultSchema parameter should be used instead")]
743748
public virtual string GetIfExistsDropConstraint(Table table, string name)
744749
{
745-
return "";
750+
return GetIfExistsDropConstraint(table, name, null, null);
746751
}
747752

748753
/// <summary>
@@ -752,7 +757,62 @@ public virtual string GetIfExistsDropConstraint(Table table, string name)
752757
/// <param name="table">The table.</param>
753758
/// <param name="name">The name.</param>
754759
/// <returns></returns>
760+
[Obsolete("Can cause issues when a custom schema is defined(https://nhibernate.jira.com/browse/NH-1285). The new overload with the defaultSchema parameter should be used instead")]
755761
public virtual string GetIfExistsDropConstraintEnd(Table table, string name)
762+
{
763+
return GetIfExistsDropConstraintEnd(table, name, null, null);
764+
}
765+
766+
/// <summary>
767+
/// The syntax that is used to check if a constraint does not exists before creating it
768+
/// </summary>
769+
/// <param name="table">The table.</param>
770+
/// <param name="name">The name.</param>
771+
/// <param name="defaultCatalog">The defaultCatalog.</param>
772+
/// <param name="defaultSchema">The defaultSchema.</param>
773+
/// <returns></returns>
774+
public virtual string GetIfNotExistsCreateConstraint(Table table, string name, string defaultCatalog, string defaultSchema)
775+
{
776+
return "";
777+
}
778+
779+
/// <summary>
780+
/// The syntax that is used to close the if for a constraint exists check, used
781+
/// for dialects that requires begin/end for ifs
782+
/// </summary>
783+
/// <param name="table">The table.</param>
784+
/// <param name="name">The name.</param>
785+
/// <param name="defaultCatalog">The defaultCatalog.</param>
786+
/// <param name="defaultSchema">The defaultSchema.</param>
787+
/// <returns></returns>
788+
public virtual string GetIfNotExistsCreateConstraintEnd(Table table, string name, string defaultCatalog, string defaultSchema)
789+
{
790+
return "";
791+
}
792+
793+
/// <summary>
794+
/// The syntax that is used to check if a constraint exists before dropping it
795+
/// </summary>
796+
/// <param name="table">The table.</param>
797+
/// <param name="name">The name.</param>
798+
/// <param name="defaultCatalog">The defaultCatalog.</param>
799+
/// <param name="defaultSchema">The defaultSchema.</param>
800+
/// <returns></returns>
801+
public virtual string GetIfExistsDropConstraint(Table table, string name, string defaultCatalog, string defaultSchema)
802+
{
803+
return "";
804+
}
805+
806+
/// <summary>
807+
/// The syntax that is used to close the if for a constraint exists check, used
808+
/// for dialects that requires begin/end for ifs
809+
/// </summary>
810+
/// <param name="table">The table.</param>
811+
/// <param name="name">The name.</param>
812+
/// <param name="defaultCatalog">The defaultCatalog.</param>
813+
/// <param name="defaultSchema">The defaultSchema.</param>
814+
/// <returns></returns>
815+
public virtual string GetIfExistsDropConstraintEnd(Table table, string name, string defaultCatalog, string defaultSchema)
756816
{
757817
return "";
758818
}
@@ -2276,4 +2336,4 @@ public virtual ISQLExceptionConverter BuildSQLExceptionConverter()
22762336
return new SQLStateConverter(ViolatedConstraintNameExtracter);
22772337
}
22782338
}
2279-
}
2339+
}

src/NHibernate/Dialect/MsSql2000Dialect.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -442,22 +442,22 @@ public override long TimestampResolutionInTicks
442442
}
443443
}
444444

445-
public override string GetIfExistsDropConstraint(Table table, string name)
445+
public override string GetIfExistsDropConstraint(Table table, string name, string defaultCatalog, string defaultSchema)
446446
{
447-
string selectExistingObject = GetSelectExistingObject(name, table);
447+
string selectExistingObject = GetSelectExistingObject(name, table, defaultCatalog, defaultSchema);
448448
return string.Format(@"if exists ({0})", selectExistingObject);
449449
}
450450

451-
protected virtual string GetSelectExistingObject(string name, Table table)
451+
protected virtual string GetSelectExistingObject(string name, Table table, string defaultCatalog, string defaultSchema)
452452
{
453453
string objName = table.GetQuotedSchemaName(this) + Quote(name);
454454
return string.Format("select 1 from sysobjects where id = OBJECT_ID(N'{0}') AND parent_obj = OBJECT_ID('{1}')",
455455
objName, table.GetQuotedName(this));
456456
}
457457

458-
public override string GetIfNotExistsCreateConstraint(Table table, string name)
458+
public override string GetIfNotExistsCreateConstraint(Table table, string name, string defaultCatalog, string defaultSchema)
459459
{
460-
string selectExistingObject = GetSelectExistingObject(name, table);
460+
string selectExistingObject = GetSelectExistingObject(name, table, defaultCatalog, defaultSchema);
461461
return string.Format(@"if not exists ({0})", selectExistingObject);
462462
}
463463

0 commit comments

Comments
 (0)