silverstripe query does not work, best way to debug? - sql

I have this silverstripe query that does not work ( it outputs all messages and not the ones with the date range )
What would be the best way to tackle this query?
Im fairly new to silverstripe and havent been able to find information on how to print the raw query.
return = Message::get()
->filter(array(
'IsPublished' => true,
'StartPublication:LessThanOrEqual' => date('Y-m-d'),
'Priority' => array('High', 'Normal')
))
->where("\"StopPublication\" >= ".date('Y-m-d')." OR \"StopPublication\" IS NULL")
->sort('StartPublication', 'DESC')->limit($this->getLimit());

The correct answer is to not use where() - this is a trap method that a lot of learners fall into (presumably due to the name). It's intended basically only for very complex things that the ORM just can't handle.
You're calling filter at least, which is the correct thing. But what you want instead of where() is filterAny():
Message::get()
->filter([
'IsPublished' => true,
'StartPublication:LessThanOrEqual' => 'now',
'Priority' => ['High', 'Normal']
])
->filterAny([
'StopPublication:GreaterThanOrEqual' => 'now',
'StopPublication' => null
])
->sort('StartPublication', 'DESC')
->limit($this->getLimit());
As the other answer already specifies, do not use an = on the return (or put a $ in front of return to make it a variable), and to return the query itself use $datalist->sql() http://api.silverstripe.org/3.1/class-DataList.html#_sql
But - seeing the docs on SQLQuery is wrong, because you're not using SQLQuery. You're using the ORM, so this doc page is far more relevant: http://docs.silverstripe.org/en/3.1/developer_guides/model/data_model_and_orm/#filterany

For starts return = Message::get() its just return Message::get()
I assume that you have set php error reporting so that it outputs errors and SS is also in development mode so it won't hide error outputs.
The answer to your question is to to do either:
to output it to the output html:
Debug::dump(Message::get()
->filter(array(
'IsPublished' => true,
'StartPublication:LessThanOrEqual' => date('Y-m-d'),
'Priority' => array('High', 'Normal')
))
->where("\"StopPublication\" >= ".date('Y-m-d')." OR \"StopPublication\" IS NULL")
->sort('StartPublication', 'DESC')->limit($this->getLimit())->sql());
or output it to the project roots log file
Debug::log(Message::get()
->filter(array(
'IsPublished' => true,
'StartPublication:LessThanOrEqual' => date('Y-m-d'),
'Priority' => array('High', 'Normal')
))
->where("\"StopPublication\" >= ".date('Y-m-d')." OR \"StopPublication\" IS NULL")
->sort('StartPublication', 'DESC')->limit($this->getLimit())->sql());
See http://docs.silverstripe.org/en/developer_guides/model/sql_query/

Related

Wordpress: Wp_Query - find posts with meta_query OR tax_query

I want to find posts which have a specific post meta key/value or posts which are in a specific category. Here is the query. I want to combine the tax_query and the meta_query with OR, but AFAICS there's no way to do this.
$args = [
'post_type' => 'my-event',
'post_status' => 'publish',
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'ASC',
'cat' => 'home',
'tax_query' => [
[
'taxonomy' => 'event-cat',
'terms' => [
'open',
],
'field' => 'slug',
'operator' => 'IN',
'include_children' => true,
],
],
'meta_query' => [
[
'key' => 'event_author',
'value' => [1,7,11,15],
'compare' => 'IN',
],
],
];
$loop = new WP_Query($args);
Result should be:
All posts (events) which are in the category 'open' (no matter who the author is) AND all posts which are from one of the specified authors (no matter in which category the event is).
On SO I found a few similar questions and I think I have to create a SQL query to find a solution but I don't know how to do it. Hope that someone can help me here.
Thanks and best regards.
In order to make custom,unconventional and a bit complicated queries like this, you have to learn some basic SQL Syntax. Trust me, SQL basics are not so hard to learn, and they are really worth it if you consider how many projects in many different programming languages need some SQL knowledge.
WordPress gives you the option to make custom queries with wpdb::get_results() function. In case you already know how to use SQL syntax, try exploring the wordpress database a little, and you will find what table columns you need to extract to get the result you want.

How to decode json data in sql for search?

