Cache Dependency On Variable

Hi,

I have the following situation: I have a CActiveDataProvider that provides entries to be rendered by a CListView. Each view of the entry is cached and depends on the evaluation of an SQL statement. Everything works fine when I create a CDbCacheDependency in the view. However, this is a very bad solution as it will result in one SQL query for each row!

So instead, I just add the query that would be made in each view to the CActiveDataProvider, resulting in a variable say $data[‘cache’]. This is an integer, and if it changes, the view needs to be re-rendered. However, I can’t figure out how to use a predefined CCacheDependency (I suppose CExpressionDependency should be it) to do this, do I really have to create my own?

Thanks!

Lupin

If your SQL query returns different results each time, the page will also change right? -> ergo you cannot pull page cached previously for different results. So I dont really understand the point…?

However, you may want to use CGlobalStateCacheDependency (http://www.yiiframework.com/doc/api/1.1/CGlobalStateCacheDependency) rather than CExpressionDependency, since you may need global variable available across many scripts…?

Also see:

http://www.yiiframework.com/forum/index.php/topic/13466-page-cache-dependency-dependencies/

I don’t fully understand, but let me try to explain:

You have a CListView rendering entries from a table say “customers”, say with a column “id”. Then there’s a table purchases, with a column “customer_id”, referencing the customers table.

Now the CListView takes all entries from customers, and for each calls a view that renders all purchases. This can be cached, and a reasonable dependency is that “SELECT COUNT(*) FROM purchases WHERE user_id = $id” hasn’t changed. If I use this with the CDbCacheDependency, then for every entry in the CListView, it will be polled separately. However, I can just have the CActiveDataProvider query this count along with the query for the entries of the CListView, I actually have that. So I have that value, and I just want to know if it changed or not.

Yeah, I thought about this, but because of lack of a better alternative my state persister saves in the database (other suggestions?), so this wouldn’t help. I could make it save in the cache though, maybe that’s a good approach, I don’t really need it (yet?) for anything persisting. But that’s not really how it’s meant I think. Another approach would be to write a class ValueCacheDependency that stores a value in cache and compares the value it is passed to the stored one and, if they differ, marks the cache as dirty.

So is this the best option? Seems like I can’t be the first one to need this?!

Thanks!

OK, I also realized that I do not understand how CDbCacheDependency saves the state, or where. Or CCacheDependency. All I can see is it stores it in its private $_data, and then compares it to it… so where is this saved? I cannot understand the code!

Help appreciated, thanks!

OK, I see that it just saves the whole instance of CDbCacheDependency (and similarly for other dependencies) to the cache and restores it later.

This means I don’t see how to do what I want, or even use the global state persister for it, unless I create a global state for every row in, using the above example, customers. That’s not good.

OK, I solved it by a workaround that could be put into a widget of its own, but I have no need for that:




$cacheArray = array(

        ...

);


$cacheCount = Yii::app()->cache->get($key);

if($cacheCount !== $data['purchase_count']) {

        $cacheArray['duration'] = 0;

        Yii::app()->cache->set($key, $data['purchase_count'], $expirytime);

}


if($this->beginCache($anotherKey, $cacheArray)) {

        ...

        $this->endCache();

}



Works well!

Thanks, hope this helps somebody else.