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 /// /// This function returns actual T-SQL command. /// /// T-SQL command will be on database Oracle, SQL Server, Access, Informix. /// T-SQL command according to CEL style. /// Comma delimited value according to CEL style. /// Return the actual T-SQL command. public static string MakeSQL(SQLSyntax sqlSyntax, string sql, params object[] args) { _sqlSyntax = sqlSyntax; return MakeSQL(sql, args); } /// /// This function returns actual T-SQL command. /// /// T-SQL command according to CEL style. /// Comma delimited value according to CEL style. /// Return the actual T-SQL command. 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 /// /// This function return T-SQL command by adding WHERE/AND depending on commandText. /// /// Previous T-SQL command. /// Return T-SQL command after addition of WHERE/AND maintaining the space. public static string TagSQL(string commandText) { return string.Format("{0} {1} ", commandText.Trim(), (commandText.Trim().Length <= 0 ? "WHERE" : "AND")); } #endregion } #endregion }