Skip to content

Added compatibility for db2 schema update. #474

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 65 additions & 1 deletion src/NHibernate/Dialect/DB2Dialect.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
using System;
using System.Data;
using System.Data.Common;
using System.Text;
using NHibernate.Cfg;
using NHibernate.Dialect.Function;
using NHibernate.SqlCommand;
using NHibernate.Type;
using NHibernate.Util;
using Environment = NHibernate.Cfg.Environment;

namespace NHibernate.Dialect
{
Expand All @@ -27,6 +31,8 @@ public class DB2Dialect : Dialect
/// <summary></summary>
public DB2Dialect()
{
TypeFactory.RegisterType(typeof(Boolean), NHibernateUtil.IntBoolean, new[] { "boolean", "bool" });

RegisterColumnType(DbType.AnsiStringFixedLength, "CHAR(254)");
RegisterColumnType(DbType.AnsiStringFixedLength, 254, "CHAR($l)");
RegisterColumnType(DbType.AnsiString, "VARCHAR(254)");
Expand Down Expand Up @@ -128,6 +134,12 @@ public DB2Dialect()
RegisterFunction("substring", new SQLFunctionTemplate(NHibernateUtil.String, "substring(?1, ?2, ?3)"));

DefaultProperties[Environment.ConnectionDriver] = "NHibernate.Driver.DB2Driver";
DefaultProperties[Environment.QuerySubstitutions] = "true 1, false 0, yes 1, no 0";
}

public override Schema.IDataBaseSchema GetDataBaseSchema(DbConnection connection)
{
return new Schema.DB2MetaData(connection);
}

/// <summary></summary>
Expand Down Expand Up @@ -270,5 +282,57 @@ public override string ForUpdateString
{
get { return " for read only with rs"; }
}

public override string Qualify(string catalog, string schema, string table)
{
StringBuilder qualifiedName = new StringBuilder();
bool quoted = false;

if (!string.IsNullOrEmpty(catalog))
{
if (catalog.StartsWith(OpenQuote.ToString()))
{
catalog = catalog.Substring(1, catalog.Length - 1);
quoted = true;
}
if (catalog.EndsWith(CloseQuote.ToString()))
{
catalog = catalog.Substring(0, catalog.Length - 1);
quoted = true;
}
qualifiedName.Append(catalog).Append(StringHelper.Underscore);
}
if (!string.IsNullOrEmpty(schema))
{
if (schema.StartsWith(OpenQuote.ToString()))
{
schema = schema.Substring(1, schema.Length - 1);
quoted = true;
}
if (schema.EndsWith(CloseQuote.ToString()))
{
schema = schema.Substring(0, schema.Length - 1);
quoted = true;
}
qualifiedName.Append(schema).Append(StringHelper.Underscore);
}

if (table.StartsWith(OpenQuote.ToString()))
{
table = table.Substring(1, table.Length - 1);
quoted = true;
}
if (table.EndsWith(CloseQuote.ToString()))
{
table = table.Substring(0, table.Length - 1);
quoted = true;
}

string name = qualifiedName.Append(table).ToString();
if (quoted)
return OpenQuote + name + CloseQuote;
return name;

}
}
}
103 changes: 103 additions & 0 deletions src/NHibernate/Dialect/Schema/DB2MetaData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
using System;
using System.Data;
using System.Data.Common;

