mirror of
https://github.com/phpbb/phpbb.git
synced 2025-06-28 06:08:52 +00:00
- fixed Oracle's large data handling
- Firebird explodes when you deal with single column update/inserts over 32767, we now turn these queries into prepared statements git-svn-id: file:///svn/phpbb/trunk@7326 89ea8834-ac86-4346-8a33-228a782c2dd0
This commit is contained in:
parent
b07520669c
commit
b62268e8c2
2 changed files with 117 additions and 38 deletions
|
@ -109,7 +109,80 @@ class dbal_firebird extends dbal
|
||||||
|
|
||||||
if ($this->query_result === false)
|
if ($this->query_result === false)
|
||||||
{
|
{
|
||||||
if (($this->query_result = @ibase_query($this->db_connect_id, $query)) === false)
|
$prepared = false;
|
||||||
|
// We overcome Firebird's 32767 char limit by binding vars
|
||||||
|
if (strlen($query) > 32767)
|
||||||
|
{
|
||||||
|
$array = array();
|
||||||
|
|
||||||
|
if (preg_match('/^(INSERT INTO[^(]+)\\(([^()]+)\\) VALUES[^(]+\\((.*?)\\)$/s', $query, $regs))
|
||||||
|
{
|
||||||
|
if (strlen($regs[3]) > 32767)
|
||||||
|
{
|
||||||
|
preg_match_all('/\'(?:[^\']++|\'\')*+\'|\\d+/', $regs[3], $vals, PREG_PATTERN_ORDER);
|
||||||
|
|
||||||
|
$inserts = $vals[0];
|
||||||
|
unset($vals);
|
||||||
|
|
||||||
|
foreach ($inserts as $key => $value)
|
||||||
|
{
|
||||||
|
if (!empty($value) && $value[0] === "'" && strlen($value) > 32769) // check to see if this thing is greater than the max + 'x2
|
||||||
|
{
|
||||||
|
$inserts[$key] = '?';
|
||||||
|
$array[] = str_replace("''", "'", substr($value, 1, -1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = $regs[1] . '(' . $regs[2] . ') VALUES (' . implode(', ', $inserts) . ')';
|
||||||
|
unset($art);
|
||||||
|
|
||||||
|
$prepared = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (preg_match_all('/^(UPDATE ([\\w_]++)\\s+SET )(\\w+ = (?:\'(?:[^\']++|\'\')*+\'|\\d+)(?:, \\w+ = (?:\'(?:[^\']++|\'\')*+\'|\\d+))*+)\\s+(WHERE.*)$/s', $query, $data, PREG_SET_ORDER))
|
||||||
|
{
|
||||||
|
if (strlen($data[0][3]) > 32767)
|
||||||
|
{
|
||||||
|
$update = $data[0][1];
|
||||||
|
$where = $data[0][4];
|
||||||
|
preg_match_all('/(\\w++) = (\'(?:[^\']++|\'\')*+\'|\\d++)/', $data[0][3], $temp, PREG_SET_ORDER);
|
||||||
|
unset($data);
|
||||||
|
|
||||||
|
$art = array();
|
||||||
|
foreach ($temp as $value)
|
||||||
|
{
|
||||||
|
if (!empty($value[2]) && $value[2][0] === "'" && strlen($value[2]) > 32769) // check to see if this thing is greater than the max + 'x2
|
||||||
|
{
|
||||||
|
$array[] = str_replace("''", "'", substr($value[2], 1, -1));
|
||||||
|
$art[] = $value[1] . '=?';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$art[] = $value[1] . '=' . $value[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = $update . implode(', ', $art) . ' ' . $where;
|
||||||
|
unset($art);
|
||||||
|
|
||||||
|
$prepared = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($prepared)
|
||||||
|
{
|
||||||
|
$p_query = ibase_prepare($this->db_connect_id, $query);
|
||||||
|
array_unshift($array, $p_query);
|
||||||
|
$this->query_result = call_user_func_array('ibase_execute', $array);
|
||||||
|
unset($array);
|
||||||
|
|
||||||
|
if ($this->query_result === false)
|
||||||
|
{
|
||||||
|
$this->sql_error($query);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (($this->query_result = @ibase_query($this->db_connect_id, $query)) === false)
|
||||||
{
|
{
|
||||||
$this->sql_error($query);
|
$this->sql_error($query);
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,9 +110,11 @@ class dbal_oracle extends dbal
|
||||||
$in_transaction = true;
|
$in_transaction = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We overcome Oracle's 4000 char limit by binding vars
|
||||||
|
if (strlen($query) > 4000)
|
||||||
|
{
|
||||||
$array = array();
|
$array = array();
|
||||||
|
|
||||||
// We overcome Oracle's 4000 char limit by binding vars
|
|
||||||
if (preg_match('/^(INSERT INTO[^(]+)\\(([^()]+)\\) VALUES[^(]+\\((.*?)\\)$/s', $query, $regs))
|
if (preg_match('/^(INSERT INTO[^(]+)\\(([^()]+)\\) VALUES[^(]+\\((.*?)\\)$/s', $query, $regs))
|
||||||
{
|
{
|
||||||
if (strlen($regs[3]) > 4000)
|
if (strlen($regs[3]) > 4000)
|
||||||
|
@ -131,7 +133,9 @@ class dbal_oracle extends dbal
|
||||||
$array[$inserts[$key]] = str_replace("''", "'", substr($value, 1, -1));
|
$array[$inserts[$key]] = str_replace("''", "'", substr($value, 1, -1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$query = $regs[1] . '(' . $regs[2] . ') VALUES (' . implode(', ', $inserts) . ')';
|
$query = $regs[1] . '(' . $regs[2] . ') VALUES (' . implode(', ', $inserts) . ')';
|
||||||
|
unset($art);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (preg_match_all('/^(UPDATE [\\w_]++\\s+SET )(\\w+ = (?:\'(?:[^\']++|\'\')*+\'|\\d+)(?:, \\w+ = (?:\'(?:[^\']++|\'\')*+\'|\\d+))*+)\\s+(WHERE.*)$/s', $query, $data, PREG_SET_ORDER))
|
else if (preg_match_all('/^(UPDATE [\\w_]++\\s+SET )(\\w+ = (?:\'(?:[^\']++|\'\')*+\'|\\d+)(?:, \\w+ = (?:\'(?:[^\']++|\'\')*+\'|\\d+))*+)\\s+(WHERE.*)$/s', $query, $data, PREG_SET_ORDER))
|
||||||
|
@ -149,7 +153,7 @@ class dbal_oracle extends dbal
|
||||||
if (!empty($value[2]) && $value[2][0] === "'" && strlen($value[2]) > 4002) // check to see if this thing is greater than the max + 'x2
|
if (!empty($value[2]) && $value[2][0] === "'" && strlen($value[2]) > 4002) // check to see if this thing is greater than the max + 'x2
|
||||||
{
|
{
|
||||||
$art[] = $value[1] . '=:' . strtoupper($value[1]);
|
$art[] = $value[1] . '=:' . strtoupper($value[1]);
|
||||||
$array[$cols[$value[1]]] = str_replace("''", "'", substr($value[2], 1, -1));
|
$array[$value[1]] = str_replace("''", "'", substr($value[2], 1, -1));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -158,6 +162,8 @@ class dbal_oracle extends dbal
|
||||||
}
|
}
|
||||||
|
|
||||||
$query = $update . implode(', ', $art) . ' ' . $where;
|
$query = $update . implode(', ', $art) . ' ' . $where;
|
||||||
|
unset($art);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue