296 lines
11 KiB
C#
296 lines
11 KiB
C#
|
using System;
|
||
|
using System.Data;
|
||
|
using System.Globalization;
|
||
|
|
||
|
namespace Ease.Core.DataAccess
|
||
|
{
|
||
|
#region DataAccess: MakeSQL
|
||
|
|
||
|
public sealed class SQLParser
|
||
|
{
|
||
|
#region Declaraion & Constructor
|
||
|
|
||
|
private static SQLSyntax _sqlSyntax;
|
||
|
|
||
|
private SQLParser()
|
||
|
{
|
||
|
_sqlSyntax = SQLSyntax.SQL;
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
#region DateTime Formatting Functions
|
||
|
|
||
|
static string GetDateLiteral(DateTime dt)
|
||
|
{
|
||
|
string s = string.Empty;
|
||
|
switch (_sqlSyntax)
|
||
|
{
|
||
|
case SQLSyntax.Access:
|
||
|
s = "#" + dt.ToString("dd MMM yyyy", CultureInfo.InvariantCulture) + "#";
|
||
|
break;
|
||
|
|
||
|
case SQLSyntax.Oracle:
|
||
|
s = "TO_DATE('" + dt.ToString("dd MM yyyy", CultureInfo.InvariantCulture) + "', '" + "DD MM YYYY" +
|
||
|
"')";
|
||
|
break;
|
||
|
|
||
|
case SQLSyntax.Informix:
|
||
|
s = string.Format("DATETIME ({0}) YEAR TO DAY",
|
||
|
dt.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture));
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
s = "'" + dt.ToString("dd MMM yyyy", CultureInfo.InvariantCulture) + "'";
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return s;
|
||
|
}
|
||
|
|
||
|
static string GetDateTimeLiteral(DateTime dt)
|
||
|
{
|
||
|
string s = string.Empty;
|
||
|
switch (_sqlSyntax)
|
||
|
{
|
||
|
case SQLSyntax.Access:
|
||
|
s = "#" + dt.ToString("dd MMM yyyy HH:mm:ss", CultureInfo.InvariantCulture) + "#";
|
||
|
break;
|
||
|
|
||
|
case SQLSyntax.Oracle:
|
||
|
s = "TO_DATE('" + dt.ToString("dd MM yyyy HH mm ss", CultureInfo.InvariantCulture) +
|
||
|
"', 'DD MM YYYY HH24 MI SS')";
|
||
|
break;
|
||
|
|
||
|
case SQLSyntax.Informix:
|
||
|
s = string.Format("DATETIME ({0}) YEAR TO SECOND",
|
||
|
dt.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture));
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
s = "'" + dt.ToString("dd MMM yyyy HH:mm:ss", CultureInfo.InvariantCulture) + "'";
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return s;
|
||
|
}
|
||
|
|
||
|
static string GetTimeLiteral(DateTime dt)
|
||
|
{
|
||
|
string s = string.Empty;
|
||
|
switch (_sqlSyntax)
|
||
|
{
|
||
|
case SQLSyntax.Access:
|
||
|
s = "#" + dt.ToString("HH:mm:ss", CultureInfo.InvariantCulture) + "#";
|
||
|
break;
|
||
|
|
||
|
case SQLSyntax.Oracle:
|
||
|
s = "TO_DATE('" + dt.ToString("HH mm ss", CultureInfo.InvariantCulture) + "', 'HH24 MI SS')";
|
||
|
break;
|
||
|
|
||
|
case SQLSyntax.Informix:
|
||
|
s = string.Format("DATETIME ({0}) HOUR TO SECOND",
|
||
|
dt.ToString("HH:mm:ss", CultureInfo.InvariantCulture));
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
s = "'" + dt.ToString("HH:mm:ss", CultureInfo.InvariantCulture) + "'";
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return s;
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
#region Make SQL function
|
||
|
|
||
|
/// <summary>
|
||
|
/// This function returns actual T-SQL command.
|
||
|
/// </summary>
|
||
|
/// <param name="sqlSyntax">T-SQL command will be on database Oracle, SQL Server, Access, Informix.</param>
|
||
|
/// <param name="sql">T-SQL command according to CEL style.</param>
|
||
|
/// <param name="args">Comma delimited value according to CEL style.</param>
|
||
|
/// <returns>Return the actual T-SQL command.</returns>
|
||
|
public static string MakeSQL(SQLSyntax sqlSyntax, string sql, params object[] args)
|
||
|
{
|
||
|
_sqlSyntax = sqlSyntax;
|
||
|
return MakeSQL(sql, args);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// This function returns actual T-SQL command.
|
||
|
/// </summary>
|
||
|
/// <param name="sql">T-SQL command according to CEL style.</param>
|
||
|
/// <param name="args">Comma delimited value according to CEL style.</param>
|
||
|
/// <returns>Return the actual T-SQL command.</returns>
|
||
|
public static string MakeSQL(string sql, params object[] args)
|
||
|
{
|
||
|
if (args.Length <= 0)
|
||
|
return sql;
|
||
|
|
||
|
int argIndex = -1;
|
||
|
string retSQL = string.Empty;
|
||
|
string[] argSQL = new string[args.Length];
|
||
|
|
||
|
int i = sql.IndexOf("%");
|
||
|
while (i != -1)
|
||
|
{
|
||
|
retSQL = retSQL + sql.Substring(0, i);
|
||
|
|
||
|
if (i == sql.Length - 1)
|
||
|
throw new InvalidExpressionException("Invalid place holder character.");
|
||
|
|
||
|
string c = sql.Substring(i + 1, 1);
|
||
|
sql = sql.Substring(i + 2);
|
||
|
|
||
|
if (c.IndexOfAny(new char[] { '%', '{' }) != -1)
|
||
|
{
|
||
|
switch (c)
|
||
|
{
|
||
|
case "%":
|
||
|
retSQL = retSQL + "%";
|
||
|
break;
|
||
|
|
||
|
case "{":
|
||
|
int next = sql.IndexOf("}");
|
||
|
|
||
|
if (next < 1)
|
||
|
throw new InvalidExpressionException("Invalid rrdinal variable.");
|
||
|
|
||
|
int ord = Convert.ToInt32(sql.Substring(0, next));
|
||
|
if (ord < 0 || ord > argIndex)
|
||
|
throw new IndexOutOfRangeException("Invalid rrdinal variable.");
|
||
|
|
||
|
retSQL = retSQL + argSQL[ord];
|
||
|
sql = sql.Substring(next + 1);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else if (c.IndexOfAny(new char[] { 's', 'n', 'd', 't', 'T', 'D', 'b', 'q', 'u' }) != -1)
|
||
|
{
|
||
|
if (++argIndex > args.Length - 1)
|
||
|
throw new ArgumentException("Too few arguments passed.");
|
||
|
|
||
|
if (args[argIndex] == null)
|
||
|
{
|
||
|
argSQL[argIndex] = "NULL";
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
switch (c)
|
||
|
{
|
||
|
case "s":
|
||
|
string s = Convert.ToString(args[argIndex], CultureInfo.InvariantCulture);
|
||
|
argSQL[argIndex] = "'" + s.Replace("'", "''") + "'";
|
||
|
break;
|
||
|
|
||
|
case "u":
|
||
|
string u = Convert.ToString(args[argIndex], CultureInfo.InvariantCulture);
|
||
|
argSQL[argIndex] = "N'" + u.Replace("'", "''") + "'";
|
||
|
break;
|
||
|
|
||
|
case "n":
|
||
|
decimal n = Convert.ToDecimal(args[argIndex], CultureInfo.InvariantCulture);
|
||
|
argSQL[argIndex] = n.ToString(CultureInfo.InvariantCulture);
|
||
|
break;
|
||
|
|
||
|
case "d":
|
||
|
DateTime d = Convert.ToDateTime(args[argIndex], CultureInfo.InvariantCulture);
|
||
|
argSQL[argIndex] = GetDateLiteral(d);
|
||
|
break;
|
||
|
|
||
|
case "t":
|
||
|
DateTime t = Convert.ToDateTime(args[argIndex], CultureInfo.InvariantCulture);
|
||
|
argSQL[argIndex] = GetTimeLiteral(t);
|
||
|
break;
|
||
|
case "T":
|
||
|
string T = Convert.ToString(args[argIndex], CultureInfo.InvariantCulture);
|
||
|
argSQL[argIndex] = "'" + T.Replace("'", "''") + "'";
|
||
|
break;
|
||
|
|
||
|
case "D":
|
||
|
DateTime D = Convert.ToDateTime(args[argIndex], CultureInfo.InvariantCulture);
|
||
|
argSQL[argIndex] = GetDateTimeLiteral(D);
|
||
|
break;
|
||
|
|
||
|
case "b":
|
||
|
bool b = Convert.ToBoolean(args[argIndex], CultureInfo.InvariantCulture);
|
||
|
if (_sqlSyntax == SQLSyntax.Access)
|
||
|
argSQL[argIndex] = b.ToString(CultureInfo.InvariantCulture);
|
||
|
else
|
||
|
argSQL[argIndex] = (b ? "1" : "0");
|
||
|
break;
|
||
|
|
||
|
case "q":
|
||
|
string q = Convert.ToString(args[argIndex], CultureInfo.InvariantCulture);
|
||
|
argSQL[argIndex] = q;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
catch
|
||
|
{
|
||
|
throw new ArgumentException(string.Format("Invalid argument no: {0}", argIndex));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
retSQL = retSQL + argSQL[argIndex];
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
throw new InvalidExpressionException("Invalid place holder character.");
|
||
|
}
|
||
|
|
||
|
i = sql.IndexOf("%");
|
||
|
}
|
||
|
|
||
|
retSQL = retSQL + sql;
|
||
|
|
||
|
// Handle the (==)
|
||
|
i = retSQL.IndexOf("==");
|
||
|
while (i != -1)
|
||
|
{
|
||
|
string rVal = retSQL.Substring(i + 2).Trim().Substring(0);
|
||
|
if (rVal.ToUpper().StartsWith("NULL"))
|
||
|
retSQL = retSQL.Substring(0, i) + " IS " + retSQL.Substring(i + 2);
|
||
|
else
|
||
|
retSQL = retSQL.Substring(0, i) + "=" + retSQL.Substring(i + 2);
|
||
|
|
||
|
i = retSQL.IndexOf("==", i + 2);
|
||
|
}
|
||
|
|
||
|
//Handle the (<>)
|
||
|
i = retSQL.IndexOf("<>");
|
||
|
while (i != -1)
|
||
|
{
|
||
|
string rVal = retSQL.Substring(i + 2).Trim().Substring(1);
|
||
|
if (rVal.ToUpper().StartsWith("NULL"))
|
||
|
retSQL = retSQL.Substring(0, i) + " IS NOT " + retSQL.Substring(i + 2);
|
||
|
|
||
|
i = retSQL.IndexOf("<>", i + 2);
|
||
|
}
|
||
|
|
||
|
return retSQL;
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
#region TagSQL Function
|
||
|
|
||
|
/// <summary>
|
||
|
/// This function return T-SQL command by adding WHERE/AND depending on commandText.
|
||
|
/// </summary>
|
||
|
/// <param name="commandText">Previous T-SQL command.</param>
|
||
|
/// <returns>Return T-SQL command after addition of WHERE/AND maintaining the space.</returns>
|
||
|
public static string TagSQL(string commandText)
|
||
|
{
|
||
|
return string.Format("{0} {1} ", commandText.Trim(), (commandText.Trim().Length <= 0 ? "WHERE" : "AND"));
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
}
|