1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* This file is part of the SVN-Buddy library. |
4
|
|
|
* For the full copyright and license information, please view |
5
|
|
|
* the LICENSE file that was distributed with this source code. |
6
|
|
|
* |
7
|
|
|
* @copyright Alexander Obuhovich <[email protected]> |
8
|
|
|
* @link https://github.com/console-helpers/svn-buddy |
9
|
|
|
*/ |
10
|
|
|
|
11
|
|
|
namespace ConsoleHelpers\SVNBuddy\Repository\RevisionLog\Plugin; |
12
|
|
|
|
13
|
|
|
|
14
|
|
|
use Aura\Sql\ExtendedPdoInterface; |
15
|
|
|
use ConsoleHelpers\SVNBuddy\Repository\RevisionLog\RepositoryFiller; |
16
|
|
|
use ConsoleHelpers\SVNBuddy\Repository\RevisionLog\RevisionLog; |
17
|
|
|
|
18
|
|
|
abstract class AbstractPlugin implements IPlugin |
19
|
|
|
{ |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* Database. |
23
|
|
|
* |
24
|
|
|
* @var ExtendedPdoInterface |
25
|
|
|
*/ |
26
|
|
|
protected $database; |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* Repository filler. |
30
|
|
|
* |
31
|
|
|
* @var RepositoryFiller |
32
|
|
|
*/ |
33
|
|
|
protected $repositoryFiller; |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* Revision log. |
37
|
|
|
* |
38
|
|
|
* @var RevisionLog |
39
|
|
|
*/ |
40
|
|
|
protected $revisionLog; |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* Parsing statistics. |
44
|
|
|
* |
45
|
|
|
* @var array |
46
|
|
|
*/ |
47
|
|
|
private $_statistics = array(); |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* Creates plugin instance. |
51
|
|
|
* |
52
|
|
|
* @param ExtendedPdoInterface $database Database. |
53
|
|
|
* @param RepositoryFiller $repository_filler Repository filler. |
54
|
|
|
*/ |
55
|
130 |
|
public function __construct(ExtendedPdoInterface $database, RepositoryFiller $repository_filler) |
56
|
|
|
{ |
57
|
130 |
|
$this->database = $database; |
58
|
130 |
|
$this->repositoryFiller = $repository_filler; |
59
|
|
|
|
60
|
130 |
|
$this->_resetParsingStatistics(); |
61
|
|
|
} |
62
|
|
|
|
63
|
|
|
/** |
64
|
|
|
* Resets parsing statistics. |
65
|
|
|
* |
66
|
|
|
* @return void |
67
|
|
|
*/ |
68
|
130 |
|
private function _resetParsingStatistics() |
69
|
|
|
{ |
70
|
130 |
|
$this->_statistics = array(); |
71
|
|
|
|
72
|
130 |
|
foreach ( $this->defineStatisticTypes() as $parsing_statistic_type ) { |
73
|
119 |
|
$this->_statistics[$parsing_statistic_type] = 0; |
74
|
|
|
} |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* Returns raw information about revisions. |
79
|
|
|
* |
80
|
|
|
* @param string $sql SQL. |
81
|
|
|
* @param string $revisions_param_name Revisions param name. |
82
|
|
|
* @param array $revisions Revisions. |
83
|
|
|
* @param boolean $assoc Use first column as returned array key. |
84
|
|
|
* |
85
|
|
|
* @return array |
86
|
|
|
*/ |
87
|
8 |
|
protected function getRawRevisionsData($sql, $revisions_param_name, array $revisions, $assoc = false) |
88
|
|
|
{ |
89
|
|
|
// Several queries on a smaller revision set appear to be much faster, then one query for all revisions. |
90
|
8 |
|
$revisions_data = array(); |
91
|
|
|
|
92
|
8 |
|
if ( $assoc ) { |
93
|
2 |
|
foreach ( array_chunk($revisions, 500) as $revisions_chunk ) { |
94
|
2 |
|
$revisions_data += $this->database->fetchAssoc($sql, array($revisions_param_name => $revisions_chunk)); |
95
|
|
|
} |
96
|
|
|
|
97
|
2 |
|
return $revisions_data; |
98
|
|
|
} |
99
|
|
|
|
100
|
6 |
|
foreach ( array_chunk($revisions, 500) as $revisions_chunk ) { |
101
|
6 |
|
$revisions_data = array_merge( |
102
|
6 |
|
$revisions_data, |
103
|
6 |
|
$this->database->fetchAll($sql, array($revisions_param_name => $revisions_chunk)) |
104
|
6 |
|
); |
105
|
|
|
} |
106
|
|
|
|
107
|
6 |
|
return $revisions_data; |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
/** |
111
|
|
|
* Hook, that is called before "RevisionLog::refresh" method call. |
112
|
|
|
* |
113
|
|
|
* @return void |
114
|
|
|
*/ |
115
|
85 |
|
public function whenDatabaseReady() |
116
|
|
|
{ |
117
|
|
|
|
118
|
85 |
|
} |
119
|
|
|
|
120
|
|
|
/** |
121
|
|
|
* Records parsing statistics. |
122
|
|
|
* |
123
|
|
|
* @param string $type Type. |
124
|
|
|
* @param integer $to_add Number to add. |
125
|
|
|
* |
126
|
|
|
* @return void |
127
|
|
|
*/ |
128
|
35 |
|
protected function recordStatistic($type, $to_add = 1) |
129
|
|
|
{ |
130
|
35 |
|
$this->_statistics[$type] += $to_add; |
131
|
|
|
} |
132
|
|
|
|
133
|
|
|
/** |
134
|
|
|
* Returns parsing statistics. |
135
|
|
|
* |
136
|
|
|
* @return array |
137
|
|
|
*/ |
138
|
38 |
|
public function getStatistics() |
139
|
|
|
{ |
140
|
38 |
|
return $this->_statistics; |
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
/** |
144
|
|
|
* Adds results for missing revisions. |
145
|
|
|
* |
146
|
|
|
* @param array $revisions Revisions. |
147
|
|
|
* @param array $results Results. |
148
|
|
|
* |
149
|
|
|
* @return array |
150
|
|
|
*/ |
151
|
4 |
|
protected function addMissingResults(array $revisions, array $results) |
152
|
|
|
{ |
153
|
4 |
|
foreach ( $this->_getMissingRevisions($revisions, $results) as $missing_revision ) { |
154
|
4 |
|
$results[$missing_revision] = array(); |
155
|
|
|
} |
156
|
|
|
|
157
|
4 |
|
return $results; |
158
|
|
|
} |
159
|
|
|
|
160
|
|
|
/** |
161
|
|
|
* Adds results for missing revisions. |
162
|
|
|
* |
163
|
|
|
* @param array $revisions Revisions. |
164
|
|
|
* @param array $results Results. |
165
|
|
|
* |
166
|
|
|
* @return void |
167
|
|
|
* @throws \InvalidArgumentException When some revisions are missing in results. |
168
|
|
|
*/ |
169
|
4 |
|
protected function assertNoMissingRevisions(array $revisions, array $results) |
170
|
|
|
{ |
171
|
4 |
|
$missing_revisions = $this->_getMissingRevisions($revisions, $results); |
172
|
|
|
|
173
|
4 |
|
if ( !$missing_revisions ) { |
|
|
|
|
174
|
2 |
|
return; |
175
|
|
|
} |
176
|
|
|
|
177
|
2 |
|
throw new \InvalidArgumentException(sprintf( |
178
|
2 |
|
'Revision(-s) "%s" not found by "%s" plugin.', |
179
|
2 |
|
implode('", "', $missing_revisions), |
180
|
2 |
|
$this->getName() |
181
|
2 |
|
)); |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
/** |
185
|
|
|
* Returns revisions, that are missing in results. |
186
|
|
|
* |
187
|
|
|
* @param array $revisions Revisions. |
188
|
|
|
* @param array $results Results. |
189
|
|
|
* |
190
|
|
|
* @return array |
191
|
|
|
*/ |
192
|
8 |
|
private function _getMissingRevisions(array $revisions, array $results) |
193
|
|
|
{ |
194
|
8 |
|
return array_diff($revisions, array_keys($results)); |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
/** |
198
|
|
|
* Returns last revision processed by plugin. |
199
|
|
|
* |
200
|
|
|
* @return integer |
201
|
|
|
*/ |
202
|
57 |
|
public function getLastRevision() |
203
|
|
|
{ |
204
|
57 |
|
$sql = 'SELECT LastRevision |
205
|
|
|
FROM PluginData |
206
|
57 |
|
WHERE Name = :name'; |
207
|
57 |
|
$last_revision = $this->database->fetchValue($sql, array('name' => $this->getName())); |
208
|
|
|
|
209
|
57 |
|
return $last_revision !== false ? $last_revision : 0; |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
/** |
213
|
|
|
* Sets last revision processed by plugin. |
214
|
|
|
* |
215
|
|
|
* @param integer $last_revision Last revision. |
216
|
|
|
* |
217
|
|
|
* @return void |
218
|
|
|
*/ |
219
|
38 |
|
protected function setLastRevision($last_revision) |
220
|
|
|
{ |
221
|
38 |
|
$sql = 'REPLACE INTO PluginData (Name, LastRevision) |
222
|
38 |
|
VALUES (:name, :last_revision)'; |
223
|
38 |
|
$this->database->perform($sql, array('name' => $this->getName(), 'last_revision' => $last_revision)); |
224
|
|
|
} |
225
|
|
|
|
226
|
|
|
/** |
227
|
|
|
* Finds project by path. |
228
|
|
|
* |
229
|
|
|
* @param string $path Path. |
230
|
|
|
* |
231
|
|
|
* @return integer |
232
|
|
|
* @throws \InvalidArgumentException When project can't be found. |
233
|
|
|
*/ |
234
|
39 |
|
protected function getProject($path) |
235
|
|
|
{ |
236
|
39 |
|
$sql = 'SELECT Id |
237
|
|
|
FROM Projects |
238
|
39 |
|
WHERE Path = :path'; |
239
|
39 |
|
$project_id = $this->database->fetchValue($sql, array('path' => $path)); |
240
|
|
|
|
241
|
39 |
|
if ( $project_id === false ) { |
242
|
5 |
|
throw new \InvalidArgumentException('The project with "' . $path . '" path not found.'); |
243
|
|
|
} |
244
|
|
|
|
245
|
34 |
|
return $project_id; |
246
|
|
|
} |
247
|
|
|
|
248
|
|
|
/** |
249
|
|
|
* Automatically free memory, when >200MB is used. |
250
|
|
|
* |
251
|
|
|
* @return void |
252
|
|
|
* |
253
|
|
|
* @codeCoverageIgnore |
254
|
|
|
*/ |
255
|
|
|
protected function freeMemoryAutomatically() |
256
|
|
|
{ |
257
|
|
|
$memory_usage = memory_get_usage(); |
258
|
|
|
|
259
|
|
|
if ( $memory_usage > 200 * 1024 * 1024 ) { |
260
|
|
|
$this->freeMemoryManually(); |
261
|
|
|
} |
262
|
|
|
} |
263
|
|
|
|
264
|
|
|
/** |
265
|
|
|
* Frees consumed memory manually. |
266
|
|
|
* |
267
|
|
|
* @return void |
268
|
|
|
* |
269
|
|
|
* @codeCoverageIgnore |
270
|
|
|
*/ |
271
|
|
|
protected function freeMemoryManually() |
272
|
|
|
{ |
273
|
|
|
$profiler = $this->database->getProfiler(); |
274
|
|
|
|
275
|
|
|
if ( is_object($profiler) && $profiler->isActive() ) { |
276
|
|
|
$profiler->resetProfiles(); |
|
|
|
|
277
|
|
|
} |
278
|
|
|
} |
279
|
|
|
|
280
|
|
|
/** |
281
|
|
|
* Sets reference to revision log. |
282
|
|
|
* |
283
|
|
|
* @param RevisionLog $revision_log Revision log. |
284
|
|
|
* |
285
|
|
|
* @return void |
286
|
|
|
*/ |
287
|
4 |
|
public function setRevisionLog(RevisionLog $revision_log) |
288
|
|
|
{ |
289
|
4 |
|
$this->revisionLog = $revision_log; |
290
|
|
|
} |
291
|
|
|
|
292
|
|
|
} |
293
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.