Passed
Pull Request — master (#70)
by Christian
02:13 queued 50s
created

DatabaseSelect::cacheUpdateRequired()   A

Complexity

Conditions 5
Paths 6

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 5
c 1
b 0
f 0
nc 6
nop 1
dl 0
loc 10
rs 9.6111
1
<?php
2
namespace Maphper\DataSource;
3
4
class DatabaseSelect {
5
    private $resultCache = [];
6
    private $idCache = [];
7
    private $idCacheTime = [];
8
    private $selectBuilder;
9
    private $whereBuilder;
10
    private $adapter;
11
    private $databaseModify;
12
    private $defaultSort;
13
    private $table;
14
15
    public function __construct(DatabaseAdapter $adapter, DatabaseModify $databaseModify, $table, $defaultSort, $cacheMode) {
16
        $this->adapter = $adapter;
17
        $this->databaseModify = $databaseModify;
18
        $this->selectBuilder = new \Maphper\Lib\SelectBuilder();
19
        $this->whereBuilder = new \Maphper\Lib\Sql\WhereBuilder();
20
        $this->defaultSort = $defaultSort;
21
        $this->cacheMode = $cacheMode;
0 ignored issues
show
Bug Best Practice introduced by
The property cacheMode does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
22
        $this->table = $table;
23
    }
24
25
    public function getColumns($table) {
26
      return $this->adapter->getColumns($table);
0 ignored issues
show
Bug introduced by
The method getColumns() does not exist on Maphper\DataSource\DatabaseAdapter. Since it exists in all sub-types, consider adding an abstract or default implementation to Maphper\DataSource\DatabaseAdapter. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

26
      return $this->adapter->/** @scrutinizer ignore-call */ getColumns($table);
Loading history...
27
    }
28
29
    private function cacheUpdateRequired($id) {
30
      if ($this->cacheMode > 0) {
31
        if (!isset($this->idCacheTime[$id])) return true; // Cache time has not been set for first time
32
33
        if (time() - $this->idCacheTime[$id] > $this->cacheMode) return true; // Cache time has expired
34
      }
35
36
      if (!isset($this->idCache[$id])) return true; // Cache has not been set for first time
37
38
      return false;
39
    }
40
41
  public function findById($id, $pk) {
42
		if ($this->cacheMode < 0 || $this->cacheUpdateRequired($id)) {
43
			try {
44
				$result = $this->selectQuery($this->selectBuilder->select($this->table, $pk . ' = :id', [':id' => $id], ['limit' => 1]));
45
			}
46
			catch (\Exception $e) {
47
                // Don't issue an error if it cannot be found since we return null
48
			}
49
50
			if (isset($result[0])) $result = $result[0];
51
			else return null;
52
		}
53
54
    if ($this->cacheMode < 0) return $result; // Cache mode is off
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $result does not seem to be defined for all execution paths leading up to this point.
Loading history...
55
56
    if ($this->cacheUpdateRequired()) {
0 ignored issues
show
Bug introduced by
The call to Maphper\DataSource\Datab...::cacheUpdateRequired() has too few arguments starting with id. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

56
    if ($this->/** @scrutinizer ignore-call */ cacheUpdateRequired()) {

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
57
      $this->idCache[$id] = $result;
58
      $this->idCacheTime[$id] = time();
59
    }
60
61
		return $this->idCache[$id];
62
	}
63
64
  public function findByField(array $fields, $options = []) {
65
		$cacheId = md5(serialize(func_get_args()));
66
67
    if ($this->cacheMode < 0 || $this->cacheUpdateRequired($cacheId)) {
68
			$query = $this->whereBuilder->createSql($fields);
69
70
			if (!isset($options['order'])) $options['order'] = $this->defaultSort;
71
72
			try {
73
				$result = $this->selectQuery($this->selectBuilder->select($this->table, $query['sql'], $query['args'], $options));
74
				$this->databaseModify->addIndex(array_keys($query['args']));
75
				$this->databaseModify->addIndex(explode(',', $options['order']));
76
			}
77
			catch (\Exception $e) {
78
				$this->errors[] = $e;
0 ignored issues
show
Bug Best Practice introduced by
The property errors does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
79
				$result = [];
80
			}
81
		}
82
83
    if ($this->cacheMode < 0) return $result; // Cache mode is off
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $result does not seem to be defined for all execution paths leading up to this point.
Loading history...
84
85
    if ($this->cacheUpdateRequired($cacheId)) {
86
      $this->idCache[$cacheId] = $result;
87
      $this->idCacheTime[$cacheId] = time();
88
    }
89
90
		return $this->idCache[$cacheId];
91
	}
92
93
    public function findAggregate($function, $field, $group = null, array $criteria = [], array $options = []) {
0 ignored issues
show
Unused Code introduced by
The parameter $options is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

93
    public function findAggregate($function, $field, $group = null, array $criteria = [], /** @scrutinizer ignore-unused */ array $options = []) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
94
		//Cannot count/sum/max multiple fields, pick the first one. This should only come into play when trying to count() a mapper with multiple primary keys
95
		if (is_array($field)) $field = $field[0];
96
		$query = $this->whereBuilder->createSql($criteria);
97
98
		try {
99
			$this->databaseModify->addIndex(array_keys($query['args']));
100
			$this->databaseModify->addIndex(explode(',', $group));
101
			$result = $this->selectQuery($this->selectBuilder->aggregate($this->table, $function, $field, $query['sql'], $query['args'], $group));
102
103
			return $this->determineAggregateResult($result, $group, $field);
104
		}
105
		catch (\Exception $e) {
106
			return $group ? [] : 0;
107
		}
108
	}
109
110
    private function determineAggregateResult($result, $group, $field) {
111
        if ($group != null) {
112
            $ret = [];
113
            foreach ($result as $res) $ret[$res->$field] = $res->val;
114
            return $ret;
115
        }
116
        else if (isset($result[0])) return $result[0]->val;
117
        else return 0;
118
    }
119
120
    private function selectQuery(\Maphper\Lib\Query $query) {
121
        return $this->adapter->query($query)->fetchAll(\PDO::FETCH_OBJ);
122
    }
123
124
    public function clearResultCache() {
125
        if ($this->cacheMode >= 0) $this->resultCache = [];
126
    }
127
128
    public function clearIDCache() {
129
        if ($this->cacheMode >= 0) $this->idCache = [];
130
    }
131
132
    public function updateCache($data, $pkValue) {
133
        if ($this->cacheMode >= 0) {
134
  		    if (isset($this->cache[$pkValue])) $this->cache[$pkValue] = (object) array_merge((array)$this->cache[$pkValue], (array)$data);
0 ignored issues
show
Bug Best Practice introduced by
The property cache does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
135
  		    else $this->cache[$pkValue] = $data;
136
        }
137
    }
138
139
    public function deleteIDFromCache($id) {
140
        if ($this->cacheMode >= 0) {
141
          unset($this->idCache[$id]);
142
          unset($this->idCacheTime[$id]);
143
        }
144
    }
145
}
146