diff options
author | David M <davidmj@users.sourceforge.net> | 2007-04-11 02:23:21 +0000 |
---|---|---|
committer | David M <davidmj@users.sourceforge.net> | 2007-04-11 02:23:21 +0000 |
commit | b62268e8c2052105715949a57d73ef4ea9a4355d (patch) | |
tree | 3ef80bccc8fbdaccf810baa920361c482c8921f8 /phpBB/includes | |
parent | b07520669c22873d66240f1f5c6b814f1fc2122e (diff) | |
download | forums-b62268e8c2052105715949a57d73ef4ea9a4355d.tar forums-b62268e8c2052105715949a57d73ef4ea9a4355d.tar.gz forums-b62268e8c2052105715949a57d73ef4ea9a4355d.tar.bz2 forums-b62268e8c2052105715949a57d73ef4ea9a4355d.tar.xz forums-b62268e8c2052105715949a57d73ef4ea9a4355d.zip |
- 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
Diffstat (limited to 'phpBB/includes')
-rw-r--r-- | phpBB/includes/db/firebird.php | 75 | ||||
-rw-r--r-- | phpBB/includes/db/oracle.php | 74 |
2 files changed, 114 insertions, 35 deletions
diff --git a/phpBB/includes/db/firebird.php b/phpBB/includes/db/firebird.php index 5c69c34fb9..4b3a15dd8d 100644 --- a/phpBB/includes/db/firebird.php +++ b/phpBB/includes/db/firebird.php @@ -109,7 +109,80 @@ class dbal_firebird extends dbal 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); } diff --git a/phpBB/includes/db/oracle.php b/phpBB/includes/db/oracle.php index 21585e5899..9c0491d8c8 100644 --- a/phpBB/includes/db/oracle.php +++ b/phpBB/includes/db/oracle.php @@ -110,54 +110,60 @@ class dbal_oracle extends dbal $in_transaction = true; } - $array = array(); - // We overcome Oracle's 4000 char limit by binding vars - if (preg_match('/^(INSERT INTO[^(]+)\\(([^()]+)\\) VALUES[^(]+\\((.*?)\\)$/s', $query, $regs)) + if (strlen($query) > 4000) { - if (strlen($regs[3]) > 4000) + $array = array(); + + if (preg_match('/^(INSERT INTO[^(]+)\\(([^()]+)\\) VALUES[^(]+\\((.*?)\\)$/s', $query, $regs)) { - $cols = explode(', ', $regs[2]); - preg_match_all('/\'(?:[^\']++|\'\')*+\'|\\d+/', $regs[3], $vals, PREG_PATTERN_ORDER); + if (strlen($regs[3]) > 4000) + { + $cols = explode(', ', $regs[2]); + preg_match_all('/\'(?:[^\']++|\'\')*+\'|\\d+/', $regs[3], $vals, PREG_PATTERN_ORDER); - $inserts = $vals[0]; - unset($vals); + $inserts = $vals[0]; + unset($vals); - foreach ($inserts as $key => $value) - { - if (!empty($value) && $value[0] === "'" && strlen($value) > 4002) // check to see if this thing is greater than the max + 'x2 + foreach ($inserts as $key => $value) { - $inserts[$key] = ':' . strtoupper($cols[$key]); - $array[$inserts[$key]] = str_replace("''", "'", substr($value, 1, -1)); + if (!empty($value) && $value[0] === "'" && strlen($value) > 4002) // check to see if this thing is greater than the max + 'x2 + { + $inserts[$key] = ':' . strtoupper($cols[$key]); + $array[$inserts[$key]] = str_replace("''", "'", substr($value, 1, -1)); + } } + + $query = $regs[1] . '(' . $regs[2] . ') VALUES (' . implode(', ', $inserts) . ')'; + unset($art); } - $query = $regs[1] . '(' . $regs[2] . ') VALUES (' . implode(', ', $inserts) . ')'; } - } - 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][2]) > 4000) + else if (preg_match_all('/^(UPDATE [\\w_]++\\s+SET )(\\w+ = (?:\'(?:[^\']++|\'\')*+\'|\\d+)(?:, \\w+ = (?:\'(?:[^\']++|\'\')*+\'|\\d+))*+)\\s+(WHERE.*)$/s', $query, $data, PREG_SET_ORDER)) { - $update = $data[0][1]; - $where = $data[0][3]; - preg_match_all('/(\\w++) = (\'(?:[^\']++|\'\')*+\'|\\d++)/', $data[0][2], $temp, PREG_SET_ORDER); - unset($data); - - $art = array(); - foreach ($temp as $value) + if (strlen($data[0][2]) > 4000) { - 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]); - $array[$cols[$value[1]]] = str_replace("''", "'", substr($value[2], 1, -1)); - } - else + $update = $data[0][1]; + $where = $data[0][3]; + preg_match_all('/(\\w++) = (\'(?:[^\']++|\'\')*+\'|\\d++)/', $data[0][2], $temp, PREG_SET_ORDER); + unset($data); + + $art = array(); + foreach ($temp as $value) { - $art[] = $value[1] . '=' . $value[2]; + 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]); + $array[$value[1]] = str_replace("''", "'", substr($value[2], 1, -1)); + } + else + { + $art[] = $value[1] . '=' . $value[2]; + } } - } - $query = $update . implode(', ', $art) . ' ' . $where; + $query = $update . implode(', ', $art) . ' ' . $where; + unset($art); + } } } |