I have created a new sql parser method for the FbCommand.
It removes single line comments "-- " and block comments "/* */".
It replaces tabs, newlines, carriage returns and multiple spaces with
a single space.
It also extracts the parameter names.
Has anyone got any comments ?
--
Gareth
private string ParseNamedParameters(string sql)
{
// Clear the current parameters.
this.namedParameters.Clear();
// Should we parse if there are no parameters. (comments ?
control characters ?)
if (sql.IndexOf('@') == -1)
{
return sql;
}
bool inParam = false;
bool inSpace = false;
bool inSingleQuote = false;
bool inDoubleQuote = false;
char[] crlf = new char[] {'\r', '\n'};
StringBuilder paramBuilder = new StringBuilder(31);
StringBuilder resultBuilder = new StringBuilder(sql.Length);
for (int i = 0, j = sql.Length; i < j; i++)
{
// Are we busy with a parameter ?
if (inParam == true)
{
if (Char.IsLetterOrDigit(sql[i]) || sql[i] == '_' ||
sql[i] == '$')
{
paramBuilder.Append(sql[i]);
continue;
}
else
{
this.namedParameters.Add(paramBuilder.ToString());
paramBuilder.Length = 0;
resultBuilder.Append('?');
inParam = false;
inSpace = false;
}
}
// Are we busy with quoted text ?
if ((inSingleQuote == true) || (inDoubleQuote == true))
{
resultBuilder.Append(sql[i]);
if (sql[i] == '\'')
{
inSingleQuote = false;
continue;
}
inDoubleQuote = false;
continue;
}
switch (sql[i])
{
// We are starting to read a parameter ?
case '@':
inParam = true;
paramBuilder.Append('@');
continue;
// Are we starting a single line comment ?
case '-':
if ((i < j - 1) && (sql[i + 1] == '-'))
{
int index = sql.IndexOfAny(crlf, i + 2);
i = index > i ?index - 1 :j;
continue;
}
break;
// Are we starting a block comment ?
case '/':
if ((i < j - 1) && (sql[i + 1] == '*'))
{
int index = sql.IndexOf("*/", i + 2);
i = index > i ? index + 1 : j;
continue;
}
break;
// We are starting single quoted text ?
case '\'':
inSingleQuote = true;
resultBuilder.Append('\'');
continue;
// We are starting double quoted text ?
case '\"':
inDoubleQuote = true;
resultBuilder.Append('\"');
continue;
// Add a space in place of control characters.
// Do not combine more than one space at a time.
case ' ':
case '\t':
case '\r':
case '\n':
if (inSpace == false)
{
inSpace = true;
resultBuilder.Append(' ');
}
continue;
}
inSpace = false;
resultBuilder.Append(sql[i]);
}
if (inParam == true)
{
this.namedParameters.Add(paramBuilder.ToString());
resultBuilder.Append('?');
}
return resultBuilder.ToString();
}
------------------------------------------------------------------------------
Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
-OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
-Strategies to boost innovation and cut costs with open source participation
-Receive a $600 discount off the registration fee with the source code: SFAD
http://p.sf.net/sfu/XcvMzF8H
_______________________________________________
Firebird-net-provider mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/firebird-net-provider