📄 mysql.php
字号:
if (is_resource($this->connection)) { if ($this->in_transaction) { $dsn = $this->dsn; $database_name = $this->database_name; $persistent = $this->options['persistent']; $this->dsn = $this->connected_dsn; $this->database_name = $this->connected_database_name; $this->options['persistent'] = $this->opened_persistent; $this->rollback(); $this->dsn = $dsn; $this->database_name = $database_name; $this->options['persistent'] = $persistent; } if (!$this->opened_persistent || $force) { @mysql_close($this->connection); } } return parent::disconnect($force); } // }}} // {{{ standaloneQuery() /** * execute a query as DBA * * @param string $query the SQL query * @param mixed $types array that contains the types of the columns in * the result set * @param boolean $is_manip if the query is a manipulation query * @return mixed MDB2_OK on success, a MDB2 error on failure * @access public */ function &standaloneQuery($query, $types = null, $is_manip = false) { $user = $this->options['DBA_username']? $this->options['DBA_username'] : $this->dsn['username']; $pass = $this->options['DBA_password']? $this->options['DBA_password'] : $this->dsn['password']; $connection = $this->_doConnect($user, $pass, $this->options['persistent']); if (PEAR::isError($connection)) { return $connection; } $offset = $this->offset; $limit = $this->limit; $this->offset = $this->limit = 0; $query = $this->_modifyQuery($query, $is_manip, $limit, $offset); $result =& $this->_doQuery($query, $is_manip, $connection, $this->database_name); if (!PEAR::isError($result)) { $result = $this->_affectedRows($connection, $result); } @mysql_close($connection); return $result; } // }}} // {{{ _doQuery() /** * Execute a query * @param string $query query * @param boolean $is_manip if the query is a manipulation query * @param resource $connection * @param string $database_name * @return result or error object * @access protected */ function &_doQuery($query, $is_manip = false, $connection = null, $database_name = null) { $this->last_query = $query; $result = $this->debug($query, 'query', array('is_manip' => $is_manip, 'when' => 'pre')); if ($result) { if (PEAR::isError($result)) { return $result; } $query = $result; } if ($this->options['disable_query']) { $result = $is_manip ? 0 : null; return $result; } if (is_null($connection)) { $connection = $this->getConnection(); if (PEAR::isError($connection)) { return $connection; } } if (is_null($database_name)) { $database_name = $this->database_name; } if ($database_name) { if ($database_name != $this->connected_database_name) { if (!@mysql_select_db($database_name, $connection)) { $err = $this->raiseError(null, null, null, 'Could not select the database: '.$database_name, __FUNCTION__); return $err; } $this->connected_database_name = $database_name; } } $function = $this->options['result_buffering'] ? 'mysql_query' : 'mysql_unbuffered_query'; $result = @$function($query, $connection); if (!$result) { $err =& $this->raiseError(null, null, null, 'Could not execute statement', __FUNCTION__); return $err; } $this->debug($query, 'query', array('is_manip' => $is_manip, 'when' => 'post', 'result' => $result)); return $result; } // }}} // {{{ _affectedRows() /** * Returns the number of rows affected * * @param resource $result * @param resource $connection * @return mixed MDB2 Error Object or the number of rows affected * @access private */ function _affectedRows($connection, $result = null) { if (is_null($connection)) { $connection = $this->getConnection(); if (PEAR::isError($connection)) { return $connection; } } return @mysql_affected_rows($connection); } // }}} // {{{ _modifyQuery() /** * Changes a query string for various DBMS specific reasons * * @param string $query query to modify * @param boolean $is_manip if it is a DML query * @param integer $limit limit the number of rows * @param integer $offset start reading from given offset * @return string modified query * @access protected */ function _modifyQuery($query, $is_manip, $limit, $offset) { if ($this->options['portability'] & MDB2_PORTABILITY_DELETE_COUNT) { // "DELETE FROM table" gives 0 affected rows in MySQL. // This little hack lets you know how many rows were deleted. if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $query)) { $query = preg_replace('/^\s*DELETE\s+FROM\s+(\S+)\s*$/', 'DELETE FROM \1 WHERE 1=1', $query); } } if ($limit > 0 && !preg_match('/LIMIT\s*\d(?:\s*(?:,|OFFSET)\s*\d+)?(?:[^\)]*)?$/i', $query) ) { $query = rtrim($query); if (substr($query, -1) == ';') { $query = substr($query, 0, -1); } // LIMIT doesn't always come last in the query // @see http://dev.mysql.com/doc/refman/5.0/en/select.html $after = ''; if (preg_match('/(\s+INTO\s+(?:OUT|DUMP)FILE\s.*)$/ims', $query, $matches)) { $after = $matches[0]; $query = preg_replace('/(\s+INTO\s+(?:OUT|DUMP)FILE\s.*)$/ims', '', $query); } elseif (preg_match('/(\s+FOR\s+UPDATE\s*)$/i', $query, $matches)) { $after = $matches[0]; $query = preg_replace('/(\s+FOR\s+UPDATE\s*)$/im', '', $query); } elseif (preg_match('/(\s+LOCK\s+IN\s+SHARE\s+MODE\s*)$/im', $query, $matches)) { $after = $matches[0]; $query = preg_replace('/(\s+LOCK\s+IN\s+SHARE\s+MODE\s*)$/im', '', $query); } if ($is_manip) { return $query . " LIMIT $limit" . $after; } else { return $query . " LIMIT $offset, $limit" . $after; } } return $query; } // }}} // {{{ getServerVersion() /** * return version information about the server * * @param bool $native determines if the raw version string should be returned * @return mixed array/string with version information or MDB2 error object * @access public */ function getServerVersion($native = false) { $connection = $this->getConnection(); if (PEAR::isError($connection)) { return $connection; } if ($this->connected_server_info) { $server_info = $this->connected_server_info; } else { $server_info = @mysql_get_server_info($connection); } if (!$server_info) { return $this->raiseError(null, null, null, 'Could not get server information', __FUNCTION__); } // cache server_info $this->connected_server_info = $server_info; if (!$native) { $tmp = explode('.', $server_info, 3); if (isset($tmp[2]) && strpos($tmp[2], '-')) { $tmp2 = explode('-', @$tmp[2], 2); } else { $tmp2[0] = isset($tmp[2]) ? $tmp[2] : null; $tmp2[1] = null; } $server_info = array( 'major' => isset($tmp[0]) ? $tmp[0] : null, 'minor' => isset($tmp[1]) ? $tmp[1] : null, 'patch' => $tmp2[0], 'extra' => $tmp2[1], 'native' => $server_info, ); } return $server_info; } // }}} // {{{ _getServerCapabilities() /** * Fetch some information about the server capabilities * (transactions, subselects, prepared statements, etc). * * @access private */ function _getServerCapabilities() { if (!$this->server_capabilities_checked) { $this->server_capabilities_checked = true; //set defaults $this->supported['sub_selects'] = 'emulated'; $this->supported['prepared_statements'] = 'emulated'; $this->supported['triggers'] = false; $this->start_transaction = false; $this->varchar_max_length = 255; $server_info = $this->getServerVersion(); if (is_array($server_info)) { $server_version = $server_info['major'].'.'.$server_info['minor'].'.'.$server_info['patch']; if (!version_compare($server_version, '4.1.0', '<')) { $this->supported['sub_selects'] = true; $this->supported['prepared_statements'] = true; } // SAVEPOINTs were introduced in MySQL 4.0.14 and 4.1.1 (InnoDB) if (version_compare($server_version, '4.1.0', '>=')) { if (version_compare($server_version, '4.1.1', '<')) { $this->supported['savepoints'] = false; } } elseif (version_compare($server_version, '4.0.14', '<')) { $this->supported['savepoints'] = false; } if (!version_compare($server_version, '4.0.11', '<')) { $this->start_transaction = true; } if (!version_compare($server_version, '5.0.3', '<')) { $this->varchar_max_length = 65532; } if (!version_compare($server_version, '5.0.2', '<')) { $this->supported['triggers'] = true; } } } } // }}} // {{{ function _skipUserDefinedVariable($query, $position) /** * Utility method, used by prepare() to avoid misinterpreting MySQL user * defined variables (SELECT @x:=5) for placeholders. * Check if the placeholder is a false positive, i.e. if it is an user defined * variable instead. If so, skip it and advance the position, otherwise * return the current position, which is valid * * @param string $query * @param integer $position current string cursor position * @return integer $new_position * @access protected */ function _skipUserDefinedVariable($query, $position) { $found = strpos(strrev(substr($query, 0, $position)), '@'); if ($found === false) { return $position; } $pos = strlen($query) - strlen(substr($query, $position)) - $found - 1; $substring = substr($query, $pos, $position - $pos + 2); if (preg_match('/^@\w+\s*:=$/', $substring)) { return $position + 1; //found an user defined variable: skip it } return $position; } // }}} // {{{ prepare() /** * Prepares a query for multiple execution with execute(). * With some database backends, this is emulated. * prepare() requires a generic query as string like * 'INSERT INTO numbers VALUES(?,?)' or * 'INSERT INTO numbers VALUES(:foo,:bar)'. * The ? and :name and are placeholders which can be set using * bindParam() and the query can be sent off using the execute() method. * The allowed format for :name can be set with the 'bindname_format' option. * * @param string $query the query to prepare
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -