Skip to content

Commit

Permalink
Named parameter auto-complete working
Browse files Browse the repository at this point in the history
  • Loading branch information
markrendle committed Jul 25, 2011
1 parent 00a80f4 commit b2eb3e9
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 16 deletions.
22 changes: 19 additions & 3 deletions Simple.Data.Pad.Test/AutoCompleterTest.cs
Expand Up @@ -118,13 +118,29 @@ public void ShouldReturnColumnsWithColonsForNakedFindBy()
}

[Fact]
public void ShouldReturnColumnsWithColonsForNakedFindByWithANamedParameter()
public void ShouldReturnColumnsWithColonsForNakedFindByExcludingExistingNamedParameter()
{
var target = CreateTarget();
var actual = target.GetOptions("db.Test.FindBy(Id: 1, ").ToArray();
Assert.Contains("Id:", actual);
Assert.DoesNotContain("Id:", actual);
Assert.Contains("Name:", actual);
}
}

[Fact]
public void ShouldReturnEmptyForNakedFindByWhenInValuePart()
{
var target = CreateTarget();
var actual = target.GetOptions("db.Test.FindBy(Id: 1").ToArray();
Assert.Empty(actual);
}

[Fact]
public void ShouldReturnEmptyForNakedFindByWhenJustAfterNamedParameter()
{
var target = CreateTarget();
var actual = target.GetOptions("db.Test.FindBy(Id:").ToArray();
Assert.Empty(actual);
}

private static IEnumerable<string> ExpectedQueryMethods(bool includeThenBy, params string[] columns)
{
Expand Down
55 changes: 45 additions & 10 deletions Simple.Data.Pad/AutoCompleter.cs
Expand Up @@ -57,13 +57,11 @@ private string[] GetOptionsImpl(string currentText)
int current = tokens.Length - 1;

int openMethodIndex;
if (IsInFindByCall(current, tokens, out openMethodIndex))
if ((tokens[current].Type == TokenType.OpenParen || tokens[current].Type == TokenType.Comma
|| tokens[current - 1].Type == TokenType.OpenParen || tokens[current - 1].Type == TokenType.Comma)
&& IsInCallWhichTakesNamedParameters(current, tokens, out openMethodIndex))
{
Table table = _schemaProvider.GetTables()
.Where(t => Prettify(t.ActualName) == Prettify(tokens[openMethodIndex - 2].Value.ToString()))
.SingleOrDefault();
if (table == null) return Empty;
return _schemaProvider.GetColumns(table).Select(c => Prettify(c.ActualName) + ":").ToArray();
return GetNamedParameterOptions(tokens, openMethodIndex, current);
}

if (tokens[current].Type != TokenType.Dot && tokens[current].Type != TokenType.Identifier) return Empty;
Expand Down Expand Up @@ -99,6 +97,36 @@ private string[] GetOptionsImpl(string currentText)
return array;
}

private string[] GetNamedParameterOptions(Token[] tokens, int openMethodIndex, int currentIndex)
{
string tableName = tokens[openMethodIndex - 2].Value.ToString();
Table table = _schemaProvider.GetTables()
.Where(t => Prettify(t.ActualName) == Prettify(tableName))
.SingleOrDefault();
if (table == null) return Empty;
var columnQuery = _schemaProvider.GetColumns(table).Select(c => Prettify(c.ActualName) + ":");

if (currentIndex - openMethodIndex > 2)
{
var usedParameterNames = new HashSet<string>();
for (int i = openMethodIndex + 1; i < currentIndex; i++)
{
if (tokens[i].Type == TokenType.Identifier && tokens[i+1].Type == TokenType.Colon)
{
usedParameterNames.Add(tokens[i].Value + ":");
++i;
}
}

if (usedParameterNames.Count > 0)
{
columnQuery = columnQuery.Where(s => !usedParameterNames.Contains(s));
}
}

return columnQuery.ToArray();
}

