Skip to content

Commit 61e59fb

Browse files
authored
Merge pull request #19 from rennokki/feature/clear-cache-for-model
[feature] Full cache purging for all resources
2 parents 1895fc6 + 0941df3 commit 61e59fb

File tree

11 files changed

+193
-2
lines changed

11 files changed

+193
-2
lines changed

README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,37 @@ $alice = Kid::whereName('Alice')->cacheFor(60)->cacheTags(['kids'])->first();
9090
$bob = Kid::whereName('Bob')->cacheFor(60)->cacheTags(['kids'])->first();
9191
```
9292

93+
### Global Cache Invalidation
94+
95+
To invalidate all the cache for a specific model, use the `flushQueryCache` method without passing the tags.
96+
97+
The package automatically appends a list of tags, called **base tags** on each query coming from a model. It defaults to the full model class name.
98+
99+
In case you want to change the base tags, you can do so in your model.
100+
101+
```php
102+
class Kid extends Model
103+
{
104+
use QueryCacheable;
105+
106+
/**
107+
* Set the base cache tags that will be present
108+
* on all queries.
109+
*
110+
* @return array
111+
*/
112+
protected function getCacheBaseTags(): array
113+
{
114+
return [
115+
'custom_tag',
116+
];
117+
}
118+
}
119+
120+
// Automatically works with `custom_tag`
121+
Kid::flushQueryCache();
122+
```
123+
93124
## Relationship Caching
94125
Relationships are just another queries. They can be intercepted and modified before the database is hit with the query. The following example needs the `Order` model (or the model associated with the `orders` relationship) to include the `QueryCacheable` trait.
95126

database/factories/BookFactory.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
/*
3+
|--------------------------------------------------------------------------
4+
| Model Factories
5+
|--------------------------------------------------------------------------
6+
|
7+
| This directory should contain each of the model factory definitions for
8+
| your application. Factories provide a convenient way to generate new
9+
| model instances for testing / seeding your application's database.
10+
|
11+
*/
12+
13+
use Illuminate\Support\Str;
14+
15+
$factory->define(\Rennokki\QueryCache\Test\Models\Book::class, function () {
16+
return [
17+
'name' => 'Book'.Str::random(5),
18+
];
19+
});

src/Traits/QueryCacheModule.php

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ trait QueryCacheModule
2222
*/
2323
protected $cacheTags = null;
2424

25+
/**
26+
* The tags for the query cache that
27+
* will be present on all queries.
28+
*
29+
* @var null|array
30+
*/
31+
protected $cacheBaseTags = null;
32+
2533
/**
2634
* The cache driver to be used.
2735
*
@@ -163,6 +171,10 @@ public function flushQueryCache(array $tags = []): bool
163171
return false;
164172
}
165173

174+
if (! $tags) {
175+
$tags = $this->getCacheBaseTags();
176+
}
177+
166178
foreach ($tags as $tag) {
167179
self::flushQueryCacheWithTag($tag);
168180
}
@@ -272,6 +284,20 @@ public function cacheDriver(string $cacheDriver)
272284
return $this;
273285
}
274286

287+
/**
288+
* Set the base cache tags; the tags
289+
* that will be present on all cached queries.
290+
*
291+
* @param array $tags
292+
* @return \Rennokki\QueryCache\Query\Builder
293+
*/
294+
public function cacheBaseTags(array $tags = [])
295+
{
296+
$this->cacheBaseTags = $tags;
297+
298+
return $this;
299+
}
300+
275301
/**
276302
* Use a plain key instead of a hashed one in the cache driver.
277303
*
@@ -302,7 +328,11 @@ public function getCacheDriver()
302328
public function getCache()
303329
{
304330
$cache = $this->getCacheDriver();
305-
$tags = $this->getCacheTags();
331+
332+
$tags = array_merge(
333+
$this->getCacheTags() ?: [],
334+
$this->getCacheBaseTags() ?: []
335+
);
306336

307337
return $tags ? $cache->tags($tags) : $cache;
308338
}
@@ -348,6 +378,16 @@ public function getCacheTags()
348378
return $this->cacheTags;
349379
}
350380

381+
/**
382+
* Get the base cache tags attribute.
383+
*
384+
* @return array|null
385+
*/
386+
public function getCacheBaseTags()
387+
{
388+
return $this->cacheBaseTags;
389+
}
390+
351391
/**
352392
* Get the cache prefix attribute.
353393
*

src/Traits/QueryCacheable.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,20 @@ protected function newBaseQueryBuilder()
4141
$builder->withPlainKey();
4242
}
4343

44-
return $builder;
44+
return $builder
45+
->cacheBaseTags($this->getCacheBaseTags());
46+
}
47+
48+
/**
49+
* Set the base cache tags that will be present
50+
* on all queries.
51+
*
52+
* @return array
53+
*/
54+
protected function getCacheBaseTags(): array
55+
{
56+
return [
57+
(string) self::class,
58+
];
4559
}
4660
}

tests/MethodsTest.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Rennokki\QueryCache\Test;
44

55
use Cache;
6+
use Rennokki\QueryCache\Test\Models\Book;
67
use Rennokki\QueryCache\Test\Models\Kid;
78
use Rennokki\QueryCache\Test\Models\Post;
89

@@ -89,6 +90,21 @@ public function test_cache_flush_with_more_tags()
8990
$this->assertNull($cache);
9091
}
9192

93+
public function test_cache_flush_with_default_tags_attached()
94+
{
95+
$book = factory(Book::class)->create();
96+
$storedBook = Book::cacheFor(now()->addHours(1))->cacheTags(['test'])->first();
97+
98+
$cache = Cache::tags(['test', Book::getCacheBaseTags()[0]])->get('leqc:sqlitegetselect * from "books" limit 1a:0:{}');
99+
$this->assertNotNull($cache);
100+
101+
Book::flushQueryCache();
102+
103+
$cache = Cache::tags(['test', Book::getCacheBaseTags()[0]])->get('leqc:sqlitegetselect * from "books" limit 1a:0:{}');
104+
105+
$this->assertNull($cache);
106+
}
107+
92108
public function test_hashed_key()
93109
{
94110
$kid = factory(Kid::class)->create();

tests/Models/Book.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace Rennokki\QueryCache\Test\Models;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
use Rennokki\QueryCache\Traits\QueryCacheable;
7+
8+
class Book extends Model
9+
{
10+
use QueryCacheable;
11+
12+
protected $cacheUsePlainKey = true;
13+
14+
protected $fillable = [
15+
'name',
16+
];
17+
}

tests/Models/Kid.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,11 @@ class Kid extends Model
1212
protected $fillable = [
1313
'name',
1414
];
15+
16+
protected function getCacheBaseTags(): array
17+
{
18+
return [
19+
//
20+
];
21+
}
1522
}

tests/Models/Post.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,11 @@ class Post extends Model
1414
protected $fillable = [
1515
'name',
1616
];
17+
18+
protected function getCacheBaseTags(): array
19+
{
20+
return [
21+
//
22+
];
23+
}
1724
}

tests/Models/User.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,11 @@ class User extends Authenticatable
1313
protected $hidden = [
1414
'password', 'remember_token',
1515
];
16+
17+
protected function getCacheBaseTags(): array
18+
{
19+
return [
20+
//
21+
];
22+
}
1623
}

tests/TestCase.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ public function getEnvironmentSetUp($app)
5656
$app['config']->set('auth.providers.users.model', User::class);
5757
$app['config']->set('auth.providers.posts.model', Post::class);
5858
$app['config']->set('auth.providers.kids.model', Kid::class);
59+
$app['config']->set('auth.providers.books.model', Book::class);
5960
$app['config']->set('app.key', 'wslxrEFGWY6GfGhvN9L3wH3KSRJQQpBD');
6061
}
6162

0 commit comments

Comments
 (0)