Introduce an auto-quoting mode in TDBConnection.EscapeString, and use that to get rid of quotes around hex values and integers in quick filters

This commit is contained in:
Ansgar Becker
2021-05-01 07:35:56 +02:00
parent b271107dad
commit 65cf4a5820
4 changed files with 33 additions and 30 deletions

View File

@ -26,6 +26,7 @@ type
TColumnDefaultType = (cdtNothing, cdtText, cdtNull, cdtAutoInc, cdtExpression);
// General purpose editing status flag
TEditingStatus = (esUntouched, esModified, esDeleted, esAddedUntouched, esAddedModified, esAddedDeleted);
TBoolAuto = (baFalse, baTrue, baAuto);
// Column object, many of them in a TObjectList
TTableColumn = class(TPersistent)
@ -484,7 +485,7 @@ type
destructor Destroy; override;
procedure Query(SQL: String; DoStoreResult: Boolean=False; LogCategory: TDBLogCategory=lcSQL); virtual; abstract;
procedure Log(Category: TDBLogCategory; Msg: String);
function EscapeString(Text: String; ProcessJokerChars: Boolean=False; DoQuote: Boolean=True): String;
function EscapeString(Text: String; ProcessJokerChars: Boolean=False; DoQuote: TBoolAuto=baTrue): String;
function QuoteIdent(Identifier: String; AlwaysQuote: Boolean=True; Glue: Char=#0): String;
function DeQuoteIdent(Identifier: String; Glue: Char=#0): String;
function QuotedDbAndTableName(DB, Obj: String): String;
@ -4361,7 +4362,7 @@ end;
@param boolean Escape text so it can be used in a LIKE-comparison
@return string
}
function TDBConnection.EscapeString(Text: String; ProcessJokerChars: Boolean=false; DoQuote: Boolean=True): String;
function TDBConnection.EscapeString(Text: String; ProcessJokerChars: Boolean=false; DoQuote: TBoolAuto=baTrue): String;
var
c1, c2, c3, c4, EscChar: Char;
begin
@ -4427,7 +4428,9 @@ begin
end;
if DoQuote then begin
if (DoQuote = baTrue)
or ((DoQuote = baAuto) and (not ExecRegExpr('^(0x[a-fA-F0-9]*|\d+)$', Result)))
then begin
// Add surrounding single quotes
Result := Char(#39) + Result + Char(#39);
end;

View File

@ -644,14 +644,14 @@ begin
Value := FileContent;
end else begin
Value := StringReplace(Value, '%filesize%', IntToStr(FileSize), [rfReplaceAll]);
Value := StringReplace(Value, '%filename%', FConnection.EscapeString(ExtractFileName(FileInfo.Filename), False, False), [rfReplaceAll]);
Value := StringReplace(Value, '%filepath%', FConnection.EscapeString(ExtractFilePath(FileInfo.Filename), False, False), [rfReplaceAll]);
Value := StringReplace(Value, '%filename%', FConnection.EscapeString(ExtractFileName(FileInfo.Filename), False, baFalse), [rfReplaceAll]);
Value := StringReplace(Value, '%filepath%', FConnection.EscapeString(ExtractFilePath(FileInfo.Filename), False, baFalse), [rfReplaceAll]);
FileAge(FileInfo.Filename, FileDate);
DecodeDate(FileDate, y, m, d);
DecodeTime(FileDate, h, mi, s, ms);
Value := StringReplace(Value, '%filedate%', FConnection.EscapeString(Format('%.4d-%.2d-%.2d', [y,m,d]), False, False), [rfReplaceAll]);
Value := StringReplace(Value, '%filedatetime%', FConnection.EscapeString(Format('%.4d-%.2d-%.2d %.2d:%.2d:%.2d', [y,m,d,h,mi,s]), False, False), [rfReplaceAll]);
Value := StringReplace(Value, '%filetime%', FConnection.EscapeString(Format('%.2d:%.2d:%.2d', [h,mi,s]), False, False), [rfReplaceAll]);
Value := StringReplace(Value, '%filedate%', FConnection.EscapeString(Format('%.4d-%.2d-%.2d', [y,m,d]), False, baFalse), [rfReplaceAll]);
Value := StringReplace(Value, '%filedatetime%', FConnection.EscapeString(Format('%.4d-%.2d-%.2d %.2d:%.2d:%.2d', [y,m,d,h,mi,s]), False, baFalse), [rfReplaceAll]);
Value := StringReplace(Value, '%filetime%', FConnection.EscapeString(Format('%.2d:%.2d:%.2d', [h,mi,s]), False, baFalse), [rfReplaceAll]);
end;
end;
sql := sql + Value + ', ';

View File

@ -6926,15 +6926,15 @@ begin
Val := DataGrid.Text[DataGrid.FocusedNode, DataGrid.FocusedColumn];
if InputQuery(_('Specify filter-value...'), Act.Caption, Val) then begin
if Act = actQuickFilterPrompt1 then
Filter := Col + ' = ''' + Val + ''''
Filter := Col + ' = ' + Conn.EscapeString(Val, False, baAuto)
else if Act = actQuickFilterPrompt2 then
Filter := Col + ' != ''' + Val + ''''
Filter := Col + ' != ' + Conn.EscapeString(Val, False, baAuto)
else if Act = actQuickFilterPrompt3 then
Filter := Col + ' > ''' + Val + ''''
Filter := Col + ' > ' + Conn.EscapeString(Val, False, baAuto)
else if Act = actQuickFilterPrompt4 then
Filter := Col + ' < ''' + Val + ''''
Filter := Col + ' < ' + Conn.EscapeString(Val, False, baAuto)
else if Act = actQuickFilterPrompt5 then
Filter := Conn.GetSQLSpecifity(spLikeCompare, [Col, '''%' + Val + '%''']);
Filter := Conn.GetSQLSpecifity(spLikeCompare, [Col, Conn.EscapeString('%'+Val+'%', False, baAuto)]);
end;
end
else begin
@ -7493,19 +7493,19 @@ begin
HasNotNullValue := True;
Value := Grid.Text[Node, Grid.FocusedColumn];
if IncludedValues.IndexOf(Value) = -1 then begin
actQuickFilterFocused1.Hint := actQuickFilterFocused1.Hint + Results.Connection.EscapeString(Value) + ', ';
actQuickFilterFocused2.Hint := actQuickFilterFocused2.Hint + Results.Connection.EscapeString(Value) + ', ';
actQuickFilterFocused1.Hint := actQuickFilterFocused1.Hint + Results.Connection.EscapeString(Value, False, baAuto) + ', ';
actQuickFilterFocused2.Hint := actQuickFilterFocused2.Hint + Results.Connection.EscapeString(Value, False, baAuto) + ', ';
actQuickFilterFocused3.Hint := actQuickFilterFocused3.Hint +
Results.Connection.GetSQLSpecifity(spLikeCompare, [Col, '''' + Results.Connection.EscapeString(Value, True, False) + '%''']) +
Results.Connection.GetSQLSpecifity(spLikeCompare, [Col, '''' + Results.Connection.EscapeString(Value, True, baFalse) + '%''']) +
' OR ';
actQuickFilterFocused4.Hint := actQuickFilterFocused4.Hint +
Results.Connection.GetSQLSpecifity(spLikeCompare, [Col, '''%' + Results.Connection.EscapeString(Value, True, False) + '''']) +
Results.Connection.GetSQLSpecifity(spLikeCompare, [Col, '''%' + Results.Connection.EscapeString(Value, True, baFalse) + '''']) +
' OR ';
actQuickFilterFocused5.Hint := actQuickFilterFocused5.Hint +
Results.Connection.GetSQLSpecifity(spLikeCompare, [Col, '''%' + Results.Connection.EscapeString(Value, True, False) + '%''']) +
Results.Connection.GetSQLSpecifity(spLikeCompare, [Col, '''%' + Results.Connection.EscapeString(Value, True, baFalse) + '%''']) +
' OR ';
actQuickFilterFocused6.Hint := actQuickFilterFocused6.Hint + Col + ' > ' + Results.Connection.EscapeString(Value) + ' OR ';
actQuickFilterFocused7.Hint := actQuickFilterFocused7.Hint + Col + ' < ' + Results.Connection.EscapeString(Value) + ' OR ';
actQuickFilterFocused6.Hint := actQuickFilterFocused6.Hint + Col + ' > ' + Results.Connection.EscapeString(Value, False, baAuto) + ' OR ';
actQuickFilterFocused7.Hint := actQuickFilterFocused7.Hint + Col + ' < ' + Results.Connection.EscapeString(Value, False, baAuto) + ' OR ';
IncludedValues.Add(Value);
end;
end;
@ -7563,15 +7563,15 @@ begin
Value := Trim(Clipboard.AsText);
if Length(Value) < SIZE_KB then begin
actQuickFilterClipboard1.Enabled := true;
actQuickFilterClipboard1.Hint := Col + ' = ' + Results.Connection.EscapeString(Value);
actQuickFilterClipboard1.Hint := Col + ' = ' + Results.Connection.EscapeString(Value, False, baAuto);
actQuickFilterClipboard2.Enabled := true;
actQuickFilterClipboard2.Hint := Col + ' != ' + Results.Connection.EscapeString(Value);
actQuickFilterClipboard2.Hint := Col + ' != ' + Results.Connection.EscapeString(Value, False, baAuto);
actQuickFilterClipboard3.Enabled := true;
actQuickFilterClipboard3.Hint := Col + ' > ' + Results.Connection.EscapeString(Value);
actQuickFilterClipboard3.Hint := Col + ' > ' + Results.Connection.EscapeString(Value, False, baAuto);
actQuickFilterClipboard4.Enabled := true;
actQuickFilterClipboard4.Hint := Col + ' < ' + Results.Connection.EscapeString(Value);
actQuickFilterClipboard4.Hint := Col + ' < ' + Results.Connection.EscapeString(Value, False, baAuto);
actQuickFilterClipboard5.Enabled := true;
actQuickFilterClipboard5.Hint := Results.Connection.GetSQLSpecifity(spLikeCompare, [Col, '''%' + Results.Connection.EscapeString(Value, True, False) + '%''']);
actQuickFilterClipboard5.Hint := Results.Connection.GetSQLSpecifity(spLikeCompare, [Col, '''%' + Results.Connection.EscapeString(Value, True, baFalse) + '%''']);
actQuickFilterClipboard6.Enabled := true;
actQuickFilterClipboard6.Hint := Col + ' IN (' + Value + ')';
end else begin
@ -9696,7 +9696,7 @@ begin
Conditions := TStringList.Create;
for i:=0 to SelectedTableColumns.Count-1 do begin
// The normal case: do a LIKE comparison
Condition := '''%' + Conn.EscapeString(ed.Text, True, False)+'%''';
Condition := '''%' + Conn.EscapeString(ed.Text, True, baFalse)+'%''';
Condition := Conn.GetSQLSpecifity(spLikeCompare, [SelectedTableColumns[i].CastAsText, Condition]);
if not SelectedTableColumns[i].DataType.ValueMustMatch.IsEmpty then begin
// Use an exact comparison for some PostgreSQL data types to overcome SQL errors, e.g. UUID, INT etc.

View File

@ -125,7 +125,7 @@ begin
Obj.Assign(DBObj^);
// Database privileges can be wildcarded. Tables/columns not so.
if Obj.NodeType = lntDb then
Obj.Database := FConnection.EscapeString(Obj.Database, True, False);
Obj.Database := FConnection.EscapeString(Obj.Database, True, baFalse);
if Obj.NodeType = lntNone then begin
Obj.NodeType := lntDb;
Obj.Database := '%';
@ -148,9 +148,9 @@ begin
if Assigned(Node) then begin
case Sender.GetNodeLevel(Node) of
0: editDb.Text := '%';
1: editDb.Text := FConnection.EscapeString(Tree.Text[Node, 0], True, False);
2: editDb.Text := FConnection.EscapeString(Tree.Text[Node.Parent, 0], True, False);
3: editDb.Text := FConnection.EscapeString(Tree.Text[Node.Parent.Parent, 0], True, False);
1: editDb.Text := FConnection.EscapeString(Tree.Text[Node, 0], True, baFalse);
2: editDb.Text := FConnection.EscapeString(Tree.Text[Node.Parent, 0], True, baFalse);
3: editDb.Text := FConnection.EscapeString(Tree.Text[Node.Parent.Parent, 0], True, baFalse);
end;
end;
// Indicate automatic changes only