6
var $default_db_server, $default_db_name, $default_db_group;
12
const MYSQL_ER_BAD_DB_ERROR = 1049;
13
const MYSQL_ER_NO_SUCH_TABLE = 1146;
14
const MYSQL_ER_DUP_ENTRY = 1062;
17
const TYPE_MINMAX = 1;
21
const NEED_COUNT = 1; // Element count
22
const TABLE_INFO = 2; // Information about cache tables
24
function __construct(SOURCERequest &$props) {
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"));
32
mysql_query("SET time_zone = '+0:00'");
34
if (!@mysql_select_db($ADEI_DB['database'], $this->dbh)) {
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) . ")");
41
throw new ADEIException(translate("Creation of the caching MySQL database is failed") . " (" . mysql_error($this->dbh) . ")");
45
throw new ADEIException(translate("Connection to the Caching MySQL Database is failed") . " (" . mysql_error($this->dbh) . ")");
48
if (isset($this->req->props['db_server']))
49
$this->default_db_server = $this->req->props['db_server'];
51
$this->default_db_server = false;
52
if (isset($this->req->props['db_name']))
53
$this->default_db_name = $this->req->props['db_name'];
55
$this->default_db_name = false;
56
if (isset($this->req->props['db_group']))
57
$this->default_db_group = $this->req->props['db_group'];
59
$this->default_db_group = false;
61
if (($this->default_db_server !== false)&&($this->default_db_name !== false)&&($this->default_db_group !== false)) {
62
$this->default_postfix = $this->GetCachePostfix();
65
$this->default_postfix = false;
68
function ListCachedGroups($db_name = false, $db_server = false) {
69
// DS, only listing databases having level0 CACHE
70
if ((!$db_server)||(!$db_name)) {
71
if (!$db_server) $db_server = $this->default_db_server;
72
if (!$db_name) $db_name = $this->default_db_name;
74
if ((!$db_server)||(!$db_name))
75
throw new ADEIException(translate("Server name and database should be specified to list available groups"));
80
$prefix = "cache0__" . $db_server . "__" . $db_name . "__";
81
$prefix_length = strlen($prefix);
83
$res = @mysql_query("SHOW TABLES LIKE 'cache0__${db_server}__${db_name}%'", $this->dbh);
85
throw new ADEIException(translate("SHOW TABLES request is failed on CACHE database, error: %s", mysql_error($this->dbh)));
87
while ($row = mysql_fetch_row($res))
88
array_push($groups, substr($row[0], $prefix_length));
92
$res = mysql_query("SHOW TABLES LIKE 'cache0__md5_%'", $this->dbh);
93
while ($row = mysql_fetch_row($res))
94
array_push($md5, substr($row[0], 6));
96
if (sizeof($md5) > 0) {
97
$prefix = "__" . $db_server . "__" . $db_name . "__";
98
$prefix_length = strlen($prefix);
100
$res = mysql_query("SELECT `hash`, `postfix` FROM md5 WHERE postfix LIKE '__${db_server}__${db_name}__%'", $this->dbh);
102
throw new ADEIException(translate("SELECT request on MD5 table is failed, error: %s", mysql_error($this->dbh)));
104
while ($row = mysql_fetch_row($res)) {
105
if (in_array($row[0], $md5))
106
array_push($groups, substr($row[1], $postfix_length));
109
return array_unique($groups);
115
function GetGroupPostfix($db_group = false, $db_name = false, $db_server = false) {
116
if ((!$db_server)||(!$db_name)||(!$db_group)) {
117
if ($db_server === false) $db_server = $this->default_db_server;
118
if ($db_name === false) $db_name = $this->default_db_name;
119
if ($db_group === false) $db_group = $this->default_db_group;
120
if (($db_server === false)||($db_name === false)||($db_group === false))
121
throw new ADEIException(translate("Server name, database and group is required to construct CACHE postfix"));
124
$db_group = preg_replace("/[^\w\d_]/","",$db_group);
126
return "__${db_server}__${db_name}__${db_group}";
129
function MD5CreateTable() {
130
if (!@mysql_query("CREATE TABLE `md5` (`hash` CHAR(64) PRIMARY KEY, `postfix` VARCHAR(4096) NOT NULL, UNIQUE INDEX(postfix(64)))", $this->dbh)) {
131
throw new ADEIException(translate("Creation of system tables (md5) within CACHE database is failed") . " (" . mysql_error($this->dbh) . ")");
135
function MD5CreateEntry($postfix) {
136
$query = "INSERT INTO `md5` VALUES('" . $this->default_postfix . "' , '" . mysql_real_escape_string($postfix) . "')";
137
if (!@mysql_query($query, $this->dbh))
138
throw new ADEIException(translate("Can not insert entry into the MD5 caching table, error") . ": " . mysql_error($this->dbh));
141
function MD5Check() {
142
$res = @mysql_query("SELECT `postfix` from `md5` WHERE `hash` = '" . $this->default_postfix . "'", $this->dbh);
144
switch (mysql_errno($this->dbh)) {
145
case CACHE::MYSQL_ER_NO_SUCH_TABLE:
146
$this->MD5CreateTable();
150
throw new ADEIException(translate("Can not query CACHE md5 table, error") . ": " . mysql_error($this->dbh));
154
$row = mysql_fetch_row($res);
157
$postfix = $this->GetGroupPostfix();
160
$this->MD5CreateEntry($postfix);
161
elseif (strcmp($row[0], $postfix))
162
throw new ADEIException(translate("Unlucky, the MD5 checksums of two groups (\"%s\" and \"%s\") are coinciding. This is not handled automaticaly yet. Please, add/alter md5 suffix to the newly added group.", $row[0], $postfix));
166
function GetCachePostfix($db_group = false, $db_name = false, $db_server = false) {
167
$postfix = $this->GetGroupPostfix($db_group, $db_name, $db_server);
169
if (isset($this->md5_postfix)) $md5 = $this->md5_postfix;
170
else $md5 = $this->req->GetCustomOption('use_md5_postfix', $db_server, $db_name, $db_group);
173
return "__md5_" . (is_string($md5)?$md5:"") . md5($postfix);
174
} else return $postfix;
177
function SetDefaultPostfix($postfix = false) {
178
if ($postfix) $this->default_postfix = $postfix;
180
$this->default_postfix = $this->GetCachePostfix();
184
function GetTableName($resolution = 0, $postfix = false) {
185
return "cache" . $resolution . ($postfix?$postfix:$this->default_postfix);
188
function DetectSubseconds($postfix = false) {
189
$table = $this->GetTableName(0, $postfix);
190
$res = mysql_query("SHOW COLUMNS FROM $table", $this->dbh);
192
throw new ADEIException("There is problem executing 'SHOW COLUMNS' request on CACHE table '$table'");
194
mysql_fetch_array($res); // skipping time column
195
$row = mysql_fetch_array($res); // possibly ns column
196
if (!strcmp($row[0],"ns")) {
197
if (!$postfix) $this->use_subseconds = true;
201
if (!$postfix) $this->use_subseconds = false;
205
function GetCacheWidth($postfix = false) {
206
$table = $this->GetTableName(0, $postfix);
208
$res = mysql_query("SHOW COLUMNS FROM $table", $this->dbh);
210
throw new ADEIException("There is problem executing 'SHOW COLUMNS' request on CACHE table '$table'");
212
while ($col = mysql_fetch_array($res)) $lastcol = &$col['Field'];
214
if (!preg_match("/(\d+)/", $lastcol, $m))
215
throw new ADEIException("There is problem finding out the number of channels. Last cache column is '$lastcol'");
220
function GetCacheIDs($postfix = false) {
221
// DS, check if we do not have a level0 CACHE
222
$size = $this->GetCacheWidth($postfix);
225
for ($i=0;$i<$size;$i++) array_push($ids, $i);
230
function CreateCacheInterval($postfix = false, array &$iinfo = NULL, $flags = 0) {
232
if ($this->req instanceof DATARequest)
233
$iinfo = $this->req->GetIntervalInfo();
236
$ivl = new INTERVAL($iinfo, NULL, NULL, $flags);
237
$ivl->ApplyCache($this);
242
function CreateInterval(array &$iinfo = NULL, $flags = 0) {
243
return $this->CreateCacheInterval(false, $iinfo, $flags);
246
function CreateCacheMask($postfix = false, array &$minfo = NULL, $flags = 0) {
248
if ($this->req instanceof GROUPRequest)
249
$minfo = $this->req->GetMaskInfo();
252
$mask = new MASK($minfo);
253
if (!$mask->ids) $mask->ids = $this->GetCacheIDs($postfix);
257
function CreateMask(array &$minfo = NULL, $flags = 0) {
258
return $this->CreateCacheMask(false, $minfo, $flags);
261
function GetTableInfo($resolution = 0, $postfix = false, $flags = 0) {
262
$table = $this->GetTableName($resolution, $postfix);
264
$req = "UNIX_TIMESTAMP(MIN(time)) AS first, UNIX_TIMESTAMP(MAX(time)) AS last";
265
if ($flags&CACHEDB::NEED_COUNT) $req .= ", COUNT(time) AS records";
267
$res = mysql_query("SELECT $req FROM `$table`", $this->dbh);
269
switch (mysql_errno($this->dbh)) {
270
case CACHE::MYSQL_ER_NO_SUCH_TABLE:
274
throw new ADEIException("SELECT request '$req' on CACHE table '$table' is failed...");
277
return mysql_fetch_assoc($res);
280
function GetCacheInfo($postfix = false, $flags = 0) {
281
// DS, check if we do not have a level0 CACHE
282
return $this->GetTableInfo(0, $postfix, $flags);
285
function GetInfo($flags = 0) {
286
return $this->GetCacheInfo(false, $flags);
289
function GetCacheItemList($postfix = false, MASK &$mask = NULL, $flags = 0) {
292
if (($mask)&&($mask->ids)) {
293
foreach ($mask->ids as $i => $id) {
296
"name" => "Channel" . ($id+1),
300
$size = $this->GetCacheWidth($postfix);
302
for ($i=0;$i<$size;$i++) {
305
"name" => "Channel" . ($i+1),
313
function GetItemList(MASK &$mask = NULL, $flags = 0) {
314
return $this->GetCacheItemList(false, $mask, $flags);
317
function SQLTime($time) {
318
return strftime("%Y%m%d%H%M%S", floor($time));
321
Subseconds are not supported by MySQL Datetime type
323
return strftime("%Y%m%d%H%M%S", $time);
325
return strftime("%Y%m%d%H%M%S", floor($time)) . substr(sprintf("%.6F", $time - floor($time)), 1);
330
function CreateTable($resolution, $items, $postfix = false) {
331
if (($this instanceof CACHE) == false)
332
throw new ADEIException(translate("CreateTable calls are only allowed on CACHE object"));
334
$name = $this->GetTableName($resolution, $postfix);
336
if ($resolution > 0) {
337
for ($i = 0; $i < $items; $i++)
338
$query .= ", `min" . $i . "` DOUBLE, `max" . $i . "` DOUBLE, `mean" . $i . "` DOUBLE";
340
/*, `duration` INT, `complete` BOOL,*/
341
if (!mysql_query("CREATE TABLE `$name` (`time` DATETIME PRIMARY KEY, `n` BIGINT, `missing` INT" . $query . ")", $this->dbh)) {
342
throw new ADEIException(translate("Unable to create cache table, error") . ": " . mysql_error($this->dbh));
345
for ($i = 0; $i < $items; $i++)
346
$query .= ", `v" . $i . "` DOUBLE";
348
if ($this->use_subseconds) {
349
$time = "`time` DATETIME, `ns` INT, `subcache` INT";
350
$index = ", PRIMARY KEY (`time`, `ns`, `subcache`)";
352
$time = "`time` DATETIME PRIMARY KEY";
356
if (!mysql_query("CREATE TABLE `$name` ($time" . $query . "$index)", $this->dbh)) {
357
throw new ADEIException(translate("Unable to create cache table, error") . ": " . mysql_error($this->dbh) . " [" . "CREATE TABLE `$name` ($time" . $query . ",$index)" . "]");
362
function CreateQuery($table, $time, &$d) {
363
if (($this instanceof CACHE) == false)
364
throw new ADEIException(translate("CreateTable calls are only allowed on CACHE object"));
367
$sqltime = $this->SQLTime((int)$time);
368
# echo "Time: $time -> $sqltime\n";
370
$query = "INSERT INTO `$table` VALUES ($sqltime, " . $d->n . ", " . $d->missing;
372
for ($j = 0; $j < $this->items; $j++) {
373
$query .= ", " . $d->min[$j] . ", " . $d->max[$j] . ", " . $d->mean[$j];
376
for ($j = 0; $j < $this->items; $j++) {
377
$query .= ", 0, 0, 0";
382
$sqltime = $this->SQLTime($time);
384
if ($this->use_subseconds) {
385
$point = strstr($time, ".");
387
$subs = substr($point, 1);
388
$chars = strlen($subs);
389
if ($chars<9) $subs .= str_repeat("0", 9 - $chars);
392
// Subcache Information
396
$query = "INSERT INTO `$table` VALUES ($sqltime" . $ns;
397
foreach ($d as $val) {
406
function Insert($resolution, &$query) {
407
if (($this instanceof CACHE) == false)
408
throw new ADEIException(translate("CreateTable calls are only allowed on CACHE object"));
410
if (!@mysql_query($query, $this->dbh)) {
411
switch (mysql_errno($this->dbh)) {
412
case CACHE::MYSQL_ER_NO_SUCH_TABLE:
413
$this->CreateTable($resolution, $this->items);
414
if (!@mysql_query($query, $this->dbh)) {
415
throw new ADEIException(translate("Can not query caching table (Resolution: $resolution), error") . ": " . mysql_error($this->dbh));
418
case CACHE::MYSQL_ER_DUP_ENTRY:
419
if (!strstr($query, "cache0"))
420
throw new ADEIException(translate("Internal error. Trying to insert the block wich is already in the cache (Resolution: $resolution)."));
421
return CACHE::MYSQL_ER_DUP_ENTRY;
424
throw new ADEIException(translate("Can not query caching table (Resolution: $resolution), error") . ": " . mysql_error($this->dbh));
431
function GetReady($table, $from, $to) {
432
return new CACHEData($this, $table, $from, $to);
436
function GetCachePoints($postfix = false, MASK &$mask = NULL, INTERVAL &$ivl = NULL, $type = CACHEDB::TYPE_AUTO, $limit = 0, $amount = 0, $resolution = false) {
437
if (!$mask) $mask = $this->CreateCacheMask();
438
if (!$ivl) $ivl = $this->CreateCacheInterval();
440
if ($type == CACHEDB::TYPE_ALL)
441
$res = new RAWPoint($this, $mask, $ivl, $limit);
443
$res = new DATAPoint($this, $mask, $ivl, $type, is_int($amount)?$amount:0, is_int($limit)?$limit:0, $resolution);
446
if (($postfix)||(!isset($this->use_subseconds))) {
447
// we should find subsecond precision
448
$use_subseconds = $this->DetectSubseconds($postfix);
449
$res->SetOption("use_subseconds", $use_subseconds);
451
if ($postfix) $res->SetOption("postfix", $postfix);
b'\\ No newline at end of file'