From df8b0c75bb9fdd2a23886f355c14094702c5acfe Mon Sep 17 00:00:00 2001 From: lnu Date: Tue, 12 Sep 2017 09:21:06 +0200 Subject: [PATCH] NH-1285 - Drop/Create script with default_schema/default_catalog fix(SqlServer) NH-2288 - Test updated (fully qualified name) Typo fixed feedbacks, new test, comments previous version restored(failing tests) Refactor quoting out of Configuration. Adjust obsoletes, avoid breaking changes. Missing async regen. Refactor get schema/catalog. --- .../Async/NHSpecificTest/NH2288/Fixture.cs | 2 +- .../DialectTest/MsSql2005DialectFixture.cs | 178 ++++++++++++---- .../NHSpecificTest/NH2288/Fixture.cs | 2 +- src/NHibernate/Cfg/Configuration.cs | 196 ++++++++++-------- src/NHibernate/Cfg/Mappings.cs | 2 +- src/NHibernate/Dialect/Dialect.cs | 177 +++++++++++++++- src/NHibernate/Dialect/MsSql2000Dialect.cs | 59 ++++-- src/NHibernate/Dialect/MsSql2005Dialect.cs | 36 +--- src/NHibernate/Mapping/Constraint.cs | 41 ++-- src/NHibernate/Mapping/ForeignKey.cs | 19 +- src/NHibernate/Mapping/Index.cs | 16 +- src/NHibernate/Mapping/PrimaryKey.cs | 17 +- src/NHibernate/Mapping/Table.cs | 56 ++++- src/NHibernate/Mapping/UniqueKey.cs | 4 +- 14 files changed, 575 insertions(+), 230 deletions(-) diff --git a/src/NHibernate.Test/Async/NHSpecificTest/NH2288/Fixture.cs b/src/NHibernate.Test/Async/NHSpecificTest/NH2288/Fixture.cs index ef4c5ba6c50..673310804e2 100644 --- a/src/NHibernate.Test/Async/NHSpecificTest/NH2288/Fixture.cs +++ b/src/NHibernate.Test/Async/NHSpecificTest/NH2288/Fixture.cs @@ -35,7 +35,7 @@ private static void CheckDialect(Configuration configuration) var sb = new StringBuilder(500); await (su.ExecuteAsync(x => sb.AppendLine(x), false, false, cancellationToken)); string script = sb.ToString(); - Assert.That(script, Does.Contain("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'))")); + Assert.That(script, Does.Contain("if exists (select 1 from nhibernate.sys.objects where object_id = OBJECT_ID(N'nhibernate.dbo.[Aclasses_Id_FK]') and parent_object_id = OBJECT_ID(N'nhibernate.dbo.Aclass'))")); } [Test] diff --git a/src/NHibernate.Test/DialectTest/MsSql2005DialectFixture.cs b/src/NHibernate.Test/DialectTest/MsSql2005DialectFixture.cs index 1d8de1fa100..9a530f9a9a7 100644 --- a/src/NHibernate.Test/DialectTest/MsSql2005DialectFixture.cs +++ b/src/NHibernate.Test/DialectTest/MsSql2005DialectFixture.cs @@ -17,7 +17,7 @@ public void GetLimitString() { var d = new MsSql2005Dialect(); - SqlString str = d.GetLimitString(new SqlString("select distinct c.Contact_Id as Contact1_19_0_, c.Rating as Rating2_19_0_, c.Last_Name as Last_Name3_19_0, c.First_Name as First_Name4_19_0 from dbo.Contact c where COALESCE(c.Rating, 0) > 0 order by c.Rating desc , c.Last_Name , c.First_Name"), new SqlString("111"), new SqlString("222")); + var str = d.GetLimitString(new SqlString("select distinct c.Contact_Id as Contact1_19_0_, c.Rating as Rating2_19_0_, c.Last_Name as Last_Name3_19_0, c.First_Name as First_Name4_19_0 from dbo.Contact c where COALESCE(c.Rating, 0) > 0 order by c.Rating desc , c.Last_Name , c.First_Name"), new SqlString("111"), new SqlString("222")); Assert.AreEqual( "SELECT TOP (222) Contact1_19_0_, Rating2_19_0_, Last_Name3_19_0, First_Name4_19_0 FROM (SELECT *, ROW_NUMBER() OVER(ORDER BY q_.Rating2_19_0_ DESC, q_.Last_Name3_19_0, q_.First_Name4_19_0) as __hibernate_sort_row FROM (select distinct c.Contact_Id as Contact1_19_0_, c.Rating as Rating2_19_0_, c.Last_Name as Last_Name3_19_0, c.First_Name as First_Name4_19_0 from dbo.Contact c where COALESCE(c.Rating, 0) > 0) as q_) as query WHERE query.__hibernate_sort_row > 111 ORDER BY query.__hibernate_sort_row", str.ToString()); @@ -74,19 +74,19 @@ public void OnlyOffsetLimit() { var d = new MsSql2005Dialect(); - SqlString str = d.GetLimitString(new SqlString("select distinct c.Contact_Id as Contact1_19_0_, c._Rating as Rating2_19_0_ from dbo.Contact c where COALESCE(c.Rating, 0) > 0 order by c.Rating desc , c.Last_Name , c.First_Name"), null, new SqlString("10")); + var str = d.GetLimitString(new SqlString("select distinct c.Contact_Id as Contact1_19_0_, c._Rating as Rating2_19_0_ from dbo.Contact c where COALESCE(c.Rating, 0) > 0 order by c.Rating desc , c.Last_Name , c.First_Name"), null, new SqlString("10")); Assert.That(str.ToString(), Is.EqualTo("select distinct TOP (10) c.Contact_Id as Contact1_19_0_, c._Rating as Rating2_19_0_ from dbo.Contact c where COALESCE(c.Rating, 0) > 0 order by c.Rating desc , c.Last_Name , c.First_Name")); } [Test] public void NH1187() { - MsSql2005Dialect d = new MsSql2005Dialect(); - SqlString result = d.GetLimitString(new SqlString("select concat(a.Description,', ', a.Description) as desc from Animal a"), new SqlString("111"), new SqlString("222")); + var d = new MsSql2005Dialect(); + var result = d.GetLimitString(new SqlString("select concat(a.Description,', ', a.Description) as desc from Animal a"), new SqlString("111"), new SqlString("222")); Assert.AreEqual("SELECT TOP (222) desc FROM (select concat(a.Description,', ', a.Description) as desc, ROW_NUMBER() OVER(ORDER BY CURRENT_TIMESTAMP) as __hibernate_sort_row from Animal a) as query WHERE query.__hibernate_sort_row > 111 ORDER BY query.__hibernate_sort_row", result.ToString()); // The test use the function "cast" because cast need the keyWork "as" too - SqlString str = d.GetLimitString(new SqlString("SELECT fish.id, cast('astring, with,comma' as string) as bar FROM fish"), new SqlString("111"), new SqlString("222")); + var str = d.GetLimitString(new SqlString("SELECT fish.id, cast('astring, with,comma' as string) as bar FROM fish"), new SqlString("111"), new SqlString("222")); Assert.AreEqual( "SELECT TOP (222) id, bar FROM (SELECT fish.id, cast('astring, with,comma' as string) as bar, ROW_NUMBER() OVER(ORDER BY CURRENT_TIMESTAMP) as __hibernate_sort_row FROM fish) as query WHERE query.__hibernate_sort_row > 111 ORDER BY query.__hibernate_sort_row", str.ToString()); @@ -97,7 +97,7 @@ public void NH2809() { var d = new MsSql2005Dialect(); - string t = d.GetTypeName(new BinarySqlType()); + var t = d.GetTypeName(new BinarySqlType()); Assert.That(t, Is.EqualTo("VARBINARY(MAX)")); t = d.GetTypeName(new BinarySqlType(), SqlClientDriver.MaxSizeForLengthLimitedBinary - 1, 0, 0); @@ -113,10 +113,10 @@ public void NH2809() [Test] public void QuotedAndParenthesisStringTokenizerTests_WithComma_InQuotes() { - MsSql2005Dialect.QuotedAndParenthesisStringTokenizer tokenizier = - new MsSql2005Dialect.QuotedAndParenthesisStringTokenizer( + var tokenizier = + new Dialect.Dialect.QuotedAndParenthesisStringTokenizer( new SqlString("select concat(a.Description,', ', a.Description) from Animal a")); - string[] expected = new string[] + var expected = new string[] { "select", "concat(a.Description,', ', a.Description)", @@ -124,7 +124,7 @@ public void QuotedAndParenthesisStringTokenizerTests_WithComma_InQuotes() "Animal", "a" }; - int current = 0; + var current = 0; foreach (SqlString token in tokenizier) { Assert.AreEqual(expected[current], token.ToString()); @@ -136,10 +136,10 @@ public void QuotedAndParenthesisStringTokenizerTests_WithComma_InQuotes() [Test] public void QuotedAndParenthesisStringTokenizerTests_WithFunctionCallContainingComma() { - MsSql2005Dialect.QuotedAndParenthesisStringTokenizer tokenizier = - new MsSql2005Dialect.QuotedAndParenthesisStringTokenizer( + var tokenizier = + new Dialect.Dialect.QuotedAndParenthesisStringTokenizer( new SqlString("SELECT fish.id, cast('astring, with,comma' as string) as bar, f FROM fish")); - string[] expected = new string[] + var expected = new string[] { "SELECT", "fish.id", @@ -152,9 +152,9 @@ public void QuotedAndParenthesisStringTokenizerTests_WithFunctionCallContainingC "FROM", "fish" }; - int current = 0; - IList tokens = tokenizier.GetTokens(); - foreach (SqlString token in tokens) + var current = 0; + var tokens = tokenizier.GetTokens(); + foreach (var token in tokens) { Assert.AreEqual(expected[current], token.ToString()); current += 1; @@ -165,10 +165,10 @@ public void QuotedAndParenthesisStringTokenizerTests_WithFunctionCallContainingC [Test] public void QuotedStringTokenizerTests() { - MsSql2005Dialect.QuotedAndParenthesisStringTokenizer tokenizier = - new MsSql2005Dialect.QuotedAndParenthesisStringTokenizer( + var tokenizier = + new Dialect.Dialect.QuotedAndParenthesisStringTokenizer( new SqlString("SELECT fish.\"id column\", fish.'fish name' as 'bar\\' column', f FROM fish")); - string[] expected = new string[] + var expected = new string[] { "SELECT", "fish.\"id column\"", @@ -181,41 +181,104 @@ public void QuotedStringTokenizerTests() "FROM", "fish" }; - int current = 0; - IList tokens = tokenizier.GetTokens(); - foreach (SqlString token in tokens) + var current = 0; + var tokens = tokenizier.GetTokens(); + foreach (var token in tokens) { Assert.AreEqual(expected[current], token.ToString()); current += 1; } - Assert.AreEqual(current, expected.Length); + Assert.That(expected, Has.Length.EqualTo(current)); + } + + [Test] + public void GetIfExistsDropConstraintTest_without_catalog_without_schema() + { + var dialect = new MsSql2005Dialect(); + + const string expected = "if exists (select 1 from sys.objects" + + " where object_id = OBJECT_ID(N'[Bar]')" + + " and parent_object_id = OBJECT_ID(N'Foo'))"; + var ifExistsDropConstraint = dialect.GetIfExistsDropConstraint(null, null, "Foo", "Bar"); + Assert.That(ifExistsDropConstraint, Is.EqualTo(expected)); + } + + [Test] + public void GetIfExistsDropConstraintTest_without_catalog_without_schema_with_quoted_table() + { + var dialect = new MsSql2005Dialect(); + + const string expected = "if exists (select 1 from sys.objects" + + " where object_id = OBJECT_ID(N'[Bar]')" + + " and parent_object_id = OBJECT_ID(N'[Foo]'))"; + var ifExistsDropConstraint = dialect.GetIfExistsDropConstraint(null, null, "[Foo]", "Bar"); + Assert.That(ifExistsDropConstraint, Is.EqualTo(expected)); + } + + [Test] + public void GetIfExistsDropConstraintTest_with_schema() + { + var dialect = new MsSql2005Dialect(); + const string expected = "if exists (select 1 from sys.objects" + + " where object_id = OBJECT_ID(N'Other.[Bar]')" + + " and parent_object_id = OBJECT_ID(N'Other.Foo'))"; + var ifExistsDropConstraint = dialect.GetIfExistsDropConstraint(null, "Other", "Foo", "Bar"); + Assert.That(ifExistsDropConstraint, Is.EqualTo(expected)); + } + + [Test] + public void GetIfExistsDropConstraintTest_with_quoted_schema() + { + var dialect = new MsSql2005Dialect(); + const string expected = "if exists (select 1 from sys.objects" + + " where object_id = OBJECT_ID(N'[Other].[Bar]')" + + " and parent_object_id = OBJECT_ID(N'[Other].Foo'))"; + var ifExistsDropConstraint = dialect.GetIfExistsDropConstraint(null, "[Other]", "Foo", "Bar"); + Assert.That(ifExistsDropConstraint, Is.EqualTo(expected)); + } + + [Test] + public void GetIfExistsDropConstraintTest_with_catalog_without_schema() + { + var dialect = new MsSql2005Dialect(); + const string expected = "if exists (select 1 from Catalog.sys.objects" + + " where object_id = OBJECT_ID(N'Catalog..[Bar]')" + + " and parent_object_id = OBJECT_ID(N'Catalog..Foo'))"; + var ifExistsDropConstraint = dialect.GetIfExistsDropConstraint("Catalog", null, "Foo", "Bar"); + Assert.That(ifExistsDropConstraint, Is.EqualTo(expected)); + } + + [Test] + public void GetIfExistsDropConstraintTest_with_quoted_catalog_without_schema() + { + var dialect = new MsSql2005Dialect(); + const string expected = "if exists (select 1 from [Catalog].sys.objects" + + " where object_id = OBJECT_ID(N'[Catalog]..[Bar]')" + + " and parent_object_id = OBJECT_ID(N'[Catalog]..Foo'))"; + var ifExistsDropConstraint = dialect.GetIfExistsDropConstraint("[Catalog]", null, "Foo", "Bar"); + Assert.That(ifExistsDropConstraint, Is.EqualTo(expected)); } [Test] - public void GetIfExistsDropConstraintTest_without_schema() + public void GetIfExistsDropConstraintTest_with_catalog_with_schema() { - MsSql2005Dialect dialect = new MsSql2005Dialect(); - Table foo = new Table("Foo"); - string expected = "if exists (select 1 from sys.objects" + - " where object_id = OBJECT_ID(N'[Bar]')" + - " AND parent_object_id = OBJECT_ID('Foo'))"; - string ifExistsDropConstraint = dialect.GetIfExistsDropConstraint(foo, "Bar"); - System.Console.WriteLine(ifExistsDropConstraint); - Assert.AreEqual(expected, ifExistsDropConstraint); + var dialect = new MsSql2005Dialect(); + const string expected = "if exists (select 1 from Catalog.sys.objects" + + " where object_id = OBJECT_ID(N'Catalog.Schema.[Bar]')" + + " and parent_object_id = OBJECT_ID(N'Catalog.Schema.Foo'))"; + var ifExistsDropConstraint = dialect.GetIfExistsDropConstraint("Catalog", "Schema", "Foo", "Bar"); + Assert.That(ifExistsDropConstraint, Is.EqualTo(expected)); } [Test] - public void GetIfExistsDropConstraintTest_For_Schema_other_than_dbo() + public void GetIfExistsDropConstraintTest_with_quoted_catalog_quoted_schema_quoted_table() { - MsSql2005Dialect dialect = new MsSql2005Dialect(); - Table foo = new Table("Foo"); - foo.Schema = "Other"; - string expected = "if exists (select 1 from sys.objects" + - " where object_id = OBJECT_ID(N'Other.[Bar]')" + - " AND parent_object_id = OBJECT_ID('Other.Foo'))"; - string ifExistsDropConstraint = dialect.GetIfExistsDropConstraint(foo, "Bar"); - System.Console.WriteLine(ifExistsDropConstraint); - Assert.AreEqual(expected, ifExistsDropConstraint); + var dialect = new MsSql2005Dialect(); + const string expected = "if exists (select 1 from [Catalog].sys.objects" + + " where object_id = OBJECT_ID(N'[Catalog].[Schema].[Bar]')" + + " and parent_object_id = OBJECT_ID(N'[Catalog].[Schema].[Foo]'))"; + var ifExistsDropConstraint = dialect.GetIfExistsDropConstraint("[Catalog]", "[Schema]", "[Foo]", "Bar"); + Assert.That(ifExistsDropConstraint, Is.EqualTo(expected)); } [Test] @@ -302,5 +365,34 @@ private static void VerifyLimitStringForStoredProcedureCalls(string sql) limitSql = d.GetLimitString(new SqlString(sql), new SqlString("10"), new SqlString("2")); Assert.That(limitSql, Is.Null, "Limit and Offset: {0}", sql); } + + [Test] + public void QualifyTableWithCatalogAndWithoutSchema() + { + var d = new MsSql2005Dialect(); + + var t = new Table + { + Name = "name", + Catalog = "catalog" + }; + + Assert.That(t.GetQualifiedName(d), Is.EqualTo("catalog..name")); + Assert.That(d.Qualify("catalog", null, "table"), Is.EqualTo("catalog..table")); + } + + [Test] + public void QualifyTableWithoutCatalogAndWithoutSchema() + { + var d = new MsSql2005Dialect(); + + var t = new Table + { + Name = "name" + }; + + Assert.That(t.GetQualifiedName(d), Is.EqualTo("name")); + Assert.That(d.Qualify(null, null, "table"), Is.EqualTo("table")); + } } -} \ No newline at end of file +} diff --git a/src/NHibernate.Test/NHSpecificTest/NH2288/Fixture.cs b/src/NHibernate.Test/NHSpecificTest/NH2288/Fixture.cs index 9b8369b2e35..dc529f781f5 100644 --- a/src/NHibernate.Test/NHSpecificTest/NH2288/Fixture.cs +++ b/src/NHibernate.Test/NHSpecificTest/NH2288/Fixture.cs @@ -23,7 +23,7 @@ private static void AssertThatCheckOnTableExistenceIsCorrect(Configuration confi var sb = new StringBuilder(500); su.Execute(x => sb.AppendLine(x), false, false); string script = sb.ToString(); - Assert.That(script, Does.Contain("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'))")); + Assert.That(script, Does.Contain("if exists (select 1 from nhibernate.sys.objects where object_id = OBJECT_ID(N'nhibernate.dbo.[Aclasses_Id_FK]') and parent_object_id = OBJECT_ID(N'nhibernate.dbo.Aclass'))")); } [Test] diff --git a/src/NHibernate/Cfg/Configuration.cs b/src/NHibernate/Cfg/Configuration.cs index a701dd4d757..01cf85eebc0 100644 --- a/src/NHibernate/Cfg/Configuration.cs +++ b/src/NHibernate/Cfg/Configuration.cs @@ -117,7 +117,7 @@ public Configuration(SerializationInfo info, StreamingContext context) private T GetSerialedObject(SerializationInfo info, string name) { - return (T)info.GetValue(name, typeof(T)); + return (T) info.GetValue(name, typeof(T)); } [SecurityCritical] @@ -817,8 +817,8 @@ public string[] GenerateDropSchemaScript(Dialect.Dialect dialect) { SecondPassCompile(); - string defaultCatalog = PropertiesHelper.GetString(Environment.DefaultCatalog, properties, null); - string defaultSchema = PropertiesHelper.GetString(Environment.DefaultSchema, properties, null); + var defaultCatalog = GetQuotedDefaultCatalog(dialect); + var defaultSchema = GetQuotedDefaultSchema(dialect); var script = new List(); @@ -892,8 +892,8 @@ public string[] GenerateSchemaCreationScript(Dialect.Dialect dialect) { SecondPassCompile(); - string defaultCatalog = PropertiesHelper.GetString(Environment.DefaultCatalog, properties, null); - string defaultSchema = PropertiesHelper.GetString(Environment.DefaultSchema, properties, null); + var defaultCatalog = GetQuotedDefaultCatalog(dialect); + var defaultSchema = GetQuotedDefaultSchema(dialect); var script = new List(); @@ -1111,7 +1111,7 @@ private void SecondPassCompile() } Property prop = clazz.GetReferencedProperty(upr.propertyName); - ((SimpleValue)prop.Value).IsAlternateUniqueKey = true; + ((SimpleValue) prop.Value).IsAlternateUniqueKey = true; } //TODO: Somehow add the newly created foreign keys to the internal collection @@ -1219,7 +1219,7 @@ public EventListeners EventListeners { get { return eventListeners; } } - + private string defaultAssembly; private string defaultNamespace; @@ -1636,7 +1636,7 @@ internal RootClass GetRootClassMapping(string clazz) { try { - return (RootClass)GetClassMapping(clazz); + return (RootClass) GetClassMapping(clazz); } catch (InvalidCastException) { @@ -1918,7 +1918,7 @@ public void SetListeners(ListenerType type, string[] listenerClasses) } else { - var listeners = (object[])Array.CreateInstance(eventListeners.GetListenerClassFor(type), listenerClasses.Length); + var listeners = (object[]) Array.CreateInstance(eventListeners.GetListenerClassFor(type), listenerClasses.Length); for (int i = 0; i < listeners.Length; i++) { try @@ -1950,7 +1950,7 @@ public void SetListener(ListenerType type, object listener) } else { - var listeners = (object[])Array.CreateInstance(eventListeners.GetListenerClassFor(type), 1); + var listeners = (object[]) Array.CreateInstance(eventListeners.GetListenerClassFor(type), 1); listeners[0] = listener; SetListeners(type, listeners); } @@ -2084,106 +2084,106 @@ public void SetListeners(ListenerType type, object[] listeners) switch (type) { case ListenerType.Autoflush: - eventListeners.AutoFlushEventListeners = (IAutoFlushEventListener[])listeners; + eventListeners.AutoFlushEventListeners = (IAutoFlushEventListener[]) listeners; break; case ListenerType.Merge: - eventListeners.MergeEventListeners = (IMergeEventListener[])listeners; + eventListeners.MergeEventListeners = (IMergeEventListener[]) listeners; break; case ListenerType.Create: - eventListeners.PersistEventListeners = (IPersistEventListener[])listeners; + eventListeners.PersistEventListeners = (IPersistEventListener[]) listeners; break; case ListenerType.CreateOnFlush: - eventListeners.PersistOnFlushEventListeners = (IPersistEventListener[])listeners; + eventListeners.PersistOnFlushEventListeners = (IPersistEventListener[]) listeners; break; case ListenerType.Delete: - eventListeners.DeleteEventListeners = (IDeleteEventListener[])listeners; + eventListeners.DeleteEventListeners = (IDeleteEventListener[]) listeners; break; case ListenerType.DirtyCheck: - eventListeners.DirtyCheckEventListeners = (IDirtyCheckEventListener[])listeners; + eventListeners.DirtyCheckEventListeners = (IDirtyCheckEventListener[]) listeners; break; case ListenerType.Evict: - eventListeners.EvictEventListeners = (IEvictEventListener[])listeners; + eventListeners.EvictEventListeners = (IEvictEventListener[]) listeners; break; case ListenerType.Flush: - eventListeners.FlushEventListeners = (IFlushEventListener[])listeners; + eventListeners.FlushEventListeners = (IFlushEventListener[]) listeners; break; case ListenerType.FlushEntity: - eventListeners.FlushEntityEventListeners = (IFlushEntityEventListener[])listeners; + eventListeners.FlushEntityEventListeners = (IFlushEntityEventListener[]) listeners; break; case ListenerType.Load: - eventListeners.LoadEventListeners = (ILoadEventListener[])listeners; + eventListeners.LoadEventListeners = (ILoadEventListener[]) listeners; break; case ListenerType.LoadCollection: - eventListeners.InitializeCollectionEventListeners = (IInitializeCollectionEventListener[])listeners; + eventListeners.InitializeCollectionEventListeners = (IInitializeCollectionEventListener[]) listeners; break; case ListenerType.Lock: - eventListeners.LockEventListeners = (ILockEventListener[])listeners; + eventListeners.LockEventListeners = (ILockEventListener[]) listeners; break; case ListenerType.Refresh: - eventListeners.RefreshEventListeners = (IRefreshEventListener[])listeners; + eventListeners.RefreshEventListeners = (IRefreshEventListener[]) listeners; break; case ListenerType.Replicate: - eventListeners.ReplicateEventListeners = (IReplicateEventListener[])listeners; + eventListeners.ReplicateEventListeners = (IReplicateEventListener[]) listeners; break; case ListenerType.SaveUpdate: - eventListeners.SaveOrUpdateEventListeners = (ISaveOrUpdateEventListener[])listeners; + eventListeners.SaveOrUpdateEventListeners = (ISaveOrUpdateEventListener[]) listeners; break; case ListenerType.Save: - eventListeners.SaveEventListeners = (ISaveOrUpdateEventListener[])listeners; + eventListeners.SaveEventListeners = (ISaveOrUpdateEventListener[]) listeners; break; case ListenerType.PreUpdate: - eventListeners.PreUpdateEventListeners = (IPreUpdateEventListener[])listeners; + eventListeners.PreUpdateEventListeners = (IPreUpdateEventListener[]) listeners; break; case ListenerType.Update: - eventListeners.UpdateEventListeners = (ISaveOrUpdateEventListener[])listeners; + eventListeners.UpdateEventListeners = (ISaveOrUpdateEventListener[]) listeners; break; case ListenerType.PreLoad: - eventListeners.PreLoadEventListeners = (IPreLoadEventListener[])listeners; + eventListeners.PreLoadEventListeners = (IPreLoadEventListener[]) listeners; break; case ListenerType.PreDelete: - eventListeners.PreDeleteEventListeners = (IPreDeleteEventListener[])listeners; + eventListeners.PreDeleteEventListeners = (IPreDeleteEventListener[]) listeners; break; case ListenerType.PreInsert: - eventListeners.PreInsertEventListeners = (IPreInsertEventListener[])listeners; + eventListeners.PreInsertEventListeners = (IPreInsertEventListener[]) listeners; break; case ListenerType.PostLoad: - eventListeners.PostLoadEventListeners = (IPostLoadEventListener[])listeners; + eventListeners.PostLoadEventListeners = (IPostLoadEventListener[]) listeners; break; case ListenerType.PostInsert: - eventListeners.PostInsertEventListeners = (IPostInsertEventListener[])listeners; + eventListeners.PostInsertEventListeners = (IPostInsertEventListener[]) listeners; break; case ListenerType.PostUpdate: - eventListeners.PostUpdateEventListeners = (IPostUpdateEventListener[])listeners; + eventListeners.PostUpdateEventListeners = (IPostUpdateEventListener[]) listeners; break; case ListenerType.PostDelete: - eventListeners.PostDeleteEventListeners = (IPostDeleteEventListener[])listeners; + eventListeners.PostDeleteEventListeners = (IPostDeleteEventListener[]) listeners; break; case ListenerType.PostCommitUpdate: - eventListeners.PostCommitUpdateEventListeners = (IPostUpdateEventListener[])listeners; + eventListeners.PostCommitUpdateEventListeners = (IPostUpdateEventListener[]) listeners; break; case ListenerType.PostCommitInsert: - eventListeners.PostCommitInsertEventListeners = (IPostInsertEventListener[])listeners; + eventListeners.PostCommitInsertEventListeners = (IPostInsertEventListener[]) listeners; break; case ListenerType.PostCommitDelete: - eventListeners.PostCommitDeleteEventListeners = (IPostDeleteEventListener[])listeners; + eventListeners.PostCommitDeleteEventListeners = (IPostDeleteEventListener[]) listeners; break; case ListenerType.PreCollectionRecreate: - eventListeners.PreCollectionRecreateEventListeners = (IPreCollectionRecreateEventListener[])listeners; + eventListeners.PreCollectionRecreateEventListeners = (IPreCollectionRecreateEventListener[]) listeners; break; case ListenerType.PreCollectionRemove: - eventListeners.PreCollectionRemoveEventListeners = (IPreCollectionRemoveEventListener[])listeners; + eventListeners.PreCollectionRemoveEventListeners = (IPreCollectionRemoveEventListener[]) listeners; break; case ListenerType.PreCollectionUpdate: - eventListeners.PreCollectionUpdateEventListeners = (IPreCollectionUpdateEventListener[])listeners; + eventListeners.PreCollectionUpdateEventListeners = (IPreCollectionUpdateEventListener[]) listeners; break; case ListenerType.PostCollectionRecreate: - eventListeners.PostCollectionRecreateEventListeners = (IPostCollectionRecreateEventListener[])listeners; + eventListeners.PostCollectionRecreateEventListeners = (IPostCollectionRecreateEventListener[]) listeners; break; case ListenerType.PostCollectionRemove: - eventListeners.PostCollectionRemoveEventListeners = (IPostCollectionRemoveEventListener[])listeners; + eventListeners.PostCollectionRemoveEventListeners = (IPostCollectionRemoveEventListener[]) listeners; break; case ListenerType.PostCollectionUpdate: - eventListeners.PostCollectionUpdateEventListeners = (IPostCollectionUpdateEventListener[])listeners; + eventListeners.PostCollectionUpdateEventListeners = (IPostCollectionUpdateEventListener[]) listeners; break; default: log.Warn("Unrecognized listener type [{0}]", type); @@ -2201,106 +2201,106 @@ public void AppendListeners(ListenerType type, object[] listeners) switch (type) { case ListenerType.Autoflush: - eventListeners.AutoFlushEventListeners = AppendListeners(eventListeners.AutoFlushEventListeners, (IAutoFlushEventListener[])listeners); + eventListeners.AutoFlushEventListeners = AppendListeners(eventListeners.AutoFlushEventListeners, (IAutoFlushEventListener[]) listeners); break; case ListenerType.Merge: - eventListeners.MergeEventListeners = AppendListeners(eventListeners.MergeEventListeners, (IMergeEventListener[])listeners); + eventListeners.MergeEventListeners = AppendListeners(eventListeners.MergeEventListeners, (IMergeEventListener[]) listeners); break; case ListenerType.Create: - eventListeners.PersistEventListeners = AppendListeners(eventListeners.PersistEventListeners, (IPersistEventListener[])listeners); + eventListeners.PersistEventListeners = AppendListeners(eventListeners.PersistEventListeners, (IPersistEventListener[]) listeners); break; case ListenerType.CreateOnFlush: - eventListeners.PersistOnFlushEventListeners = AppendListeners(eventListeners.PersistOnFlushEventListeners, (IPersistEventListener[])listeners); + eventListeners.PersistOnFlushEventListeners = AppendListeners(eventListeners.PersistOnFlushEventListeners, (IPersistEventListener[]) listeners); break; case ListenerType.Delete: - eventListeners.DeleteEventListeners = AppendListeners(eventListeners.DeleteEventListeners, (IDeleteEventListener[])listeners); + eventListeners.DeleteEventListeners = AppendListeners(eventListeners.DeleteEventListeners, (IDeleteEventListener[]) listeners); break; case ListenerType.DirtyCheck: - eventListeners.DirtyCheckEventListeners = AppendListeners(eventListeners.DirtyCheckEventListeners, (IDirtyCheckEventListener[])listeners); + eventListeners.DirtyCheckEventListeners = AppendListeners(eventListeners.DirtyCheckEventListeners, (IDirtyCheckEventListener[]) listeners); break; case ListenerType.Evict: - eventListeners.EvictEventListeners = AppendListeners(eventListeners.EvictEventListeners, (IEvictEventListener[])listeners); + eventListeners.EvictEventListeners = AppendListeners(eventListeners.EvictEventListeners, (IEvictEventListener[]) listeners); break; case ListenerType.Flush: - eventListeners.FlushEventListeners = AppendListeners(eventListeners.FlushEventListeners, (IFlushEventListener[])listeners); + eventListeners.FlushEventListeners = AppendListeners(eventListeners.FlushEventListeners, (IFlushEventListener[]) listeners); break; case ListenerType.FlushEntity: - eventListeners.FlushEntityEventListeners = AppendListeners(eventListeners.FlushEntityEventListeners, (IFlushEntityEventListener[])listeners); + eventListeners.FlushEntityEventListeners = AppendListeners(eventListeners.FlushEntityEventListeners, (IFlushEntityEventListener[]) listeners); break; case ListenerType.Load: - eventListeners.LoadEventListeners = AppendListeners(eventListeners.LoadEventListeners, (ILoadEventListener[])listeners); + eventListeners.LoadEventListeners = AppendListeners(eventListeners.LoadEventListeners, (ILoadEventListener[]) listeners); break; case ListenerType.LoadCollection: - eventListeners.InitializeCollectionEventListeners = AppendListeners(eventListeners.InitializeCollectionEventListeners, (IInitializeCollectionEventListener[])listeners); + eventListeners.InitializeCollectionEventListeners = AppendListeners(eventListeners.InitializeCollectionEventListeners, (IInitializeCollectionEventListener[]) listeners); break; case ListenerType.Lock: - eventListeners.LockEventListeners = AppendListeners(eventListeners.LockEventListeners, (ILockEventListener[])listeners); + eventListeners.LockEventListeners = AppendListeners(eventListeners.LockEventListeners, (ILockEventListener[]) listeners); break; case ListenerType.Refresh: - eventListeners.RefreshEventListeners = AppendListeners(eventListeners.RefreshEventListeners, (IRefreshEventListener[])listeners); + eventListeners.RefreshEventListeners = AppendListeners(eventListeners.RefreshEventListeners, (IRefreshEventListener[]) listeners); break; case ListenerType.Replicate: - eventListeners.ReplicateEventListeners = AppendListeners(eventListeners.ReplicateEventListeners, (IReplicateEventListener[])listeners); + eventListeners.ReplicateEventListeners = AppendListeners(eventListeners.ReplicateEventListeners, (IReplicateEventListener[]) listeners); break; case ListenerType.SaveUpdate: - eventListeners.SaveOrUpdateEventListeners = AppendListeners(eventListeners.SaveOrUpdateEventListeners, (ISaveOrUpdateEventListener[])listeners); + eventListeners.SaveOrUpdateEventListeners = AppendListeners(eventListeners.SaveOrUpdateEventListeners, (ISaveOrUpdateEventListener[]) listeners); break; case ListenerType.Save: - eventListeners.SaveEventListeners = AppendListeners(eventListeners.SaveEventListeners, (ISaveOrUpdateEventListener[])listeners); + eventListeners.SaveEventListeners = AppendListeners(eventListeners.SaveEventListeners, (ISaveOrUpdateEventListener[]) listeners); break; case ListenerType.PreUpdate: - eventListeners.PreUpdateEventListeners = AppendListeners(eventListeners.PreUpdateEventListeners, (IPreUpdateEventListener[])listeners); + eventListeners.PreUpdateEventListeners = AppendListeners(eventListeners.PreUpdateEventListeners, (IPreUpdateEventListener[]) listeners); break; case ListenerType.Update: - eventListeners.UpdateEventListeners = AppendListeners(eventListeners.UpdateEventListeners, (ISaveOrUpdateEventListener[])listeners); + eventListeners.UpdateEventListeners = AppendListeners(eventListeners.UpdateEventListeners, (ISaveOrUpdateEventListener[]) listeners); break; case ListenerType.PreLoad: - eventListeners.PreLoadEventListeners = AppendListeners(eventListeners.PreLoadEventListeners, (IPreLoadEventListener[])listeners); + eventListeners.PreLoadEventListeners = AppendListeners(eventListeners.PreLoadEventListeners, (IPreLoadEventListener[]) listeners); break; case ListenerType.PreDelete: - eventListeners.PreDeleteEventListeners = AppendListeners(eventListeners.PreDeleteEventListeners, (IPreDeleteEventListener[])listeners); + eventListeners.PreDeleteEventListeners = AppendListeners(eventListeners.PreDeleteEventListeners, (IPreDeleteEventListener[]) listeners); break; case ListenerType.PreInsert: - eventListeners.PreInsertEventListeners = AppendListeners(eventListeners.PreInsertEventListeners, (IPreInsertEventListener[])listeners); + eventListeners.PreInsertEventListeners = AppendListeners(eventListeners.PreInsertEventListeners, (IPreInsertEventListener[]) listeners); break; case ListenerType.PostLoad: - eventListeners.PostLoadEventListeners = AppendListeners(eventListeners.PostLoadEventListeners, (IPostLoadEventListener[])listeners); + eventListeners.PostLoadEventListeners = AppendListeners(eventListeners.PostLoadEventListeners, (IPostLoadEventListener[]) listeners); break; case ListenerType.PostInsert: - eventListeners.PostInsertEventListeners = AppendListeners(eventListeners.PostInsertEventListeners, (IPostInsertEventListener[])listeners); + eventListeners.PostInsertEventListeners = AppendListeners(eventListeners.PostInsertEventListeners, (IPostInsertEventListener[]) listeners); break; case ListenerType.PostUpdate: - eventListeners.PostUpdateEventListeners = AppendListeners(eventListeners.PostUpdateEventListeners, (IPostUpdateEventListener[])listeners); + eventListeners.PostUpdateEventListeners = AppendListeners(eventListeners.PostUpdateEventListeners, (IPostUpdateEventListener[]) listeners); break; case ListenerType.PostDelete: - eventListeners.PostDeleteEventListeners = AppendListeners(eventListeners.PostDeleteEventListeners, (IPostDeleteEventListener[])listeners); + eventListeners.PostDeleteEventListeners = AppendListeners(eventListeners.PostDeleteEventListeners, (IPostDeleteEventListener[]) listeners); break; case ListenerType.PostCommitUpdate: - eventListeners.PostCommitUpdateEventListeners = AppendListeners(eventListeners.PostCommitUpdateEventListeners, (IPostUpdateEventListener[])listeners); + eventListeners.PostCommitUpdateEventListeners = AppendListeners(eventListeners.PostCommitUpdateEventListeners, (IPostUpdateEventListener[]) listeners); break; case ListenerType.PostCommitInsert: - eventListeners.PostCommitInsertEventListeners = AppendListeners(eventListeners.PostCommitInsertEventListeners, (IPostInsertEventListener[])listeners); + eventListeners.PostCommitInsertEventListeners = AppendListeners(eventListeners.PostCommitInsertEventListeners, (IPostInsertEventListener[]) listeners); break; case ListenerType.PostCommitDelete: - eventListeners.PostCommitDeleteEventListeners = AppendListeners(eventListeners.PostCommitDeleteEventListeners, (IPostDeleteEventListener[])listeners); + eventListeners.PostCommitDeleteEventListeners = AppendListeners(eventListeners.PostCommitDeleteEventListeners, (IPostDeleteEventListener[]) listeners); break; case ListenerType.PreCollectionRecreate: - eventListeners.PreCollectionRecreateEventListeners = AppendListeners(eventListeners.PreCollectionRecreateEventListeners, (IPreCollectionRecreateEventListener[])listeners); + eventListeners.PreCollectionRecreateEventListeners = AppendListeners(eventListeners.PreCollectionRecreateEventListeners, (IPreCollectionRecreateEventListener[]) listeners); break; case ListenerType.PreCollectionRemove: - eventListeners.PreCollectionRemoveEventListeners = AppendListeners(eventListeners.PreCollectionRemoveEventListeners, (IPreCollectionRemoveEventListener[])listeners); + eventListeners.PreCollectionRemoveEventListeners = AppendListeners(eventListeners.PreCollectionRemoveEventListeners, (IPreCollectionRemoveEventListener[]) listeners); break; case ListenerType.PreCollectionUpdate: - eventListeners.PreCollectionUpdateEventListeners = AppendListeners(eventListeners.PreCollectionUpdateEventListeners, (IPreCollectionUpdateEventListener[])listeners); + eventListeners.PreCollectionUpdateEventListeners = AppendListeners(eventListeners.PreCollectionUpdateEventListeners, (IPreCollectionUpdateEventListener[]) listeners); break; case ListenerType.PostCollectionRecreate: - eventListeners.PostCollectionRecreateEventListeners = AppendListeners(eventListeners.PostCollectionRecreateEventListeners, (IPostCollectionRecreateEventListener[])listeners); + eventListeners.PostCollectionRecreateEventListeners = AppendListeners(eventListeners.PostCollectionRecreateEventListeners, (IPostCollectionRecreateEventListener[]) listeners); break; case ListenerType.PostCollectionRemove: - eventListeners.PostCollectionRemoveEventListeners = AppendListeners(eventListeners.PostCollectionRemoveEventListeners, (IPostCollectionRemoveEventListener[])listeners); + eventListeners.PostCollectionRemoveEventListeners = AppendListeners(eventListeners.PostCollectionRemoveEventListeners, (IPostCollectionRemoveEventListener[]) listeners); break; case ListenerType.PostCollectionUpdate: - eventListeners.PostCollectionUpdateEventListeners = AppendListeners(eventListeners.PostCollectionUpdateEventListeners, (IPostCollectionUpdateEventListener[])listeners); + eventListeners.PostCollectionUpdateEventListeners = AppendListeners(eventListeners.PostCollectionUpdateEventListeners, (IPostCollectionUpdateEventListener[]) listeners); break; default: log.Warn("Unrecognized listener type [{0}]", type); @@ -2323,8 +2323,8 @@ public string[] GenerateSchemaUpdateScript(Dialect.Dialect dialect, IDatabaseMet { SecondPassCompile(); - string defaultCatalog = PropertiesHelper.GetString(Environment.DefaultCatalog, properties, null); - string defaultSchema = PropertiesHelper.GetString(Environment.DefaultSchema, properties, null); + var defaultCatalog = GetQuotedDefaultCatalog(dialect); + var defaultSchema = GetQuotedDefaultSchema(dialect); var script = new List(50); foreach (var table in TableMappings) @@ -2403,8 +2403,8 @@ public void ValidateSchema(Dialect.Dialect dialect, IDatabaseMetadata databaseMe { SecondPassCompile(); - string defaultCatalog = PropertiesHelper.GetString(Environment.DefaultCatalog, properties, null); - string defaultSchema = PropertiesHelper.GetString(Environment.DefaultSchema, properties, null); + var defaultCatalog = GetQuotedDefaultCatalog(dialect); + var defaultSchema = GetQuotedDefaultSchema(dialect); var validationErrors = new List(); var iter = TableMappings; @@ -2453,16 +2453,14 @@ public void ValidateSchema(Dialect.Dialect dialect, IDatabaseMetadata databaseMe private IEnumerable IterateGenerators(Dialect.Dialect dialect) { var generators = new Dictionary(); - string defaultCatalog = PropertiesHelper.GetString(Environment.DefaultCatalog, properties, null); - string defaultSchema = PropertiesHelper.GetString(Environment.DefaultSchema, properties, null); + var defaultCatalog = GetQuotedDefaultCatalog(dialect); + var defaultSchema = GetQuotedDefaultSchema(dialect); foreach (var pc in classes.Values) { if (!pc.IsInherited) { - var ig = - pc.Identifier.CreateIdentifierGenerator(dialect, defaultCatalog, defaultSchema, (RootClass)pc) as - IPersistentIdentifierGenerator; + var ig = pc.Identifier.CreateIdentifierGenerator(dialect, defaultCatalog, defaultSchema, (RootClass) pc) as IPersistentIdentifierGenerator; if (ig != null) { @@ -2475,9 +2473,7 @@ private IEnumerable IterateGenerators(Dialect.Di { if (collection.IsIdentified) { - var ig = - ((IdentifierCollection)collection).Identifier.CreateIdentifierGenerator(dialect, defaultCatalog, defaultSchema, - null) as IPersistentIdentifierGenerator; + var ig = ((IdentifierCollection) collection).Identifier.CreateIdentifierGenerator(dialect, defaultCatalog, defaultSchema, null) as IPersistentIdentifierGenerator; if (ig != null) { @@ -2489,6 +2485,26 @@ private IEnumerable IterateGenerators(Dialect.Di return generators.Values; } + /// + /// Returns the default catalog, quoted converted if needed. + /// + /// The instance of dialect to use + /// The default catalog, with back-tilt quote converted if any. + private string GetQuotedDefaultCatalog(Dialect.Dialect dialect) + { + var name = PropertiesHelper.GetString(Environment.DefaultCatalog, properties, null); + return dialect.ConvertQuotesForCatalogName(name); + } + /// + /// Returns the default catalog, quoted converted if needed. + /// + /// The instance of dialect to use + /// The default catalog, with back-tilt quote converted if any. + private string GetQuotedDefaultSchema(Dialect.Dialect dialect) + { + var name = PropertiesHelper.GetString(Environment.DefaultSchema, properties, null); + return dialect.ConvertQuotesForSchemaName(name); + } } } diff --git a/src/NHibernate/Cfg/Mappings.cs b/src/NHibernate/Cfg/Mappings.cs index 8b955edf087..bbf925639e4 100644 --- a/src/NHibernate/Cfg/Mappings.cs +++ b/src/NHibernate/Cfg/Mappings.cs @@ -630,7 +630,7 @@ private string GetLogicalTableName(string schema, string catalog, string physica public string GetLogicalTableName(Table table) { - return GetLogicalTableName(table.GetQuotedSchema(), table.Catalog, table.GetQuotedName()); + return GetLogicalTableName(table.GetQuotedSchema(), table.GetQuotedCatalog(), table.GetQuotedName()); } public ResultSetMappingDefinition GetResultSetMapping(string name) diff --git a/src/NHibernate/Dialect/Dialect.cs b/src/NHibernate/Dialect/Dialect.cs index 753462bbc27..53a31c43e15 100644 --- a/src/NHibernate/Dialect/Dialect.cs +++ b/src/NHibernate/Dialect/Dialect.cs @@ -40,7 +40,7 @@ public abstract partial class Dialect /// Characters used for closing quoted sql identifiers public const string PossibleClosedQuoteChars = "`'\"]"; - + private readonly TypeNames _typeNames = new TypeNames(); private readonly TypeNames _hibernateTypeNames = new TypeNames(); private readonly IDictionary _properties = new Dictionary(); @@ -390,14 +390,14 @@ public virtual string GetAddForeignKeyConstraintString(string constraintName, st res.Append(" constraint ") .Append(constraintName) .Append(" foreign key (") - .Append(StringHelper.Join(StringHelper.CommaSpace, foreignKey)) + .Append(string.Join(StringHelper.CommaSpace, foreignKey)) .Append(") references ") .Append(referencedTable); if (!referencesPrimaryKey) { res.Append(" (") - .Append(StringHelper.Join(StringHelper.CommaSpace, primaryKey)) + .Append(string.Join(StringHelper.CommaSpace, primaryKey)) .Append(')'); } @@ -758,15 +758,22 @@ public virtual string GetDropForeignKeyConstraintString(string constraintName) return " drop constraint " + constraintName; } + /// /// The syntax that is used to check if a constraint does not exists before creating it /// /// The table. /// The name. /// + // Since v5.1 + [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")] public virtual string GetIfNotExistsCreateConstraint(Table table, string name) { - return ""; + var catalog = table.GetQuotedCatalog(this, null); + var schema = table.GetQuotedSchema(this, null); + var tableName = table.GetQuotedName(this); + + return GetIfNotExistsCreateConstraint(catalog, schema, tableName, name); } /// @@ -776,9 +783,15 @@ public virtual string GetIfNotExistsCreateConstraint(Table table, string name) /// The table. /// The name. /// + // Since v5.1 + [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")] public virtual string GetIfNotExistsCreateConstraintEnd(Table table, string name) { - return ""; + var catalog = table.GetQuotedCatalog(this, null); + var schema = table.GetQuotedSchema(this, null); + var tableName = table.GetQuotedName(this); + + return GetIfNotExistsCreateConstraintEnd(catalog, schema, tableName, name); } /// @@ -787,9 +800,15 @@ public virtual string GetIfNotExistsCreateConstraintEnd(Table table, string name /// The table. /// The name. /// + // Since v5.1 + [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")] public virtual string GetIfExistsDropConstraint(Table table, string name) { - return ""; + var catalog = table.GetQuotedCatalog(this, null); + var schema = table.GetQuotedSchema(this, null); + var tableName = table.GetQuotedName(this); + + return GetIfExistsDropConstraint(catalog, schema, tableName, name); } /// @@ -799,7 +818,67 @@ public virtual string GetIfExistsDropConstraint(Table table, string name) /// The table. /// The name. /// + // Since v5.1 + [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")] public virtual string GetIfExistsDropConstraintEnd(Table table, string name) + { + var catalog = table.GetQuotedCatalog(this, null); + var schema = table.GetQuotedSchema(this, null); + var tableName = table.GetQuotedName(this); + + return GetIfExistsDropConstraintEnd(catalog, schema, tableName, name); + } + + /// + /// The syntax that is used to check if a constraint does not exists before creating it + /// + /// The catalog. + /// The schema. + /// The table. + /// The name. + /// + public virtual string GetIfNotExistsCreateConstraint(string catalog, string schema, string table, string name) + { + return ""; + } + + /// + /// The syntax that is used to close the if for a constraint exists check, used + /// for dialects that requires begin/end for ifs + /// + /// The catalog. + /// The schema. + /// The table. + /// The name. + /// + public virtual string GetIfNotExistsCreateConstraintEnd(string catalog, string schema, string table, string name) + { + return ""; + } + + /// + /// The syntax that is used to check if a constraint exists before dropping it + /// + /// The catalog. + /// The schema. + /// The table. + /// The name. + /// + public virtual string GetIfExistsDropConstraint(string catalog, string schema, string table, string name) + { + return ""; + } + + /// + /// The syntax that is used to close the if for a constraint exists check, used + /// for dialects that requires begin/end for ifs + /// + /// The catalog. + /// The schema. + /// The table. + /// The name. + /// + public virtual string GetIfExistsDropConstraintEnd(string catalog, string schema, string table, string name) { return ""; } @@ -1429,7 +1508,7 @@ IEnumerator IEnumerable.GetEnumerator() public IEnumerator GetEnumerator() { - return ((IEnumerable)this).GetEnumerator(); + return ((IEnumerable) this).GetEnumerator(); } public enum TokenizerState @@ -1641,7 +1720,7 @@ public virtual bool IsQuoted(string name) return (name[0] == OpenQuote && name[name.Length - 1] == CloseQuote); } - public virtual string Qualify(string catalog, string schema, string table) + public virtual string Qualify(string catalog, string schema, string name) { StringBuilder qualifiedName = new StringBuilder(); @@ -1653,7 +1732,7 @@ public virtual string Qualify(string catalog, string schema, string table) { qualifiedName.Append(schema).Append(StringHelper.Dot); } - return qualifiedName.Append(table).ToString(); + return qualifiedName.Append(name).ToString(); } /// @@ -1670,7 +1749,7 @@ public virtual string Qualify(string catalog, string schema, string table) /// protected virtual string Quote(string name) { - string quotedName = name.Replace(OpenQuote.ToString(), new string(OpenQuote, 2)); + var quotedName = name.Replace(OpenQuote.ToString(), new string(OpenQuote, 2)); // in some dbs the Open and Close Quote are the same chars - if they are // then we don't have to escape the Close Quote char because we already @@ -1757,6 +1836,24 @@ public virtual string QuoteForSchemaName(string schemaName) return IsQuoted(schemaName) ? schemaName : Quote(schemaName); } + /// + /// Quotes a name for being used as a catalogname + /// + /// Name of the catalog + /// A Quoted name in the format of OpenQuote + catalogName + CloseQuote + /// + ///

+ /// If the catalogName is already enclosed in the OpenQuote and CloseQuote then this + /// method will return the catalogName that was passed in without going through any + /// Quoting process. So if catalogName is passed in already Quoted make sure that + /// you have escaped all of the chars according to your DataBase's specifications. + ///

+ ///
+ public virtual string QuoteForCatalogName(string catalogName) + { + return IsQuoted(catalogName) ? catalogName : Quote(catalogName); + } + /// /// Unquotes and unescapes an already quoted name /// @@ -1829,6 +1926,66 @@ public virtual string[] UnQuote(string[] quoted) return unquoted; } + /// + /// Convert back-tilt quotes in a name for being used as an aliasname. + /// + /// Name of the alias. + /// A name with back-tilt quotes converted if any. + public virtual string ConvertQuotesForAliasName(string aliasName) + { + return StringHelper.IsBackticksEnclosed(aliasName) + ? Quote(StringHelper.PurgeBackticksEnclosing(aliasName)) + : aliasName; + } + + /// + /// Convert back-tilt quotes in a name for being used as a columnname. + /// + /// Name of the column. + /// A name with back-tilt quotes converted if any. + public virtual string ConvertQuotesForColumnName(string columnName) + { + return StringHelper.IsBackticksEnclosed(columnName) + ? Quote(columnName) + : columnName; + } + + /// + /// Convert back-tilt quotes in a name for being used as a tablename. + /// + /// Name of the table. + /// A name with back-tilt quotes converted if any. + public virtual string ConvertQuotesForTableName(string tableName) + { + return StringHelper.IsBackticksEnclosed(tableName) + ? Quote(tableName) + : tableName; + } + + /// + /// Convert back-tilt quotes in a name for being used as a schemaname. + /// + /// Name of the schema. + /// A name with back-tilt quotes converted if any. + public virtual string ConvertQuotesForSchemaName(string schemaName) + { + return StringHelper.IsBackticksEnclosed(schemaName) + ? Quote(schemaName) + : schemaName; + } + + /// + /// Convert back-tilt quotes in a name for being used as a catalogname. + /// + /// Name of the catalog. + /// A name with back-tilt quotes converted if any. + public virtual string ConvertQuotesForCatalogName(string catalogName) + { + return StringHelper.IsBackticksEnclosed(catalogName) + ? Quote(catalogName) + : catalogName; + } + #endregion #region Union subclass support diff --git a/src/NHibernate/Dialect/MsSql2000Dialect.cs b/src/NHibernate/Dialect/MsSql2000Dialect.cs index 9fbadeeda95..213f7152e63 100644 --- a/src/NHibernate/Dialect/MsSql2000Dialect.cs +++ b/src/NHibernate/Dialect/MsSql2000Dialect.cs @@ -554,6 +554,19 @@ public override bool DropTemporaryTableAfterUse() return true; } + public override string Qualify(string catalog, string schema, string name) + { + if (!string.IsNullOrEmpty(catalog)) + { + return string.Join(".", catalog, schema, name); + } + if (!string.IsNullOrEmpty(schema)) + { + return string.Join(".", schema, name); + } + return name; + } + /// /// /// @@ -621,25 +634,45 @@ public override long TimestampResolutionInTicks } } - public override string GetIfExistsDropConstraint(Table table, string name) + public override string GetIfExistsDropConstraint(string catalog, string schema, string tableName, string name) { - string selectExistingObject = GetSelectExistingObject(name, table); + string selectExistingObject = GetSelectExistingObject(catalog, schema, tableName, name); return string.Format(@"if exists ({0})", selectExistingObject); } + public override string GetIfNotExistsCreateConstraint(string catalog, string schema, string table, string name) + { + string selectExistingObject = GetSelectExistingObject(catalog, schema, table, name); + return string.Format(@"if not exists ({0})", selectExistingObject); + } + + // Since v5.1 + [Obsolete("Please use overload with catalog and schema parameters")] protected virtual string GetSelectExistingObject(string name, Table table) { - string objName = table.GetQuotedSchemaName(this) + Quote(name); - return string.Format("select 1 from sysobjects where id = OBJECT_ID(N'{0}') AND parent_obj = OBJECT_ID('{1}')", - objName, table.GetQuotedName(this)); + var catalog = table.GetQuotedCatalog(this, null); + var schema = table.GetQuotedSchema(this, null); + return GetSelectExistingObject(catalog, schema, table.GetQuotedName(), name); } - public override string GetIfNotExistsCreateConstraint(Table table, string name) + /// + /// Returns a string containing the query to check if an object exists + /// + /// The catalong name + /// The schema name + /// The table name + /// The name of the object + /// + protected virtual string GetSelectExistingObject(string catalog, string schema, string table, string name) { - string selectExistingObject = GetSelectExistingObject(name, table); - return string.Format(@"if not exists ({0})", selectExistingObject); + return + string.Format( + "select 1 from {0} where id = OBJECT_ID(N'{1}') and parent_obj = OBJECT_ID(N'{2}')", + Qualify(catalog, "dbo", "sysobjects"), + Qualify(catalog, schema, Quote(name)), + Qualify(catalog, schema, table)); } - + [Serializable] protected class CountBigQueryFunction : ClassicAggregateFunction { @@ -733,7 +766,7 @@ public LockHintAppender(MsSql2000Dialect dialect, IDictionary // in various kinds of "FROM table1 alias1, table2 alias2". _matchRegex = new Regex(" (" + aliasesPattern + ")([, ]|$)"); _unionSubclassRegex = new Regex(@"from\s+\(((?:.|\r|\n)*)\)(?:\s+as)?\s+(?" + aliasesPattern + ")", RegexOptions.IgnoreCase | RegexOptions.Multiline); - } + } public SqlString AppendLockHint(SqlString sql) { @@ -743,11 +776,11 @@ public SqlString AppendLockHint(SqlString sql) { if (part == Parameter.Placeholder) { - result.Add((Parameter)part); + result.Add((Parameter) part); continue; -} + } - result.Add(ProcessUnionSubclassCase((string)part) ?? _matchRegex.Replace((string)part, ReplaceMatch)); + result.Add(ProcessUnionSubclassCase((string) part) ?? _matchRegex.Replace((string) part, ReplaceMatch)); } return result.ToSqlString(); diff --git a/src/NHibernate/Dialect/MsSql2005Dialect.cs b/src/NHibernate/Dialect/MsSql2005Dialect.cs index a53b2248de8..7383e1214ef 100644 --- a/src/NHibernate/Dialect/MsSql2005Dialect.cs +++ b/src/NHibernate/Dialect/MsSql2005Dialect.cs @@ -2,6 +2,7 @@ using NHibernate.Driver; using NHibernate.Mapping; using NHibernate.SqlCommand; +using NHibernate.Util; namespace NHibernate.Dialect { @@ -43,39 +44,25 @@ public override SqlString GetLimitString(SqlString queryString, SqlString offset /// functionality. /// /// true - public override bool SupportsLimit - { - get { return true; } - } + public override bool SupportsLimit => true; /// /// Sql Server 2005 supports a query statement that provides LIMIT /// functionality with an offset. /// /// true - public override bool SupportsLimitOffset - { - get { return true; } - } + public override bool SupportsLimitOffset => true; - public override bool SupportsVariableLimit - { - get { return true; } - } + public override bool SupportsVariableLimit => true; - protected override string GetSelectExistingObject(string name, Table table) + protected override string GetSelectExistingObject(string catalog, string schema, string table, string name) { - string schema = table.GetQuotedSchemaName(this); - if (schema != null) - { - schema += "."; - } - string objName = string.Format("{0}{1}", schema, Quote(name)); - string parentName = string.Format("{0}{1}", schema, table.GetQuotedName(this)); return string.Format( - "select 1 from sys.objects where object_id = OBJECT_ID(N'{0}') AND parent_object_id = OBJECT_ID('{1}')", objName, - parentName); + "select 1 from {0} where object_id = OBJECT_ID(N'{1}') and parent_object_id = OBJECT_ID(N'{2}')", + Qualify(catalog, "sys", "objects"), + Qualify(catalog, schema, Quote(name)), + Qualify(catalog, schema, table)); } /// @@ -83,10 +70,7 @@ protected override string GetSelectExistingObject(string name, Table table) /// functionality with an offset. /// /// false - public override bool UseMaxForLimit - { - get { return false; } - } + public override bool UseMaxForLimit => false; public override string AppendLockHint(LockMode lockMode, string tableName) { diff --git a/src/NHibernate/Mapping/Constraint.cs b/src/NHibernate/Mapping/Constraint.cs index 21459c87e5e..e4b053d1208 100644 --- a/src/NHibernate/Mapping/Constraint.cs +++ b/src/NHibernate/Mapping/Constraint.cs @@ -71,7 +71,7 @@ public int ColumnSpan public IList Columns { - get{return columns;} + get { return columns; } } /// @@ -99,19 +99,23 @@ public Table Table /// public virtual string SqlDropString(Dialect.Dialect dialect, string defaultCatalog, string defaultSchema) { - if (IsGenerated(dialect)) - { - string ifExists = dialect.GetIfExistsDropConstraint(Table, Name); - string drop = - string.Format("alter table {0} drop constraint {1}", Table.GetQualifiedName(dialect, defaultCatalog, defaultSchema), Name); - string end = dialect.GetIfExistsDropConstraintEnd(Table, Name); - - return ifExists + System.Environment.NewLine + drop + System.Environment.NewLine + end; - } - else + if (!IsGenerated(dialect)) { return null; } + + var catalog = Table.GetQuotedCatalog(dialect, defaultCatalog); + var schema = Table.GetQuotedSchema(dialect, defaultSchema); + var tableName = Table.GetQuotedName(dialect); + + return new StringBuilder() + .AppendLine(dialect.GetIfExistsDropConstraint(catalog, schema, tableName, Name)) + .Append("alter table ") + .Append(Table.GetQualifiedName(dialect, defaultCatalog, defaultSchema)) + .Append(" drop constraint ") + .AppendLine(Name) + .Append(dialect.GetIfExistsDropConstraintEnd(catalog, schema, tableName, Name)) + .ToString(); } /// @@ -126,18 +130,15 @@ public virtual string SqlDropString(Dialect.Dialect dialect, string defaultCatal /// public virtual string SqlCreateString(Dialect.Dialect dialect, IMapping p, string defaultCatalog, string defaultSchema) { - if (IsGenerated(dialect)) - { - string constraintString = SqlConstraintString(dialect, Name, defaultCatalog, defaultSchema); - StringBuilder buf = new StringBuilder("alter table ") - .Append(Table.GetQualifiedName(dialect, defaultCatalog, defaultSchema)) - .Append(constraintString); - return buf.ToString(); - } - else + if (!IsGenerated(dialect)) { return null; } + + StringBuilder buf = new StringBuilder("alter table ") + .Append(Table.GetQualifiedName(dialect, defaultCatalog, defaultSchema)) + .Append(SqlConstraintString(dialect, Name, defaultCatalog, defaultSchema)); + return buf.ToString(); } #endregion diff --git a/src/NHibernate/Mapping/ForeignKey.cs b/src/NHibernate/Mapping/ForeignKey.cs index 67335b03c9a..b27a2569501 100644 --- a/src/NHibernate/Mapping/ForeignKey.cs +++ b/src/NHibernate/Mapping/ForeignKey.cs @@ -86,11 +86,18 @@ public bool CascadeDeleteEnabled /// public override string SqlDropString(Dialect.Dialect dialect, string defaultCatalog, string defaultSchema) { - string ifExists = dialect.GetIfExistsDropConstraint(Table, Name); - string drop = string.Format("alter table {0} {1}", Table.GetQualifiedName(dialect, defaultCatalog, defaultSchema), - dialect.GetDropForeignKeyConstraintString(Name)); - string end = dialect.GetIfExistsDropConstraintEnd(Table, Name); - return ifExists + System.Environment.NewLine + drop + System.Environment.NewLine + end; + var catalog = Table.GetQuotedCatalog(dialect, defaultCatalog); + var schema = Table.GetQuotedSchema(dialect, defaultSchema); + var quotedName = Table.GetQuotedName(dialect); + + return new StringBuilder() + .AppendLine(dialect.GetIfExistsDropConstraint(catalog, schema, quotedName, Name)) + .AppendFormat("alter table ") + .Append(Table.GetQualifiedName(dialect, defaultCatalog, defaultSchema)) + .Append(" ") + .AppendLine(dialect.GetDropForeignKeyConstraintString(Name)) + .Append(dialect.GetIfExistsDropConstraintEnd(catalog, schema, quotedName, Name)) + .ToString(); } #endregion @@ -190,7 +197,7 @@ public override string ToString() result.Append(GetType().FullName) .Append('(') .Append(Table.Name) - .Append(StringHelper.Join(", " , Columns)) + .Append(StringHelper.Join(", ", Columns)) .Append(" ref-columns:") .Append('(') .Append(StringHelper.Join(", ", ReferencedColumns)) diff --git a/src/NHibernate/Mapping/Index.cs b/src/NHibernate/Mapping/Index.cs index 118d4bc51d0..74729189c9b 100644 --- a/src/NHibernate/Mapping/Index.cs +++ b/src/NHibernate/Mapping/Index.cs @@ -44,10 +44,16 @@ public static string BuildSqlCreateIndexString(Dialect.Dialect dialect, string n public static string BuildSqlDropIndexString(Dialect.Dialect dialect, Table table, string name, string defaultCatalog, string defaultSchema) { - string ifExists = dialect.GetIfExistsDropConstraint(table, name); - string drop = string.Format("drop index {0}", StringHelper.Qualify(table.GetQualifiedName(dialect, defaultCatalog, defaultSchema), name)); - string end = dialect.GetIfExistsDropConstraintEnd(table, name); - return ifExists + Environment.NewLine + drop + Environment.NewLine + end; + var catalog = table.GetQuotedCatalog(dialect, defaultCatalog); + var schema = table.GetQuotedSchema(dialect, defaultSchema); + var tableName = table.GetQuotedName(dialect); + + return new StringBuilder() + .AppendLine(dialect.GetIfExistsDropConstraint(catalog, schema, tableName, name)) + .Append("drop index ") + .AppendLine(StringHelper.Qualify(table.GetQualifiedName(dialect, defaultCatalog, defaultSchema), name)) + .Append(dialect.GetIfExistsDropConstraintEnd(catalog, schema, tableName, name)) + .ToString(); } /// @@ -148,4 +154,4 @@ public override string ToString() return GetType().FullName + "(" + Name + ")"; } } -} \ No newline at end of file +} diff --git a/src/NHibernate/Mapping/PrimaryKey.cs b/src/NHibernate/Mapping/PrimaryKey.cs index fd5c734cc8e..d10673a71c3 100644 --- a/src/NHibernate/Mapping/PrimaryKey.cs +++ b/src/NHibernate/Mapping/PrimaryKey.cs @@ -75,12 +75,19 @@ public override string SqlConstraintString(Dialect.Dialect d, string constraintN /// public override string SqlDropString(Dialect.Dialect dialect, string defaultCatalog, string defaultSchema) { - string ifExists = dialect.GetIfExistsDropConstraint(Table, Name); - string drop = string.Format("alter table {0}{1}", Table.GetQualifiedName(dialect, defaultCatalog, defaultSchema), dialect.GetDropPrimaryKeyConstraintString(Name)); - string end = dialect.GetIfExistsDropConstraintEnd(Table, Name); - return ifExists + Environment.NewLine + drop + Environment.NewLine + end; + var catalog = Table.GetQuotedCatalog(dialect, defaultCatalog); + var schema = Table.GetQuotedSchema(dialect, defaultSchema); + var tableName = Table.GetQuotedName(dialect); + + return new StringBuilder() + .AppendLine(dialect.GetIfExistsDropConstraint(catalog, schema, tableName, Name)) + .Append("alter table ") + .Append(Table.GetQualifiedName(dialect, defaultCatalog, defaultSchema)) + .AppendLine(dialect.GetDropPrimaryKeyConstraintString(Name)) + .Append(dialect.GetIfExistsDropConstraintEnd(catalog, schema, tableName, Name)) + .ToString(); } #endregion } -} \ No newline at end of file +} diff --git a/src/NHibernate/Mapping/Table.cs b/src/NHibernate/Mapping/Table.cs index 9956f298118..724ba63abc5 100644 --- a/src/NHibernate/Mapping/Table.cs +++ b/src/NHibernate/Mapping/Table.cs @@ -41,6 +41,7 @@ public class Table : IRelationalModel private IKeyValue idValue; private bool isAbstract; private bool isSchemaQuoted; + private bool isCatalogQuoted; private string name; private bool quoted; private string schema; @@ -274,7 +275,18 @@ public bool HasPrimaryKey public string Catalog { get { return catalog; } - set { catalog = value; } + set + { + if (value != null && value[0] == '`') + { + isCatalogQuoted = true; + catalog = value.Substring(1, value.Length - 2); + } + else + { + catalog = value; + } + } } public string Comment @@ -318,6 +330,11 @@ public bool IsSchemaQuoted get { return isSchemaQuoted; } } + public bool IsCatalogQuoted + { + get { return isCatalogQuoted; } + } + #region IRelationalModel Members /// @@ -493,9 +510,9 @@ public virtual string GetQualifiedName(Dialect.Dialect dialect, string defaultCa { return "( " + subselect + " )"; } - string quotedName = GetQuotedName(dialect); - string usedSchema = schema == null ? defaultSchema : GetQuotedSchema(dialect); - string usedCatalog = catalog ?? defaultCatalog; + var quotedName = GetQuotedName(dialect); + var usedSchema = GetQuotedSchema(dialect, defaultSchema); + var usedCatalog = GetQuotedCatalog(dialect, defaultCatalog); return dialect.Qualify(usedCatalog, usedSchema, quotedName); } @@ -528,19 +545,44 @@ public string GetQuotedSchema() public string GetQuotedSchema(Dialect.Dialect dialect) { - return IsSchemaQuoted ? dialect.OpenQuote + schema + dialect.CloseQuote : schema; + return IsSchemaQuoted ? dialect.QuoteForSchemaName(schema) : schema; + } + + public string GetQuotedSchema(Dialect.Dialect dialect, string defaultQuotedSchema) + { + return schema == null ? defaultQuotedSchema : + GetQuotedSchema(dialect); + } + + /// returns quoted name as it is in the mapping file. + public string GetQuotedCatalog() + { + return IsCatalogQuoted ? "`" + catalog + "`" : catalog; + } + + public string GetQuotedCatalog(Dialect.Dialect dialect) + { + return IsCatalogQuoted ? dialect.QuoteForCatalogName(catalog) : catalog; + } + + public string GetQuotedCatalog(Dialect.Dialect dialect, string defaultQuotedCatalog) + { + return catalog == null ? defaultQuotedCatalog : + GetQuotedCatalog(dialect); } /// /// Gets the schema for this table in quoted form if it is necessary. /// /// - /// The that knows how to quote the table name. + /// The that knows how to quote the schema name. /// /// /// The schema name for this table in a form that is safe to use inside /// of a SQL statement. Quoted if it needs to be, not quoted if it does not need to be. /// + // Since v5.1; back-tilts are removed when storing schema: this thing is non-sens. + [Obsolete("This method is no-op and has no usages")] public string GetQuotedSchemaName(Dialect.Dialect dialect) { if (schema == null) @@ -727,7 +769,7 @@ public UniqueKey GetOrCreateUniqueKey(string keyName) return uk; } - public virtual void CreateForeignKeys() {} + public virtual void CreateForeignKeys() { } public virtual ForeignKey CreateForeignKey(string keyName, IEnumerable keyColumns, string referencedEntityName) { diff --git a/src/NHibernate/Mapping/UniqueKey.cs b/src/NHibernate/Mapping/UniqueKey.cs index a320d8ab5a2..51148cbd3ad 100644 --- a/src/NHibernate/Mapping/UniqueKey.cs +++ b/src/NHibernate/Mapping/UniqueKey.cs @@ -107,10 +107,10 @@ public override bool IsGenerated(Dialect.Dialect dialect) return true; foreach (Column column in ColumnIterator) { - if(column.IsNullable) + if (column.IsNullable) return false; } return true; } } -} \ No newline at end of file +}