59     var 
$string_quoting = array(
'start' => 
"'", 
'end' => 
"'", 
'escape' => 
'\\', 
'escape_pattern' => 
'\\');
 
   64         array(
'start' => 
'-- ', 
'end' => 
"\n", 
'escape' => 
false),
 
   65         array(
'start' => 
'#', 
'end' => 
"\n", 
'escape' => 
false),
 
   66         array(
'start' => 
'/*', 
'end' => 
'*/', 
'escape' => 
false),
 
   82         $this->phptype = 
'mysql';
 
   83         $this->dbsyntax = 
'mysql';
 
   85         $this->supported[
'sequences'] = 
'emulated';
 
   86         $this->supported[
'indexes'] = 
true;
 
   87         $this->supported[
'affected_rows'] = 
true;
 
   88         $this->supported[
'transactions'] = 
false;
 
   89         $this->supported[
'savepoints'] = 
false;
 
   90         $this->supported[
'summary_functions'] = 
true;
 
   91         $this->supported[
'order_by_text'] = 
true;
 
   92         $this->supported[
'current_id'] = 
'emulated';
 
   93         $this->supported[
'limit_queries'] = 
true;
 
   94         $this->supported[
'LOBs'] = 
true;
 
   95         $this->supported[
'replace'] = 
true;
 
   96         $this->supported[
'sub_selects'] = 
'emulated';
 
   97         $this->supported[
'auto_increment'] = 
true;
 
   98         $this->supported[
'primary_key'] = 
true;
 
   99         $this->supported[
'result_introspection'] = 
true;
 
  100         $this->supported[
'prepared_statements'] = 
'emulated';
 
  101         $this->supported[
'identifier_quoting'] = 
true;
 
  102         $this->supported[
'pattern_escaping'] = 
true;
 
  103         $this->supported[
'new_link'] = 
true;
 
  105         $this->options[
'default_table_type'] = 
'';
 
  120         if ($this->connection) {
 
  121             $native_code = @mysql_errno($this->connection);
 
  122             $native_msg  = @mysql_error($this->connection);
 
  124             $native_code = @mysql_errno();
 
  125             $native_msg  = @mysql_error();
 
  127         if (is_null($error)) {
 
  129             if (empty($ecode_map)) {
 
  169             if (isset($ecode_map[$native_code])) {
 
  170                 $error = $ecode_map[$native_code];
 
  173         return array($error, $native_code, $native_msg);
 
  190     function escape($text, $escape_wildcards = 
false)
 
  192         if ($escape_wildcards) {
 
  199         $text = @mysql_real_escape_string($text, 
$connection);
 
  216         $this->
debug(
'Starting transaction/savepoint', __FUNCTION__, array(
'is_manip' => 
true, 
'savepoint' => $savepoint));
 
  218         if (!is_null($savepoint)) {
 
  219             if (!$this->
supports(
'savepoints')) {
 
  221                     'savepoints are not supported', __FUNCTION__);
 
  223             if (!$this->in_transaction) {
 
  225                     'savepoint cannot be released when changes are auto committed', __FUNCTION__);
 
  227             $query = 
'SAVEPOINT '.$savepoint;
 
  229         } elseif ($this->in_transaction) {
 
  232         if (!$this->destructor_registered && $this->opened_persistent) {
 
  233             $this->destructor_registered = 
true;
 
  234             register_shutdown_function(
'MDB2_closeOpenTransactions');
 
  236         $query = $this->start_transaction ? 
'START TRANSACTION' : 
'SET AUTOCOMMIT = 1';
 
  241         $this->in_transaction = 
true;
 
  261         $this->
debug(
'Committing transaction/savepoint', __FUNCTION__, array(
'is_manip' => 
true, 
'savepoint' => $savepoint));
 
  262         if (!$this->in_transaction) {
 
  264                 'commit/release savepoint cannot be done changes are auto committed', __FUNCTION__);
 
  266         if (!is_null($savepoint)) {
 
  267             if (!$this->
supports(
'savepoints')) {
 
  269                     'savepoints are not supported', __FUNCTION__);
 
  272             if (version_compare($server_info[
'major'].
'.'.$server_info[
'minor'].
'.'.$server_info[
'patch'], 
'5.0.3', 
'<')) {
 
  275             $query = 
'RELEASE SAVEPOINT '.$savepoint;
 
  279         if (!$this->
supports(
'transactions')) {
 
  281                 'transactions are not supported', __FUNCTION__);
 
  288         if (!$this->start_transaction) {
 
  289             $query = 
'SET AUTOCOMMIT = 0';
 
  295         $this->in_transaction = 
false;
 
  315         $this->
debug(
'Rolling back transaction/savepoint', __FUNCTION__, array(
'is_manip' => 
true, 
'savepoint' => $savepoint));
 
  316         if (!$this->in_transaction) {
 
  318                 'rollback cannot be done changes are auto committed', __FUNCTION__);
 
  320         if (!is_null($savepoint)) {
 
  321             if (!$this->
supports(
'savepoints')) {
 
  323                     'savepoints are not supported', __FUNCTION__);
 
  325             $query = 
'ROLLBACK TO SAVEPOINT '.$savepoint;
 
  334         if (!$this->start_transaction) {
 
  335             $query = 
'SET AUTOCOMMIT = 0';
 
  341         $this->in_transaction = 
false;
 
  363         $this->
debug(
'Setting transaction isolation level', __FUNCTION__, array(
'is_manip' => 
true));
 
  364         if (!$this->
supports(
'transactions')) {
 
  366                 'transactions are not supported', __FUNCTION__);
 
  368         switch ($isolation) {
 
  369         case 'READ UNCOMMITTED':
 
  370         case 'READ COMMITTED':
 
  371         case 'REPEATABLE READ':
 
  376                 'isolation level is not supported: '.$isolation, __FUNCTION__);
 
  379         $query = 
"SET SESSION TRANSACTION ISOLATION LEVEL $isolation";
 
  393         if (is_resource($this->connection)) {
 
  395             #if (count(array_diff($this->connected_dsn, $this->dsn)) == 0 
  396             if($this->connected_dsn == $this->dsn
 
  397                 && $this->opened_persistent == $this->options[
'persistent']
 
  398                 && $this->connected_database_name == $this->database_name
 
  407                 'extension '.$this->phptype.
' is not compiled into PHP', __FUNCTION__);
 
  411         if ($this->dsn[
'protocol'] && $this->dsn[
'protocol'] == 
'unix') {
 
  412             $params[0] = 
':' . $this->dsn[
'socket'];
 
  414             $params[0] = $this->dsn[
'hostspec'] ? $this->dsn[
'hostspec']
 
  416             if ($this->dsn[
'port']) {
 
  417                 $params[0].= 
':' . $this->dsn[
'port'];
 
  420         $params[] = $this->dsn[
'username'] ? $this->dsn[
'username'] : null;
 
  421         $params[] = $this->dsn[
'password'] ? $this->dsn[
'password'] : null;
 
  422         if (!$this->options[
'persistent']) {
 
  423             if (isset($this->dsn[
'new_link'])
 
  424                 && ($this->dsn[
'new_link'] == 
'true' || $this->dsn[
'new_link'] === 
true)
 
  431         if (version_compare(phpversion(), 
'4.3.0', 
'>=')) {
 
  432             $params[] = isset($this->dsn[
'client_flags'])
 
  433                 ? $this->dsn[
'client_flags'] : null;
 
  435         $connect_function = $this->options[
'persistent'] ? 
'mysql_pconnect' : 
'mysql_connect';
 
  437         $connection = @call_user_func_array($connect_function, $params);
 
  439             if (($err = @mysql_error()) != 
'') {
 
  444                     'unable to establish a connection', __FUNCTION__);
 
  448         if (!empty($this->dsn[
'charset'])) {
 
  457         $this->connected_database_name = 
'';
 
  458         $this->opened_persistent = $this->options[
'persistent'];
 
  459         $this->dbsyntax = $this->dsn[
'dbsyntax'] ? $this->dsn[
'dbsyntax'] : 
$this->phptype;
 
  461         if ($this->database_name) {
 
  462             if ($this->database_name != $this->connected_database_name) {
 
  463                 if (!@mysql_select_db($this->database_name, 
$connection)) {
 
  465                         'Could not select the database: '.$this->database_name, __FUNCTION__);
 
  472         $this->supported[
'transactions'] = $this->options[
'use_transactions'];
 
  473         if ($this->options[
'default_table_type']) {
 
  474             switch (strtoupper($this->options[
'default_table_type'])) {
 
  486                 $this->supported[
'transactions'] = 
false;
 
  487                 $this->warnings[] = $this->options[
'default_table_type'] .
 
  488                     ' is not a supported default table type';
 
  535         if (is_resource($this->connection)) {
 
  536             if ($this->in_transaction) {
 
  539                 $persistent = $this->options[
'persistent'];
 
  546                 $this->options[
'persistent'] = $persistent;
 
  549             if (!$this->opened_persistent || $force) {
 
  550                 @mysql_close($this->connection);
 
  570         $this->last_query = 
$query;
 
  571         $result = $this->
debug(
$query, 
'query', array(
'is_manip' => $is_manip, 
'when' => 
'pre'));
 
  578         if ($this->options[
'disable_query']) {
 
  579             $result = $is_manip ? 0 : null;
 
  604         $function = $this->options[
'result_buffering']
 
  605             ? 
'mysql_query' : 
'mysql_unbuffered_query';
 
  609                 'Could not execute statement', __FUNCTION__);
 
  613         $this->
debug(
$query, 
'query', array(
'is_manip' => $is_manip, 
'when' => 
'post', 
'result' => 
$result));
 
  657             if (preg_match(
'/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', 
$query)) {
 
  658                 $query = preg_replace(
'/^\s*DELETE\s+FROM\s+(\S+)\s*$/',
 
  659                                       'DELETE FROM \1 WHERE 1=1', 
$query);
 
  663             && !preg_match(
'/LIMIT\s*\d(?:\s*(?:,|OFFSET)\s*\d+)?(?:[^\)]*)?$/i', 
$query)
 
  666             if (substr(
$query, -1) == 
';') {
 
  673             if (preg_match(
'/(\s+INTO\s+(?:OUT|DUMP)FILE\s.*)$/ims', 
$query, $matches)) {
 
  674                 $after = $matches[0];
 
  675                 $query = preg_replace(
'/(\s+INTO\s+(?:OUT|DUMP)FILE\s.*)$/ims', 
'', 
$query);
 
  676             } elseif (preg_match(
'/(\s+FOR\s+UPDATE\s*)$/i', 
$query, $matches)) {
 
  677                $after = $matches[0];
 
  678                $query = preg_replace(
'/(\s+FOR\s+UPDATE\s*)$/im', 
'', 
$query);
 
  679             } elseif (preg_match(
'/(\s+LOCK\s+IN\s+SHARE\s+MODE\s*)$/im', 
$query, $matches)) {
 
  680                $after = $matches[0];
 
  681                $query = preg_replace(
'/(\s+LOCK\s+IN\s+SHARE\s+MODE\s*)$/im', 
'', 
$query);
 
  685                 return $query . 
" LIMIT $limit" . $after;
 
  687                 return $query . 
" LIMIT $offset, $limit" . $after;
 
  709         if ($this->connected_server_info) {
 
  712             $server_info = @mysql_get_server_info(
$connection);
 
  716                 'Could not get server information', __FUNCTION__);
 
  719         $this->connected_server_info = $server_info;
 
  721             $tmp = explode(
'.', $server_info, 3);
 
  722             if (isset($tmp[2]) && strpos($tmp[2], 
'-')) {
 
  723                 $tmp2 = explode(
'-', @$tmp[2], 2);
 
  725                 $tmp2[0] = isset($tmp[2]) ? $tmp[2] : null;
 
  728             $server_info = array(
 
  729                 'major' => isset($tmp[0]) ? $tmp[0] : null,
 
  730                 'minor' => isset($tmp[1]) ? $tmp[1] : null,
 
  733                 'native' => $server_info,
 
  750         static $already_checked = 
false;
 
  751         if (!$already_checked) {
 
  752             $already_checked = 
true;
 
  755             $this->supported[
'sub_selects'] = 
'emulated';
 
  756             $this->supported[
'prepared_statements'] = 
'emulated';
 
  757             $this->start_transaction = 
false;
 
  758             $this->varchar_max_length = 255;
 
  761             if (is_array($server_info)) {
 
  762                 if (!version_compare($server_info[
'major'].
'.'.$server_info[
'minor'].
'.'.$server_info[
'patch'], 
'4.1.0', 
'<')) {
 
  763                     $this->supported[
'sub_selects'] = 
true;
 
  764                     $this->supported[
'prepared_statements'] = 
true;
 
  767                 if (!version_compare($server_info[
'major'].
'.'.$server_info[
'minor'].
'.'.$server_info[
'patch'], 
'4.0.14', 
'<')
 
  768                     || !version_compare($server_info[
'major'].
'.'.$server_info[
'minor'].
'.'.$server_info[
'patch'], 
'4.1.1', 
'<')
 
  770                     $this->supported[
'savepoints'] = 
true;
 
  773                 if (!version_compare($server_info[
'major'].
'.'.$server_info[
'minor'].
'.'.$server_info[
'patch'], 
'4.0.11', 
'<')) {
 
  774                     $this->start_transaction = 
true;
 
  777                 if (!version_compare($server_info[
'major'].
'.'.$server_info[
'minor'].
'.'.$server_info[
'patch'], 
'5.0.3', 
'<')) {
 
  778                     $this->varchar_max_length = 65532;
 
  801         $found = strpos(strrev(substr(
$query, 0, $position)), 
'@');
 
  802         if ($found === 
false) {
 
  805         $pos = strlen(
$query) - strlen(substr(
$query, $position)) - $found - 1;
 
  806         $substring = substr(
$query, $pos, $position - $pos + 2);
 
  807         if (preg_match(
'/^@\w+:=$/', $substring)) {
 
  808             return $position + 1; 
 
  836     function &
prepare(
$query, $types = null, $result_types = null, $lobs = array())
 
  838         if ($this->options[
'emulate_prepared']
 
  839             || $this->supported[
'prepared_statements'] !== 
true 
  847         $this->offset = $this->limit = 0;
 
  849         $result = $this->
debug(
$query, __FUNCTION__, array(
'is_manip' => $is_manip, 
'when' => 
'pre'));
 
  856         $placeholder_type_guess = $placeholder_type = null;
 
  859         $positions = array();
 
  861         while ($position < strlen(
$query)) {
 
  862             $q_position = strpos(
$query, $question, $position);
 
  863             $c_position = strpos(
$query, $colon, $position);
 
  864             if ($q_position && $c_position) {
 
  865                 $p_position = min($q_position, $c_position);
 
  866             } elseif ($q_position) {
 
  867                 $p_position = $q_position;
 
  868             } elseif ($c_position) {
 
  869                 $p_position = $c_position;
 
  873             if (is_null($placeholder_type)) {
 
  874                 $placeholder_type_guess = 
$query[$p_position];
 
  881             if ($new_pos != $position) {
 
  882                 $position = $new_pos;
 
  886             if (
$query[$position] == $placeholder_type_guess) {
 
  887                 if (is_null($placeholder_type)) {
 
  888                     $placeholder_type = 
$query[$p_position];
 
  889                     $question = $colon = $placeholder_type;
 
  891                 if ($placeholder_type == 
':') {
 
  894                     if ($new_pos != $position) {
 
  895                         $position = $new_pos;
 
  898                     $parameter = preg_replace(
'/^.{'.($position+1).
'}([a-z0-9_]+).*$/si', 
'\\1', 
$query);
 
  899                     if ($parameter === 
'') {
 
  901                             'named parameter with an empty name', __FUNCTION__);
 
  904                     $positions[$p_position] = $parameter;
 
  905                     $query = substr_replace(
$query, 
'?', $position, strlen($parameter)+1);
 
  907                     $positions[$p_position] = count($positions);
 
  909                 $position = $p_position + 1;
 
  911                 $position = $p_position;
 
  918         $statement_name = sprintf($this->options[
'statement_format'], $this->phptype, md5(time() + rand()));
 
  919         $query = 
"PREPARE $statement_name FROM ".$this->quote(
$query, 
'text');
 
  925         $class_name = 
'MDB2_Statement_'.$this->phptype;
 
  926         $obj =& 
new $class_name($this, $statement_name, $positions, 
$query, $types, $result_types, $is_manip, 
$limit, 
$offset);
 
  927         $this->
debug(
$query, __FUNCTION__, array(
'is_manip' => $is_manip, 
'when' => 
'post', 
'result' => $obj));
 
 1000         $count = count($fields);
 
 1002         $keys = $colnum = 0;
 
 1003         for (reset($fields); $colnum < $count; next($fields), $colnum++) {
 
 1004             $name = key($fields);
 
 1010             if (isset($fields[$name][
'null']) && $fields[$name][
'null']) {
 
 1013                 $type = isset($fields[$name][
'type']) ? $fields[$name][
'type'] : null;
 
 1014                 $value = $this->
quote($fields[$name][
'value'], $type);
 
 1017             if (isset($fields[$name][
'key']) && $fields[$name][
'key']) {
 
 1018                 if ($value === 
'NULL') {
 
 1020                         'key value '.$name.
' may not be NULL', __FUNCTION__);
 
 1027                 'not specified which fields are keys', __FUNCTION__);
 
 1035         $query = 
"REPLACE INTO $table ($query) VALUES ($values)";
 
 1060         $seqcol_name = $this->
quoteIdentifier($this->options[
'seqcol_name'], 
true);
 
 1061         $query = 
"INSERT INTO $sequence_name ($seqcol_name) VALUES (NULL)";
 
 1068                 $result = $this->manager->createSequence($seq_name);
 
 1071                         'on demand sequence '.$seq_name.
' could not be created', __FUNCTION__);
 
 1073                     return $this->
nextID($seq_name, 
false);
 
 1079         if (is_numeric($value)) {
 
 1080             $query = 
"DELETE FROM $sequence_name WHERE $seqcol_name < $value";
 
 1083                 $this->warnings[] = 
'nextID: could not delete previous sequence table values from '.$seq_name;
 
 1104         return $this->
queryOne(
'SELECT LAST_INSERT_ID()', 
'integer');
 
 1120         $seqcol_name = $this->
quoteIdentifier($this->options[
'seqcol_name'], 
true);
 
 1121         $query = 
"SELECT MAX($seqcol_name) FROM $sequence_name";
 
 1155             $fetchmode = $this->db->fetchmode;
 
 1158             $row = @mysql_fetch_assoc($this->result);
 
 1162                 $row = array_change_key_case(
$row, $this->db->options[
'field_case']);
 
 1165            $row = @mysql_fetch_row($this->result);
 
 1169             if ($this->result === 
false) {
 
 1171                     'resultset has already been freed', __FUNCTION__);
 
 1179             $this->db->_fixResultArrayValues(
$row, $mode);
 
 1181         if (!empty($this->types)) {
 
 1182             $row = $this->db->datatype->convertResultRow($this->types, 
$row, 
false);
 
 1184         if (!empty($this->values)) {
 
 1188             $object_class = $this->db->options[
'fetch_class'];
 
 1189             if ($object_class == 
'stdClass') {
 
 1218         for ($column = 0; $column < $numcols; $column++) {
 
 1219             $column_name = @mysql_field_name($this->result, $column);
 
 1223             $columns = array_change_key_case(
$columns, $this->db->options[
'field_case']);
 
 1240         $cols = @mysql_num_fields($this->result);
 
 1241         if (is_null($cols)) {
 
 1242             if ($this->result === 
false) {
 
 1244                     'resultset has already been freed', __FUNCTION__);
 
 1245             } elseif (is_null($this->result)) {
 
 1246                 return count($this->types);
 
 1248             return $this->db->raiseError(null, null, null,
 
 1249                 'Could not get column count', __FUNCTION__);
 
 1265         if (is_resource($this->result) && $this->db->connection) {
 
 1266             $free = @mysql_free_result($this->result);
 
 1267             if ($free === 
false) {
 
 1268                 return $this->db->raiseError(null, null, null,
 
 1269                     'Could not free result', __FUNCTION__);
 
 1272         $this->result = 
false;
 
 1298         if ($this->rownum != (
$rownum - 1) && !@mysql_data_seek($this->result, 
$rownum)) {
 
 1299             if ($this->result === 
false) {
 
 1301                     'resultset has already been freed', __FUNCTION__);
 
 1302             } elseif (is_null($this->result)) {
 
 1306                 'tried to seek to an invalid row number ('.
$rownum.
')', __FUNCTION__);
 
 1327         return $this->rownum < ($numrows - 1);
 
 1341         $rows = @mysql_num_rows($this->result);
 
 1342         if (is_null($rows)) {
 
 1343             if ($this->result === 
false) {
 
 1345                     'resultset has already been freed', __FUNCTION__);
 
 1346             } elseif (is_null($this->result)) {
 
 1349             return $this->db->raiseError(null, null, null,
 
 1350                 'Could not get row count', __FUNCTION__);
 
 1375     function &
_execute($result_class = 
true, $result_wrap_class = 
false)
 
 1377         if (is_null($this->statement)) {
 
 1382         $this->db->debug($this->query, 
'execute', array(
'is_manip' => $this->is_manip, 
'when' => 
'pre', 
'parameters' => $this->values));
 
 1383         if ($this->db->getOption(
'disable_query')) {
 
 1384             $result = $this->is_manip ? 0 : null;
 
 1388         $connection = $this->db->getConnection();
 
 1393         $query = 
'EXECUTE '.$this->statement;
 
 1394         if (!empty($this->positions)) {
 
 1395             $parameters = array();
 
 1396             foreach ($this->positions as $parameter) {
 
 1397                 if (!array_key_exists($parameter, $this->values)) {
 
 1399                         'Unable to bind to missing placeholder: '.$parameter, __FUNCTION__);
 
 1401                 $value = $this->values[$parameter];
 
 1402                 $type = array_key_exists($parameter, $this->types) ? $this->types[$parameter] : null;
 
 1403                 if (is_resource($value) || $type == 
'clob' || $type == 
'blob') {
 
 1404                     if (!is_resource($value) && preg_match(
'/^(\w+:\/\/)(.*)$/', $value, $match)) {
 
 1405                         if ($match[1] == 
'file://') {
 
 1408                         $value = @fopen($value, 
'r');
 
 1411                     if (is_resource($value)) {
 
 1413                         while (!@feof($value)) {
 
 1414                             $data.= @fread($value, $this->db->options[
'lob_buffer_length']);
 
 1422                 $quoted = $this->db->quote($value, $type);
 
 1426                 $param_query = 
'SET @'.$parameter.
' = '.$quoted;
 
 1427                 $result = $this->db->_doQuery($param_query, 
true, $connection);
 
 1432             $query.= 
' USING @'.implode(
', @', array_values($this->positions));
 
 1435         $result = $this->db->_doQuery(
$query, $this->is_manip, $connection);
 
 1440         if ($this->is_manip) {
 
 1441             $affected_rows = $this->db->_affectedRows($connection, 
$result);
 
 1442             return $affected_rows;
 
 1446             $result_class, $result_wrap_class, $this->limit, $this->offset);
 
 1447         $this->db->debug($this->query, 
'execute', array(
'is_manip' => $this->is_manip, 
'when' => 
'post', 
'result' => 
$result));
 
 1462         if (is_null($this->positions)) {
 
 1463             return $this->db->raiseError(
MDB2_ERROR, null, null,
 
 1464                 'Prepared statement has already been freed', __FUNCTION__);
 
 1468         if (!is_null($this->statement)) {
 
 1469             $connection = $this->db->getConnection();
 
 1473             $query = 
'DEALLOCATE PREPARE '.$this->statement;