diff --git a/core/class/DB.class.php b/core/class/DB.class.php index ca3b48db09..7300404cb9 100644 --- a/core/class/DB.class.php +++ b/core/class/DB.class.php @@ -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'; @@ -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) { diff --git a/core/class/event.class.php b/core/class/event.class.php index f5e956a6f1..a71f72b820 100644 --- a/core/class/event.class.php +++ b/core/class/event.class.php @@ -22,105 +22,60 @@ 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; } } @@ -128,31 +83,28 @@ public static function cleanEvent($_events) { 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 { @@ -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; } @@ -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; + } } diff --git a/install/database.json b/install/database.json index e342e4c0a2..618bbae007 100644 --- a/install/database.json +++ b/install/database.json @@ -276,7 +276,7 @@ }, { "name": "lifetime", - "type": "int", + "type": "int(11)", "null": "YES", "key": "", "default": null, @@ -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": [ @@ -920,6 +962,7 @@ }, { "name": "interactQuery", + "engine" : "MyISAM", "fields": [ { "name": "id",