/openshift/adei

To get this branch, use:
bzr branch http://darksoft.org/webbzr/openshift/adei

« back to all changes in this revision

Viewing changes to classes/cache/cachedb.php

  • Committer: Suren A. Chilingaryan
  • Date: 2008-06-17 23:19:26 UTC
  • Revision ID: csa@dside.dyndns.org-20080617231926-w9mpfxw6lv0r0450
Administrative interface and better handling of missing group channels

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 const TYPE_MEAN = 2;
19
19
 const TYPE_ALL = 3;
20
20
 
21
 
 const NEED_COUNT = 1;          // Element count
22
 
 const TABLE_INFO = 2;          // Information about cache tables
 
21
 const NEED_INFO = 1;
 
22
 const NEED_COUNT = 2;          // Element count
 
23
 const TABLE_INFO = 4;          // Information about cache tables
 
24
 const NEED_REQUESTS = 8;       // Create appropriate requests on listing
 
25
 const ITEM_INFO = 16;          // Information about group items
 
26
 const FIND_BROKEN = 32;        // Find incomplete caches
23
27
 
24
 
 function __construct(SOURCERequest &$props) {
 
28
 function __construct(SOURCERequest &$props = NULL) {
25
29
    global $ADEI_DB;
26
30
 
27
 
    $this->req = &$props;
28
 
 
29
 
    $this->dbh = mysql_connect($ADEI_DB['host'] . ($ADEI_DB['port']?(":" . $ADEI_DB['port']):""), $ADEI_DB['user'], $ADEI_DB['password']);
30
 
    if (!$this->dbh) throw new ADEIException(translate("Connection to the Caching MySQL Server is failed"));
31
 
    
32
 
    mysql_query("SET time_zone = '+0:00'");
33
 
 
34
 
    if (!@mysql_select_db($ADEI_DB['database'], $this->dbh)) {
35
 
                // ER_NO_DB_ERROR
36
 
        if (mysql_errno($this->dbh) == CACHEDB::MYSQL_ER_BAD_DB_ERROR) { 
37
 
            if (mysql_query("CREATE DATABASE " . $ADEI_DB['database'], $this->dbh)) {
38
 
                if (!mysql_select_db($ADEI_DB['database'], $this->dbh))
39
 
                    throw new ADEIException(translate("Connection to the Caching MySQL Database is failed") . " (" . mysql_error($this->dbh) . ")");
40
 
            } else 
41
 
                throw new ADEIException(translate("Creation of the caching MySQL database is failed") . " (" . mysql_error($this->dbh) . ")");
42
 
            
43
 
            
44
 
        } else 
45
 
            throw new ADEIException(translate("Connection to the Caching MySQL Database is failed") . " (" . mysql_error($this->dbh) . ")");
46
 
    }
 
31
    if ($props) $this->req = &$props;
 
32
    else $this->req = new REQUEST();
 
33
 
 
34
    $this->dbh = $this->ConnectDB();
47
35
 
48
36
    if (isset($this->req->props['db_server']))
49
37
        $this->default_db_server = $this->req->props['db_server'];
57
45
        $this->default_db_group = $this->req->props['db_group'];
58
46
    else 
59
47
        $this->default_db_group = false;
60
 
    
 
48
 
61
49
    if (($this->default_db_server !== false)&&($this->default_db_name !== false)&&($this->default_db_group !== false)) {
62
50
        $this->default_postfix = $this->GetCachePostfix();      
63
 
    }
64
 
 
65
 
    $this->default_postfix = false;
 
51
    } else {
 
52
        $this->default_postfix = false;
 
53
    }
 
54
 }
 
