Mercurial > pub > bltoolkit
diff Source/Data/Sql/SqlProvider/PostgreSQLSqlProvider.cs @ 0:f990fcb411a9
Копия текущей версии из github
author | cin |
---|---|
date | Thu, 27 Mar 2014 21:46:09 +0400 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Data/Sql/SqlProvider/PostgreSQLSqlProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,208 @@ +using System; +using System.Data; +using System.Text; + +namespace BLToolkit.Data.Sql.SqlProvider +{ + using DataProvider; + using Reflection; + + public class PostgreSQLSqlProvider : BasicSqlProvider + { + public override bool IsInsertOrUpdateSupported { get { return false; } } + + public override int CommandCount(SqlQuery sqlQuery) + { + return sqlQuery.IsInsert && sqlQuery.Insert.WithIdentity ? 2 : 1; + } + + protected override void BuildCommand(int commandNumber, StringBuilder sb) + { + var into = SqlQuery.Insert.Into; + var attr = GetSequenceNameAttribute(into, false); + var name = + attr != null ? + attr.SequenceName : + Convert( + string.Format("{0}_{1}_seq", into.PhysicalName, into.GetIdentityField().PhysicalName), + ConvertType.NameToQueryField); + + AppendIndent(sb) + .Append("SELECT currval('") + .Append(name) + .AppendLine("')"); + } + + protected override ISqlProvider CreateSqlProvider() + { + return new PostgreSQLSqlProvider(); + } + + protected override string LimitFormat { get { return "LIMIT {0}"; } } + protected override string OffsetFormat { get { return "OFFSET {0} "; } } + + public override ISqlExpression ConvertExpression(ISqlExpression expr) + { + expr = base.ConvertExpression(expr); + + if (expr is SqlBinaryExpression) + { + var be = (SqlBinaryExpression)expr; + + switch (be.Operation) + { + case "^": return new SqlBinaryExpression(be.SystemType, be.Expr1, "#", be.Expr2); + case "+": return be.SystemType == typeof(string)? new SqlBinaryExpression(be.SystemType, be.Expr1, "||", be.Expr2, be.Precedence): expr; + } + } + else if (expr is SqlFunction) + { + var func = (SqlFunction) expr; + + switch (func.Name) + { + case "Convert" : + if (TypeHelper.GetUnderlyingType(func.SystemType) == typeof(bool)) + { + var ex = AlternativeConvertToBoolean(func, 1); + if (ex != null) + return ex; + } + + return new SqlExpression(func.SystemType, "Cast({0} as {1})", Precedence.Primary, FloorBeforeConvert(func), func.Parameters[0]); + + case "CharIndex" : + return func.Parameters.Length == 2? + new SqlExpression(func.SystemType, "Position({0} in {1})", Precedence.Primary, func.Parameters[0], func.Parameters[1]): + Add<int>( + new SqlExpression(func.SystemType, "Position({0} in {1})", Precedence.Primary, func.Parameters[0], + ConvertExpression(new SqlFunction(typeof(string), "Substring", + func.Parameters[1], + func.Parameters[2], + Sub<int>(ConvertExpression(new SqlFunction(typeof(int), "Length", func.Parameters[1])), func.Parameters[2])))), + Sub(func.Parameters[2], 1)); + } + } + else if (expr is SqlExpression) + { + var e = (SqlExpression)expr; + + if (e.Expr.StartsWith("Extract(DOW")) + return Inc(new SqlExpression(expr.SystemType, e.Expr.Replace("Extract(DOW", "Extract(Dow"), e.Parameters)); + + if (e.Expr.StartsWith("Extract(Millisecond")) + return new SqlExpression(expr.SystemType, "Cast(To_Char({0}, 'MS') as int)", e.Parameters); + } + + return expr; + } + + public override void BuildValue(StringBuilder sb, object value) + { + if (value is bool) + sb.Append(value); + else + base.BuildValue(sb, value); + } + + protected override void BuildDataType(StringBuilder sb, SqlDataType type) + { + switch (type.SqlDbType) + { + case SqlDbType.TinyInt : sb.Append("SmallInt"); break; + case SqlDbType.Money : sb.Append("Decimal(19,4)"); break; + case SqlDbType.SmallMoney : sb.Append("Decimal(10,4)"); break; +#if !MONO + case SqlDbType.DateTime2 : +#endif + case SqlDbType.SmallDateTime : + case SqlDbType.DateTime : sb.Append("TimeStamp"); break; + case SqlDbType.Bit : sb.Append("Boolean"); break; + case SqlDbType.NVarChar : + sb.Append("VarChar"); + if (type.Length > 0) + sb.Append('(').Append(type.Length).Append(')'); + break; + default : base.BuildDataType(sb, type); break; + } + } + + public override SqlQuery Finalize(SqlQuery sqlQuery) + { + CheckAliases(sqlQuery, int.MaxValue); + + sqlQuery = base.Finalize(sqlQuery); + + switch (sqlQuery.QueryType) + { + case QueryType.Delete : return GetAlternativeDelete(sqlQuery); + case QueryType.Update : return GetAlternativeUpdate(sqlQuery); + default : return sqlQuery; + } + } + + protected override void BuildFromClause(StringBuilder sb) + { + if (!SqlQuery.IsUpdate) + base.BuildFromClause(sb); + } + + public static bool QuoteIdentifiers; + + public override object Convert(object value, ConvertType convertType) + { + switch (convertType) + { + case ConvertType.NameToQueryField: + case ConvertType.NameToQueryFieldAlias: + case ConvertType.NameToQueryTable: + case ConvertType.NameToQueryTableAlias: + if (QuoteIdentifiers) + { + var name = value.ToString(); + + if (name.Length > 0 && name[0] == '"') + return value; + + return '"' + name + '"'; + } + + break; + + case ConvertType.NameToQueryParameter: + case ConvertType.NameToCommandParameter: + case ConvertType.NameToSprocParameter: + return ":" + value; + + case ConvertType.SprocParameterToName: + if (value != null) + { + var str = value.ToString(); + return (str.Length > 0 && str[0] == ':')? str.Substring(1): str; + } + + break; + } + + return value; + } + + public override ISqlExpression GetIdentityExpression(SqlTable table, SqlField identityField, bool forReturning) + { + if (table.SequenceAttributes != null) + { + var attr = GetSequenceNameAttribute(table, false); + + if (attr != null) + return new SqlExpression("nextval('" + attr.SequenceName+"')", Precedence.Primary); + } + + return base.GetIdentityExpression(table, identityField, forReturning); + } + + //protected override void BuildInsertOrUpdateQuery(StringBuilder sb) + //{ + // BuildInsertOrUpdateQueryAsMerge(sb, null); + //} + } +}