20
21
const TYPE_ALL = 3;
22
23
const TABLE_INFO = 0x00010000; // Information about cache tables
23
const NEED_REQUESTS = 0x00020000; // Create appropriate requests on listing
24
const FIND_BROKEN = 0x00040000; // Find incomplete caches
24
const LEVEL_INFO = 0x00020000; // Return information about the cache levels
25
const NEED_REQUESTS = 0x00040000; // Create appropriate requests on listing
26
const FIND_BROKEN = 0x00080000; // Find incomplete caches
27
const SKIP_OK = 0x00100000; // Don't report info on fully cached groups
28
const SKIP_MISSING = 0x00200000; // Don't report info on fully cached groups
26
30
const INSERT_CALL = 1;
27
31
const DESTRUCTOR_CALL = 2;
91
94
static function FindAggregator($aggregator) {
92
$name = "CACHEDB::TYPE_" . strtoupper($aggregator);
93
if (defined($name)) return constant($name);
94
else if ((!$aggregator)||(($aggregator>0)&&($aggregator<=CACHEDB::TYPE_ALL))) return $aggregator;
96
$name = "CACHEDB::TYPE_" . strtoupper($aggregator);
97
if (defined($name)) return constant($name);
98
else if ((!$aggregator)||(($aggregator>0)&&($aggregator<=CACHEDB::TYPE_ALL))) return $aggregator;
96
throw new ADEIException(translate("Unknown aggregation mode (%s) is specified", $aggregator));
100
throw new ADEIException(translate("Unknown aggregation mode (%s) is specified", $aggregator));
103
return CACHE::TYPE_AUTO;
99
106
function GetSize() {
241
249
$postfix = $info['postfix'];
242
250
$srv = $info['db_server'];
243
251
$db = $info['db_name'];
252
$source = "${srv}__${db}";
244
253
$group = $info['db_group'];
245
254
$supported = $info['supported'];
256
$cache_info = array();
257
if (($flags&CACHEDB::TABLE_INFO)&&($supported)) {
258
$cache_info = $this->GetCacheInfo($postfix);
260
if ($flags&CACHEDB::SKIP_OK) {
262
if ((isset($cache_info['last']))&&(abs($now - $cache_info['last']) < $ADEI_CACHE_LATENCY_THRESHOLD))
247
267
if ($flags&CACHE::NEED_REQUESTS) {
248
268
if ($supported) {
263
283
if ($reader->server['disconnected'])
264
284
$info['disconnected'] = true;
266
$db_list = $reader->GetDatabaseList(REQUEST::LIST_WILDCARDED);
267
if (isset($db_list[$db])) {
286
if (!in_array($srv, $this->db_list_cache))
287
$this->db_list_cache[$srv] = $reader->GetDatabaseList($flags&REQUEST::LIST_WILDCARDED);
288
$db_list = $this->db_list_cache[$srv];
290
if (isset($db_list[$db])) {
268
291
$info['database'] = $db_list[$db]['name'];
269
292
if ((is_array($req->srv['database']))&&(!in_array($db, $req->srv['database'])))
270
293
$info['wildcarded'] = true;
296
$grp = $reader->CreateGroup($req->props);
273
297
// Slows down considerably on big installations
274
298
if ($flags&REQUEST::NEED_READERINFO)
275
$group_list = $reader->GetGroupInfo(NULL, REQUEST::NEED_INFO|REQUEST::NEED_COUNT);
299
$group_list = $reader->GetGroupInfo($grp, REQUEST::NEED_INFO|REQUEST::NEED_COUNT|REQUEST::PREFER_EXACTINFO);
277
$group_list = $reader->GetGroupInfo();
301
$group_list = $reader->GetGroupInfo($grp);
279
303
if (isset($group_list[$group])) {
280
$ginfo = &$group_list[$group];
304
$ginfo = $group_list[$group];
305
} elseif (is_array($group_list)) {
306
$ginfo = $group_list;
281
313
$info['group'] = $ginfo['name'];
314
foreach ($ginfo as $gkey => $gval) {
315
$info[$gkey] = $gval;
282
319
if (isset($ginfo['first'])) $info['first'] = $ginfo['first'];
283
320
if (isset($ginfo['last'])) $info['last'] = $ginfo['last'];
284
321
if (isset($ginfo['records'])) $info['last'] = $ginfo['records'];
322
if (isset($ginfo['query_time'])) $info['last'] = $ginfo['query_time'];
327
if ($flags&CACHEDB::SKIP_MISSING)
293
331
} catch (ADEIException $ae) {
294
if ($info['server']) $info['disconnected'] = true;
332
if ($info['server']) {
333
$info['disconnected'] = true;
334
$info['error'] = $ae->getMessage();
297
338
} else $req = false;
299
340
$info['req'] = $req;
302
if (($flags&CACHEDB::TABLE_INFO)&&($supported)&&($cache_info=$this->GetCacheInfo($postfix))) {
344
// Fast variant of REQUEST:::NEED_COUNT is as precise as TABLE INFO (i.e. not)
345
if (($flags&CACHEDB::TABLE_INFO)&&($supported)&&($cache_info)) {
303
346
$info['info'] = $cache_info;
305
348
if (is_array($postfix_or_row)) {
306
349
$info['info']['records'] = $postfix_or_row[4];
307
350
$info['info']['dbsize'] = $postfix_or_row[6] + $postfix_or_row[8];
310
353
$tables = array();
312
$mres = @mysql_query("SHOW TABLE STATUS LIKE 'cache%$postfix'", $this->dbh);
355
if ($flags&CACHEDB::LEVEL_INFO) $mres = @mysql_query("SHOW TABLE STATUS LIKE 'cache%$postfix'", $this->dbh);
356
else if ((!is_array($postfix_or_row))||(sizeof($postfix_or_row)<9)) $mres = @mysql_query("SHOW TABLE STATUS LIKE 'cache%$postfix'", $this->dbh);
357
else $mres = array($postfix_or_row);
315
while ($mrow = mysql_fetch_row($mres)) {
361
while ($mrow = (is_array($mres)?array_pop($mres):mysql_fetch_row($mres))) {
316
362
$size += $mrow[6] + $mrow[8];
317
363
if (preg_match("/^cache(\d+)$postfix$/", $mrow[0], $m)) {
320
366
if (!$id) $info['info']['records'] = $mrow[4];
322
$tables[$id] = $this->GetTableInfo($id, $postfix);
368
$tables[$id] = ($id > 0)?$this->GetTableInfo($id, $postfix):$cache_info;
323
369
if (!is_array($tables[$id])) $tables[$id] = array();
325
371
$tables[$id]['resolution'] = $id;
391
437
$info['info']['items'] = $reader->GetItemList();
398
function GetCacheList($flags = 0) {
443
function GetCacheList($filter = false, $flags = 0) {
445
if ($filter) $query .= preg_replace("/_/", "\\_", $filter) . "\\_\\_";
448
$list = $this->GetCacheListSimple($query, $flags);
451
$res = @mysql_query("SELECT hash FROM md5 WHERE postfix LIKE '${query}'", $this->dbh);
453
while ($row = mysql_fetch_row($res)) {
454
$md5_list = $this->GetCacheListSimple($row[0], $flags);
455
$list = array_merge($list, $md5_list);
463
function GetCacheListSimple($query = false, $flags = 0) {
466
// This is inaccurate with InnoDB.
402
467
if ($flags&CACHEDB::TABLE_INFO)
403
$res = @mysql_query("SHOW TABLE STATUS LIKE 'cache0\\_\\_%'", $this->dbh);
468
$res = @mysql_query("SHOW TABLE STATUS LIKE 'cache0${query}'", $this->dbh);
405
$res = @mysql_query("SHOW TABLES LIKE 'cache0\\_\\_%'", $this->dbh);
408
$res = @mysql_query("SHOW TABLES LIKE 'cache0\\_\\_aircoils%'", $this->dbh);
409
$flags = $flags&~CACHE::FIND_BROKEN;
470
$res = @mysql_query("SHOW TABLES LIKE 'cache0${query}'", $this->dbh);
412
472
$postfixes = array();
414
473
while ($row = mysql_fetch_row($res)) {
475
$t_start = microtime(true);
416
476
$info = $this->GetExtendedCacheInfo($row, $flags);
417
array_push($list, $info);
477
$t_end = microtime(true);
478
$t = $t_end - $t_start;
479
//echo "> " . date('h:i:s', floor($t_start)) . substr($t_start - floor($t_start), 1) . " ($t) " . "${row[0]} util " . date('h:i:s', floor($t_end)) . substr($t_end - floor($t_end), 1) ."\n";
419
array_push($postfixes, $info['postfix']);
482
$info['get_extended_cache_info_time'] = $t;
483
$list[$info['postfix']] = $info;
484
array_push($postfixes, $info['postfix']);
420
486
} catch (ADEIException $ae) {
421
487
// DS: what to do? Do we need to pass the error or we relly or FIND_BROKEN?
425
491
if ($flags&CACHE::FIND_BROKEN) {
426
$res = @mysql_query("SHOW TABLES LIKE 'cache%\\_\\_%'", $this->dbh);
492
$res = @mysql_query("SHOW TABLES LIKE 'cache%${query}%'", $this->dbh);
428
494
$all_postfixes = array();
429
495
while ($row = mysql_fetch_row($res)) {
1020
1086
function GetTableInfo($resolution = 0, $postfix = false, $flags = 0) {
1021
1087
$table = $this->GetTableName($resolution, $postfix);
1023
$req = "EXTENDED_UNIX_TIMESTAMP(MIN(time)) AS first, EXTENDED_UNIX_TIMESTAMP(MAX(time)) AS last";
1024
if ($flags&REQUEST::NEED_COUNT) $req .= ", COUNT(time) AS records";
1026
$res = mysql_query("SELECT $req FROM `$table`", $this->dbh);
1091
if ($flags&REQUEST::NEED_COUNT) {
1092
// This could be extremely slow on InnoDB (it will make a full scan of the index at minimum)
1093
$extra .= ", COUNT(time) AS records";
1097
if (($resolution)||(!$this->DetectSubseconds($postfix)))
1098
$req = "SELECT EXTENDED_UNIX_TIMESTAMP(MIN(time)) AS first, EXTENDED_UNIX_TIMESTAMP(MAX(time)) AS last${extra} FROM `$table`";
1100
// Querying 'ns' like this would be significantly slower
1101
//$req = "ADEI_TIMESTAMP(EXTENDED_UNIX_TIMESTAMP(MIN(time)),ns) AS first, ADEI_TIMESTAMP(EXTENDED_UNIX_TIMESTAMP(MAX(time)),ns) AS last";
1102
$req = "SELECT (SELECT ADEI_TIMESTAMP(EXTENDED_UNIX_TIMESTAMP(time),ns)/1000000000 FROM `$table` ORDER BY id LIMIT 1) as first, (SELECT ADEI_TIMESTAMP(EXTENDED_UNIX_TIMESTAMP(time),ns)/1000000000 FROM `$table` ORDER BY id DESC LIMIT 1) as last${extra}";
1105
$res = mysql_query($req, $this->dbh);
1028
1107
switch (mysql_errno($this->dbh)) {
1029
1108
case CACHE::MYSQL_ER_NO_SUCH_TABLE:
1033
1112
throw new ADEIException(translate("SELECT request '%s' on CACHE table '%s' is failed. MySQL error: %s", $req, $table, mysql_error($this->dbh)));
1036
return mysql_fetch_assoc($res);
1116
$info = mysql_fetch_assoc($res);
1118
if ($flags&REQUEST::NEED_COUNT) {
1119
// This could be inprecise, but other method is extremely slow on InnoDB (and very imprecise if done on the MySQL/Slave)
1120
$res = mysql_query("EXPLAIN SELECT COUNT(time) AS records FROM `$table`", $this->dbh);
1122
$vals = mysql_fetch_assoc($res);
1123
if ($vals) $info['records'] = $vals['rows'];
1039
1130
function GetCacheInfo($postfix = false, $flags = 0) {