mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-18 09:35:38 -05:00
Adding decoding of multipart identifiers, default schema workaround (#295)
This change adds a couple things _Multipart Identifier Decoding_ The ability to decode a multipart identifier (with or without escaping) has been added to the SqlScriptFormatter utility class. This code is utilized to split a table name provided to the edit/initialize request into schema and table name. _Default Schema Workaround_ The code that retrieves the SMO metadata objects originally used the `[]` operator to access the objects. Due to a bug(?) in SMO, this results in problems when loading tables without a default schema (in our case if you're logged in as SA). Using the metadata object constructors gets around this issue, we are explicitly using them. * Adding decoding of multipart identifiers Adding code fix for default schema issue * Adding some more localizable strings for errors when loading metadata * Adding localization files... again? * Changes as per pull request comments
This commit is contained in:
@@ -176,6 +176,83 @@ namespace Microsoft.SqlTools.ServiceLayer.Utility
|
||||
return literal;
|
||||
}
|
||||
|
||||
public static string[] DecodeMultipartIdenfitier(string multipartIdentifier)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
List<string> namedParts = new List<string>();
|
||||
bool insideBrackets = false;
|
||||
bool bracketsClosed = false;
|
||||
for (int i = 0; i < multipartIdentifier.Length; i++)
|
||||
{
|
||||
char iChar = multipartIdentifier[i];
|
||||
if (insideBrackets)
|
||||
{
|
||||
if (iChar == ']')
|
||||
{
|
||||
if (HasNextCharacter(multipartIdentifier, ']', i))
|
||||
{
|
||||
// This is an escaped ]
|
||||
sb.Append(iChar);
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This bracket closes the bracket we were in
|
||||
insideBrackets = false;
|
||||
bracketsClosed = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is a standard character
|
||||
sb.Append(iChar);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (iChar)
|
||||
{
|
||||
case '[':
|
||||
if (bracketsClosed)
|
||||
{
|
||||
throw new FormatException();
|
||||
}
|
||||
|
||||
// We're opening a set of brackets
|
||||
insideBrackets = true;
|
||||
bracketsClosed = false;
|
||||
break;
|
||||
case '.':
|
||||
if (sb.Length == 0)
|
||||
{
|
||||
throw new FormatException();
|
||||
}
|
||||
|
||||
// We're splitting the identifier into a new part
|
||||
namedParts.Add(sb.ToString());
|
||||
sb = new StringBuilder();
|
||||
bracketsClosed = false;
|
||||
break;
|
||||
default:
|
||||
if (bracketsClosed)
|
||||
{
|
||||
throw new FormatException();
|
||||
}
|
||||
|
||||
// This is a standard character
|
||||
sb.Append(iChar);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sb.Length == 0)
|
||||
{
|
||||
throw new FormatException();
|
||||
}
|
||||
namedParts.Add(sb.ToString());
|
||||
return namedParts.ToArray();
|
||||
}
|
||||
|
||||
#region Private Helpers
|
||||
|
||||
private static string SimpleFormatter(object value)
|
||||
@@ -260,6 +337,12 @@ namespace Microsoft.SqlTools.ServiceLayer.Utility
|
||||
return "0x" + BitConverter.ToString(bytes).Replace("-", string.Empty);
|
||||
}
|
||||
|
||||
private static bool HasNextCharacter(string haystack, char needle, int position)
|
||||
{
|
||||
return position + 1 < haystack.Length
|
||||
&& haystack[position + 1] == needle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a valid SQL string packaged in single quotes with single quotes inside escaped
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user