From 6c042c60dda274047cc6a46e53c27672404577a8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?=
<12201973+fredericDelaporte@users.noreply.github.com>
Date: Wed, 11 Jul 2018 12:59:36 +0200
Subject: [PATCH 1/3] Fix SQLite validation failure on tables with a schema
Fixes #1609
---
.../SchemaValidateTableWithSchemaFixture.cs | 113 ++++++++++++++++++
.../SchemaValidateTableWithSchemaFixture.cs | 102 ++++++++++++++++
.../SchemaValidator/VersionWithSchema.hbm.xml | 17 +++
src/NHibernate/Dialect/SQLiteDialect.cs | 2 +-
.../Dialect/Schema/SQLiteMetaData.cs | 88 +++++++++++++-
5 files changed, 319 insertions(+), 3 deletions(-)
create mode 100644 src/NHibernate.Test/Async/Tools/hbm2ddl/SchemaValidator/SchemaValidateTableWithSchemaFixture.cs
create mode 100644 src/NHibernate.Test/Tools/hbm2ddl/SchemaValidator/SchemaValidateTableWithSchemaFixture.cs
create mode 100644 src/NHibernate.Test/Tools/hbm2ddl/SchemaValidator/VersionWithSchema.hbm.xml
diff --git a/src/NHibernate.Test/Async/Tools/hbm2ddl/SchemaValidator/SchemaValidateTableWithSchemaFixture.cs b/src/NHibernate.Test/Async/Tools/hbm2ddl/SchemaValidator/SchemaValidateTableWithSchemaFixture.cs
new file mode 100644
index 00000000000..d0f1a6bf409
--- /dev/null
+++ b/src/NHibernate.Test/Async/Tools/hbm2ddl/SchemaValidator/SchemaValidateTableWithSchemaFixture.cs
@@ -0,0 +1,113 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by AsyncGenerator.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+
+using System;
+using System.Data;
+using NHibernate.Dialect;
+using NHibernate.Util;
+using NUnit.Framework;
+
+namespace NHibernate.Test.Tools.hbm2ddl.SchemaValidator
+{
+ using System.Threading.Tasks;
+ [TestFixture]
+ public class SchemaValidateTableWithSchemaFixtureAsync : TestCase
+ {
+ protected override string MappingsAssembly => "NHibernate.Test";
+
+ protected override string[] Mappings => new[] { "Tools.hbm2ddl.SchemaValidator.VersionWithSchema.hbm.xml" };
+
+ protected override bool AppliesTo(Dialect.Dialect dialect)
+ {
+ switch (Dialect)
+ {
+ case MsSql2000Dialect _:
+ case PostgreSQLDialect _:
+ case SQLiteDialect _:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ protected override void CreateSchema()
+ {
+ switch (Dialect)
+ {
+ case MsSql2000Dialect _:
+ case PostgreSQLDialect _:
+ // Must handle the schema manually: mapped database-objects are handled too late.
+ var cnx = Sfi.ConnectionProvider.GetConnection();
+ try
+ {
+ using (var cmd = cnx.CreateCommand())
+ {
+ cmd.CommandText = "create schema Test";
+ cmd.ExecuteNonQuery();
+ }
+ }
+ catch (Exception ex)
+ {
+ // Unfortunateley Assert.Warn and Console.WriteLine at this place seems to be ignored in Rider
+ // viewer.
+ Assert.Warn("Creating the schema failed, assuming it already exists. {0}", ex);
+ Console.WriteLine("Creating the schema failed, assuming it already exists.");
+ Console.WriteLine(ex);
+ }
+ finally
+ {
+ Sfi.ConnectionProvider.CloseConnection(cnx);
+ }
+ break;
+ }
+ base.CreateSchema();
+ }
+
+ protected override void DropSchema()
+ {
+ // SQL-Server do not need this call, but Postgres does not accept dropping a schema carrying objects.
+ base.DropSchema();
+
+ switch (Dialect)
+ {
+ case MsSql2000Dialect _:
+ case PostgreSQLDialect _:
+ var cnx = Sfi.ConnectionProvider.GetConnection();
+ try
+ {
+ using (var cmd = cnx.CreateCommand())
+ {
+ cmd.CommandText = "drop schema Test";
+ cmd.ExecuteNonQuery();
+ }
+ }
+ finally
+ {
+ Sfi.ConnectionProvider.CloseConnection(cnx);
+ }
+ break;
+ }
+ }
+
+ [Test]
+ public async Task ShouldVerifyAsync()
+ {
+ var validator = new Tool.hbm2ddl.SchemaValidator(cfg);
+ try
+ {
+ await (validator.ValidateAsync());
+ }
+ catch (SchemaValidationException sve)
+ {
+ Assert.Fail("Validation failed: {0}.\n{1}", StringHelper.CollectionToString(sve.ValidationErrors), sve);
+ }
+ }
+ }
+}
diff --git a/src/NHibernate.Test/Tools/hbm2ddl/SchemaValidator/SchemaValidateTableWithSchemaFixture.cs b/src/NHibernate.Test/Tools/hbm2ddl/SchemaValidator/SchemaValidateTableWithSchemaFixture.cs
new file mode 100644
index 00000000000..5ccc386e62b
--- /dev/null
+++ b/src/NHibernate.Test/Tools/hbm2ddl/SchemaValidator/SchemaValidateTableWithSchemaFixture.cs
@@ -0,0 +1,102 @@
+using System;
+using System.Data;
+using NHibernate.Dialect;
+using NHibernate.Util;
+using NUnit.Framework;
+
+namespace NHibernate.Test.Tools.hbm2ddl.SchemaValidator
+{
+ [TestFixture]
+ public class SchemaValidateTableWithSchemaFixture : TestCase
+ {
+ protected override string MappingsAssembly => "NHibernate.Test";
+
+ protected override string[] Mappings => new[] { "Tools.hbm2ddl.SchemaValidator.VersionWithSchema.hbm.xml" };
+
+ protected override bool AppliesTo(Dialect.Dialect dialect)
+ {
+ switch (Dialect)
+ {
+ case MsSql2000Dialect _:
+ case PostgreSQLDialect _:
+ case SQLiteDialect _:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ protected override void CreateSchema()
+ {
+ switch (Dialect)
+ {
+ case MsSql2000Dialect _:
+ case PostgreSQLDialect _:
+ // Must handle the schema manually: mapped database-objects are handled too late.
+ var cnx = Sfi.ConnectionProvider.GetConnection();
+ try
+ {
+ using (var cmd = cnx.CreateCommand())
+ {
+ cmd.CommandText = "create schema Test";
+ cmd.ExecuteNonQuery();
+ }
+ }
+ catch (Exception ex)
+ {
+ // Unfortunateley Assert.Warn and Console.WriteLine at this place seems to be ignored in Rider
+ // viewer.
+ Assert.Warn("Creating the schema failed, assuming it already exists. {0}", ex);
+ Console.WriteLine("Creating the schema failed, assuming it already exists.");
+ Console.WriteLine(ex);
+ }
+ finally
+ {
+ Sfi.ConnectionProvider.CloseConnection(cnx);
+ }
+ break;
+ }
+ base.CreateSchema();
+ }
+
+ protected override void DropSchema()
+ {
+ // SQL-Server do not need this call, but Postgres does not accept dropping a schema carrying objects.
+ base.DropSchema();
+
+ switch (Dialect)
+ {
+ case MsSql2000Dialect _:
+ case PostgreSQLDialect _:
+ var cnx = Sfi.ConnectionProvider.GetConnection();
+ try
+ {
+ using (var cmd = cnx.CreateCommand())
+ {
+ cmd.CommandText = "drop schema Test";
+ cmd.ExecuteNonQuery();
+ }
+ }
+ finally
+ {
+ Sfi.ConnectionProvider.CloseConnection(cnx);
+ }
+ break;
+ }
+ }
+
+ [Test]
+ public void ShouldVerify()
+ {
+ var validator = new Tool.hbm2ddl.SchemaValidator(cfg);
+ try
+ {
+ validator.Validate();
+ }
+ catch (SchemaValidationException sve)
+ {
+ Assert.Fail("Validation failed: {0}.\n{1}", StringHelper.CollectionToString(sve.ValidationErrors), sve);
+ }
+ }
+ }
+}
diff --git a/src/NHibernate.Test/Tools/hbm2ddl/SchemaValidator/VersionWithSchema.hbm.xml b/src/NHibernate.Test/Tools/hbm2ddl/SchemaValidator/VersionWithSchema.hbm.xml
new file mode 100644
index 00000000000..fe73b2f166e
--- /dev/null
+++ b/src/NHibernate.Test/Tools/hbm2ddl/SchemaValidator/VersionWithSchema.hbm.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+ uid_table
+ next_hi_value_column
+
+
+
+
+
+
+
diff --git a/src/NHibernate/Dialect/SQLiteDialect.cs b/src/NHibernate/Dialect/SQLiteDialect.cs
index 77d027987f7..802ef14eb6e 100644
--- a/src/NHibernate/Dialect/SQLiteDialect.cs
+++ b/src/NHibernate/Dialect/SQLiteDialect.cs
@@ -190,7 +190,7 @@ protected virtual void RegisterDefaultProperties()
public override Schema.IDataBaseSchema GetDataBaseSchema(DbConnection connection)
{
- return new Schema.SQLiteDataBaseMetaData(connection);
+ return new Schema.SQLiteDataBaseMetaData(connection, this);
}
public override string AddColumnString
diff --git a/src/NHibernate/Dialect/Schema/SQLiteMetaData.cs b/src/NHibernate/Dialect/Schema/SQLiteMetaData.cs
index 8be4242acce..124ea8c874c 100644
--- a/src/NHibernate/Dialect/Schema/SQLiteMetaData.cs
+++ b/src/NHibernate/Dialect/Schema/SQLiteMetaData.cs
@@ -6,7 +6,91 @@ namespace NHibernate.Dialect.Schema
{
public class SQLiteDataBaseMetaData : AbstractDataBaseSchema
{
- public SQLiteDataBaseMetaData(DbConnection connection) : base(connection) {}
+ // Since v5.2
+ [Obsolete("Use overload with dialect argument.")]
+ public SQLiteDataBaseMetaData(DbConnection connection) : this(connection, Dialect.GetDialect()) {}
+
+ public SQLiteDataBaseMetaData(DbConnection connection, Dialect dialect) : base(connection)
+ {
+ _dialect = dialect;
+ }
+
+ private readonly Dialect _dialect;
+
+ public override DataTable GetTables(string catalog, string schemaPattern, string tableNamePattern, string[] types)
+ {
+ if (_dialect is SQLiteDialect)
+ {
+ // SQLiteDialect concatenates catalog and schema to the table name.
+ var actualTablePattern = _dialect.Qualify(catalog, schemaPattern, tableNamePattern);
+ var tables = base.GetTables(null, null, actualTablePattern, types);
+ // Caller may check the table name of yielded results, we need to patch them
+ foreach (DataRow tableRow in tables.Rows)
+ {
+ var tableName = Convert.ToString(tableRow[ColumnNameForTableName]);
+ if (tableName.Equals(actualTablePattern, StringComparison.InvariantCultureIgnoreCase))
+ {
+ tableRow[ColumnNameForTableName] = tableNamePattern;
+ // Columns are looked-up according to the row table name, and schema and catalog data.
+ // We need to patch schema and catalog for being able to reconstruct the adequate table name.
+ if (!string.IsNullOrEmpty(catalog))
+ {
+ tableRow["TABLE_CATALOG"] = catalog;
+ }
+ else
+ {
+ // SQLite indicates "main" here by default, wrecking the other Get method
+ // overrides.
+ tableRow["TABLE_CATALOG"] = string.Empty;
+ }
+ if (!string.IsNullOrEmpty(schemaPattern))
+ {
+ tableRow["TABLE_SCHEMA"] = schemaPattern;
+ }
+ }
+ }
+
+ return tables;
+ }
+
+ return base.GetTables(catalog, schemaPattern, tableNamePattern, types);
+ }
+
+ public override DataTable GetColumns(string catalog, string schemaPattern, string tableNamePattern, string columnNamePattern)
+ {
+ if (_dialect is SQLiteDialect)
+ {
+ // SQLiteDialect concatenates catalog and schema to the table name.
+ var actualTablePattern = _dialect.Qualify(catalog, schemaPattern, tableNamePattern);
+ return base.GetColumns(null, null, actualTablePattern, columnNamePattern);
+ }
+
+ return base.GetColumns(catalog, schemaPattern, tableNamePattern, columnNamePattern);
+ }
+
+ public override DataTable GetForeignKeys(string catalog, string schema, string table)
+ {
+ if (_dialect is SQLiteDialect)
+ {
+ // SQLiteDialect concatenates catalog and schema to the table name.
+ var actualTable = _dialect.Qualify(catalog, schema, table);
+ return base.GetForeignKeys(null, null, actualTable);
+ }
+
+ return base.GetForeignKeys(catalog, schema, table);
+ }
+
+ public override DataTable GetIndexColumns(string catalog, string schemaPattern, string tableName, string indexName)
+ {
+ if (_dialect is SQLiteDialect)
+ {
+ // SQLiteDialect concatenates catalog and schema to the table name.
+ var actualTableName = _dialect.Qualify(catalog, schemaPattern, tableName);
+ return base.GetIndexColumns(null, null, actualTableName, indexName);
+ }
+
+ return base.GetIndexColumns(catalog, schemaPattern, tableName, indexName);
+ }
public override ITableMetadata GetTableMetadata(DataRow rs, bool extras)
{
@@ -93,4 +177,4 @@ public SQLiteForeignKeyMetaData(DataRow rs) : base(rs)
Name = Convert.ToString(rs["CONSTRAINT_NAME"]);
}
}
-}
\ No newline at end of file
+}
From becdd46d0767c5ab7f683370234a8d1174000c69 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?=
<12201973+fredericDelaporte@users.noreply.github.com>
Date: Wed, 11 Jul 2018 18:00:19 +0200
Subject: [PATCH 2/3] fixup! Fix SQLite validation failure on tables with a
schema
Do the same for SQL-Server CE
---
.../SchemaValidateTableWithSchemaFixture.cs | 11 ++-
src/NHibernate/Dialect/MsSqlCeDialect.cs | 2 +-
.../Dialect/Schema/AbstractDataBaseSchema.cs | 97 ++++++++++++++++---
.../Dialect/Schema/MsSqlCeMetaData.cs | 11 ++-
.../Dialect/Schema/SQLiteMetaData.cs | 74 ++------------
5 files changed, 112 insertions(+), 83 deletions(-)
diff --git a/src/NHibernate.Test/Tools/hbm2ddl/SchemaValidator/SchemaValidateTableWithSchemaFixture.cs b/src/NHibernate.Test/Tools/hbm2ddl/SchemaValidator/SchemaValidateTableWithSchemaFixture.cs
index 5ccc386e62b..87afcd89625 100644
--- a/src/NHibernate.Test/Tools/hbm2ddl/SchemaValidator/SchemaValidateTableWithSchemaFixture.cs
+++ b/src/NHibernate.Test/Tools/hbm2ddl/SchemaValidator/SchemaValidateTableWithSchemaFixture.cs
@@ -1,5 +1,4 @@
using System;
-using System.Data;
using NHibernate.Dialect;
using NHibernate.Util;
using NUnit.Framework;
@@ -20,8 +19,16 @@ protected override bool AppliesTo(Dialect.Dialect dialect)
case MsSql2000Dialect _:
case PostgreSQLDialect _:
case SQLiteDialect _:
+ case MsSqlCeDialect _:
return true;
default:
+ // Firebird does not support schema. Its current dialect leave table name being schema prefixed,
+ // which causes SQL parse errors. It has a "create schema" command but instead creates a new
+ // database.
+ // MySql does not truly support schema. Its current dialect leave table name being schema prefixed,
+ // which is interpreted as a database name. It has a "create schema" command but instead creates
+ // a new database.
+ // Oracle tightly bounds schema to users.
return false;
}
}
@@ -61,7 +68,7 @@ protected override void CreateSchema()
protected override void DropSchema()
{
- // SQL-Server do not need this call, but Postgres does not accept dropping a schema carrying objects.
+ // SQL-Server does not need this call, but Postgres does not accept dropping a schema carrying objects.
base.DropSchema();
switch (Dialect)
diff --git a/src/NHibernate/Dialect/MsSqlCeDialect.cs b/src/NHibernate/Dialect/MsSqlCeDialect.cs
index 88c1fa21be1..86407ba2530 100644
--- a/src/NHibernate/Dialect/MsSqlCeDialect.cs
+++ b/src/NHibernate/Dialect/MsSqlCeDialect.cs
@@ -263,7 +263,7 @@ public override bool SupportsLimitOffset
public override IDataBaseSchema GetDataBaseSchema(DbConnection connection)
{
- return new MsSqlCeDataBaseSchema(connection);
+ return new MsSqlCeDataBaseSchema(connection, this);
}
public override SqlString GetLimitString(SqlString querySqlString, SqlString offset, SqlString limit)
diff --git a/src/NHibernate/Dialect/Schema/AbstractDataBaseSchema.cs b/src/NHibernate/Dialect/Schema/AbstractDataBaseSchema.cs
index 5ae17dbd564..dc7caa8e925 100644
--- a/src/NHibernate/Dialect/Schema/AbstractDataBaseSchema.cs
+++ b/src/NHibernate/Dialect/Schema/AbstractDataBaseSchema.cs
@@ -15,20 +15,27 @@ namespace NHibernate.Dialect.Schema
///
public abstract class AbstractDataBaseSchema : IDataBaseSchema
{
- private readonly DbConnection connection;
+ private readonly Dialect _dialect;
- protected AbstractDataBaseSchema(DbConnection connection)
- {
- this.connection = connection;
- }
+ protected AbstractDataBaseSchema(DbConnection connection) : this(connection, null) {}
- protected DbConnection Connection
+ protected AbstractDataBaseSchema(DbConnection connection, Dialect dialect)
{
- get { return connection; }
+ Connection = connection;
+ _dialect = dialect;
}
+ protected DbConnection Connection { get; }
+
public virtual bool IncludeDataTypesInReservedWords => true;
+ ///
+ /// Should be used for searching tables instead of using separately
+ /// the table, schema and catalog names? If , dialect must be provided
+ /// with .
+ ///
+ public virtual bool UseDialectQualifyInsteadOfTableName => false;
+
#region IDataBaseSchema Members
public virtual bool StoresMixedCaseQuotedIdentifiers
@@ -58,8 +65,36 @@ public virtual bool StoresLowerCaseIdentifiers
public virtual DataTable GetTables(string catalog, string schemaPattern, string tableNamePattern, string[] types)
{
+ if (UseDialectQualifyInsteadOfTableName)
+ {
+ var actualTablePattern = GetActualTableName(catalog, schemaPattern, tableNamePattern);
+ var tables = Connection.GetSchema("Tables", new[] { null, null, actualTablePattern });
+
+ // Caller may check the table name of yielded results, we need to patch them
+ foreach (DataRow tableRow in tables.Rows)
+ {
+ var tableName = Convert.ToString(tableRow[ColumnNameForTableName]);
+ if (tableName.Equals(actualTablePattern, StringComparison.InvariantCultureIgnoreCase))
+ {
+ tableRow[ColumnNameForTableName] = tableNamePattern;
+ // Columns are looked-up according to the row table name, and schema and catalog data.
+ // We need to patch schema and catalog for being able to reconstruct the adequate table name.
+ if (!string.IsNullOrEmpty(catalog))
+ {
+ tableRow["TABLE_CATALOG"] = catalog;
+ }
+ if (!string.IsNullOrEmpty(schemaPattern))
+ {
+ tableRow["TABLE_SCHEMA"] = schemaPattern;
+ }
+ }
+ }
+
+ return tables;
+ }
+
var restrictions = new[] { catalog, schemaPattern, tableNamePattern };
- return connection.GetSchema("Tables", restrictions);
+ return Connection.GetSchema("Tables", restrictions);
}
public virtual string ColumnNameForTableName
@@ -72,32 +107,56 @@ public virtual string ColumnNameForTableName
public virtual DataTable GetColumns(string catalog, string schemaPattern, string tableNamePattern,
string columnNamePattern)
{
+ if (UseDialectQualifyInsteadOfTableName)
+ {
+ var actualTablePattern = GetActualTableName(catalog, schemaPattern, tableNamePattern);
+ return Connection.GetSchema("Columns", new[] {null, null, actualTablePattern, columnNamePattern});
+ }
+
var restrictions = new[] {catalog, schemaPattern, tableNamePattern, columnNamePattern};
- return connection.GetSchema("Columns", restrictions);
+ return Connection.GetSchema("Columns", restrictions);
}
public virtual DataTable GetIndexInfo(string catalog, string schemaPattern, string tableName)
{
+ if (UseDialectQualifyInsteadOfTableName)
+ {
+ var actualTableName = GetActualTableName(catalog, schemaPattern, tableName);
+ return Connection.GetSchema("Indexes", new[] {null, null, actualTableName, null});
+ }
+
var restrictions = new[] {catalog, schemaPattern, tableName, null};
- return connection.GetSchema("Indexes", restrictions);
+ return Connection.GetSchema("Indexes", restrictions);
}
public virtual DataTable GetIndexColumns(string catalog, string schemaPattern, string tableName, string indexName)
{
+ if (UseDialectQualifyInsteadOfTableName)
+ {
+ var actualTableName = GetActualTableName(catalog, schemaPattern, tableName);
+ return Connection.GetSchema("IndexColumns", new[] {null, null, actualTableName, indexName, null});
+ }
+
var restrictions = new[] {catalog, schemaPattern, tableName, indexName, null};
- return connection.GetSchema("IndexColumns", restrictions);
+ return Connection.GetSchema("IndexColumns", restrictions);
}
public virtual DataTable GetForeignKeys(string catalog, string schema, string table)
{
+ if (UseDialectQualifyInsteadOfTableName)
+ {
+ var actualTableName = GetActualTableName(catalog, schema, table);
+ return Connection.GetSchema(ForeignKeysSchemaName, new[] {null, null, actualTableName, null});
+ }
+
var restrictions = new[] {catalog, schema, table, null};
- return connection.GetSchema(ForeignKeysSchemaName, restrictions);
+ return Connection.GetSchema(ForeignKeysSchemaName, restrictions);
}
public virtual ISet GetReservedWords()
{
var result = new HashSet(StringComparer.OrdinalIgnoreCase);
- DataTable dtReservedWords = connection.GetSchema(DbMetaDataCollectionNames.ReservedWords);
+ DataTable dtReservedWords = Connection.GetSchema(DbMetaDataCollectionNames.ReservedWords);
foreach (DataRow row in dtReservedWords.Rows)
{
result.Add(row["ReservedWord"].ToString());
@@ -105,7 +164,7 @@ public virtual ISet GetReservedWords()
if (IncludeDataTypesInReservedWords)
{
- DataTable dtTypes = connection.GetSchema(DbMetaDataCollectionNames.DataTypes);
+ DataTable dtTypes = Connection.GetSchema(DbMetaDataCollectionNames.DataTypes);
foreach (DataRow row in dtTypes.Rows)
{
result.Add(row["TypeName"].ToString());
@@ -120,6 +179,16 @@ protected virtual string ForeignKeysSchemaName
get { return "ForeignKeys"; }
}
+ private string GetActualTableName(string catalog, string schemaPattern, string tableNamePattern)
+ {
+ if (_dialect == null)
+ throw new InvalidOperationException($"{this}: cannot qualify table name without the dialect");
+
+ // _dialect is supposed to concatenate catalog and schema with the table name as an
+ // unqualified name instead of actually qualifying it.
+ return _dialect.Qualify(catalog, schemaPattern, tableNamePattern);
+ }
+
#endregion
}
}
diff --git a/src/NHibernate/Dialect/Schema/MsSqlCeMetaData.cs b/src/NHibernate/Dialect/Schema/MsSqlCeMetaData.cs
index 12671a58d67..0269314eda4 100644
--- a/src/NHibernate/Dialect/Schema/MsSqlCeMetaData.cs
+++ b/src/NHibernate/Dialect/Schema/MsSqlCeMetaData.cs
@@ -6,7 +6,16 @@ namespace NHibernate.Dialect.Schema
{
public class MsSqlCeDataBaseSchema: AbstractDataBaseSchema
{
- public MsSqlCeDataBaseSchema(DbConnection connection) : base(connection) {}
+ // Since v5.2
+ [Obsolete("Use overload with dialect argument.")]
+ public MsSqlCeDataBaseSchema(DbConnection connection) : this(connection, Dialect.GetDialect()) {}
+
+ public MsSqlCeDataBaseSchema(DbConnection connection, Dialect dialect) : base(connection, dialect)
+ {
+ UseDialectQualifyInsteadOfTableName = dialect is MsSqlCeDialect;
+ }
+
+ public override bool UseDialectQualifyInsteadOfTableName { get; }
public override ITableMetadata GetTableMetadata(DataRow rs, bool extras)
{
diff --git a/src/NHibernate/Dialect/Schema/SQLiteMetaData.cs b/src/NHibernate/Dialect/Schema/SQLiteMetaData.cs
index 124ea8c874c..493e4aa7d07 100644
--- a/src/NHibernate/Dialect/Schema/SQLiteMetaData.cs
+++ b/src/NHibernate/Dialect/Schema/SQLiteMetaData.cs
@@ -10,86 +10,30 @@ public class SQLiteDataBaseMetaData : AbstractDataBaseSchema
[Obsolete("Use overload with dialect argument.")]
public SQLiteDataBaseMetaData(DbConnection connection) : this(connection, Dialect.GetDialect()) {}
- public SQLiteDataBaseMetaData(DbConnection connection, Dialect dialect) : base(connection)
+ public SQLiteDataBaseMetaData(DbConnection connection, Dialect dialect) : base(connection, dialect)
{
- _dialect = dialect;
+ UseDialectQualifyInsteadOfTableName = dialect is SQLiteDialect;
}
- private readonly Dialect _dialect;
+ public override bool UseDialectQualifyInsteadOfTableName { get; }
public override DataTable GetTables(string catalog, string schemaPattern, string tableNamePattern, string[] types)
{
- if (_dialect is SQLiteDialect)
+ var tables = base.GetTables(catalog, schemaPattern, tableNamePattern, types);
+ if (UseDialectQualifyInsteadOfTableName)
{
- // SQLiteDialect concatenates catalog and schema to the table name.
- var actualTablePattern = _dialect.Qualify(catalog, schemaPattern, tableNamePattern);
- var tables = base.GetTables(null, null, actualTablePattern, types);
- // Caller may check the table name of yielded results, we need to patch them
foreach (DataRow tableRow in tables.Rows)
{
var tableName = Convert.ToString(tableRow[ColumnNameForTableName]);
- if (tableName.Equals(actualTablePattern, StringComparison.InvariantCultureIgnoreCase))
+ if (tableName.Equals(tableNamePattern, StringComparison.InvariantCultureIgnoreCase))
{
- tableRow[ColumnNameForTableName] = tableNamePattern;
- // Columns are looked-up according to the row table name, and schema and catalog data.
- // We need to patch schema and catalog for being able to reconstruct the adequate table name.
- if (!string.IsNullOrEmpty(catalog))
- {
- tableRow["TABLE_CATALOG"] = catalog;
- }
- else
- {
- // SQLite indicates "main" here by default, wrecking the other Get method
- // overrides.
- tableRow["TABLE_CATALOG"] = string.Empty;
- }
- if (!string.IsNullOrEmpty(schemaPattern))
- {
- tableRow["TABLE_SCHEMA"] = schemaPattern;
- }
+ // SQLite indicates "main" here by default, wrecking the other Get methods.
+ tableRow["TABLE_CATALOG"] = string.Empty;
}
}
-
- return tables;
- }
-
- return base.GetTables(catalog, schemaPattern, tableNamePattern, types);
- }
-
- public override DataTable GetColumns(string catalog, string schemaPattern, string tableNamePattern, string columnNamePattern)
- {
- if (_dialect is SQLiteDialect)
- {
- // SQLiteDialect concatenates catalog and schema to the table name.
- var actualTablePattern = _dialect.Qualify(catalog, schemaPattern, tableNamePattern);
- return base.GetColumns(null, null, actualTablePattern, columnNamePattern);
- }
-
- return base.GetColumns(catalog, schemaPattern, tableNamePattern, columnNamePattern);
- }
-
- public override DataTable GetForeignKeys(string catalog, string schema, string table)
- {
- if (_dialect is SQLiteDialect)
- {
- // SQLiteDialect concatenates catalog and schema to the table name.
- var actualTable = _dialect.Qualify(catalog, schema, table);
- return base.GetForeignKeys(null, null, actualTable);
- }
-
- return base.GetForeignKeys(catalog, schema, table);
- }
-
- public override DataTable GetIndexColumns(string catalog, string schemaPattern, string tableName, string indexName)
- {
- if (_dialect is SQLiteDialect)
- {
- // SQLiteDialect concatenates catalog and schema to the table name.
- var actualTableName = _dialect.Qualify(catalog, schemaPattern, tableName);
- return base.GetIndexColumns(null, null, actualTableName, indexName);
}
- return base.GetIndexColumns(catalog, schemaPattern, tableName, indexName);
+ return tables;
}
public override ITableMetadata GetTableMetadata(DataRow rs, bool extras)
From a683e2587787032ce7b67da7694876feaf0648a8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?=
<12201973+fredericDelaporte@users.noreply.github.com>
Date: Thu, 12 Jul 2018 00:31:56 +0200
Subject: [PATCH 3/3] fixup! Fix SQLite validation failure on tables with a
schema
Regen async
---
.../SchemaValidateTableWithSchemaFixture.cs | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/src/NHibernate.Test/Async/Tools/hbm2ddl/SchemaValidator/SchemaValidateTableWithSchemaFixture.cs b/src/NHibernate.Test/Async/Tools/hbm2ddl/SchemaValidator/SchemaValidateTableWithSchemaFixture.cs
index d0f1a6bf409..3e719891bfe 100644
--- a/src/NHibernate.Test/Async/Tools/hbm2ddl/SchemaValidator/SchemaValidateTableWithSchemaFixture.cs
+++ b/src/NHibernate.Test/Async/Tools/hbm2ddl/SchemaValidator/SchemaValidateTableWithSchemaFixture.cs
@@ -9,7 +9,6 @@
using System;
-using System.Data;
using NHibernate.Dialect;
using NHibernate.Util;
using NUnit.Framework;
@@ -31,8 +30,16 @@ protected override bool AppliesTo(Dialect.Dialect dialect)
case MsSql2000Dialect _:
case PostgreSQLDialect _:
case SQLiteDialect _:
+ case MsSqlCeDialect _:
return true;
default:
+ // Firebird does not support schema. Its current dialect leave table name being schema prefixed,
+ // which causes SQL parse errors. It has a "create schema" command but instead creates a new
+ // database.
+ // MySql does not truly support schema. Its current dialect leave table name being schema prefixed,
+ // which is interpreted as a database name. It has a "create schema" command but instead creates
+ // a new database.
+ // Oracle tightly bounds schema to users.
return false;
}
}
@@ -72,7 +79,7 @@ protected override void CreateSchema()
protected override void DropSchema()
{
- // SQL-Server do not need this call, but Postgres does not accept dropping a schema carrying objects.
+ // SQL-Server does not need this call, but Postgres does not accept dropping a schema carrying objects.
base.DropSchema();
switch (Dialect)