I need to find and replace, within a potentially big SQL dump file (~2-3MB), all date occurrences with their actual value increased with a given value. This is needed as my company uses this SQL dump file to deploy demos of a particular software, and the dates need to be translated to correctly fit the period the demo will be usable.
This is a small extract to serve as an example:
INSERT INTO
ordini
(id
,id_fornitore
,data
,oggetti_ordine
,data_consegna
,controllo
,data_consegna_prevista
,resp_controllo
,DDT
,nr_DDT
,iknow_iddocu
,spedizione
,pagamento
) VALUES (10, 204, '2011-11-29', 'Palline gialle##Palline rosse##Palline verdi##§§1000##200##360##§§12 €##10 €##11.5 €##', '2012-12-29', 0, '2011-12-05', 0, '', '', 0, 'A mano', '30 gg.'), (13, 204, '2011-11-30', 'Palline verdi##§§12##§§5.750##', '2013-04-23', 0, '1970-01-01', 0, '', '', 0, '', ''), (14, 204, '2011-11-30', 'Palline verdi##Palline rosse##§§12##22##§§5.750##5.750##', '2013-02-22', 0, '2011-12-31', 0, '', '', 0, 'A mano', 'Ri.Ba. 30 gg.');
As you can see, all the dates within the file are in mysql YYYY-MM-DD DATETIME format, like: '2013-03-12'. Occasionally, some of them may include the time as well after the date, but being this irrelevant to my needs, times should be left unchanged.
I eventually arranged this simple script:
<?php
$push_period = "30";
print "<h1>Parsing file...</h1>";
print "<h2>Pushing dates ahead of {$push_period} days.</h2>";
$file=implode("\n",file('db.sql'));
print($file);
preg_match_all('@(\d\d\d\d)-(\d\d)-(\d\d)@', $file, $match, PREG_OFFSET_CAPTURE);
print "<br /><br />";
print "<table border=1 align='center'>";
print "<th colspan='3'><b>Dates moved {$push_period} days ahead</b></th>";
$array_new_dates = array();
foreach ($match[0] as $occurrence) {
print "<tr><td>";
print "<pre>";
print_r($occurrence);
print "</pre>";
print "</td><td width='40' align='center'>";
print "=>";
print "</td><td>";
print "<pre>";
$temp_array = array();
$modified_value = date('Y-m-d', strtotime($occurrence[0] . " +".$push_period." days"));
$temp_array[0] = $modified_value;
$temp_array[1] = $occurrence[1];
$array_new_dates[] = $temp_array;
print_r($temp_array);
print "</pre>";
print "</td></tr>";
$file = substr_replace($file, $modified_value, $occurrence[1], 10);
}
print "</table>";
print($file);
$file = str_replace("\n", "", $file);
$fp=fopen('updated_db.sql','w');
// Dumping updated file
fwrite($fp,$file,strlen($file));
?>
Now, my problem is that if I run this script with large files, I am predictably prompted this error:
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 64 bytes) in /srv/www/htdocs/mysoftware_dev/date_replacer.php on line 10
I hence need to elaborate the input in steps. Problem is, if I split the input file in fixed-size blocks, I might happen to trunk a date (and consequently not pushing it ahead of the needed value). What would a good approach to this problem be? (apart from manually pre-splitting the input file into several smaller files). Thank you for any help.