Final (Stable) Version of AdvantageDatabaseServer8 Dialect
using System;
using System.Data;
using System.Data.Common;
using NHibernate.Dialect.Function;
using NHibernate.Dialect.Schema;
using NHibernate.Driver;
using NHibernate.SqlCommand;
using Environment = NHibernate.Cfg.Environment;
namespace NHibernate.Dialect
{
/// <summary>
/// A dialect for Sybase's Advantage Database Server 8.0 and
above.
/// </summary>
public class AdvantageDatabaseServer8Dialect : Dialect
{
public AdvantageDatabaseServer8Dialect()
{
RegisterDefaultProperties();
RegisterKeywords();
RegisterCharacterTypeMappings();
RegisterNumericTypeMappings();
RegisterDateTimeTypeMappings();
RegisterLargeObjectTypeMappings();
RegisterFunctions();
}
protected virtual void RegisterDefaultProperties()
{
DefaultProperties[Environment.ConnectionProvider] =
"NHibernate.Connection.DriverConnectionProvider";
DefaultProperties[Environment.ConnectionDriver] =
"NHibernate.Driver.AdvantageDatabaseServerDriver";
DefaultProperties[Environment.BatchSize] = "20";
DefaultProperties[Environment.QuerySubstitutions] = "true
1, false 0, yes 'Y', no 'N'";
DefaultProperties[Environment.Hbm2ddlKeyWords] = "none";
}
protected virtual void RegisterKeywords()
{
#region Programability
RegisterKeyword("top");
RegisterKeyword("declare");
RegisterKeyword("as");
RegisterKeyword("between");
RegisterKeyword("cast");
RegisterKeyword("begin");
RegisterKeyword("end");
RegisterKeyword("constraint");
RegisterKeyword("fetch");
RegisterKeyword("function");
RegisterKeyword("in");
RegisterKeyword("into");
RegisterKeyword("left");
#endregion
#region DataTypes
RegisterKeyword("shortint");
RegisterKeyword("integer");
RegisterKeyword("double");
RegisterKeyword("curdouble");
RegisterKeyword("logical");
RegisterKeyword("autoincrement");
RegisterKeyword("binary");
RegisterKeyword("image");
RegisterKeyword("raw");
RegisterKeyword("character");
RegisterKeyword("cicharacter");
RegisterKeyword("nvarchar");
RegisterKeyword("memo");
RegisterKeyword("numeric");
RegisterKeyword("date");
RegisterKeyword("shortdate");
RegisterKeyword("time");
RegisterKeyword("timestamp");
RegisterKeyword("money");
RegisterKeyword("rowversion");
RegisterKeyword("modtime");
#endregion
RegisterKeyword("cursor");
RegisterKeyword("timestamp");
RegisterKeyword("uniqueidentifier");
RegisterKeyword("sql_variant");
RegisterKeyword("table");
}
protected virtual void RegisterFunctions()
{
RegisterFunction("count", new
StandardSQLFunction("count"));
RegisterFunction("abs", new StandardSQLFunction("abs"));
RegisterFunction("absval", new
StandardSQLFunction("absval"));
RegisterFunction("sign", new StandardSQLFunction("sign",
NHibernateUtil.Int32));
RegisterFunction("ceiling", new
StandardSQLFunction("ceiling"));
RegisterFunction("ceil", new StandardSQLFunction("ceil"));
RegisterFunction("floor", new
StandardSQLFunction("floor"));
RegisterFunction("round", new
StandardSQLFunction("round"));
RegisterFunction("acos", new StandardSQLFunction("acos",
NHibernateUtil.Double));
RegisterFunction("asin", new StandardSQLFunction("asin",
NHibernateUtil.Double));
RegisterFunction("atan", new StandardSQLFunction("atan",
NHibernateUtil.Double));
RegisterFunction("cos", new StandardSQLFunction("cos",
NHibernateUtil.Double));
RegisterFunction("cot", new StandardSQLFunction("cot",
NHibernateUtil.Double));
RegisterFunction("degrees", new
StandardSQLFunction("degrees", NHibernateUtil.Double));
RegisterFunction("exp", new StandardSQLFunction("exp",
NHibernateUtil.Double));
RegisterFunction("float", new StandardSQLFunction("float",
NHibernateUtil.Double));
RegisterFunction("hex", new StandardSQLFunction("hex",
NHibernateUtil.String));
RegisterFunction("ln", new StandardSQLFunction("ln",
NHibernateUtil.Double));
RegisterFunction("log", new StandardSQLFunction("log",
NHibernateUtil.Double));
RegisterFunction("log10", new StandardSQLFunction("log10",
NHibernateUtil.Double));
RegisterFunction("mod", new
SQLFunctionTemplate(NHibernateUtil.Int32, "((?1) % (?2))"));
RegisterFunction("radians", new
StandardSQLFunction("radians", NHibernateUtil.Double));
RegisterFunction("rand", new NoArgSQLFunction("rand",
NHibernateUtil.Double));
RegisterFunction("sin", new StandardSQLFunction("sin",
NHibernateUtil.Double));
RegisterFunction("soundex", new
StandardSQLFunction("soundex", NHibernateUtil.String));
RegisterFunction("sqrt", new StandardSQLFunction("sqrt",
NHibernateUtil.Double));
RegisterFunction("stddev", new
StandardSQLFunction("stddev", NHibernateUtil.Double));
RegisterFunction("tan", new StandardSQLFunction("tan",
NHibernateUtil.Double));
RegisterFunction("variance", new
StandardSQLFunction("variance", NHibernateUtil.Double));
RegisterFunction("left", new
SQLFunctionTemplate(NHibernateUtil.String, "left(?1, ?2)"));
RegisterFunction("right", new
SQLFunctionTemplate(NHibernateUtil.String, "right(?1, ?2)"));
RegisterFunction("locate", new
StandardSQLFunction("charindex", NHibernateUtil.Int32));
RegisterFunction("current_timestamp", new
NoArgSQLFunction("now", NHibernateUtil.DateTime, true));
RegisterFunction("second", new
SQLFunctionTemplate(NHibernateUtil.Int32, "extract(second from ?1)"));
RegisterFunction("minute", new
SQLFunctionTemplate(NHibernateUtil.Int32, "extract(minute from ?1)"));
RegisterFunction("hour", new
SQLFunctionTemplate(NHibernateUtil.Int32, "extract(hour from ?1)"));
RegisterFunction("day", new
SQLFunctionTemplate(NHibernateUtil.Int32, "extract(day from ?1)"));
RegisterFunction("month", new
SQLFunctionTemplate(NHibernateUtil.Int32, "extract(month from ?1)"));
RegisterFunction("year", new
SQLFunctionTemplate(NHibernateUtil.Int32, "extract(year from ?1)"));
RegisterFunction("concat", new
VarArgsSQLFunction(NHibernateUtil.String, "(", "+", ")"));
RegisterFunction("chr", new StandardSQLFunction("chr",
NHibernateUtil.Character));
RegisterFunction("upper", new
StandardSQLFunction("upper"));
RegisterFunction("ucase", new
StandardSQLFunction("ucase"));
RegisterFunction("lcase", new
StandardSQLFunction("lcase"));
RegisterFunction("lower", new
StandardSQLFunction("lower"));
RegisterFunction("length", new StandardSQLFunction("len",
NHibernateUtil.Int32));
RegisterFunction("ltrim", new
StandardSQLFunction("ltrim"));
RegisterFunction("trim", new
SQLFunctionTemplate(NHibernateUtil.String, "trim(?1)"));
RegisterFunction("iif", new SQLFunctionTemplate(null,
"iif(?1, ?2, ?3)"));
RegisterFunction("replace", new
StandardSafeSQLFunction("replace", NHibernateUtil.String, 3));
RegisterFunction("str", new
SQLFunctionTemplate(NHibernateUtil.String, "cast(?1 as
sql_varchar)"));
RegisterFunction("substring", new
EmulatedLengthSubstringFunction());
}
protected virtual void RegisterLargeObjectTypeMappings()
{
RegisterColumnType(DbType.Binary, "BINARY");
RegisterColumnType(DbType.Binary, "IMAGE");
}
protected virtual void RegisterDateTimeTypeMappings()
{
RegisterColumnType(DbType.Date, "DATE");
RegisterColumnType(DbType.Date, "SHORTDATE");
RegisterColumnType(DbType.Time, "TIME");
RegisterColumnType(DbType.DateTime, "TIMESTAMP");
RegisterColumnType(DbType.DateTime, "MODTIME");
}
protected virtual void RegisterNumericTypeMappings()
{
RegisterColumnType(DbType.Boolean, "NUMERIC(1)");
RegisterColumnType(DbType.Byte, "NUMERIC(3)");
RegisterColumnType(DbType.Currency, "NUMERIC(19,6)");
RegisterColumnType(DbType.Decimal, "NUMERIC(19,5)");
RegisterColumnType(DbType.Decimal, 19, "NUMERIC($p, $s)");
RegisterColumnType(DbType.Double, "DOUBLE");
RegisterColumnType(DbType.Int16, "SHORTINT");
RegisterColumnType(DbType.Int32, "INTEGER");
RegisterColumnType(DbType.Int64, "NUMERIC(19,0)");
RegisterColumnType(DbType.Single, "NUMERIC(19,6)");
}
protected virtual void RegisterCharacterTypeMappings()
{
RegisterColumnType(DbType.AnsiStringFixedLength,
"CHARACTER(255)");
RegisterColumnType(DbType.AnsiStringFixedLength, 4000,
"CHARACTER($l)");
RegisterColumnType(DbType.AnsiString, "NVARCHAR(255)");
RegisterColumnType(DbType.AnsiString,
SqlClientDriver.MaxSizeForLengthLimitedAnsiString, "NVARCHAR($l)");
RegisterColumnType(DbType.AnsiString,
SqlClientDriver.MaxSizeForAnsiClob, "MEMO");
RegisterColumnType(DbType.StringFixedLength,
"CHARACTER(255)");
RegisterColumnType(DbType.StringFixedLength,
SqlClientDriver.MaxSizeForLengthLimitedString, "CHARACTER($l)");
RegisterColumnType(DbType.String, "NVARCHAR(255)");
RegisterColumnType(DbType.String,
SqlClientDriver.MaxSizeForLengthLimitedString, "NVARCHAR($l)");
RegisterColumnType(DbType.String,
SqlClientDriver.MaxSizeForClob, "MEMO");
}
public override string AddColumnString
{
get { return "add"; }
}
public override string NullColumnString
{
get { return " null"; }
}
public override string CurrentTimestampSQLFunctionName
{
get { return "NOW"; }
}
public override string CurrentTimestampSelectString
{
get { return "SELECT NOW() from system.iota"; }
}
public override bool IsCurrentTimestampSelectStringCallable
{
get { return true; }
}
public override bool SupportsCurrentTimestampSelection
{
get { return true; }
}
public override bool QualifyIndexName
{
get { return false; }
}
public override string SelectGUIDString
{
get { return "select NEWIDSTRING() from system.iota"; }
}
/// <summary>
/// Generates the string to drop the table using Advantage No
Drop Clause.
/// </summary>
/// <param name="tableName">The name of the table to drop.</
param>
public override string GetDropTableString(string tableName)
{
string dropTable = "drop table {0} from database
no_delete";
return String.Format(dropTable);
}
public override string ForUpdateString
{
get { return string.Empty; }
}
public override SqlString
AppendIdentitySelectToInsert(SqlString insertSql)
{
return insertSql.Append("; " + IdentitySelectString);
}
public override bool SupportsInsertSelectIdentity
{
get { return true; }
}
public override bool SupportsIdentityColumns
{
get { return true; }
}
public override string IdentitySelectString
{
get { return "select NEWIDSTRING() from system.iota"; }
}
public override string IdentityColumnString
{
get { return "IDENTITY NOT NULL"; }
}
public override string NoColumnsInsertString
{
get { return "DEFAULT VALUES"; }
}
public override char CloseQuote
{
get { return ']'; }
}
public override char OpenQuote
{
get { return '['; }
}
/// <summary>
/// Using SELECT TOP N as limiting clause.
/// </summary>
public override bool SupportsLimit
{
get { return true; }
}
/// <summary>
/// This dialect supports limit offset.
/// </summary>
public override bool SupportsLimitOffset
{
get { return true; }
}
/// <summary>
/// Can parameters be used for a statement containing a LIMIT?
/// </summary>
public override bool SupportsVariableLimit
{
get { return false; }
}
public override SqlString GetLimitString(SqlString
queryString, SqlString offset, SqlString limit)
{
/*
* "SELECT TOP 10 START AT 11 rest of sql statement[* FROM
*]
*/
int insertIndex = GetAfterSelectInsertPoint(queryString);
var limitFragment = new SqlStringBuilder();
if (limit != null)
{
limitFragment.Add(" top ");
limitFragment.Add(limit);
}
if (offset != null)
{
limitFragment.Add(" start at ");
limitFragment.Add(offset);
}
return
queryString.Insert(GetAfterSelectInsertPoint(queryString),
limitFragment.ToSqlString());
}
public override bool SupportsTemporaryTables
{
get { return true; }
}
public override string GenerateTemporaryTableName(string
baseTableName)
{
return "#" + baseTableName;
}
public override bool DropTemporaryTableAfterUse()
{
return true;
}
/// <summary />
/// <param name="name"></param>
/// <returns></returns>
/// <remarks>
protected override string Quote(string name)
{
return OpenQuote + name.Replace(CloseQuote.ToString(), new
string(CloseQuote, 2)) + CloseQuote;
}
public override string UnQuote(string quoted)
{
if (IsQuoted(quoted))
{
quoted = quoted.Substring(1, quoted.Length - 2);
}
return quoted.Replace(new string(CloseQuote, 2),
CloseQuote.ToString());
}
private static int GetAfterSelectInsertPoint(SqlString sql)
{
if (sql.StartsWithCaseInsensitive("select distinct"))
{
return 15;
}
else if (sql.StartsWithCaseInsensitive("select"))
{
return 6;
}
throw new NotSupportedException("The query should start
with 'SELECT' or 'SELECT DISTINCT'");
}
protected bool NeedsLockHint(LockMode lockMode)
{
return lockMode.GreaterThan(LockMode.Read);
}
public override string AppendLockHint(LockMode lockMode,
string tableName)
{
if (NeedsLockHint(lockMode))
{
return tableName + " with (updlock, rowlock)";
}
return tableName;
}
public override long TimestampResolutionInTicks
{
get
{
return TimeSpan.TicksPerMillisecond * 10L;
}
}
public override bool SupportsCircularCascadeDeleteConstraints
{
get
{
return false;
}
}
public override IDataBaseSchema GetDataBaseSchema(DbConnection
connection)
{
return new MsSqlDataBaseSchema(connection);
}
public override bool SupportsUnionAll
{
get { return true; }
}
public override bool SupportsSqlBatches
{
get { return true; }
}
public override bool IsKnownToken(string currentToken, string
nextToken)
{
return currentToken == "n" && nextToken == "'";
}
}
}