Skip to content

Commit 3e6ae1a

Browse files
authored
Merge pull request #8 from rennokki/feature/modularized-cache-method
[feature] Modularized cache method
2 parents 5ec03cb + 3daf6a9 commit 3e6ae1a

File tree

4 files changed

+491
-298
lines changed

4 files changed

+491
-298
lines changed

README.md

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,115 @@ class Book extends Model
141141
public $cacheDriver = 'dynamodb'; // equivalent of ->cacheDriver('dynamodb');
142142
}
143143
```
144+
145+
## Implement the caching method to your own Builder class
146+
Since this package modifies the `newBaseQueryBuilder()` in the model, having multiple traits that
147+
modify this function will lead to an overlap.
148+
149+
This can happen in case you are creating your own Builder class for another database drivers or simply to ease out your app query builder for more flexibility.
150+
151+
To solve this, all you have to do is to add the `\Rennokki\QueryCache\Traits\QueryCacheModule` trait and the `\Rennokki\QueryCache\Contracts\QueryCacheModuleInterface` interface to your `Builder` class. Make sure that the model will no longer use the original `QueryCacheable` trait.
152+
153+
```php
154+
use Rennokki\QueryCache\Traits\QueryCacheModule;
155+
use Illuminate\Database\Query\Builder as BaseBuilder; // the base laravel builder
156+
use Rennokki\QueryCache\Contract\QueryCacheModuleInterface;
157+
158+
// MyCustomBuilder.php
159+
class MyCustomBuilder implements QueryCacheModuleInterface
160+
{
161+
use QueryCacheModule;
162+
163+
// the rest of the logic here.
164+
}
165+
166+
// MyBuilderTrait.php
167+
trait MyBuilderTrait
168+
{
169+
protected function newBaseQueryBuilder()
170+
{
171+
return new MyCustomBuilder(
172+
//
173+
);
174+
}
175+
}
176+
177+
// app/CustomModel.php
178+
class CustomModel extends Model
179+
{
180+
use MyBuilderTrait;
181+
}
182+
183+
CustomModel::cacheFor(30)->customGetMethod();
184+
```
185+
186+
## Generating your own key
187+
This is how the default key generation function looks like:
188+
```php
189+
public function generatePlainCacheKey(string $method = 'get', $id = null, $appends = null): string
190+
{
191+
$name = $this->connection->getName();
192+
193+
// Count has no Sql, that's why it can't be used ->toSql()
194+
if ($method === 'count') {
195+
return $name.$method.$id.serialize($this->getBindings()).$appends;
196+
}
197+
198+
return $name.$method.$id.$this->toSql().serialize($this->getBindings()).$appends;
199+
}
200+
```
201+
202+
In some cases, like implementing your own Builder for MongoDB for example, you might not want to use the `toSql()` and use your own
203+
method of generating per-sql key. You can do so by overwriting the `MyCustomBuilder` class `generatePlainCacheKey()` with your own one.
204+
205+
It is, however, highly recommended to use the most of the variables provided by the function to avoid cache overlapping issues.
206+
207+
```php
208+
class MyCustomBuilder implements QueryCacheModuleInterface
209+
{
210+
use QueryCacheModule;
211+
212+
public function generatePlainCacheKey(string $method = 'get', $id = null, $appends = null): string
213+
{
214+
$name = $this->connection->getName();
215+
216+
// Using ->myCustomSqlString() instead of ->toSql()
217+
return $name.$method.$id.$this->myCustomSqlString().serialize($this->getBindings()).$appends;
218+
}
219+
}
220+
```
221+
222+
## Implementing cache for other functions than get()
223+
Since all of the Laravel Eloquent functions are based on it, the builder that comes with this package replaces only the `get()` one:
224+
```php
225+
class Builder
226+
{
227+
public function get($columns = ['*'])
228+
{
229+
if (! $this->shouldAvoidCache()) {
230+
return $this->getFromQueryCache('get', $columns);
231+
}
232+
233+
return parent::get($columns);
234+
}
235+
}
236+
```
237+
238+
In case that you want to cache your own methods from your custom builder or, for instance, your `count()` method doesn't rely on `get()`, you can replace it using this syntax:
239+
```php
240+
class MyCustomBuilder
241+
{
242+
public function count()
243+
{
244+
if (! $this->shouldAvoidCache()) {
245+
return $this->getFromQueryCache('count');
246+
}
247+
248+
return parent::count();
249+
}
250+
}
251+
```
252+
253+
In fact, you can also replace any eloquent method within your builder if you use `$this->shouldAvoidCache()` check and retrieve the cached data using `getFromQueryCache()` method, passing the method name as string, and, optionally, an array of columns that defaults to `['*']`.
254+
255+
Notice that the `getFromQueryCache()` method accepts a method name and a `$columns` parameter. If your method doesn't implement the `$columns`, don't pass it.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace Rennokki\QueryCache\Contracts;
4+
5+
interface QueryCacheModuleInterface
6+
{
7+
/**
8+
* Generate the plain unique cache key for the query.
9+
*
10+
* @param string $method
11+
* @param string|null $id
12+
* @param string|null $appends
13+
* @return string
14+
*/
15+
public function generatePlainCacheKey(string $method = 'get', $id = null, $appends = null): string;
16+
}

0 commit comments

Comments
 (0)