From 62fe0fd9ef4da3047cf56f96cfd619ffd27cb3f6 Mon Sep 17 00:00:00 2001 From: joyfullservice Date: Wed, 15 Nov 2023 15:10:22 -0600 Subject: [PATCH] Add support for ! boundary character This character is used in Microsoft Access in a query when referring directly to a control on a form, and should be treated similar to a period as a separator between elements. #457 --- .../modules/clsSqlFormatter.cls | 76 +++++++++++++++++-- 1 file changed, 70 insertions(+), 6 deletions(-) diff --git a/Version Control.accda.src/modules/clsSqlFormatter.cls b/Version Control.accda.src/modules/clsSqlFormatter.cls index 6ee0f6d7..dd53f9be 100644 --- a/Version Control.accda.src/modules/clsSqlFormatter.cls +++ b/Version Control.accda.src/modules/clsSqlFormatter.cls @@ -359,7 +359,8 @@ Public Function FormatSQL(Optional strSql As String, Optional intDialect As eSql ' If the token shouldn't have a space before it If strTokenValue = "." _ Or strTokenValue = "," _ - Or strTokenValue = ";" Then + Or strTokenValue = ";" _ + Or (strTokenValue = "!" And m_intDialect = esdAccess) Then ' Trim any whitespace cReturn.RTrim End If @@ -368,7 +369,9 @@ Public Function FormatSQL(Optional strSql As String, Optional intDialect As eSql cReturn.Add strTokenValue, " " ' If the token shouldn't have a space after it - If strTokenValue = "(" Or strTokenValue = "." Then + If strTokenValue = "(" _ + Or strTokenValue = "." _ + Or (strTokenValue = "!" And m_intDialect = esdAccess) Then cReturn.RTrim End If @@ -512,7 +515,8 @@ Private Sub Tokenize(strSql As String, intDialect As eSqlDialect) ' A reserved word cannot be preceded by a "." ' This makes it so in "mytable.from", "from" is not considered a reserved word - ElseIf PeekChar(-1, ".") Then + ElseIf PeekChar(-1, ".") _ + Or (PeekChar(-1, "!") And m_intDialect = esdAccess) Then ' Likely an object name If HasMatches("^(.*?)($|\s|[""\'`]|" & RegExBoundaries & ")", strMatch) Then @@ -1461,9 +1465,69 @@ Public Sub SelfTest() If (strActual <> FormatSQL) Then Diff.Strings strActual, FormatSQL - 'PrintTokens - 'BuildTestFromTokens - 'Diff.Strings strActual, FormatSQL + ' Test multi-part names + Tokenize "SELECT [dbo].[field] FROM [server].[schema].[table];", esdMSSQL + + ' Verify tokens + Debug.Assert m_colTokens.Count = 13 + Debug.Assert VerifyToken(1, ttReservedTopLevel, "SELECT") + Debug.Assert VerifyToken(2, ttWhitespace, " ") + Debug.Assert VerifyToken(3, ttQuote, "[dbo]") + Debug.Assert VerifyToken(4, ttBoundary, ".") + Debug.Assert VerifyToken(5, ttQuote, "[field]") + Debug.Assert VerifyToken(6, ttWhitespace, " ") + Debug.Assert VerifyToken(7, ttReservedTopLevel, "FROM") + Debug.Assert VerifyToken(8, ttWhitespace, " ") + Debug.Assert VerifyToken(9, ttQuote, "[server]") + Debug.Assert VerifyToken(10, ttBoundary, ".") + Debug.Assert VerifyToken(11, ttQuote, "[schema]") + Debug.Assert VerifyToken(12, ttBoundary, ".") + Debug.Assert VerifyToken(13, ttQuote, "[table]") + + ' Verify result + With New clsConcat + .AppendOnAdd = vbCrLf + .Add "SELECT" + .Add " [dbo].[field]" + .Add "FROM" + .Add " [server].[schema].[table]" + .Remove 2 + strActual = .GetStr + End With + Debug.Assert (strActual = FormatSQL) + If (strActual <> FormatSQL) Then Diff.Strings strActual, FormatSQL + + + ' Test parameter expression + Tokenize "SELECT [Forms]![frmColors]![Text18];", esdAccess + + ' Verify tokens + Debug.Assert m_colTokens.Count = 7 + Debug.Assert VerifyToken(1, ttReservedTopLevel, "SELECT") + Debug.Assert VerifyToken(2, ttWhitespace, " ") + Debug.Assert VerifyToken(3, ttQuote, "[Forms]") + Debug.Assert VerifyToken(4, ttBoundary, "!") + Debug.Assert VerifyToken(5, ttQuote, "[frmColors]") + Debug.Assert VerifyToken(6, ttBoundary, "!") + Debug.Assert VerifyToken(7, ttQuote, "[Text18]") + + ' Verify result + With New clsConcat + .AppendOnAdd = vbCrLf + .Add "SELECT" + .Add " [Forms]![frmColors]![Text18]" + .Remove 2 + strActual = .GetStr + End With + Debug.Assert (strActual = FormatSQL) + If (strActual <> FormatSQL) Then Diff.Strings strActual, FormatSQL + +' PrintTokens +' BuildTestFromTokens +' Diff.Strings strActual, FormatSQL + + ' Test performance + TestPerformance End Sub