Mercurial > pub > bltoolkit
comparison Source/Data/Sql/SqlProvider/InformixSqlProvider.cs @ 0:f990fcb411a9
Копия текущей версии из github
| author | cin |
|---|---|
| date | Thu, 27 Mar 2014 21:46:09 +0400 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:f990fcb411a9 |
|---|---|
| 1 using System; | |
| 2 using System.Data; | |
| 3 using System.Text; | |
| 4 | |
| 5 namespace BLToolkit.Data.Sql.SqlProvider | |
| 6 { | |
| 7 using DataProvider; | |
| 8 using Reflection; | |
| 9 | |
| 10 public class InformixSqlProvider : BasicSqlProvider | |
| 11 { | |
| 12 public override int CommandCount(SqlQuery sqlQuery) | |
| 13 { | |
| 14 return sqlQuery.IsInsert && sqlQuery.Insert.WithIdentity ? 2 : 1; | |
| 15 } | |
| 16 | |
| 17 protected override void BuildCommand(int commandNumber, StringBuilder sb) | |
| 18 { | |
| 19 sb.AppendLine("SELECT DBINFO('sqlca.sqlerrd1') FROM systables where tabid = 1"); | |
| 20 } | |
| 21 | |
| 22 protected override ISqlProvider CreateSqlProvider() | |
| 23 { | |
| 24 return new InformixSqlProvider(); | |
| 25 } | |
| 26 | |
| 27 public override int BuildSql(int commandNumber, SqlQuery sqlQuery, StringBuilder sb, int indent, int nesting, bool skipAlias) | |
| 28 { | |
| 29 var n = base.BuildSql(commandNumber, sqlQuery, sb, indent, nesting, skipAlias); | |
| 30 | |
| 31 sb | |
| 32 .Replace("NULL IS NOT NULL", "1=0") | |
| 33 .Replace("NULL IS NULL", "1=1"); | |
| 34 | |
| 35 return n; | |
| 36 } | |
| 37 | |
| 38 protected override void BuildSelectClause(StringBuilder sb) | |
| 39 { | |
| 40 if (SqlQuery.From.Tables.Count == 0) | |
| 41 { | |
| 42 AppendIndent(sb).Append("SELECT FIRST 1").AppendLine(); | |
| 43 BuildColumns(sb); | |
| 44 AppendIndent(sb).Append("FROM SYSTABLES").AppendLine(); | |
| 45 } | |
| 46 else | |
| 47 base.BuildSelectClause(sb); | |
| 48 } | |
| 49 | |
| 50 public override bool IsSubQueryTakeSupported { get { return false; } } | |
| 51 public override bool IsInsertOrUpdateSupported { get { return false; } } | |
| 52 public override bool IsGroupByExpressionSupported { get { return false; } } | |
| 53 | |
| 54 protected override string FirstFormat { get { return "FIRST {0}"; } } | |
| 55 protected override string SkipFormat { get { return "SKIP {0}"; } } | |
| 56 | |
| 57 protected override void BuildLikePredicate(StringBuilder sb, SqlQuery.Predicate.Like predicate) | |
| 58 { | |
| 59 if (predicate.IsNot) | |
| 60 sb.Append("NOT "); | |
| 61 | |
| 62 var precedence = GetPrecedence(predicate); | |
| 63 | |
| 64 BuildExpression(sb, precedence, predicate.Expr1); | |
| 65 sb.Append(" LIKE "); | |
| 66 BuildExpression(sb, precedence, predicate.Expr2); | |
| 67 | |
| 68 if (predicate.Escape != null) | |
| 69 { | |
| 70 sb.Append(" ESCAPE "); | |
| 71 BuildExpression(sb, precedence, predicate.Escape); | |
| 72 } | |
| 73 } | |
| 74 | |
| 75 public override ISqlExpression ConvertExpression(ISqlExpression expr) | |
| 76 { | |
| 77 expr = base.ConvertExpression(expr); | |
| 78 | |
| 79 if (expr is SqlBinaryExpression) | |
| 80 { | |
| 81 var be = (SqlBinaryExpression)expr; | |
| 82 | |
| 83 switch (be.Operation) | |
| 84 { | |
| 85 case "%": return new SqlFunction(be.SystemType, "Mod", be.Expr1, be.Expr2); | |
| 86 case "&": return new SqlFunction(be.SystemType, "BitAnd", be.Expr1, be.Expr2); | |
| 87 case "|": return new SqlFunction(be.SystemType, "BitOr", be.Expr1, be.Expr2); | |
| 88 case "^": return new SqlFunction(be.SystemType, "BitXor", be.Expr1, be.Expr2); | |
| 89 case "+": return be.SystemType == typeof(string)? new SqlBinaryExpression(be.SystemType, be.Expr1, "||", be.Expr2, be.Precedence): expr; | |
| 90 } | |
| 91 } | |
| 92 else if (expr is SqlFunction) | |
| 93 { | |
| 94 var func = (SqlFunction)expr; | |
| 95 | |
| 96 switch (func.Name) | |
| 97 { | |
| 98 case "Coalesce" : return new SqlFunction(func.SystemType, "Nvl", func.Parameters); | |
| 99 case "Convert" : | |
| 100 { | |
| 101 var par0 = func.Parameters[0]; | |
| 102 var par1 = func.Parameters[1]; | |
| 103 | |
| 104 switch (Type.GetTypeCode(TypeHelper.GetUnderlyingType(func.SystemType))) | |
| 105 { | |
| 106 case TypeCode.String : return new SqlFunction(func.SystemType, "To_Char", func.Parameters[1]); | |
| 107 case TypeCode.Boolean : | |
| 108 { | |
| 109 var ex = AlternativeConvertToBoolean(func, 1); | |
| 110 if (ex != null) | |
| 111 return ex; | |
| 112 break; | |
| 113 } | |
| 114 | |
| 115 case TypeCode.UInt64: | |
| 116 if (TypeHelper.IsFloatType(func.Parameters[1].SystemType)) | |
| 117 par1 = new SqlFunction(func.SystemType, "Floor", func.Parameters[1]); | |
| 118 break; | |
| 119 | |
| 120 case TypeCode.DateTime : | |
| 121 if (IsDateDataType(func.Parameters[0], "Date")) | |
| 122 { | |
| 123 if (func.Parameters[1].SystemType == typeof(string)) | |
| 124 { | |
| 125 return new SqlFunction( | |
| 126 func.SystemType, | |
| 127 "Date", | |
| 128 new SqlFunction(func.SystemType, "To_Date", func.Parameters[1], new SqlValue("%Y-%m-%d"))); | |
| 129 } | |
| 130 | |
| 131 return new SqlFunction(func.SystemType, "Date", func.Parameters[1]); | |
| 132 } | |
| 133 | |
| 134 if (IsTimeDataType(func.Parameters[0])) | |
| 135 return new SqlExpression(func.SystemType, "Cast(Extend({0}, hour to second) as Char(8))", Precedence.Primary, func.Parameters[1]); | |
| 136 | |
| 137 return new SqlFunction(func.SystemType, "To_Date", func.Parameters[1]); | |
| 138 | |
| 139 default: | |
| 140 if (TypeHelper.GetUnderlyingType(func.SystemType) == typeof(DateTimeOffset)) | |
| 141 goto case TypeCode.DateTime; | |
| 142 break; | |
| 143 } | |
| 144 | |
| 145 return new SqlExpression(func.SystemType, "Cast({0} as {1})", Precedence.Primary, par1, par0); | |
| 146 } | |
| 147 | |
| 148 case "Quarter" : return Inc(Div(Dec(new SqlFunction(func.SystemType, "Month", func.Parameters)), 3)); | |
| 149 case "WeekDay" : return Inc(new SqlFunction(func.SystemType, "weekDay", func.Parameters)); | |
| 150 case "DayOfYear": | |
| 151 return | |
| 152 Inc(Sub<int>( | |
| 153 new SqlFunction(null, "Mdy", | |
| 154 new SqlFunction(null, "Month", func.Parameters), | |
| 155 new SqlFunction(null, "Day", func.Parameters), | |
| 156 new SqlFunction(null, "Year", func.Parameters)), | |
| 157 new SqlFunction(null, "Mdy", | |
| 158 new SqlValue(1), | |
| 159 new SqlValue(1), | |
| 160 new SqlFunction(null, "Year", func.Parameters)))); | |
| 161 case "Week" : | |
| 162 return | |
| 163 new SqlExpression( | |
| 164 func.SystemType, | |
| 165 "((Extend({0}, year to day) - (Mdy(12, 31 - WeekDay(Mdy(1, 1, year({0}))), Year({0}) - 1) + Interval(1) day to day)) / 7 + Interval(1) day to day)::char(10)::int", | |
| 166 func.Parameters); | |
| 167 case "Hour" : | |
| 168 case "Minute" : | |
| 169 case "Second" : return new SqlExpression(func.SystemType, string.Format("({{0}}::datetime {0} to {0})::char(3)::int", func.Name), func.Parameters); | |
| 170 } | |
| 171 } | |
| 172 | |
| 173 return expr; | |
| 174 } | |
| 175 | |
| 176 protected override void BuildFunction(StringBuilder sb, SqlFunction func) | |
| 177 { | |
| 178 func = ConvertFunctionParameters(func); | |
| 179 base.BuildFunction(sb, func); | |
| 180 } | |
| 181 | |
| 182 public virtual object ConvertBooleanValue(bool value) | |
| 183 { | |
| 184 return value ? 't' : 'f'; | |
| 185 } | |
| 186 | |
| 187 public override void BuildValue(StringBuilder sb, object value) | |
| 188 { | |
| 189 if (value is bool || value is bool?) | |
| 190 sb.Append("'").Append(ConvertBooleanValue((bool)value)).Append("'"); | |
| 191 else | |
| 192 base.BuildValue(sb, value); | |
| 193 } | |
| 194 | |
| 195 protected override void BuildDataType(StringBuilder sb, SqlDataType type) | |
| 196 { | |
| 197 switch (type.SqlDbType) | |
| 198 { | |
| 199 case SqlDbType.TinyInt : sb.Append("SmallInt"); break; | |
| 200 case SqlDbType.SmallMoney : sb.Append("Decimal(10,4)"); break; | |
| 201 default : base.BuildDataType(sb, type); break; | |
| 202 } | |
| 203 } | |
| 204 | |
| 205 static void SetQueryParameter(IQueryElement element) | |
| 206 { | |
| 207 if (element.ElementType == QueryElementType.SqlParameter) | |
| 208 ((SqlParameter)element).IsQueryParameter = false; | |
| 209 } | |
| 210 | |
| 211 public override SqlQuery Finalize(SqlQuery sqlQuery) | |
| 212 { | |
| 213 CheckAliases(sqlQuery, int.MaxValue); | |
| 214 | |
| 215 new QueryVisitor().Visit(sqlQuery.Select, SetQueryParameter); | |
| 216 | |
| 217 //if (sqlQuery.QueryType == QueryType.InsertOrUpdate) | |
| 218 //{ | |
| 219 // foreach (var key in sqlQuery.Insert.Items) | |
| 220 // new QueryVisitor().Visit(key.Expression, SetQueryParameter); | |
| 221 // | |
| 222 // foreach (var key in sqlQuery.Update.Items) | |
| 223 // new QueryVisitor().Visit(key.Expression, SetQueryParameter); | |
| 224 //} | |
| 225 | |
| 226 sqlQuery = base.Finalize(sqlQuery); | |
| 227 | |
| 228 switch (sqlQuery.QueryType) | |
| 229 { | |
| 230 case QueryType.Delete : | |
| 231 sqlQuery = GetAlternativeDelete(sqlQuery); | |
| 232 sqlQuery.From.Tables[0].Alias = "$"; | |
| 233 break; | |
| 234 | |
| 235 case QueryType.Update : | |
| 236 sqlQuery = GetAlternativeUpdate(sqlQuery); | |
| 237 break; | |
| 238 } | |
| 239 | |
| 240 return sqlQuery; | |
| 241 } | |
| 242 | |
| 243 protected override void BuildFromClause(StringBuilder sb) | |
| 244 { | |
| 245 if (!SqlQuery.IsUpdate) | |
| 246 base.BuildFromClause(sb); | |
| 247 } | |
| 248 | |
| 249 public override object Convert(object value, ConvertType convertType) | |
| 250 { | |
| 251 switch (convertType) | |
| 252 { | |
| 253 case ConvertType.NameToQueryParameter : return "?"; | |
| 254 case ConvertType.NameToCommandParameter : | |
| 255 case ConvertType.NameToSprocParameter : return ":" + value; | |
| 256 case ConvertType.SprocParameterToName : | |
| 257 if (value != null) | |
| 258 { | |
| 259 var str = value.ToString(); | |
| 260 return (str.Length > 0 && str[0] == ':')? str.Substring(1): str; | |
| 261 } | |
| 262 | |
| 263 break; | |
| 264 } | |
| 265 | |
| 266 return value; | |
| 267 } | |
| 268 | |
| 269 //protected override void BuildInsertOrUpdateQuery(StringBuilder sb) | |
| 270 //{ | |
| 271 // BuildInsertOrUpdateQueryAsMerge(sb, "FROM SYSTABLES"); | |
| 272 //} | |
| 273 } | |
| 274 } |
