Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cache mode expiry time #70

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Maphper/DataSource/Database.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ class Database implements \Maphper\DataSource {
const EDIT_OPTIMISE = 4;

private $primaryKey;
private $table;

private $fields = '*';
private $databaseSelect;
private $databaseCrud;
Expand All @@ -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')));

Expand All @@ -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);
}
Expand Down
2 changes: 1 addition & 1 deletion Maphper/DataSource/DatabaseOptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
56 changes: 42 additions & 14 deletions Maphper/DataSource/DatabaseSelect.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
class DatabaseSelect {
private $resultCache = [];
private $idCache = [];
private $idCacheTime = [];
private $selectBuilder;
private $whereBuilder;
private $adapter;
Expand All @@ -21,8 +22,24 @@ public function __construct(DatabaseAdapter $adapter, DatabaseModify $databaseMo
$this->table = $table;
}

public function findById($id, $pk) {
if (($this->cacheMode && !isset($this->idCache[$id])) || !$this->cacheMode) {
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

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]));
}
Expand All @@ -34,14 +51,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;
Expand All @@ -57,12 +80,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 = []) {
Expand Down Expand Up @@ -97,21 +122,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]);
}
}
}
12 changes: 12 additions & 0 deletions Maphper/DataSource/MysqlAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down
2 changes: 1 addition & 1 deletion Maphper/DataSource/SqliteAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
4 changes: 4 additions & 0 deletions Maphper/Maphper.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down