55
 
 
56
 static function ConnectDB() {
 
57
    global $ADEI_DB;
 
58
 
 
59
    $dbh = mysql_connect($ADEI_DB['host'] . ($ADEI_DB['port']?(":" . $ADEI_DB['port']):""), $ADEI_DB['user'], $ADEI_DB['password']);
 
60
    if (!$dbh) throw new ADEIException(translate("Connection to the Caching MySQL Server is failed"));
 
61
    
 
62
    mysql_query("SET time_zone = '+0:00'");
 
63
 
 
64
    if (!@mysql_select_db($ADEI_DB['database'], $dbh)) {
 
65
                // ER_NO_DB_ERROR
 
66
        if (mysql_errno($dbh) == CACHEDB::MYSQL_ER_BAD_DB_ERROR) { 
 
67
            if (mysql_query("CREATE DATABASE " . $ADEI_DB['database'], $dbh)) {
 
68
                if (!mysql_select_db($ADEI_DB['database'], $dbh))
 
69
                    throw new ADEIException(translate("Connection to the Caching MySQL Database is failed") . " (" . mysql_error($dbh) . ")");
 
70
            } else 
 
71
                throw new ADEIException(translate("Creation of the caching MySQL database is failed") . " (" . mysql_error($dbh) . ")");
 
72
            
 
73
            
 
74
        } else 
 
75
            throw new ADEIException(translate("Connection to the Caching MySQL Database is failed") . " (" . mysql_error($dbh) . ")");
 
76
    }
 
77
    
 
78
    return $dbh;
 
79
 }
 
80
 
 
81
 function ParsePostfix($postfix, $prefix="", $allow_incomplete = false) {
 
82
    if (preg_match("/^$prefix(__md5_(.*))$/", $postfix, $m)) {
 
83
        $supported = true;
 
84
            
 
85
        $postfix = $m[1];
 
86
        $md5 = $m[2];
 
87
            
 
88
        $mres = @mysql_query("SELECT `postfix` FROM md5 WHERE hash = '" . $postfix . "'", $this->dbh);
 
89
        if ($mres) $mrow = mysql_fetch_row($mres);
 
90
        else $mrow = false;
 
91
            
 
92
        if (($mrow)&&(preg_match("/^__(.*)__(.*)__(.*)$/", $mrow[0], $m))) {
 
93
            $srv = $m[1];
 
94
            $db = $m[2];
 
95
            $group = $m[3];
 
96
        } else if ($allow_incomplete) {
 
97
            $srv = false;
 
98
            $db = false;
 
99
            $group = false;
 
100
        } else {
 
101
            throw new ADEIException(translate("Supplied MD5 postfix (%s) is not listed in md5 table", $postfix));
 
102
        }
 
103
 
 
104
        unset($mres);
 
105
    } else if (preg_match("/^$prefix(__(.*)__(.*)__(.*))$/", $postfix, $m)) {
 
106
        $supported = true;
 
107
        $md5 = false;
 
108
 
 
109
        $postfix = $m[1];
 
110
        $srv = $m[2];
 
111
        $db = $m[3];
 
112
        $group = $m[4];
 
113
    } else if (preg_match("/^$prefix(__.*)$/", $postfix, $m)) {
 
114
        if ($allow_incomplete) {
 
115
            $supported = false;
 
116
            $postfix = $m[1];
 
117
            $md5 = false;
 
118
            $srv = false;
 
119
            $db = false;
 
120
            $group = false;
 
121
        } else {
 
122
            throw new ADEIException(translate("Unsupported postfix (%s) is supplied", $postfix));
 
123
        }
 
124
    } else {
 
125
        if ($postfix) {
 
126
            throw new ADEIException(translate("Unsupported postfix is specified: %s", $string));
 
127
        } else {
 
128
            throw new ADEIException(translate("Postfix should be specified"));
 
129
        }
 
130
    }
 
131
    
 
132
    return array(
 
133
        'postfix' => $postfix,
 
134
        'md5' => $md5,
 
135
        'db_server' => $srv,
 
136
        'db_name' => $db,
 
137
        'db_group' => $group,
 
138
        'supported' => $supported
 
139
    );
 
140
 }
 
141
 
 
142
 function CreateServerRequest(&$postfix_or_info) {
 
143
    if (is_array($postfix_or_info))
 
144
        $info = &$postfix_or_info;
 
145
    else if ($postfix_or_info)
 
146
        $info = $this->ParsePostfix($postfix_or_info);
 
147
    else
 
148
        $info = $this->ParsePostfix($this->default_postfix);
 
149
        
 
150
    return new SERVERRequest($req = array(
 
151
            'db_server' => $info['db_server']
 
152
    ));
 
153
        
 
154
 }
 
