From c843b196b5692472e933013b6ee3f480216dbd23 Mon Sep 17 00:00:00 2001 From: Ansgar Becker Date: Thu, 12 Feb 2026 18:06:59 +0100 Subject: [PATCH] feat: create SQL export option for wrapping DML commands in a BEGIN/COMMIT transaction This also * removes the MyISAM-only ALTER TABLE .. DISABLE/ENABLE KEYS command, which in mid size tables costs more than it helps. * shows the number of checked export options on the button caption * saves settings when the user just closes the dialog, without having exported Closes #1262 --- source/apphelpers.pas | 3 ++- source/tabletools.dfm | 8 ++++++++ source/tabletools.pas | 35 ++++++++++++++++++++++++++--------- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/source/apphelpers.pas b/source/apphelpers.pas index c7a4d61f..312a00cf 100644 --- a/source/apphelpers.pas +++ b/source/apphelpers.pas @@ -193,7 +193,7 @@ type asSSLCert, asSSLCA, asSSLCipher, asSSLVerification, asSSLWarnUnused, asNetType, asCompressed, asLocalTimeZone, asQueryTimeout, asKeepAlive, asStartupScriptFilename, asDatabases, asComment, asDatabaseFilter, asTableFilter, asFilterVT, asExportSQLCreateDatabases, asExportSQLCreateTables, asExportSQLDataHow, asExportSQLDataInsertSize, asExportSQLFilenames, asExportZIPFilenames, asExportSQLDirectories, - asExportSQLDatabase, asExportSQLServerDatabase, asExportSQLOutput, asExportSQLAddComments, asExportSQLRemoveAutoIncrement, asExportSQLRemoveDefiner, + asExportSQLDatabase, asExportSQLServerDatabase, asExportSQLOutput, asExportSQLAddComments, asExportSQLTransactions, asExportSQLRemoveAutoIncrement, asExportSQLRemoveDefiner, asGridExportWindowWidth, asGridExportWindowHeight, asGridExportOutputCopy, asGridExportOutputFile, asGridExportFilename, asGridExportRecentFiles, asGridExportEncoding, asGridExportFormat, asGridExportSelection, asGridExportColumnNames, asGridExportIncludeAutoInc, asGridExportIncludeQuery, asGridExportRemoveLinebreaks, asGridExportOpenFile, @@ -3953,6 +3953,7 @@ begin InitSetting(asExportSQLServerDatabase, 'ExportSQL_ServerDatabase', 0, False, ''); InitSetting(asExportSQLOutput, 'ExportSQL_Output', 0); InitSetting(asExportSQLAddComments, 'ExportSQLAddComments', 0, True); + InitSetting(asExportSQLTransactions, 'ExportSQLTransactions', 0, False); InitSetting(asExportSQLRemoveAutoIncrement, 'ExportSQLRemoveAutoIncrement', 0, False); InitSetting(asExportSQLRemoveDefiner, 'ExportSQLRemoveDefiner', 0, True); InitSetting(asGridExportWindowWidth, 'GridExportWindowWidth', 400); diff --git a/source/tabletools.dfm b/source/tabletools.dfm index 8f249cc3..fbace92e 100644 --- a/source/tabletools.dfm +++ b/source/tabletools.dfm @@ -814,14 +814,22 @@ object frmTableTools: TfrmTableTools object menuExportAddComments: TMenuItem AutoCheck = True Caption = 'Add comments' + OnClick = menuExportOptionClick + end + object menuExportTransactions: TMenuItem + AutoCheck = True + Caption = 'Wrap data DML in transactions' + OnClick = menuExportOptionClick end object menuExportRemoveAutoIncrement: TMenuItem AutoCheck = True Caption = 'Remove AUTO_INCREMENT clauses' + OnClick = menuExportOptionClick end object menuExportRemoveDefiner: TMenuItem AutoCheck = True Caption = 'Remove DEFINER clauses' + OnClick = menuExportOptionClick end object menuCopyMysqldumpCommand: TMenuItem Caption = 'Copy mysqldump command' diff --git a/source/tabletools.pas b/source/tabletools.pas index a750d695..2a841a4c 100644 --- a/source/tabletools.pas +++ b/source/tabletools.pas @@ -103,6 +103,7 @@ type editGenerateDataNullAmount: TEdit; updownGenerateDataNullAmount: TUpDown; menuInvertCheck: TMenuItem; + menuExportTransactions: TMenuItem; procedure FormCreate(Sender: TObject); procedure FormShow(Sender: TObject); procedure btnHelpMaintenanceClick(Sender: TObject); @@ -128,7 +129,7 @@ type procedure ResultGridPaintText(Sender: TBaseVirtualTree; const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType); procedure ValidateControls(Sender: TObject); - procedure SaveSettings(Sender: TObject); + procedure SaveSettings; procedure chkExportOptionClick(Sender: TObject); procedure btnExportOutputTargetSelectClick(Sender: TObject); procedure comboExportOutputTargetChange(Sender: TObject); @@ -159,6 +160,7 @@ type Index: Integer; Rect: TRect; State: TOwnerDrawState); procedure comboExportOutputTypeMeasureItem(Control: TWinControl; Index: Integer; var Height: Integer); + procedure menuExportOptionClick(Sender: TObject); const StatusMsg = '%s %s ...'; private @@ -295,6 +297,7 @@ begin comboExportData.ItemIndex := AppSettings.ReadInt(asExportSQLDataHow); updownInsertSize.Position := AppSettings.ReadInt(asExportSQLDataInsertSize); menuExportAddComments.Checked := AppSettings.ReadBool(asExportSQLAddComments); + menuExportTransactions.Checked := AppSettings.ReadBool(asExportSQLTransactions); menuExportRemoveAutoIncrement.Checked := AppSettings.ReadBool(asExportSQLRemoveAutoIncrement); menuExportRemoveDefiner.Checked := AppSettings.ReadBool(asExportSQLRemoveDefiner); // Add hardcoded output options and session names from registry @@ -539,11 +542,26 @@ begin end; +procedure TfrmTableTools.menuExportOptionClick(Sender: TObject); +var + i: Integer; + MenuItem: TMenuItem; +begin + // Display number of checked options in button caption + i := 0; + for MenuItem in popupExportOptions.Items do begin + if MenuItem.Checked then + Inc(i); + end; + btnExportOptions.Caption := _('Options') + ' (' + i.ToString + ')'; +end; + procedure TfrmTableTools.FormClose(Sender: TObject; var Action: TCloseAction); begin // Auto close temorary connection if Assigned(FTargetConnection) then FreeAndNil(FTargetConnection); + SaveSettings; // Save GUI setup AppSettings.WriteIntDpiAware(asTableToolsWindowWidth, Self, Width); AppSettings.WriteIntDpiAware(asTableToolsWindowHeight, Self, Height); @@ -551,7 +569,7 @@ begin end; -procedure TfrmTableTools.SaveSettings(Sender: TObject); +procedure TfrmTableTools.SaveSettings; var i: Integer; Items: TStringList; @@ -573,6 +591,7 @@ begin if comboExportData.ItemIndex > 0 then AppSettings.WriteInt(asExportSQLDataInsertSize, updownInsertSize.Position); AppSettings.WriteBool(asExportSQLAddComments, menuExportAddComments.Checked); + AppSettings.WriteBool(asExportSQLTransactions, menuExportTransactions.Checked); AppSettings.WriteBool(asExportSQLRemoveAutoIncrement, menuExportRemoveAutoIncrement.Checked); AppSettings.WriteBool(asExportSQLRemoveDefiner, menuExportRemoveDefiner.Checked); @@ -629,6 +648,7 @@ begin TExtForm.PageControlTabHighlight(tabsTools); btnSeeResults.Visible := tabsTools.ActivePage = tabFind; lblCheckedSize.Caption := f_('Selected objects size: %s', [FormatByteNumber(FObjectSizes)]); + menuExportOptionClick(Sender); if tabsTools.ActivePage = tabMaintenance then begin btnExecute.Caption := _('Execute'); btnExecute.Enabled := (Pos(_(SUnsupported), comboOperation.Text) = 0) and SomeChecked; @@ -1025,7 +1045,6 @@ begin tabsTools.Enabled := True; treeObjects.Enabled := True; ValidateControls(Sender); - SaveSettings(Sender); Screen.Cursor := crDefault; end; @@ -2042,6 +2061,8 @@ begin tmp := '~'+tmp+' ('+_('approximately')+')'; if menuExportAddComments.Checked then Output('-- '+f_('Dumping data for table %s.%s: %s', [DBObj.Database, DBObj.Name, tmp])+CRLF, False, True, True, False, False); + if menuExportTransactions.Checked then + Output('BEGIN', True, True, True, True, True); TargetDbAndObject := Quoter.QuoteIdent(DBObj.Name); if ToDb then TargetDbAndObject := Quoter.QuoteIdent(FinalDbName) + '.' + TargetDbAndObject; @@ -2064,9 +2085,6 @@ begin Limit := Round(100 * SIZE_MB / IfThen(DBObj.AvgRowLen>0, DBObj.AvgRowLen, AssumedAvgRowLen)); if comboExportData.Text = DATA_REPLACE then Output('DELETE FROM '+TargetDbAndObject, True, True, True, True, True); - if DBObj.Engine.ToLowerInvariant <> 'innodb' then begin - Output('/*!40000 ALTER TABLE '+TargetDbAndObject+' DISABLE KEYS */', True, True, True, True, True); - end; while true do begin Data := DBObj.Connection.GetResults( DBObj.Connection.ApplyLimitClause( @@ -2144,9 +2162,8 @@ begin break; end; - if DBObj.Engine.ToLowerInvariant <> 'innodb' then begin - Output('/*!40000 ALTER TABLE '+TargetDbAndObject+' ENABLE KEYS */', True, True, True, True, True); - end; + if menuExportTransactions.Checked then + Output('COMMIT', True, True, True, True, True); Output(CRLF, False, True, True, True, True); // Cosmetic fix for estimated InnoDB row count DBObj.Rows := RowCount;