namespace NHibernate.Dialect.Schema
{
public class DB2MetaData : AbstractDataBaseSchema
{
public DB2MetaData(DbConnection connection) : base(connection)
{
}

public override ITableMetadata GetTableMetadata(DataRow rs, bool extras)
{
return new DB2TableMetaData(rs, this, extras);
}

public override DataTable GetIndexColumns(string catalog, string schemaPattern, string tableName, string indexName)
{
var restrictions = new[] { tableName, indexName};
return Connection.GetSchema("Indexes", restrictions);
}
}

public class DB2TableMetaData : AbstractTableMetadata
{
public DB2TableMetaData(DataRow rs, IDataBaseSchema meta, bool extras) : base(rs, meta, extras) {}

protected override IColumnMetadata GetColumnMetadata(DataRow rs)
{
return new DB2ColumnMetaData(rs);
}

protected override string GetColumnName(DataRow rs)
{
return Convert.ToString(rs["COLUMN_NAME"]);
}

protected override string GetConstraintName(DataRow rs)
{
//TODO validate
return Convert.ToString(rs[11]);
//return Convert.ToString(rs["CONSTRAINT_NAME"]);
}

protected override IForeignKeyMetadata GetForeignKeyMetadata(DataRow rs)
{
return new DB2ForeignKeyMetaData(rs);
}

protected override IIndexMetadata GetIndexMetadata(DataRow rs)
{
return new DB2IndexMetaData(rs);
}

protected override string GetIndexName(DataRow rs)
{
return Convert.ToString(rs["INDEX_NAME"]);
}

protected override void ParseTableInfo(DataRow rs)
{
Catalog = Convert.ToString(rs["TABLE_CATALOG"]);
Schema = Convert.ToString(rs["TABLE_SCHEMA"]);
if (string.IsNullOrEmpty(Catalog))
{
Catalog = null;
}
if (string.IsNullOrEmpty(Schema))
{
Schema = null;
}
Name = Convert.ToString(rs["TABLE_NAME"]);
}
}

public class DB2ColumnMetaData : AbstractColumnMetaData
{
public DB2ColumnMetaData(DataRow rs) : base(rs)
{
Name = Convert.ToString(rs["COLUMN_NAME"]);

Nullable = Convert.ToString(rs["IS_NULLABLE"]);
TypeName = Convert.ToString(rs["DATA_TYPE"]);
}
}

public class DB2IndexMetaData : AbstractIndexMetadata
{
public DB2IndexMetaData(DataRow rs) : base(rs)
{
Name = Convert.ToString(rs["INDEX_NAME"]);
}
}

public class DB2ForeignKeyMetaData : AbstractForeignKeyMetadata
{
public DB2ForeignKeyMetaData(DataRow rs) : base(rs)
{
Name = Convert.ToString(rs[11]);
}
}
}
22 changes: 22 additions & 0 deletions src/NHibernate/Driver/DB2Driver.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text.RegularExpressions;
using NHibernate.Dialect;
using NHibernate.SqlCommand;
using NHibernate.SqlTypes;
using NHibernate.Util;

namespace NHibernate.Driver
{
Expand All @@ -7,6 +15,8 @@ namespace NHibernate.Driver
/// </summary>
public class DB2Driver : ReflectionBasedDriver
{
private readonly DB2Dialect _db2Dialect = new DB2Dialect();

/// <summary>
/// Initializes a new instance of the <see cref="DB2Driver"/> class.
/// </summary>
Expand Down Expand Up @@ -40,5 +50,17 @@ public override bool SupportsMultipleOpenReaders
{
get { return false; }
}

protected override void InitializeParameter(IDbDataParameter dbParam, string name, SqlType sqlType)
{
var convertedSqlType = sqlType;

if (convertedSqlType.DbType == DbType.Boolean)
{
convertedSqlType = new SqlType(DbType.Int16);
}

base.InitializeParameter(dbParam, name, convertedSqlType);
}
}
}
8 changes: 5 additions & 3 deletions src/NHibernate/NHibernate.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,9 @@
<Reference Include="System.Xml.Linq" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\SharedAssemblyInfo.cs">
<Link>SharedAssemblyInfo.cs</Link>
</Compile>
<Compile Include="..\SharedAssemblyInfo.cs">
<Link>SharedAssemblyInfo.cs</Link>
</Compile>
<Compile Include="ADOException.cs" />
<Compile Include="AdoNet\MySqlClientBatchingBatcher.cs" />
<Compile Include="AdoNet\MySqlClientBatchingBatcherFactory.cs" />
Expand Down Expand Up @@ -164,6 +164,7 @@
<Compile Include="Dialect\BitwiseNativeOperation.cs" />
<Compile Include="Dialect\Oracle12cDialect.cs" />
<Compile Include="Dialect\PostgreSQLDialect.cs" />
<Compile Include="Dialect\Schema\DB2MetaData.cs" />
<Compile Include="Dialect\Schema\PostgreSQLMetadata.cs" />
<Compile Include="Dialect\Schema\SchemaHelper.cs" />
<Compile Include="Dialect\SQLiteDialect.cs" />
Expand Down Expand Up @@ -703,6 +704,7 @@
<Compile Include="Type\Int16Type.cs" />
<Compile Include="Type\Int32Type.cs" />
<Compile Include="Type\Int64Type.cs" />
<Compile Include="Type\IntBooleanType.cs" />
<Compile Include="Type\IType.cs" />
<Compile Include="Type\IVersionType.cs" />
<Compile Include="Type\ManyToOneType.cs" />
Expand Down
5 changes: 5 additions & 0 deletions src/NHibernate/NHibernateUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,11 @@ public static IType GuessType(System.Type type)
/// </summary>
public static readonly YesNoType YesNo = new YesNoType();