155
 
 
156
 function CreateGroupRequest(&$postfix_or_info) {
 
157
    if (is_array($postfix_or_info))
 
158
        $info = &$postfix_or_info;
 
159
    else if ($postfix_or_info)
 
160
        $info = $this->ParsePostfix($postfix_or_info);
 
161
    else
 
162
        $info = $this->ParsePostfix($this->default_postfix);
 
163
 
 
164
    return new GROUPRequest($req = array(
 
165
        'db_server' => $info['db_server'],
 
166
        'db_name' => $info['db_name'],
 
167
        'db_group' => $info['db_group']
 
168
    ));
 
169
 }
 
170
 
 
171
 function GetExtendedCacheInfo(&$postfix_or_row, $flags = 0) {
 
172
    global $READER_DB;
 
173
    
 
174
    if (is_array($postfix_or_row)) {
 
175
        $prefix = "cache0";
 
176
        $string = $postfix_or_row[0];
 
177
    } else if ($postfix_or_row) {
 
178
        $prefix = "";
 
179
        $string = $postfix_or_row;
 
180
    } else {
 
181
        $prefix = "";
 
182
        $string = $this->default_postfix;
 
183
    }
 
184
 
 
185
    $info = $this->ParsePostfix($string, $prefix, true);
 
186
    
 
187
    $postfix = $info['postfix'];
 
188
    $srv = $info['db_server'];
 
189
    $db = $info['db_name'];
 
190
    $group = $info['db_group'];
 
191
    $supported = $info['supported'];
 
192
    
 
193
 
 
194
    if ($flags&CACHE::NEED_REQUESTS) {
 
195
            if ($supported) {
 
196
                try {
 
197
                    $req = $this->CreateGroupRequest($info);
 
198
 
 
199
                    $info['server'] = $READER_DB[$srv]['title'];
 
200
                    
 
201
                    try {
 
202
                        $reader = $req->CreateReader();
 
203
                    } catch (ADEIException $ae) {
 
204
                        $sreq = $this->CreateServerRequest($info);
 
205
                        $reader = $sreq->CreateReader();
 
206
                    }
 
207
                    
 
208
                    $info['reader'] = get_class($reader);
 
209
                    
 
210
                    if ($reader->server['disconnected'])
 
211
                        $info['disconnected'] = true;
 
212
 
 
213
                    $db_list = $reader->GetDatabaseList();
 
214
                    if (isset($db_list[$db])) {
 
215
                        $info['database'] = $db_list[$db]['name'];
 
216
                        
 
217
                        if ($req) {
 
218
                            $group_list = $reader->GetGroupList();
 
219
                            if (isset($group_list[$group])) {
 
220
                                $info['group'] = $group_list[$group]['name'];
 
221
                            } else {
 
222
                                $req = false;
 
223
                            }
 
224
                        }
 
225
                    } else {
 
226
                        $req = false;
 
227
                    }
 
228
                    
 
229
                } catch (ADEIException $ae) {
 
230
                    if ($info['server']) $info['disconnected'] = true;
 
231
                    $req = false;
 
232
                }
 
233
            } else $req = false;
 
234
            
 
235
            $info['req'] = $req;
 
236
    }
 
237
 
 
238
    if (($flags&CACHEDB::TABLE_INFO)&&($supported)) {
 
239
            $info['info'] = $this->GetCacheInfo($postfix);
 
240
            if (is_array($postfix_or_row)) {
 
241
                $info['info']['records'] = $postfix_or_row[4];
 
242
                $info['info']['dbsize'] = $postfix_or_row[6] + $postfix_or_row[8];
 
243
            }
 
244
            
 
245
            $tables = array();
 
246
 
 
247
            $mres = @mysql_query("SHOW TABLE STATUS LIKE 'cache%$postfix'", $this->dbh);
 
248
            if ($mres) {
 
249
                $size = 0;
 
250
                while ($mrow = mysql_fetch_row($mres)) {
 
251
                    $size += $mrow[6] + $mrow[8];
 
252
                    if (preg_match("/^cache(\d+)$postfix$/", $mrow[0], $m)) {
 
253
                        $id = $m[1];
 
254
                        
 
255
                        if (!$id) $info['info']['records'] = $mrow[4];
 
256
 
 
257
                        $tables[$id] = $this->GetTableInfo($id, $postfix);
 
258
                        if (!is_array($tables[$id])) $tables[$id] = array();
 
259
 
 
260
                        $tables[$id]['resolution'] = $id;
 
261
                        $tables[$id]['records'] = $mrow[4];
 
262
                        $tables[$id]['dbsize'] = $mrow[6] + $mrow[8];
 
263
                    }
 
264
                }
 
265
                unset($mres);
 
266
                
 
267
                if ($size) {
 
268
                    $info['info']['dbsize'] = $size;
 
269
                }
 
270
                
 
271
                if ($tables) {
 
272
                    ksort($tables);
 
273
                    $info['info']['tables'] = $tables;
 
274
                } else {
 
275
                    $info['info']['tables'] = array(
 
276
                        0 => &$info['info']
 
277
                    );
 
278
                }
 
279
            }
 
280
    }
 
281
 
 
282
    if (($flags&CACHEDB::ITEM_INFO)&&($supported)) {
 
283
            $mres = mysql_query("SHOW COLUMNS FROM `cache0$postfix`", $this->dbh);
 
284
            if ($mres) {
 
285
                $mrow = mysql_fetch_row($mres);
 
286
                if ($mrow[0] == 'time') {
 
287
                    $mrow = mysql_fetch_row($mres);
 
288
                    if ($mrow[0] == 'ns') {
 
289
                        $info['info']['ns'] = true;
 
290
                        $lastrow = "";
 
291
//                      $item_number = 0;
 
292
                    } else {
 
293
                        $info['info']['ns'] = false;
 
294
                        $lastrow = $mrow[0];
 
295
//                      $item_number = 1;
 
296
                    }
 
297
 
 
298
                    while ($mrow = mysql_fetch_array($mres)) $lastrow = $mrow[0];
 
299
                    if (preg_match("/(\d+)/", $lastrow, $m)) {
 
300
                        $info['info']['width'] = $m[1] + 1;
 
301
                    } else {
 
302
                        $info['info']['width'] = 0;
 
303
                    }
 
304
                    
 
305
/*                      
 
306
                    $mrow = mysql_fetch_row($mres);
 
307
                    if ($mrow[0] != 'subcache') $item_number++;
 
308
                    
 
309
                    while ($mrow = mysql_fetch_row($mres)) {
 
310
                        if ($mrow[0]) $item_number++;
 
311
                    }
 
312
                    $info['info']['width'] = $item_number;
 
313
*/
 
314
                }
 
315
            }      
 
316
#           echo $postfix . " - " . $info['info']['width'] . "<br/>";
 
317
 
 
318
 
 
319
            if ($req) {
 
320
                $info['info']['items'] = $reader->GetItemList();
 
321
            }
 
322
    }
 
323
        
 
324
    return $info;
 
325
 }
 
