diff --git a/src/Query/Builder.php b/src/Query/Builder.php index 2270466..f446853 100644 --- a/src/Query/Builder.php +++ b/src/Query/Builder.php @@ -33,4 +33,22 @@ public function useWritePdo() return $this; } + + /** + * Add a subselect expression to the query. + * + * @param \Closure|$this|string $query + * @param string $as + * @return $this + * + * @throws \InvalidArgumentException + */ + public function selectSub($query, $as) + { + if (get_class($query) == self::class) { + $this->appendCacheTags($query->getCacheTags() ?? []); + } + + return parent::selectSub($query, $as); + } } diff --git a/src/Traits/QueryCacheModule.php b/src/Traits/QueryCacheModule.php index 738e8f2..53c58c0 100644 --- a/src/Traits/QueryCacheModule.php +++ b/src/Traits/QueryCacheModule.php @@ -272,6 +272,19 @@ public function cacheTags(array $cacheTags = []) return $this; } + /** + * Append tags to the cache. + * + * @param array $cacheTags + * @return \Rennokki\QueryCache\Query\Builder + */ + public function appendCacheTags(array $cacheTags = []) + { + $this->cacheTags = array_unique(array_merge($this->cacheTags ?? [], $cacheTags)); + + return $this; + } + /** * Use a specific cache driver. * diff --git a/tests/MethodsTest.php b/tests/MethodsTest.php index 75ee440..1bd6cea 100644 --- a/tests/MethodsTest.php +++ b/tests/MethodsTest.php @@ -6,6 +6,7 @@ use Rennokki\QueryCache\Test\Models\Book; use Rennokki\QueryCache\Test\Models\Kid; use Rennokki\QueryCache\Test\Models\Post; +use Rennokki\QueryCache\Test\Models\User; class MethodsTest extends TestCase { @@ -123,4 +124,50 @@ public function test_hashed_key() $this->assertNotNull($cache); } + + public function test_append_cache_tags() + { + $post = factory(Post::class)->create(); + $storedPost = Post::cacheFor(now()->addHours(1))->appendCacheTags(['test'])->first(); + + $cache = $this->getCacheWithTags('leqc:sqlitegetselect * from "posts" limit 1a:0:{}'); + + // The caches that do not support tagging should + // cache the query either way. + $this->driverSupportsTags() + ? $this->assertNull($cache) + : $this->assertNotNull($cache); + + $cache = $this->getCacheWithTags('leqc:sqlitegetselect * from "posts" limit 1a:0:{}', ['test']); + $this->assertNotNull($cache); + } + + public function test_multiple_append_cache_tags() + { + $post = factory(Post::class)->create(); + $storedPostQuery = Post::cacheFor(now()->addHours(1))->appendCacheTags(['test'])->appendCacheTags(['test2']); + + $this->assertEquals($storedPostQuery->getQuery()->getCacheTags(), ['test', 'test2']); + } + + public function test_append_cache_tags_with_sub_query() + { + $user = factory(User::class)->create(); + factory(Post::class)->createMany([ + ['user_id' => $user->id, 'name' => 'Post 1 on topic 1'], + ['user_id' => $user->id, 'name' => 'Post 2 on topic 1'], + ['user_id' => $user->id, 'name' => 'Post 3 on topic 2'], + ]); + + $userAndPosts = User::cacheFor(now()->addHours(1)) + ->withCount([ + 'posts' => function ($query) { + $query->appendCacheTags(['posts']) + ->where('name', 'like', '%topic 1%'); + }, + ]) + ->appendCacheTags(['user']); + + $this->assertEquals($userAndPosts->getQuery()->getCacheTags(), ['posts', 'user']); + } } diff --git a/tests/Models/User.php b/tests/Models/User.php index dac6955..935252f 100644 --- a/tests/Models/User.php +++ b/tests/Models/User.php @@ -3,9 +3,12 @@ namespace Rennokki\QueryCache\Test\Models; use Illuminate\Foundation\Auth\User as Authenticatable; +use Rennokki\QueryCache\Traits\QueryCacheable; class User extends Authenticatable { + use QueryCacheable; + protected $fillable = [ 'name', 'email', 'password', ]; @@ -20,4 +23,9 @@ protected function getCacheBaseTags(): array // ]; } + + public function posts() + { + return $this->hasMany(Post::class); + } } diff --git a/tests/database/migrations/2018_07_14_183253_posts.php b/tests/database/migrations/2018_07_14_183253_posts.php index ddcb62d..85fb75c 100644 --- a/tests/database/migrations/2018_07_14_183253_posts.php +++ b/tests/database/migrations/2018_07_14_183253_posts.php @@ -15,6 +15,7 @@ public function up() { Schema::create('posts', function (Blueprint $table) { $table->increments('id'); + $table->unsignedBigInteger('user_id')->nullable(); $table->string('name'); $table->timestamps(); });