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