0
|
1 using System;
|
|
2 using System.Text;
|
|
3
|
|
4 namespace BLToolkit.Data.Sql.SqlProvider
|
|
5 {
|
|
6 using DataProvider;
|
|
7 using Reflection;
|
|
8
|
|
9 public class SQLiteSqlProvider : BasicSqlProvider
|
|
10 {
|
|
11 public override int CommandCount(SqlQuery sqlQuery)
|
|
12 {
|
|
13 return sqlQuery.IsInsert && sqlQuery.Insert.WithIdentity ? 2 : 1;
|
|
14 }
|
|
15
|
|
16 protected override void BuildCommand(int commandNumber, StringBuilder sb)
|
|
17 {
|
|
18 sb.AppendLine("SELECT last_insert_rowid()");
|
|
19 }
|
|
20
|
|
21 protected override ISqlProvider CreateSqlProvider()
|
|
22 {
|
|
23 return new SQLiteSqlProvider();
|
|
24 }
|
|
25
|
|
26 protected override string LimitFormat { get { return "LIMIT {0}"; } }
|
|
27 protected override string OffsetFormat { get { return "OFFSET {0}"; } }
|
|
28
|
|
29 public override bool IsSkipSupported { get { return SqlQuery.Select.TakeValue != null; } }
|
|
30 public override bool IsNestedJoinSupported { get { return false; } }
|
|
31 public override bool IsInsertOrUpdateSupported { get { return false; } }
|
|
32
|
|
33 public override ISqlExpression ConvertExpression(ISqlExpression expr)
|
|
34 {
|
|
35 expr = base.ConvertExpression(expr);
|
|
36
|
|
37 if (expr is SqlBinaryExpression)
|
|
38 {
|
|
39 var be = (SqlBinaryExpression)expr;
|
|
40
|
|
41 switch (be.Operation)
|
|
42 {
|
|
43 case "+": return be.SystemType == typeof(string)? new SqlBinaryExpression(be.SystemType, be.Expr1, "||", be.Expr2, be.Precedence): expr;
|
|
44 case "^": // (a + b) - (a & b) * 2
|
|
45 return Sub(
|
|
46 Add(be.Expr1, be.Expr2, be.SystemType),
|
|
47 Mul(new SqlBinaryExpression(be.SystemType, be.Expr1, "&", be.Expr2), 2), be.SystemType);
|
|
48 }
|
|
49 }
|
|
50 else if (expr is SqlFunction)
|
|
51 {
|
|
52 var func = (SqlFunction) expr;
|
|
53
|
|
54 switch (func.Name)
|
|
55 {
|
|
56 case "Space" : return new SqlFunction(func.SystemType, "PadR", new SqlValue(" "), func.Parameters[0]);
|
|
57 case "Convert" :
|
|
58 {
|
|
59 var ftype = TypeHelper.GetUnderlyingType(func.SystemType);
|
|
60
|
|
61 if (ftype == typeof(bool))
|
|
62 {
|
|
63 var ex = AlternativeConvertToBoolean(func, 1);
|
|
64 if (ex != null)
|
|
65 return ex;
|
|
66 }
|
|
67
|
|
68 if (ftype == typeof(DateTime) || ftype == typeof(DateTimeOffset))
|
|
69 {
|
|
70 if (IsDateDataType(func.Parameters[0], "Date"))
|
|
71 return new SqlFunction(func.SystemType, "Date", func.Parameters[1]);
|
|
72 return new SqlFunction(func.SystemType, "DateTime", func.Parameters[1]);
|
|
73 }
|
|
74
|
|
75 return new SqlExpression(func.SystemType, "Cast({0} as {1})", Precedence.Primary, func.Parameters[1], func.Parameters[0]);
|
|
76 }
|
|
77 }
|
|
78 }
|
|
79 else if (expr is SqlExpression)
|
|
80 {
|
|
81 var e = (SqlExpression)expr;
|
|
82
|
|
83 if (e.Expr.StartsWith("Cast(StrFTime(Quarter"))
|
|
84 return Inc(Div(Dec(new SqlExpression(e.SystemType, e.Expr.Replace("Cast(StrFTime(Quarter", "Cast(StrFTime('%m'"), e.Parameters)), 3));
|
|
85
|
|
86 if (e.Expr.StartsWith("Cast(StrFTime('%w'"))
|
|
87 return Inc(new SqlExpression(e.SystemType, e.Expr.Replace("Cast(StrFTime('%w'", "Cast(strFTime('%w'"), e.Parameters));
|
|
88
|
|
89 if (e.Expr.StartsWith("Cast(StrFTime('%f'"))
|
|
90 return new SqlExpression(e.SystemType, "Cast(strFTime('%f', {0}) * 1000 as int) % 1000", Precedence.Multiplicative, e.Parameters);
|
|
91
|
|
92 if (e.Expr.StartsWith("DateTime"))
|
|
93 {
|
|
94 if (e.Expr.EndsWith("Quarter')"))
|
|
95 return new SqlExpression(e.SystemType, "DateTime({1}, '{0} Month')", Precedence.Primary, Mul(e.Parameters[0], 3), e.Parameters[1]);
|
|
96
|
|
97 if (e.Expr.EndsWith("Week')"))
|
|
98 return new SqlExpression(e.SystemType, "DateTime({1}, '{0} Day')", Precedence.Primary, Mul(e.Parameters[0], 7), e.Parameters[1]);
|
|
99 }
|
|
100 }
|
|
101
|
|
102 return expr;
|
|
103 }
|
|
104
|
|
105 public override SqlQuery Finalize(SqlQuery sqlQuery)
|
|
106 {
|
|
107 sqlQuery = base.Finalize(sqlQuery);
|
|
108
|
|
109 switch (sqlQuery.QueryType)
|
|
110 {
|
|
111 case QueryType.Delete :
|
|
112 sqlQuery = GetAlternativeDelete(base.Finalize(sqlQuery));
|
|
113 sqlQuery.From.Tables[0].Alias = "$";
|
|
114 break;
|
|
115
|
|
116 case QueryType.Update :
|
|
117 sqlQuery = GetAlternativeUpdate(sqlQuery);
|
|
118 break;
|
|
119 }
|
|
120
|
|
121 return sqlQuery;
|
|
122 }
|
|
123
|
|
124 protected override void BuildFromClause(StringBuilder sb)
|
|
125 {
|
|
126 if (!SqlQuery.IsUpdate)
|
|
127 base.BuildFromClause(sb);
|
|
128 }
|
|
129
|
|
130 public override void BuildValue(StringBuilder sb, object value)
|
|
131 {
|
|
132 if (value is Guid)
|
|
133 {
|
|
134 var s = ((Guid)value).ToString("N");
|
|
135
|
|
136 sb
|
|
137 .Append("Cast(x'")
|
|
138 .Append(s.Substring( 6, 2))
|
|
139 .Append(s.Substring( 4, 2))
|
|
140 .Append(s.Substring( 2, 2))
|
|
141 .Append(s.Substring( 0, 2))
|
|
142 .Append(s.Substring(10, 2))
|
|
143 .Append(s.Substring( 8, 2))
|
|
144 .Append(s.Substring(14, 2))
|
|
145 .Append(s.Substring(12, 2))
|
|
146 .Append(s.Substring(16, 16))
|
|
147 .Append("' as blob)");
|
|
148 }
|
|
149 else
|
|
150 base.BuildValue(sb, value);
|
|
151 }
|
|
152
|
|
153 protected override void BuildDateTime(StringBuilder sb, object value)
|
|
154 {
|
|
155 sb
|
|
156 .Append(string.Format("'{0:yyyy-MM-dd HH:mm:ss.fff}", value).TrimEnd('0'))
|
|
157 .Append('\'');
|
|
158 }
|
|
159
|
|
160 public override object Convert(object value, ConvertType convertType)
|
|
161 {
|
|
162 switch (convertType)
|
|
163 {
|
|
164 case ConvertType.NameToQueryParameter:
|
|
165 case ConvertType.NameToCommandParameter:
|
|
166 case ConvertType.NameToSprocParameter:
|
|
167 return "@" + value;
|
|
168
|
|
169 case ConvertType.NameToQueryField:
|
|
170 case ConvertType.NameToQueryFieldAlias:
|
|
171 case ConvertType.NameToQueryTableAlias:
|
|
172 {
|
|
173 var name = value.ToString();
|
|
174
|
|
175 if (name.Length > 0 && name[0] == '[')
|
|
176 return value;
|
|
177 }
|
|
178
|
|
179 return "[" + value + "]";
|
|
180
|
|
181 case ConvertType.NameToDatabase:
|
|
182 case ConvertType.NameToOwner:
|
|
183 case ConvertType.NameToQueryTable:
|
|
184 {
|
|
185 var name = value.ToString();
|
|
186
|
|
187 if (name.Length > 0 && name[0] == '[')
|
|
188 return value;
|
|
189
|
|
190 if (name.IndexOf('.') > 0)
|
|
191 value = string.Join("].[", name.Split('.'));
|
|
192 }
|
|
193
|
|
194 return "[" + value + "]";
|
|
195
|
|
196 case ConvertType.SprocParameterToName:
|
|
197 {
|
|
198 var name = (string)value;
|
|
199 return name.Length > 0 && name[0] == '@'? name.Substring(1): name;
|
|
200 }
|
|
201 }
|
|
202
|
|
203 return value;
|
|
204 }
|
|
205 }
|
|
206 }
|