And now i feel even more dirty because i had to adjust the oracle hack to allow for queries > 4k to let it recognise concatenated strings and strings having the character ")" in it. I also added fallback code in case our regex splits too much. :/

git-svn-id: file:///svn/phpbb/branches/phpBB-3_0_0@10175 89ea8834-ac86-4346-8a33-228a782c2dd0
This commit is contained in:
Meik Sievertsen 2009-09-21 18:02:33 +00:00
parent 3d5ca6b2b7
commit 2ba402b06d

View file

@ -255,13 +255,62 @@ class dbal_oracle extends dbal
// We overcome Oracle's 4000 char limit by binding vars
if (strlen($query) > 4000)
{
if (preg_match('/^(INSERT INTO[^(]++)\\(([^()]+)\\) VALUES[^(]++\\((.*?)\\)$/s', $query, $regs))
if (preg_match('/^(INSERT INTO[^(]++)\\(([^()]+)\\) VALUES[^(]++\\((.*?)\\)$/sU', $query, $regs))
{
if (strlen($regs[3]) > 4000)
{
$cols = explode(', ', $regs[2]);
preg_match_all('/\'(?:[^\']++|\'\')*+\'|[\d-.]+/', $regs[3], $vals, PREG_PATTERN_ORDER);
if (sizeof($cols) !== sizeof($vals))
{
// Try to replace some common data we know is from our restore script or from other sources
$regs[3] = str_replace("'||chr(47)||'", '/', $regs[3]);
$_vals = explode(', ', $regs[3]);
$vals = array();
$is_in_val = false;
$i = 0;
$string = '';
foreach ($_vals as $value)
{
if (strpos($value, "'") === false && !$is_in_val)
{
$vals[$i++] = $value;
continue;
}
if (substr($value, -1) === "'")
{
$vals[$i] = $string . (($is_in_val) ? ', ' : '') . $value;
$string = '';
$is_in_val = false;
if ($vals[$i][0] !== "'")
{
$vals[$i] = "''" . $vals[$i];
}
$i++;
continue;
}
else
{
$string .= (($is_in_val) ? ', ' : '') . $value;
$is_in_val = true;
}
}
if ($string)
{
// New value if cols != value
$vals[(sizeof($cols) !== sizeof($vals)) ? $i : $i - 1] .= $string;
}
$vals = array(0 => $vals);
}
$inserts = $vals[0];
unset($vals);