Documentation TYPO3 par Ameos |
00001 <?php 00002 /* 00003 V4.80 8 Mar 2006 (c) 2000-2006 John Lim (jlim@natsoft.com.my). All rights reserved. 00004 Released under both BSD license and Lesser GPL library license. 00005 Whenever there is any discrepancy between the two licenses, 00006 the BSD license will take precedence. 00007 Set tabs to 8. 00008 00009 MySQL code that does not support transactions. Use mysqlt if you need transactions. 00010 Requires mysql client. Works on Windows and Unix. 00011 00012 21 October 2003: MySQLi extension implementation by Arjen de Rijke (a.de.rijke@xs4all.nl) 00013 Based on adodb 3.40 00014 */ 00015 00016 // security - hide paths 00017 //if (!defined('ADODB_DIR')) die(); 00018 00019 if (! defined("_ADODB_MYSQLI_LAYER")) { 00020 define("_ADODB_MYSQLI_LAYER", 1 ); 00021 00022 // PHP5 compat... 00023 if (! defined("MYSQLI_BINARY_FLAG")) define("MYSQLI_BINARY_FLAG", 128); 00024 if (!defined('MYSQLI_READ_DEFAULT_GROUP')) define('MYSQLI_READ_DEFAULT_GROUP',1); 00025 00026 // disable adodb extension - currently incompatible. 00027 global $ADODB_EXTENSION; $ADODB_EXTENSION = false; 00028 00029 class ADODB_mysqli extends ADOConnection { 00030 var $databaseType = 'mysqli'; 00031 var $dataProvider = 'native'; 00032 var $hasInsertID = true; 00033 var $hasAffectedRows = true; 00034 var $metaTablesSQL = "SHOW TABLES"; 00035 var $metaColumnsSQL = "SHOW COLUMNS FROM %s"; 00036 var $fmtTimeStamp = "'Y-m-d H:i:s'"; 00037 var $hasLimit = true; 00038 var $hasMoveFirst = true; 00039 var $hasGenID = true; 00040 var $isoDates = true; // accepts dates in ISO format 00041 var $sysDate = 'CURDATE()'; 00042 var $sysTimeStamp = 'NOW()'; 00043 var $hasTransactions = true; 00044 var $forceNewConnect = false; 00045 var $poorAffectedRows = true; 00046 var $clientFlags = 0; 00047 var $substr = "substring"; 00048 var $port = false; 00049 var $socket = false; 00050 var $_bindInputArray = false; 00051 var $nameQuote = '`'; 00052 var $optionFlags = array(array(MYSQLI_READ_DEFAULT_GROUP,0)); 00053 00054 function ADODB_mysqli() 00055 { 00056 // if(!extension_loaded("mysqli")) 00057 ;//trigger_error("You must have the mysqli extension installed.", E_USER_ERROR); 00058 00059 } 00060 00061 00062 // returns true or false 00063 // To add: parameter int $port, 00064 // parameter string $socket 00065 function _connect($argHostname = NULL, 00066 $argUsername = NULL, 00067 $argPassword = NULL, 00068 $argDatabasename = NULL, $persist=false) 00069 { 00070 if(!extension_loaded("mysqli")) { 00071 return null; 00072 } 00073 $this->_connectionID = @mysqli_init(); 00074 00075 if (is_null($this->_connectionID)) { 00076 // mysqli_init only fails if insufficient memory 00077 if ($this->debug) 00078 ADOConnection::outp("mysqli_init() failed : " . $this->ErrorMsg()); 00079 return false; 00080 } 00081 /* 00082 I suggest a simple fix which would enable adodb and mysqli driver to 00083 read connection options from the standard mysql configuration file 00084 /etc/my.cnf - "Bastien Duclaux" <bduclaux#yahoo.com> 00085 */ 00086 foreach($this->optionFlags as $arr) { 00087 mysqli_options($this->_connectionID,$arr[0],$arr[1]); 00088 } 00089 00090 #if (!empty($this->port)) $argHostname .= ":".$this->port; 00091 $ok = mysqli_real_connect($this->_connectionID, 00092 $argHostname, 00093 $argUsername, 00094 $argPassword, 00095 $argDatabasename, 00096 $this->port, 00097 $this->socket, 00098 $this->clientFlags); 00099 00100 if ($ok) { 00101 if ($argDatabasename) return $this->SelectDB($argDatabasename); 00102 return true; 00103 } else { 00104 if ($this->debug) 00105 ADOConnection::outp("Could't connect : " . $this->ErrorMsg()); 00106 return false; 00107 } 00108 } 00109 00110 // returns true or false 00111 // How to force a persistent connection 00112 function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename) 00113 { 00114 return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename, true); 00115 00116 } 00117 00118 // When is this used? Close old connection first? 00119 // In _connect(), check $this->forceNewConnect? 00120 function _nconnect($argHostname, $argUsername, $argPassword, $argDatabasename) 00121 { 00122 $this->forceNewConnect = true; 00123 return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename); 00124 } 00125 00126 function IfNull( $field, $ifNull ) 00127 { 00128 return " IFNULL($field, $ifNull) "; // if MySQL 00129 } 00130 00131 function ServerInfo() 00132 { 00133 $arr['description'] = $this->GetOne("select version()"); 00134 $arr['version'] = ADOConnection::_findvers($arr['description']); 00135 return $arr; 00136 } 00137 00138 00139 function BeginTrans() 00140 { 00141 if ($this->transOff) return true; 00142 $this->transCnt += 1; 00143 $this->Execute('SET AUTOCOMMIT=0'); 00144 $this->Execute('BEGIN'); 00145 return true; 00146 } 00147 00148 function CommitTrans($ok=true) 00149 { 00150 if ($this->transOff) return true; 00151 if (!$ok) return $this->RollbackTrans(); 00152 00153 if ($this->transCnt) $this->transCnt -= 1; 00154 $this->Execute('COMMIT'); 00155 $this->Execute('SET AUTOCOMMIT=1'); 00156 return true; 00157 } 00158 00159 function RollbackTrans() 00160 { 00161 if ($this->transOff) return true; 00162 if ($this->transCnt) $this->transCnt -= 1; 00163 $this->Execute('ROLLBACK'); 00164 $this->Execute('SET AUTOCOMMIT=1'); 00165 return true; 00166 } 00167 00168 function RowLock($tables,$where='',$flds='1 as adodb_ignore') 00169 { 00170 if ($this->transCnt==0) $this->BeginTrans(); 00171 if ($where) $where = ' where '.$where; 00172 $rs =& $this->Execute("select $flds from $tables $where for update"); 00173 return !empty($rs); 00174 } 00175 00176 // if magic quotes disabled, use mysql_real_escape_string() 00177 // From readme.htm: 00178 // Quotes a string to be sent to the database. The $magic_quotes_enabled 00179 // parameter may look funny, but the idea is if you are quoting a 00180 // string extracted from a POST/GET variable, then 00181 // pass get_magic_quotes_gpc() as the second parameter. This will 00182 // ensure that the variable is not quoted twice, once by qstr and once 00183 // by the magic_quotes_gpc. 00184 // 00185 //Eg. $s = $db->qstr(_GET['name'],get_magic_quotes_gpc()); 00186 function qstr($s, $magic_quotes = false) 00187 { 00188 if (!$magic_quotes) { 00189 if (PHP_VERSION >= 5) 00190 return "'" . mysqli_real_escape_string($this->_connectionID, $s) . "'"; 00191 00192 if ($this->replaceQuote[0] == '\\') 00193 $s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\0"),$s); 00194 return "'".str_replace("'",$this->replaceQuote,$s)."'"; 00195 } 00196 // undo magic quotes for " 00197 $s = str_replace('\\"','"',$s); 00198 return "'$s'"; 00199 } 00200 00201 function _insertid() 00202 { 00203 $result = @mysqli_insert_id($this->_connectionID); 00204 if ($result == -1){ 00205 if ($this->debug) ADOConnection::outp("mysqli_insert_id() failed : " . $this->ErrorMsg()); 00206 } 00207 return $result; 00208 } 00209 00210 // Only works for INSERT, UPDATE and DELETE query's 00211 function _affectedrows() 00212 { 00213 $result = @mysqli_affected_rows($this->_connectionID); 00214 if ($result == -1) { 00215 if ($this->debug) ADOConnection::outp("mysqli_affected_rows() failed : " . $this->ErrorMsg()); 00216 } 00217 return $result; 00218 } 00219 00220 // See http://www.mysql.com/doc/M/i/Miscellaneous_functions.html 00221 // Reference on Last_Insert_ID on the recommended way to simulate sequences 00222 var $_genIDSQL = "update %s set id=LAST_INSERT_ID(id+1);"; 00223 var $_genSeqSQL = "create table %s (id int not null)"; 00224 var $_genSeq2SQL = "insert into %s values (%s)"; 00225 var $_dropSeqSQL = "drop table %s"; 00226 00227 function CreateSequence($seqname='adodbseq',$startID=1) 00228 { 00229 if (empty($this->_genSeqSQL)) return false; 00230 $u = strtoupper($seqname); 00231 00232 $ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname)); 00233 if (!$ok) return false; 00234 return $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1)); 00235 } 00236 00237 function GenID($seqname='adodbseq',$startID=1) 00238 { 00239 // post-nuke sets hasGenID to false 00240 if (!$this->hasGenID) return false; 00241 00242 $getnext = sprintf($this->_genIDSQL,$seqname); 00243 $holdtransOK = $this->_transOK; // save the current status 00244 $rs = @$this->Execute($getnext); 00245 if (!$rs) { 00246 if ($holdtransOK) $this->_transOK = true; //if the status was ok before reset 00247 $u = strtoupper($seqname); 00248 $this->Execute(sprintf($this->_genSeqSQL,$seqname)); 00249 $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1)); 00250 $rs = $this->Execute($getnext); 00251 } 00252 $this->genID = mysqli_insert_id($this->_connectionID); 00253 00254 if ($rs) $rs->Close(); 00255 00256 return $this->genID; 00257 } 00258 00259 function &MetaDatabases() 00260 { 00261 $query = "SHOW DATABASES"; 00262 $ret =& $this->Execute($query); 00263 if ($ret && is_object($ret)){ 00264 $arr = array(); 00265 while (!$ret->EOF){ 00266 $db = $ret->Fields('Database'); 00267 if ($db != 'mysql') $arr[] = $db; 00268 $ret->MoveNext(); 00269 } 00270 return $arr; 00271 } 00272 return $ret; 00273 } 00274 00275 00276 function &MetaIndexes ($table, $primary = FALSE) 00277 { 00278 // save old fetch mode 00279 global $ADODB_FETCH_MODE; 00280 00281 $false = false; 00282 $save = $ADODB_FETCH_MODE; 00283 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 00284 if ($this->fetchMode !== FALSE) { 00285 $savem = $this->SetFetchMode(FALSE); 00286 } 00287 00288 // get index details 00289 $rs = $this->Execute(sprintf('SHOW INDEXES FROM %s',$table)); 00290 00291 // restore fetchmode 00292 if (isset($savem)) { 00293 $this->SetFetchMode($savem); 00294 } 00295 $ADODB_FETCH_MODE = $save; 00296 00297 if (!is_object($rs)) { 00298 return $false; 00299 } 00300 00301 $indexes = array (); 00302 00303 // parse index data into array 00304 while ($row = $rs->FetchRow()) { 00305 if ($primary == FALSE AND $row[2] == 'PRIMARY') { 00306 continue; 00307 } 00308 00309 if (!isset($indexes[$row[2]])) { 00310 $indexes[$row[2]] = array( 00311 'unique' => ($row[1] == 0), 00312 'columns' => array() 00313 ); 00314 } 00315 00316 $indexes[$row[2]]['columns'][$row[3] - 1] = $row[4]; 00317 } 00318 00319 // sort columns by order in the index 00320 foreach ( array_keys ($indexes) as $index ) 00321 { 00322 ksort ($indexes[$index]['columns']); 00323 } 00324 00325 return $indexes; 00326 } 00327 00328 00329 // Format date column in sql string given an input format that understands Y M D 00330 function SQLDate($fmt, $col=false) 00331 { 00332 if (!$col) $col = $this->sysTimeStamp; 00333 $s = 'DATE_FORMAT('.$col.",'"; 00334 $concat = false; 00335 $len = strlen($fmt); 00336 for ($i=0; $i < $len; $i++) { 00337 $ch = $fmt[$i]; 00338 switch($ch) { 00339 case 'Y': 00340 case 'y': 00341 $s .= '%Y'; 00342 break; 00343 case 'Q': 00344 case 'q': 00345 $s .= "'),Quarter($col)"; 00346 00347 if ($len > $i+1) $s .= ",DATE_FORMAT($col,'"; 00348 else $s .= ",('"; 00349 $concat = true; 00350 break; 00351 case 'M': 00352 $s .= '%b'; 00353 break; 00354 00355 case 'm': 00356 $s .= '%m'; 00357 break; 00358 case 'D': 00359 case 'd': 00360 $s .= '%d'; 00361 break; 00362 00363 case 'H': 00364 $s .= '%H'; 00365 break; 00366 00367 case 'h': 00368 $s .= '%I'; 00369 break; 00370 00371 case 'i': 00372 $s .= '%i'; 00373 break; 00374 00375 case 's': 00376 $s .= '%s'; 00377 break; 00378 00379 case 'a': 00380 case 'A': 00381 $s .= '%p'; 00382 break; 00383 00384 case 'w': 00385 $s .= '%w'; 00386 break; 00387 00388 case 'l': 00389 $s .= '%W'; 00390 break; 00391 00392 default: 00393 00394 if ($ch == '\\') { 00395 $i++; 00396 $ch = substr($fmt,$i,1); 00397 } 00398 $s .= $ch; 00399 break; 00400 } 00401 } 00402 $s.="')"; 00403 if ($concat) $s = "CONCAT($s)"; 00404 return $s; 00405 } 00406 00407 // returns concatenated string 00408 // much easier to run "mysqld --ansi" or "mysqld --sql-mode=PIPES_AS_CONCAT" and use || operator 00409 function Concat() 00410 { 00411 $s = ""; 00412 $arr = func_get_args(); 00413 00414 // suggestion by andrew005@mnogo.ru 00415 $s = implode(',',$arr); 00416 if (strlen($s) > 0) return "CONCAT($s)"; 00417 else return ''; 00418 } 00419 00420 // dayFraction is a day in floating point 00421 function OffsetDate($dayFraction,$date=false) 00422 { 00423 if (!$date) 00424 $date = $this->sysDate; 00425 return "from_unixtime(unix_timestamp($date)+($dayFraction)*24*3600)"; 00426 } 00427 00428 function &MetaTables($ttype=false,$showSchema=false,$mask=false) 00429 { 00430 $save = $this->metaTablesSQL; 00431 if ($showSchema && is_string($showSchema)) { 00432 $this->metaTablesSQL .= " from $showSchema"; 00433 } 00434 00435 if ($mask) { 00436 $mask = $this->qstr($mask); 00437 $this->metaTablesSQL .= " like $mask"; 00438 } 00439 $ret =& ADOConnection::MetaTables($ttype,$showSchema); 00440 00441 $this->metaTablesSQL = $save; 00442 return $ret; 00443 } 00444 00445 // "Innox - Juan Carlos Gonzalez" <jgonzalez#innox.com.mx> 00446 function MetaForeignKeys( $table, $owner = FALSE, $upper = FALSE, $associative = FALSE ) 00447 { 00448 if ( !empty($owner) ) { 00449 $table = "$owner.$table"; 00450 } 00451 $a_create_table = $this->getRow(sprintf('SHOW CREATE TABLE %s', $table)); 00452 if ($associative) $create_sql = $a_create_table["Create Table"]; 00453 else $create_sql = $a_create_table[1]; 00454 00455 $matches = array(); 00456 00457 if (!preg_match_all("/FOREIGN KEY \(`(.*?)`\) REFERENCES `(.*?)` \(`(.*?)`\)/", $create_sql, $matches)) return false; 00458 $foreign_keys = array(); 00459 $num_keys = count($matches[0]); 00460 for ( $i = 0; $i < $num_keys; $i ++ ) { 00461 $my_field = explode('`, `', $matches[1][$i]); 00462 $ref_table = $matches[2][$i]; 00463 $ref_field = explode('`, `', $matches[3][$i]); 00464 00465 if ( $upper ) { 00466 $ref_table = strtoupper($ref_table); 00467 } 00468 00469 $foreign_keys[$ref_table] = array(); 00470 $num_fields = count($my_field); 00471 for ( $j = 0; $j < $num_fields; $j ++ ) { 00472 if ( $associative ) { 00473 $foreign_keys[$ref_table][$ref_field[$j]] = $my_field[$j]; 00474 } else { 00475 $foreign_keys[$ref_table][] = "{$my_field[$j]}={$ref_field[$j]}"; 00476 } 00477 } 00478 } 00479 00480 return $foreign_keys; 00481 } 00482 00483 function &MetaColumns($table) 00484 { 00485 $false = false; 00486 if (!$this->metaColumnsSQL) 00487 return $false; 00488 00489 global $ADODB_FETCH_MODE; 00490 $save = $ADODB_FETCH_MODE; 00491 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 00492 if ($this->fetchMode !== false) 00493 $savem = $this->SetFetchMode(false); 00494 $rs = $this->Execute(sprintf($this->metaColumnsSQL,$table)); 00495 if (isset($savem)) $this->SetFetchMode($savem); 00496 $ADODB_FETCH_MODE = $save; 00497 if (!is_object($rs)) 00498 return $false; 00499 00500 $retarr = array(); 00501 while (!$rs->EOF) { 00502 $fld = new ADOFieldObject(); 00503 $fld->name = $rs->fields[0]; 00504 $type = $rs->fields[1]; 00505 00506 // split type into type(length): 00507 $fld->scale = null; 00508 if (preg_match("/^(.+)\((\d+),(\d+)/", $type, $query_array)) { 00509 $fld->type = $query_array[1]; 00510 $fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1; 00511 $fld->scale = is_numeric($query_array[3]) ? $query_array[3] : -1; 00512 } elseif (preg_match("/^(.+)\((\d+)/", $type, $query_array)) { 00513 $fld->type = $query_array[1]; 00514 $fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1; 00515 } elseif (preg_match("/^(enum)\((.*)\)$/i", $type, $query_array)) { 00516 $fld->type = $query_array[1]; 00517 $fld->max_length = max(array_map("strlen",explode(",",$query_array[2]))) - 2; // PHP >= 4.0.6 00518 $fld->max_length = ($fld->max_length == 0 ? 1 : $fld->max_length); 00519 } else { 00520 $fld->type = $type; 00521 $fld->max_length = -1; 00522 } 00523 $fld->not_null = ($rs->fields[2] != 'YES'); 00524 $fld->primary_key = ($rs->fields[3] == 'PRI'); 00525 $fld->auto_increment = (strpos($rs->fields[5], 'auto_increment') !== false); 00526 $fld->binary = (strpos($type,'blob') !== false); 00527 $fld->unsigned = (strpos($type,'unsigned') !== false); 00528 00529 if (!$fld->binary) { 00530 $d = $rs->fields[4]; 00531 if ($d != '' && $d != 'NULL') { 00532 $fld->has_default = true; 00533 $fld->default_value = $d; 00534 } else { 00535 $fld->has_default = false; 00536 } 00537 } 00538 00539 if ($save == ADODB_FETCH_NUM) { 00540 $retarr[] = $fld; 00541 } else { 00542 $retarr[strtoupper($fld->name)] = $fld; 00543 } 00544 $rs->MoveNext(); 00545 } 00546 00547 $rs->Close(); 00548 return $retarr; 00549 } 00550 00551 // returns true or false 00552 function SelectDB($dbName) 00553 { 00554 // $this->_connectionID = $this->mysqli_resolve_link($this->_connectionID); 00555 $this->database = $dbName; 00556 $this->databaseName = $dbName; # obsolete, retained for compat with older adodb versions 00557 00558 if ($this->_connectionID) { 00559 $result = @mysqli_select_db($this->_connectionID, $dbName); 00560 if (!$result) { 00561 ADOConnection::outp("Select of database " . $dbName . " failed. " . $this->ErrorMsg()); 00562 } 00563 return $result; 00564 } 00565 return false; 00566 } 00567 00568 // parameters use PostgreSQL convention, not MySQL 00569 function &SelectLimit($sql, 00570 $nrows = -1, 00571 $offset = -1, 00572 $inputarr = false, 00573 $arg3 = false, 00574 $secs = 0) 00575 { 00576 $offsetStr = ($offset >= 0) ? "$offset," : ''; 00577 if ($nrows < 0) $nrows = '18446744073709551615'; 00578 00579 if ($secs) 00580 $rs =& $this->CacheExecute($secs, $sql . " LIMIT $offsetStr$nrows" , $inputarr , $arg3); 00581 else 00582 $rs =& $this->Execute($sql . " LIMIT $offsetStr$nrows" , $inputarr , $arg3); 00583 00584 return $rs; 00585 } 00586 00587 00588 function Prepare($sql) 00589 { 00590 return $sql; 00591 00592 $stmt = $this->_connectionID->prepare($sql); 00593 if (!$stmt) { 00594 echo $this->ErrorMsg(); 00595 return $sql; 00596 } 00597 return array($sql,$stmt); 00598 } 00599 00600 00601 // returns queryID or false 00602 function _query($sql, $inputarr) 00603 { 00604 global $ADODB_COUNTRECS; 00605 00606 if (is_array($sql)) { 00607 $stmt = $sql[1]; 00608 $a = ''; 00609 foreach($inputarr as $k => $v) { 00610 if (is_string($v)) $a .= 's'; 00611 else if (is_integer($v)) $a .= 'i'; 00612 else $a .= 'd'; 00613 } 00614 00615 $fnarr = array_merge( array($stmt,$a) , $inputarr); 00616 $ret = call_user_func_array('mysqli_stmt_bind_param',$fnarr); 00617 00618 $ret = mysqli_stmt_execute($stmt); 00619 return $ret; 00620 } 00621 if (!$mysql_res = mysqli_query($this->_connectionID, $sql, ($ADODB_COUNTRECS) ? MYSQLI_STORE_RESULT : MYSQLI_USE_RESULT)) { 00622 if ($this->debug) ADOConnection::outp("Query: " . $sql . " failed. " . $this->ErrorMsg()); 00623 return false; 00624 } 00625 00626 return $mysql_res; 00627 } 00628 00629 /* Returns: the last error message from previous database operation */ 00630 function ErrorMsg() 00631 { 00632 if (empty($this->_connectionID)) 00633 $this->_errorMsg = @mysqli_connect_error(); 00634 else 00635 $this->_errorMsg = @mysqli_error($this->_connectionID); 00636 return $this->_errorMsg; 00637 } 00638 00639 /* Returns: the last error number from previous database operation */ 00640 function ErrorNo() 00641 { 00642 if (empty($this->_connectionID)) 00643 return @mysqli_connect_errno(); 00644 else 00645 return @mysqli_errno($this->_connectionID); 00646 } 00647 00648 // returns true or false 00649 function _close() 00650 { 00651 @mysqli_close($this->_connectionID); 00652 $this->_connectionID = false; 00653 } 00654 00655 /* 00656 * Maximum size of C field 00657 */ 00658 function CharMax() 00659 { 00660 return 255; 00661 } 00662 00663 /* 00664 * Maximum size of X field 00665 */ 00666 function TextMax() 00667 { 00668 return 4294967295; 00669 } 00670 00671 00672 00673 // this is a set of functions for managing client encoding - very important if the encodings 00674 // of your database and your output target (i.e. HTML) don't match 00675 // for instance, you may have UTF8 database and server it on-site as latin1 etc. 00676 // GetCharSet - get the name of the character set the client is using now 00677 // Under Windows, the functions should work with MySQL 4.1.11 and above, the set of charsets supported 00678 // depends on compile flags of mysql distribution 00679 00680 function GetCharSet() 00681 { 00682 //we will use ADO's builtin property charSet 00683 if (!is_callable($this->_connectionID,'character_set_name')) 00684 return false; 00685 00686 $this->charSet = @$this->_connectionID->character_set_name(); 00687 if (!$this->charSet) { 00688 return false; 00689 } else { 00690 return $this->charSet; 00691 } 00692 } 00693 00694 // SetCharSet - switch the client encoding 00695 function SetCharSet($charset_name) 00696 { 00697 if (!is_callable($this->_connectionID,'set_charset')) 00698 return false; 00699 00700 if ($this->charSet !== $charset_name) { 00701 $if = @$this->_connectionID->set_charset($charset_name); 00702 if ($if == "0" & $this->GetCharSet() == $charset_name) { 00703 return true; 00704 } else return false; 00705 } else return true; 00706 } 00707 00708 00709 00710 00711 } 00712 00713 /*-------------------------------------------------------------------------------------- 00714 Class Name: Recordset 00715 --------------------------------------------------------------------------------------*/ 00716 00717 class ADORecordSet_mysqli extends ADORecordSet{ 00718 00719 var $databaseType = "mysqli"; 00720 var $canSeek = true; 00721 00722 function ADORecordSet_mysqli($queryID, $mode = false) 00723 { 00724 if ($mode === false) 00725 { 00726 global $ADODB_FETCH_MODE; 00727 $mode = $ADODB_FETCH_MODE; 00728 } 00729 00730 switch ($mode) 00731 { 00732 case ADODB_FETCH_NUM: 00733 $this->fetchMode = MYSQLI_NUM; 00734 break; 00735 case ADODB_FETCH_ASSOC: 00736 $this->fetchMode = MYSQLI_ASSOC; 00737 break; 00738 case ADODB_FETCH_DEFAULT: 00739 case ADODB_FETCH_BOTH: 00740 default: 00741 $this->fetchMode = MYSQLI_BOTH; 00742 break; 00743 } 00744 $this->adodbFetchMode = $mode; 00745 $this->ADORecordSet($queryID); 00746 } 00747 00748 function _initrs() 00749 { 00750 global $ADODB_COUNTRECS; 00751 00752 $this->_numOfRows = $ADODB_COUNTRECS ? @mysqli_num_rows($this->_queryID) : -1; 00753 $this->_numOfFields = @mysqli_num_fields($this->_queryID); 00754 } 00755 00756 /* 00757 1 = MYSQLI_NOT_NULL_FLAG 00758 2 = MYSQLI_PRI_KEY_FLAG 00759 4 = MYSQLI_UNIQUE_KEY_FLAG 00760 8 = MYSQLI_MULTIPLE_KEY_FLAG 00761 16 = MYSQLI_BLOB_FLAG 00762 32 = MYSQLI_UNSIGNED_FLAG 00763 64 = MYSQLI_ZEROFILL_FLAG 00764 128 = MYSQLI_BINARY_FLAG 00765 256 = MYSQLI_ENUM_FLAG 00766 512 = MYSQLI_AUTO_INCREMENT_FLAG 00767 1024 = MYSQLI_TIMESTAMP_FLAG 00768 2048 = MYSQLI_SET_FLAG 00769 32768 = MYSQLI_NUM_FLAG 00770 16384 = MYSQLI_PART_KEY_FLAG 00771 32768 = MYSQLI_GROUP_FLAG 00772 65536 = MYSQLI_UNIQUE_FLAG 00773 131072 = MYSQLI_BINCMP_FLAG 00774 */ 00775 00776 function &FetchField($fieldOffset = -1) 00777 { 00778 $fieldnr = $fieldOffset; 00779 if ($fieldOffset != -1) { 00780 $fieldOffset = mysqli_field_seek($this->_queryID, $fieldnr); 00781 } 00782 $o = mysqli_fetch_field($this->_queryID); 00783 /* Properties of an ADOFieldObject as set by MetaColumns */ 00784 $o->primary_key = $o->flags & MYSQLI_PRI_KEY_FLAG; 00785 $o->not_null = $o->flags & MYSQLI_NOT_NULL_FLAG; 00786 $o->auto_increment = $o->flags & MYSQLI_AUTO_INCREMENT_FLAG; 00787 $o->binary = $o->flags & MYSQLI_BINARY_FLAG; 00788 // $o->blob = $o->flags & MYSQLI_BLOB_FLAG; /* not returned by MetaColumns */ 00789 $o->unsigned = $o->flags & MYSQLI_UNSIGNED_FLAG; 00790 00791 return $o; 00792 } 00793 00794 function &GetRowAssoc($upper = true) 00795 { 00796 if ($this->fetchMode == MYSQLI_ASSOC && !$upper) 00797 return $this->fields; 00798 $row =& ADORecordSet::GetRowAssoc($upper); 00799 return $row; 00800 } 00801 00802 /* Use associative array to get fields array */ 00803 function Fields($colname) 00804 { 00805 if ($this->fetchMode != MYSQLI_NUM) 00806 return @$this->fields[$colname]; 00807 00808 if (!$this->bind) { 00809 $this->bind = array(); 00810 for ($i = 0; $i < $this->_numOfFields; $i++) { 00811 $o = $this->FetchField($i); 00812 $this->bind[strtoupper($o->name)] = $i; 00813 } 00814 } 00815 return $this->fields[$this->bind[strtoupper($colname)]]; 00816 } 00817 00818 function _seek($row) 00819 { 00820 if ($this->_numOfRows == 0) 00821 return false; 00822 00823 if ($row < 0) 00824 return false; 00825 00826 mysqli_data_seek($this->_queryID, $row); 00827 $this->EOF = false; 00828 return true; 00829 } 00830 00831 // 10% speedup to move MoveNext to child class 00832 // This is the only implementation that works now (23-10-2003). 00833 // Other functions return no or the wrong results. 00834 function MoveNext() 00835 { 00836 if ($this->EOF) return false; 00837 $this->_currentRow++; 00838 $this->fields = @mysqli_fetch_array($this->_queryID,$this->fetchMode); 00839 00840 if (is_array($this->fields)) return true; 00841 $this->EOF = true; 00842 return false; 00843 } 00844 00845 function _fetch() 00846 { 00847 $this->fields = mysqli_fetch_array($this->_queryID,$this->fetchMode); 00848 return is_array($this->fields); 00849 } 00850 00851 function _close() 00852 { 00853 mysqli_free_result($this->_queryID); 00854 $this->_queryID = false; 00855 } 00856 00857 /* 00858 00859 0 = MYSQLI_TYPE_DECIMAL 00860 1 = MYSQLI_TYPE_CHAR 00861 1 = MYSQLI_TYPE_TINY 00862 2 = MYSQLI_TYPE_SHORT 00863 3 = MYSQLI_TYPE_LONG 00864 4 = MYSQLI_TYPE_FLOAT 00865 5 = MYSQLI_TYPE_DOUBLE 00866 6 = MYSQLI_TYPE_NULL 00867 7 = MYSQLI_TYPE_TIMESTAMP 00868 8 = MYSQLI_TYPE_LONGLONG 00869 9 = MYSQLI_TYPE_INT24 00870 10 = MYSQLI_TYPE_DATE 00871 11 = MYSQLI_TYPE_TIME 00872 12 = MYSQLI_TYPE_DATETIME 00873 13 = MYSQLI_TYPE_YEAR 00874 14 = MYSQLI_TYPE_NEWDATE 00875 247 = MYSQLI_TYPE_ENUM 00876 248 = MYSQLI_TYPE_SET 00877 249 = MYSQLI_TYPE_TINY_BLOB 00878 250 = MYSQLI_TYPE_MEDIUM_BLOB 00879 251 = MYSQLI_TYPE_LONG_BLOB 00880 252 = MYSQLI_TYPE_BLOB 00881 253 = MYSQLI_TYPE_VAR_STRING 00882 254 = MYSQLI_TYPE_STRING 00883 255 = MYSQLI_TYPE_GEOMETRY 00884 */ 00885 00886 function MetaType($t, $len = -1, $fieldobj = false) 00887 { 00888 if (is_object($t)) { 00889 $fieldobj = $t; 00890 $t = $fieldobj->type; 00891 $len = $fieldobj->max_length; 00892 } 00893 00894 00895 $len = -1; // mysql max_length is not accurate 00896 switch (strtoupper($t)) { 00897 case 'STRING': 00898 case 'CHAR': 00899 case 'VARCHAR': 00900 case 'TINYBLOB': 00901 case 'TINYTEXT': 00902 case 'ENUM': 00903 case 'SET': 00904 00905 case MYSQLI_TYPE_TINY_BLOB : 00906 case MYSQLI_TYPE_CHAR : 00907 case MYSQLI_TYPE_STRING : 00908 case MYSQLI_TYPE_ENUM : 00909 case MYSQLI_TYPE_SET : 00910 case 253 : 00911 if ($len <= $this->blobSize) return 'C'; 00912 00913 case 'TEXT': 00914 case 'LONGTEXT': 00915 case 'MEDIUMTEXT': 00916 return 'X'; 00917 00918 00919 // php_mysql extension always returns 'blob' even if 'text' 00920 // so we have to check whether binary... 00921 case 'IMAGE': 00922 case 'LONGBLOB': 00923 case 'BLOB': 00924 case 'MEDIUMBLOB': 00925 00926 case MYSQLI_TYPE_BLOB : 00927 case MYSQLI_TYPE_LONG_BLOB : 00928 case MYSQLI_TYPE_MEDIUM_BLOB : 00929 00930 return !empty($fieldobj->binary) ? 'B' : 'X'; 00931 case 'YEAR': 00932 case 'DATE': 00933 case MYSQLI_TYPE_DATE : 00934 case MYSQLI_TYPE_YEAR : 00935 00936 return 'D'; 00937 00938 case 'TIME': 00939 case 'DATETIME': 00940 case 'TIMESTAMP': 00941 00942 case MYSQLI_TYPE_DATETIME : 00943 case MYSQLI_TYPE_NEWDATE : 00944 case MYSQLI_TYPE_TIME : 00945 case MYSQLI_TYPE_TIMESTAMP : 00946 00947 return 'T'; 00948 00949 case 'INT': 00950 case 'INTEGER': 00951 case 'BIGINT': 00952 case 'TINYINT': 00953 case 'MEDIUMINT': 00954 case 'SMALLINT': 00955 00956 case MYSQLI_TYPE_INT24 : 00957 case MYSQLI_TYPE_LONG : 00958 case MYSQLI_TYPE_LONGLONG : 00959 case MYSQLI_TYPE_SHORT : 00960 case MYSQLI_TYPE_TINY : 00961 00962 if (!empty($fieldobj->primary_key)) return 'R'; 00963 00964 return 'I'; 00965 00966 00967 // Added floating-point types 00968 // Maybe not necessery. 00969 case 'FLOAT': 00970 case 'DOUBLE': 00971 // case 'DOUBLE PRECISION': 00972 case 'DECIMAL': 00973 case 'DEC': 00974 case 'FIXED': 00975 default: 00976 //if (!is_numeric($t)) echo "<p>--- Error in type matching $t -----</p>"; 00977 return 'N'; 00978 } 00979 } // function 00980 00981 00982 } // rs class 00983 00984 } 00985 00986 ?>