View Issue Details

IDProjectCategoryView StatusLast Update
0031126FPCPatchpublic2017-01-26 07:36
ReporterPaul MichellAssigned ToMichael Van Canneyt 
PrioritynormalSeverityminorReproducibilityN/A
Status closedResolutionfixed 
Product Version3.1.1Product Build35125 
Target Version3.2.0Fixed in Version3.1.1 
Summary0031126: AlwaysQuote property added to TStrings
DescriptionThis patch adds a property to TStrings that will force all items in the DelimitedText output to be quoted regardless of white space. Property defaults to false, so no change in current behaviour of the class.

Additional InformationThis is useful for generating things like SQL IN clauses using TStringsList:

"AField" IN ('ItemA','ItemB','ItemC')
TagsNo tags attached.
Fixed in Revision35333
FPCOldBugId
FPCTarget
Attached Files
  • AlwaysQuote.diff (1,565 bytes)
    Index: classesh.inc
    ===================================================================
    --- classesh.inc	(revision 35125)
    +++ classesh.inc	(working copy)
    @@ -603,6 +603,7 @@
         FDefaultEncoding: TEncoding;
         FEncoding: TEncoding;
         FSpecialCharsInited : boolean;
    +    FAlwaysQuote: Boolean;
         FQuoteChar : Char;
         FDelimiter : Char;
         FNameValueSeparator : Char;
    @@ -707,6 +708,7 @@
         property Encoding: TEncoding read FEncoding;
         property LineBreak : string Read GetLineBreak write SetLineBreak;
         Property StrictDelimiter : Boolean Read FStrictDelimiter Write FStrictDelimiter;
    +    property AlwaysQuote: Boolean read FAlwaysQuote write FAlwaysQuote;
         property QuoteChar: Char read GetQuoteChar write SetQuoteChar;
         Property NameValueSeparator : Char Read GetNameValueSeparator Write SetNameValueSeparator;
         property ValueFromIndex[Index: Integer]: string read GetValueFromIndex write SetValueFromIndex;
    Index: stringl.inc
    ===================================================================
    --- stringl.inc	(revision 35125)
    +++ stringl.inc	(working copy)
    @@ -217,7 +217,7 @@
         //Quote strings that include BreakChars:
         while not(p^ in BreakChars) do
          inc(p);
    -    if (p<>pchar(S)+length(S)) then
    +    if FAlwaysQuote or (p<>pchar(S)+length(S)) then
           Result:=Result+QuoteString(S,QuoteChar)
         else
           Result:=Result+S;
    @@ -722,6 +722,7 @@
       FDefaultEncoding:=TEncoding.Default;
       FEncoding:=nil;
       FWriteBOM:=True;
    +  FAlwaysQuote:=False;
     end;
     
     Function TStrings.Add(const S: string): Integer;
    
    AlwaysQuote.diff (1,565 bytes)
  • AlwaysQuoteTest.pas (580 bytes)
    Program AlwaysQuoteTest;
    
    Uses
      Classes;
    
    Var
      ItemList: TStringList;
    
    Begin
      ItemList := TStringList.Create;
      ItemList.Add('ItemOne');
      ItemList.Add('ItemTwo');
      ItemList.Add('ItemThree');
      ItemList.Add('Item With Spaces');
      ItemList.QuoteChar := '''';
      WriteLn('Default string list output:');
      WriteLn('SELECT * FROM "ATable" WHERE "AField" IN ('+ItemList.DelimitedText+');');
      ItemList.AlwaysQuote := True;
      WriteLn('String list output with AlwaysQuote:');
      WriteLn('SELECT * FROM "ATable" WHERE "AField" IN ('+ItemList.DelimitedText+');');
      ItemList.Free;
    End.
    
    
    AlwaysQuoteTest.pas (580 bytes)

Activities

Paul Michell

2016-12-16 12:44

reporter  

AlwaysQuote.diff (1,565 bytes)
Index: classesh.inc
===================================================================
--- classesh.inc	(revision 35125)
+++ classesh.inc	(working copy)
@@ -603,6 +603,7 @@
     FDefaultEncoding: TEncoding;
     FEncoding: TEncoding;
     FSpecialCharsInited : boolean;
+    FAlwaysQuote: Boolean;
     FQuoteChar : Char;
     FDelimiter : Char;
     FNameValueSeparator : Char;
@@ -707,6 +708,7 @@
     property Encoding: TEncoding read FEncoding;
     property LineBreak : string Read GetLineBreak write SetLineBreak;
     Property StrictDelimiter : Boolean Read FStrictDelimiter Write FStrictDelimiter;
+    property AlwaysQuote: Boolean read FAlwaysQuote write FAlwaysQuote;
     property QuoteChar: Char read GetQuoteChar write SetQuoteChar;
     Property NameValueSeparator : Char Read GetNameValueSeparator Write SetNameValueSeparator;
     property ValueFromIndex[Index: Integer]: string read GetValueFromIndex write SetValueFromIndex;
Index: stringl.inc
===================================================================
--- stringl.inc	(revision 35125)
+++ stringl.inc	(working copy)
@@ -217,7 +217,7 @@
     //Quote strings that include BreakChars:
     while not(p^ in BreakChars) do
      inc(p);
-    if (p<>pchar(S)+length(S)) then
+    if FAlwaysQuote or (p<>pchar(S)+length(S)) then
       Result:=Result+QuoteString(S,QuoteChar)
     else
       Result:=Result+S;
@@ -722,6 +722,7 @@
   FDefaultEncoding:=TEncoding.Default;
   FEncoding:=nil;
   FWriteBOM:=True;
+  FAlwaysQuote:=False;
 end;
 
 Function TStrings.Add(const S: string): Integer;
AlwaysQuote.diff (1,565 bytes)

Michael Van Canneyt

2016-12-16 14:48

administrator   ~0096829

Last edited: 2016-12-16 14:48

View 2 revisions

Can you please provide a small test program that tests what you expect as output ?

It will also make clear what this is supposed to do, because from your description I cannot understand what the expected output is.

Paul Michell

2016-12-16 15:06

reporter  

AlwaysQuoteTest.pas (580 bytes)
Program AlwaysQuoteTest;

Uses
  Classes;

Var
  ItemList: TStringList;

Begin
  ItemList := TStringList.Create;
  ItemList.Add('ItemOne');
  ItemList.Add('ItemTwo');
  ItemList.Add('ItemThree');
  ItemList.Add('Item With Spaces');
  ItemList.QuoteChar := '''';
  WriteLn('Default string list output:');
  WriteLn('SELECT * FROM "ATable" WHERE "AField" IN ('+ItemList.DelimitedText+');');
  ItemList.AlwaysQuote := True;
  WriteLn('String list output with AlwaysQuote:');
  WriteLn('SELECT * FROM "ATable" WHERE "AField" IN ('+ItemList.DelimitedText+');');
  ItemList.Free;