/// <summary>
/// NHibernate IntBoolean type
/// </summary>
public static readonly IntBooleanType IntBoolean = new IntBooleanType();

/// <summary>
/// NHibernate class type
/// </summary>
Expand Down
74 changes: 74 additions & 0 deletions src/NHibernate/Type/IntBooleanType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using System.Data;
using NHibernate.SqlTypes;
using NHibernate.UserTypes;

namespace NHibernate.Type
{
public class IntBooleanType : BooleanType, IUserType
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be done with query substitutions.

{
public override SqlType SqlType
{
get { return new SqlType(DbType.Int32);}
}

public SqlType[] SqlTypes
{
get { return new SqlType[] { SqlType};}
}

public System.Type ReturnedType
{
get { return typeof (bool); }
}
public bool Equals(object x, object y)
{
if (ReferenceEquals(x, y)) return true;

if (x == null || y == null) return false;

return x.Equals(y);
}

public int GetHashCode(object x)
{
return x.GetHashCode();
}

public new void NullSafeSet(IDbCommand cmd, object value, int index)
{
var val = !((bool) value) ? 0 : 1;
NHibernateUtil.Int32.NullSafeSet(cmd, val, index);
}

public override void Set(IDbCommand cmd, object value, int index)
{
var val = !((bool) value) ? 0 : 1;
((IDataParameter) cmd.Parameters[index]).Value = val;
}

public object NullSafeGet(IDataReader rs, string[] names, object owner)
{
return NHibernateUtil.Int32.NullSafeGet(rs, names[0]);
}

public object DeepCopy(object value)
{
return value;
}

public object Replace(object original, object target, object owner)
{
return original;
}

public object Assemble(object cached, object owner)
{
return cached;
}

public object Disassemble(object value)
{
return value;
}
}
}
3 changes: 2 additions & 1 deletion src/NHibernate/Type/TypeFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ private enum TypeClassification

private delegate NullableType NullableTypeCreatorDelegate(SqlType sqlType);

private static void RegisterType(System.Type systemType, IType nhibernateType, IEnumerable<string> aliases)
public static void RegisterType(System.Type systemType, IType nhibernateType, IEnumerable<string> aliases)
{
var typeAliases = new List<string>(aliases);
typeAliases.AddRange(GetClrTypeAliases(systemType));
Expand Down Expand Up @@ -242,6 +242,7 @@ private static void RegisterBuiltInTypes()
RegisterType(NHibernateUtil.Time, new[] { "time" });
RegisterType(NHibernateUtil.TrueFalse, new[] { "true_false" });
RegisterType(NHibernateUtil.YesNo, new[] { "yes_no" });
RegisterType(NHibernateUtil.IntBoolean, new[] {"int_bool"});
RegisterType(NHibernateUtil.Ticks, new[] { "ticks" });
RegisterType(NHibernateUtil.TimeAsTimeSpan, EmptyAliases);
RegisterType(NHibernateUtil.LocalDateTime, new[] { "localdatetime" });
Expand Down