diff --git a/components/zmsql/demo/project1/project1.lpi b/components/zmsql/demo/project1/project1.lpi index 89b0087a0..ea11de18d 100644 --- a/components/zmsql/demo/project1/project1.lpi +++ b/components/zmsql/demo/project1/project1.lpi @@ -40,7 +40,7 @@ - + @@ -55,8 +55,8 @@ - - + + @@ -142,8 +142,17 @@ + + + + + + + + + - + @@ -164,6 +173,22 @@ + + + + + + + + + + + + + + + + diff --git a/components/zmsql/demo/project1/unit1.lfm b/components/zmsql/demo/project1/unit1.lfm index 2804982d7..f8d3d8902 100644 --- a/components/zmsql/demo/project1/unit1.lfm +++ b/components/zmsql/demo/project1/unit1.lfm @@ -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 diff --git a/components/zmsql/demo/project1/unit1.pas b/components/zmsql/demo/project1/unit1.pas index cc24494c8..b4f074f46 100644 --- a/components/zmsql/demo/project1/unit1.pas +++ b/components/zmsql/demo/project1/unit1.pas @@ -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. diff --git a/components/zmsql/source/zmquerydataset.pas b/components/zmsql/source/zmquerydataset.pas index 4b6b3317a..76fca42eb 100644 --- a/components/zmsql/source/zmquerydataset.pas +++ b/components/zmsql/source/zmquerydataset.pas @@ -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)));