16 if (!defined(
'ADODB_DIR'))
die();
18 if (! defined(
"_ADODB_MYSQL_LAYER")) {
19 define(
"_ADODB_MYSQL_LAYER", 1 );
21 class ADODB_mysql
extends ADOConnection {
22 var $databaseType =
'mysql';
23 var $dataProvider =
'mysql';
24 var $hasInsertID =
true;
25 var $hasAffectedRows =
true;
26 var $metaTablesSQL =
"SELECT 28 CASE WHEN TABLE_TYPE = 'VIEW' THEN 'V' ELSE 'T' END 29 FROM INFORMATION_SCHEMA.TABLES 31 var $metaColumnsSQL =
"SHOW COLUMNS FROM `%s`";
32 var $fmtTimeStamp =
"'Y-m-d H:i:s'";
34 var $hasMoveFirst =
true;
37 var $sysDate =
'CURDATE()';
38 var $sysTimeStamp =
'NOW()';
39 var $hasTransactions =
false;
40 var $forceNewConnect =
false;
41 var $poorAffectedRows =
true;
44 var $substr =
"substring";
46 var $compat323 =
false;
48 function ADODB_mysql()
50 if (defined(
'ADODB_EXTENSION')) $this->rsPrefix .=
'ext_';
55 function SetCharSet($charset_name)
57 if (!function_exists(
'mysql_set_charset'))
60 if ($this->charSet !== $charset_name) {
61 $ok = @mysql_set_charset($charset_name,$this->_connectionID);
63 $this->charSet = $charset_name;
73 $arr[
'description'] = ADOConnection::GetOne(
"select version()");
74 $arr[
'version'] = ADOConnection::_findvers($arr[
'description']);
78 function IfNull( $field, $ifNull )
80 return " IFNULL($field, $ifNull) ";
83 function MetaProcedures($NamePattern =
false, $catalog = null, $schemaPattern = null)
86 global $ADODB_FETCH_MODE;
89 $save = $ADODB_FETCH_MODE;
90 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
92 if ($this->fetchMode !== FALSE) {
93 $savem = $this->SetFetchMode(FALSE);
96 $procedures = array ();
102 $likepattern =
" LIKE '".$NamePattern.
"'";
104 $rs = $this->Execute(
'SHOW PROCEDURE STATUS'.$likepattern);
105 if (is_object(
$rs)) {
108 while ($row =
$rs->FetchRow()) {
109 $procedures[$row[1]] = array(
110 'type' =>
'PROCEDURE',
114 'remarks' => $row[7],
119 $rs = $this->Execute(
'SHOW FUNCTION STATUS'.$likepattern);
120 if (is_object(
$rs)) {
122 while ($row =
$rs->FetchRow()) {
123 $procedures[$row[1]] = array(
124 'type' =>
'FUNCTION',
134 $this->SetFetchMode($savem);
137 $ADODB_FETCH_MODE = $save;
152 function MetaTables($ttype=
false,$showSchema=
false,$mask=
false)
154 $save = $this->metaTablesSQL;
155 if ($showSchema && is_string($showSchema)) {
156 $this->metaTablesSQL .= $this->qstr($showSchema);
158 $this->metaTablesSQL .=
"schema()";
162 $mask = $this->qstr($mask);
163 $this->metaTablesSQL .=
" AND table_name LIKE $mask";
165 $ret = ADOConnection::MetaTables($ttype,$showSchema);
167 $this->metaTablesSQL = $save;
172 function MetaIndexes ($table, $primary = FALSE, $owner=
false)
175 global $ADODB_FETCH_MODE;
178 $save = $ADODB_FETCH_MODE;
179 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
180 if ($this->fetchMode !== FALSE) {
181 $savem = $this->SetFetchMode(FALSE);
185 $rs = $this->Execute(sprintf(
'SHOW INDEX FROM %s',$table));
189 $this->SetFetchMode($savem);
191 $ADODB_FETCH_MODE = $save;
193 if (!is_object(
$rs)) {
200 while ($row =
$rs->FetchRow()) {
201 if ($primary == FALSE AND $row[2] ==
'PRIMARY') {
205 if (!isset($indexes[$row[2]])) {
206 $indexes[$row[2]] = array(
207 'unique' => ($row[1] == 0),
212 $indexes[$row[2]][
'columns'][$row[3] - 1] = $row[4];
216 foreach ( array_keys ($indexes) as $index )
218 ksort ($indexes[$index][
'columns']);
226 function qstr($s,$magic_quotes=
false)
228 if (is_null($s))
return 'NULL';
229 if (!$magic_quotes) {
231 if (ADODB_PHPVER >= 0x4300) {
232 if (is_resource($this->_connectionID))
233 return "'".mysql_real_escape_string($s,$this->_connectionID).
"'";
235 if ($this->replaceQuote[0] ==
'\\'){
236 $s = adodb_str_replace(array(
'\\',
"\0"),array(
'\\\\',
"\\\0"),$s);
238 return "'".str_replace(
"'",$this->replaceQuote,$s).
"'";
242 $s = str_replace(
'\\"',
'"',$s);
248 return ADOConnection::GetOne(
'SELECT LAST_INSERT_ID()');
252 function GetOne(
$sql,$inputarr=
false)
254 global $ADODB_GETONE_EOF;
255 if ($this->compat323 ==
false && strncasecmp(
$sql,
'sele',4) == 0) {
256 $rs = $this->SelectLimit(
$sql,1,-1,$inputarr);
259 if (
$rs->EOF)
return $ADODB_GETONE_EOF;
260 return reset(
$rs->fields);
263 return ADOConnection::GetOne(
$sql,$inputarr);
268 function BeginTrans()
270 if ($this->
debug) ADOConnection::outp(
"Transactions not supported in 'mysql' driver. Use 'mysqlt' or 'mysqli' driver");
273 function _affectedrows()
275 return mysql_affected_rows($this->_connectionID);
280 var $_genIDSQL =
"update %s set id=LAST_INSERT_ID(id+1);";
281 var $_genSeqSQL =
"create table %s (id int not null)";
282 var $_genSeqCountSQL =
"select count(*) from %s";
283 var $_genSeq2SQL =
"insert into %s values (%s)";
284 var $_dropSeqSQL =
"drop table %s";
286 function CreateSequence($seqname=
'adodbseq',$startID=1)
288 if (empty($this->_genSeqSQL))
return false;
289 $u = strtoupper($seqname);
291 $ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname));
292 if (!$ok)
return false;
293 return $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
297 function GenID($seqname=
'adodbseq',$startID=1)
300 if (!$this->hasGenID)
return false;
302 $savelog = $this->_logsql;
303 $this->_logsql =
false;
304 $getnext = sprintf($this->_genIDSQL,$seqname);
305 $holdtransOK = $this->_transOK;
306 $rs = @$this->Execute($getnext);
308 if ($holdtransOK) $this->_transOK =
true;
309 $u = strtoupper($seqname);
310 $this->Execute(sprintf($this->_genSeqSQL,$seqname));
311 $cnt = $this->GetOne(sprintf($this->_genSeqCountSQL,$seqname));
312 if (!$cnt) $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
313 $rs = $this->Execute($getnext);
317 $this->genID = mysql_insert_id($this->_connectionID);
322 $this->_logsql = $savelog;
326 function MetaDatabases()
328 $qid = mysql_list_dbs($this->_connectionID);
331 $max = mysql_num_rows($qid);
333 $db = mysql_tablename($qid,$i);
334 if ($db !=
'mysql') $arr[] = $db;
342 function SQLDate($fmt, $col=
false)
344 if (!$col) $col = $this->sysTimeStamp;
345 $s =
'DATE_FORMAT('.$col.
",'";
348 for ($i=0; $i < $len; $i++) {
355 $ch = substr($fmt,$i,1);
381 $s .=
"'),Quarter($col)";
383 if ($len > $i+1) $s .=
",DATE_FORMAT($col,'";
423 if ($concat) $s =
"CONCAT($s)";
433 $arr = func_get_args();
436 $s = implode(
',',$arr);
437 if (strlen($s) > 0)
return "CONCAT($s)";
441 function OffsetDate($dayFraction,$date=
false)
443 if (!$date) $date = $this->sysDate;
445 $fraction = $dayFraction * 24 * 3600;
446 return '('. $date .
' + INTERVAL ' . $fraction.
' SECOND)';
452 function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
454 if (!empty($this->port)) $argHostname .=
":".$this->port;
456 if (ADODB_PHPVER >= 0x4300)
457 $this->_connectionID = mysql_connect($argHostname,$argUsername,$argPassword,
458 $this->forceNewConnect,$this->clientFlags);
459 else if (ADODB_PHPVER >= 0x4200)
460 $this->_connectionID = mysql_connect($argHostname,$argUsername,$argPassword,
461 $this->forceNewConnect);
463 $this->_connectionID = mysql_connect($argHostname,$argUsername,$argPassword);
465 if ($this->_connectionID ===
false)
return false;
466 if ($argDatabasename)
return $this->SelectDB($argDatabasename);
471 function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
473 if (!empty($this->port)) $argHostname .=
":".$this->port;
475 if (ADODB_PHPVER >= 0x4300)
476 $this->_connectionID = mysql_pconnect($argHostname,$argUsername,$argPassword,$this->clientFlags);
478 $this->_connectionID = mysql_pconnect($argHostname,$argUsername,$argPassword);
479 if ($this->_connectionID ===
false)
return false;
480 if ($this->autoRollback) $this->RollbackTrans();
481 if ($argDatabasename)
return $this->SelectDB($argDatabasename);
485 function _nconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
487 $this->forceNewConnect =
true;
488 return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename);
491 function MetaColumns($table, $normalize=
true)
493 $this->_findschema($table,$schema);
496 $this->SelectDB($schema);
498 global $ADODB_FETCH_MODE;
499 $save = $ADODB_FETCH_MODE;
500 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
502 if ($this->fetchMode !==
false) $savem = $this->SetFetchMode(
false);
503 $rs = $this->Execute(sprintf($this->metaColumnsSQL,$table));
506 $this->SelectDB($dbName);
509 if (isset($savem)) $this->SetFetchMode($savem);
510 $ADODB_FETCH_MODE = $save;
511 if (!is_object(
$rs)) {
518 $fld =
new ADOFieldObject();
519 $fld->name =
$rs->fields[0];
520 $type =
$rs->fields[1];
524 if (preg_match(
"/^(.+)\((\d+),(\d+)/", $type, $query_array)) {
525 $fld->type = $query_array[1];
526 $fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1;
527 $fld->scale = is_numeric($query_array[3]) ? $query_array[3] : -1;
528 } elseif (preg_match(
"/^(.+)\((\d+)/", $type, $query_array)) {
529 $fld->type = $query_array[1];
530 $fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1;
531 } elseif (preg_match(
"/^(enum)\((.*)\)$/i", $type, $query_array)) {
532 $fld->type = $query_array[1];
533 $arr = explode(
",",$query_array[2]);
535 $zlen = max(array_map(
"strlen",$arr)) - 2;
536 $fld->max_length = ($zlen > 0) ? $zlen : 1;
539 $fld->max_length = -1;
541 $fld->not_null = (
$rs->fields[2] !=
'YES');
542 $fld->primary_key = (
$rs->fields[3] ==
'PRI');
543 $fld->auto_increment = (strpos(
$rs->fields[5],
'auto_increment') !==
false);
544 $fld->binary = (strpos($type,
'blob') !==
false || strpos($type,
'binary') !==
false);
545 $fld->unsigned = (strpos($type,
'unsigned') !==
false);
546 $fld->zerofill = (strpos($type,
'zerofill') !==
false);
550 if ($d !=
'' && $d !=
'NULL') {
551 $fld->has_default =
true;
552 $fld->default_value = $d;
554 $fld->has_default =
false;
558 if ($save == ADODB_FETCH_NUM) {
561 $retarr[strtoupper($fld->name)] = $fld;
571 function SelectDB($dbName)
573 $this->database = $dbName;
574 $this->databaseName = $dbName; # obsolete, retained
for compat with older adodb versions
575 if ($this->_connectionID) {
576 return @mysql_select_db($dbName,$this->_connectionID);
582 function SelectLimit(
$sql,$nrows=-1,$offset=-1,$inputarr=
false,$secs=0)
584 $offsetStr =($offset>=0) ? ((integer)$offset).
"," :
'';
586 if ($nrows < 0) $nrows =
'18446744073709551615';
589 $rs = $this->CacheExecute($secs,
$sql.
" LIMIT $offsetStr".((integer)$nrows),$inputarr);
591 $rs = $this->Execute(
$sql.
" LIMIT $offsetStr".((integer)$nrows),$inputarr);
596 function _query(
$sql,$inputarr=
false)
599 return mysql_query(
$sql,$this->_connectionID);
613 if ($this->_logsql)
return $this->_errorMsg;
614 if (empty($this->_connectionID)) $this->_errorMsg = @mysql_error();
615 else $this->_errorMsg = @mysql_error($this->_connectionID);
616 return $this->_errorMsg;
622 if ($this->_logsql)
return $this->_errorCode;
623 if (empty($this->_connectionID))
return @mysql_errno();
624 else return @mysql_errno($this->_connectionID);
630 @mysql_close($this->_connectionID);
633 $this->_connectionID =
false;
654 function MetaForeignKeys( $table, $owner = FALSE, $upper = FALSE, $associative = FALSE )
656 global $ADODB_FETCH_MODE;
657 if ($ADODB_FETCH_MODE == ADODB_FETCH_ASSOC || $this->fetchMode == ADODB_FETCH_ASSOC) $associative =
true;
659 if ( !empty($owner) ) {
660 $table =
"$owner.$table";
662 $a_create_table = $this->getRow(sprintf(
'SHOW CREATE TABLE %s', $table));
664 $create_sql = isset($a_create_table[
"Create Table"]) ? $a_create_table[
"Create Table"] : $a_create_table[
"Create View"];
665 }
else $create_sql = $a_create_table[1];
669 if (!preg_match_all(
"/FOREIGN KEY \(`(.*?)`\) REFERENCES `(.*?)` \(`(.*?)`\)/", $create_sql, $matches))
return false;
670 $foreign_keys = array();
671 $num_keys = count($matches[0]);
672 for ( $i = 0; $i < $num_keys; $i ++ ) {
673 $my_field = explode(
'`, `', $matches[1][$i]);
674 $ref_table = $matches[2][$i];
675 $ref_field = explode(
'`, `', $matches[3][$i]);
678 $ref_table = strtoupper($ref_table);
682 if (!isset($foreign_keys[$ref_table])) {
683 $foreign_keys[$ref_table] = array();
685 $num_fields = count($my_field);
686 for ( $j = 0; $j < $num_fields; $j ++ ) {
687 if ( $associative ) {
688 $foreign_keys[$ref_table][$ref_field[$j]] = $my_field[$j];
690 $foreign_keys[$ref_table][] =
"{$my_field[$j]}={$ref_field[$j]}";
695 return $foreign_keys;
706 class ADORecordSet_mysql
extends ADORecordSet{
708 var $databaseType =
"mysql";
711 function ADORecordSet_mysql($queryID,$mode=
false)
713 if ($mode ===
false) {
714 global $ADODB_FETCH_MODE;
715 $mode = $ADODB_FETCH_MODE;
719 case ADODB_FETCH_NUM: $this->fetchMode = MYSQL_NUM;
break;
720 case ADODB_FETCH_ASSOC:$this->fetchMode = MYSQL_ASSOC;
break;
721 case ADODB_FETCH_DEFAULT:
722 case ADODB_FETCH_BOTH:
724 $this->fetchMode = MYSQL_BOTH;
break;
726 $this->adodbFetchMode = $mode;
727 $this->ADORecordSet($queryID);
734 $this->_numOfRows = @mysql_num_rows($this->_queryID);
735 $this->_numOfFields = @mysql_num_fields($this->_queryID);
738 function FetchField($fieldOffset = -1)
740 if ($fieldOffset != -1) {
741 $o = @mysql_fetch_field($this->_queryID, $fieldOffset);
742 $f = @mysql_field_flags($this->_queryID,$fieldOffset);
743 if ($o) $o->max_length = @mysql_field_len($this->_queryID,$fieldOffset);
745 if ($o) $o->binary = (strpos($f,
'binary')!==
false);
748 $o = @mysql_fetch_field($this->_queryID);
756 function GetRowAssoc($upper=
true)
758 if ($this->fetchMode == MYSQL_ASSOC && !$upper) $row = $this->fields;
759 else $row = ADORecordSet::GetRowAssoc($upper);
764 function Fields($colname)
767 if ($this->fetchMode != MYSQL_NUM)
return @$this->fields[$colname];
770 $this->bind = array();
771 for ($i=0; $i < $this->_numOfFields; $i++) {
772 $o = $this->FetchField($i);
773 $this->bind[strtoupper($o->name)] = $i;
776 return $this->fields[$this->bind[strtoupper($colname)]];
781 if ($this->_numOfRows == 0)
return false;
782 return @mysql_data_seek($this->_queryID,$row);
789 if (@$this->fields = mysql_fetch_array($this->_queryID,$this->fetchMode)) {
790 $this->_currentRow += 1;
794 $this->_currentRow += 1;
802 $this->fields = @mysql_fetch_array($this->_queryID,$this->fetchMode);
803 return is_array($this->fields);
807 @mysql_free_result($this->_queryID);
808 $this->_queryID =
false;
811 function MetaType($t,$len=-1,$fieldobj=
false)
815 $t = $fieldobj->type;
816 $len = $fieldobj->max_length;
820 switch (strtoupper($t)) {
828 if ($len <= $this->blobSize)
return 'C';
842 return !empty($fieldobj->binary) ?
'B' :
'X';
845 case 'DATE':
return 'D';
849 case 'TIMESTAMP':
return 'T';
858 if (!empty($fieldobj->primary_key))
return 'R';
867 class ADORecordSet_ext_mysql
extends ADORecordSet_mysql {
868 function ADORecordSet_ext_mysql($queryID,$mode=
false)
870 if ($mode ===
false) {
871 global $ADODB_FETCH_MODE;
872 $mode = $ADODB_FETCH_MODE;
876 case ADODB_FETCH_NUM: $this->fetchMode = MYSQL_NUM;
break;
877 case ADODB_FETCH_ASSOC:$this->fetchMode = MYSQL_ASSOC;
break;
878 case ADODB_FETCH_DEFAULT:
879 case ADODB_FETCH_BOTH:
881 $this->fetchMode = MYSQL_BOTH;
break;
883 $this->adodbFetchMode = $mode;
884 $this->ADORecordSet($queryID);
889 return @adodb_movenext($this);
if(isset($_REQUEST['nrows'])) else $rs
debug($variable='', $name=' *variable *', $line=' *line *', $file=' *file *', $recursiveDepth=3, $debugLevel=E_DEBUG)