Mercurial > pub > bltoolkit
diff Source/Data/Sql/SqlProvider/SQLiteSqlProvider.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/SQLiteSqlProvider.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,206 @@ +using System; +using System.Text; + +namespace BLToolkit.Data.Sql.SqlProvider +{ + using DataProvider; + using Reflection; + + public class SQLiteSqlProvider : BasicSqlProvider + { + public override int CommandCount(SqlQuery sqlQuery) + { + return sqlQuery.IsInsert && sqlQuery.Insert.WithIdentity ? 2 : 1; + } + + protected override void BuildCommand(int commandNumber, StringBuilder sb) + { + sb.AppendLine("SELECT last_insert_rowid()"); + } + + protected override ISqlProvider CreateSqlProvider() + { + return new SQLiteSqlProvider(); + } + + protected override string LimitFormat { get { return "LIMIT {0}"; } } + protected override string OffsetFormat { get { return "OFFSET {0}"; } } + + public override bool IsSkipSupported { get { return SqlQuery.Select.TakeValue != null; } } + public override bool IsNestedJoinSupported { get { return false; } } + public override bool IsInsertOrUpdateSupported { get { return false; } } + + public override ISqlExpression ConvertExpression(ISqlExpression expr) + { + expr = base.ConvertExpression(expr); + + if (expr is SqlBinaryExpression) + { + var be = (SqlBinaryExpression)expr; + + switch (be.Operation) + { + case "+": return be.SystemType == typeof(string)? new SqlBinaryExpression(be.SystemType, be.Expr1, "||", be.Expr2, be.Precedence): expr; + case "^": // (a + b) - (a & b) * 2 + return Sub( + Add(be.Expr1, be.Expr2, be.SystemType), + Mul(new SqlBinaryExpression(be.SystemType, be.Expr1, "&", be.Expr2), 2), be.SystemType); + } + } + else if (expr is SqlFunction) + { + var func = (SqlFunction) expr; + + switch (func.Name) + { + case "Space" : return new SqlFunction(func.SystemType, "PadR", new SqlValue(" "), func.Parameters[0]); + case "Convert" : + { + var ftype = TypeHelper.GetUnderlyingType(func.SystemType); + + if (ftype == typeof(bool)) + { + var ex = AlternativeConvertToBoolean(func, 1); + if (ex != null) + return ex; + } + + if (ftype == typeof(DateTime) || ftype == typeof(DateTimeOffset)) + { + if (IsDateDataType(func.Parameters[0], "Date")) + return new SqlFunction(func.SystemType, "Date", func.Parameters[1]); + return new SqlFunction(func.SystemType, "DateTime", func.Parameters[1]); + } + + return new SqlExpression(func.SystemType, "Cast({0} as {1})", Precedence.Primary, func.Parameters[1], func.Parameters[0]); + } + } + } + else if (expr is SqlExpression) + { + var e = (SqlExpression)expr; + + if (e.Expr.StartsWith("Cast(StrFTime(Quarter")) + return Inc(Div(Dec(new SqlExpression(e.SystemType, e.Expr.Replace("Cast(StrFTime(Quarter", "Cast(StrFTime('%m'"), e.Parameters)), 3)); + + if (e.Expr.StartsWith("Cast(StrFTime('%w'")) + return Inc(new SqlExpression(e.SystemType, e.Expr.Replace("Cast(StrFTime('%w'", "Cast(strFTime('%w'"), e.Parameters)); + + if (e.Expr.StartsWith("Cast(StrFTime('%f'")) + return new SqlExpression(e.SystemType, "Cast(strFTime('%f', {0}) * 1000 as int) % 1000", Precedence.Multiplicative, e.Parameters); + + if (e.Expr.StartsWith("DateTime")) + { + if (e.Expr.EndsWith("Quarter')")) + return new SqlExpression(e.SystemType, "DateTime({1}, '{0} Month')", Precedence.Primary, Mul(e.Parameters[0], 3), e.Parameters[1]); + + if (e.Expr.EndsWith("Week')")) + return new SqlExpression(e.SystemType, "DateTime({1}, '{0} Day')", Precedence.Primary, Mul(e.Parameters[0], 7), e.Parameters[1]); + } + } + + return expr; + } + + public override SqlQuery Finalize(SqlQuery sqlQuery) + { + sqlQuery = base.Finalize(sqlQuery); + + switch (sqlQuery.QueryType) + { + case QueryType.Delete : + sqlQuery = GetAlternativeDelete(base.Finalize(sqlQuery)); + sqlQuery.From.Tables[0].Alias = "$"; + break; + + case QueryType.Update : + sqlQuery = GetAlternativeUpdate(sqlQuery); + break; + } + + return sqlQuery; + } + + protected override void BuildFromClause(StringBuilder sb) + { + if (!SqlQuery.IsUpdate) + base.BuildFromClause(sb); + } + + public override void BuildValue(StringBuilder sb, object value) + { + if (value is Guid) + { + var s = ((Guid)value).ToString("N"); + + sb + .Append("Cast(x'") + .Append(s.Substring( 6, 2)) + .Append(s.Substring( 4, 2)) + .Append(s.Substring( 2, 2)) + .Append(s.Substring( 0, 2)) + .Append(s.Substring(10, 2)) + .Append(s.Substring( 8, 2)) + .Append(s.Substring(14, 2)) + .Append(s.Substring(12, 2)) + .Append(s.Substring(16, 16)) + .Append("' as blob)"); + } + else + base.BuildValue(sb, value); + } + + protected override void BuildDateTime(StringBuilder sb, object value) + { + sb + .Append(string.Format("'{0:yyyy-MM-dd HH:mm:ss.fff}", value).TrimEnd('0')) + .Append('\''); + } + + public override object Convert(object value, ConvertType convertType) + { + switch (convertType) + { + case ConvertType.NameToQueryParameter: + case ConvertType.NameToCommandParameter: + case ConvertType.NameToSprocParameter: + return "@" + value; + + case ConvertType.NameToQueryField: + case ConvertType.NameToQueryFieldAlias: + case ConvertType.NameToQueryTableAlias: + { + var name = value.ToString(); + + if (name.Length > 0 && name[0] == '[') + return value; + } + + return "[" + value + "]"; + + case ConvertType.NameToDatabase: + case ConvertType.NameToOwner: + case ConvertType.NameToQueryTable: + { + var name = value.ToString(); + + if (name.Length > 0 && name[0] == '[') + return value; + + if (name.IndexOf('.') > 0) + value = string.Join("].[", name.Split('.')); + } + + return "[" + value + "]"; + + case ConvertType.SprocParameterToName: + { + var name = (string)value; + return name.Length > 0 && name[0] == '@'? name.Substring(1): name; + } + } + + return value; + } + } +}