How show all queries to database in yii framework - yii

In CodeIgniter I would do:
print_r ($this->db->queries);
In Yii I tried:
print_r (Yii::app()->db)
But this doesn't show any queries.
UPDATE:
I understand my problem: when I want to show db queries on a POST action, I don't show it. When using GET, it's ok.

As #bool.dev said, you can use CWebLogRoute or in my case i use CFileLogRoute to store these queries in file.
array (
'class' => 'CFileLogRoute',
'categories' => 'system.db.*',
'logFile' => 'sql.log',
),

To complement #snippLeaf-com's answer, you can trace this file filtering by the keywords you want like this:
// filter by "INSERT" or "UPDATE"
$ tail -f /path_to/protected/runtime/sql.log |grep 'INSERT\|UPDATE'
// filter (case insensitive) by "SELECT" in table "x2_users"
$ tail -f /path_to/protected/runtime/sql.log |grep -i SELECT.*x2_users
OBS: to get fresh data you could need refresh database cache:
rm -f protected/runtime/cache/*.bin

If you really want every query log in yii use yii db profiler extension.
Step1. Download extension from --> link
Step2. Unpack to protected/extensions/
Step3. Rename folder name yii-db-profiler-master to db_profiler
Step4. Update the following to your protected/config/main.php:
<?php
return array(
// …
'components' => array(
// …
'db' => array(
// …
'enableProfiling'=>true,
'enableParamLogging' => true,
),
'log'=>array(
'class'=>'CLogRouter',
'routes'=>array(
// …
array(
'class'=>'ext.db_profiler.DbProfileLogRoute',
'countLimit' => 1, // How many times the same query should be executed to be considered inefficient
'slowQueryMin' => 0.01, // Minimum time for the query to be slow
),
),
),
),
);

Related

My schedule command deletes all my records

I have a table called offers and this is how I store in my controller:
$offer = Offer::Create([
'user_id' => Auth::id(),
'property_id' => $request->property_id,
'offer_price' => $request->offer_price,
'offer_period' => $request->offer_period,
'offer_message' => $request->offer_message,
'cash_amount' => $request->cash_amount,
'buyer_type' => $request->buyer_type,
'expires_at' => now()->addMinutes($request->offer_period),
]);
I want to delete all the offers where the expires_at is older than the updated_at date. I am using the timestamps.
This is what I have in my kernel:
$schedule->call(function () {
Offer::where('updated_at', '>', 'expires_at' )->delete();
})->everyMinute();
When I ran the command:
php artisan schedule:run
I noticed that all the offers were deleted from my database.
I ran the command at 11:22, and even the rows that were meant to expire at 11:30 were deleted.
Is there anything that I possibly did wrong?
Instead of:
Offer::where('updated_at', '>', 'expires_at' )->delete();
you should use:
Offer::whereColumn('updated_at', '>', 'expires_at' )->delete();
Initially you used simple where. Laravel doesn't know that expires_at is here column name so where would be something like this:
SELECT * FROM offers where updated_at > 'expires_at'
And using second method Laravel will generate:
SELECT * FROM offers where updated_at > expires_at
without quotes (ant this is what you need here).
Instead of second method you can also use DB::raw construction like this:
Offer::where('updated_at', '>', \DB::raw('expires_at'))->delete();

How to get last executed query Yii

How to get Last executed query after model save, update, delete in yii.
i.e:
$model->save();
like $this->db->last_query(); in CI
Thanks
Put this on your config.php file , you can see other details along with your query ...
'db'=>array(
'enableProfiling'=>true,
'enableParamLogging' => true,
),
'log'=>array(
'class'=>'CLogRouter',
'routes'=>array(
…
array(
'class'=>'CProfileLogRoute',
'levels'=>'profile',
'enabled'=>true,
),
),
),
The simplest way to show last executed query is to make an sql error in that query! :p Give an invalid column name in query, then Yii error reporting will show that query as error, but you can see that query.

cakephp array's and find statement

I have two find statements and need the results of one find statement to use in the second find statement however the two methods I have tried to use have come back with errors
here is the first find statement, it lists the sender_id's
$sender=$this->Invoice->Find('list', array('fields'=>('sender_id')));
here is the second find statement, it takes that list of sender_id's and returns the corresponding company_name
$senderName=$this->Account->Find('all', array(
'conditions' => array(
$sender=>'account.id')));
this returns the right information however returns this error Warning (2): Illegal offset type [APP\Controller\InvoicesController.php, line 185]
so i tried doing it this way
$senderName=$this->Account->Find('all', array(
'conditions' => array(
'id'=>$sender['Invoice']['sender_id'])));
and get an undefined index on invoice.
$senderName=$this->Account->Find('all', array(
'conditions' => array(
'Account.id' => array_values($sender),
),
));
The key is the field and the value is, well, the value(s).

Need listbox with multiple selection - in yii

I need listbox of multiple selection in yii, i have code of form area
but its saving to database as a word "Array" in field, How to handle
this problem?
how to get back while view and update and grid view also
<?php echo $form->dropDownList($model,'clients',
CHtml::listData(client::model()->findAll(array('order'=>'id')), 'id', 'name'),
array('empty'=>'','multiple'=>'multiple','style'=>'width:400px;','size'=>'10'));
?>
Thank you.
For me works this:
'multiple'=>true
Your code must be something like that:
<?php echo $form->dropDownList($model,'clients',
CHtml::listData(client::model()->findAll(array('order'=>'id')), 'id', 'name'),
array('empty'=>'','multiple'=>true ,'style'=>'width:400px;','size'=>'10'));
?>
$htmlOptions = array('size' => '5', 'multiple' => 'true','style'=>'width: 333px');
$model->field_id = array_of_data_to_be_selected
$form->listBox($model,'field_id',$listData, $htmlOptions);
If it is a relation you may want to use this : http://yiiext.github.com/activerecord-relation-behavior/ which takes care of saving array into many to many relation junction table.
Otherwise, like Orlymee said, you need to save each item of the array by looping through it or you can serialize the array or implode it into comma separated values and do the reverse of whatever method you chose to save, while viewing.
keep this code in controller
$arr = implode(",",$model->attributes['hobbies']);
$model->hobbies=$arr;
in controler create,update in the first if condition
in database you can see the values with comma as delimiter
How does this work in CHtml::listBox()
if(!empty($htmlOptions['multiple']))
{
if(substr($name,-2)!=='[]')
$name.='[]';
}
So you can try this
<?php echo $form->dropDownList($model,'clients',
CHtml::listData(client::model()->findAll(array('order'=>'id')), 'id', 'name'),
array(
>>> 'name'=>CHtml::resolveName($model, 'clients').'[]',
'empty'=>'',
'multiple'=>'multiple',
'style'=>'width:400px;',
'size'=>'10',
)
);?>
But it's better to use CHtml::listBox()

Getting the string representation from CDbCriteria

Is there any way to the get the string representation of the query from CDbCriteria? For testing and debugging purposes.
You can use logging and profiling configuring your main.php like this:
'components'=>array(
'log'=>array(
'class'=>'CLogRouter',
'routes'=>array(
array(
'class'=>'CWebLogRoute',
'categories'=>'system.db.CDbCommand',
'showInFireBug'=>true,
),
),
),
'db'=>array(
'enableProfiling'=>true,
'enableParamLogging'=>true,
),
),
I spend a lot amount of time for finding the answer to this question, so thought of sharing it with you guys. Hope this saves your precious time.
As mentioned by Jon above: CDbCriteria does not aggregate enough information to construct the full query, you have to use the model class information also on which you will put the query constraints.
As the example given in Yii docs for CDbCriteria; this is how basically you use it-
$criteria=new CDbCriteria();
$criteria->compare('status',Post::STATUS_ACTIVE);
$criteria->addInCondition('id',array(1,2,3,4,5,6));
$posts = Post::model()->findAll($criteria);
Here Post is the name of the model on which you execute the query condition.
So if you want to get the text representation of the query written in CDbCriteria, you have to involve the model information also i.e. Post.
This is how you can do it -
$model = new Post();
$query = $model->getCommandBuilder()->createFindCommand($model->getTableSchema(), $criteria)->getText();
When you print the value in $query variable it prints the raw query.
Hope this helps.