Fix bug #693 Import CSV file: LOAD DATA statement breaks data if the CSV file has a different charset than the current DB. Implements the discussed pulldown on the first page of the dialog, below the file input. Defaults to UTF-8 selection.

This commit is contained in:
Ansgar Becker
2008-09-02 23:11:05 +00:00
parent 48aca3d928
commit cc901ae8d3
2 changed files with 88 additions and 20 deletions

View File

@ -60,18 +60,18 @@ object loaddataform: Tloaddataform
415
282)
object grpFilename: TGroupBox
Left = 10
Top = 10
Width = 394
Height = 63
Left = 5
Top = 2
Width = 403
Height = 90
Anchors = [akLeft, akTop, akRight]
Caption = 'Filename'
Caption = 'File'
TabOrder = 0
DesignSize = (
394
63)
403
90)
object btnOpenFile: TPngSpeedButton
Left = 353
Left = 362
Top = 24
Width = 22
Height = 22
@ -79,10 +79,26 @@ object loaddataform: Tloaddataform
Flat = True
OnClick = btnOpenFileClick
end
object lblFilename: TLabel
Left = 10
Top = 27
Width = 46
Height = 13
Caption = 'Filename:'
FocusControl = editFilename
end
object lblCharset: TLabel
Left = 10
Top = 54
Width = 70
Height = 13
Caption = '&Character set:'
FocusControl = comboCharset
end
object editFilename: TEdit
Left = 16
Left = 104
Top = 24
Width = 331
Width = 252
Height = 21
Anchors = [akLeft, akTop, akRight]
TabOrder = 0
@ -90,11 +106,20 @@ object loaddataform: Tloaddataform
OnChange = editFilenameChange
OnDblClick = btnOpenFileClick
end
object comboCharset: TComboBox
Left = 104
Top = 51
Width = 252
Height = 21
Style = csDropDownList
ItemHeight = 13
TabOrder = 1
end
end
object grpFields: TGroupBox
Left = 10
Top = 78
Width = 394
Left = 5
Top = 93
Width = 403
Height = 109
Anchors = [akLeft, akTop, akRight]
Caption = 'Fields'
@ -153,9 +178,9 @@ object loaddataform: Tloaddataform
end
end
object grpLines: TGroupBox
Left = 10
Top = 193
Width = 394
Left = 5
Top = 202
Width = 403
Height = 74
Anchors = [akLeft, akTop, akRight]
Caption = 'Lines'

View File

@ -11,7 +11,7 @@ interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, comctrls, Buttons, CheckLst, Registry, PngSpeedButton,
WideStrings, TntCheckLst, TntStdCtrls;
WideStrings, TntCheckLst, TntStdCtrls, db, SynRegExpr;
type
Tloaddataform = class(TForm)
@ -52,6 +52,9 @@ type
editLineTerminator: TEdit;
lblLineTerminator: TLabel;
lblIgnoreLines: TLabel;
lblFilename: TLabel;
comboCharset: TComboBox;
lblCharset: TLabel;
procedure FormCreate(Sender: TObject);
procedure editFilenameChange(Sender: TObject);
procedure FormShow(Sender: TObject);
@ -65,6 +68,7 @@ type
procedure btnColDownClick(Sender: TObject);
private
{ Private declarations }
dsCharsets: TDataset;
public
{ Public declarations }
end;
@ -73,7 +77,7 @@ type
implementation
uses Main, Childwin, helpers, Db;
uses Main, Childwin, helpers;
{$R *.DFM}
@ -133,9 +137,11 @@ end;
procedure Tloaddataform.comboDatabaseChange(Sender: TObject);
var
count: Integer;
count, i, selCharsetIndex: Integer;
ds: TDataset;
seldb, seltable: String;
seldb, seltable, dbcreate: WideString;
rx: TRegExpr;
DefCharset: String;
begin
// read tables from db
comboTable.Items.Clear;
@ -153,6 +159,38 @@ begin
comboTable.ItemIndex := 0;
comboTableChange(self);
selCharsetIndex := comboCharset.ItemIndex;
comboCharset.Enabled := False;
comboCharset.Clear;
try
if dsCharsets = nil then
dsCharsets := Mainform.Childwin.GetResults('SHOW CHARSET');
comboCharset.Enabled := True;
// Detect db charset
DefCharset := 'Let server/database decide';
dbcreate := Mainform.Childwin.GetVar('SHOW CREATE DATABASE '+Mainform.mask(comboDatabase.Text), 1);
rx := TRegExpr.Create;
rx.ModifierG := True;
rx.Expression := 'CHARACTER SET (\w+)';
if rx.Exec(dbcreate) then
DefCharset := DefCharset + ' ('+rx.Match[1]+')';
comboCharset.Items.Add(DefCharset);
dsCharsets.First;
for i:=1 to dsCharsets.RecordCount do begin
comboCharset.Items.Add(dsCharsets.Fields[1].AsWideString + ' ('+dsCharsets.Fields[0].AsWideString+')');
if dsCharsets.Fields[0].AsWideString = 'utf8' then begin
comboCharset.Items[i] := comboCharset.Items[i] + ' - '+APPNAME+' output';
if selCharsetIndex = -1 then
selCharsetIndex := i;
end;
dsCharsets.Next;
end;
comboCharset.ItemIndex := selCharsetIndex;
except
// Ignore it when the above statements don't work on pre 4.1 servers.
// In that case, the combobox is disabled and we load the file without specifying charset.
end;
end;
@ -230,6 +268,11 @@ begin
query := query + 'IGNORE ';
query := query + 'INTO TABLE ' + Mainform.Mask(comboDatabase.Text) + '.' + Mainform.Mask(comboTable.Text) + ' ';
if comboCharset.ItemIndex > 0 then begin
dsCharsets.RecNo := comboCharset.ItemIndex;
query := query + 'CHARACTER SET '+dsCharsets.Fields[0].AsString+' ';
end;
// Fields:
if (editFieldTerminator.Text <> '') or (editFieldEncloser.Text <> '') or (editFieldEscaper.Text <> '') then
query := query + 'FIELDS ';