Caching in Yii framework - yii

For caching the country list for used in drop list by using api, which is the best way or which cache is best in Yii framework? When we can cache this country list in cache?

I will provide you with a few links to help out, and also an example. Firstly, you should check out
http://www.yiiframework.com/doc/guide/1.1/en/caching.data to understand caching in yii.
I am using APC Caching, which involves installing the APC PHP extension, and configuring your config/main.php
There is an article on how to do this here: http://www.yiiframework.com/wiki/312/getting-the-most-out-of-apc-for-yii/
Next, in order to cache a country list, you could do the following
$tableName = CountryName::model()->tableName();
$dependencySql ='select max('.$tableName.'.update_time) from '.$tableName;
$dependency = new CDbCacheDependency($dependencySql);
$myModelSql= 'select name from '. $tablename;
$allCountries= CountryName::model()->cache(1000, $dependency)->findAllBySql($myModelSql);
If $allCountries hasn't been updated in the last 1000 seconds, Yii will retrieve from cache instead of hitting the db.
Hope this helps

Related

PhpStorm unable to resolve column for multiple database connections

I have only been using PhpStorm a week or so, so far all my SQL queries have been working fine with no errors after setting up the database connection. This current code actually uses a second database (one is for users the other for the specific product) so I added that connection in the database tab too but its still giving me a 'unable to resolve column' warning.
Is there a way to see what database its looking at? Will it work with multiple databases? Or have I done something else wrong?
Error below:
$this->db->setSQL("SELECT T1.*, trunc(sysdate) - trunc(DATE_CHANGED) EXPIRES FROM " . $this->tableName . " T1 WHERE lower(" . $this->primaryKey . ")=lower(:id)")
Also here is what my database settings window looks like as seen some people having problems with parameter patterns causing this error but I'm fairly sure that is not the issue here:
Using PhpStorm 10.0.3
You can set the SQL resolution scope in File -> Settings -> Languages & Frameworks -> SQL Resolution Scopes.
This allows you to provide a default for the entire project and you can optionally define specific mappings to certain paths in the project.
So the short answer is that it cant read the table name as a variable even though its set in a variable above. I thought PhpStorm could work that out. The only way to remove the error would be to either completely turn off SQL inspections (obviously not ideal as I use it throughout my project) or to temporarily disable it for this statement only using the doc comment:
/** #noinspection SqlResolve */
Was hoping to find a more focused comment much like the #var or #method ones to help tell Phpstorm what the table should be so it could still inspect the rest of the statement. Something like:
/** #var $this->tableName TABLE_IM_USING */
Maybe in the future JetBrains will add that or make PhpStorm clever enough to look at the variable 3 lines above.
You can use Nowdoc/Heredoc also instead of using
/** #noinspection SqlResolve */
Here is the example
$name = "your name";
$query = <<<SQL
SELECT * FROM user WHERE name LIKE "%$name%" ORDER BY id
SQL;
Both of the methods will make the warning gone

Database content cache for used it in form dropdown list

