Skip to content

Commit 77cd891

Browse files
committed
feat: implement cache invalidate command and cache type detection
- Add cache invalidate <pattern> CLI command with support for: * Table name patterns (users, table:users) * Table prefix patterns (table:users_*) * Key patterns (pdodb_table_users_*) - Add cache type detection in cache stats (Redis, Memcached, APCu, Filesystem, Array, Unknown) - Implement metadata storage for table associations in cache keys - Add table extraction from SQL queries for metadata tracking - Update cache stats to show cache backend type - Add comprehensive tests for cache invalidate functionality - Update bash completion script for cache invalidate command - Update documentation with cache invalidate examples and patterns - Update cache management example with invalidate demonstration - Fix testQueryCaching to filter metadata keys correctly The invalidate command supports universal table name matching for all cache types, with enhanced pattern matching for Redis/Memcached backends.
1 parent bc3a96e commit 77cd891

File tree

10 files changed

+667
-20
lines changed

10 files changed

+667
-20
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
.idea
22
.cursor
3+
.env
34
/nbproject
45
vendor
56
composer.lock

documentation/05-advanced-features/21-cli-tools.md

Lines changed: 73 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -907,7 +907,7 @@ The display updates every 2 seconds. Press `Ctrl+C` to exit.
907907

908908
## Cache Management
909909

910-
Manage query result cache using CLI commands for cache statistics and clearing.
910+
Manage query result cache using CLI commands for cache statistics, invalidation, and clearing.
911911

912912
### Usage
913913

@@ -918,6 +918,15 @@ vendor/bin/pdodb cache stats
918918
# Show cache statistics in JSON format
919919
vendor/bin/pdodb cache stats --format=json
920920

921+
# Invalidate cache entries by pattern (interactive)
922+
vendor/bin/pdodb cache invalidate users
923+
924+
# Invalidate cache entries by pattern without confirmation
925+
vendor/bin/pdodb cache invalidate "table:users" --force
926+
927+
# Invalidate cache entries by table prefix
928+
vendor/bin/pdodb cache invalidate "table:users_*" --force
929+
921930
# Clear all cached query results (interactive)
922931
vendor/bin/pdodb cache clear
923932

@@ -928,7 +937,7 @@ vendor/bin/pdodb cache clear --force
928937
### Options
929938

930939
- `--format=table|json` - Output format for stats (default: table)
931-
- `--force` - Skip confirmation prompt (for clear)
940+
- `--force` - Skip confirmation prompt (for clear/invalidate)
932941

933942
### Examples
934943

@@ -941,6 +950,7 @@ Cache Statistics
941950
================
942951

943952
Enabled: Yes
953+
Type: Redis
944954
Prefix: pdodb_
945955
Default TTL: 3600 seconds
946956
Hits: 1250
@@ -958,6 +968,7 @@ $ vendor/bin/pdodb cache stats --format=json
958968

