Improvements for CSV import dialog:

* Add feature: Read and write all options from / to registry, using some existing CSV-options
* Fix bug: Correct escaping for db, table, columns, values for terminator, etc.
* Style change: Drop superflous checkboxes from checkbox/edit pairs to save clicks. Checking for empty edits has the same effect.
* Style change: Don't convert backslashes in filename to slashes. No need to take care of escaping, esc() does that better.
This commit is contained in:
Ansgar Becker
2007-07-05 19:45:18 +00:00
parent 8bc4e646f3
commit bf68e4433c
2 changed files with 112 additions and 135 deletions

View File

@ -40,7 +40,7 @@ object loaddataform: Tloaddataform
end end
object lblFields: TLabel object lblFields: TLabel
Left = 208 Left = 208
Top = 56 Top = 58
Width = 30 Width = 30
Height = 13 Height = 13
Caption = 'Fields:' Caption = 'Fields:'
@ -52,13 +52,12 @@ object loaddataform: Tloaddataform
Height = 13 Height = 13
Caption = 'Lines:' Caption = 'Lines:'
end end
object lblIgnoreLines: TLabel object lblIgnoreLinesCount: TLabel
Left = 415 Left = 415
Top = 169 Top = 169
Width = 25 Width = 25
Height = 13 Height = 13
Caption = 'Lines' Caption = 'Lines'
Enabled = False
end end
object lblColumns: TLabel object lblColumns: TLabel
Left = 16 Left = 16
@ -84,6 +83,41 @@ object loaddataform: Tloaddataform
'ons > 3.22.6. On previous versions you will get an error!' 'ons > 3.22.6. On previous versions you will get an error!'
WordWrap = True WordWrap = True
end end
object lblFieldTerminater: TLabel
Left = 272
Top = 58
Width = 63
Height = 13
Caption = 'terminated by'
end
object lblFieldEncloser: TLabel
Left = 272
Top = 83
Width = 57
Height = 13
Caption = 'enclosed by'
end
object lblFieldEscaper: TLabel
Left = 272
Top = 107
Width = 55
Height = 13
Caption = 'escaped by'
end
object lblLineTerminator: TLabel
Left = 272
Top = 147
Width = 63
Height = 13
Caption = 'terminated by'
end
object lblIgnoreLines: TLabel
Left = 272
Top = 170
Width = 29
Height = 13
Caption = 'ignore'
end
object btnImport: TButton object btnImport: TButton
Left = 328 Left = 328
Top = 312 Top = 312
@ -150,57 +184,27 @@ object loaddataform: Tloaddataform
TabOrder = 5 TabOrder = 5
OnChange = comboTableChange OnChange = comboTableChange
end end
object chkFieldsTerminated: TCheckBox
Left = 272
Top = 56
Width = 97
Height = 17
Caption = 'terminated by'
TabOrder = 6
OnClick = chkFieldsTerminatedClick
end
object editFieldTerminator: TEdit object editFieldTerminator: TEdit
Left = 360 Left = 360
Top = 56 Top = 56
Width = 49 Width = 49
Height = 21 Height = 21
Enabled = False TabOrder = 6
TabOrder = 7
Text = '\t' Text = '\t'
end end
object chkFieldsEnclosed: TCheckBox
Left = 272
Top = 80
Width = 97
Height = 17
Caption = 'enclosed by'
TabOrder = 8
OnClick = chkFieldsEnclosedClick
end
object editFieldEncloser: TEdit object editFieldEncloser: TEdit
Left = 360 Left = 360
Top = 80 Top = 80
Width = 49 Width = 49
Height = 21 Height = 21
Enabled = False TabOrder = 7
TabOrder = 9
end
object chkFieldsEscaped: TCheckBox
Left = 272
Top = 104
Width = 97
Height = 17
Caption = 'escaped by'
TabOrder = 10
OnClick = chkFieldsEscapedClick
end end
object editFieldEscaper: TEdit object editFieldEscaper: TEdit
Left = 360 Left = 360
Top = 104 Top = 104
Width = 49 Width = 49
Height = 21 Height = 21
Enabled = False TabOrder = 8
TabOrder = 11
Text = '\\' Text = '\\'
end end
object chkFieldsEnclosedOptionally: TCheckBox object chkFieldsEnclosedOptionally: TCheckBox
@ -209,43 +213,23 @@ object loaddataform: Tloaddataform
Width = 73 Width = 73
Height = 17 Height = 17
Caption = 'optionally' Caption = 'optionally'
Enabled = False TabOrder = 9
TabOrder = 12
end
object chkLinesTerminated: TCheckBox
Left = 272
Top = 144
Width = 89
Height = 17
Caption = 'terminated by'
TabOrder = 13
OnClick = chkLinesTerminatedClick
end end
object editLineTerminator: TEdit object editLineTerminator: TEdit
Left = 360 Left = 360
Top = 144 Top = 144
Width = 49 Width = 49
Height = 21 Height = 21
Enabled = False TabOrder = 10
TabOrder = 14
Text = '\n' Text = '\n'
end end
object chkLinesIgnore: TCheckBox
Left = 272
Top = 168
Width = 73
Height = 17
Caption = 'ignore'
TabOrder = 15
OnClick = chkLinesIgnoreClick
end
object chklistColumns: TCheckListBox object chklistColumns: TCheckListBox
Left = 16 Left = 16
Top = 128 Top = 128
Width = 121 Width = 121
Height = 161 Height = 161
ItemHeight = 13 ItemHeight = 13
TabOrder = 16 TabOrder = 11
end end
object comboDatabase: TComboBox object comboDatabase: TComboBox
Left = 16 Left = 16
@ -254,7 +238,7 @@ object loaddataform: Tloaddataform
Height = 21 Height = 21
Style = csDropDownList Style = csDropDownList
ItemHeight = 13 ItemHeight = 13
TabOrder = 17 TabOrder = 12
OnChange = comboDatabaseChange OnChange = comboDatabaseChange
end end
object chkReplace: TCheckBox object chkReplace: TCheckBox
@ -263,7 +247,7 @@ object loaddataform: Tloaddataform
Width = 65 Width = 65
Height = 17 Height = 17
Caption = 'Replace' Caption = 'Replace'
TabOrder = 18 TabOrder = 13
OnClick = chkReplaceClick OnClick = chkReplaceClick
end end
object chkIgnore: TCheckBox object chkIgnore: TCheckBox
@ -272,7 +256,7 @@ object loaddataform: Tloaddataform
Width = 57 Width = 57
Height = 17 Height = 17
Caption = 'Ignore' Caption = 'Ignore'
TabOrder = 19 TabOrder = 14
OnClick = chkIgnoreClick OnClick = chkIgnoreClick
end end
object btnColUp: TBitBtn object btnColUp: TBitBtn
@ -280,7 +264,7 @@ object loaddataform: Tloaddataform
Top = 178 Top = 178
Width = 25 Width = 25
Height = 25 Height = 25
TabOrder = 21 TabOrder = 16
OnClick = btnColUpClick OnClick = btnColUpClick
Glyph.Data = { Glyph.Data = {
F6000000424DF600000000000000760000002800000010000000100000000100 F6000000424DF600000000000000760000002800000010000000100000000100
@ -297,7 +281,7 @@ object loaddataform: Tloaddataform
Top = 202 Top = 202
Width = 25 Width = 25
Height = 25 Height = 25
TabOrder = 20 TabOrder = 15
OnClick = btnColDownClick OnClick = btnColDownClick
Glyph.Data = { Glyph.Data = {
F6000000424DF600000000000000760000002800000010000000100000000100 F6000000424DF600000000000000760000002800000010000000100000000100
@ -314,20 +298,18 @@ object loaddataform: Tloaddataform
Top = 167 Top = 167
Width = 33 Width = 33
Height = 21 Height = 21
Enabled = False TabOrder = 17
TabOrder = 22
Text = '1' Text = '1'
end end
object updownIgnoreLines: TUpDown object updownIgnoreLines: TUpDown
Left = 391 Left = 393
Top = 168 Top = 167
Width = 18 Width = 18
Height = 21 Height = 21
Associate = editIgnoreLines Associate = editIgnoreLines
Enabled = False
Max = 32767 Max = 32767
Position = 1 Position = 1
TabOrder = 23 TabOrder = 18
end end
object OpenDialogCSVFile: TOpenDialog object OpenDialogCSVFile: TOpenDialog
DefaultExt = 'csv' DefaultExt = 'csv'

View File

@ -23,19 +23,14 @@ type
lblTable: TLabel; lblTable: TLabel;
comboTable: TComboBox; comboTable: TComboBox;
lblFilename: TLabel; lblFilename: TLabel;
chkFieldsTerminated: TCheckBox;
lblFields: TLabel; lblFields: TLabel;
editFieldTerminator: TEdit; editFieldTerminator: TEdit;
chkFieldsEnclosed: TCheckBox;
editFieldEncloser: TEdit; editFieldEncloser: TEdit;
chkFieldsEscaped: TCheckBox;
editFieldEscaper: TEdit; editFieldEscaper: TEdit;
chkFieldsEnclosedOptionally: TCheckBox; chkFieldsEnclosedOptionally: TCheckBox;
lblLines: TLabel; lblLines: TLabel;
chkLinesTerminated: TCheckBox;
editLineTerminator: TEdit; editLineTerminator: TEdit;
chkLinesIgnore: TCheckBox; lblIgnoreLinesCount: TLabel;
lblIgnoreLines: TLabel;
lblColumns: TLabel; lblColumns: TLabel;
chklistColumns: TCheckListBox; chklistColumns: TCheckListBox;
comboDatabase: TComboBox; comboDatabase: TComboBox;
@ -48,15 +43,15 @@ type
btnColDown: TBitBtn; btnColDown: TBitBtn;
editIgnoreLines: TEdit; editIgnoreLines: TEdit;
updownIgnoreLines: TUpDown; updownIgnoreLines: TUpDown;
lblFieldTerminater: TLabel;
lblFieldEncloser: TLabel;
lblFieldEscaper: TLabel;
lblLineTerminator: TLabel;
lblIgnoreLines: TLabel;
procedure btnCancelClick(Sender: TObject); procedure btnCancelClick(Sender: TObject);
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
procedure comboDatabaseChange(Sender: TObject); procedure comboDatabaseChange(Sender: TObject);
procedure comboTableChange(Sender: TObject); procedure comboTableChange(Sender: TObject);
procedure chkFieldsTerminatedClick(Sender: TObject);
procedure chkFieldsEnclosedClick(Sender: TObject);
procedure chkFieldsEscapedClick(Sender: TObject);
procedure chkLinesTerminatedClick(Sender: TObject);
procedure chkLinesIgnoreClick(Sender: TObject);
procedure btnImportClick(Sender: TObject); procedure btnImportClick(Sender: TObject);
procedure btnOpenFileClick(Sender: TObject); procedure btnOpenFileClick(Sender: TObject);
procedure chkReplaceClick(Sender: TObject); procedure chkReplaceClick(Sender: TObject);
@ -102,6 +97,7 @@ procedure Tloaddataform.FormShow(Sender: TObject);
var var
tn : TTreeNode; tn : TTreeNode;
i : Integer; i : Integer;
reg : TRegistry;
begin begin
// read dbs and Tables from treeview // read dbs and Tables from treeview
comboDatabase.Items.Clear; comboDatabase.Items.Clear;
@ -122,13 +118,29 @@ begin
end; end;
comboDatabaseChange(self); comboDatabaseChange(self);
reg := TRegistry.Create;
if reg.OpenKey(REGPATH, true) then
begin
// filename // filename
with TRegistry.Create do editFilename.Text := reg.ReadString('loadfilename');
if OpenKey(REGPATH, true) then // Use options from CSV export
editFilename.Text := ReadString('loadfilename'); editFieldTerminator.Text := reg.ReadString('CSVSeparator');
if editFilename.Text = '' then editFieldEncloser.Text := reg.ReadString('CSVEncloser');
editFilename.Text := ExtractFilePath(paramstr(0)) + 'import.csv'; editLineTerminator.Text := reg.ReadString('CSVTerminator');
editFilename.Text := stringreplace(editFilename.Text, '\', '/', [rfReplaceAll]); // Other options
if reg.ValueExists('CSVImportFieldsEnclosedOptionally') then
chkFieldsEnclosedOptionally.Checked := reg.ReadBool('CSVImportFieldsEnclosedOptionally');
editFieldEscaper.Text := reg.ReadString('CSVImportFieldEscaper');
if reg.ValueExists('CSVImportIgnoreLines') then
updownIgnoreLines.Position := reg.ReadInteger('CSVImportIgnoreLines');
if reg.ValueExists('CSVImportLowPriority') then
chkLowPriority.Checked := reg.ReadBool('CSVImportLowPriority');
if reg.ValueExists('CSVImportReplace') then
chkReplace.Checked := reg.ReadBool('CSVImportReplace');
if reg.ValueExists('CSVImportIgnore') then
chkIgnore.Checked := reg.ReadBool('CSVImportIgnore');
end;
end; end;
@ -174,49 +186,32 @@ begin
end; end;
procedure Tloaddataform.chkFieldsTerminatedClick(Sender: TObject);
begin
editFieldTerminator.Enabled := (sender as TCheckBox).checked;
end;
procedure Tloaddataform.chkFieldsEnclosedClick(Sender: TObject);
begin
editFieldEncloser.Enabled := (sender as TCheckBox).checked;
chkFieldsEnclosedOptionally.Enabled := (sender as TCheckBox).checked;
end;
procedure Tloaddataform.chkFieldsEscapedClick(Sender: TObject);
begin
editFieldEscaper.Enabled := (sender as TCheckBox).checked;
end;
procedure Tloaddataform.chkLinesTerminatedClick(Sender: TObject);
begin
editLineTerminator.Enabled := (sender as TCheckBox).checked;
end;
procedure Tloaddataform.chkLinesIgnoreClick(Sender: TObject);
begin
updownIgnoreLines.Enabled := (sender as TCheckBox).checked;
editIgnoreLines.Enabled := (sender as TCheckBox).checked;
lblIgnoreLines.Enabled := (sender as TCheckBox).checked;
end;
procedure Tloaddataform.btnImportClick(Sender: TObject); procedure Tloaddataform.btnImportClick(Sender: TObject);
var var
query : string; query : string;
col : TStringList; col : TStringList;
i : Integer; i : Integer;
reg : TRegistry;
begin begin
with TRegistry.Create do // Save settings
if OpenKey(REGPATH, true) then reg := TRegistry.Create;
WriteString('loadfilename', editFilename.Text); if reg.OpenKey(REGPATH, true) then
begin
// filename
reg.WriteString( 'loadfilename', editFilename.Text );
// Use options from CSV export
reg.WriteString( 'CSVSeparator', editFieldTerminator.Text );
reg.WriteString( 'CSVEncloser', editFieldEncloser.Text );
reg.WriteString( 'CSVTerminator', editLineTerminator.Text );
// Other options
reg.WriteBool( 'CSVImportFieldsEnclosedOptionally', chkFieldsEnclosedOptionally.Checked );
reg.WriteString( 'CSVImportFieldEscaper', editFieldEscaper.Text );
reg.WriteInteger( 'CSVImportIgnoreLines', updownIgnoreLines.Position );
reg.WriteBool( 'CSVImportLowPriority', chkLowPriority.Checked );
reg.WriteBool( 'CSVImportReplace', chkReplace.Checked );
reg.WriteBool( 'CSVImportIgnore', chkIgnore.Checked );
end;
query := 'LOAD DATA '; query := 'LOAD DATA ';
@ -228,33 +223,33 @@ begin
query := query + 'REPLACE ' query := query + 'REPLACE '
else if chkIgnore.Checked then else if chkIgnore.Checked then
query := query + 'IGNORE '; query := query + 'IGNORE ';
query := query + 'INTO TABLE ' + comboDatabase.Text + '.' + comboTable.Text + ' '; query := query + 'INTO TABLE ' + Mainform.Mask(comboDatabase.Text) + '.' + Mainform.Mask(comboTable.Text) + ' ';
// Fields: // Fields:
if chkFieldsTerminated.Checked or chkFieldsEnclosed.Checked or chkFieldsEscaped.Checked then if (editFieldTerminator.Text <> '') or (editFieldEncloser.Text <> '') or (editFieldEscaper.Text <> '') then
query := query + 'FIELDS '; query := query + 'FIELDS ';
if chkFieldsTerminated.Checked then if editFieldTerminator.Text <> '' then
query := query + 'TERMINATED BY ''' + editFieldTerminator.Text + ''' '; query := query + 'TERMINATED BY ' + esc(editFieldTerminator.Text) + ' ';
if chkFieldsEnclosed.Checked then if editFieldEncloser.Text <> '' then
begin begin
if chkFieldsEnclosedOptionally.Checked then if chkFieldsEnclosedOptionally.Checked then
query := query + 'OPTIONALLY '; query := query + 'OPTIONALLY ';
query := query + 'ENCLOSED BY ''' + editFieldEncloser.Text + ''' '; query := query + 'ENCLOSED BY ' + esc(editFieldEncloser.Text) + ' ';
end; end;
if chkFieldsEscaped.Checked then if editFieldEscaper.Text <> '' then
query := query + 'ESCAPED BY ''' + editFieldEscaper.Text + ''' '; query := query + 'ESCAPED BY ' + esc(editFieldEscaper.Text) + ' ';
// Lines: // Lines:
if chkLinesTerminated.Checked then if editLineTerminator.Text <> '' then
query := query + 'LINES TERMINATED BY ''' + editLineTerminator.Text + ''' '; query := query + 'LINES TERMINATED BY ''' + editLineTerminator.Text + ''' ';
if chkLinesIgnore.Checked then if updownIgnoreLines.Position > 0 then
query := query + 'IGNORE ' + inttostr(updownIgnoreLines.Position) + ' LINES '; query := query + 'IGNORE ' + inttostr(updownIgnoreLines.Position) + ' LINES ';
col := TStringList.Create; col := TStringList.Create;
for i:=0 to chklistColumns.Items.Count - 1 do for i:=0 to chklistColumns.Items.Count - 1 do
begin begin
if chklistColumns.checked[i] then if chklistColumns.checked[i] then
col.Add(chklistColumns.Items[i]); col.Add(Mainform.Mask( chklistColumns.Items[i] ));
end; end;
// if col.Count < ColumnsCheckListBox.Items.Count then // if col.Count < ColumnsCheckListBox.Items.Count then