unit copytable; // ------------------------------------- // Copy table // ------------------------------------- interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons, CheckLst, ZDataSet, ComCtrls; type TCopyTableForm = class(TForm) editNewTablename: TEdit; lblNewTablename: TLabel; radioStructure: TRadioButton; radioStructureAndData: TRadioButton; CheckListBoxFields: TCheckListBox; CheckBoxWithAllFields: TCheckBox; ButtonCancel: TButton; CheckBoxWithIndexes: TCheckBox; lblTargetDB: TLabel; ComboSelectDatabase: TComboBox; ButtonOK: TButton; procedure radioStructureClick(Sender: TObject); procedure radioStructureAndDataClick(Sender: TObject); procedure CheckBoxWithAllFieldsClick(Sender: TObject); procedure editNewTablenameChange(Sender: TObject); procedure FormShow(Sender: TObject); procedure ButtonOKClick(Sender: TObject); procedure ButtonCancelClick(Sender: TObject); private { Private declarations } oldTableName : String; public { Public declarations } end; function CopyTableWindow(AOwner: TComponent): Boolean; const OPTION_UNDEFINED = 255; OPTION_STRUCTURE = 0; OPTION_STRUCTURE_AND_DATA = 1; OPTION_REGNAME_STRUC_DATA = 'CopyTable_Option_StructureData'; OPTION_REGNAME_WITH_INDEXES = 'CopyTable_Option_WithIndexes'; OPTION_REGNAME_WITH_ALL_FIELDS = 'CopyTable_Option_WithAllFields'; implementation uses helpers, main, childwin, db; {$R *.DFM} {** Create form on demand @param TComponent Owner of form (should be calling form) @return Boolean Form closed using modalresult mrOK } function CopyTableWindow(AOwner: TComponent): Boolean; var f : TCopyTableForm; begin f := TCopyTableForm.Create(AOwner); Result := (f.ShowModal=mrOK); FreeAndNil(f); end; procedure TCopyTableForm.radioStructureClick(Sender: TObject); begin radioStructureAndData.Checked := not radioStructure.Checked; end; procedure TCopyTableForm.radioStructureAndDataClick(Sender: TObject); begin radioStructure.Checked := not radioStructureAndData.Checked; end; procedure TCopyTableForm.CheckBoxWithAllFieldsClick(Sender: TObject); begin CheckListBoxFields.Enabled := not CheckBoxWithAllFields.Checked; end; procedure TCopyTableForm.editNewTablenameChange(Sender: TObject); begin // validate tablename ButtonOK.Enabled := (editNewTablename.text <> ''); end; procedure TCopyTableForm.FormShow(Sender: TObject); var i : Integer; tn : TTreeNode; struc_data : Byte; ds: TDataSet; NodeData: PVTreeData; begin NodeData := Mainform.ChildWin.ListTables.GetNodeData(Mainform.ChildWin.ListTables.FocusedNode); oldTableName := NodeData.Captions[0]; editNewTablename.Text := oldTableName + '_copy'; editNewTablename.SetFocus; lblNewTablename.Caption := 'Copy ''' + oldTableName + ''' to new Table:'; // Select TargetDatabase ComboSelectDatabase.Items.Clear; for i:=0 to Mainform.ChildWin.DBTree.Items.Count-1 do begin tn := Mainform.ChildWin.DBTree.Items[i]; if tn.Level = 1 then comboSelectDatabase.Items.Add(tn.Text); end; for i:=0 to comboSelectDatabase.Items.Count-1 do begin if (comboSelectDatabase.Items[i] = Mainform.ChildWin.ActiveDatabase) then begin comboSelectDatabase.ItemIndex := i; break; end; end; if comboSelectDatabase.ItemIndex = -1 then comboSelectDatabase.ItemIndex := 0; // fill columns: CheckListBoxFields.Items.Clear; ds := Mainform.ChildWin.GetResults( 'SHOW FIELDS FROM ' + mainform.mask(oldTableName) ); for i:=1 to ds.RecordCount do begin CheckListBoxFields.Items.Add( ds.Fields[0].AsString ); ds.Next; end; // select all: for i:=0 to CheckListBoxFields.Items.Count-1 do CheckListBoxFields.checked[i] := true; {*** restore last settings @see feature #1647058 } struc_data := mainform.GetRegValue( OPTION_REGNAME_STRUC_DATA, OPTION_STRUCTURE_AND_DATA ); case struc_data of OPTION_STRUCTURE: radioStructure.Checked := true; OPTION_STRUCTURE_AND_DATA: radioStructureAndData.Checked := true; end; CheckBoxWithIndexes.Checked := mainform.GetRegValue( OPTION_REGNAME_WITH_INDEXES, CheckBoxWithIndexes.Checked ); CheckBoxWithAllFields.Checked := mainform.GetRegValue( OPTION_REGNAME_WITH_ALL_FIELDS, CheckBoxWithAllFields.Checked ); end; procedure TCopyTableForm.ButtonOKClick(Sender: TObject); var strquery : String; i,which,k : Integer; keylist : Array of TMyKey; keystr : String; ai_q, notnull, default : String; zq : TDataSet; isFulltext : Boolean; struc_data : Byte; begin // copy table! // store settings struc_data := OPTION_UNDEFINED; if radioStructure.Checked then struc_data := OPTION_STRUCTURE; if radioStructureAndData.Checked then struc_data := OPTION_STRUCTURE_AND_DATA; mainform.SaveRegValue( OPTION_REGNAME_STRUC_DATA, struc_data ); mainform.SaveRegValue( OPTION_REGNAME_WITH_INDEXES, CheckBoxWithIndexes.Checked ); mainform.SaveRegValue( OPTION_REGNAME_WITH_ALL_FIELDS, CheckBoxWithAllFields.Checked ); strquery := 'CREATE TABLE ' + mainform.mask(ComboSelectDatabase.Text) + '.' + mainform.mask(editNewTablename.Text) + ' '; // keys > if CheckBoxWithIndexes.Checked then begin zq := Mainform.ChildWin.GetResults( 'SHOW KEYS FROM ' + mainform.mask(oldtablename) ); setLength(keylist, 0); keystr := ''; for i:=1 to zq.RecordCount do begin which := -1; for k:=0 to length(keylist)-1 do begin if keylist[k].Name = zq.Fields[2].AsString then // keyname exists! which := k; end; if which = -1 then begin setlength(keylist, length(keylist)+1); which := high(keylist); keylist[which].Columns := TStringList.Create; keylist[which].SubParts := TStringList.Create; with keylist[which] do // set properties for new key begin if Mainform.ChildWin.mysql_version < 40002 then isFulltext := (zq.FieldByName('Comment').AsString = 'FULLTEXT') else isFulltext := (zq.FieldByName('Index_type').AsString = 'FULLTEXT'); Name := zq.Fields[2].AsString; if zq.Fields[2].AsString = 'PRIMARY' then _type := 'PRIMARY' else if isFulltext then _type := 'FULLTEXT' else if zq.Fields[1].AsString = '1' then _type := '' else if zq.Fields[1].AsString = '0' then _type := 'UNIQUE'; end; end; // add column keylist[which].Columns.add( zq.FieldByName('Column_Name').AsString ); keylist[which].SubParts.add( zq.FieldByName('Sub_part').AsString ); zq.Next; end; for k:=0 to high(keylist) do begin if k > 0 then keystr := keystr + ','; if keylist[k].Name = 'PRIMARY' then keystr := keystr + ' PRIMARY KEY (' else keystr := keystr + ' ' + keylist[k]._type + ' KEY ' + keylist[k].Name + ' ('; for i := 0 to keylist[k].Columns.count - 1 do begin if i > 0 then keystr := keystr + ', '; keystr := keystr + keylist[k].Columns[i]; if keylist[k].SubParts[i] <> '' then keystr := keystr + '(' + keylist[k].SubParts[i] + ')'; end; keystr := keystr + ')'; end; if keystr<> '' then strquery := strquery + '(' + keystr + ')' end; // < keys strquery := strquery + ' SELECT'; // which fields? if CheckBoxWithAllFields.Checked then strquery := strquery + ' *' else begin for i:=0 to CheckListBoxFields.Items.Count-1 do if CheckListBoxFields.Checked[i] then strquery := strquery + ' ' + mainform.mask(CheckListBoxFields.Items[i]) + ','; delete(strquery, length(strquery), 1); end; strquery := strquery + ' FROM ' + mainform.mask(oldTableName); // what? if radioStructure.Checked then strquery := strquery + ' WHERE 1 = 0'; Mainform.ChildWin.ExecUpdateQuery(strquery); // Find a auto_increment-column zq := Mainform.ChildWin.GetResults('SHOW FIELDS FROM ' + mainform.mask(oldtablename)); for i:=1 to zq.RecordCount do begin if zq.Fields[5].AsString = 'auto_increment' then begin if zq.Fields[2].AsString = '' then notnull := 'NOT NULL' else notnull := ''; if zq.Fields[4].AsString <> '' then default := 'DEFAULT "'+zq.Fields[4].AsString+'"' else default := ''; ai_q := 'ALTER TABLE ' + mainform.mask(ComboSelectDatabase.Text) + '.'+mainform.mask(editNewTablename.Text)+' CHANGE '+mainform.mask(zq.Fields[0].AsString)+' '+mainform.mask(zq.Fields[0].AsString)+' '+zq.Fields[1].AsString+' '+default+' '+notnull+' AUTO_INCREMENT'; Mainform.ChildWin.ExecUpdateQuery(ai_q); end; zq.Next; end; Mainform.Childwin.MenuRefreshClick(Self); close; end; procedure TCopyTableForm.ButtonCancelClick(Sender: TObject); begin close; end; end.