326
 
 
327
 function GetCacheList($flags = 0) {
 
328
    $list = array();
 
329
 
 
330
    if ($flags&CACHEDB::TABLE_INFO)
 
331
        $res = @mysql_query("SHOW TABLE STATUS LIKE 'cache0\\_\\_%'", $this->dbh);
 
332
    else
 
333
        $res = @mysql_query("SHOW TABLES LIKE 'cache0\\_\\_%'", $this->dbh);
 
334
    
 
335
    $postfixes = array();
 
336
    
 
337
    while ($row = mysql_fetch_row($res)) {
 
338
        $info = $this->GetExtendedCacheInfo($row, $flags);
 
339
        array_push($list, $info);
 
340
 
 
341
        array_push($postfixes, $info['postfix']);
 
342
    }
 
343
 
 
344
    if ($flags&CACHE::FIND_BROKEN) {
 
345
        $res = @mysql_query("SHOW TABLES LIKE 'cache%\\_\\_%'", $this->dbh);
 
346
        if ($res) {
 
347
            $all_postfixes = array();
 
348
            while ($row = mysql_fetch_row($res)) {
 
349
                if (preg_match("/^cache\d+(__.*)$/", $row[0], $m)) {
 
350
                    array_push($all_postfixes, $m[1]);
 
351
                }
 
352
            }
 
353
 
 
354
            $incomplete = array_diff(array_unique($all_postfixes), $postfixes);
 
355
            
 
356
            foreach ($incomplete as $postfix) {
 
357
                $info = $this->GetExtendedCacheInfo($postfix, $flags);
 
358
                $info['incomplete'] = true;
 
359
                array_push($list, $info);
 
360
            }
 
361
        }
 
362
    }
 
363
        
 
364
    return $list;
 
365
 }
 
