From e38ad6e5977d020c4b8c836d6b362b541827affb Mon Sep 17 00:00:00 2001 From: christiangarsia <43134868+christiangarsia@users.noreply.github.com> Date: Fri, 22 May 2020 19:32:18 +0200 Subject: [PATCH 1/7] Cache expiry time Return cache mode as integer --- Maphper/DataSource/DatabaseOptions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Maphper/DataSource/DatabaseOptions.php b/Maphper/DataSource/DatabaseOptions.php index 01fa163..da7415a 100644 --- a/Maphper/DataSource/DatabaseOptions.php +++ b/Maphper/DataSource/DatabaseOptions.php @@ -24,7 +24,7 @@ public function getEditMode() { } public function getCacheMode() { - return $this->options['cachemode'] ?? true; + return (int) ($this->options['cachemode'] ?? 0); } public function read($option) { From f8ffbfbee7914bea590b5bd4d2e6188e27700521 Mon Sep 17 00:00:00 2001 From: christiangarsia <43134868+christiangarsia@users.noreply.github.com> Date: Fri, 22 May 2020 19:33:58 +0200 Subject: [PATCH 2/7] Cache mode expiry time Added cache mode expiry time. Cache mode is integer with <0 off, 0 infinite cache, >0 store cache for x seconds. --- Maphper/DataSource/DatabaseSelect.php | 52 +++++++++++++++++++-------- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/Maphper/DataSource/DatabaseSelect.php b/Maphper/DataSource/DatabaseSelect.php index 2eb145b..20aae31 100644 --- a/Maphper/DataSource/DatabaseSelect.php +++ b/Maphper/DataSource/DatabaseSelect.php @@ -4,6 +4,7 @@ class DatabaseSelect { private $resultCache = []; private $idCache = []; + private $idCacheTime = []; private $selectBuilder; private $whereBuilder; private $adapter; @@ -21,8 +22,20 @@ public function __construct(DatabaseAdapter $adapter, DatabaseModify $databaseMo $this->table = $table; } - public function findById($id, $pk) { - if (($this->cacheMode && !isset($this->idCache[$id])) || !$this->cacheMode) { + private function cacheUpdateRequired($id) { + if ($this->cacheMode > 0) { + if (!isset($this->idCacheTime[$id])) return true; // Cache time has not been set for first time + + if (time() - $this->idCacheTime[$id] > $this->cacheMode) return true; // Cache time has expired + } + + if (!isset($this->idCache[$id])) return true; // Cache has not been set for first time + + return false; + } + + public function findById($id, $pk) { + if ($this->cacheMode < 0 || $this->cacheUpdateRequired($id)) { try { $result = $this->selectQuery($this->selectBuilder->select($this->table, $pk . ' = :id', [':id' => $id], ['limit' => 1])); } @@ -34,14 +47,20 @@ public function findById($id, $pk) { else return null; } - if (!$this->cacheMode) return $result; - else return $this->idCache[$id] = $result; + if ($this->cacheMode < 0) return $result; // Cache mode is off + + if ($this->cacheUpdateRequired()) { + $this->idCache[$id] = $result; + $this->idCacheTime[$id] = time(); + } + + return $this->idCache[$id]; } - public function findByField(array $fields, $options = []) { + public function findByField(array $fields, $options = []) { $cacheId = md5(serialize(func_get_args())); - if (($this->cacheMode && !isset($this->resultCache[$cacheId])) || !$this->cacheMode) { + if ($this->cacheMode < 0 || $this->cacheUpdateRequired($cacheId)) { $query = $this->whereBuilder->createSql($fields); if (!isset($options['order'])) $options['order'] = $this->defaultSort; @@ -57,12 +76,14 @@ public function findByField(array $fields, $options = []) { } } - if ($this->cacheMode) { - if (isset($result)) $this->resultCache[$cacheId] = $result; - if (isset($this->resultCache[$cacheId])) return $this->resultCache[$cacheId]; + if ($this->cacheMode < 0) return $result; // Cache mode is off + + if ($this->cacheUpdateRequired($cacheId)) { + $this->idCache[$cacheId] = $result; + $this->idCacheTime[$cacheId] = time(); } - return $result; + return $this->idCache[$cacheId]; } public function findAggregate($function, $field, $group = null, array $criteria = [], array $options = []) { @@ -97,21 +118,24 @@ private function selectQuery(\Maphper\Lib\Query $query) { } public function clearResultCache() { - if ($this->cacheMode) $this->resultCache = []; + if ($this->cacheMode >= 0) $this->resultCache = []; } public function clearIDCache() { - if ($this->cacheMode) $this->idCache = []; + if ($this->cacheMode >= 0) $this->idCache = []; } public function updateCache($data, $pkValue) { - if ($this->cacheMode) { + if ($this->cacheMode >= 0) { if (isset($this->cache[$pkValue])) $this->cache[$pkValue] = (object) array_merge((array)$this->cache[$pkValue], (array)$data); else $this->cache[$pkValue] = $data; } } public function deleteIDFromCache($id) { - if ($this->cacheMode) unset($this->idCache[$id]); + if ($this->cacheMode >= 0) { + unset($this->idCache[$id]); + unset($this->idCacheTime[$id]); + } } } From c9335df3162fbc57876c84a35ceba28a2933a13b Mon Sep 17 00:00:00 2001 From: christiangarsia <43134868+christiangarsia@users.noreply.github.com> Date: Fri, 22 May 2020 23:13:08 +0200 Subject: [PATCH 3/7] Method getColumns Method to retrieve table column names. --- Maphper/Maphper.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Maphper/Maphper.php b/Maphper/Maphper.php index 07027df..2f9489a 100644 --- a/Maphper/Maphper.php +++ b/Maphper/Maphper.php @@ -65,6 +65,10 @@ private function getResults() { return $results; } + public function getColumns() { + return $this->dataSource->getColumns(); + } + public function item($n) { $array = $this->getResults(); return isset($array[$n]) ? $array[$n] : null; From d6eaafabe8870f5e5265758e332212cd15955f49 Mon Sep 17 00:00:00 2001 From: christiangarsia <43134868+christiangarsia@users.noreply.github.com> Date: Fri, 22 May 2020 23:13:51 +0200 Subject: [PATCH 4/7] Method getColumns Method to retrieve table column names. --- Maphper/DataSource/Database.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Maphper/DataSource/Database.php b/Maphper/DataSource/Database.php index 1da8d3a..0484847 100644 --- a/Maphper/DataSource/Database.php +++ b/Maphper/DataSource/Database.php @@ -6,6 +6,8 @@ class Database implements \Maphper\DataSource { const EDIT_OPTIMISE = 4; private $primaryKey; + private $table; + private $fields = '*'; private $databaseSelect; private $databaseCrud; @@ -15,6 +17,7 @@ public function __construct($db, $table, $primaryKey = 'id', array $options = [] $adapter = $options->getAdapter(); $this->primaryKey = is_array($primaryKey) ? $primaryKey : [$primaryKey]; + $this->table = $table; $this->fields = implode(',', array_map([$adapter, 'quote'], (array) $options->read('fields'))); @@ -32,6 +35,10 @@ public function getPrimaryKey() { return $this->primaryKey; } + public function getColumns() { + return $this->databaseSelect->getColumns($this->table); + } + public function deleteById($id) { $this->databaseCrud->deleteById($id); } From b0c05ab080bfde9f81715c1991785615804ffc92 Mon Sep 17 00:00:00 2001 From: christiangarsia <43134868+christiangarsia@users.noreply.github.com> Date: Fri, 22 May 2020 23:14:22 +0200 Subject: [PATCH 5/7] Method getColumns Method to retrieve table column names. --- Maphper/DataSource/DatabaseSelect.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Maphper/DataSource/DatabaseSelect.php b/Maphper/DataSource/DatabaseSelect.php index 20aae31..a304318 100644 --- a/Maphper/DataSource/DatabaseSelect.php +++ b/Maphper/DataSource/DatabaseSelect.php @@ -22,6 +22,10 @@ public function __construct(DatabaseAdapter $adapter, DatabaseModify $databaseMo $this->table = $table; } + public function getColumns($table) { + return $this->adapter->getColumns($table); + } + private function cacheUpdateRequired($id) { if ($this->cacheMode > 0) { if (!isset($this->idCacheTime[$id])) return true; // Cache time has not been set for first time From 8cbba4591d5c0b61283d7af0501be4030f8668e7 Mon Sep 17 00:00:00 2001 From: christiangarsia <43134868+christiangarsia@users.noreply.github.com> Date: Fri, 22 May 2020 23:16:15 +0200 Subject: [PATCH 6/7] Method getColumns (placeholder) Method to retrieve table column names. Not yet tested for MySQL database --- Maphper/DataSource/MysqlAdapter.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Maphper/DataSource/MysqlAdapter.php b/Maphper/DataSource/MysqlAdapter.php index 3872f91..1c8b2f4 100644 --- a/Maphper/DataSource/MysqlAdapter.php +++ b/Maphper/DataSource/MysqlAdapter.php @@ -48,6 +48,18 @@ public function alterDatabase($table, array $primaryKey, $data) { $this->alterColumns($table, $primaryKey, $data); } + public function getColumns($table) { + return []; + + // TODO: test this from https://stackoverflow.com/a/13891451 + $result = $this->pdo->query('SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = ' . $table . ';')->fetchAll(\PDO::FETCH_ASSOC); + $return = []; + foreach ($result as $row) { + $return[] = $row['COLUMN_NAME']; + } + return $return; + } + public function lastInsertId() { return $this->pdo->lastInsertId(); } From 1d103d8ed00e8a5ee4355d427a4d78c1df247444 Mon Sep 17 00:00:00 2001 From: christiangarsia <43134868+christiangarsia@users.noreply.github.com> Date: Fri, 22 May 2020 23:17:05 +0200 Subject: [PATCH 7/7] Method getColumns Made existing method public to retrieve table column names. --- Maphper/DataSource/SqliteAdapter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Maphper/DataSource/SqliteAdapter.php b/Maphper/DataSource/SqliteAdapter.php index cb9f197..e0cebea 100644 --- a/Maphper/DataSource/SqliteAdapter.php +++ b/Maphper/DataSource/SqliteAdapter.php @@ -44,7 +44,7 @@ private function tableExists($name) { return count($result->fetchAll()) == 1; } - private function getColumns($table) { + public function getColumns($table) { $result = $this->pdo->query('PRAGMA table_info(' . $table . ');')->fetchAll(\PDO::FETCH_OBJ); $return = []; foreach ($result as $row) {