PluginProbe
SQLite Object Cache / trunk
SQLite Object Cache vtrunk
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 trunk, at includes/cli.php

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