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);
+		//}
+	}
+}