366
 
 
367
 function CreateReader($postfix = false) {
 
368
    if (!$postfix) $postfix = $this->default_postfix;
 
369
    
 
370
    $req = $this->CreateGroupRequest($postfix);
 
371
    return $req->CreateReader();
 
372
 }
 
373
 
 
374
 function Drop($postfix) {
 
375
    $lock = new LOCK("cache");
 
376
    $lock->Lock(LOCK::BLOCK|LOCK::ALL);
 
377
 
 
378
    try {       
 
379
        $resolutions = $this->ListResolutions($postfix);
 
380
        sort($resolutions);
 
381
    
 
382
        foreach ($resolutions as $res) {
 
383
            $table = $this->GetTableName($res, $postfix);
 
384
            $query = "DROP TABLE `$table`;";
 
385
            if (!mysql_query($query, $this->dbh)) {
 
386
                throw new ADEIException(translate("Failed to drop CACHE (%s). Request '%s' is failed with error: %s", "cache*_$postfix", $query,  mysql_error($this->dbh)));
 
387
            }
 
388
        }
 
389
    } catch (ADEIException $ae) {
 
390
        $lock->UnLock();    
 
391
        throw $ae;
 
392
    }
 
393
    
 
394
    $lock->UnLock();    
 
395
 }
 
396
 
 
397
 function Rewidth($postfix, $report = false) {
 
398
    $lock = new LOCK("cache");
 
399
    $lock->Lock(LOCK::BLOCK|LOCK::ALL);
 
400
 
 
401
    try {
 
402
        $current = $this->GetCacheWidth($postfix);
 
403
 
 
404
        $reader = $this->CreateReader($postfix);
 
405
        $actual = $reader->GetGroupSize();
 
406
    
 
407
        if ($current == $actual) {
 
408
            $lock->UnLock();    
 
409
            return;
 
410
        }
 
411
 
 
412
        if ($report) {
 
413
            echo translate("Resizing %s from %d to %d", "cache*_$postfix", $current, $actual);
 
414
            if ($report === "html") echo "<br/>";
 
415
            echo "\n";
 
416
        }
 
417
        
 
418
        if ($current < $actual) {
 
419
            for ($i = $current; $i < $actual; $i++) {
 
420
                if ($i > $current) {
 
421
                    $spec0 .= ", ";
 
422
                    $spec .= ", ";
 
423
                }
 
424
                $spec0 = "ADD `v$i` DOUBLE";
 
425
                $spec = "ADD `min" . $i . "` DOUBLE, ADD `max" . $i . "` DOUBLE, ADD `mean" . $i . "` DOUBLE";
 
426
            }
 
427
        } else {
 
428
            for ($i = $actual; $i < $current; $i++) {
 
429
                if ($i > $actual) {
 
430
                    $spec0 .= ", ";
 
431
                    $spec .= ", ";
 
432
                }
 
433
                $spec0 = "DROP `v$i`";
 
434
                $spec = "DROP `min" . $i . "`, DROP `max" . $i . "`, DROP `mean" . $i . "`";
 
435
            }
 
436
        }
 
437
 
 
438
        $resolutions = $this->ListResolutions($postfix);
 
439
        rsort($resolutions);
 
440
    
 
441
        foreach ($resolutions as $res) {
 
442
            if ($res) {
 
443
                $width = $this->GetTableWidth($postfix, $res);
 
444
                if ($width != $current) {
 
445
                    if ($width == $actual) {
 
446
                        if ($report) {
 
447
                            echo translate("Resolution %lu is already converted", $res);
 
448
                            if ($report === "html") echo "<br/>";
 
449
                            echo "\n";
 
450
                        }
 
451
                        continue;
 
452
                    }
 
453
                    throw new ADEIException(translate("CACHE table (%s) have unexpected size: %d (converting from %d to %d)", "cache${res}${postfix}", $width, $current, $actual));
 
454
                }
 
455
 
 
456
                $query = "ALTER TABLE `cache${res}${postfix}` $spec";
 
457
            } else {
 
458
                $query = "ALTER TABLE `cache0$postfix` $spec0";
 
459
            }
 
460
        
 
461
            if ($report) {
 
462
                echo translate("Converting resolution %lu", $res);
 
463
                if ($report === "html") echo "<br/>";
 
464
                echo "\n";
 
465
            }
 
466
 
 
467
#           echo $query . "<br/>\n";
 
468
            if (!mysql_query($query, $this->dbh)) {
 
469
                throw new ADEIException(translate("The CACHE (%s) resizing request is not complete. Request '%s' is failed with error: %s", "cache*_$postfix", $query,  mysql_error($this->dbh)));
 
470
            }
 
471
        
 
472
        }
 
473
    } catch (ADEIException $ae) {
 
474
        $lock->UnLock();    
 
475
        throw $ae;
 
476
    }
 
477
    
 
478
    $lock->UnLock();    
 
479
 
66
480
 }
