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. See License.txt.
7 Set tabs to 4 for best viewing.
9 Latest version is available at http://adodb.sourceforge.net
11 Library for basic performance monitoring and tuning.
13 My apologies if you see code mixed with presentation. The presentation suits
14 my needs. If you want to separate code from presentation, be my guest. Patches
19 if (!defined('ADODB_DIR')) include_once(dirname(__FILE__
).'/adodb.inc.php');
20 include_once(ADODB_DIR
.'/tohtml.inc.php');
22 global $ADODB_PERF_MIN;
23 $ADODB_PERF_MIN = 0.05; // log only if >= minimum number of secs to run
25 define( 'ADODB_OPT_HIGH', 2);
26 define( 'ADODB_OPT_LOW', 1);
28 // returns in K the memory of current process, or 0 if not known
29 function adodb_getmem()
31 if (function_exists('memory_get_usage'))
32 return (integer) ((memory_get_usage()+
512)/1024);
36 if ( strncmp(strtoupper(PHP_OS
),'WIN',3)==0) {
39 exec('tasklist /FI "PID eq ' . $pid. '" /FO LIST', $output);
40 return substr($output[5], strpos($output[5], ':') +
1);
44 exec("ps --pid $pid --no-headers -o%mem,size", $output);
45 if (sizeof($output) == 0) return 0;
47 $memarr = explode(' ',$output[0]);
48 if (sizeof($memarr)>=2) return (integer) $memarr[1];
53 // avoids localization problems where , is used instead of .
54 function adodb_round($n,$prec)
56 return number_format($n, $prec, '.', '');
59 /* return microtime value as a float */
60 function adodb_microtime()
64 return (float)$t[1]+
(float)$t[0];
68 function& adodb_log_sql(&$connx,$sql,$inputarr)
70 $perf_table = adodb_perf
::table();
71 $connx->fnExecute
= false;
73 $rs =& $connx->Execute($sql,$inputarr);
76 if (!empty($connx->_logsql
) && (empty($connx->_logsqlErrors
) ||
!$rs)) {
77 global $ADODB_LOG_CONN;
79 if (!empty($ADODB_LOG_CONN)) {
80 $conn = &$ADODB_LOG_CONN;
81 if ($conn->databaseType
!= $connx->databaseType
)
82 $prefix = '/*dbx='.$connx->databaseType
.'*/ ';
90 $conn->_logsql
= false; // disable logsql error simulation
91 $dbT = $conn->databaseType
;
94 $a0 = (float)$a0[1]+
(float)$a0[0];
97 $a1 = (float)$a1[1]+
(float)$a1[0];
102 $errM = $connx->ErrorMsg();
103 $errN = $connx->ErrorNo();
104 $conn->lastInsID
= 0;
105 $tracer = substr('ERROR: '.htmlspecialchars($errM),0,250);
111 $conn->debug
= false;
112 if (!is_object($rs) ||
$rs->dataProvider
== 'empty')
113 $conn->_affected
= $conn->affected_rows(true);
114 $conn->lastInsID
= @$conn->Insert_ID();
117 if (isset($_SERVER['HTTP_HOST'])) {
118 $tracer .= '<br>'.$_SERVER['HTTP_HOST'];
119 if (isset($_SERVER['PHP_SELF'])) $tracer .= $_SERVER['PHP_SELF'];
121 if (isset($_SERVER['PHP_SELF'])) $tracer .= '<br>'.$_SERVER['PHP_SELF'];
122 //$tracer .= (string) adodb_backtrace(false);
124 $tracer = (string) substr($tracer,0,500);
126 if (is_array($inputarr)) {
127 if (is_array(reset($inputarr))) $params = 'Array sizeof='.sizeof($inputarr);
129 // Quote string parameters so we can see them in the
130 // performance stats. This helps spot disabled indexes.
131 $xar_params = $inputarr;
132 foreach ($xar_params as $xar_param_key => $xar_param) {
133 if (gettype($xar_param) == 'string')
134 $xar_params[$xar_param_key] = '"' . $xar_param . '"';
136 $params = implode(', ', $xar_params);
137 if (strlen($params) >= 3000) $params = substr($params, 0, 3000);
143 if (is_array($sql)) $sql = $sql[0];
144 if ($prefix) $sql = $prefix.$sql;
145 $arr = array('b'=>strlen($sql).'.'.crc32($sql),
146 'c'=>substr($sql,0,3900), 'd'=>$params,'e'=>$tracer,'f'=>adodb_round($time,6));
148 $saved = $conn->debug
;
151 $d = $conn->sysTimeStamp
;
152 if (empty($d)) $d = date("'Y-m-d H:i:s'");
153 if ($conn->dataProvider
== 'oci8' && $dbT != 'oci8po') {
154 $isql = "insert into $perf_table values($d,:b,:c,:d,:e,:f)";
155 } else if ($dbT == 'odbc_mssql' ||
$dbT == 'informix' ||
strncmp($dbT,'odbtp',4)==0) {
157 if ($dbT == 'informix') $sql2 = substr($sql2,0,230);
159 $sql1 = $conn->qstr($arr['b']);
160 $sql2 = $conn->qstr($arr['c']);
161 $params = $conn->qstr($arr['d']);
162 $tracer = $conn->qstr($arr['e']);
164 $isql = "insert into $perf_table (created,sql0,sql1,params,tracer,timer) values($d,$sql1,$sql2,$params,$tracer,$timer)";
165 if ($dbT == 'informix') $isql = str_replace(chr(10),' ',$isql);
168 if ($dbT == 'db2') $arr['f'] = (float) $arr['f'];
169 $isql = "insert into $perf_table (created,sql0,sql1,params,tracer,timer) values( $d,?,?,?,?,?)";
171 global $ADODB_PERF_MIN;
172 if ($errN != 0 ||
$time >= $ADODB_PERF_MIN) {
173 $ok = $conn->Execute($isql,$arr);
177 $conn->debug
= $saved;
180 $conn->_logsql
= true;
182 $err2 = $conn->ErrorMsg();
183 $conn->_logsql
= true; // enable logsql error simulation
184 $perf =& NewPerfMonitor($conn);
186 if ($perf->CreateLogTable()) $ok = $conn->Execute($isql,$arr);
188 $ok = $conn->Execute("create table $perf_table (
192 params varchar(3000),
194 timer decimal(16,6))");
197 ADOConnection
::outp( "<p><b>LOGSQL Insert Failed</b>: $isql<br>$err2</p>");
198 $conn->_logsql
= false;
201 $connx->_errorMsg
= $errM;
202 $connx->_errorCode
= $errN;
204 $connx->fnExecute
= 'adodb_log_sql';
210 The settings data structure is an associative array that database parameter per element.
212 Each database parameter element in the array is itself an array consisting of:
214 0: category code, used to group related db parameters
216 a. sql string to retrieve value, eg. "select value from v\$parameter where name='db_block_size'",
217 b. array holding sql string and field to look for, e.g. array('show variables','table_cache'),
218 c. a string prefixed by =, then a PHP method of the class is invoked,
219 e.g. to invoke $this->GetIndexValue(), set this array element to '=GetIndexValue',
220 2: description of the database parameter
225 var $color = '#F0F0F0';
226 var $table = '<table border=1 bgcolor=white>';
227 var $titles = '<tr><td><b>Parameter</b></td><td><b>Value</b></td><td><b>Description</b></td></tr>';
229 var $tablesSQL = false;
230 var $cliFormat = "%32s => %s \r\n";
231 var $sql1 = 'sql1'; // used for casting sql1 to text for mssql
233 var $helpurl = "<a href=http://phplens.com/adodb/reference.functions.fnexecute.and.fncacheexecute.properties.html#logsql>LogSQL help</a>";
234 var $createTableSQL = false;
235 var $maxLength = 2000;
237 // Sets the tablename to be used
238 function table($newtable = false)
242 if (!empty($newtable)) $_table = $newtable;
243 if (empty($_table)) $_table = 'adodb_logsql';
247 // returns array with info to calculate CPU Load
252 cpu 524152 2662 2515228 336057010
253 cpu0 264339 1408 1257951 168025827
254 cpu1 259813 1254 1257277 168031181
257 intr 890153570 868093576 6 0 4 4 0 6 1 2 0 0 0 124 0 8098760 2 13961053 0 0 0 0 0 0 0 0 0 0 0 0 0 16 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
258 disk_io: (3,0):(3144904,54369,610378,3090535,50936192) (3,1):(3630212,54097,633016,3576115,50951320)
264 // Algorithm is taken from
265 // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/example__obtaining_raw_performance_data.asp
266 if (strncmp(PHP_OS
,'WIN',3)==0) {
267 if (PHP_VERSION
== '5.0.0') return false;
268 if (PHP_VERSION
== '5.0.1') return false;
269 if (PHP_VERSION
== '5.0.2') return false;
270 if (PHP_VERSION
== '5.0.3') return false;
271 if (PHP_VERSION
== '4.3.10') return false; # see http://bugs.php.net/bug.php?id=31737
273 @$c = new COM("WinMgmts:{impersonationLevel=impersonate}!Win32_PerfRawData_PerfOS_Processor.Name='_Total'");
274 if (!$c) return false;
276 $info[0] = $c->PercentProcessorTime
;
279 $info[3] = $c->TimeStamp_Sys100NS
;
284 // Algorithm - Steve Blinch (BlitzAffe Online, http://www.blitzaffe.com)
285 $statfile = '/proc/stat';
286 if (!file_exists($statfile)) return false;
288 $fd = fopen($statfile,"r");
289 if (!$fd) return false;
291 $statinfo = explode("\n",fgets($fd, 1024));
293 foreach($statinfo as $line) {
294 $info = explode(" ",$line);
295 if($info[0]=="cpu") {
296 array_shift($info); // pop off "cpu"
297 if(!$info[0]) array_shift($info); // pop off blank space (if any)
306 /* NOT IMPLEMENTED */
311 total: used: free: shared: buffers: cached:
312 Mem: 1055289344 917299200 137990144 0 165437440 599773184
313 Swap: 2146775040 11055104 2135719936
321 Inact_dirty: 322856 kB
322 Inact_clean: 24256 kB
323 Inact_target: 168316 kB
328 SwapTotal: 2096460 kB
330 Committed_AS: 348732 kB
336 Remember that this is client load, not db server load!
341 $info = $this->_CPULoad();
342 if (!$info) return false;
344 if (empty($this->_lastLoad
)) {
346 $this->_lastLoad
= $info;
347 $info = $this->_CPULoad();
350 $last = $this->_lastLoad
;
351 $this->_lastLoad
= $info;
353 $d_user = $info[0] - $last[0];
354 $d_nice = $info[1] - $last[1];
355 $d_system = $info[2] - $last[2];
356 $d_idle = $info[3] - $last[3];
358 //printf("Delta - User: %f Nice: %f System: %f Idle: %f<br>",$d_user,$d_nice,$d_system,$d_idle);
360 if (strncmp(PHP_OS
,'WIN',3)==0) {
361 if ($d_idle < 1) $d_idle = 1;
362 return 100*(1-$d_user/$d_idle);
364 $total=$d_user+
$d_nice+
$d_system+
$d_idle;
365 if ($total<1) $total=1;
366 return 100*($d_user+
$d_nice+
$d_system)/$total;
370 function Tracer($sql)
372 $perf_table = adodb_perf
::table();
373 $saveE = $this->conn
->fnExecute
;
374 $this->conn
->fnExecute
= false;
376 global $ADODB_FETCH_MODE;
377 $save = $ADODB_FETCH_MODE;
378 $ADODB_FETCH_MODE = ADODB_FETCH_NUM
;
379 if ($this->conn
->fetchMode
!== false) $savem = $this->conn
->SetFetchMode(false);
381 $sqlq = $this->conn
->qstr($sql);
382 $arr = $this->conn
->GetArray(
383 "select count(*),tracer
384 from $perf_table where sql1=$sqlq
389 $s .= '<h3>Scripts Affected</h3>';
390 foreach($arr as $k) {
391 $s .= sprintf("%4d",$k[0]).' '.strip_tags($k[1]).'<br>';
395 if (isset($savem)) $this->conn
->SetFetchMode($savem);
396 $ADODB_CACHE_MODE = $save;
397 $this->conn
->fnExecute
= $saveE;
402 Explain Plan for $sql.
403 If only a snippet of the $sql is passed in, then $partial will hold the crc32 of the
406 function Explain($sql,$partial=false)
411 function InvalidSQL($numsql = 10)
414 if (isset($_GET['sql'])) return;
415 $s = '<h3>Invalid SQL</h3>';
416 $saveE = $this->conn
->fnExecute
;
417 $this->conn
->fnExecute
= false;
418 $perf_table = adodb_perf
::table();
419 $rs =& $this->conn
->SelectLimit("select distinct count(*),sql1,tracer as error_msg from $perf_table where tracer like 'ERROR:%' group by sql1,tracer order by 1 desc",$numsql);//,$numsql);
420 $this->conn
->fnExecute
= $saveE;
422 $s .= rs2html($rs,false,false,false,false);
424 return "<p>$this->helpurl. ".$this->conn
->ErrorMsg()."</p>";
431 This script identifies the longest running SQL
433 function _SuspiciousSQL($numsql = 10)
435 global $ADODB_FETCH_MODE;
437 $perf_table = adodb_perf
::table();
438 $saveE = $this->conn
->fnExecute
;
439 $this->conn
->fnExecute
= false;
441 if (isset($_GET['exps']) && isset($_GET['sql'])) {
442 $partial = !empty($_GET['part']);
443 echo "<a name=explain></a>".$this->Explain($_GET['sql'],$partial)."\n";
446 if (isset($_GET['sql'])) return;
449 $save = $ADODB_FETCH_MODE;
450 $ADODB_FETCH_MODE = ADODB_FETCH_NUM
;
451 if ($this->conn
->fetchMode
!== false) $savem = $this->conn
->SetFetchMode(false);
452 //$this->conn->debug=1;
453 $rs =& $this->conn
->SelectLimit(
454 "select avg(timer) as avg_timer,$sql1,count(*),max(timer) as max_timer,min(timer) as min_timer
456 where {$this->conn->upperCase}({$this->conn->substr}(sql0,1,5)) not in ('DROP ','INSER','COMMI','CREAT')
457 and (tracer is null or tracer not like 'ERROR:%')
459 order by 1 desc",$numsql);
460 if (isset($savem)) $this->conn
->SetFetchMode($savem);
461 $ADODB_FETCH_MODE = $save;
462 $this->conn
->fnExecute
= $saveE;
464 if (!$rs) return "<p>$this->helpurl. ".$this->conn
->ErrorMsg()."</p>";
465 $s = "<h3>Suspicious SQL</h3>
466 <font size=1>The following SQL have high average execution times</font><br>
467 <table border=1 bgcolor=white><tr><td><b>Avg Time</b><td><b>Count</b><td><b>SQL</b><td><b>Max</b><td><b>Min</b></tr>\n";
468 $max = $this->maxLength
;
470 $sql = $rs->fields
[1];
471 $raw = urlencode($sql);
472 if (strlen($raw)>$max-100) {
473 $sql2 = substr($sql,0,$max-500);
474 $raw = urlencode($sql2).'&part='.crc32($sql);
476 $prefix = "<a target=sql".rand()." href=\"?hidem=1&exps=1&sql=".$raw."&x#explain\">";
478 if ($this->explain
== false ||
strlen($prefix)>$max) {
479 $suffix = ' ... <i>String too long for GET parameter: '.strlen($prefix).'</i>';
482 $s .= "<tr><td>".adodb_round($rs->fields
[0],6)."<td align=right>".$rs->fields
[2]."<td><font size=-1>".$prefix.htmlspecialchars($sql).$suffix."</font>".
483 "<td>".$rs->fields
[3]."<td>".$rs->fields
[4]."</tr>";
486 return $s."</table>";
490 function CheckMemory()
496 function SuspiciousSQL($numsql=10)
498 return adodb_perf
::_SuspiciousSQL($numsql);
501 function ExpensiveSQL($numsql=10)
503 return adodb_perf
::_ExpensiveSQL($numsql);
508 This reports the percentage of load on the instance due to the most
509 expensive few SQL statements. Tuning these statements can often
510 make huge improvements in overall system performance.
512 function _ExpensiveSQL($numsql = 10)
514 global $ADODB_FETCH_MODE;
516 $perf_table = adodb_perf
::table();
517 $saveE = $this->conn
->fnExecute
;
518 $this->conn
->fnExecute
= false;
520 if (isset($_GET['expe']) && isset($_GET['sql'])) {
521 $partial = !empty($_GET['part']);
522 echo "<a name=explain></a>".$this->Explain($_GET['sql'],$partial)."\n";
525 if (isset($_GET['sql'])) return;
528 $save = $ADODB_FETCH_MODE;
529 $ADODB_FETCH_MODE = ADODB_FETCH_NUM
;
530 if ($this->conn
->fetchMode
!== false) $savem = $this->conn
->SetFetchMode(false);
532 $rs =& $this->conn
->SelectLimit(
533 "select sum(timer) as total,$sql1,count(*),max(timer) as max_timer,min(timer) as min_timer
535 where {$this->conn->upperCase}({$this->conn->substr}(sql0,1,5)) not in ('DROP ','INSER','COMMI','CREAT')
536 and (tracer is null or tracer not like 'ERROR:%')
539 order by 1 desc",$numsql);
540 if (isset($savem)) $this->conn
->SetFetchMode($savem);
541 $this->conn
->fnExecute
= $saveE;
542 $ADODB_FETCH_MODE = $save;
543 if (!$rs) return "<p>$this->helpurl. ".$this->conn
->ErrorMsg()."</p>";
544 $s = "<h3>Expensive SQL</h3>
545 <font size=1>Tuning the following SQL could reduce the server load substantially</font><br>
546 <table border=1 bgcolor=white><tr><td><b>Load</b><td><b>Count</b><td><b>SQL</b><td><b>Max</b><td><b>Min</b></tr>\n";
547 $max = $this->maxLength
;
549 $sql = $rs->fields
[1];
550 $raw = urlencode($sql);
551 if (strlen($raw)>$max-100) {
552 $sql2 = substr($sql,0,$max-500);
553 $raw = urlencode($sql2).'&part='.crc32($sql);
555 $prefix = "<a target=sqle".rand()." href=\"?hidem=1&expe=1&sql=".$raw."&x#explain\">";
557 if($this->explain
== false ||
strlen($prefix>$max)) {
561 $s .= "<tr><td>".adodb_round($rs->fields
[0],6)."<td align=right>".$rs->fields
[2]."<td><font size=-1>".$prefix.htmlspecialchars($sql).$suffix."</font>".
562 "<td>".$rs->fields
[3]."<td>".$rs->fields
[4]."</tr>";
565 return $s."</table>";
569 Raw function to return parameter value from $settings.
571 function DBParameter($param)
573 if (empty($this->settings
[$param])) return false;
574 $sql = $this->settings
[$param][1];
575 return $this->_DBParameter($sql);
579 Raw function returning array of poll paramters
581 function &PollParameters()
583 $arr[0] = (float)$this->DBParameter('data cache hit ratio');
584 $arr[1] = (float)$this->DBParameter('data reads');
585 $arr[2] = (float)$this->DBParameter('data writes');
586 $arr[3] = (integer) $this->DBParameter('current connections');
591 Low-level Get Database Parameter
593 function _DBParameter($sql)
595 $savelog = $this->conn
->LogSQL(false);
596 if (is_array($sql)) {
597 global $ADODB_FETCH_MODE;
601 if (sizeof($sql)>2) $pos = $sql[2];
603 if (sizeof($sql)>3) $coef = $sql[3];
606 $save = $ADODB_FETCH_MODE;
607 $ADODB_FETCH_MODE = ADODB_FETCH_NUM
;
608 if ($this->conn
->fetchMode
!== false) $savem = $this->conn
->SetFetchMode(false);
610 $rs = $this->conn
->Execute($sql1);
612 if (isset($savem)) $this->conn
->SetFetchMode($savem);
613 $ADODB_FETCH_MODE = $save;
616 $keyf = reset($rs->fields
);
617 if (trim($keyf) == $key) {
618 $ret = $rs->fields
[$pos];
619 if ($coef) $ret *= $coef;
626 $this->conn
->LogSQL($savelog);
629 if (strncmp($sql,'=',1) == 0) {
630 $fn = substr($sql,1);
633 $sql = str_replace('$DATABASE',$this->conn
->database
,$sql);
634 $ret = $this->conn
->GetOne($sql);
635 $this->conn
->LogSQL($savelog);
642 Warn if cache ratio falls below threshold. Displayed in "Description" column.
644 function WarnCacheRatio($val)
646 if ($val < $this->warnRatio
)
647 return '<font color=red><b>Cache ratio should be at least '.$this->warnRatio
.'%</b></font>';
653 $perf_table = adodb_perf
::table();
654 $this->conn
->Execute("delete from $perf_table where created<".$this->conn
->sysTimeStamp
);
657 /***********************************************************************************************/
658 // HIGH LEVEL UI FUNCTIONS
659 /***********************************************************************************************/
662 function UI($pollsecs=5)
664 global $ADODB_LOG_CONN;
666 $perf_table = adodb_perf
::table();
670 if ($conn->host
&& $conn->database
) $app .= ', db=';
671 $app .= $conn->database
;
673 if ($app) $app .= ', ';
674 $savelog = $this->conn
->LogSQL(false);
675 $info = $conn->ServerInfo();
676 if (isset($_GET['clearsql'])) {
679 $this->conn
->LogSQL($savelog);
683 if (isset($_GET['sql']) && get_magic_quotes_gpc()) {
684 $_GET['sql'] = $_GET['sql'] = str_replace(array("\\'",'\"'),array("'",'"'),$_GET['sql']);
687 if (!isset($_SESSION['ADODB_PERF_SQL'])) $nsql = $_SESSION['ADODB_PERF_SQL'] = 10;
688 else $nsql = $_SESSION['ADODB_PERF_SQL'];
690 $app .= $info['description'];
693 if (isset($_GET['do'])) $do = $_GET['do'];
694 else if (isset($_POST['do'])) $do = $_POST['do'];
695 else if (isset($_GET['sql'])) $do = 'viewsql';
698 if (isset($_GET['nsql'])) {
699 if ($_GET['nsql'] > 0) $nsql = $_SESSION['ADODB_PERF_SQL'] = (integer) $_GET['nsql'];
701 echo "<title>ADOdb Performance Monitor on $app</title><body bgcolor=white>";
702 if ($do == 'viewsql') $form = "<td><form># SQL:<input type=hidden value=viewsql name=do> <input type=text size=4 name=nsql value=$nsql><input type=submit value=Go></td></form>";
703 else $form = "<td> </td>";
705 $allowsql = !defined('ADODB_PERF_NO_RUN_SQL');
706 global $ADODB_PERF_MIN;
707 $app .= " (Min sql timing \$ADODB_PERF_MIN=$ADODB_PERF_MIN secs)";
709 if (empty($_GET['hidem']))
710 echo "<table border=1 width=100% bgcolor=lightyellow><tr><td colspan=2>
711 <b><a href=http://adodb.sourceforge.net/?perf=1>ADOdb</a> Performance Monitor</b> <font size=1>for $app</font></tr><tr><td>
712 <a href=?do=stats><b>Performance Stats</b></a> <a href=?do=viewsql><b>View SQL</b></a>
713 <a href=?do=tables><b>View Tables</b></a> <a href=?do=poll><b>Poll Stats</b></a>",
714 $allowsql ?
' <a href=?do=dosql><b>Run SQL</b></a>' : '',
723 if (empty($ADODB_LOG_CONN))
724 echo "<p> <a href=\"?do=viewsql&clearsql=1\">Clear SQL Log</a><br>";
725 echo $this->HealthCheck();
726 //$this->conn->debug=1;
727 echo $this->CheckMemory();
728 global $ADODB_LOG_CONN;
731 echo "<iframe width=720 height=80%
732 src=\"{$_SERVER['PHP_SELF']}?do=poll2&hidem=1\"></iframe>";
736 $this->Poll($pollsecs);
740 if (!$allowsql) break;
745 if (empty($_GET['hidem']))
746 echo " <a href=\"?do=viewsql&clearsql=1\">Clear SQL Log</a><br>";
747 echo($this->SuspiciousSQL($nsql));
748 echo($this->ExpensiveSQL($nsql));
749 echo($this->InvalidSQL($nsql));
752 echo $this->Tables(); break;
755 echo "<p><div align=center><font size=1>$ADODB_vers Sponsored by <a href=http://phplens.com/>phpLens</a></font></div>";
759 Runs in infinite loop, returning real-time statistics
761 function Poll($secs=5)
763 $this->conn
->fnExecute
= false;
764 //$this->conn->debug=1;
765 if ($secs <= 1) $secs = 1;
766 echo "Accumulating statistics, every $secs seconds...\n";flush();
767 $arro =& $this->PollParameters();
773 $arr =& $this->PollParameters();
775 $hits = sprintf('%2.2f',$arr[0]);
776 $reads = sprintf('%12.4f',($arr[1]-$arro[1])/$secs);
777 $writes = sprintf('%12.4f',($arr[2]-$arro[2])/$secs);
778 $sess = sprintf('%5d',$arr[3]);
780 $load = $this->CPULoad();
781 if ($load !== false) {
782 $oslabel = 'WS-CPU%';
783 $osval = sprintf(" %2.1f ",(float) $load);
788 if ($cnt %
10 == 0) echo " Time ".$oslabel." Hit% Sess Reads/s Writes/s\n";
790 echo date('H:i:s').' '.$osval."$hits $sess $reads $writes\n";
793 if (connection_aborted()) return;
801 Returns basic health check in a command line interface
803 function HealthCheckCLI()
805 return $this->HealthCheck(true);
810 Returns basic health check as HTML
812 function HealthCheck($cli=false)
814 $saveE = $this->conn
->fnExecute
;
815 $this->conn
->fnExecute
= false;
816 if ($cli) $html = '';
817 else $html = $this->table
.'<tr><td colspan=3><h3>'.$this->conn
->databaseType
.'</h3></td></tr>'.$this->titles
;
821 foreach($this->settings
as $name => $arr) {
822 if ($arr === false) break;
824 if (!is_string($name)) {
825 if ($cli) $html .= " -- $arr -- \n";
826 else $html .= "<tr bgcolor=$this->color><td colspan=3><i>$arr</i> </td></tr>";
830 if (!is_array($arr)) break;
833 if (sizeof($arr)>2) $desc = $arr[2];
834 else $desc = ' ';
837 if ($category == 'HIDE') continue;
839 $val = $this->_DBParameter($how);
841 if ($desc && strncmp($desc,"=",1) === 0) {
842 $fn = substr($desc,1);
843 $desc = $this->$fn($val);
846 if ($val === false) {
847 $m = $this->conn
->ErrorMsg();
850 if (is_numeric($val) && $val >= 256*1024) {
851 if ($val %
(1024*1024) == 0) {
854 } else if ($val %
1024 == 0) {
858 //$val = htmlspecialchars($val);
861 if ($category != $oldc) {
863 //$bgc = ($bgc == ' bgcolor='.$this->color) ? ' bgcolor=white' : ' bgcolor='.$this->color;
865 if (strlen($desc)==0) $desc = ' ';
866 if (strlen($val)==0) $val = ' ';
868 $html .= str_replace(' ','',sprintf($this->cliFormat
,strip_tags($name),strip_tags($val),strip_tags($desc)));
871 $html .= "<tr$bgc><td>".$name.'</td><td>'.$val.'</td><td>'.$desc."</td></tr>\n";
875 if (!$cli) $html .= "</table>\n";
876 $this->conn
->fnExecute
= $saveE;
881 function Tables($orderby='1')
883 if (!$this->tablesSQL
) return false;
885 $savelog = $this->conn
->LogSQL(false);
886 $rs = $this->conn
->Execute($this->tablesSQL
.' order by '.$orderby);
887 $this->conn
->LogSQL($savelog);
888 $html = rs2html($rs,false,false,false,false);
893 function CreateLogTable()
895 if (!$this->createTableSQL
) return false;
897 $table = $this->table();
898 $sql = str_replace('adodb_logsql',$table,$this->createTableSQL
);
899 $savelog = $this->conn
->LogSQL(false);
900 $ok = $this->conn
->Execute($sql);
901 $this->conn
->LogSQL($savelog);
902 return ($ok) ?
true : false;
909 $PHP_SELF = $_SERVER['PHP_SELF'];
910 $sql = isset($_REQUEST['sql']) ?
$_REQUEST['sql'] : '';
912 if (isset($_SESSION['phplens_sqlrows'])) $rows = $_SESSION['phplens_sqlrows'];
915 if (isset($_REQUEST['SMALLER'])) {
917 if ($rows < 3) $rows = 3;
918 $_SESSION['phplens_sqlrows'] = $rows;
920 if (isset($_REQUEST['BIGGER'])) {
922 $_SESSION['phplens_sqlrows'] = $rows;
927 <form method
="POST" action
="<?php echo $PHP_SELF ?>">
929 <td
> Form size
: <input type
="submit" value
=" < " name
="SMALLER"><input type
="submit" value
=" > > " name
="BIGGER">
932 <input type
="submit" value
=" Run SQL Below " name
="RUN"><input type
=hidden name
=do value
=dosql
>
935 <td colspan
=2><textarea rows
=<?php
print $rows; ?
> name
="sql" cols
="80"><?php
print htmlspecialchars($sql) ?
></textarea
>
942 if (!isset($_REQUEST['sql'])) return;
944 $sql = $this->undomq(trim($sql));
945 if (substr($sql,strlen($sql)-1) === ';') {
947 $sqla = $this->SplitSQL($sql);
952 foreach($sqla as $sqls) {
954 if (!$sqls) continue;
957 print "<p>".htmlspecialchars($sqls)."</p>";
960 $savelog = $this->conn
->LogSQL(false);
961 $rs = $this->conn
->Execute($sqls);
962 $this->conn
->LogSQL($savelog);
963 if ($rs && is_object($rs) && !$rs->EOF
) {
965 while ($rs->NextRecordSet()) {
966 print "<table width=98% bgcolor=#C0C0FF><tr><td> </td></tr></table>";
970 $e1 = (integer) $this->conn
->ErrorNo();
971 $e2 = $this->conn
->ErrorMsg();
972 if (($e1) ||
($e2)) {
973 if (empty($e1)) $e1 = '-1'; // postgresql fix
974 print ' '.$e1.': '.$e2;
976 print "<p>No Recordset returned<br></p>";
982 function SplitSQL($sql)
984 $arr = explode(';',$sql);
990 if (get_magic_quotes_gpc()) {
992 $m = str_replace('\\\\','\\',$m);
993 $m = str_replace('\"','"',$m);
994 $m = str_replace('\\\'','\'',$m);
1000 /************************************************************************/
1003 * Reorganise multiple table-indices/statistics/..
1004 * OptimizeMode could be given by last Parameter
1008 * optimizeTables( 'tableA');
1011 * optimizeTables( 'tableA', 'tableB', 'tableC');
1014 * optimizeTables( 'tableA', 'tableB', ADODB_OPT_LOW);
1017 * @param string table name of the table to optimize
1018 * @param int mode optimization-mode
1019 * <code>ADODB_OPT_HIGH</code> for full optimization
1020 * <code>ADODB_OPT_LOW</code> for CPU-less optimization
1021 * Default is LOW <code>ADODB_OPT_LOW</code>
1022 * @author Markus Staab
1023 * @return Returns <code>true</code> on success and <code>false</code> on error
1025 function OptimizeTables()
1027 $args = func_get_args();
1028 $numArgs = func_num_args();
1030 if ( $numArgs == 0) return false;
1032 $mode = ADODB_OPT_LOW
;
1033 $lastArg = $args[ $numArgs - 1];
1034 if ( !is_string($lastArg)) {
1036 unset( $args[ $numArgs - 1]);
1039 foreach( $args as $table) {
1040 $this->optimizeTable( $table, $mode);
1045 * Reorganise the table-indices/statistics/.. depending on the given mode.
1046 * Default Implementation throws an error.
1048 * @param string table name of the table to optimize
1049 * @param int mode optimization-mode
1050 * <code>ADODB_OPT_HIGH</code> for full optimization
1051 * <code>ADODB_OPT_LOW</code> for CPU-less optimization
1052 * Default is LOW <code>ADODB_OPT_LOW</code>
1053 * @author Markus Staab
1054 * @return Returns <code>true</code> on success and <code>false</code> on error
1056 function OptimizeTable( $table, $mode = ADODB_OPT_LOW
)
1058 ADOConnection
::outp( sprintf( "<p>%s: '%s' not implemented for driver '%s'</p>", __CLASS__
, __FUNCTION__
, $this->conn
->databaseType
));
1063 * Reorganise current database.
1064 * Default implementation loops over all <code>MetaTables()</code> and
1065 * optimize each using <code>optmizeTable()</code>
1067 * @author Markus Staab
1068 * @return Returns <code>true</code> on success and <code>false</code> on error
1070 function optimizeDatabase()
1072 $conn = $this->conn
;
1073 if ( !$conn) return false;
1075 $tables = $conn->MetaTables( 'TABLES');
1076 if ( !$tables ) return false;
1078 foreach( $tables as $table) {
1079 if ( !$this->optimizeTable( $table)) {