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 } |