959969
{
960970
"enabled": true,
971+
"type": "Redis",
961972
"prefix": "pdodb_",
962973
"default_ttl": 3600,
963974
"hits": 1250,
@@ -969,6 +980,33 @@ $ vendor/bin/pdodb cache stats --format=json
969980
}
970981
```
971982

983+
#### Invalidate Cache by Table Name
984+
985+
```bash
986+
$ vendor/bin/pdodb cache invalidate users
987+
988+
Are you sure you want to invalidate cache entries matching pattern 'users'? [y/N]: y
989+
✓ Invalidated 25 cache entries matching pattern 'users'
990+
```
991+
992+
#### Invalidate Cache by Table Pattern
993+
994+
```bash
995+
$ vendor/bin/pdodb cache invalidate "table:users" --force
996+
997+
✓ Invalidated 25 cache entries matching pattern 'table:users'
998+
```
999+
1000+
#### Invalidate Cache by Table Prefix
1001+
1002+
```bash
1003+
$ vendor/bin/pdodb cache invalidate "table:users_*" --force
1004+
1005+
✓ Invalidated 50 cache entries matching pattern 'table:users_*'
1006+
```
1007+
1008+
**Note**: Table prefix patterns (`*` wildcards) work only with Redis and Memcached cache backends that support key pattern matching.
1009+
9721010
#### Clear Cache
9731011

9741012
```bash
@@ -986,8 +1024,34 @@ $ vendor/bin/pdodb cache clear --force
9861024
✓ Cache cleared successfully
9871025
```
9881026

1027+
### Invalidation Patterns
1028+
1029+
The `cache invalidate` command supports several pattern formats:
1030+
1031+
1. **Table Name** - `users` - Invalidates all cache entries for the `users` table
1032+
2. **Table Prefix** - `table:users` - Same as table name (explicit form)
1033+
3. **Table Prefix with Wildcard** - `table:users_*` - Invalidates all cache entries for tables starting with `users_` (requires Redis/Memcached)
1034+
4. **Key Pattern** - `pdodb_table_users_*` - Invalidates by cache key pattern (requires Redis/Memcached)
1035+
1036+
**Examples:**
1037+
1038+
```bash
1039+
# Invalidate all entries for 'users' table
1040+
vendor/bin/pdodb cache invalidate users --force
1041+
1042+
# Invalidate all entries for 'users' table (explicit form)
1043+
vendor/bin/pdodb cache invalidate "table:users" --force
1044+
1045+
# Invalidate all entries for tables starting with 'users_' (Redis/Memcached only)
1046+
vendor/bin/pdodb cache invalidate "table:users_*" --force
1047+
1048+
# Invalidate by key pattern (Redis/Memcached only)
1049+
vendor/bin/pdodb cache invalidate "pdodb_table_users_*" --force
1050+
```
1051+
9891052
### Statistics Explained
9901053

1054+
- **Type** - Cache backend type (Redis, Memcached, APCu, Filesystem, Array, Unknown)
9911055
- **Hits** - Number of successful cache retrievals (query result found in cache)
9921056
- **Misses** - Number of cache lookups that didn't find a result (query executed)
9931057
- **Hit Rate** - Percentage of successful cache hits: `(hits / (hits + misses)) * 100`
@@ -998,17 +1062,20 @@ $ vendor/bin/pdodb cache clear --force
9981062
### Notes
9991063

10001064
- **Cache Must Be Enabled**: Cache commands require cache to be enabled in your configuration. If cache is disabled, the command will show an error.
1001-
- **Statistics Are In-Memory**: Cache statistics are runtime counters that reset when the application restarts. Use this for monitoring cache effectiveness during development and testing.
1065+
- **Persistent Statistics**: Cache statistics are stored in the cache backend itself, so they persist across requests. Statistics include both in-memory counters (current request) and persistent counters (accumulated across all requests).
10021066
- **Universal Support**: Cache statistics work with any PSR-16 cache adapter (Filesystem, Redis, APCu, Memcached, Array).
1003-
- **Clear Removes All Cache**: The `cache clear` command removes ALL cached query results. This cannot be undone.
1067+
- **Pattern Matching**: Key pattern matching (wildcards) works only with Redis and Memcached. For other cache types, only exact table name matching is supported.
1068+
- **Clear Removes All Cache**: The `cache clear` command removes ALL cached query results and statistics. This cannot be undone.
1069+
- **Invalidate Removes Matching Entries**: The `cache invalidate` command removes only cache entries matching the specified pattern. Statistics are updated accordingly.
10041070
- **Statistics Tracking**: Statistics are tracked automatically when using `$db->find()->cache()` methods. Manual cache operations via `$db->cacheManager` also update statistics.
10051071

10061072
### When to Use
10071073

10081074
- **Development**: Monitor cache hit rates to optimize cache TTL settings
10091075
- **Debugging**: Check cache statistics when investigating performance issues
10101076
- **Deployment**: Clear cache after schema changes or data migrations
1011-
- **Maintenance**: Periodic cache clearing to ensure fresh data after updates
1077+
- **Maintenance**: Invalidate specific table caches after data updates without clearing all cache
1078+
- **Performance**: Use selective invalidation to maintain cache for unchanged tables while refreshing updated tables
10121079

10131080
## Installation
10141081

@@ -1037,7 +1104,7 @@ vendor/bin/pdodb <command> [subcommand] [arguments] [options]
10371104
- **`model`** - Generate ActiveRecord models
10381105
- **`table`** - Manage tables (info, list, exists, create, drop, rename, truncate, describe, columns, indexes, foreign keys)
10391106
- **`monitor`** - Monitor database queries, connections, and performance
1040-
- **`cache`** - Manage query result cache (clear, statistics)
1107+
- **`cache`** - Manage query result cache (clear, invalidate, statistics)
10411108

10421109
### Getting Help
10431110

examples/11-schema/06-cache-management.php

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Cache Management Examples.
77
*
88
* This example demonstrates how to use the pdodb cache command
9-
* to manage query result cache (clear, statistics).
9+
* to manage query result cache (clear, invalidate, statistics).
1010
*
1111
* Usage:
1212
* php examples/11-schema/06-cache-management.php
@@ -148,17 +148,34 @@
148148
->get();
149149
echo " Found " . count($result6) . " records (cache hit)\n\n";
150150

151-
echo "6. Final Cache Statistics (from CLI):\n";
151+
echo "6. Invalidate Cache by Table Pattern:\n";
152+
echo " Command: pdodb cache invalidate cache_test --force\n";
153+
echo " Output:\n";
154+
ob_start();
155+
$app->run(['pdodb', 'cache', 'invalidate', 'cache_test', '--force']);
156+
$output = ob_get_clean();
157+
echo $output . "\n";
158+
159+
echo "7. Invalidate Cache by Table Pattern (table: prefix):\n";
160+
echo " Command: pdodb cache invalidate \"table:cache_test\" --force\n";
161+
// First generate some cache again
162+
$db->find()->from('cache_test')->cache(3600)->get();
163+
ob_start();
164+
$app->run(['pdodb', 'cache', 'invalidate', 'table:cache_test', '--force']);
165+
$output = ob_get_clean();
166+
echo $output . "\n";
167+
168+
echo "8. Final Cache Statistics (from CLI):\n";
152169
echo " Note: CLI commands create a separate CacheManager instance,\n";
153170
echo " so statistics may differ from the application's CacheManager.\n";
154-
echo " Command: pdodb cache stats --format=json\n";
171+
echo " Command: pdodb cache stats\n";
155172
echo " Output:\n";
156173
ob_start();
157-
$app->run(['pdodb', 'cache', 'stats', '--format=json']);
174+
$app->run(['pdodb', 'cache', 'stats']);
158175
$output = ob_get_clean();
159176
echo $output . "\n";
160177

161-
echo "\n7. Direct Cache Statistics (from application's CacheManager):\n";
178+
echo "\n9. Direct Cache Statistics (from application's CacheManager):\n";
162179
$cacheManager = $db->getCacheManager();
163180
if ($cacheManager !== null) {
164181
$stats = $cacheManager->getStats();
@@ -171,9 +188,12 @@
171188
echo "\nAdditional Notes:\n";
172189
echo "- Cache statistics track hits, misses, sets, and deletes\n";
173190
echo "- Hit rate is calculated as: (hits / (hits + misses)) * 100\n";
174-
echo "- Statistics are in-memory counters that reset on application restart\n";
175-
echo "- Use --force flag to skip confirmation when clearing cache\n";
191+
echo "- Statistics are persistent across requests (stored in cache backend)\n";
192+
echo "- Cache type (Redis, Memcached, APCu, Filesystem, Array) is shown in statistics\n";
193+
echo "- Use --force flag to skip confirmation when clearing/invalidating cache\n";
176194
echo "- Cache clear removes ALL cached query results\n";
195+
echo "- Cache invalidate removes entries matching a pattern (table name, table prefix, or key pattern)\n";
196+
echo "- Supported patterns: 'table:users', 'table:users_*', 'pdodb_table_users_*', 'users'\n";
177197
echo "- Cache statistics help monitor cache effectiveness\n";
178198

179199
// Cleanup

scripts/pdodb-completion.bash

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,14 +213,22 @@ _pdodb() {
213213

214214
# Cache command
215215
if [[ "${cmd}" == "cache" ]]; then
216-
local cache_subcommands="clear stats"
216+
local cache_subcommands="clear invalidate stats"
217217

218218
if [[ ${COMP_CWORD} -eq 2 ]]; then
219219
COMPREPLY=($(compgen -W "${cache_subcommands} --help" -- "${cur}"))
220220
else
221221
if [[ "${subcmd}" == "clear" ]]; then
222222
local cache_opts="--force"
223223
COMPREPLY=($(compgen -W "${cache_opts}" -- "${cur}"))
224+
elif [[ "${subcmd}" == "invalidate" ]]; then
225+
if [[ ${COMP_CWORD} -eq 3 ]]; then
226+
# Pattern argument - no completions for now
227+
COMPREPLY=()
228+
else
229+
local cache_opts="--force"
230+
COMPREPLY=($(compgen -W "${cache_opts}" -- "${cur}"))
231+
fi
224232
elif [[ "${subcmd}" == "stats" ]]; then
225233
local cache_opts="--format=table --format=json --format"
226234
COMPREPLY=($(compgen -W "${cache_opts}" -- "${cur}"))

0 commit comments

Comments
 (0)