diff options
author | David M <davidmj@users.sourceforge.net> | 2007-06-07 05:58:45 +0000 |
---|---|---|
committer | David M <davidmj@users.sourceforge.net> | 2007-06-07 05:58:45 +0000 |
commit | dd9c236e6a47fb93d2f39f746f2bac5efc62066d (patch) | |
tree | da04db2d671b6c83f434b8097d99e1ab23e53eea /phpBB/includes | |
parent | 5e78e5ad95fb8608d693f8f6b5ac075cbe072e07 (diff) | |
download | forums-dd9c236e6a47fb93d2f39f746f2bac5efc62066d.tar forums-dd9c236e6a47fb93d2f39f746f2bac5efc62066d.tar.gz forums-dd9c236e6a47fb93d2f39f746f2bac5efc62066d.tar.bz2 forums-dd9c236e6a47fb93d2f39f746f2bac5efc62066d.tar.xz forums-dd9c236e6a47fb93d2f39f746f2bac5efc62066d.zip |
- Oracle, woe is you... I will say this much, this fixes Oracle's handling of empty strings... We also fix custom profiles and now provide database size for Oracle...
git-svn-id: file:///svn/phpbb/trunk@7721 89ea8834-ac86-4346-8a33-228a782c2dd0
Diffstat (limited to 'phpBB/includes')
-rw-r--r-- | phpBB/includes/acp/acp_profile.php | 2 | ||||
-rw-r--r-- | phpBB/includes/db/oracle.php | 114 | ||||
-rw-r--r-- | phpBB/includes/functions_admin.php | 8 |
3 files changed, 119 insertions, 5 deletions
diff --git a/phpBB/includes/acp/acp_profile.php b/phpBB/includes/acp/acp_profile.php index da11868cc2..2d4091f2f9 100644 --- a/phpBB/includes/acp/acp_profile.php +++ b/phpBB/includes/acp/acp_profile.php @@ -1508,7 +1508,7 @@ class acp_profile case 'oracle': // We are defining the biggest common value, because of the possibility to edit the min/max values of each field. - $sql = 'ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . " ADD \"$field_ident\" "; + $sql = 'ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . " ADD $field_ident "; switch ($field_type) { diff --git a/phpBB/includes/db/oracle.php b/phpBB/includes/db/oracle.php index 360928e96d..c0d960506d 100644 --- a/phpBB/includes/db/oracle.php +++ b/phpBB/includes/db/oracle.php @@ -48,7 +48,7 @@ class dbal_oracle extends dbal $connect = $sqlserver . (($port) ? ':' . $port : '') . '/' . $database; } - $this->db_connect_id = ($new_link) ? @ocinlogon($this->user, $sqlpassword, $connect, 'UTF8') : (($this->persistency) ? @ociplogon($this->user, $sqlpassword, $connect, 'UTF8') : @ocinlogon($this->user, $sqlpassword, $connect, 'UTF8')); + $this->db_connect_id = ($new_link) ? @ocinlogon($this->user, $sqlpassword, $connect, 'UTF8') : (($this->persistency) ? @ociplogon($this->user, $sqlpassword, $connect, 'UTF8') : @ocilogon($this->user, $sqlpassword, $connect, 'UTF8')); return ($this->db_connect_id) ? $this->db_connect_id : $this->sql_error(''); } @@ -86,6 +86,90 @@ class dbal_oracle extends dbal } /** + * Oracle specific code to handle the fact that it does not compare columns properly + * @access private + */ + function _rewrite_col_compare($args) + { + if (sizeof($args) == 4) + { + if ($args[2] == '=') + { + return '(' . $args[0] . ' OR (' . $args[1] . ' is NULL AND ' . $args[3] . ' is NULL))'; + } + else if ($args[2] == '<>') + { + // really just a fancy way of saying foo <> bar or (foo is NULL XOR bar is NULL) but SQL has no XOR :P + return '(' . $args[0] . ' OR ((' . $args[1] . ' is NULL AND ' . $args[3] . ' is NOT NULL) OR (' . $args[1] . ' is NOT NULL AND ' . $args[3] . ' is NULL)))'; + } + } + else + { + return $this->_rewrite_where($args[0]); + } + } + + /** + * Oracle specific code to handle it's lack of sanity + * @access private + */ + function _rewrite_where($where_clause) + { + preg_match_all('/\s*(AND|OR)?\s*([\w_.]++)\s*(?:(=|<>)\s*((?>\'(?>[^\']++|\'\')*+\'|\d+))|((NOT )?IN\s*\((?>\'(?>[^\']++|\'\')*+\',? ?|\d+,? ?)*+\)))/', $where_clause, $result, PREG_SET_ORDER); + $out = ''; + foreach ($result as $val) + { + if (!isset($val[5])) + { + if ($val[4] !== "''") + { + $out .= $val[0]; + } + else + { + $out .= ' ' . $val[1] . ' ' . $val[2]; + if ($val[3] == '=') + { + $out .= ' is NULL'; + } + else if ($val[3] == '<>') + { + $out .= ' is NOT NULL'; + } + } + } + else + { + $in_clause = array(); + $sub_exp = substr($val[5], strpos($val[5], '(') + 1, -1); + $extra = false; + preg_match_all('/\'(?>[^\']++|\'\')*+\'|\d++/', $sub_exp, $sub_vals, PREG_PATTERN_ORDER); + foreach ($sub_vals[0] as $sub_val) + { + if ($sub_val !== "''") + { + $in_clause[] = $sub_val; + } + else + { + $extra = true; + } + } + if (!$extra) + { + $out .= $val[0]; + } + else + { + $out .= ' ' . $val[1] . ' (' . $val[2]. ' ' . (isset($val[6]) ? $val[6] : '') . 'IN(' . implode(', ', $in_clause) . ') OR ' . $val[2] . ' is ' . (isset($val[6]) ? $val[6] : '') . 'NULL)'; + } + } + } + + return $out; + } + + /** * Base query method * * @param string $query Contains the SQL query which shall be executed @@ -127,7 +211,6 @@ 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 (strlen($regs[3]) > 4000) @@ -151,13 +234,13 @@ class dbal_oracle extends dbal 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)) { if (strlen($data[0][2]) > 4000) { $update = $data[0][1]; $where = $data[0][3]; - preg_match_all('/(\\w++) = (\'(?:[^\']++|\'\')*+\'|\\d++)/', $data[0][2], $temp, PREG_SET_ORDER); + preg_match_all('/([\\w_]++) = (\'(?:[^\']++|\'\')*+\'|\\d++)/', $data[0][2], $temp, PREG_SET_ORDER); unset($data); $art = array(); @@ -180,6 +263,29 @@ class dbal_oracle extends dbal } } + switch (substr($query, 0, 6)) + { + case 'DELETE': + if (preg_match('/^(DELETE FROM [\w_]++ WHERE)((?:\s*(?:AND|OR)?\s*[\w_]+\s*(?:(?:=|<>)\s*(?>\'(?>[^\']++|\'\')*+\'|\d+)|(?:NOT )?IN\s*\((?>\'(?>[^\']++|\'\')*+\',? ?|\d+,? ?)*+\)))*+)$/', $query, $regs)) + { + $query = $regs[1] . $this->_rewrite_where($regs[2]); + unset($regs); + } + break; + + case 'UPDATE': + if (preg_match('/^(UPDATE [\\w_]++\\s+SET [\\w_]+\s*=\s*(?:\'(?:[^\']++|\'\')*+\'|\\d++|:\w++)(?:, [\\w_]+\s*=\s*(?:\'(?:[^\']++|\'\')*+\'|\\d++|:\w++))*+\\s+WHERE)(.*)$/s', $query, $regs)) + { + $query = $regs[1] . $this->_rewrite_where($regs[2]); + unset($regs); + } + break; + + case 'SELECT': + $query = preg_replace_callback('/([\w_.]++)\s*(?:(=|<>)\s*(?>\'(?>[^\']++|\'\')*+\'|\d++|([\w_.]++))|(?:NOT )?IN\s*\((?>\'(?>[^\']++|\'\')*+\',? ?|\d++,? ?)*+\))/', array($this, '_rewrite_col_compare'), $query); + break; + } + $this->query_result = @ociparse($this->db_connect_id, $query); foreach ($array as $key => $value) diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index 3a24c5db1c..28a5ab9983 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -2824,6 +2824,14 @@ function get_database_size() $database_size = $row['size']; } break; + + case 'oracle': + $sql = 'SELECT SUM(bytes) as dbsize + FROM user_segments'; + $result = $db->sql_query($sql); + $database_size = ($row = $db->sql_fetchrow($result)) ? $row['dbsize'] : false; + $db->sql_freeresult($result); + break; } if ($database_size !== false) |