diff --git a/docs/scripts_md/delete_imaging_upload.md b/docs/scripts_md/delete_imaging_upload.md index 66700b52f..f26207892 100644 --- a/docs/scripts_md/delete_imaging_upload.md +++ b/docs/scripts_md/delete_imaging_upload.md @@ -6,7 +6,7 @@ delete\_imaging\_upload.pl -- Delete everything that was produced (or part of wh # SYNOPSIS perl delete\_imaging\_upload.pl \[-profile file\] \[-ignore\] \[-backup\_path basename\] \[-protocol\] \[-form\] \[-uploadID list\_of\_uploadIDs\] - \[-type list\_of\_scan\_types\] \[-defaced\] \[-basename fileBaseName\] \[-nosqlbk\] \[-nofilesbk\] + \[-type list\_of\_scan\_types\] \[-defaced\] \[-basename fileBaseName\] \[-nosqlbk\] \[-nofilesbk\] \[-extra\_mysqlcnf file\] Available options are: @@ -61,10 +61,19 @@ Available options are: `imaging_upload_restore.sql`, to the backup file is the default behaviour. \-dumpOptions : options to add to the mysqldump command. By default, the following options are used - `--no-create-info --compact --single-transaction --skip-extended-insert --no-tablespaces`. + `--no-create-info --compact --skip-extended-insert --no-tablespaces`. Example of additional option: `--column-statistics=0` to disable column statistics flag in mysqldump 8. +\-extra\_mysqlcnf <file> : MySql config file containing the password to log in the database (see + `https://dev.mysql.com/doc/refman/8.0/en/option-files.html` for a description of this file's format). + This file should only contain the password stored in the `@db` array defined in your `prod` file. + You should use that option if you do not have a default `.mysql.cnf` config file containing the credentials + to log in the database. If this option is used, `delete_imaging_upload.pl` will pass the option + `--defaults-extra-file=file` to the `mysqldump` command when creating a backup of the SQL tables. Note that + only the password is fetched in this file, the host name and user name used to access the database are actually + retrieved from the `prod` file. + # DESCRIPTION This program deletes an imaging upload or specific parts of it from the database and the file system. There are four @@ -110,9 +119,13 @@ one must use `tar` with option `--absolute-names`. The script will also create a file that contains a backup of all the information that was deleted or modified from the database tables. This backup is created using `mysqldump` and contains an `INSERT` statement for every record erased. -It will be part of the backup archive mentioned above unless option `-nosqlbk` is used. If sourced back into the database -with `mysql`, it should allow the database to be exactly like it was before `delete_imaging_upload.pl` was invoked, -provided the database was not modified in the meantime. The SQL backup file will be named `imaging_upload_restore.sql`. +When running `mysqldump` the script uses the database credentials in file `~/.my.cnf` to connect to the database. Option +`-extra_mysqlcnf` has to be used to specify an alternate credentials file when the default credential file does not exist +(see `https://dev.mysql.com/doc/refman/8.0/en/option-files.html` for a descrption of MySQL option files format). +The backup produced by `mysqldump` will be part of the backup archive mentioned above unless option `-nosqlbk` is used. +If sourced back into the database with `mysql`, it should allow the database to be exactly like it was before +`delete_imaging_upload.pl` was invoked, provided the database was not modified in the meantime. The SQL backup file will +be named `imaging_upload_restore.sql`. 2\. Delete specific scan types from an archive. The behaviour of the script is identical to the one described above, except that: @@ -491,7 +504,7 @@ INPUTS: that are associated to the upload(s) passed on the command line. - $tmpSQLFile: path of the SQL file that contains the SQL statements used to restore the deleted records. -### deleteMriParameterForm($dbh, $mriUploadsRef, $tmpSQLFile, $dump\_opt) +### deleteMriParameterForm($dbh, $mriUploadsRef, $tmpSQLFile, $optionsRef) Delete the entries in `mri_parameter_form` (and associated `flag` entry) for the upload(s) passed on the command line. The script also adds an SQL statement in the SQL file whose path is passed as argument to @@ -504,7 +517,7 @@ INPUTS: in the array. The properties stored for each hash are: `UploadID`, `TarchiveID`, `FullPath` `Inserting`, `InsertionComplete` and `SessionID`. - $tmpSQLFile: path of the SQL file that contains the SQL statements used to restore the deleted records. - - $dump\_opt: additional options to use for mysqldump + - $optionsRef: reference to the array that contains the options passed on the command line. RETURNS: - The numbers of records deleted as a result of this operation. @@ -549,7 +562,7 @@ INPUTS: RETURNS: - A reference on an array containing the `TarchiveSeriesID` to delete. -### deleteTableData($dbh, $table, $key, $keyValuesRef, $tmpSQLBackupFile, $dump\_opt) +### deleteTableData($dbh, $table, $key, $keyValuesRef, $tmpSQLBackupFile, $optionsRef) Deletes records from a database table and adds in a file the SQL statements that allow rewriting the records back in the table. @@ -560,12 +573,12 @@ INPUTS: - $key: name of the key used to delete the records. - $keyValuesRef: reference on the list of values that field `$key` has for the records to delete. - $tmpSQLBackupFile: path of the SQL file that contains the SQL statements used to restore the deleted records. - - $dump\_opt: additional options to use for mysqldump + - $optionsRef: reference to the array that contains the options passed on the command line. RETURNS: - The number of records deleted. -### updateSQLBackupFile($tmpSQLBackupFile, $table, $key, $keyValuesRef, $dump\_opt) +### updateSQLBackupFile($tmpSQLBackupFile, $table, $key, $keyValuesRef, $optionsRef) Updates the SQL file with the statements to restore the records whose properties are passed as argument. The block of statements is written at the beginning of the file. @@ -575,7 +588,7 @@ INPUTS: - $table: name of the database table. - $key: name of the key used to delete the records. - $keyValuesRef: reference on the list of values that field `$key` has for the records to delete. - - $dump\_opt: additional options to use for mysqldump + - $optionsRef: reference to the array that contains the options passed on the command line. ### getInvalidDefacedFiles($dbh, $filesRef, $scanTypesToDeleteRef) diff --git a/tools/delete_imaging_upload.pl b/tools/delete_imaging_upload.pl index 1dee3487b..a3c6aa936 100755 --- a/tools/delete_imaging_upload.pl +++ b/tools/delete_imaging_upload.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/perl -w =pod @@ -10,7 +10,7 @@ =head1 NAME =head1 SYNOPSIS perl delete_imaging_upload.pl [-profile file] [-ignore] [-backup_path basename] [-protocol] [-form] [-uploadID list_of_uploadIDs] - [-type list_of_scan_types] [-defaced] [-basename fileBaseName] [-nosqlbk] [-nofilesbk] + [-type list_of_scan_types] [-defaced] [-basename fileBaseName] [-nosqlbk] [-nofilesbk] [-extra_mysqlcnf file] Available options are: @@ -65,10 +65,19 @@ =head1 SYNOPSIS C, to the backup file is the default behaviour. -dumpOptions : options to add to the mysqldump command. By default, the following options are used - C<--no-create-info --compact --single-transaction --skip-extended-insert --no-tablespaces>. + C<--no-create-info --compact --skip-extended-insert --no-tablespaces>. Example of additional option: C<--column-statistics=0> to disable column statistics flag in mysqldump 8. +-extra_mysqlcnf : MySql config file containing the password to log in the database (see + C for a description of this file's format). + This file should only contain the password stored in the C<@db> array defined in your C file. + You should use that option if you do not have a default C<.mysql.cnf> config file containing the credentials + to log in the database. If this option is used, C will pass the option + C<--defaults-extra-file=file> to the C command when creating a backup of the SQL tables. Note that + only the password is fetched in this file, the host name and user name used to access the database are actually + retrieved from the C file. + =head1 DESCRIPTION This program deletes an imaging upload or specific parts of it from the database and the file system. There are four @@ -114,9 +123,13 @@ =head1 DESCRIPTION The script will also create a file that contains a backup of all the information that was deleted or modified from the database tables. This backup is created using C and contains an C statement for every record erased. -It will be part of the backup archive mentioned above unless option C<-nosqlbk> is used. If sourced back into the database -with C, it should allow the database to be exactly like it was before C was invoked, -provided the database was not modified in the meantime. The SQL backup file will be named C. +When running C the script uses the database credentials in file C<~/.my.cnf> to connect to the database. Option +C<-extra_mysqlcnf> has to be used to specify an alternate credentials file when the default credential file does not exist +(see C for a descrption of MySQL option files format). +The backup produced by C will be part of the backup archive mentioned above unless option C<-nosqlbk> is used. +If sourced back into the database with C, it should allow the database to be exactly like it was before +C was invoked, provided the database was not modified in the meantime. The SQL backup file will +be named C. 2. Delete specific scan types from an archive. The behaviour of the script is identical to the one described above, except that: @@ -167,7 +180,10 @@ =head2 Methods use NeuroDB::objectBroker::ObjectBrokerException; use NeuroDB::objectBroker::ConfigOB; +# Default credentials file used when running mysqldump +use constant DEFAULT_MYSQLDUMP_CNF_FILE => '~/.my.cnf'; +# Default values for various options use constant DEFAULT_PROFILE => 'prod'; use constant DEFAULT_DIE_ON_FILE_ERROR => 1; use constant DEFAULT_NO_FILES_BK => 0; @@ -215,7 +231,8 @@ =head2 Methods BACKUP_PATH => '', UPLOAD_ID => '', BASENAME => '', - DUMP_ADDITIONAL_OPTIONS => '' + DUMP_ADDITIONAL_OPTIONS => '', + EXTRA_MYSQLCNF => '' ); my $scanTypeList = undef; @@ -248,8 +265,11 @@ =head2 Methods 'Delete a file with a specific basename.'], ['-dumpOptions', 'string' , 1, \$options{'DUMP_ADDITIONAL_OPTIONS'}, 'Additional options to use with the mysqldump command. By default, the following options are used when running' - . 'mysqldump: --no-create-info --compact --single-transaction --skip-extended-insert --no-tablespaces.' - . 'Example of additional option: \'--column-statistics=0\' to disable column statistics flag in mysqldump 8.'] + . 'mysqldump: --no-create-info --compact --skip-extended-insert --no-tablespaces.' + . 'Example of additional option: \'--column-statistics=0\' to disable column statistics flag in mysqldump 8.'], + ['-extra_mysqlcnf', 'string' , 1, \$options{'EXTRA_MYSQLCNF'}, + '(OPTIONAL) Path of the extra MySQL configuration file to use'], + ); my $Help = <{$t} }) { - $f->{'Exists'} = undef, next if !$f->{'FullPath'}; + $f->{'Exists'} = undef, next if !$f->{'FullPath'}; - $f->{'Exists'} = -e $f->{'FullPath'}; + # The -f test is to ensure $f->{'FullPath'} is an actual file + # and not a directory. If $f->{'FullPath'} is a directory, it + # means that it has an incorrect/invalid value and should not be backed up + # later on. + $f->{'Exists'} = -f $f->{'FullPath'} && -e $f->{'FullPath'}; # A file is only considered "missing" if it is expected to be on the file # system but is not. There are some file paths refered to in the database that @@ -1708,7 +1741,6 @@ sub deleteUploadsInDatabase { # This starts a DB transaction. All operations are delayed until # commit is called $dbh->begin_work; - my $dump_opt = $options{DUMP_ADDITIONAL_OPTIONS}; my(undef, $tmpSQLFile) = $optionsRef->{'NO_SQL_BK'} ? (undef, undef) : tempfile('sql_backup_XXXX', UNLINK => 1); @@ -1717,52 +1749,52 @@ sub deleteUploadsInDatabase { my $nbRecordsDeleted = 0; if(!@$scanTypesToDeleteRef && $optionsRef->{'BASENAME'} eq '') { - $nbRecordsDeleted += &deleteTableData($dbh, 'notification_spool', 'ProcessID', \@IDs, $tmpSQLFile, $dump_opt); + $nbRecordsDeleted += &deleteTableData($dbh, 'notification_spool', 'ProcessID', \@IDs, $tmpSQLFile, $optionsRef); } # If only specific scan types are targeted for deletion, do not delete the entries in # tarchive_files and tarchive_series as these are tied to the archive, not the MINC files if(!@$scanTypesToDeleteRef && $optionsRef->{'BASENAME'} eq '') { my $IDsRef = &getTarchiveSeriesIDs($dbh, $filesRef); - $nbRecordsDeleted += &deleteTableData($dbh, 'tarchive_files', 'TarchiveSeriesID', $IDsRef, $tmpSQLFile, $dump_opt); + $nbRecordsDeleted += &deleteTableData($dbh, 'tarchive_files', 'TarchiveSeriesID', $IDsRef, $tmpSQLFile, $optionsRef); - $nbRecordsDeleted += &deleteTableData($dbh, 'tarchive_series', 'TarchiveSeriesID', $IDsRef, $tmpSQLFile, $dump_opt); + $nbRecordsDeleted += &deleteTableData($dbh, 'tarchive_series', 'TarchiveSeriesID', $IDsRef, $tmpSQLFile, $optionsRef); } @IDs = map { $_->{'ParameterFileID'} } @{ $filesRef->{'parameter_file'} }; - $nbRecordsDeleted += &deleteTableData($dbh, 'parameter_file', 'ParameterFileID', \@IDs, $tmpSQLFile, $dump_opt); + $nbRecordsDeleted += &deleteTableData($dbh, 'parameter_file', 'ParameterFileID', \@IDs, $tmpSQLFile, $optionsRef); @IDs = map { $_->{'IntermedID'} } @{ $filesRef->{'files_intermediary'} }; - $nbRecordsDeleted += &deleteTableData($dbh, 'files_intermediary', 'IntermedID', \@IDs, $tmpSQLFile, $dump_opt); + $nbRecordsDeleted += &deleteTableData($dbh, 'files_intermediary', 'IntermedID', \@IDs, $tmpSQLFile, $optionsRef); # Since all files in files_intermediary are linked to other files in table files, we # have to delete these files first from table files. if(!$optionsRef->{'KEEP_DEFACED'}) { @IDs = map { $_->{'FileID'} } @{ $filesRef->{'files_intermediary'} }; - $nbRecordsDeleted += &deleteTableData($dbh, 'files', 'FileID', \@IDs, $tmpSQLFile, $dump_opt); + $nbRecordsDeleted += &deleteTableData($dbh, 'files', 'FileID', \@IDs, $tmpSQLFile, $optionsRef); } else { &updateFilesIntermediaryTable($dbh, $filesRef, $tmpSQLFile); } @IDs = map { $_->{'BIDSExportedFileID'} } @{ $filesRef->{'bids_export_files'}}; - $nbRecordsDeleted += &deleteTableData($dbh, 'bids_export_files', 'BIDSExportedFileID', \@IDs, $tmpSQLFile, $dump_opt); + $nbRecordsDeleted += &deleteTableData($dbh, 'bids_export_files', 'BIDSExportedFileID', \@IDs, $tmpSQLFile, $optionsRef); @IDs = map { $_->{'FileID'} } @{ $filesRef->{'files'} }; - $nbRecordsDeleted += &deleteTableData($dbh, 'files', 'FileID', \@IDs, $tmpSQLFile, $dump_opt); + $nbRecordsDeleted += &deleteTableData($dbh, 'files', 'FileID', \@IDs, $tmpSQLFile, $optionsRef); @IDs = map { $_->{'ProcessProtocolID'} } @{ $filesRef->{'mri_processing_protocol'} }; - $nbRecordsDeleted += &deleteTableData($dbh, 'mri_processing_protocol', 'ProcessProtocolID', \@IDs, $tmpSQLFile, $dump_opt); + $nbRecordsDeleted += &deleteTableData($dbh, 'mri_processing_protocol', 'ProcessProtocolID', \@IDs, $tmpSQLFile, $optionsRef); @IDs = map { $_->{'ID'} } @{ $filesRef->{'mri_protocol_violated_scans'} }; - $nbRecordsDeleted += &deleteTableData($dbh, 'mri_protocol_violated_scans', 'ID', \@IDs, $tmpSQLFile, $dump_opt); + $nbRecordsDeleted += &deleteTableData($dbh, 'mri_protocol_violated_scans', 'ID', \@IDs, $tmpSQLFile, $optionsRef); @IDs = map { $_->{'LogID'} } @{ $filesRef->{'mri_violations_log'} }; - $nbRecordsDeleted += &deleteTableData($dbh, 'mri_violations_log', 'LogID', \@IDs, $tmpSQLFile, $dump_opt); + $nbRecordsDeleted += &deleteTableData($dbh, 'mri_violations_log', 'LogID', \@IDs, $tmpSQLFile, $optionsRef); @IDs = map { $_->{'ID'} } @{ $filesRef->{'MRICandidateErrors'} }; - $nbRecordsDeleted += &deleteTableData($dbh, 'MRICandidateErrors', 'ID', \@IDs, $tmpSQLFile, $dump_opt); + $nbRecordsDeleted += &deleteTableData($dbh, 'MRICandidateErrors', 'ID', \@IDs, $tmpSQLFile, $optionsRef); - $nbRecordsDeleted += &deleteMriParameterForm($dbh, $filesRef->{'mri_upload'}, $tmpSQLFile, $dump_opt) if $optionsRef->{'DELETE_MRI_PARAMETER_FORM'}; + $nbRecordsDeleted += &deleteMriParameterForm($dbh, $filesRef->{'mri_upload'}, $tmpSQLFile, $optionsRef) if $optionsRef->{'DELETE_MRI_PARAMETER_FORM'}; # Should check instead if the tarchive is not tied to anything # (i.e no associated entries in files, mri_violations_log, etc...) @@ -1772,9 +1804,9 @@ sub deleteUploadsInDatabase { my $tarchiveID = $filesRef->{'mri_upload'}->[0]->{'TarchiveID'}; if(!@$scanTypesToDeleteRef && $optionsRef->{'BASENAME'} eq '') { @IDs = map { $_->{'UploadID'} } @{ $filesRef->{'mri_upload'} }; - $nbRecordsDeleted += &deleteTableData($dbh, 'mri_upload', 'UploadID', \@IDs, $tmpSQLFile, $dump_opt); + $nbRecordsDeleted += &deleteTableData($dbh, 'mri_upload', 'UploadID', \@IDs, $tmpSQLFile, $optionsRef); - $nbRecordsDeleted += &deleteTableData($dbh, 'tarchive', 'TarchiveID', [$tarchiveID], $tmpSQLFile, $dump_opt) if defined $tarchiveID; + $nbRecordsDeleted += &deleteTableData($dbh, 'tarchive', 'TarchiveID', [$tarchiveID], $tmpSQLFile, $optionsRef) if defined $tarchiveID; } &updateSessionTable($dbh, $filesRef->{'mri_upload'}, $tmpSQLFile) unless @$scanTypesToDeleteRef || $optionsRef->{'BASENAME'} ne ''; @@ -1915,7 +1947,7 @@ sub updateFilesIntermediaryTable { =pod -=head3 deleteMriParameterForm($dbh, $mriUploadsRef, $tmpSQLFile, $dump_opt) +=head3 deleteMriParameterForm($dbh, $mriUploadsRef, $tmpSQLFile, $optionsRef) Delete the entries in C (and associated C entry) for the upload(s) passed on the command line. The script also adds an SQL statement in the SQL file whose path is passed as argument to @@ -1928,14 +1960,14 @@ =head3 deleteMriParameterForm($dbh, $mriUploadsRef, $tmpSQLFile, $dump_opt) in the array. The properties stored for each hash are: C, C, C C, C and C. - $tmpSQLFile: path of the SQL file that contains the SQL statements used to restore the deleted records. - - $dump_opt: additional options to use for mysqldump + - $optionsRef: reference to the array that contains the options passed on the command line. RETURNS: - The numbers of records deleted as a result of this operation. =cut sub deleteMriParameterForm { - my($dbh, $mriUploadsRef, $tmpSQLFile, $dump_opt) = @_; + my($dbh, $mriUploadsRef, $tmpSQLFile, $optionsRef) = @_; my @uploadIDs = map { $_->{'UploadID'} } @$mriUploadsRef; my $query = "SELECT f.CommentID FROM flag f " @@ -1951,8 +1983,8 @@ sub deleteMriParameterForm { return if !@commentIDs; my $nbRecordsDeleted = 0; - $nbRecordsDeleted += &deleteTableData($dbh, 'mri_parameter_form', 'CommentID', \@commentIDs, $tmpSQLFile, $dump_opt); - $nbRecordsDeleted += &deleteTableData($dbh, 'flag' , 'CommentID', \@commentIDs, $tmpSQLFile, $dump_opt); + $nbRecordsDeleted += &deleteTableData($dbh, 'mri_parameter_form', 'CommentID', \@commentIDs, $tmpSQLFile, $optionsRef); + $nbRecordsDeleted += &deleteTableData($dbh, 'flag' , 'CommentID', \@commentIDs, $tmpSQLFile, $optionsRef); return $nbRecordsDeleted; } @@ -2062,7 +2094,7 @@ sub getTarchiveSeriesIDs { return [ map { $_->{'TarchiveSeriesID'} } @$tarchiveFilesRef ]; } -=head3 deleteTableData($dbh, $table, $key, $keyValuesRef, $tmpSQLBackupFile, $dump_opt) +=head3 deleteTableData($dbh, $table, $key, $keyValuesRef, $tmpSQLBackupFile, $optionsRef) Deletes records from a database table and adds in a file the SQL statements that allow rewriting the records back in the table. @@ -2074,14 +2106,14 @@ =head3 deleteTableData($dbh, $table, $key, $keyValuesRef, $tmpSQLBackupFile, $du - $key: name of the key used to delete the records. - $keyValuesRef: reference on the list of values that field C<$key> has for the records to delete. - $tmpSQLBackupFile: path of the SQL file that contains the SQL statements used to restore the deleted records. - - $dump_opt: additional options to use for mysqldump + - $optionsRef: reference to the array that contains the options passed on the command line. RETURNS: - The number of records deleted. =cut sub deleteTableData { - my($dbh, $table, $key, $keyValuesRef, $tmpSQLBackupFile, $dump_opt) = @_; + my($dbh, $table, $key, $keyValuesRef, $tmpSQLBackupFile, $optionsRef) = @_; return 0 unless @$keyValuesRef; @@ -2089,14 +2121,14 @@ sub deleteTableData { . join(',', ('?') x @$keyValuesRef) . ')'; - &updateSQLBackupFile($tmpSQLBackupFile, $table, $key, $keyValuesRef, $dump_opt) if $tmpSQLBackupFile; + &updateSQLBackupFile($tmpSQLBackupFile, $table, $key, $keyValuesRef, $optionsRef) if $tmpSQLBackupFile; my $nbRecordsDeleted = $dbh->do($query, undef, @$keyValuesRef); return $nbRecordsDeleted; } -=head3 updateSQLBackupFile($tmpSQLBackupFile, $table, $key, $keyValuesRef, $dump_opt) +=head3 updateSQLBackupFile($tmpSQLBackupFile, $table, $key, $keyValuesRef, $optionsRef) Updates the SQL file with the statements to restore the records whose properties are passed as argument. The block of statements is written at the beginning of the file. @@ -2106,11 +2138,11 @@ =head3 updateSQLBackupFile($tmpSQLBackupFile, $table, $key, $keyValuesRef, $dump - $table: name of the database table. - $key: name of the key used to delete the records. - $keyValuesRef: reference on the list of values that field C<$key> has for the records to delete. - - $dump_opt: additional options to use for mysqldump + - $optionsRef: reference to the array that contains the options passed on the command line. =cut sub updateSQLBackupFile { - my($tmpSQLBackupFile, $table, $key, $keyValuesRef, $dump_opt) = @_; + my($tmpSQLBackupFile, $table, $key, $keyValuesRef, $optionsRef) = @_; # Make sure all keys are quoted before using them in the Unix command my %quotedKeys; @@ -2127,24 +2159,43 @@ sub updateSQLBackupFile { # Run the mysqldump command for the current table and store the # result in $tmpSqlBackupFile (overwrite contents) - my $mysqldumpOptions = "$dump_opt --no-create-info --compact --single-transaction --skip-extended-insert --no-tablespaces"; - - my $warningToIgnore = 'mysqldump: [Warning] Using a password on the command line interface can be insecure.'; + # Note that --defaults-extra-file has to be the first option (it it is provided) + my $mySqldumpOptions = $optionsRef->{'EXTRA_MYSQLCNF'} ne '' + ? sprintf("--defaults-extra-file=%s", quotemeta($optionsRef->{'EXTRA_MYSQLCNF'})) + : ''; + $mySqldumpOptions .= sprintf( + " %s --no-create-info --compact --skip-extended-insert --no-tablespaces", + $optionsRef->{'DUMP_ADDITIONAL_OPTIONS'} + ); + + # Create a temporary file for mySqlDump's stdout and stderr + my($unusedFileHandle, $mySqlDumpOutputFile) = tempfile("mysqlDumpXXXXX", UNLINK => 1); my $cmd = sprintf( - "mysqldump $mysqldumpOptions --where='%s IN (%s)' --result-file=%s -h %s -p%s -u %s %s %s 2>&1 | fgrep -v '$warningToIgnore'", + "mysqldump $mySqldumpOptions --where='%s IN (%s)' --result-file=%s -h %s -u %s %s %s >$mySqlDumpOutputFile 2>&1", $key, join(',', keys %quotedKeys), quotemeta($tmpSQLBackupFile), quotemeta($Settings::db[3]), - quotemeta($Settings::db[2]), quotemeta($Settings::db[1]), quotemeta($Settings::db[0]), $table ); - - system($cmd) != 0 - or die "Cannot run command $cmd. Aborting\n"; - + + + # Execute the command and read the file containing the warnings+errors of the mysqldump command + my $mySqlDumpReturnCode = system($cmd); + open(MYSQLDUMP_OUTPUT, "<$mySqlDumpOutputFile") or die "Cannot read $mySqlDumpOutputFile: $!\n"; + my @mySqlDumpOutput = ; + close(MYSQLDUMP_OUTPUT); + + # Check that command succeeded. Echo the warnings and errors on stdout in all cases. + if ($mySqlDumpReturnCode == 0) { + printf("Backup of table $table succeeded but a warning was issued: %s.\n", join('', @mySqlDumpOutput)) if @mySqlDumpOutput; + } else { + die sprintf("Backup of table $table failed with the following output:\n%sAborting\n", join('', @mySqlDumpOutput)); + } + unlink $mySqlDumpOutputFile or warn "Warning! Cannot delete $mySqlDumpOutputFile: $!.\n"; + # Write back the original lines contained in $tmpSQlBackupFile at the end of the file. # This is so that the mysqldump results are written in the file in the reverse order in # which the mySQL delete statements are made. diff --git a/uploadNeuroDB/NeuroDB/Database.pm b/uploadNeuroDB/NeuroDB/Database.pm index a1866d0a1..d4976103e 100644 --- a/uploadNeuroDB/NeuroDB/Database.pm +++ b/uploadNeuroDB/NeuroDB/Database.pm @@ -280,9 +280,7 @@ sub disconnect { my $self = shift; if($self->dbh) { - try { - $self->dbh->disconnect(); - } catch { + if($self->dbh->disconnect()) { NeuroDB::DatabaseException->throw( statement => 'Call to disconnect failed', args => [], @@ -293,20 +291,6 @@ sub disconnect { } } -=pod - -=head3 C - -Object destructor: terminates the connection previously instantiated to the -database (if any). - -=cut -sub DESTROY { - my $self = shift; - - $self->disconnect(); -} - 1; __END__