private static int FindUnmatchedOpenParen(Token[] tokens, int current)
{
int closeParenCount = 0;
Expand All @@ -121,12 +149,12 @@ private static int FindUnmatchedOpenParen(Token[] tokens, int current)
return -1;
}

private static bool IsInFindByCall(int current, Token[] tokens, out int openMethodIndex)
private static bool IsInCallWhichTakesNamedParameters(int current, Token[] tokens, out int openMethodIndex)
{
int openCallIndex = FindUnmatchedOpenParen(tokens, current);
if (openCallIndex > 0)
{
if (IsFindByCall(tokens[openCallIndex], tokens[openCallIndex - 1]))
if (IsCallWhichTakesNamedParameters(tokens[openCallIndex], tokens[openCallIndex - 1]))
{
openMethodIndex = openCallIndex - 1;
return true;
Expand All @@ -136,11 +164,16 @@ private static bool IsInFindByCall(int current, Token[] tokens, out int openMeth
return false;
}

private static bool IsFindByCall(Token current, Token previous)
private static bool IsCallWhichTakesNamedParameters(Token current, Token previous)
{
return current.Type == TokenType.OpenParen
&& previous.Type == TokenType.Identifier
&& previous.Value.ToString().Equals("FindBy", StringComparison.CurrentCultureIgnoreCase);
&& (previous.Value.ToString().Equals("FindBy", StringComparison.CurrentCultureIgnoreCase)
|| previous.Value.ToString().Equals("FindAllBy", StringComparison.CurrentCultureIgnoreCase)
|| previous.Value.ToString().Equals("Insert", StringComparison.CurrentCultureIgnoreCase)
|| previous.Value.ToString().StartsWith("DeleteBy", StringComparison.CurrentCultureIgnoreCase)
|| previous.Value.ToString().StartsWith("UpdateBy", StringComparison.CurrentCultureIgnoreCase)
);
}

private IEnumerable<string> GetOptionsForMethodReturnType(Token[] tokens, int current, bool methodChainIncludesOrderBy, string partial)
Expand Down Expand Up @@ -220,6 +253,8 @@ private IEnumerable<string> TableOptions(string tableName)

yield return "All";
yield return "Query";
yield return "FindBy";
yield return "FindAllBy";

foreach (var column in _schemaProvider.GetColumns(table).Select(c => Prettify(c.ActualName)))
{
Expand Down
2 changes: 1 addition & 1 deletion Simple.Data.Pad/MainViewModel.cs
Expand Up @@ -181,7 +181,7 @@ public IEnumerable<string> AutoCompleteOptions
{
get
{
if (QueryText.Length >= CursorPosition)
if ((!string.IsNullOrWhiteSpace(QueryText)) && QueryText.Length >= CursorPosition)
{
return _autoCompleter.GetOptions(QueryTextToCursor);
}
Expand Down
7 changes: 5 additions & 2 deletions Simple.Data.Pad/MainWindow.xaml.cs
Expand Up @@ -148,15 +148,18 @@ private void ListBoxMouseUp(object sender, RoutedEventArgs e)
SelectAutoCompleteText();
}

private static readonly HashSet<char> AutoCompleteTriggers =
new HashSet<char> {'.', ',', ' ', '('};

private void SelectAutoCompleteText(string andAppend = "")
{
var selected = AutoCompleteListBox.SelectedItem;
while (QueryTextBox.SelectedText.FirstOrDefault() != '.')
while (!AutoCompleteTriggers.Contains(QueryTextBox.SelectedText.FirstOrDefault()))
{
QueryTextBox.SelectionStart -= 1;
QueryTextBox.SelectionLength += 1;
}
QueryTextBox.SelectedText = "." + selected + andAppend;
QueryTextBox.SelectedText = string.Concat(QueryTextBox.SelectedText[0], selected, andAppend);
QueryTextBox.SelectionStart += QueryTextBox.SelectionLength;
QueryTextBox.SelectionLength = 0;
QueryTextBox.CaretIndex = QueryTextBox.SelectionStart;
Expand Down

0 comments on commit b2eb3e9

Please sign in to comment.