I want to cache the database content in yii and used that data in Yii drop down list. In the dropdownlist want to load the country names from database. (Have 2 tables user and country). In user form need the drop down list. That selected from country table using cache. Where queries are placed and when we can use the cache result in the user form?
In order to cache the results from a table and then use that in a dropdown you'll need to first set up caching in your config file as described in the Caching Overview of the Definitive Guide. If you wanted to use memCache you could set it up like so;
array(
......
'components'=>array(
......
'cache'=>array(
'class'=>'system.caching.CMemCache',
),
),
);
Yii can use a number of difference caches which are listed in the Caching Overview link above.
You'll then need to make use of Yii's data caching features. You can just do this in your user/_form.php view, for example;
...
echo $form->dropDownList($model,'country_id',CHtml::listData(Country::model()->cache(1000)->findAll(),'id','name'));
...
But the more MVC way would be to do this in your controller, something like so would work;
In your UserController:
...
public function actionUpdate()
{
...
$this->render('update',array(
'model'=>$model,
'countryList=>Country::model()->cache(1000)->findAll();,
);
}
...
In your user/update.php view:
...
echo $this->renderPartial('_form', array('model'=>$model,'countryList'=>$countryList));
...
In your user/_form.php view:
...
echo $form->dropDownList($model,'country_id',CHtml::listData($countryList,'id','name'));
...
The examples above use no dependency for the cache, so the cached values will stay valid until the time (in this case 1000 seconds) expires.
To read more about using a cache dependency, you can read the Cache Dependency section of the Data Caching doc.
[EDIT]
If you need to install memcached, and are using xampp on Windows, this is a great guide to get it working: HOW TO INSTALL MEMCACHED ON XAMPP ON WINDOWS 7

How to update the values of Magento products using installer/update scripts and Magento abstractions?

I added a custom eav attribute to my Magento application product entity using an installer script (Basically, following the procedure described here: Installing Custom Attributes with Your Module). Now, I want to use an update script to change (populate) the values of this attribute for each product according to some criteria (based on the product category). The script I attempted to use was essentially like this:
$attributeValues = array(...) // Map from $productId to the desired $value
$product = Mage::getModel('catalog/product');
foreach($attributeValues as $productId=>$value){
$product->load($productId)->setMyAttribute($value);
$product->save();
}
My questions would then be: Is it ok to use this level of abstraction (Mage::getModel('catalog/product') and its methods) in update scripts? If it isn't, how would you recommend to change these attribute values using update scripts (without requiring sql)?
The script I used (until now) has not worked and failed with the error:
Call to a member function getStoreIds() on a non-object
in a magento core file.
I don't know if this error is a Magento bug or is a problem with how I'm using the update scripts.
I'm using Magento 1.4.0.1
Data update scripts are the way to go
Simply use a data upgrade script for this. This is a script placed in the data folder instead of the sql folder. Those scripts run later then the database structure updates, and allow access to more functionality.
Example file names:
app/code/local/My/Module/data/your_setup/data-install-0.1.0.php
app/code/local/My/Module/data/your_setup/data-upgrade-0.1.0-0.2.0.php
This is already available in Magento 1.4.
Try adding Mage::app()->setUpdateMode(false) in your sql upgrade script. e.g.
$installer = new Mage_Eav_Model_Entity_Setup('core_setup');;
$installer->startSetup();
Mage::app()->setUpdateMode(false);
Mage::app()->setCurrentStore('your_store_code_here');
If you look in Mage::app()->getStore() you will see the following snippet that returns an incorrect store which is required for saving a product.
if (!Mage::isInstalled() || $this->getUpdateMode()) {
return $this->_getDefaultStore();
}

ASP.net MVC: Execute Razor from DB String?

I was thinking about giving end users the ability to drop Partial Views (controls) into the information being stored in the database. Is there a way to execute a string I get from the database as part of the Razor view?
Update (I forgot all about this)
I had asked this question previously (which lead me to create RazorEngine) Pulling a View from a database rather than a file
I know of at least two: RazorEngine, MvcMailer
I have a bias towards RazorEngine as it's one that I've worked on but I have a much simpler one at Github called RazorSharp (though it only supports c#)
These are all pretty easy to use.
RazorEngine:
string result = RazorEngine.Razor.Parse(razorTemplate, new { Name = "World" });
MvcMailer
I haven't used this one so I can't help.
RazorSharp
RazorSharp also supports master pages.
string result = RazorSharp.Razor.Parse(new { Name = "World" },
razorTemplate,
masterTemplate); //master template not required
Neither RazorSharp, nor RazorEngine support any of the Mvc helpers such as Html and Url. Since these libraries are supposed to exist outside of Mvc and thus require more work to get them to work with those helpers. I can't say anything about MvcMailer but I suspect the situation is the same.
Hope these help.

How to cache a query in Ruby on Rails 3

I have the following query in my application
#categories = Category.joins(:posts).select('distinct categories.*').order('label')
This query gets loaded on every page view since the categories are displayed on every page. This seems messy to me since the list of categories are not getting updated that often. Is there a nifty way to cache just the query? I have tried
Category.cache do
#categories = Category.joins(:posts).select('distinct categories.*').order('label')
end
but I still see the query getting loaded every time from the database in the development log.
In your controller, you can try something like:
#categories = Rails.cache.fetch('categories', :expires_in => 24.hours) { Category.joins(:posts).select('distinct categories.*').order('label') }
Which will only read to see if the following data block 'categories' has been cached and not expired. If expired after 24 hours, will then query the model and write the new record into Rails cache.
For more information, I followed the following guide.
Try it out. I have it working this way. Hope that helps.
You can use fragment caching for the part of your view template that displays the categories. This means that the categories will be served from the cache store and the query will only be executed once until the cache is expired (by using the expire_fragment method).
Fragment Caching Rails Guide