67
481
 
68
482
 function ListCachedGroups($db_name = false, $db_server = false) {
112
526
    return $groups;    
113
527
 }
114
528
 
 
529
 function ListResolutions($postfix) {
 
530
    if (!$postfix) $postfix = $this->default_postfix;
 
531
    
 
532
    $tables = array();
 
533
    
 
534
    $mres = @mysql_query("SHOW TABLES LIKE 'cache%$postfix'", $this->dbh);
 
535
    if ($mres) {
 
536
        while ($mrow = mysql_fetch_row($mres)) {
 
537
            if (preg_match("/^cache(\d+)$postfix$/", $mrow[0], $m)) {
 
538
                array_push($tables, $m[1]);
 
539
            }
 
540
        }
 
541
    }
 
542
    
 
543
    return $tables;
 
544
 }
 
545
 
115
546
 function GetGroupPostfix($db_group = false, $db_name = false, $db_server = false) {
116
547
    if ((!$db_server)||(!$db_name)||(!$db_group)) {
117
548
        if ($db_server === false) $db_server = $this->default_db_server;
202
633
    return false;
203
634
 }
204
635
 
205
 
 function GetCacheWidth($postfix = false) {
206
 
    $table = $this->GetTableName(0, $postfix);
 
636
 function GetTableWidth($postfix = false, $resolution = 0) {
 
637
    $table = $this->GetTableName($resolution, $postfix);
207
638
 
208
639
    $res = mysql_query("SHOW COLUMNS FROM `$table`", $this->dbh);
209
640
    if (!$res)
217
648
    return ($m[1] + 1);
218
649
 }
219
650
 
 
651
 function GetCacheWidth($postfix = false) {
 
652
    return $this->GetTableWidth($postfix, 0);
 
653
 }
 
654
 
220
655
 function GetCacheIDs($postfix = false) {
221
656
        // DS, check if we do not have a level0 CACHE
222
657
        $size = $this->GetCacheWidth($postfix);
370
805
        $query = "INSERT INTO `$table` VALUES ($sqltime, " . $d->n . ", " . $d->missing;
371
806
        if ($d->n > 0) {
372
807
            for ($j = 0; $j < $this->items; $j++) {
373
 
                $query .= ", " . $d->min[$j] . ", " . $d->max[$j] . ", " . $d->mean[$j];
 
808
                $query .= ", " . (($d->min[$j]!==NULL)?$d->min[$j]:"NULL") . ", " . (($d->max[$j]!==NULL)?$d->max[$j]:"NULL") . ", " . (($d->mean[$j]!==NULL)?$d->mean[$j]:"NULL");
374
809
            }
375
810
        } else {
376
811
            for ($j = 0; $j < $this->items; $j++) {
395
830
            
396
831
        $query = "INSERT INTO `$table` VALUES ($sqltime" . $ns;
397
832
        foreach ($d as $val) {
398
 
            $query .= ", $val";
 
833
            if ($val === NULL)
 
834
                $query .= ", NULL";
 
835
            else
 
836
                $query .= ", $val";
399
837
        }
400
838
        $query .= ")";
401
839
    }