zmsql: Add new ZMDataset property FieldDelimiter (as requested in http://forum.lazarus.freepascal.org/index.php/topic,38705.msg271365.html#msg271365. Update demo1.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@6122 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2018-01-09 11:00:31 +00:00
parent 9b6ff70a30
commit c5ac664c09
4 changed files with 90 additions and 25 deletions

View File

@ -40,7 +40,7 @@
<PackageName Value="LCL"/>
</Item3>
</RequiredPackages>
<Units Count="14">
<Units Count="15">
<Unit0>
<Filename Value="project1.lpr"/>
<IsPartOfProject Value="True"/>
@ -55,8 +55,8 @@
<ResourceBaseClass Value="Form"/>
<UnitName Value="Unit1"/>
<IsVisibleTab Value="True"/>
<TopLine Value="41"/>
<CursorPos X="42" Y="69"/>
<TopLine Value="45"/>
<CursorPos X="23" Y="74"/>
<UsageCount Value="46"/>
<Loaded Value="True"/>
<LoadedDesigner Value="True"/>
@ -142,8 +142,17 @@
<CursorPos X="3" Y="103"/>
<UsageCount Value="10"/>
</Unit13>
<Unit14>
<Filename Value="../../source/zmquerydataset.pas"/>
<UnitName Value="ZMQueryDataSet"/>
<EditorIndex Value="1"/>
<TopLine Value="121"/>
<CursorPos X="95" Y="138"/>
<UsageCount Value="10"/>
<Loaded Value="True"/>
</Unit14>
</Units>
<JumpHistory Count="5" HistoryIndex="4">
<JumpHistory Count="9" HistoryIndex="8">
<Position1>
<Filename Value="unit1.pas"/>
<Caret Line="56" Column="13" TopLine="25"/>
@ -164,6 +173,22 @@
<Filename Value="unit1.pas"/>
<Caret Line="31" Column="30" TopLine="31"/>
</Position5>
<Position6>
<Filename Value="unit1.pas"/>
<Caret Line="69" Column="42" TopLine="41"/>
</Position6>
<Position7>
<Filename Value="unit1.pas"/>
<Caret Line="74" TopLine="43"/>
</Position7>
<Position8>
<Filename Value="unit1.pas"/>
<Caret Line="75" TopLine="44"/>
</Position8>
<Position9>
<Filename Value="unit1.pas"/>
<Caret Line="74" Column="23" TopLine="45"/>
</Position9>
</JumpHistory>
</ProjectOptions>
<CompilerOptions>

View File

@ -1,7 +1,7 @@
object Form1: TForm1
Left = 234
Left = 266
Height = 423
Top = 73
Top = 139
Width = 745
Caption = 'Form1'
ClientHeight = 423
@ -21,7 +21,7 @@ object Form1: TForm1
object DBNavigator1: TDBNavigator
Left = 224
Height = 25
Top = 72
Top = 66
Width = 241
BevelOuter = bvNone
ChildSizing.EnlargeHorizontal = crsScaleChilds
@ -38,8 +38,8 @@ object Form1: TForm1
end
object DBGrid1: TDBGrid
Left = 15
Height = 299
Top = 109
Height = 304
Top = 104
Width = 720
Anchors = [akTop, akLeft, akRight, akBottom]
AutoFillColumns = True
@ -94,6 +94,34 @@ object Form1: TForm1
OnClick = Button2Click
TabOrder = 3
end
object Label1: TLabel
Left = 560
Height = 15
Top = 45
Width = 100
Caption = 'New field delimiter'
ParentColor = False
end
object ComboBox1: TComboBox
Left = 560
Height = 23
Top = 66
Width = 175
ItemHeight = 15
ItemIndex = 1
Items.Strings = (
'semicolon (;)'
'tab (#9)'
'comma (,)'
'bar (|)'
'colon (:)'
'dash (-)'
'slash (/)'
'back-slash (\)'
)
TabOrder = 4
Text = 'tab (#9)'
end
object ZMConnection1: TZMConnection
Connected = False
FloatPrecision = 0

View File

@ -15,9 +15,11 @@ type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
ComboBox1: TComboBox;
Datasource1: TDatasource;
DBGrid1: TDBGrid;
DBNavigator1: TDBNavigator;
Label1: TLabel;
ZMConnection1: TZMConnection;
ZMQueryDataSet1: TZMQueryDataSet;
procedure Button1Click(Sender: TObject);
@ -50,18 +52,21 @@ end;
procedure TForm1.Button2Click(Sender: TObject);
var
vOriginalTableName:string;
vOrigDelim: TFieldDelimiter;
begin
try
vOriginalTableName:=ZMQueryDataset1.TableName;
vOrigDelim := ZMQueryDataset1.FieldDelimiter;
ZMQueryDataset1.TableName:='Test';
ZMQueryDataset1.FieldDelimiter := TFieldDelimiter(Combobox1.ItemIndex);
ShowMessage('Dataset is going to be saved to: '+
ZMQueryDataset1.ZMConnection.DatabasePath +
ZMQueryDataset1.TableName+'.csv');
ZMQueryDataset1.SaveToTable(FormatSettings.DecimalSeparator);
finally
ZMQueryDataset1.FieldDelimiter := vOrigDelim;
ZMQueryDataset1.TableName:=vOriginalTableName;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
@ -69,6 +74,5 @@ begin
ZMConnection1.DatabasePath := '..\data\';
end;
end.

View File

@ -135,6 +135,8 @@ type
TSourceData=(sdSdfDataset, sdJanSQL, sdOtherDataset, sdInternal);
TInspectFields=(ifCreateFieldsFromFieldDefs, ifCreateFieldDefsAndFields, ifDoNothing, ifNewIsEmpty, ifOther);
TFieldDelimiter = (fdSemicolon, fdTab, fdComma, fdBar, fdColon, fdDash, fdSlash, fdBackSlash);
// ; #9 , | : - / \
{ TZMQueryDataSet }
@ -154,6 +156,7 @@ type
FDoReferentialUpdate:Boolean;
FDynamicFieldsCreated: Boolean;
FFieldCount:Integer; //This is number of columns (fielddefs) that dataset will have after an action (after loading from a table, after loading from a dataset, after query execution....)
FFieldDelimiter: TFieldDelimiter;
FFieldsLoaded: boolean; //// edgarrod71@gmail.com
FJanSQLInstance:TjanSQL;
FMasterDataSetTo: TList;
@ -293,6 +296,7 @@ type
property MemoryDataSetOpened:Boolean read FMemoryDataSetOpened write SetMemoryDataSetOpened; //"True" executes CreateDynamicFieldsFromFieldDefs and activates dataset for editing.
property PersistentSave:Boolean read FPersistentSave write SetPersistentSave; //If "True", insert/delete/edit will immediately be written to underlying .csv file. If "False", then dataset is only in-memory.
property Parameters: TParams read FParameters write SetParameters; //Parameters for parameterized SQL text.
property FieldDelimiter: TFieldDelimiter read FFieldDelimiter write FFieldDelimiter default fdSemicolon;
//Read-only properties for getting info about referential integrity
property MasterRefKeysList:TList read FMasterReferentialKeys;//List of referential keys in which self is master dataset.
property SlaveRefKeysList:TList read FSlaveReferentialKeys; //List of referential keys in which self is slave dataset.
@ -344,8 +348,8 @@ uses
ZMReferentialKey;
const
C: Char = ';';
DELIMITERS: array[TFieldDelimiter] of char = (';', #9, ',', '|', ':', '-', '/', '\');
//fdSemicolon, fdTab, fdComma, fdBar, fdColon, fdDash, fdSlash, fdBackSlash);
{ TZMQueryDataSet }
@ -509,7 +513,7 @@ begin
FSdfDatasetImport.Close;
FSdfDatasetImport.FileName:=ZMConnection.DatabasePath{Full}+ TableName + '.csv';
FSdfDatasetImport.FirstLineAsSchema:=True;
FSdfDatasetImport.Delimiter := C;
FSdfDatasetImport.Delimiter := DELIMITERS[FFieldDelimiter];
FSdfDatasetImport.FileMustExist:=False;
FSdfDatasetImport.Open;
//Let object knows data source...
@ -549,7 +553,7 @@ begin
Close;
FileName:=ZMConnection.DatabasePath{Full}+TableName+'.csv';
FirstLineAsSchema:=True;
FSdfDatasetImport.Delimiter:= C;
FSdfDatasetImport.Delimiter:= DELIMITERS[FFieldDelimiter];
FSdfDatasetImport.FileMustExist:=False;
Open;
//Let object knows data source...
@ -1292,7 +1296,7 @@ begin
Dataset:=self;
FileName:=ZMConnection.DatabasePath{Full}+TableName+'.csv';
FromCurrent:=False;
FormatSettings.FieldDelimiter:= C;
FormatSettings.FieldDelimiter:= DELIMITERS[FFieldDelimiter];
FormatSettings.HeaderRow:=True;
// FormatSettings.QuoteStrings:=[qsAlways]; //=== ct9999 in FPC SVN 30449 NOT Exists ====
FormatSettings.BooleanFalse:='False';
@ -1346,7 +1350,7 @@ begin
{FileName:=ZMConnection.DatabasePathFull+TableName+'.txt';}
FileName:=ZMConnection.DatabasePath{Full}+TableName+'.csv';
FromCurrent:=False;
FormatSettings.FieldDelimiter:= C;
FormatSettings.FieldDelimiter:= DELIMITERS[FFieldDelimiter];
FormatSettings.HeaderRow:=True;
// FormatSettings.QuoteStrings:=[qsAlways]; //=== ct9999 in FPC SVN 30449 NOT Exists ====
FormatSettings.BooleanFalse:='False';
@ -1742,6 +1746,7 @@ var
vFieldDefNamesMatch:Boolean;
vNewIsEmpty:Boolean;
vFieldType: TFieldType;
vDelim: Char;
begin
//Set default values
Result:=ifOther;
@ -1753,16 +1758,17 @@ begin
vNewFieldNames:='';
vNewFieldDefNames:='';
vFieldDefsCount := FieldDefs.Count;
vDelim := DELIMITERS[FFieldDelimiter];
//Iterate through Old Dataset (assumption: There cannot be fields without fielddefs).
//FieldDefs
for i:=0 to pred(vFieldDefsCount) do begin
vOldFieldDefNames += FieldDefs[i].Name + C;
vOldFieldDefNames += FieldDefs[i].Name + vDelim;
vFieldType := FieldDefs[i].DataType;
if (vFieldType = ftAutoInc) and (FAutoIncIdx = -1) then
FAutoIncIdx := I; { Question (edgarrod71@gmail.com)::: how many AutoIncrement fields must syncronize with this? I suppose it must be only one! }
//Fields
if (Fields.Count>0) and (Fields.Count >= (i + 1)) then
vOldFieldNames += Fields[i].FieldName + C;
vOldFieldNames += Fields[i].FieldName + vDelim;
end;
// end;
//Iterate through New Dataset
@ -1772,9 +1778,9 @@ begin
else
for i:=0 to pred(FFieldCount) do begin
case FSourceData of
sdJanSQL:vNewFieldDefNames += FJanSQLInstance.recordsets[FRecordsetIndex].FieldNames[i]+ C;
sdSdfDataset:vNewFieldDefNames += FSdfDatasetImport.FieldDefs[i].Name+ C;
sdOtherDataset:vNewFieldDefNames += FOtherDatasetImport.FieldDefs[i].Name+ C;
sdJanSQL:vNewFieldDefNames += FJanSQLInstance.recordsets[FRecordsetIndex].FieldNames[i]+ vDelim;
sdSdfDataset:vNewFieldDefNames += FSdfDatasetImport.FieldDefs[i].Name+ vDelim;
sdOtherDataset:vNewFieldDefNames += FOtherDatasetImport.FieldDefs[i].Name+ vDelim;
//// sdInternal: vNewFieldDefNames += FieldDefs[i].Name+';'; //// Old Code, review it to eliminate
end;
end;
@ -2522,9 +2528,11 @@ var
procedure FillFieldDefs;
var
vFieldDef: TFieldDef;
vDelim: Char;
begin
if FieldDefs.Count > 0 then
FieldDefs.Clear;
vDelim := DELIMITERS[FFieldDelimiter];
P := @S[1];
if P <> '' then
repeat /// This gets the Fields from File and updates FieldDefs...
@ -2532,8 +2540,8 @@ var
repeat
fField += P^;
inc(P);
until P^ in [#0, #10, #13, C];
if P^ = C then inc(P);
until P^ in [#0, #10, #13, vDelim];
if P^ = vDelim then inc(P);
vFieldDef := FieldDefs.AddFieldDef;
vFieldDef.Name := fField;
vFieldDef.DataType:=ftString;
@ -2622,7 +2630,7 @@ begin
vtString: value := Values[i].vString^;
end;
if i <> High(Values) then
value += C
value += DELIMITERS[FFieldDelimiter]
else
value += #10;
Result := boolean(FTableFile.Write(PChar(value)^, length(value)));