Skip to content

Commit 7de94a8

Browse files
committed
Initial commit
0 parents  commit 7de94a8

23 files changed

+1011
-0
lines changed

.codecov.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
codecov:
2+
notify:
3+
require_ci_to_pass: yes
4+
5+
coverage:
6+
precision: 2
7+
round: down
8+
range: "70...100"
9+
10+
status:
11+
project: yes
12+
patch: yes
13+
changes: no
14+
15+
comment:
16+
layout: "reach, diff, flags, files, footer"
17+
behavior: default
18+
require_changes: no

.editorconfig

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
end_of_line = lf
6+
insert_final_newline = true
7+
indent_style = space
8+
indent_size = 4
9+
trim_trailing_whitespace = true
10+
11+
[*.{yml,yaml}]
12+
indent_size = 2
13+
14+
[*.md]
15+
trim_trailing_whitespace = false

.gitattributes

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/tests export-ignore
2+
.editorconfig export-ignore
3+
.gitattributes export-ignore
4+
.gitignore export-ignore
5+
phpunit.xml export-ignore

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/vendor
2+
composer.phar
3+
composer.lock
4+
.DS_Store

.styleci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
preset: laravel

.travis.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
language: php
2+
3+
php:
4+
- 7.2
5+
- 7.3
6+
7+
env:
8+
matrix:
9+
- COMPOSER_FLAGS=""
10+
11+
before_script:
12+
- travis_retry composer self-update
13+
- travis_retry composer update ${COMPOSER_FLAGS} --no-interaction --prefer-source
14+
15+
script:
16+
- phpunit --coverage-text --coverage-clover=coverage.xml
17+
18+
after_success:
19+
- bash <(curl -s https://codecov.io/bash)

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2018 rennokki
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
Laravel Eloquent Query Cache
2+
===================================
3+
4+
Laravel Eloquent Query Cache (LEQC; Le QC; Le Query Cache) is a package that brings the `remember()` functionality that has been removed from Laravel a long time ago.
5+
This package helps adding caching functionalities directly on the Eloquent level, making use of cache before retrieving the data from the DB.
6+
7+
This package adds caching support for **all** query methods.
8+
9+
## Installing the package
10+
Hop into your console and install the package via Composer:
11+
12+
```bash
13+
$ composer require rennokki/rennokki/laravel-eloquent-query-cache
14+
```
15+
16+
Each model that will accept query-by-query caching will have to use the `Rennokki\QueryCache\Traits\QueryCacheable` trait.
17+
18+
```php
19+
use Rennokki\QueryCache\Traits\QueryCacheable;
20+
21+
class Podcast extends Model
22+
{
23+
use QueryCacheable;
24+
25+
...
26+
}
27+
```
28+
29+
## Showcase
30+
Query Cache has the ability to track the SQL used and use it as a key in the cache storage, making the caching query-by-query a breeze.
31+
32+
```php
33+
use Rennokki\QueryCache\Traits\QueryCacheable;
34+
35+
class Article extends Model
36+
{
37+
use QueryCacheable;
38+
39+
$cacheFor = 3600; // cache time, in seconds
40+
...
41+
}
42+
43+
// SELECT * FROM articles ORDER BY created_at DESC LIMIT 1;
44+
$latestArticle = Article::latest()->first();
45+
46+
// SELECT * FROM articles WHERE published = 1;
47+
$publishedArticles = Article::wherePublished(true)->get();
48+
```
49+
50+
In the above example, both queries have different keys in the cache storage, thus it doesn't matter what query we handle. By default, caching is disabled unless specifying a value for `$cacheFor`. As long as `$cacheFor` is existent and is greater than `0`, all queries will be cached.
51+
52+
It is also possible to enable caching for specific queries. This is the recommended way because it is easier to manage each query.
53+
54+
```php
55+
$postsCount = Post::cacheFor(60 * 60)->count();
56+
57+
// Using a DateTime instance like Carbon works perfectly fine!
58+
$postsCount = Post::cacheFor(now()->addDays(1))->count();
59+
```
60+
61+
## Cache Tags & Cache Invalidation
62+
Some caching stores accept tags. This is really useful if you plan on tagging your cached queries and invalidate only some of the queries when needed.
63+
64+
```php
65+
$shelfOneBooks = Book::whereShelf(1)->cacheFor(60)->cacheTags(['shelf:1'])->get();
66+
$shelfTwoBooks = Book::whereShelf(2)->cacheFor(60)->cacheTags(['shelf:2'])->get();
67+
68+
// After flushing the cache for shelf:1, the query of$shelfTwoBooks will still hit the cache if re-called again.
69+
Book::flushQueryCache(['shelf:1']);
70+
```
71+
72+
Be careful tho - specifying cache tags does not change the behaviour of key storage.
73+
For example, the following two queries, altough the use the same tag, they have different keys stored in the caching database.
74+
75+
```php
76+
$alice = Kid::whereName('Alice')->cacheFor(60)->cacheTags(['kids'])->first();
77+
$bob = Kid::whereName('Bob')->cacheFor(60)->cacheTags(['kids'])->first();
78+
```
79+
80+
In case you want to invalidate all the cache, don't specify an argument for the `flushQueryCache()` method:
81+
82+
```php
83+
Problem::flushQueryCache(); // bye-bye problems!
84+
```
85+
86+
## Relationship Caching
87+
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.
88+
89+
```php
90+
$user = User::with(['orders' => function ($query) {
91+
return $query->cacheFor(60 * 60)->cacheTags(['my:orders']);
92+
}])->get();
93+
94+
// This comes from the cache if existed.
95+
$orders = $user->orders;
96+
```
97+
98+
## Cache Keys
99+
The package automatically generate the keys needed to store the data in the cache store. However, prefixing them might be useful if the cache store is used by other applications and/or models and you want to manage the keys better to avoid collisions.
100+
101+
```php
102+
$bob = Kid::whereName('Bob')->cacheFor(60)->prefix('kids_')->first();
103+
```
104+
105+
If no prefix is specified, the string `leqc` is going to be used.
106+
107+
## Cache Drivers
108+
By default, the trait uses the default cache driver. If you want to **force** a specific one, you can do so by calling `cacheDriver()`:
109+
110+
```php
111+
$bob = Kid::whereName('Bob')->cacheFor(60)->cacheDriver('dynamodb')->first();
112+
```
113+
114+
## Disable caching
115+
If you enabled caching (either by model variable or by the `cacheFor` scope), you can also opt to disable it mid-builder.
116+
```php
117+
$uncachedBooks = Book::dontCache()->get();
118+
$uncachedBooks = Book::doNotCache()->get(); // same thing
119+
```
120+
121+
## Equivalent Methods and Variables
122+
You can use the methods provided in this documentation query-by-query, or you can set defaults for each one in the model; using the methods query-by-query will overwrite the defaults.
123+
While settings defaults is not mandatory (excepting for `$cacheFor` that will enable caching on **all** queries), it can be useful to avoid using the chained methods on each query.
124+
125+
```php
126+
class Book extends Model
127+
{
128+
public $cacheFor = 3600; // equivalent of ->cacheFor(3600)
129+
130+
public $cacheTags = ['books']; // equivalent of ->cacheTags(['books'])
131+
132+
public $cachePrefix = 'books_' // equivalent of ->cachePrefix('books_');
133+
134+
public $cacheDriver = 'dynamodb'; // equivalent of ->cacheDriver('dynamodb');
135+
}
136+
```

composer.json

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"name": "rennokki/laravel-eloquent-query-cache",
3+
"description": "Adding cache for Laravel Eloquent queries' results is now a breeze.",
4+
"keywords": ["laravel", "caching", "eloquent", "remember", "query", "sql"],
5+
"license": "MIT",
6+
"homepage": "https://github.com/rennokki/laravel-eloquent-query-cache",
7+
"authors": [
8+
{
9+
"name": "Alex Renoki",
10+
"email": "rennokki@gmail.com",
11+
"homepage": "https://twitter.com/rennokki",
12+
"role": "Developer"
13+
}
14+
],
15+
"require": {
16+
"php": ">=5.4.0",
17+
"illuminate/database": "^6.0",
18+
"illuminate/support": "^6.0"
19+
},
20+
"autoload": {
21+
"psr-4": {
22+
"Rennokki\\QueryCache\\": "src/"
23+
}
24+
},
25+
"autoload-dev": {
26+
"psr-4": {
27+
"Rennokki\\QueryCache\\Test\\": "tests"
28+
}
29+
},
30+
"scripts": {
31+
"test": "vendor/bin/phpunit"
32+
},
33+
"require-dev": {
34+
"phpunit/phpunit": "^6.2|^7.0|^8.0",
35+
"orchestra/testbench": "~3.5.0|~3.6.0|~4.0.0",
36+
"orchestra/database": "~3.5.0|~3.6.0|~4.0.0"
37+
},
38+
"config": {
39+
"sort-packages": true
40+
},
41+
"minimum-stability": "dev"
42+
}

database/factories/PostFactory.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\Post::class, function () {
16+
return [
17+
'name' => 'Post'.Str::random(5),
18+
];
19+
});

0 commit comments

Comments
 (0)