#!/usr/bin/env perl #------------------------------------------------------------------- # WebGUI is Copyright 2001-2011 Plain Black Corporation. #------------------------------------------------------------------- # Please read the legal notices (docs/legal.txt) and the license # (docs/license.txt) that came with this distribution before using # this software. #------------------------------------------------------------------- # http://www.plainblack.com info@plainblack.com #------------------------------------------------------------------- $|++; # disable output buffering our ($webguiRoot, $configFile, $help, $man, $quiet); BEGIN { $webguiRoot = ".."; unshift (@INC, $webguiRoot."/lib"); } use strict; use Pod::Usage; use Tie::IxHash; use Getopt::Long; use WebGUI::Session; use WebGUI::Asset; use WebGUI::Asset::Wobject; use WebGUI::User; # General settings and defaults my $overwrite; # Return all metadata to pre-upgrade values. my $preserve; # DO NOT remove old metadata without revision dates when done. my $verbose; # Maximum output; details on all metadata values. my $limit = 0; # Number of records to process this time. 0 means do all. my $doit; # Update metadata; lack of this flag means you are testing only. GetOptions( 'configFile=s' => \$configFile, 'help' => \$help, 'man' => \$man, 'verbose' => \$verbose, 'overwrite' => \$overwrite, 'preserve' => \$preserve, 'limit:i' => \$limit, 'doit' => \$doit ); # Help and parameter checks pod2usage( verbose => 1 ) if $help; pod2usage( verbose => 2 ) if $man; pod2usage( msg => "\nMust specify a WebGUI config file!" ) unless $configFile; ### Gather necessary data for processing my $session = start($webguiRoot,$configFile); print "\nStarting up ..."; # Find all pre-upgrade metadata values (have no revisionDate) my $SQL = $session->db->buildArrayRefOfHashRefs( "SELECT fieldId, assetId, value FROM metaData_values WHERE revisionDate = 0" ); my $numResults = scalar @{$SQL}; if ($numResults > 0) { print "OK\n\n"; } else { finish($session); die "NOT OK\nNo metadata without revision dates found.\n"; } my $counter = 0; # Number of initial metadata values processed my $skipped = 0; # Number of initial metadata values skipped for some reason my $sameVal = 0; # Number skipped because of same new/old values my $noOver = 0; # Number skipped because $overwrite NOT invoked my $added = 0; # Number of new metadata value revisions added my $updated = 0; # Number existing metadata updated my $deleted = 0; # Number of old metadata values deleted (revisionDate == 0) my $i = 0; # Loop incrementer my @rD; # Array to hold individual metadata versions my $mValue; # Variable to hold value for queried metadata my $testout; # Variable to hold testing output ### Loop through query results and update as necessary for ($i=0;$i<$numResults;$i++) { # Break out of loop if $limit is set and has been reached last if ($limit > 0 && $counter >= $limit); $counter++; # Create array of revisionDate values for the Asset associated # with this metadata value @rD = $session->db->buildArray( "SELECT revisionDate FROM assetData WHERE assetId = ? ORDER BY revisionDate", [$SQL->[$i]{assetId}] ); # For each asset revision, check for metadata & process foreach my $rD (@rD) { # Determine whether metadata exists for that date ($mValue) = $session->db->quickArray( "SELECT value FROM metaData_values WHERE assetId = ? AND fieldId = ? AND revisionDate = ?", [$SQL->[$i]{assetId},$SQL->[$i]{fieldId},$rD] ); # Start logic to handle data # dM = "dated Metadata" & "ndM" = "not dated Metadata" # IF dM was found and == ndM, NOTHING TO DO if ($mValue eq $SQL->[$i]{value}) { $skipped++; $sameVal++; } # ELSE, if dM found and $overwrite NOT set, LEAVE ORIGINAL VALUE elsif (defined $mValue && length $mValue > 0 && !$overwrite) { $skipped++; $noOver++; } # ELSE, add/update metadata (if $doit) # IF dM found, UPDATE elsif (defined $mValue && length $mValue > 0) { $updated++; if ($doit) { $session->db->write( "UPDATE metaData_values SET value = ? WHERE assetId = ? AND fieldId = ? AND revisionDate = ?", [$SQL->[$i]{value},$SQL->[$i]{assetId},$SQL->[$i]{fieldId},$rD] ); if ($verbose) { $testout = "$counter. Asset $SQL->[$i]{assetId} Metadata $SQL->[$i]{fieldId} = $SQL->[$i]{value}\n"; print $testout; } } elsif ($verbose) { $testout = "$counter. UPDATE metaData_values SET value = $SQL->[$i]{value} "; $testout .= "WHERE assetId = $SQL->[$i]{assetId} AND "; $testout .= "fieldId = $SQL->[$i]{fieldId} AND revisionDate = $rD\n"; print $testout; } } # ELSE INSERT (using REPLACE just to be safe) else { $added++; if ($doit) { $session->db->write( "REPLACE INTO metaData_values (assetId, fieldId, revisionDate, value) VALUES (?,?,?,?)", [$SQL->[$i]{assetId},$SQL->[$i]{fieldId},$rD,$SQL->[$i]{value}] ); if ($verbose) { $testout = "$counter. Asset $SQL->[$i]{assetId} Metadata $SQL->[$i]{fieldId} = $SQL->[$i]{value}\n"; } print $testout; } elsif ($verbose) { $testout = "$counter. REPLACE INTO metaData_values "; $testout .= "(assetId, fieldId, revisionDate, value) VALUES "; $testout .= "($SQL->[$i]{assetId},$SQL->[$i]{fieldId},$rD,"; $testout .= "$SQL->[$i]{value})\n"; print $testout; } } } # Once done with that metadata value, DELETE original, undated record if ($doit && !$preserve) { $session->db->write( "DELETE FROM metaData_values WHERE assetId = ? AND fieldId = ? AND revisionDate = 0", [$SQL->[$i]{assetId},$SQL->[$i]{fieldId}] ); $deleted++ } } ### Test to see whether there are any metadata without revisionDate values my ($metaLeft) = $session->db->quickArray( "SELECT COUNT(*) FROM metaData_values WHERE revisionDate = 0" ); ### Generate summary output print "\nSummary:\n"; print "\tTESTING MODE\n" unless ($doit); print "\tTotal Processed: $counter\n"; print "\tSkipped: $skipped\n"; print "\t\tSame Value: $sameVal, No Overwrite: $noOver\n"; if ($skipped != $sameVal + $noOver) { print "\t\tCALCULATION ERROR - Same Value + No Overwrite != Skipped\n"; } print "\tUpdated: $updated\n"; print "\tAdded: $added\n"; print "\tDeleted: $deleted\n"; if ($deleted != $counter && !$preserve && $doit) { print "\n\tERROR - Total Processed != Total Deleted\n"; } if ($metaLeft > 0) { print "\n\tERROR - $metaLeft metadata values without revision dates remain!\n" unless (!$doit || $preserve); } # print "Total Errors: $globalErrors\n\n"; # Clean up (commit version tag!) print "\nCleaning up ..."; finish($session); print "OK\n\n"; #---------------------------------------------------------------------------- sub start { my $webguiRoot = shift; my $configFile = shift; my $session = WebGUI::Session->open($webguiRoot,$configFile); $session->user({userId=>3}); if ($doit) { my $versionTag = WebGUI::VersionTag->getWorking($session); my $tagName = "Auto Import " . time; $versionTag->set({name => $tagName}); } return $session; } #---------------------------------------------------------------------------- sub finish { my $session = shift; if ($doit) { my $versionTag = WebGUI::VersionTag->getWorking($session); $versionTag->commit; } $session->var->end; $session->close; } __END__ =head1 NAME metadataFixer - A utility for fixing "missing" metadata that appear to disappear during the 7.9.34 to 7.10.22 upgrade, which adds metadata versioning and asset class context. Existing metadata values were not updated with proper revisionDate values, causing them to no longer be associated with the appropriate asset revisions during either view or editing of the assets. =head1 SYNOPSIS metadataFixer.pl --configFile config.conf [--verbose] [--overwrite] [--preserve] [--limit number] [--doit] utility --help =head1 DESCRIPTION ... stuff here =head1 OPTIONS =over =item B<--configFile config.conf> The WebGUI config file to use. Only the file name needs to be specified, since it will be looked up inside WebGUI's configuration directory. This parameter is required. =item B<--verbose> Generates the maximum available output during execution of the script. Summary text will be given for each metadata value to be udpated. Without this flag, output will consist of a summary of successes and failures in processing metadata. =item B<--overwrite> Determines whether any metadata values that were set AFTER the upgrade took place will be retained or re-set back to the pre-upgrade values. Without this flag, any metadata values with revisionDate other than 0 will retain their current values. This preserves any editing done after the upgrade. With this flag, all metadata values will be re-set to the pre-upgrade state (determined by having a revisionDate of 0). If this script is run immediately after the upgrade from 7.9 to 7.10, and thus no metadata values have had revisionDates set, the state of this flag will have no impact to the outcome of the script. =item B<--preserve> Flag to indicate whether to preserve old metadata values without revision dates once script is done. Default is to clear out these data, as they are no longer needed. If OVERWRITE is not invoked, you may lose some pre-upgrade metadata values for assets that have been edited; in this case, the PRESERVE flag may be useful to retain historic data. =item B<--limit number> Limits the number of records processed before the script terminates. Without a limit, all metadata are processed. Limit is recognized in both testing and --doit modes. =item B<--doit> This flag is necessary to update records. Without it, the script is in testing mode by default. It encourages the user to test settings and flags prior to executing the update. =item B<--help> Shows a short summary and usage =item B<--man> Shows this document =back =head1 AUTHOR Copyright 2001-2012 Plain Black Corporation. Copyright 2012 Dale Trexel =cut #vim:ft=perl