|
From: <fab...@us...> - 2010-08-05 12:30:44
|
Revision: 5114
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5114&view=rev
Author: fabiomaulo
Date: 2010-08-05 12:30:38 +0000 (Thu, 05 Aug 2010)
Log Message:
-----------
Fix NH-2149 (by Paul Wideman)
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Dialect/MySQL5Dialect.cs
trunk/nhibernate/src/NHibernate/Dialect/MySQLDialect.cs
Modified: trunk/nhibernate/src/NHibernate/Dialect/MySQL5Dialect.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/MySQL5Dialect.cs 2010-08-05 12:20:09 UTC (rev 5113)
+++ trunk/nhibernate/src/NHibernate/Dialect/MySQL5Dialect.cs 2010-08-05 12:30:38 UTC (rev 5114)
@@ -12,6 +12,15 @@
RegisterColumnType(DbType.Guid, "BINARY(16)");
}
+ protected override void RegisterCastTypes() {
+ base.RegisterCastTypes();
+ // MySql 5 also supports DECIMAL as a cast type target
+ // http://dev.mysql.com/doc/refman/5.5/en/cast-functions.html
+ RegisterCastType(DbType.Decimal, "DECIMAL");
+ RegisterCastType(DbType.Double, "DECIMAL");
+ RegisterCastType(DbType.Single, "DECIMAL");
+ }
+
//Reference 5.x
//Numeric:
//http://dev.mysql.com/doc/refman/5.0/en/numeric-type-overview.html
Modified: trunk/nhibernate/src/NHibernate/Dialect/MySQLDialect.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/MySQLDialect.cs 2010-08-05 12:20:09 UTC (rev 5113)
+++ trunk/nhibernate/src/NHibernate/Dialect/MySQLDialect.cs 2010-08-05 12:30:38 UTC (rev 5114)
@@ -5,6 +5,7 @@
using NHibernate.Dialect.Function;
using NHibernate.Dialect.Schema;
using NHibernate.SqlCommand;
+using NHibernate.SqlTypes;
using NHibernate.Util;
using Environment=NHibernate.Cfg.Environment;
@@ -32,85 +33,90 @@
/// </remarks>
public class MySQLDialect : Dialect
{
- public MySQLDialect()
- {
- //Reference 3-4.x
- //Numeric:
- //http://dev.mysql.com/doc/refman/4.1/en/numeric-type-overview.html
- //Date and time:
- //http://dev.mysql.com/doc/refman/4.1/en/date-and-time-type-overview.html
- //String:
- //http://dev.mysql.com/doc/refman/5.0/en/string-type-overview.html
- //default:
- //http://dev.mysql.com/doc/refman/5.0/en/data-type-defaults.html
+ private readonly TypeNames castTypeNames = new TypeNames();
- //string type
- RegisterColumnType(DbType.AnsiStringFixedLength, "CHAR(255)");
- RegisterColumnType(DbType.AnsiStringFixedLength, 255, "CHAR($l)");
- RegisterColumnType(DbType.AnsiStringFixedLength, 65535, "TEXT");
- RegisterColumnType(DbType.AnsiStringFixedLength, 16777215, "MEDIUMTEXT");
- RegisterColumnType(DbType.AnsiString, "VARCHAR(255)");
- RegisterColumnType(DbType.AnsiString, 255, "VARCHAR($l)");
- RegisterColumnType(DbType.AnsiString, 65535, "TEXT");
- RegisterColumnType(DbType.AnsiString, 16777215, "MEDIUMTEXT");
- RegisterColumnType(DbType.StringFixedLength, "CHAR(255)");
- RegisterColumnType(DbType.StringFixedLength, 255, "CHAR($l)");
- RegisterColumnType(DbType.StringFixedLength, 65535, "TEXT");
- RegisterColumnType(DbType.StringFixedLength, 16777215, "MEDIUMTEXT");
- RegisterColumnType(DbType.String, "VARCHAR(255)");
- RegisterColumnType(DbType.String, 255, "VARCHAR($l)");
- RegisterColumnType(DbType.String, 65535, "TEXT");
- RegisterColumnType(DbType.String, 16777215, "MEDIUMTEXT");
- //todo: future: add compatibility with decimal???
- //An unpacked fixed-point number. Behaves like a CHAR column;
- //\x93unpacked\x94 means the number is stored as a string, using one character for each digit of the value.
- //M is the total number of digits and D is the number of digits after the decimal point
- //DECIMAL[(M[,D])] [UNSIGNED] [ZEROFILL]
+ public MySQLDialect()
+ {
+ //Reference 3-4.x
+ //Numeric:
+ //http://dev.mysql.com/doc/refman/4.1/en/numeric-type-overview.html
+ //Date and time:
+ //http://dev.mysql.com/doc/refman/4.1/en/date-and-time-type-overview.html
+ //String:
+ //http://dev.mysql.com/doc/refman/5.0/en/string-type-overview.html
+ //default:
+ //http://dev.mysql.com/doc/refman/5.0/en/data-type-defaults.html
- //binary type:
- RegisterColumnType(DbType.Binary, "LONGBLOB");
- RegisterColumnType(DbType.Binary, 127, "TINYBLOB");
- RegisterColumnType(DbType.Binary, 65535, "BLOB");
- RegisterColumnType(DbType.Binary, 16777215, "MEDIUMBLOB");
- //Numeric type:
- RegisterColumnType(DbType.Boolean, "TINYINT(1)"); // SELECT IF(0, 'true', 'false');
- RegisterColumnType(DbType.Byte, "TINYINT UNSIGNED");
- RegisterColumnType(DbType.Currency, "MONEY");
- RegisterColumnType(DbType.Decimal, "NUMERIC(19,5)");
- RegisterColumnType(DbType.Decimal, 19, "NUMERIC($p, $s)");
- RegisterColumnType(DbType.Double, "DOUBLE");
- //The signed range is -32768 to 32767. The unsigned range is 0 to 65535.
- RegisterColumnType(DbType.Int16, "SMALLINT");
- RegisterColumnType(DbType.Int32, "INTEGER"); //alias INT
- //As of MySQL 4.1, SERIAL is an alias for BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE.
- RegisterColumnType(DbType.Int64, "BIGINT");
- //!!!
- //Using FLOAT might give you some unexpected problems because all calculations in MySQL are done with double precision
- RegisterColumnType(DbType.Single, "FLOAT");
- RegisterColumnType(DbType.Byte, 1, "BIT"); //Like TinyInt(i)
- RegisterColumnType(DbType.SByte, "TINYINT");
+ //string type
+ RegisterColumnType(DbType.AnsiStringFixedLength, "CHAR(255)");
+ RegisterColumnType(DbType.AnsiStringFixedLength, 255, "CHAR($l)");
+ RegisterColumnType(DbType.AnsiStringFixedLength, 65535, "TEXT");
+ RegisterColumnType(DbType.AnsiStringFixedLength, 16777215, "MEDIUMTEXT");
+ RegisterColumnType(DbType.AnsiString, "VARCHAR(255)");
+ RegisterColumnType(DbType.AnsiString, 255, "VARCHAR($l)");
+ RegisterColumnType(DbType.AnsiString, 65535, "TEXT");
+ RegisterColumnType(DbType.AnsiString, 16777215, "MEDIUMTEXT");
+ RegisterColumnType(DbType.StringFixedLength, "CHAR(255)");
+ RegisterColumnType(DbType.StringFixedLength, 255, "CHAR($l)");
+ RegisterColumnType(DbType.StringFixedLength, 65535, "TEXT");
+ RegisterColumnType(DbType.StringFixedLength, 16777215, "MEDIUMTEXT");
+ RegisterColumnType(DbType.String, "VARCHAR(255)");
+ RegisterColumnType(DbType.String, 255, "VARCHAR($l)");
+ RegisterColumnType(DbType.String, 65535, "TEXT");
+ RegisterColumnType(DbType.String, 16777215, "MEDIUMTEXT");
+ //todo: future: add compatibility with decimal???
+ //An unpacked fixed-point number. Behaves like a CHAR column;
+ //\x93unpacked\x94 means the number is stored as a string, using one character for each digit of the value.
+ //M is the total number of digits and D is the number of digits after the decimal point
+ //DECIMAL[(M[,D])] [UNSIGNED] [ZEROFILL]
- //UNSINGED Numeric type:
- RegisterColumnType(DbType.UInt16, "SMALLINT UNSIGNED");
- RegisterColumnType(DbType.UInt32, "INTEGER UNSIGNED");
- RegisterColumnType(DbType.UInt64, "BIGINT UNSIGNED");
- //there are no other DbType unsigned...but mysql support Float unsigned, double unsigned, etc..
+ //binary type:
+ RegisterColumnType(DbType.Binary, "LONGBLOB");
+ RegisterColumnType(DbType.Binary, 127, "TINYBLOB");
+ RegisterColumnType(DbType.Binary, 65535, "BLOB");
+ RegisterColumnType(DbType.Binary, 16777215, "MEDIUMBLOB");
- //Date and time type:
- RegisterColumnType(DbType.Date, "DATE");
- RegisterColumnType(DbType.DateTime, "DATETIME");
- RegisterColumnType(DbType.Time, "TIME");
+ //Numeric type:
+ RegisterColumnType(DbType.Boolean, "TINYINT(1)"); // SELECT IF(0, 'true', 'false');
+ RegisterColumnType(DbType.Byte, "TINYINT UNSIGNED");
+ RegisterColumnType(DbType.Currency, "MONEY");
+ RegisterColumnType(DbType.Decimal, "NUMERIC(19,5)");
+ RegisterColumnType(DbType.Decimal, 19, "NUMERIC($p, $s)");
+ RegisterColumnType(DbType.Double, "DOUBLE");
+ //The signed range is -32768 to 32767. The unsigned range is 0 to 65535.
+ RegisterColumnType(DbType.Int16, "SMALLINT");
+ RegisterColumnType(DbType.Int32, "INTEGER"); //alias INT
+ //As of MySQL 4.1, SERIAL is an alias for BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE.
+ RegisterColumnType(DbType.Int64, "BIGINT");
+ //!!!
+ //Using FLOAT might give you some unexpected problems because all calculations in MySQL are done with double precision
+ RegisterColumnType(DbType.Single, "FLOAT");
+ RegisterColumnType(DbType.Byte, 1, "BIT"); //Like TinyInt(i)
+ RegisterColumnType(DbType.SByte, "TINYINT");
- //special:
- RegisterColumnType(DbType.Guid, "VARCHAR(40)");
+ //UNSINGED Numeric type:
+ RegisterColumnType(DbType.UInt16, "SMALLINT UNSIGNED");
+ RegisterColumnType(DbType.UInt32, "INTEGER UNSIGNED");
+ RegisterColumnType(DbType.UInt64, "BIGINT UNSIGNED");
+ //there are no other DbType unsigned...but mysql support Float unsigned, double unsigned, etc..
- //functions:
- RegisterFunction("concat", new VarArgsSQLFunction(NHibernateUtil.String, "concat(", ",", ")"));
+ //Date and time type:
+ RegisterColumnType(DbType.Date, "DATE");
+ RegisterColumnType(DbType.DateTime, "DATETIME");
+ RegisterColumnType(DbType.Time, "TIME");
- DefaultProperties[Environment.ConnectionDriver] = "NHibernate.Driver.MySqlDataDriver";
- }
+ //special:
+ RegisterColumnType(DbType.Guid, "VARCHAR(40)");
+ RegisterCastTypes();
+
+ //functions:
+ RegisterFunction("concat", new VarArgsSQLFunction(NHibernateUtil.String, "concat(", ",", ")"));
+
+ DefaultProperties[Environment.ConnectionDriver] = "NHibernate.Driver.MySqlDataDriver";
+ }
+
/// <summary></summary>
public override string AddColumnString
{
@@ -245,5 +251,57 @@
{
get { return "create temporary table if not exists"; }
}
+
+ protected virtual void RegisterCastTypes()
+ {
+ // According to the MySql documentation (http://dev.mysql.com/doc/refman/4.1/en/cast-functions.html)
+ // only a few values are supported for the cast target type: BINARY, CHAR, DATE, DATETIME,
+ // SIGNED, TIME, and UNSIGNED. So we must limit our possible cast types to these
+
+ // The Dialect.GetCastTypeName() method uses the default length, precision, and
+ // scale values, so there's no need to consider those values here either, just use the defaults
+ RegisterCastType(DbType.AnsiString, "CHAR");
+ RegisterCastType(DbType.AnsiStringFixedLength, "CHAR");
+ RegisterCastType(DbType.String, "CHAR");
+ RegisterCastType(DbType.StringFixedLength, "CHAR");
+ RegisterCastType(DbType.Binary, "BINARY");
+ RegisterCastType(DbType.Int16, "SIGNED");
+ RegisterCastType(DbType.Int32, "SIGNED");
+ RegisterCastType(DbType.Int64, "SIGNED");
+ RegisterCastType(DbType.UInt16, "UNSIGNED");
+ RegisterCastType(DbType.UInt32, "UNSIGNED");
+ RegisterCastType(DbType.UInt64, "UNSIGNED");
+ RegisterCastType(DbType.Guid, "CHAR(40)");
+ RegisterCastType(DbType.Time, "TIME");
+ RegisterCastType(DbType.Date, "DATE");
+ RegisterCastType(DbType.DateTime, "DATETIME");
+ }
+
+ /// <summary>
+ /// Suclasses register a typename for the given type code, to be used in CAST()
+ /// statements.
+ /// </summary>
+ /// <param name="code">The typecode</param>
+ /// <param name="name">The database type name</param>
+ protected void RegisterCastType(DbType code, string name)
+ {
+ castTypeNames.Put(code, name);
+ }
+
+ /// <summary>
+ /// Get the name of the database type appropriate for casting operations
+ /// (via the CAST() SQL function) for the given <see cref="SqlType"/> typecode.
+ /// </summary>
+ /// <param name="sqlType">The <see cref="SqlType"/> typecode </param>
+ /// <returns> The database type name </returns>
+ public override string GetCastTypeName(SqlType sqlType)
+ {
+ string result = castTypeNames.Get(sqlType.DbType);
+ if (result == null)
+ {
+ throw new HibernateException(string.Format("No CAST() type mapping for SqlType {0}", sqlType));
+ }
+ return result;
+ }
}
}
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|