need some advice to solve problem with yii grid/POstgreSql search.
In table I have some row let's call - some_important_data.
For showing in gridview i write some code in MyModel.php afterFind() method.
$someData = $this->some_data ? json_decode(urldecode($this->some_data)) :'';
if(!empty($someData)) {
$this->searcheeReason = $someData->csr_refuse_reason;
$this->witnessReason = $someData->csr_witness_reason;
}
........
if(!empty($this->starttime) && !empty($this->endtime) && !empty($csrPauseData->csr_colleague_reason)){
$this->status = "Rejected";
}
Now I want to write Search Part in search method in MyMethodSearch.php and Order in my controller =>
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
$dataProvider->setSort([
'attributes' => [
'searchNum' => [
'asc' => ['responses.number' => SORT_ASC],
'desc' => ['csresponses.number' => SORT_DESC]
],
'searcheeReason' => ???
I try a lot of things, but I don't find any optimal way. One of that ways
=>
SELECT substring(csresponses.some_data
from (POSITION('%22csr_refuse_reason%22%3A%22' in
csresponses.some_data) +
LENGTH('%22csr_refuse_reason%22%3A%22'))
for (POSITION('%22%2C%22' in
substring(csresponses.some_data
from (POSITION('%22csr_refuse_reason%22%3A%22' in
csresponses.some_data) )
for (LENGTH( csresponses.some_data) -
POSITION('%22csr_refuse_reason%22%3A%22' in csresponses.some_data))))
- LENGTH('%22use_firstname%22%3A%22')))
from csresponses
Code written ofcourse with yii rules, it's just sql interpretation

cakephp see the compiled SQL Query before execution

My query gets the timeout error on each run. Its a pagination with joins.
I want to debug the SQL, but since I get a timeout, I can't see it.
How can I see the compiled SQL Query before execution?
Some cake code:
$this -> paginate = array(
'limit' => '16',
'joins' => array( array(
'table' => 'products',
'alias' => 'Product',
'type' => 'LEFT',
'conditions' => array('ProductModel.id = Product.product_model_id')
)),
'fields' => array(
'COUNT(Product.product_model_id) as Counter',
'ProductModel.name'
),
'conditions' => array(
'ProductModel.category_id' => $category_id,
),
'group' => array('ProductModel.id')
);
First off, set the debug variable to 2 in app/config/config.php.
Then add:
<?php echo $this->element('sql_dump');?>
at the end of your layout. This should actually be commented out in your default cake layout.
You will now be able see all SQL queries that go to the database.
Now copy the query and use the SQL EXPLAIN command (link is for MySQL) over the database to see what the query does in the DBMS. For more on CakePHP debugging check here.
Since your script doesn't even render you can try to get the latest log directly from the datasource with:
function getLastQuery()
{
$dbo = $this->getDatasource();
$logs = $dbo->getLog();
$lastLog = end($logs['log']);
return $lastLog['query'];
}
This needs to be in a model since the getDatasource() function is defined in a model.
Inspect the whole $logs variable and see what's in there.
One more thing you can do is ....
Go to Cake/Model/DataSource/DboSource.php and locate function execute() and print $sql variable.
That should print the sql.
This certainly is not be the cleanest way (as you are changing Cake directory) .. but certainly would be quickest just to debug if something is not working with sql.
Try...
function getLastQuery($model) {
$dbo = $model->getDatasource();
$logData = $dbo->getLog();
$getLog = end($logData['log']);
echo $getLog['query'];
}
Simple way to show all executed query of your given model:
$sqllog = $this->ModelName->getDataSource()->getLog(false, false);
debug($sqllog);
class YourController extends AppController {
function testfunc(){
$this->Model->find('all', $options);
echo 'SQL: '.$this->getLastQuery();
}
function getLastQuery()
{
$dbo = ConnectionManager::getDataSource('default');
$logs = $dbo->getLog();
$lastLog = end($logs['log']);
return $lastLog['query'];
}
}
or you can get all the query by adding following line in to the function execute() in lib/Cake/Model/DataSource.php
Debugger::dump($sql);
set the debug variable to 2 in app/config/config.php.
echo $this->Payment->save();
Out put like =>SQL Query: INSERT INTO photoora_photoorange.payments VALUES (*******)
[insert query][2]
set the debug variable to 2 in app/config/config.php.
And

findByAttributes Example

Explanation for the use of $condition and $param in findByAttributes in Yii
In most case, this is how I use findByAttributes
Person::model()->findByAttributes(array('first_name'=>$firstName,'last_name'=>$lastName));
Copy from this thread http://www.yiiframework.com/forum/index.php/topic/21178-findbyattributes-example/
Explain what you want to do and where is your errors.
Try to read documentation http://www.yiiframework.com/doc/api/1.1/CActiveRecord#findByAttributes-detail
When you do a find in Yii's CActiveRecord using the attributes of the model, you would most likely find by some equality.
Person::model()->findByAttributes(array(
'first_name' => $firstName,
'last_name' => $lastName,
));
In English, this translates to "Find me a person whose last name is $lastname and whose first name is $firstname". But this is a bad example. Consider the following.
Person::model()->findByAttributes(array(
'age' => 18,
));
This is a better example which translates, in English, to "Fetch me all eighteen year olds" (that is, "where age = 18). This can be re-written with conditions like so
Person::model()->findByAttributes(array(
'condition' => 'age = :age',
'params' => array(
':age' => 18,
),
));
So far, there may seem to be little benefits. But such expressions make us able to use more boolean operators. For example...
Person::model()->findByAttributes(array(
'condition' => 'age < :age',
'params' => array(
':age' => 18,
),
));
...can now help us find all those below a certain age.
The query can grow as complex as you wish with $conditions and $params, but with your normal method, you may only use assignment queries.

LookbackAPI: When did user stories become unblocked?

I'm running the following query to the lookback API to find stories in a date range that were unblocked, but I'm getting no results. Am I missing something obvious? No errors, warnings or results returned.
Below is the Generated Query I get back from the lookback API:
'GeneratedQuery' => {
'fields' => 'true',
'skip' => 0,
'limit' => 100,
'find' => {
'_PreviousValues.Blocked' => 'true',
'_TypeHierarchy' => -51038,
'Blocked' => 'false',
'_ValidFrom' => {
'$lte' => '2012-11-02T04:00:00.000Z',
'$gte' => '2012-07-01T04:00:00.000Z'
}
}
},
When you pass in Boolean values, you need to make sure that they are bare true or false. If you pass them in as Strings, it will not behave as expected. Similarly for values of type Number. They should not have quotes around them.
Ok, the problem was related to "true" and "false" and the fact that I'm using Perl.
I'm using the Perl JSON library, and I didn't realize that you need to pass in JSON::true() and JSON::false() for true and false, not the literals 'true' and 'false'. So, in effect Larry was right: it was passing "true" instead of true.