Skip to content

Commit

Permalink
Merge pull request #2757 from jeedom/event-db
Browse files Browse the repository at this point in the history
Begin event on database
  • Loading branch information
zoic21 authored Jul 17, 2024
2 parents 7d0f940 + a391ab0 commit ffe54c0
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 129 deletions.
23 changes: 19 additions & 4 deletions core/class/DB.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -656,14 +656,18 @@ public static function compareTable($_table) {
$return[$_table['name']]['sql'] .= static::buildDefinitionField($field);
$return[$_table['name']]['sql'] .= ',';
}
$return[$_table['name']]['sql'] .= "\n" . 'primary key(';
$primary_key = '';
foreach ($_table['fields'] as $field) {
if (isset($field['key']) && $field['key'] == 'PRI') {
$return[$_table['name']]['sql'] .= '`' . $field['name'] . '`,';
$primary_key .= '`' . $field['name'] . '`,';
}
}
$return[$_table['name']]['sql'] = trim($return[$_table['name']]['sql'], ',');
$return[$_table['name']]['sql'] .= ')';
if($primary_key != ''){
$return[$_table['name']]['sql'] .= "\n" . 'primary key(';
$return[$_table['name']]['sql'] = trim($primary_key, ',');
$return[$_table['name']]['sql'] .= ')';
}
$return[$_table['name']]['sql'] = trim($return[$_table['name']]['sql'],',');
$return[$_table['name']]['sql'] .= ')' . "\n";
if (!isset($_table['engine'])) {
$_table['engine'] = 'InnoDB';
Expand All @@ -676,6 +680,17 @@ public static function compareTable($_table) {
return $return;
}
$forceRebuildIndex = false;
try {
$status = DB::Prepare('show table status where name="' . $_table['name'] . '"', array(), DB::FETCH_TYPE_ROW);
} catch (\Exception $e) {
$status = array();
}
if(!isset($_table['engine'])){
$_table['engine'] = 'InnoDB';
}
if(isset($status['Engine']) && $status['Engine'] != $_table['engine']){
$return[$_table['name']]['sql'] = 'ALTER TABLE `' . $_table['name'] . '` ENGINE = '.$_table['engine'];
}
foreach ($_table['fields'] as $field) {
$found = false;
foreach ($describes as $describe) {
Expand Down
221 changes: 97 additions & 124 deletions core/class/event.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,137 +22,89 @@
class event {
/* * *************************Attributs****************************** */

private static $limit = 250;
private static $_fd = null;
protected $datetime;
protected $name;
protected $option;

/* * ***********************Methode static*************************** */

public static function getFileDescriptorLock() {
if (self::$_fd === null) {
@chmod(jeedom::getTmpFolder() . '/event_cache_lock', 0777);
self::$_fd = fopen(jeedom::getTmpFolder() . '/event_cache_lock', 'w');
}
if (self::$_fd === false) {
@chmod(jeedom::getTmpFolder() . '/event_cache_lock', 0777);
self::$_fd = fopen(jeedom::getTmpFolder() . '/event_cache_lock', 'w');
}
return self::$_fd;
}

public static function add($_event, $_option = array()) {
if (config::byKey('cache::engine') == 'MariadbCache') {
$cache = cache::byKey('event');
$value = json_decode($cache->getValue('[]'), true);
if (!is_array($value)) {
$value = array();
}
$value[] = array('datetime' => getmicrotime(), 'name' => $_event, 'option' => $_option);
cache::set('event', json_encode(self::cleanEvent($value)));
return;
}
$waitIfLocked = true;
$fd = self::getFileDescriptorLock();
if($fd === false){
return;
}
if (@flock($fd, LOCK_EX, $waitIfLocked)) {
$cache = cache::byKey('event');
$value = json_decode($cache->getValue('[]'), true);
if (!is_array($value)) {
$value = array();
}
$value[] = array('datetime' => getmicrotime(), 'name' => $_event, 'option' => $_option);
cache::set('event', json_encode(self::cleanEvent($value)));
flock($fd, LOCK_UN);
}
public static function add($_event, $_option = array(),$_clean = true) {
if(is_array($_option)){
$_option = json_encode($_option, JSON_UNESCAPED_UNICODE);
}
$value = array(
'datetime' => getmicrotime(),
'name' => $_event,
'option' => $_option
);
$sql = 'INSERT INTO `event` SET `datetime`=:datetime, `name`=:name,`option`=:option';
DB::Prepare($sql,$value, DB::FETCH_TYPE_ROW);
}

public static function adds($_event, $_values = array()) {
if (config::byKey('cache::engine') == 'MariadbCache') {
$cache = cache::byKey('event');
$value_src = json_decode($cache->getValue('[]'), true);
if (!is_array($value_src)) {
$value_src = array();
}
$value = array();
foreach ($_values as $option) {
$value[] = array('datetime' => getmicrotime(), 'name' => $_event, 'option' => $option);
}
cache::set('event', json_encode(self::cleanEvent(array_merge($value_src, $value))));
return;
}
$waitIfLocked = true;
$fd = self::getFileDescriptorLock();
if($fd === false){
return;
}
if (flock($fd, LOCK_EX, $waitIfLocked)) {
$cache = cache::byKey('event');
$value_src = json_decode($cache->getValue('[]'), true);
if (!is_array($value_src)) {
$value_src = array();
}
$value = array();
foreach ($_values as $option) {
$value[] = array('datetime' => getmicrotime(), 'name' => $_event, 'option' => $option);
}
cache::set('event', json_encode(self::cleanEvent(array_merge($value_src, $value))));
flock($fd, LOCK_UN);
foreach ($_values as $option) {
self::add($_event,$option,false);
}
}

public static function cleanEvent($_events) {
$_events = array_slice(array_values($_events), -self::$limit, self::$limit);
public static function cleanEvent() {
$sql = 'SELECT count(*) as number FROM `event`';
$result = DB::Prepare($sql, array(), DB::FETCH_TYPE_ROW);
$delete_number = $result['number'] - 250;
if($delete_number > 0){
$sql = 'DELETE FROM event ORDER BY `datetime` ASC LIMIT '.$delete_number;
DB::Prepare($sql, array(), DB::FETCH_TYPE_ROW);
}
$sql = 'SELECT ' . DB::buildField(__CLASS__) . '
FROM event';
$events = DB::Prepare($sql, array(), DB::FETCH_TYPE_ALL, PDO::FETCH_CLASS, __CLASS__);
$find = array();
$events = array_values($_events);
$now = strtotime('now') + 300;
foreach ($events as $key => $event) {
if ($event['datetime'] > $now) {
unset($events[$key]);
foreach ($events as $event) {
if ($event->getDatetime() > $now) {
$event->remove();
continue;
}
if ($event['name'] == 'eqLogic::update') {
$id = 'eqLogic::update::' . $event['option']['eqLogic_id'];
} elseif ($event['name'] == 'cmd::update') {
$id = 'cmd::update::' . $event['option']['cmd_id'];
} elseif ($event['name'] == 'scenario::update') {
$id = 'scenario::update::' . $event['option']['scenario_id'];
} elseif ($event['name'] == 'jeeObject::summary::update') {
$id = 'jeeObject::summary::update::' . $event['option']['object_id'];
if (is_array($event['option']['keys']) && count($event['option']['keys']) > 0) {
foreach ($event['option']['keys'] as $key2 => $value) {
if ($event->getName() == 'eqLogic::update') {
$id = 'eqLogic::update::' . $event->getOption('eqLogic_id');
} elseif ($event->getName() == 'cmd::update') {
$id = 'cmd::update::' . $event->getOption('cmd_id');
} elseif ($event->getName() == 'scenario::update') {
$id = 'scenario::update::' . $event->getOption('scenario_id');
} elseif ($event->getName() == 'jeeObject::summary::update') {
$id = 'jeeObject::summary::update::' . $event->getOption('object_id');
if (is_array($event->getOption('keys')) && count($event->getOption('keys')) > 0) {
foreach ($event->getOption('keys') as $key2 => $value) {
$id .= $key2;
}
}
} else {
continue;
}
if (isset($find[$id])) {
if ($find[$id]['datetime'] > $event['datetime']) {
unset($events[$key]);
if ($find[$id]->getDatetime() > $event->getDatetime()) {
$event->remove();
continue;
} else {
unset($events[$find[$id]['key']]);
$find[$id]->remove();
unset($find[$id]);
}
}
$find[$id] = array('datetime' => $event['datetime'], 'key' => $key);
$find[$id] = $event;
}
return array_values($events);
}

public static function orderEvent($a, $b) {
return ($a['datetime'] - $b['datetime']);
}

public static function changes($_datetime, $_longPolling = null, $_filter = null) {
self::cleanEvent();
$return = self::filterEvent(self::changesSince($_datetime), $_filter);
if ($_longPolling === null || count($return['result']) > 0) {
return $return;
if ($_longPolling === null || count($return) > 0) {
return array('datetime' => getmicrotime(), 'result'=> utils::o2a($return));
}
$waitTime = config::byKey('event::waitPollingTime');
$i = 0;
$max_cycle = $_longPolling / $waitTime;
while (count($return['result']) == 0 && $i < $max_cycle) {
while (count($return) == 0 && $i < $max_cycle) {
if ($waitTime < 1) {
usleep(1000000 * $waitTime);
} else {
Expand All @@ -162,24 +114,23 @@ public static function changes($_datetime, $_longPolling = null, $_filter = null
$return = self::filterEvent(self::changesSince($_datetime), $_filter);
$i++;
}
$return['result'] = self::cleanEvent($return['result']);
return $return;
return array('datetime' => getmicrotime(), 'result'=> utils::o2a($return));
}

private static function filterEvent($_data = array(), $_filter = null) {
private static function filterEvent($_events = array(), $_filter = null) {
if ($_filter == null) {
return $_data;
return $_events;
}
$filters = ($_filter !== null) ? cache::byKey($_filter . '::event')->getValue(array()) : array();
$return = array('datetime' => $_data['datetime'], 'result' => array());
foreach ($_data['result'] as $value) {
if ($_filter !== null && isset($_filter::$_listenEvents) && !in_array($value['name'], $_filter::$_listenEvents)) {
$return = array();
foreach (_events as $event) {
if ($_filter !== null && isset($_filter::$_listenEvents) && !in_array($event->getName(), $_filter::$_listenEvents)) {
continue;
}
if (count($filters) != 0 && $value['name'] == 'cmd::update' && !in_array($value['option']['cmd_id'], $filters)) {
if (count($filters) != 0 && $event->getName() == 'cmd::update' && !in_array($event->getOption('cmd_id'), $filters)) {
continue;
}
$return['result'][] = $value;
$return[] = $event;
}
return $return;
}
Expand All @@ -189,27 +140,49 @@ private static function changesSince($_datetime) {
if ($_datetime > $now) {
$_datetime = $now;
}
$return = array('datetime' => $_datetime, 'result' => array());
$cache = cache::byKey('event');
$events = json_decode($cache->getValue('[]'), true);
if (!is_array($events)) {
$events = array();
}
$values = array_reverse($events);
if (count($values) > 0) {
$return['datetime'] = $values[0]['datetime'];
foreach ($values as $value) {
if ($value['datetime'] <= $_datetime) {
break;
}
$return['result'][] = $value;
}
}
$return['result'] = array_reverse($return['result']);
return $return;
$sql = 'SELECT ' . DB::buildField(__CLASS__) . '
FROM event
WHERE `datetime` >= :datetime
ORDER BY `datetime`';
return DB::Prepare($sql, array('datetime' => $_datetime), DB::FETCH_TYPE_ALL, PDO::FETCH_CLASS, __CLASS__);
}

/* * *********************Methode d'instance************************* */

public function save($_direct = false){
DB::save($this, $_direct);
}

public function remove() {
return DB::remove($this);
}

/* * **********************Getteur Setteur*************************** */

public function getDatetime() {
return $this->datetime;
}

public function setDatetime($_datetime) {
$this->datetime = $_datetime;
return $this;
}

public function getName() {
return $this->name;
}

public function setName($_name) {
$this->name = $_name;
return $this;
}

public function getOption($_key = '', $_default = '') {
return utils::getJsonAttr($this->option, $_key, $_default);
}

public function setOption($_key, $_value) {
$this->option = utils::setJsonAttr($this->option, $_key, $_value);
return $this;
}
}
45 changes: 44 additions & 1 deletion install/database.json
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@
},
{
"name": "lifetime",
"type": "int",
"type": "int(11)",
"null": "YES",
"key": "",
"default": null,
Expand Down Expand Up @@ -716,6 +716,48 @@
}
}
},
{
"name": "event",
"engine" : "MEMORY",
"fields": [
{
"name": "datetime",
"type": "double(16,6)",
"null": "YES",
"key": "",
"default": null,
"extra": ""
},
{
"name": "name",
"type": "varchar(255)",
"null": "YES",
"key": "",
"default": null,
"extra": ""
},
{
"name": "option",
"type": "varchar(4095)",
"null": "YES",
"key": "",
"default": null,
"extra": ""
}
],
"indexes": {
"datetime": {
"Key_name": "datetime",
"Non_unique": "1",
"columns": {
"1": {
"column": "datetime",
"Sub_part": null
}
}
}
}
},
{
"name": "history",
"fields": [
Expand Down Expand Up @@ -920,6 +962,7 @@
},
{
"name": "interactQuery",
"engine" : "MyISAM",
"fields": [
{
"name": "id",
Expand Down

0 comments on commit ffe54c0

Please sign in to comment.