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 }