renoki-co / laravel-eloquent-query-cache Goto Github PK
View Code? Open in Web Editor NEWAdding cache on your Laravel Eloquent queries' results is now a breeze.
License: Apache License 2.0
Adding cache on your Laravel Eloquent queries' results is now a breeze.
License: Apache License 2.0
Hello. Is there any way to use this library with Lumen 8.x? Thank you.
Hi,
Is it possible to just flush the "updated" model from the cache, instead of all models (of the same type)?
IE: If I have a model "Foo" and I query from the DB id 1 and id 2, then a subsequent query for id 1 or id 2 should result in the data come from the cache. However, if I update id 1, and have have $flushCacheOnUpdate=TRUE set, then both id 1 and id 2 are flushed from the cache.
I would like just id 1 to be flushed, so that the next query for that ID retrieves the data from the DB (with the updates).
I'm using laravel debugbar which was showing me some queries taking about 2 seconds.
I added caching to the model as described in the docs but debugbar is still telling me the query is taking about 2 seconds.
Have I missed something?
is it possible to set the time to cache in form of function and variable
/**
* Specify the amount of time to cache queries.
* Do not specify or set it to null to disable caching.
*
* @var int|\DateTime
*/
public $cacheFor = 3600;
/**
* Specify the amount of time to cache queries.
* Set it to null to disable caching.
*
* @return mixed
*/
public function cacheFor()
{
if (request()->user()->hasRole('admin')) {
return null;
}
return 1337;
}
that way, we can conditionally handle the cache which helps with
In Laravel 7, i have this:
Call to undefined method Rennokki\QueryCache\Query\Builder::getDb()
Bad Method Call
Did you mean Rennokki\QueryCache\Query\Builder::get() ?
Some query not caching...
use Rennokki\QueryCache\Traits\QueryCacheable;
class Event extends Model {
use QueryCacheable;
protected $cacheFor = 60 * 60; // 1 hour
protected static $flushCacheOnUpdate = true;
/**
* Set the base cache tags that will be present
* on all queries.
*
* @return array
*/
protected function getCacheBaseTags(): array
{
return [
'event_tag',
];
}
}
i put this on every models, with different tag each model...
but some query is not caching why..?.
and how i can check is that my query is caching..?.,
if not caching how i can check, why thats query is not cache...
thankyou...
sorry for my english...
First of all I would like to say that this package solves a very big problem for me.
Now I would like to know about cacheTags. I'll explain in detail, I don't know if I didn't understand or if it's not working properly.
I have the getThroughId
method, and in it I set the cache tag to: 'announcement:id_1', for example. However when I parse the cache via Redis-cli, I see that this "tag" is empty, and the cache has really gone somewhere else, something like:
"laravel_database_laravel_cache:d8480f04bdab8f0a2bfe7798e478abff705048d8:leqc:2ae5775e226f5a09747f7d249952285ce8b9cb4c68f35a43000a2f6d291ee053"
Images:
But analyzing another one with a bigger name:
The contet is there!
So I would like to know why when I call cacheTags it doesn't insert the content into it, but into another index?
How to find out whether data is being taken from the cache or from the database?
For example, there might be an isCache() method that returns true / false.
So that you can perform the action if not from the cache.
`return $builder->cacheBaseTags($this->getCacheBaseTags());`
It should have a base tags check like:
// changed so it could work without base tags
if ($this->cacheBaseTags) {
$builder
->cacheBaseTags($this->getCacheBaseTags());
}
return $builder;
As described here: https://laravel.com/docs/7.x/cache
Laravel has built in functionality for caching. What are the advantages of using this package instead?
Does updating cache work with belongsTo, HasOne? If so, how should this be done?
First off, thanks so much for this!
I was just wondering if there's any means by which I can purge the cache entirely?
As an example use case:
Hi!
First of all, this package has saved my project! Haha.
I want know if we have some method to control the cache saving based on environment. For i.e:
I solved this problem like this:
... but the cache file still generated (but not used in next query)!
It would be interesting if we could do:
$query->dontCache(true/false);
So we could use the conditional of the environment variable
Its a really nice package. Will you support Laravel 8 soon?
Hi,
I updated to the latest version (1.4.0) and it looks that it doesn't support the file cache driver anymore.
It is working fine on 1.3.1, and for what i need it's enough.
Can you keep the functionality in later versions too?
When set $flushCacheOnUpdate, flush won't work.
Use User::flushQueryCache() to force flush still not working.
Please check
if it not support ,when we are require it ,laravel will report a error .
For example:
User::where(["id"=>1])->get("name")->toArray();
for laravel is support;
for laravel-eloquent-query-cache is not support;
For me it seems that flushQueryCache() doesn't work without tags at all: https://github.com/rennokki/laravel-eloquent-query-cache/blob/master/src/Traits/QueryCacheModule.php#L152
Am I right? There doesn't seem to be easy way to empty whole cache per model?
Originally posted by @apeisa in #12 (comment)
Caching
$model->cacheTags(['Tags.id.name'])
Delete cache like this:
$model->flushQueryCache(['Tags.*'])
Or like :
$model->tags('Tags')->flush()
Hi, firstly let me say I love the package. It Has saved a great deal of time improving efficiency within our app.
While implementing this within my setup I've noticed a couple of issues.
The public function get($columns = ['*'])
and public function selectSub($query, $as)
methods implemented in Rennokki\QueryCache\Query\Builder
handle parameters differently to \Illuminate\Database\Eloquent\Builder
public function get($columns = ['*'])
The method should be able to accept a single column as a string and then wrap this using the Arr::wrap
helper as declared in \Illuminate\Database\Eloquent\Builder::get
.
When the model does not need caching this is fine as the parent method is called immediately and the string is wrapped. Going through the QueryCacheModule::getFromQueryCache
produces the following stack trace
This was previously mentioned in #46
Argument 1 passed to Illuminate\Database\Grammar::columnize() must be of the type array, string given, called in D:\xampp\htdocs\j2e_laravel\vendor\laravel\framework\src\Illuminate\Database\Query\Grammars\Grammar.php on line 143 {"exception":"[object] (TypeError(code: 0): Argument 1 passed to Illuminate\\Database\\Grammar::columnize() must be of the type array, string given, called in D:\\xampp\\htdocs\\j2e_laravel\\vendor\\laravel\\framework\\src\\Illuminate\\Database\\Query\\Grammars\\Grammar.php on line 143 at D:\\xampp\\htdocs\\j2e_laravel\\vendor\\laravel\\framework\\src\\Illuminate\\Database\\Grammar.php:125)
[stacktrace]
#0 D:\\xampp\\htdocs\\j2e_laravel\\vendor\\laravel\\framework\\src\\Illuminate\\Database\\Query\\Grammars\\Grammar.php(143): Illuminate\\Database\\Grammar->columnize('homework_id')
#1 D:\\xampp\\htdocs\\j2e_laravel\\vendor\\laravel\\framework\\src\\Illuminate\\Database\\Query\\Grammars\\Grammar.php(91): Illuminate\\Database\\Query\\Grammars\\Grammar->compileColumns(Object(Rennokki\\QueryCache\\Query\\Builder), 'homework_id')
#2 D:\\xampp\\htdocs\\j2e_laravel\\vendor\\laravel\\framework\\src\\Illuminate\\Database\\Query\\Grammars\\Grammar.php(65): Illuminate\\Database\\Query\\Grammars\\Grammar->compileComponents(Object(Rennokki\\QueryCache\\Query\\Builder))
#3 D:\\xampp\\htdocs\\j2e_laravel\\vendor\\laravel\\framework\\src\\Illuminate\\Database\\Query\\Builder.php(2264): Illuminate\\Database\\Query\\Grammars\\Grammar->compileSelect(Object(Rennokki\\QueryCache\\Query\\Builder))
#4 D:\\xampp\\htdocs\\j2e_laravel\\vendor\
ennokki\\laravel-eloquent-query-cache\\src\\Traits\\QueryCacheModule.php(158): Illuminate\\Database\\Query\\Builder->toSql()
#5 D:\\xampp\\htdocs\\j2e_laravel\\vendor\
ennokki\\laravel-eloquent-query-cache\\src\\Traits\\QueryCacheModule.php(132): Rennokki\\QueryCache\\Query\\Builder->generatePlainCacheKey('get', NULL, NULL)
#6 D:\\xampp\\htdocs\\j2e_laravel\\vendor\
ennokki\\laravel-eloquent-query-cache\\src\\Traits\\QueryCacheModule.php(116): Rennokki\\QueryCache\\Query\\Builder->generateCacheKey('get', NULL, NULL)
#7 D:\\xampp\\htdocs\\j2e_laravel\\vendor\
ennokki\\laravel-eloquent-query-cache\\src\\Traits\\QueryCacheModule.php(77): Rennokki\\QueryCache\\Query\\Builder->getCacheKey('get')
#8 D:\\xampp\\htdocs\\j2e_laravel\\vendor\
ennokki\\laravel-eloquent-query-cache\\src\\Query\\Builder.php(20): Rennokki\\QueryCache\\Query\\Builder->getFromQueryCache('get', 'homework_id')
#9 D:\\xampp\\htdocs\\j2e_laravel\\vendor\\laravel\\framework\\src\\Illuminate\\Database\\Eloquent\\Builder.php(571): Rennokki\\QueryCache\\Query\\Builder->get('homework_id')
#10 D:\\xampp\\htdocs\\j2e_laravel\\vendor\\laravel\\framework\\src\\Illuminate\\Database\\Eloquent\\Builder.php(555): Illuminate\\Database\\Eloquent\\Builder->getModels('homework_id')
#11 D:\\xampp\\htdocs\\j2e_laravel\\app\\Listeners\\Homework\\ClearUserOldClassNotifications.php(41): Illuminate\\Database\\Eloquent\\Builder->get('homework_id')
public function selectSub($query, $as)
When passing a raw query as a string, the if statement used to check whether to append cache tags produces an error as the get_class
is expecting an object to be passed.
local.ERROR: get_class() expects parameter 1 to be object, string given {"userId":22,"exception":"[object] (ErrorException(code: 0): get_class() expects parameter 1 to be object, string given at D:\\xampp\\htdocs\\j2e_laravel\\vendor\
ennokki\\laravel-eloquent-query-cache\\src\\Query\\Builder.php:49)
[stacktrace]
#0 [internal function]: Illuminate\\Foundation\\Bootstrap\\HandleExceptions->handleError(2, 'get_class() exp...', 'D:\\\\xampp\\\\htdocs...', 49, Array)
#1 D:\\xampp\\htdocs\\j2e_laravel\\vendor\
ennokki\\laravel-eloquent-query-cache\\src\\Query\\Builder.php(49): get_class('SELECT `date` F...')
#2 D:\\xampp\\htdocs\\j2e_laravel\\vendor\\laravel\\framework\\src\\Illuminate\\Support\\Traits\\ForwardsCalls.php(23): Rennokki\\QueryCache\\Query\\Builder->selectSub('SELECT `date` F...', 'last_login')
#3 D:\\xampp\\htdocs\\j2e_laravel\\vendor\\laravel\\framework\\src\\Illuminate\\Database\\Eloquent\\Builder.php(1533): Illuminate\\Database\\Eloquent\\Builder->forwardCallTo(Object(Rennokki\\QueryCache\\Query\\Builder), 'selectSub', Array)
#4 D:\\xampp\\htdocs\\j2e_laravel\\app\\Http\\Controllers\\Management\\SearchController.php(75): Illuminate\\Database\\Eloquent\\Builder->__call('selectSub', Array)
If you're happy for me to submit a PR I can make the necessary changes.
Thanks,
Luke
I needed to clear cache on logout so I imported the trait in my controller and did this
public function logout() {
admins::flushQueryCache();
invitations::flushQueryCache();
customers::flushQueryCache();
rides::flushQueryCache();
users::flushQueryCache();
}
am I doing something wrong?
Hi I'm using https://github.com/mattstauffer/Torch which provides eloquent and caching as well, but since it doesn't have facades caching is a little different from normal caching in terms of calling it.
https://github.com/mattstauffer/Torch/blob/master/components/cache/index.php
Here's a full example, would you mind adding some support about custom functions for doing the caching?That would make it possible to use with torch and also Lumeon.
I have an Account model, and it implements Rennokki\QueryCache\Traits\QueryCacheable.
Current version 2.4.2
I am calling Account::flushQueryCache();
to flush the cache.
My IDE mentions the method is not found, and the cache is not being cleared in tests. I did not find the method in QueryCacheable either.
What am I missing :)
Hi, and thanks for the great works!
I have an issue with inner join statements are not cached example:
while mostly think the issue because the pluck method not added to model methods!
select "discount" from "products" inner join "category_product" on "products"."id" = "category_product"."product_id" where "category_product"."category_id" = 29 and "active" = 1 and exists (select * from "categories" where "products"."category_id" = "categories"."id") order by "category_product"."order" asc
while Products Model are cached, category_product model cached and categories model cached!
statement example
$Products = new \App\Category ;
$Products = $Products->newQuery();
$Products = $Products->find($cat->id)->ProductsN()->has("Mcat")->with('Mcat');
$DiscountIds = $Products->pluck("discount")->toArray();
any ideas ?
thanks in advance
Trait method newBaseQueryBuilder has not been applied, because there are collisions with other trait methods on App\\
I'm using https://github.com/grimzy/laravel-mysql-spatial and it has the other newBaseQueryBuilder, I'm trying some of this https://github.com/renoki-co/laravel-eloquent-query-cache#advanced but I'm not getting good results, could some one give some advice or example?
I have a table in the database that assigned a model to. This table has a user_id and I want to cache the queries for the user individually. In other words, I need users to have their own specific cache so that I do not remove a global cache when invalidate. I did a prefix ->cachePrefix('m'.$user_id.'_')
but do not know how to invalidate on update/insert/delete. Please can you help?
Does the package automatically invalidate the cache whenever new Eloquent records is created/updated/deleted?
I have some complex queries and have to use DB class but package it seem to not supported. Is is possible?
Hello,
thank you for this wonderful project :). Something I noticed:
Category::whereName('Foobar')->firstOrFail()->values()->get()->pluck('name', 'id')->all();
Cached. get() retrieves all values first. Then specific columns are retrieved.
Category::whereName('Foobar')->firstOrFail()->values()->pluck('name', 'id')->all();
Not cached. A query is constructed such that not all columns are returned but only those that are specified in pluck.
I would expect the second (better) query to be cached. Is this a limitation of this project?
Is it possible to cache query builder? like for example:
DB::cacheFor(60 * 60)->select("SELECT DISTINCT ".$field." FROM ".$schemaName.".tests")
thanks!
Add phpDoc to trait, for enable autocompletion:
/**
* @method Builder cacheFor(int $seconds)
* @method Builder cacheTags(string[] $tags)
* @method Builder cachePrefix(string $prefix)
* @method Builder cacheDriver(string $driver)
*/
trait QueryCacheable {}
Hello, I encountered a new problem.
Example
EcommerceOffer::where("id", $id)->delete(); -- deleted_at = '2021-06-10 17:00:00' updated ?
QueryCacheable > FlushQueryCacheObserver > deleted
SoftDelete not triggering either.
When used with compoships i got this error:
Trait method Awobaz\Compoships\Compoships::newBaseQueryBuilder has not been applied as App\User::newBaseQueryBuilder, because of collision with Rennokki\QueryCache\Traits
\QueryCacheable::newBaseQueryBuilder
Thanks for the great package!
I have trouble with Laravel's loadCount method. Could you please give your advice for a workaround?
$user->loadCount(['phones' => function ($query) {
return $query->cacheFor(now()->addMonths(3));
}]);
Query is
select `id`, (select count(*) from `phones` where `users`.`id` = `phones`.`user_id`) as `phones_count`
from `users` where `users`.`id` in ('1');
composer require rennokki/rennokki/laravel-eloquent-query-cache
to
composer require rennokki/laravel-eloquent-query-cache
I'm using https://github.com/jenssegers/laravel-mongodb to have Eloquent queries for MongoDB, is there a way to use this caching with that library?
My following the basic set up I get
Call to a member function prepare() on null
at
Illuminate\Database\Connection::Illuminate\Database\{closure}
vendor/laravel/framework/src/Illuminate/Database/Connection.php:331
...
$statement = $this->prepared(
$this->getPdoForSelect($useReadPdo)->prepare($query)
)
I'm getting an error when booting my model (App\Product
). The error is the following:
Undefined index: App\Product
On laravel/framework/src/Illuminate/Database/Eloquent/Model.php
:
protected function initializeTraits()
{
foreach (static::$traitInitializers[static::class] as $method) {
$this->{$method}();
}
}
I think the right approach is to change the boot method on the QueryCacheable trait to use the recommended Laravel approach for booting traits. So instead of being public static function boot()
it would be public static function bootQueryCacheable()
and also remove the call to parent::boot()
Hello,
I was testing the package and everything works absolutely fine when caching models.
For example if I have a Model with a many-to-many relation, and I update that relation, the cache won't flush and update, even if I use protected static $flushCacheOnUpdate = true;
.
I was thinking that those relation could have a separated model and define protected static $flushCacheOnUpdate = true;
there, but IMO isn't really dinamic.
I don't have the skills to build this feature so, I will leave here the suggestion. Don't really know if it's easy to have an array of relation to flush cache on attach
, detach
, sync
or simply like protected static $flushRelationsCacheOnUpdate = true;
public $cacheFor = 86400;
and protected static $flushCacheOnUpdate = true;
$template->sites()->attach(1)
dd($template)
'Stay safe!
Thanks,
Helder
Is there a way to completely disable cache for tests in global way? It's causing some of my tests to fail and I find flushQueryCache()
a bit too much (to call every time).
This looks like a great package...something I can benefit from. However, I'm trying to use it with a model where I have my own custom Eloquent builder.
Please look at the following link: https://timacdonald.me/dedicated-eloquent-model-query-builders/
The builder extends Illuminate\Database\Eloquent\Builder
rather than Illuminate\Database\Query\Builder
.
Am I doing something wrong, or does this not support Illuminate\Database\Eloquent\Builder
...?
Thanks...! ๐ค
Hey @rennokki,
thanks for super robust library. I can not handle my polymorphic relationships with your lib. What do you suggest?
When making data changes (inserts, updates, and deletes) from one model/table to another model/table via Eloquent Relationships, the protected static $flushCacheOnUpdate = true;
feature does not seem to recognize that a change occurred. For instance, if I have a model/table called foo
that has a function that edits a thingamajig and then edits the related thingamabobs in the model/table bar
via a relationship in the foo
model. When Laravel/Eloquent retrieves the data for me to view the listing of thingamabobs from bar
(retrieving the data through the bar
model), the data displayed is still the old data from the cache. If I comment-out use Rennokki\QueryCache\Traits\QueryCacheable;
and use QueryCacheable;
in the model bar
, then making such edits in the foo
model (via relationships) will properly display the edits pertaining to bar
.
This issue appears to only be relevant to data changes via relationships. When using the bar
model (i.e. use bar;
) within the foo
model, this issue does not occur. It is as if QueryCacheable does not recognize relationships properly.
I hope I clearly explained and described this issue. If not, feel free to ask for clarification.
Hi,
I was using this amazing package on my project.
I have requirement to modify cache content directly, in parralel with the update of database. So I could prevent re query everytime. So I need to get the key of a cache.
I'm using newest version and using redis as my cache driver
After making some debug into redis every key looks like prefixed with string like this
my_project_database_my_project_cache:015cd49cea3e5add0c86b2e6940d434f0e2b1353:leqc:theactualkey
I just want to ask, where is 015cd49cea3e5add0c86b2e6940d434f0e2b1353 come from?
Call to undefined method Illuminate\Database\Eloquent\Relations\BelongsTo::cacheTags()
My code:
return PostUsersComment::with([
'user' => function ($query) use($post) {
return $query
->cacheTags(["post:{$post->id}:comments:user"])
->select(['id', 'name']);
}
])
->where('post_id', 65)
->latest()
->paginate(10);
Why?
How to flush for specific user after the user update profile? the only flush method is flushQueryCache() with clear all the caches in the same tags.
Instead of having to manually specify protected $cacheFor
in every model, simply apply env('CACHE_FOR', 0)
on every Model where use \Rennokki\QueryCache\Traits\QueryCacheable;
trait is installed :)
Hi,
As expected I am not a technical person. The purpose that I am chasing is to cache all queries in the form of DB::(TABLE)->where('XXX','YYY')->get()->toArray() or similarly DB::(TABLE)->whereRaw('XXX','YYY')->get()->toArray(). The cache should invalidate on update/create/delete. Please can you kindly guide on steps?
When will Laravel 6. X be supported?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.