PluginProbe
SQLite Object Cache / 1.4.0
SQLite Object Cache v1.4.0
1.6.5 trunk 0.1.7 1.0.0 1.1.0 1.1.1 1.2.0 1.2.1 1.2.2 1.2.3 1.3.0 1.3.1 1.3.2 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.4.0 1.4.1 1.5.1 1.5.4 1.5.5 1.5.6 1.5.7 All 30 releases
sqlite-object-cache / includes / cli.php

cli.php in SQLite Object Cache 1.4.0, at includes/cli.php

428 lines 15.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php /** @noinspection ALL */
2 /** @noinspection PhpUnused */
3 /** @noinspection PhpUndefinedFunctionInspection */
4 /** @noinspection PhpUndefinedNamespaceInspection */
5 /** @noinspection PhpUndefinedClassInspection */
6
7 /**
8 * SQLite Object Cache plugin
9 *
10 * ## OPTIONS
11 *
12 * [--format=<format>]
13 * : The display format. table, csv, json, yaml.
14 *
15 * [--blogid=<blogid>]
16 * : The blog id for a multisite network. --url also selects the blog if you prefer.
17 *
18 */
19 class SQLite_Object_Cache_CLI extends WP_CLI_Command {
20
21 public $db;
22 public $assoc_args;
23 public $cmd = 'wp index-mysql';
24 public $allSwitch = false;
25 public $rekeying;
26 public $errorMessages = [];
27 public $dryrun;
28 private $commentPrefix;
29
30 /**
31 * Show the version of the plugin.
32 *
33 */
34 function version( $args, $assoc_args ) {
35 $this->setupCliEnvironment( $args, $assoc_args );
36
37 global $wp_object_cache;
38 $igbinary = function_exists( 'igbinary_serialize' ) && function_exists( 'igbinary_unserialize' )
39 ? __( 'available', 'sqlite-object-cache' )
40 : __( 'unavailable', 'sqlite-object-cache' );
41
42 if ( method_exists( $wp_object_cache, 'sqlite_get_version' ) ) {
43 $msg = sprintf(
44 /* translators: 1: version for sqlite 2: version for plugin 3: status of igbinary --- for WP-CLI */
45 __( 'Versions: SQLite: %1$s Plugin: %2$s igbinary: %3$s.', 'sqlite-object-cache' ),
46 $wp_object_cache->sqlite_get_version(),
47 '1.4.0',
48 $igbinary );
49 }
50
51 WP_CLI::log( $this->commentPrefix . $msg );
52 }
53
54 /** @noinspection PhpUnusedParameterInspection */
55 private function setupCliEnvironment( $args, $assoc_args ) {
56 $this->assoc_args = $assoc_args;
57 if ( is_multisite() ) {
58 $restoreBlogId = get_current_blog_id();
59 if ( ! empty( $assoc_args['blogid'] ) ) {
60 $this->cmd .= ' --blogid=' . $assoc_args['blogid'];
61 switch_to_blog( $assoc_args['blogid'] );
62 } else {
63 switch_to_blog( $restoreBlogId );
64 }
65 }
66 }
67
68 /**
69 * Show status.
70 *
71 * @param $args
72 * @param $assoc_args
73 */
74 function status( $args, $assoc_args ) {
75 $this->setupCliEnvironment( $args, $assoc_args );
76 global $wp_object_cache;
77 if ( method_exists( $wp_object_cache, 'sqlite_sizes' ) ) {
78
79 $sizes = $wp_object_cache->sqlite_sizes();
80 $msgs = array();
81
82 /* translators: 1: size of .sqlite database file in MiB. --- for WP-CLI */
83 $msgs[] = sprintf( __( 'SQLite File Size Total: %sMiB', 'sqlite-object-cache' ), number_format_i18n( $sizes['page_size'] * $sizes['total_pages'] / ( 1024.0 * 1024.0 ), 3 ) );
84 /* translators: 1: size of .sqlite database file free space in MiB. --- for WP-CLI */
85 $msgs[] = sprintf( __( 'Free: %sMiB', 'sqlite-object-cache' ), number_format_i18n( $sizes['page_size'] * $sizes['free_pages'] / ( 1024.0 * 1024.0 ), 3 ) );
86 $mmapsize = $sizes['mmap_size'];
87 if ( $mmapsize > 0 ) {
88 /* translators: 1: size of memory mapped segment in MiB. --- for WP-CLI */
89 $msgs[] = sprintf( __( 'Memory Mapped Segment Size: %sMiB', 'sqlite-object-cache' ), number_format_i18n( $mmapsize / ( 1024.0 * 1024.0 ) ) );
90 }
91
92 $length = 0;
93 $count = 0;
94 $earliest = PHP_INT_MAX;
95 $latest = PHP_INT_MIN;
96 try {
97 foreach ( $wp_object_cache->sqlite_load_usages( true ) as $item ) {
98 $length += $item->length;
99 $count ++;
100 $ts = $item->expires;
101 $earliest = min( $earliest, $ts );
102 $latest = max( $latest, $ts );
103 }
104 } catch ( Exception $ex ) {
105 $length = 0;
106 $count = 0;
107 $earliest = PHP_INT_MAX;
108 $latest = PHP_INT_MIN;
109 }
110 if ( $length > 0 ) {
111 /* translators: 1: number of cached items. --- for WP-CLI */
112 $msgs[] = sprintf( __( 'Cached Data Size %sMiB', 'sqlite-object-cache' ), number_format_i18n( $length / ( 1024.0 * 1024.0 ), 3 ) );
113 }
114 if ( $count > 0 ) {
115 /* translators: 1: number of cached items. --- for WP-CLI */
116 $msgs[] = sprintf( __( 'Item Count: %s', 'sqlite-object-cache' ), number_format_i18n( $count ) );
117 }
118 if ( $earliest <= $latest ) {
119 /* translators: 1 start time 2 end time both in localized format. --- for WP-CLI */
120 $msgs[] = sprintf( __( 'Expirations: %1$s to %2$s.', 'sqlite-object-cache' ),
121 $this->format_datestamp( $earliest ), $this->format_datestamp( $latest ) );
122 }
123
124 WP_CLI::log( $this->commentPrefix . implode( ' ', $msgs ) );
125
126 }
127 }
128
129 /**
130 * Set or get the target size of the SQLite database file holding the object cache.
131 * ## OPTIONS
132 *
133 * [<size>]
134 * : The size to set in MiB. Omit to get the current size.
135 */
136 function size( $args, $assoc_args ) {
137
138 $targetAction = 1;
139 $this->setupCliEnvironment( $args, $assoc_args );
140 if ( count( $args ) > 1 ) {
141 WP_CLI::error( $this->commentPrefix . __( 'Too many args. "sqlite-object-cache size 64" sets it to 64MiB.', 'sqlite-object-cache' ) );
142 return;
143 }
144 list( $options, $old_target_size ) = $this->get_one_option( 'target_size' );
145
146 if ( 1 === count( $args ) ) {
147 $new_target_size = strval( $args[0] );
148 if ( $new_target_size === $old_target_size ) {
149 /* translators: 1: new target cache size --- for WP-CLI */
150 $msg = __( 'Target cache size unchanged at %1$sMiB', 'sqlite_object_cache' );
151 $msg = sprintf( $msg, $new_target_size );
152 WP_CLI::log( $this->commentPrefix . $msg );
153 } else {
154 /* translators: 1: new target cache size 2:former target cache size */
155 $msg = __( 'Target cache size changed from %2$sMiB to %1$sMiB', 'sqlite_object_cache' );
156 $msg = sprintf( $msg, $new_target_size, $old_target_size );
157 $options['target_size'] = strval( $new_target_size );
158 update_option( 'sqlite_object_cache_settings', $options, true );
159 WP_CLI::success( $this->commentPrefix . $msg );
160 }
161 } else {
162 /* translators: 1: target cache size */
163 $msg = __( 'Target cache size is %1$sMiB', 'sqlite_object_cache' );
164 $msg = sprintf( $msg, $old_target_size );
165 WP_CLI::log( $this->commentPrefix . $msg );
166 }
167
168 }
169
170 /**
171 * Set or get the performance measurement sample rate percentage. 0 disables measurement.
172 * ## OPTIONS
173 *
174 * [<samplerate>]
175 * : The sample rate to set. A number 0 - 100. Omit to get the current rate.
176 */
177 function samplerate( $args, $assoc_args ) {
178
179 $this->setupCliEnvironment( $args, $assoc_args );
180 if ( count( $args ) > 1 ) {
181 WP_CLI::error( $this->commentPrefix . __( 'Too many args. "sqlite-object-cache samplerate 10" samples ten percent.', 'sqlite-object-cache' ) );
182 return;
183 }
184 list( $options, $old_samplerate ) = $this->get_one_option( 'samplerate' );
185 list( $options, $old_capture ) = $this->get_one_option( 'capture' );
186 $old_samplerate = strval( ( $old_samplerate < 0 ) ? 0 : $old_samplerate );
187 $old_samplerate = strval( ( $old_samplerate > 100 ) ? 100 : $old_samplerate );
188 $old_capture = ( 'on' !== $old_capture ) ? 'off' : 'on';
189 $old_samplerate = strval( ( 'on' !== $old_capture ) ? 0 : $old_samplerate );
190 $old_capture = ( '0' === $old_samplerate ) ? 'off' : 'on';
191
192 if ( 1 === count( $args ) ) {
193 $new_samplerate = strval( $args[0] );
194 $new_samplerate = strval( ( $new_samplerate < 0 ) ? 0 : $new_samplerate );
195 $new_samplerate = strval( ( $new_samplerate > 100 ) ? 100 : $new_samplerate );
196 $new_capture = ( '0' === $new_samplerate ) ? 'off' : 'on';
197 if ( $old_samplerate === $new_samplerate ) {
198 /* translators: 1: new sample rate 0-100 --- for WP-CLI */
199 $msg = __( 'Performance measurement sample rate unchanged at %1$s%%', 'sqlite_object_cache' );
200 $msg = sprintf( $msg, $new_samplerate );
201 WP_CLI::log( $this->commentPrefix . $msg );
202 } else {
203 /* translators: 1: new rate 2:former rate --- for WP-CLI */
204 $msg = __( 'Performance measurement sample rate changed from %2$s%% to %1$s%%', 'sqlite_object_cache' );
205 $msg = sprintf( $msg, $new_samplerate, $old_samplerate );
206 $options['samplerate'] = strval( $new_samplerate );
207 $options['capture'] = $new_capture;
208
209 update_option( 'sqlite_object_cache_settings', $options, true );
210 WP_CLI::success( $this->commentPrefix . $msg );
211
212 }
213 } else {
214 /* translators: 1: sample rate --- for WP-CLI */
215 $msg = __( 'Performance measurement sample rate is %1$s%%', 'sqlite_object_cache' );
216 $msg = sprintf( $msg, $old_samplerate );
217 WP_CLI::log( $this->commentPrefix . $msg );
218 }
219
220 }
221
222 /**
223 * Set or get how long to retain performance measurements.
224 * ## OPTIONS
225 *
226 * [<time>]
227 * : The time in hours to retain measurements. Omit to get the current retention time.
228 */
229 function retain( $args, $assoc_args ) {
230
231 $this->setupCliEnvironment( $args, $assoc_args );
232 if ( count( $args ) > 1 ) {
233 WP_CLI::error( $this->commentPrefix . __( 'Too many args. "sqlite-object-cache retain 4" retains measuremewnts for 4 hours.', 'sqlite-object-cache' ) );
234 return;
235 }
236 list( $options, $old_samplerate ) = $this->get_one_option( 'retainmeasurements' );
237 $old_retain = strval( ( $old_retain < 1 ) ? 1 : $old_retain );
238
239 if ( 1 === count( $args ) ) {
240 $new_retain = strval( $args[0] );
241 $new_retain = strval( ( $new_retain < 1 ) ? 1 : $new_retain );
242 if ( $old_retain === $new_retain ) {
243 /* translators: 1: retention time --- for WP-CLI */
244 $msg = __( 'Performance measurement retention unchanged at %1$shr', 'sqlite_object_cache' );
245 $msg = sprintf( $msg, $new_retain );
246 WP_CLI::log( $this->commentPrefix . $msg );
247 } else {
248 /* translators: 1: new retention time 2:former time --- for WP-CLI */
249 $msg = __( 'Performance measurement retention changed from %2$shr to %1$shr', 'sqlite_object_cache' );
250 $msg = sprintf( $msg, $new_retain, $old_retain );
251 $options['retainmeasurements'] = strval( $new_retain );
252
253 update_option( 'sqlite_object_cache_settings', $options, true );
254 WP_CLI::success( $this->commentPrefix . $msg );
255
256 }
257 } else {
258 /* translators: 1: retention time --- for WP-CLI */
259 $msg = __( 'Performance measurement retention is %1$shr', 'sqlite_object_cache' );
260 $msg = sprintf( $msg, $old_retain );
261 WP_CLI::log( $this->commentPrefix . $msg );
262 }
263
264 }
265
266 /**
267 * Flush the cache (delete all its entries). This briefly puts your site into maintenance mode.
268 */
269 function flush( $args, $assoc_args ) {
270 global $wp_object_cache;
271 if ( method_exists( $wp_object_cache, 'flush' ) ) {
272 try {
273 $this->enter_maintenance_mode();
274 $wp_object_cache->flush( true );
275 } finally {
276 $this->exit_maintenance_mode();
277 }
278 }
279 }
280
281 /**
282 * Vacuum (defragment) the cache. This briefly puts your site into maintenance mode.
283 */
284 function vacuum( $args, $assoc_args ) {
285 global $wp_object_cache;
286 if ( method_exists( $wp_object_cache, 'vacuum' ) ) {
287 try {
288 $this->enter_maintenance_mode();
289 $wp_object_cache->vacuum();
290 } finally {
291 $this->exit_maintenance_mode();
292 }
293 }
294 }
295
296 /**
297 * Clean up (delete expired entries from) the cache.
298 */
299 function cleanup( $args, $assoc_args ) {
300 list( $options, $target_size ) = $this->get_one_option( 'target_size' );
301
302 $target_size *= ( 1024 * 1024 );
303 $threshold_size = (int) ( $target_size );
304
305 global $wp_object_cache;
306 if ( ! method_exists( $wp_object_cache, 'sqlite_get_size' ) ) {
307 return;
308 }
309 $original_size = $wp_object_cache->sqlite_get_size();
310 $current_size = $original_size;
311 /* Skip this if the current size is small enough. */
312 if ( $current_size <= $threshold_size ) {
313 /* translators: 1: size of cache --- For WP-CLI */
314 $msg = __( 'Cache contains %1$01.1fMiB, no cleanup performed', 'sqlite_object_cache' );
315 $msg = sprintf( $msg, $original_size / ( 1024.0 * 1024.0 ) );
316 WP_CLI::log( $this->commentPrefix . $msg );
317
318 return;
319 }
320
321
322 /* Remove expired items (transients mostly). --- For WP-CLI */
323 if ( $wp_object_cache->sqlite_remove_expired() ) {
324 /* If anything was removed, get the size again. --- For WP-CLI */
325 $current_size = $wp_object_cache->sqlite_get_size();
326
327 if ( $current_size < $original_size ) {
328 /* translators: 1: size removed 2: size remaining */
329 $msg = __( '%1$01.1fMiB of expired items removed from cache, leaving %2$01.1fMiB', 'sqlite_object_cache' );
330 $msg = sprintf( $msg, ( $original_size - $current_size ) / ( 1024.0 * 1024.0 ), ( $current_size ) / ( 1024.0 * 1024.0 ) );
331 WP_CLI::success( $this->commentPrefix . $msg );
332 }
333 }
334
335 /* Skip this if the size is small enough, after removing expired items. */
336 if ( $current_size <= $threshold_size ) {
337 return;
338 }
339
340 /* Clean up old statistics. */
341 $original_size = $current_size;
342 list( $options, $target_size ) = $this->get_one_option( 'retainmeasurements' );
343 $wp_object_cache->sqlite_reset_statistics( $retention * HOUR_IN_SECONDS );
344 $current_size = $wp_object_cache->sqlite_get_size();
345 if ( $current_size < $original_size ) {
346 /* translators: 1: size removed 2: size remaining --- For WP-CLI */
347 $msg = __( '%1$01.1fMiB of performance measurements removed from cache, leaving %2$01.1fMiB', 'sqlite_object_cache' );
348 $msg = sprintf( $msg, ( $original_size - $current_size ) / ( 1024.0 * 1024.0 ), ( $current_size ) / ( 1024.0 * 1024.0 ) );
349 WP_CLI::success( $this->commentPrefix . $msg );
350 }
351
352 if ( $current_size <= $threshold_size ) {
353 return;
354 }
355
356 /* Delete the least-recently-updated items to get to the target size. */
357 $original_size = $current_size;
358 $wp_object_cache->sqlite_delete_old( $target_size, $current_size );
359 $current_size = $wp_object_cache->sqlite_get_size();
360 if ( $current_size < $original_size ) {
361 /* translators: 1: size removed 2: size remaining --- For WP-CLI */
362 $msg = __( '%1$01.1fMiB of least recently updated items removed from cache, leaving %2$01.1fMiB', 'sqlite_object_cache' );
363 $msg = sprintf( $msg, ( $original_size - $current_size ) / ( 1024.0 * 1024.0 ), ( $current_size ) / ( 1024.0 * 1024.0 ) );
364 WP_CLI::success( $this->commentPrefix . $msg );
365 }
366
367 $wp_object_cache->sqlite_delete_old( $target_size, $current_size );
368 }
369
370 private function get_one_option(
371 $name
372 ): array {
373 #a:5:{s:11:"target_size";s:2:"16";s:7:"capture";s:2:"on";s:10:"samplerate";s:3:"100";s:18:"retainmeasurements";s:1:"2";s:15:"previouscapture";i:0;}
374 $default = array(
375 'target_size' => '16',
376 'capture' => 'off',
377 'samplerate' => '1',
378 'retainmeasurements' => '2'
379 );
380 $options = get_option( 'sqlite_object_cache_settings', $default );
381 $val = strval( $options[ $name ] );
382 return array( $options, $val );
383 }
384
385 /**
386 * Enters maintenance mode.
387 *
388 * @return void
389 */
390 private function enter_maintenance_mode() {
391 $maintenanceFileName = ABSPATH . '.maintenance';
392 $maintain = array();
393 array_push( $maintain,
394 '<?php',
395 '$upgrading = ' . time() . ';',
396 '?>' );
397 file_put_contents( $maintenanceFileName, implode( PHP_EOL, $maintain ) );
398 }
399
400 /**
401 * Exits maintenance mode.
402 *
403 * @return void
404 */
405 private function exit_maintenance_mode() {
406 $maintenanceFileName = ABSPATH . '.maintenance';
407 unlink( $maintenanceFileName );
408 }
409
410 /**
411 * Format a UNIX timestamp using WP settings.
412 *
413 * @param $stamp
414 *
415 * @return false|string
416 */
417 private function format_datestamp(
418 $stamp
419 ) {
420 $date_format = get_option( 'date_format' ) . ' ' . get_option( 'time_format' );
421
422 return wp_date( $date_format, (int) $stamp );
423 }
424
425 }
426
427 WP_CLI::add_command( 'sqlite-object-cache', 'SQLite_Object_Cache_CLI' );
428