Skip to content
This repository has been archived by the owner on Feb 17, 2022. It is now read-only.

Commit

Permalink
Merge pull request #2 from DarkGhostHunter/master
Browse files Browse the repository at this point in the history
Added Laravel 7 support.
  • Loading branch information
DarkGhostHunter committed Mar 5, 2020
2 parents c4efcaa + e9de98c commit dd8e3fc
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 65 deletions.
86 changes: 50 additions & 36 deletions .github/workflows/php.yml
Original file line number Diff line number Diff line change
@@ -1,44 +1,58 @@
name: PHP Composer

on: [push]
on:
push:
pull_request:

jobs:
build:
test:

runs-on: ubuntu-latest
strategy:
fail-fast: true
matrix:
php: [7.4, 7.3, 7.2.15]
laravel: [7.*, 6.*]
dependency-version: [prefer-lowest, prefer-stable]
include:
- laravel: 7.*
testbench: 5.*
- laravel: 6.*
testbench: 4.*

name: PHP ${{ matrix.php }} - Laravel ${{ matrix.laravel }} - ${{ matrix.dependency-version }}

steps:
- name: Checkout
uses: actions/checkout@v1

- name: Setup PHP
uses: shivammathur/setup-php@v1
with:
php-version: '7.2'
extension-csv: mbstring, intl
coverage: xdebug

- name: Install dependencies
run: composer install --prefer-dist --no-progress --no-suggest

- name: Get Composer Cache Directory
id: composer-cache
run: echo "::set-output name=dir::$(composer config cache-files-dir)"

- name: Cache dependencies
uses: actions/cache@v1
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-

- name: Run test suite
run: composer run-script test

- name: Upload coverage results to Coveralls
env:
COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
COVERALLS_SERVICE_NAME: github
run: |
composer require cedx/coveralls
vendor/bin/coveralls build/logs/clover.xml
- name: Checkout
uses: actions/checkout@v1

- name: Setup PHP
uses: shivammathur/setup-php@v1
with:
php-version: ${{ matrix.php }}
extensions: mbstring, intl
coverage: xdebug

- name: Cache dependencies
uses: actions/cache@v1
with:
path: ~/.composer/cache/files
key: ${{ runner.os }}-laravel-${{ matrix.laravel }}-php-${{ matrix.php }}-composer-${{ hashFiles('composer.json') }}
restore-keys: ${{ runner.os }}-laravel-${{ matrix.laravel }}-php-${{ matrix.php }}-composer-

- name: Install dependencies
run: |
composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" --no-progress --no-update
composer update --${{ matrix.dependency-version }} --prefer-dist --no-progress --no-suggest
- name: Run Tests
run: composer run-script test

- name: Upload Coverage to Coveralls
env:
COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
COVERALLS_SERVICE_NAME: github
run: |
rm -rf composer.* vendor/
composer require cedx/coveralls
vendor/bin/coveralls build/logs/clover.xml
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ build
composer.lock
docs
vendor
coverage
coverage
/.phpunit.result.cache
1 change: 0 additions & 1 deletion .phpunit.result.cache

This file was deleted.

46 changes: 37 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ Remember your Query results using only one method. Yes, only one.

## Requirements

* PHP 7.2 or latest
* Laravel 5.8|6.0
* A functioning brain
* PHP 7.2.15 or latest
* Laravel 6 or Laravel 7.
* A working brain

## Installation

Expand All @@ -33,26 +33,26 @@ Just use the `remember()` method to remember a Query result. That's it.
use Illuminate\Support\Facades\DB;
use Illuminate\Foundation\Auth\User;

$userA = DB::table('users')->remember()->where('name', 'Joe')->first();
$query = DB::table('users')->remember()->where('name', 'Joe')->first();

$userB = User::where('name', 'Joe')->remember()->first();
$eloquent = User::where('name', 'Joe')->remember()->first();
```

The next time you call the **same** query, the result will be retrieved from the cache instead of connecting to Database.
The next time you call the **same** query, the result will be retrieved from the cache instead of running the SQL statement in the database.

> If the result is `null` or `false`, it won't be remembered, which mimics the Cache behaviour on these values.
### Time-to-live

By default, queries are remembered by 60 seconds, but you're free to use any length, or Datetime or Carbon instance.
By default, queries are remembered by 60 seconds, but you're free to use any length, Datetime, DateInterval or Carbon instance.

```php
User::where('name', 'Joe')->remember(today()->addHour())->first();
```

### Custom Cache Key

By default, the cache key is an MD5 hash of the SQL query and bindings, which avoids any collision with other queries. You can use any string, but is recommended to append `query|myCustomKey` to avoid conflicts with other cache keys.
By default, the cache key is an MD5 hash of the SQL query and bindings, which avoids any collision with other queries. You can use any string, but is recommended to append `query|{key}` to avoid conflicts with other cache keys in your application.

```php
User::where('name', 'Joe')->remember(30, 'query|find_joe')->first();
Expand All @@ -74,7 +74,35 @@ public function boot()