End.

AlwaysQuoteTest.pas (580 bytes)

Paul Michell

2016-12-16 15:09

reporter   ~0096830

I've uploaded a small test program. The output from this is as follows:

Default string list output:
SELECT * FROM "ATable" WHERE "AField" IN (ItemOne,ItemTwo,ItemThree,'Item With Spaces');

String list output with AlwaysQuote:
SELECT * FROM "ATable" WHERE "AField" IN ('ItemOne','ItemTwo','ItemThree','Item With Spaces');

There are instances when it is useful for delimited output to always insert quotes regardless of the absence of white space in the item. The example I am using is in generating a valid SQL statement.

Michael Van Canneyt

2017-01-25 23:38

administrator   ~0097715

Thank you for the example program. I have implemented AlwaysQuote, but changed the patch so the code is slightly more efficient.

Paul Michell

2017-01-26 07:36

reporter   ~0097717

Thank you

Issue History

Date Modified Username Field Change
2016-12-16 12:44 Paul Michell New Issue
2016-12-16 12:44 Paul Michell File Added: AlwaysQuote.diff
2016-12-16 14:46 Michael Van Canneyt Assigned To => Michael Van Canneyt
2016-12-16 14:46 Michael Van Canneyt Status new => assigned
2016-12-16 14:48 Michael Van Canneyt Note Added: 0096829
2016-12-16 14:48 Michael Van Canneyt Status assigned => feedback
2016-12-16 14:48 Michael Van Canneyt Note Edited: 0096829 View Revisions
2016-12-16 15:06 Paul Michell File Added: AlwaysQuoteTest.pas
2016-12-16 15:09 Paul Michell Note Added: 0096830
2016-12-16 15:09 Paul Michell Status feedback => assigned
2017-01-25 23:38 Michael Van Canneyt Fixed in Revision => 35333
2017-01-25 23:38 Michael Van Canneyt Note Added: 0097715
2017-01-25 23:38 Michael Van Canneyt Status assigned => resolved
2017-01-25 23:38 Michael Van Canneyt Fixed in Version => 3.1.1
2017-01-25 23:38 Michael Van Canneyt Resolution open => fixed
2017-01-25 23:38 Michael Van Canneyt Target Version => 3.2.0
2017-01-26 07:36 Paul Michell Note Added: 0097717
2017-01-26 07:36 Paul Michell Status resolved => closed