Code:
/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / Designer / WebForms / System / Web / UI / Design / WebControls / SqlDataSourceCommandParser.cs / 1 / SqlDataSourceCommandParser.cs
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------
namespace System.Web.UI.Design.WebControls {
using System;
using System.Collections;
using System.Diagnostics;
using System.Globalization;
using System.Text;
using System.Web.UI.WebControls;
//
///
/// Helper class for parsing simple SQL SELECT commands to extract the
/// list of selected fields and which table they are being selected
/// from. This it not a complete parser, it only handles limited scenarios.
///
internal static class SqlDataSourceCommandParser {
private static bool ConsumeField(string s, int startIndex, System.Collections.Generic.List parts) {
// Skip whitespace
while ((startIndex < s.Length) && (Char.IsWhiteSpace(s, startIndex))) {
startIndex++;
}
string fieldName;
startIndex = ConsumeIdentifier(s, startIndex, out fieldName);
parts.Add(fieldName);
return ExpectField(s, startIndex, parts);
}
private static bool ConsumeFrom(string s, int startIndex, System.Collections.Generic.List parts) {
// Skip whitespace
while ((startIndex < s.Length) && (Char.IsWhiteSpace(s, startIndex))) {
startIndex++;
}
// If we're at the end of the string, abort
if (startIndex + 5 >= s.Length) {
return false;
}
if (String.Compare(s, startIndex, "from", 0, 4, StringComparison.OrdinalIgnoreCase) == 0) {
if (Char.IsWhiteSpace(s, startIndex + 4)) {
return ConsumeTable(s, startIndex + 5, parts);
}
}
return false;
}
private static int ConsumeIdentifier(string s, int startIndex, out string identifier) {
bool inBracket = false;
identifier = String.Empty;
//
while (startIndex < s.Length) {
if ((!inBracket) && (s[startIndex] == '[')) {
inBracket = true;
identifier += s[startIndex];
startIndex++;
}
else {
if (inBracket && (s[startIndex] == ']')) {
inBracket = false;
identifier += s[startIndex];
startIndex++;
}
else {
if (inBracket) {
// In a bracket we'll take anything
identifier += s[startIndex];
startIndex++;
}
else {
// Not in a bracket, we'll only take certain chars
if ((!Char.IsWhiteSpace(s, startIndex)) && (s[startIndex] != ',')) {
identifier += s[startIndex];
startIndex++;
}
else {
break;
}
}
}
}
}
return startIndex;
}
private static bool ConsumeSelect(string s, int startIndex, System.Collections.Generic.List parts) {
if (s.Length < 7) {
return false;
}
if (!s.ToLowerInvariant().StartsWith("select", StringComparison.Ordinal)) {
return false;
}
if (!Char.IsWhiteSpace(s, 6)) {
return false;
}
return ConsumeField(s, startIndex + 7, parts);
}
private static bool ConsumeTable(string s, int startIndex, System.Collections.Generic.List parts) {
// Skip whitespace
while ((startIndex < s.Length) && (Char.IsWhiteSpace(s, startIndex))) {
startIndex++;
}
string fieldName;
startIndex = ConsumeIdentifier(s, startIndex, out fieldName);
parts.Add(fieldName);
// Make sure there is nothing after this
if (startIndex == s.Length) {
return true;
}
else {
return false;
}
}
private static bool ExpectField(string s, int startIndex, System.Collections.Generic.List parts) {
// Skip whitespace
while ((startIndex < s.Length) && (Char.IsWhiteSpace(s, startIndex))) {
startIndex++;
}
// If we're at the end of the string, abort
if (startIndex >= s.Length - 1) {
return false;
}
if (s[startIndex] == ',') {
// A comma indicates there are more fields coming
return ConsumeField(s, startIndex + 1, parts);
}
else {
// No comma, we are done with fields
return ConsumeFrom(s, startIndex, parts);
}
}
///
/// Splits a SQL identifier such as [db].[user].[object] into its parts:
/// db, user, object
///
private static string[] GetIdentifierParts(string identifier) {
Debug.Assert(identifier != null);
bool inBrackets = false;
StringBuilder sb = new StringBuilder();
ArrayList result = new ArrayList();
for (int i = 0; i < identifier.Length; i++) {
char c = identifier[i];
switch (c) {
case '[':
if (inBrackets) {
Debug.Fail(String.Format(CultureInfo.InvariantCulture, "The identifier {0} contains invalid characters", identifier));
return null;
}
inBrackets = true;
break;
case ']':
if ((inBrackets == false) || (identifier.Length > i + 2) && (identifier[i + 1] != '.')) {
Debug.Fail(String.Format(CultureInfo.InvariantCulture, "The identifier {0} contains invalid characters", identifier));
return null;
}
inBrackets = false;
break;
case '.':
if (inBrackets) {
sb.Append('.');
}
else {
result.Add(sb.ToString());
sb.Length = 0;
}
break;
default:
if (inBrackets == false) {
switch (c) {
case '@':
case '#':
case '_':
case '*': // This allows [foo].* to work
break;
default:
if (Char.IsLetter(c)) {
break;
}
// First char can't be $ or digit
if ((sb.Length > 0) && ((c == '$') || Char.IsDigit(c))) {
break;
}
Debug.Fail(String.Format(CultureInfo.InvariantCulture, "The identifier {0} contains invalid characters", identifier));
return null;
}
}
sb.Append(c);
break;
}
}
result.Add(sb.ToString());
return (string[])result.ToArray(typeof(string));
}
///
/// Parses an identifier such as [foo].[bar] and returns just the
/// "bar" part.
///
public static string GetLastIdentifierPart(string identifier) {
string[] parts = GetIdentifierParts(identifier);
if ((parts == null) || (parts.Length == 0)) {
return null;
}
else {
return parts[parts.Length - 1];
}
}
///
/// Parses a simple SQL command string and extracts the list of
/// selected fields and the table name. The return value is null if
/// there was any problem parsing the string. The last field returned
/// is really the name of the table being selected from, not a field.
///
public static string[] ParseSqlString(string sqlString) {
if (String.IsNullOrEmpty(sqlString)) {
return null;
}
try {
sqlString = sqlString.Trim();
System.Collections.Generic.List parts = new System.Collections.Generic.List();
bool success = ConsumeSelect(sqlString, 0, parts);
return (success ? parts.ToArray() : null);
}
catch (Exception ex) {
Debug.Fail("Caught an exception in SqlParser: " + ex.Message);
return null;
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- HttpDebugHandler.cs
- AtomServiceDocumentSerializer.cs
- IsolationInterop.cs
- HttpInputStream.cs
- RowUpdatingEventArgs.cs
- HttpCachePolicyElement.cs
- RelationshipNavigation.cs
- CompatibleComparer.cs
- ControlFilterExpression.cs
- StyleModeStack.cs
- EventMappingSettingsCollection.cs
- ExtendedPropertyDescriptor.cs
- BufferedStream.cs
- InvariantComparer.cs
- OpenTypeLayoutCache.cs
- PhysicalAddress.cs
- Win32KeyboardDevice.cs
- CheckedPointers.cs
- httpapplicationstate.cs
- BrowserDefinition.cs
- PrintDocument.cs
- SafeBitVector32.cs
- HashHelper.cs
- SQLResource.cs
- ParallelTimeline.cs
- DefaultParameterValueAttribute.cs
- SyntaxCheck.cs
- SqlFacetAttribute.cs
- IfElseDesigner.xaml.cs
- DataGridViewAccessibleObject.cs
- AnonymousIdentificationSection.cs
- TreeNodeStyleCollection.cs
- EventArgs.cs
- ClientFormsIdentity.cs
- SmtpSection.cs
- GridViewColumnCollection.cs
- BulletedListEventArgs.cs
- SecurityTokenRequirement.cs
- CqlLexerHelpers.cs
- BitmapMetadata.cs
- XmlArrayAttribute.cs
- BaseResourcesBuildProvider.cs
- StreamMarshaler.cs
- Label.cs
- graph.cs
- WebPartDescription.cs
- HideDisabledControlAdapter.cs
- objectquery_tresulttype.cs
- SessionSwitchEventArgs.cs
- EntryIndex.cs
- EmptyEnumerator.cs
- DrawItemEvent.cs
- ReachSerializableProperties.cs
- ListViewTableCell.cs
- CardSpaceSelector.cs
- Encoding.cs
- RectAnimationBase.cs
- StrokeNodeOperations2.cs
- DataGrid.cs
- XmlSchema.cs
- InteropAutomationProvider.cs
- Globals.cs
- SubMenuStyleCollection.cs
- NotifyInputEventArgs.cs
- MetadataPropertyCollection.cs
- WebEvents.cs
- IItemProperties.cs
- OlePropertyStructs.cs
- ListViewCommandEventArgs.cs
- XmlReflectionImporter.cs
- HttpListenerPrefixCollection.cs
- DataGridViewLinkCell.cs
- TextTreeObjectNode.cs
- ActivityContext.cs
- ScrollProperties.cs
- AuthenticationException.cs
- UnsafeNativeMethods.cs
- HttpHandlersSection.cs
- UniqueConstraint.cs
- ConfigurationProperty.cs
- SigningCredentials.cs
- FixedSOMElement.cs
- HttpBindingExtension.cs
- StringUtil.cs
- ParallelTimeline.cs
- TextSpanModifier.cs
- AssemblyBuilder.cs
- XmlSchemaRedefine.cs
- exports.cs
- BStrWrapper.cs
- CodeChecksumPragma.cs
- BreakRecordTable.cs
- StackBuilderSink.cs
- XmlWrappingReader.cs
- ErrorHandler.cs
- DrawListViewColumnHeaderEventArgs.cs
- WebPartsPersonalization.cs
- SqlProfileProvider.cs
- TagMapInfo.cs
- EntityClassGenerator.cs