// ...
}
```
```

## Mind the gap

There are two things you should be warned about.

### Operations are **NOT** commutative

Altering the Builder methods order may change the automatic cache key generation. Even if they are *practically* the same, the order of statements makes them different. For example:

```php
<?php

DB::table('users')->remember()->whereName('Joe')->whereAge(20)->first();
// "query|fecc2c1bb6396e485d94eede60532937"

DB::table('users')->remember()->whereAge(20)->whereName('Joe')->first();
// "query|3ac5eba7cd0ef6151481bdfe46f6c22f"
```

If you plan to _remember_ the same query on different parts of your application, it's recommended to set manually the same Cache Key to ensure hitting the cached results.

### Only works for SELECT statements

The nature of remembering a Query is to cache the result automatically.

Caching the result for `UPDATE`, `DELETE` and `INSERT` operations will cache the result and subsequents operations won't be executed, returning unexpected results.

Don't use `remember()` on anything that is not a `SELECT` statement.

## License

Expand Down
7 changes: 3 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,11 @@
}
],
"require": {
"php": "^7.2",
"illuminate/support": "5.8.*|6.*"
"php": "^7.2.15",
"illuminate/support": "6.*|7.*"
},
"require-dev": {
"orchestra/testbench": "4.*",
"phpunit/phpunit": "^8.0"
"orchestra/testbench": ">4.0|5.*"
},
"autoload": {
"psr-4": {
Expand Down
30 changes: 19 additions & 11 deletions src/RememberableQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class RememberableQuery
/**
* Query Builder instance
*
* @var \Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder
* @var \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder
*/
protected $builder;

Expand All @@ -43,23 +43,22 @@ class RememberableQuery
* RememberableQuery constructor.
*
* @param \Illuminate\Contracts\Cache\Repository $cache
* @param \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder
*/
public function __construct(Cache $cache)
public function __construct(Cache $cache, $builder)
{
$this->cache = $cache;
$this->builder = $builder;
}

/**
* Sets the Builder instance
* Returns the Builder instance
*
* @param \Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder $builder
* @return $this
* @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder
*/
public function setBuilder($builder)
public function builder()
{
$this->builder = $builder;

return $this;
return $this->builder;
}

/**
Expand Down Expand Up @@ -117,7 +116,16 @@ public function __call($method, $arguments)
*/
protected function cacheKey() : string
{
return $this->cacheKey
?? 'query|' . md5($this->builder->toSql() . implode('', $this->builder->getBindings()));
return $this->cacheKey ?? $this->cacheKeyHash();
}

/**
* Returns the auto-generated cache key
*
* @return string
*/
public function cacheKeyHash() : string
{
return 'query|' . md5($this->builder->toSql() . implode('', $this->builder->getBindings()));
}
}
6 changes: 3 additions & 3 deletions src/RememberableQueryServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
namespace DarkGhostHunter\RememberableQuery;

use Illuminate\Support\ServiceProvider;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Query\Builder as QueryBuilder;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;

class RememberableQueryServiceProvider extends ServiceProvider
{
Expand All @@ -16,11 +16,11 @@ class RememberableQueryServiceProvider extends ServiceProvider
public function boot()
{
QueryBuilder::macro('remember', function ($ttl = 60, string $cacheKey = null) {
return app(RememberableQuery::class)->setBuilder($this)->remember($ttl, $cacheKey);
return app(RememberableQuery::class, ['builder' => $this ])->remember($ttl, $cacheKey);
});

EloquentBuilder::macro('remember', function ($ttl = 60, string $cacheKey = null) {
return app(RememberableQuery::class)->setBuilder($this)->remember($ttl, $cacheKey);
return app(RememberableQuery::class, ['builder' => $this ])->remember($ttl, $cacheKey);
});
}
}

0 comments on commit dd8e3fc

Please sign in to comment.