| [ Index ] |
PHP Cross Reference of Moodle 1.9.3 [Build 15-Oct-2008] |
[Summary view] [Print] [Text view]
1 <?php 2 /* 3 V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved. 4 Released under both BSD license and Lesser GPL library license. 5 Whenever there is any discrepancy between the two licenses, 6 the BSD license will take precedence. 7 Set tabs to 8. 8 9 MySQL code that does not support transactions. Use mysqlt if you need transactions. 10 Requires mysql client. Works on Windows and Unix. 11 12 21 October 2003: MySQLi extension implementation by Arjen de Rijke (a.de.rijke@xs4all.nl) 13 Based on adodb 3.40 14 */ 15 16 // security - hide paths 17 if (!defined('ADODB_DIR')) die(); 18 19 if (! defined("_ADODB_MYSQLI_LAYER")) { 20 define("_ADODB_MYSQLI_LAYER", 1 ); 21 22 // PHP5 compat... 23 if (! defined("MYSQLI_BINARY_FLAG")) define("MYSQLI_BINARY_FLAG", 128); 24 if (!defined('MYSQLI_READ_DEFAULT_GROUP')) define('MYSQLI_READ_DEFAULT_GROUP',1); 25 26 // disable adodb extension - currently incompatible. 27 global $ADODB_EXTENSION; $ADODB_EXTENSION = false; 28 29 class ADODB_mysqli extends ADOConnection { 30 var $databaseType = 'mysqli'; 31 var $dataProvider = 'native'; 32 var $hasInsertID = true; 33 var $hasAffectedRows = true; 34 var $metaTablesSQL = "SHOW TABLES"; 35 var $metaColumnsSQL = "SHOW COLUMNS FROM `%s`"; 36 var $fmtTimeStamp = "'Y-m-d H:i:s'"; 37 var $hasLimit = true; 38 var $hasMoveFirst = true; 39 var $hasGenID = true; 40 var $isoDates = true; // accepts dates in ISO format 41 var $sysDate = 'CURDATE()'; 42 var $sysTimeStamp = 'NOW()'; 43 var $hasTransactions = true; 44 var $forceNewConnect = false; 45 var $poorAffectedRows = true; 46 var $clientFlags = 0; 47 var $substr = "substring"; 48 var $port = false; 49 var $socket = false; 50 var $_bindInputArray = false; 51 var $nameQuote = '`'; /// string to use to quote identifiers and names 52 var $optionFlags = array(array(MYSQLI_READ_DEFAULT_GROUP,0)); 53 var $arrayClass = 'ADORecordSet_array_mysqli'; 54 55 function ADODB_mysqli() 56 { 57 // if(!extension_loaded("mysqli")) 58 ;//trigger_error("You must have the mysqli extension installed.", E_USER_ERROR); 59 60 } 61 62 function SetTransactionMode( $transaction_mode ) 63 { 64 $this->_transmode = $transaction_mode; 65 if (empty($transaction_mode)) { 66 $this->Execute('SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ'); 67 return; 68 } 69 if (!stristr($transaction_mode,'isolation')) $transaction_mode = 'ISOLATION LEVEL '.$transaction_mode; 70 $this->Execute("SET SESSION TRANSACTION ".$transaction_mode); 71 } 72 73 // returns true or false 74 // To add: parameter int $port, 75 // parameter string $socket 76 function _connect($argHostname = NULL, 77 $argUsername = NULL, 78 $argPassword = NULL, 79 $argDatabasename = NULL, $persist=false) 80 { 81 if(!extension_loaded("mysqli")) { 82 return null; 83 } 84 $this->_connectionID = @mysqli_init(); 85 86 if (is_null($this->_connectionID)) { 87 // mysqli_init only fails if insufficient memory 88 if ($this->debug) 89 ADOConnection::outp("mysqli_init() failed : " . $this->ErrorMsg()); 90 return false; 91 } 92 /* 93 I suggest a simple fix which would enable adodb and mysqli driver to 94 read connection options from the standard mysql configuration file 95 /etc/my.cnf - "Bastien Duclaux" <bduclaux#yahoo.com> 96 */ 97 foreach($this->optionFlags as $arr) { 98 mysqli_options($this->_connectionID,$arr[0],$arr[1]); 99 } 100 101 #if (!empty($this->port)) $argHostname .= ":".$this->port; 102 $ok = mysqli_real_connect($this->_connectionID, 103 $argHostname, 104 $argUsername, 105 $argPassword, 106 $argDatabasename, 107 $this->port, 108 $this->socket, 109 $this->clientFlags); 110 111 if ($ok) { 112 if ($argDatabasename) return $this->SelectDB($argDatabasename); 113 return true; 114 } else { 115 if ($this->debug) 116 ADOConnection::outp("Could't connect : " . $this->ErrorMsg()); 117 $this->_connectionID = null; 118 return false; 119 } 120 } 121 122 // returns true or false 123 // How to force a persistent connection 124 function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename) 125 { 126 return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename, true); 127 128 } 129 130 // When is this used? Close old connection first? 131 // In _connect(), check $this->forceNewConnect? 132 function _nconnect($argHostname, $argUsername, $argPassword, $argDatabasename) 133 { 134 $this->forceNewConnect = true; 135 return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename); 136 } 137 138 function IfNull( $field, $ifNull ) 139 { 140 return " IFNULL($field, $ifNull) "; // if MySQL 141 } 142 143 // do not use $ADODB_COUNTRECS 144 function GetOne($sql,$inputarr=false) 145 { 146 $ret = false; 147 $rs = &$this->Execute($sql,$inputarr); 148 if ($rs) { 149 if (!$rs->EOF) $ret = reset($rs->fields); 150 $rs->Close(); 151 } 152 return $ret; 153 } 154 155 function ServerInfo() 156 { 157 $arr['description'] = $this->GetOne("select version()"); 158 $arr['version'] = ADOConnection::_findvers($arr['description']); 159 return $arr; 160 } 161 162 163 function BeginTrans() 164 { 165 if ($this->transOff) return true; 166 $this->transCnt += 1; 167 168 //$this->Execute('SET AUTOCOMMIT=0'); 169 mysqli_autocommit($this->_connectionID, false); 170 $this->Execute('BEGIN'); 171 return true; 172 } 173 174 function CommitTrans($ok=true) 175 { 176 if ($this->transOff) return true; 177 if (!$ok) return $this->RollbackTrans(); 178 179 if ($this->transCnt) $this->transCnt -= 1; 180 $this->Execute('COMMIT'); 181 182 //$this->Execute('SET AUTOCOMMIT=1'); 183 mysqli_autocommit($this->_connectionID, true); 184 return true; 185 } 186 187 function RollbackTrans() 188 { 189 if ($this->transOff) return true; 190 if ($this->transCnt) $this->transCnt -= 1; 191 $this->Execute('ROLLBACK'); 192 //$this->Execute('SET AUTOCOMMIT=1'); 193 mysqli_autocommit($this->_connectionID, true); 194 return true; 195 } 196 197 function RowLock($tables,$where='',$flds='1 as adodb_ignore') 198 { 199 if ($this->transCnt==0) $this->BeginTrans(); 200 if ($where) $where = ' where '.$where; 201 $rs =& $this->Execute("select $flds from $tables $where for update"); 202 return !empty($rs); 203 } 204 205 // if magic quotes disabled, use mysql_real_escape_string() 206 // From readme.htm: 207 // Quotes a string to be sent to the database. The $magic_quotes_enabled 208 // parameter may look funny, but the idea is if you are quoting a 209 // string extracted from a POST/GET variable, then 210 // pass get_magic_quotes_gpc() as the second parameter. This will 211 // ensure that the variable is not quoted twice, once by qstr and once 212 // by the magic_quotes_gpc. 213 // 214 //Eg. $s = $db->qstr(_GET['name'],get_magic_quotes_gpc()); 215 function qstr($s, $magic_quotes = false) 216 { 217 if (is_null($s)) return 'NULL'; 218 if (!$magic_quotes) { 219 if (PHP_VERSION >= 5) 220 return "'" . mysqli_real_escape_string($this->_connectionID, $s) . "'"; 221 222 if ($this->replaceQuote[0] == '\\') 223 $s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\0"),$s); 224 return "'".str_replace("'",$this->replaceQuote,$s)."'"; 225 } 226 // undo magic quotes for " 227 $s = str_replace('\\"','"',$s); 228 return "'$s'"; 229 } 230 231 function _insertid() 232 { 233 $result = @mysqli_insert_id($this->_connectionID); 234 if ($result == -1){ 235 if ($this->debug) ADOConnection::outp("mysqli_insert_id() failed : " . $this->ErrorMsg()); 236 } 237 return $result; 238 } 239 240 // Only works for INSERT, UPDATE and DELETE query's 241 function _affectedrows() 242 { 243 $result = @mysqli_affected_rows($this->_connectionID); 244 if ($result == -1) { 245 if ($this->debug) ADOConnection::outp("mysqli_affected_rows() failed : " . $this->ErrorMsg()); 246 } 247 return $result; 248 } 249 250 // See http://www.mysql.com/doc/M/i/Miscellaneous_functions.html 251 // Reference on Last_Insert_ID on the recommended way to simulate sequences 252 var $_genIDSQL = "update %s set id=LAST_INSERT_ID(id+1);"; 253 var $_genSeqSQL = "create table %s (id int not null)"; 254 var $_genSeq2SQL = "insert into %s values (%s)"; 255 var $_dropSeqSQL = "drop table %s"; 256 257 function CreateSequence($seqname='adodbseq',$startID=1) 258 { 259 if (empty($this->_genSeqSQL)) return false; 260 $u = strtoupper($seqname); 261 262 $ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname)); 263 if (!$ok) return false; 264 return $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1)); 265 } 266 267 function GenID($seqname='adodbseq',$startID=1) 268 { 269 // post-nuke sets hasGenID to false 270 if (!$this->hasGenID) return false; 271 272 $getnext = sprintf($this->_genIDSQL,$seqname); 273 $holdtransOK = $this->_transOK; // save the current status 274 $rs = @$this->Execute($getnext); 275 if (!$rs) { 276 if ($holdtransOK) $this->_transOK = true; //if the status was ok before reset 277 $u = strtoupper($seqname); 278 $this->Execute(sprintf($this->_genSeqSQL,$seqname)); 279 $cnt = $this->GetOne(sprintf($this->_genSeqCountSQL,$seqname)); 280 if (!$cnt) $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1)); 281 $rs = $this->Execute($getnext); 282 } 283 284 if ($rs) { 285 $this->genID = mysqli_insert_id($this->_connectionID); 286 $rs->Close(); 287 } else 288 $this->genID = 0; 289 290 return $this->genID; 291 } 292 293 function &MetaDatabases() 294 { 295 $query = "SHOW DATABASES"; 296 $ret =& $this->Execute($query); 297 if ($ret && is_object($ret)){ 298 $arr = array(); 299 while (!$ret->EOF){ 300 $db = $ret->Fields('Database'); 301 if ($db != 'mysql') $arr[] = $db; 302 $ret->MoveNext(); 303 } 304 return $arr; 305 } 306 return $ret; 307 } 308 309 310 function &MetaIndexes ($table, $primary = FALSE) 311 { 312 // save old fetch mode 313 global $ADODB_FETCH_MODE; 314 315 $false = false; 316 $save = $ADODB_FETCH_MODE; 317 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 318 if ($this->fetchMode !== FALSE) { 319 $savem = $this->SetFetchMode(FALSE); 320 } 321 322 // get index details 323 $rs = $this->Execute(sprintf('SHOW INDEXES FROM %s',$table)); 324 325 // restore fetchmode 326 if (isset($savem)) { 327 $this->SetFetchMode($savem); 328 } 329 $ADODB_FETCH_MODE = $save; 330 331 if (!is_object($rs)) { 332 return $false; 333 } 334 335 $indexes = array (); 336 337 // parse index data into array 338 while ($row = $rs->FetchRow()) { 339 if ($primary == FALSE AND $row[2] == 'PRIMARY') { 340 continue; 341 } 342 343 if (!isset($indexes[$row[2]])) { 344 $indexes[$row[2]] = array( 345 'unique' => ($row[1] == 0), 346 'columns' => array() 347 ); 348 } 349 350 $indexes[$row[2]]['columns'][$row[3] - 1] = $row[4]; 351 } 352 353 // sort columns by order in the index 354 foreach ( array_keys ($indexes) as $index ) 355 { 356 ksort ($indexes[$index]['columns']); 357 } 358 359 return $indexes; 360 } 361 362 363 // Format date column in sql string given an input format that understands Y M D 364 function SQLDate($fmt, $col=false) 365 { 366 if (!$col) $col = $this->sysTimeStamp; 367 $s = 'DATE_FORMAT('.$col.",'"; 368 $concat = false; 369 $len = strlen($fmt); 370 for ($i=0; $i < $len; $i++) { 371 $ch = $fmt[$i]; 372 switch($ch) { 373 case 'Y': 374 case 'y': 375 $s .= '%Y'; 376 break; 377 case 'Q': 378 case 'q': 379 $s .= "'),Quarter($col)"; 380 381 if ($len > $i+1) $s .= ",DATE_FORMAT($col,'"; 382 else $s .= ",('"; 383 $concat = true; 384 break; 385 case 'M': 386 $s .= '%b'; 387 break; 388 389 case 'm': 390 $s .= '%m'; 391 break; 392 case 'D': 393 case 'd': 394 $s .= '%d'; 395 break; 396 397 case 'H': 398 $s .= '%H'; 399 break; 400 401 case 'h': 402 $s .= '%I'; 403 break; 404 405 case 'i': 406 $s .= '%i'; 407 break; 408 409 case 's': 410 $s .= '%s'; 411 break; 412 413 case 'a': 414 case 'A': 415 $s .= '%p'; 416 break; 417 418 case 'w': 419 $s .= '%w'; 420 break; 421 422 case 'l': 423 $s .= '%W'; 424 break; 425 426 default: 427 428 if ($ch == '\\') { 429 $i++; 430 $ch = substr($fmt,$i,1); 431 } 432 $s .= $ch; 433 break; 434 } 435 } 436 $s.="')"; 437 if ($concat) $s = "CONCAT($s)"; 438 return $s; 439 } 440 441 // returns concatenated string 442 // much easier to run "mysqld --ansi" or "mysqld --sql-mode=PIPES_AS_CONCAT" and use || operator 443 function Concat() 444 { 445 $s = ""; 446 $arr = func_get_args(); 447 448 // suggestion by andrew005@mnogo.ru 449 $s = implode(',',$arr); 450 if (strlen($s) > 0) return "CONCAT($s)"; 451 else return ''; 452 } 453 454 // dayFraction is a day in floating point 455 function OffsetDate($dayFraction,$date=false) 456 { 457 if (!$date) $date = $this->sysDate; 458 459 $fraction = $dayFraction * 24 * 3600; 460 return $date . ' + INTERVAL ' . $fraction.' SECOND'; 461 462 // return "from_unixtime(unix_timestamp($date)+$fraction)"; 463 } 464 465 function &MetaTables($ttype=false,$showSchema=false,$mask=false) 466 { 467 $save = $this->metaTablesSQL; 468 if ($showSchema && is_string($showSchema)) { 469 $this->metaTablesSQL .= " from $showSchema"; 470 } 471 472 if ($mask) { 473 $mask = $this->qstr($mask); 474 $this->metaTablesSQL .= " like $mask"; 475 } 476 $ret =& ADOConnection::MetaTables($ttype,$showSchema); 477 478 $this->metaTablesSQL = $save; 479 return $ret; 480 } 481 482 // "Innox - Juan Carlos Gonzalez" <jgonzalez#innox.com.mx> 483 function MetaForeignKeys( $table, $owner = FALSE, $upper = FALSE, $associative = FALSE ) 484 { 485 global $ADODB_FETCH_MODE; 486 487 if ($ADODB_FETCH_MODE == ADODB_FETCH_ASSOC || $this->fetchMode == ADODB_FETCH_ASSOC) $associative = true; 488 489 if ( !empty($owner) ) { 490 $table = "$owner.$table"; 491 } 492 $a_create_table = $this->getRow(sprintf('SHOW CREATE TABLE %s', $table)); 493 if ($associative) $create_sql = $a_create_table["Create Table"]; 494 else $create_sql = $a_create_table[1]; 495 496 $matches = array(); 497 498 if (!preg_match_all("/FOREIGN KEY \(`(.*?)`\) REFERENCES `(.*?)` \(`(.*?)`\)/", $create_sql, $matches)) return false; 499 $foreign_keys = array(); 500 $num_keys = count($matches[0]); 501 for ( $i = 0; $i < $num_keys; $i ++ ) { 502 $my_field = explode('`, `', $matches[1][$i]); 503 $ref_table = $matches[2][$i]; 504 $ref_field = explode('`, `', $matches[3][$i]); 505 506 if ( $upper ) { 507 $ref_table = strtoupper($ref_table); 508 } 509 510 $foreign_keys[$ref_table] = array(); 511 $num_fields = count($my_field); 512 for ( $j = 0; $j < $num_fields; $j ++ ) { 513 if ( $associative ) { 514 $foreign_keys[$ref_table][$ref_field[$j]] = $my_field[$j]; 515 } else { 516 $foreign_keys[$ref_table][] = "{$my_field[$j]}={$ref_field[$j]}"; 517 } 518 } 519 } 520 521 return $foreign_keys; 522 } 523 524 function &MetaColumns($table) 525 { 526 $false = false; 527 if (!$this->metaColumnsSQL) 528 return $false; 529 530 global $ADODB_FETCH_MODE; 531 $save = $ADODB_FETCH_MODE; 532 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 533 if ($this->fetchMode !== false) 534 $savem = $this->SetFetchMode(false); 535 $rs = $this->Execute(sprintf($this->metaColumnsSQL,$table)); 536 if (isset($savem)) $this->SetFetchMode($savem); 537 $ADODB_FETCH_MODE = $save; 538 if (!is_object($rs)) 539 return $false; 540 541 $retarr = array(); 542 while (!$rs->EOF) { 543 $fld = new ADOFieldObject(); 544 $fld->name = $rs->fields[0]; 545 $type = $rs->fields[1]; 546 547 // split type into type(length): 548 $fld->scale = null; 549 if (preg_match("/^(.+)\((\d+),(\d+)/", $type, $query_array)) { 550 $fld->type = $query_array[1]; 551 $fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1; 552 $fld->scale = is_numeric($query_array[3]) ? $query_array[3] : -1; 553 } elseif (preg_match("/^(.+)\((\d+)/", $type, $query_array)) { 554 $fld->type = $query_array[1]; 555 $fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1; 556 } elseif (preg_match("/^(enum)\((.*)\)$/i", $type, $query_array)) { 557 $fld->type = $query_array[1]; 558 $arr = explode(",",$query_array[2]); 559 $fld->enums = $arr; 560 $fld->max_length = max(array_map("strlen",explode(",",$query_array[2]))) - 2; // PHP >= 4.0.6 561 $fld->max_length = ($fld->max_length == 0 ? 1 : $fld->max_length); 562 } else { 563 $fld->type = $type; 564 $fld->max_length = -1; 565 } 566 $fld->not_null = ($rs->fields[2] != 'YES'); 567 $fld->primary_key = ($rs->fields[3] == 'PRI'); 568 $fld->auto_increment = (strpos($rs->fields[5], 'auto_increment') !== false); 569 $fld->binary = (strpos($type,'blob') !== false); 570 $fld->unsigned = (strpos($type,'unsigned') !== false); 571 $fld->zerofill = (strpos($type,'zerofill') !== false); 572 573 if (!$fld->binary) { 574 $d = $rs->fields[4]; 575 if ($d != '' && $d != 'NULL') { 576 $fld->has_default = true; 577 $fld->default_value = $d; 578 } else { 579 $fld->has_default = false; 580 } 581 } 582 583 if ($save == ADODB_FETCH_NUM) { 584 $retarr[] = $fld; 585 } else { 586 $retarr[strtoupper($fld->name)] = $fld; 587 } 588 $rs->MoveNext(); 589 } 590 591 $rs->Close(); 592 return $retarr; 593 } 594 595 // returns true or false 596 function SelectDB($dbName) 597 { 598 // $this->_connectionID = $this->mysqli_resolve_link($this->_connectionID); 599 $this->database = $dbName; 600 $this->databaseName = $dbName; # obsolete, retained for compat with older adodb versions 601 602 if ($this->_connectionID) { 603 $result = @mysqli_select_db($this->_connectionID, $dbName); 604 if (!$result) { 605 ADOConnection::outp("Select of database " . $dbName . " failed. " . $this->ErrorMsg()); 606 } 607 return $result; 608 } 609 return false; 610 } 611 612 // parameters use PostgreSQL convention, not MySQL 613 function &SelectLimit($sql, 614 $nrows = -1, 615 $offset = -1, 616 $inputarr = false, 617 $secs = 0) 618 { 619 $offsetStr = ($offset >= 0) ? "$offset," : ''; 620 if ($nrows < 0) $nrows = '18446744073709551615'; 621 622 if ($secs) 623 $rs =& $this->CacheExecute($secs, $sql . " LIMIT $offsetStr$nrows" , $inputarr); 624 else 625 $rs =& $this->Execute($sql . " LIMIT $offsetStr$nrows" , $inputarr); 626 627 return $rs; 628 } 629 630 631 function Prepare($sql) 632 { 633 return $sql; 634 635 $stmt = $this->_connectionID->prepare($sql); 636 if (!$stmt) { 637 echo $this->ErrorMsg(); 638 return $sql; 639 } 640 return array($sql,$stmt); 641 } 642 643 644 // returns queryID or false 645 function _query($sql, $inputarr) 646 { 647 global $ADODB_COUNTRECS; 648 649 if (is_array($sql)) { 650 $stmt = $sql[1]; 651 $a = ''; 652 foreach($inputarr as $k => $v) { 653 if (is_string($v)) $a .= 's'; 654 else if (is_integer($v)) $a .= 'i'; 655 else $a .= 'd'; 656 } 657 658 $fnarr = array_merge( array($stmt,$a) , $inputarr); 659 $ret = call_user_func_array('mysqli_stmt_bind_param',$fnarr); 660 661 $ret = mysqli_stmt_execute($stmt); 662 return $ret; 663 } 664 if (!$mysql_res = mysqli_query($this->_connectionID, $sql, ($ADODB_COUNTRECS) ? MYSQLI_STORE_RESULT : MYSQLI_USE_RESULT)) { 665 if ($this->debug) ADOConnection::outp("Query: " . $sql . " failed. " . $this->ErrorMsg()); 666 return false; 667 } 668 669 return $mysql_res; 670 } 671 672 /* Returns: the last error message from previous database operation */ 673 function ErrorMsg() 674 { 675 if (empty($this->_connectionID)) 676 $this->_errorMsg = @mysqli_connect_error(); 677 else 678 $this->_errorMsg = @mysqli_error($this->_connectionID); 679 return $this->_errorMsg; 680 } 681 682 /* Returns: the last error number from previous database operation */ 683 function ErrorNo() 684 { 685 if (empty($this->_connectionID)) 686 return @mysqli_connect_errno(); 687 else 688 return @mysqli_errno($this->_connectionID); 689 } 690 691 // returns true or false 692 function _close() 693 { 694 @mysqli_close($this->_connectionID); 695 $this->_connectionID = false; 696 } 697 698 /* 699 * Maximum size of C field 700 */ 701 function CharMax() 702 { 703 return 255; 704 } 705 706 /* 707 * Maximum size of X field 708 */ 709 function TextMax() 710 { 711 return 4294967295; 712 } 713 714 715 716 // this is a set of functions for managing client encoding - very important if the encodings 717 // of your database and your output target (i.e. HTML) don't match 718 // for instance, you may have UTF8 database and server it on-site as latin1 etc. 719 // GetCharSet - get the name of the character set the client is using now 720 // Under Windows, the functions should work with MySQL 4.1.11 and above, the set of charsets supported 721 // depends on compile flags of mysql distribution 722 723 function GetCharSet() 724 { 725 //we will use ADO's builtin property charSet 726 if (!method_exists($this->_connectionID,'character_set_name')) 727 return false; 728 729 $this->charSet = @$this->_connectionID->character_set_name(); 730 if (!$this->charSet) { 731 return false; 732 } else { 733 return $this->charSet; 734 } 735 } 736 737 // SetCharSet - switch the client encoding 738 function SetCharSet($charset_name) 739 { 740 if (!method_exists($this->_connectionID,'set_charset')) 741 return false; 742 743 if ($this->charSet !== $charset_name) { 744 $if = @$this->_connectionID->set_charset($charset_name); 745 if ($if == "0" & $this->GetCharSet() == $charset_name) { 746 return true; 747 } else return false; 748 } else return true; 749 } 750 751 752 753 754 } 755 756 /*-------------------------------------------------------------------------------------- 757 Class Name: Recordset 758 --------------------------------------------------------------------------------------*/ 759 760 class ADORecordSet_mysqli extends ADORecordSet{ 761 762 var $databaseType = "mysqli"; 763 var $canSeek = true; 764 765 function ADORecordSet_mysqli($queryID, $mode = false) 766 { 767 if ($mode === false) 768 { 769 global $ADODB_FETCH_MODE; 770 $mode = $ADODB_FETCH_MODE; 771 } 772 773 switch ($mode) 774 { 775 case ADODB_FETCH_NUM: 776 $this->fetchMode = MYSQLI_NUM; 777 break; 778 case ADODB_FETCH_ASSOC: 779 $this->fetchMode = MYSQLI_ASSOC; 780 break; 781 case ADODB_FETCH_DEFAULT: 782 case ADODB_FETCH_BOTH: 783 default: 784 $this->fetchMode = MYSQLI_BOTH; 785 break; 786 } 787 $this->adodbFetchMode = $mode; 788 $this->ADORecordSet($queryID); 789 } 790 791 function _initrs() 792 { 793 global $ADODB_COUNTRECS; 794 795 $this->_numOfRows = $ADODB_COUNTRECS ? @mysqli_num_rows($this->_queryID) : -1; 796 $this->_numOfFields = @mysqli_num_fields($this->_queryID); 797 } 798 799 /* 800 1 = MYSQLI_NOT_NULL_FLAG 801 2 = MYSQLI_PRI_KEY_FLAG 802 4 = MYSQLI_UNIQUE_KEY_FLAG 803 8 = MYSQLI_MULTIPLE_KEY_FLAG 804 16 = MYSQLI_BLOB_FLAG 805 32 = MYSQLI_UNSIGNED_FLAG 806 64 = MYSQLI_ZEROFILL_FLAG 807 128 = MYSQLI_BINARY_FLAG 808 256 = MYSQLI_ENUM_FLAG 809 512 = MYSQLI_AUTO_INCREMENT_FLAG 810 1024 = MYSQLI_TIMESTAMP_FLAG 811 2048 = MYSQLI_SET_FLAG 812 32768 = MYSQLI_NUM_FLAG 813 16384 = MYSQLI_PART_KEY_FLAG 814 32768 = MYSQLI_GROUP_FLAG 815 65536 = MYSQLI_UNIQUE_FLAG 816 131072 = MYSQLI_BINCMP_FLAG 817 */ 818 819 function &FetchField($fieldOffset = -1) 820 { 821 $fieldnr = $fieldOffset; 822 if ($fieldOffset != -1) { 823 $fieldOffset = mysqli_field_seek($this->_queryID, $fieldnr); 824 } 825 $o = mysqli_fetch_field($this->_queryID); 826 /* Properties of an ADOFieldObject as set by MetaColumns */ 827 $o->primary_key = $o->flags & MYSQLI_PRI_KEY_FLAG; 828 $o->not_null = $o->flags & MYSQLI_NOT_NULL_FLAG; 829 $o->auto_increment = $o->flags & MYSQLI_AUTO_INCREMENT_FLAG; 830 $o->binary = $o->flags & MYSQLI_BINARY_FLAG; 831 // $o->blob = $o->flags & MYSQLI_BLOB_FLAG; /* not returned by MetaColumns */ 832 $o->unsigned = $o->flags & MYSQLI_UNSIGNED_FLAG; 833 834 return $o; 835 } 836 837 function &GetRowAssoc($upper = true) 838 { 839 if ($this->fetchMode == MYSQLI_ASSOC && !$upper) 840 return $this->fields; 841 $row =& ADORecordSet::GetRowAssoc($upper); 842 return $row; 843 } 844 845 /* Use associative array to get fields array */ 846 function Fields($colname) 847 { 848 if ($this->fetchMode != MYSQLI_NUM) 849 return @$this->fields[$colname]; 850 851 if (!$this->bind) { 852 $this->bind = array(); 853 for ($i = 0; $i < $this->_numOfFields; $i++) { 854 $o = $this->FetchField($i); 855 $this->bind[strtoupper($o->name)] = $i; 856 } 857 } 858 return $this->fields[$this->bind[strtoupper($colname)]]; 859 } 860 861 function _seek($row) 862 { 863 if ($this->_numOfRows == 0) 864 return false; 865 866 if ($row < 0) 867 return false; 868 869 mysqli_data_seek($this->_queryID, $row); 870 $this->EOF = false; 871 return true; 872 } 873 874 // 10% speedup to move MoveNext to child class 875 // This is the only implementation that works now (23-10-2003). 876 // Other functions return no or the wrong results. 877 function MoveNext() 878 { 879 if ($this->EOF) return false; 880 $this->_currentRow++; 881 $this->fields = @mysqli_fetch_array($this->_queryID,$this->fetchMode); 882 883 if (is_array($this->fields)) return true; 884 $this->EOF = true; 885 return false; 886 } 887 888 function _fetch() 889 { 890 $this->fields = mysqli_fetch_array($this->_queryID,$this->fetchMode); 891 return is_array($this->fields); 892 } 893 894 function _close() 895 { 896 mysqli_free_result($this->_queryID); 897 $this->_queryID = false; 898 } 899 900 /* 901 902 0 = MYSQLI_TYPE_DECIMAL 903 1 = MYSQLI_TYPE_CHAR 904 1 = MYSQLI_TYPE_TINY 905 2 = MYSQLI_TYPE_SHORT 906 3 = MYSQLI_TYPE_LONG 907 4 = MYSQLI_TYPE_FLOAT 908 5 = MYSQLI_TYPE_DOUBLE 909 6 = MYSQLI_TYPE_NULL 910 7 = MYSQLI_TYPE_TIMESTAMP 911 8 = MYSQLI_TYPE_LONGLONG 912 9 = MYSQLI_TYPE_INT24 913 10 = MYSQLI_TYPE_DATE 914 11 = MYSQLI_TYPE_TIME 915 12 = MYSQLI_TYPE_DATETIME 916 13 = MYSQLI_TYPE_YEAR 917 14 = MYSQLI_TYPE_NEWDATE 918 247 = MYSQLI_TYPE_ENUM 919 248 = MYSQLI_TYPE_SET 920 249 = MYSQLI_TYPE_TINY_BLOB 921 250 = MYSQLI_TYPE_MEDIUM_BLOB 922 251 = MYSQLI_TYPE_LONG_BLOB 923 252 = MYSQLI_TYPE_BLOB 924 253 = MYSQLI_TYPE_VAR_STRING 925 254 = MYSQLI_TYPE_STRING 926 255 = MYSQLI_TYPE_GEOMETRY 927 */ 928 929 function MetaType($t, $len = -1, $fieldobj = false) 930 { 931 if (is_object($t)) { 932 $fieldobj = $t; 933 $t = $fieldobj->type; 934 $len = $fieldobj->max_length; 935 } 936 937 938 $len = -1; // mysql max_length is not accurate 939 switch (strtoupper($t)) { 940 case 'STRING': 941 case 'CHAR': 942 case 'VARCHAR': 943 case 'TINYBLOB': 944 case 'TINYTEXT': 945 case 'ENUM': 946 case 'SET': 947 948 case MYSQLI_TYPE_TINY_BLOB : 949 #case MYSQLI_TYPE_CHAR : 950 case MYSQLI_TYPE_STRING : 951 case MYSQLI_TYPE_ENUM : 952 case MYSQLI_TYPE_SET : 953 case 253 : 954 if ($len <= $this->blobSize) return 'C'; 955 956 case 'TEXT': 957 case 'LONGTEXT': 958 case 'MEDIUMTEXT': 959 return 'X'; 960 961 962 // php_mysql extension always returns 'blob' even if 'text' 963 // so we have to check whether binary... 964 case 'IMAGE': 965 case 'LONGBLOB': 966 case 'BLOB': 967 case 'MEDIUMBLOB': 968 969 case MYSQLI_TYPE_BLOB : 970 case MYSQLI_TYPE_LONG_BLOB : 971 case MYSQLI_TYPE_MEDIUM_BLOB : 972 973 return !empty($fieldobj->binary) ? 'B' : 'X'; 974 case 'YEAR': 975 case 'DATE': 976 case MYSQLI_TYPE_DATE : 977 case MYSQLI_TYPE_YEAR : 978 979 return 'D'; 980 981 case 'TIME': 982 case 'DATETIME': 983 case 'TIMESTAMP': 984 985 case MYSQLI_TYPE_DATETIME : 986 case MYSQLI_TYPE_NEWDATE : 987 case MYSQLI_TYPE_TIME : 988 case MYSQLI_TYPE_TIMESTAMP : 989 990 return 'T'; 991 992 case 'INT': 993 case 'INTEGER': 994 case 'BIGINT': 995 case 'TINYINT': 996 case 'MEDIUMINT': 997 case 'SMALLINT': 998 999 case MYSQLI_TYPE_INT24 : 1000 case MYSQLI_TYPE_LONG : 1001 case MYSQLI_TYPE_LONGLONG : 1002 case MYSQLI_TYPE_SHORT : 1003 case MYSQLI_TYPE_TINY : 1004 1005 if (!empty($fieldobj->primary_key)) return 'R'; 1006 1007 return 'I'; 1008 1009 1010 // Added floating-point types 1011 // Maybe not necessery. 1012 case 'FLOAT': 1013 case 'DOUBLE': 1014 // case 'DOUBLE PRECISION': 1015 case 'DECIMAL': 1016 case 'DEC': 1017 case 'FIXED': 1018 default: 1019 //if (!is_numeric($t)) echo "<p>--- Error in type matching $t -----</p>"; 1020 return 'N'; 1021 } 1022 } // function 1023 1024 1025 } // rs class 1026 1027 } 1028 1029 class ADORecordSet_array_mysqli extends ADORecordSet_array { 1030 function ADORecordSet_array_mysqli($id=-1,$mode=false) 1031 { 1032 $this->ADORecordSet_array($id,$mode); 1033 } 1034 1035 1036 function MetaType($t, $len = -1, $fieldobj = false) 1037 { 1038 if (is_object($t)) { 1039 $fieldobj = $t; 1040 $t = $fieldobj->type; 1041 $len = $fieldobj->max_length; 1042 } 1043 1044 1045 $len = -1; // mysql max_length is not accurate 1046 switch (strtoupper($t)) { 1047 case 'STRING': 1048 case 'CHAR': 1049 case 'VARCHAR': 1050 case 'TINYBLOB': 1051 case 'TINYTEXT': 1052 case 'ENUM': 1053 case 'SET': 1054 1055 case MYSQLI_TYPE_TINY_BLOB : 1056 #case MYSQLI_TYPE_CHAR : 1057 case MYSQLI_TYPE_STRING : 1058 case MYSQLI_TYPE_ENUM : 1059 case MYSQLI_TYPE_SET : 1060 case 253 : 1061 if ($len <= $this->blobSize) return 'C'; 1062 1063 case 'TEXT': 1064 case 'LONGTEXT': 1065 case 'MEDIUMTEXT': 1066 return 'X'; 1067 1068 1069 // php_mysql extension always returns 'blob' even if 'text' 1070 // so we have to check whether binary... 1071 case 'IMAGE': 1072 case 'LONGBLOB': 1073 case 'BLOB': 1074 case 'MEDIUMBLOB': 1075 1076 case MYSQLI_TYPE_BLOB : 1077 case MYSQLI_TYPE_LONG_BLOB : 1078 case MYSQLI_TYPE_MEDIUM_BLOB : 1079 1080 return !empty($fieldobj->binary) ? 'B' : 'X'; 1081 case 'YEAR': 1082 case 'DATE': 1083 case MYSQLI_TYPE_DATE : 1084 case MYSQLI_TYPE_YEAR : 1085 1086 return 'D'; 1087 1088 case 'TIME': 1089 case 'DATETIME': 1090 case 'TIMESTAMP': 1091 1092 case MYSQLI_TYPE_DATETIME : 1093 case MYSQLI_TYPE_NEWDATE : 1094 case MYSQLI_TYPE_TIME : 1095 case MYSQLI_TYPE_TIMESTAMP : 1096 1097 return 'T'; 1098 1099 case 'INT': 1100 case 'INTEGER': 1101 case 'BIGINT': 1102 case 'TINYINT': 1103 case 'MEDIUMINT': 1104 case 'SMALLINT': 1105 1106 case MYSQLI_TYPE_INT24 : 1107 case MYSQLI_TYPE_LONG : 1108 case MYSQLI_TYPE_LONGLONG : 1109 case MYSQLI_TYPE_SHORT : 1110 case MYSQLI_TYPE_TINY : 1111 1112 if (!empty($fieldobj->primary_key)) return 'R'; 1113 1114 return 'I'; 1115 1116 1117 // Added floating-point types 1118 // Maybe not necessery. 1119 case 'FLOAT': 1120 case 'DOUBLE': 1121 // case 'DOUBLE PRECISION': 1122 case 'DECIMAL': 1123 case 'DEC': 1124 case 'FIXED': 1125 default: 1126 //if (!is_numeric($t)) echo "<p>--- Error in type matching $t -----</p>"; 1127 return 'N'; 1128 } 1129 } // function 1130 1131 } 1132 1133 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Wed Jan 14 11:33:29 2009 | Cross-referenced by PHPXref 0.7 |