"Call to a member function mergeWith() on a non-object" when using related queries - propel

I'm having this situation with Propel 1.6 and a MySQL database:
$query->usePublicationQuery("pq");
$query->condition('c1', '(YEAR(`pq.PUBLISHED_DATE`)) = ?', "2013")
->condition('c2', '(MONTH(`pq.PUBLISHED_DATE`)) = ?', "03")
->condition('c3', '(DAY(`pq.PUBLISHED_DATE`)) = ?', "01")
->combine(array('c1', 'c2','c3'), 'and', 'c123');
$query->endUse();
The mergeWith()-error appears upon invocation of the endUse()-method. It is thrown when Propel tries to merge the queries like this in ModelCriteria.php:
$primaryCriteria->mergeWith($this); // (line 941)
$primaryCriteria seems to be null. Can anyone tell me, when and why this can possibly happen?

The caveat is that Propel's useQuery() and endUse() methods RETURN new query rather that change current one. So, either rewrite whole query using method chaining:
$query
->usePublicationQuery("pq")
->condition('c1', '(YEAR(`pq.PUBLISHED_DATE`)) = ?', "2013")
->condition('c2', '(MONTH(`pq.PUBLISHED_DATE`)) = ?', "03")
->condition('c3', '(DAY(`pq.PUBLISHED_DATE`)) = ?', "01")
->combine(array('c1', 'c2','c3'), 'and', 'c123')
->endUse();
...or something like this:
$query2 = $query->usePublicationQuery("pq");
$query2->condition('c1', '(YEAR(`pq.PUBLISHED_DATE`)) = ?', "2013")
->condition('c2', '(MONTH(`pq.PUBLISHED_DATE`)) = ?', "03")
->condition('c3', '(DAY(`pq.PUBLISHED_DATE`)) = ?', "01")
->combine(array('c1', 'c2','c3'), 'and', 'c123');
$query = $query2->endUse();

How are you instantiating the $query variable? Are you sure you're not trying to do this:
$query = PublicationQuery::create()
Without more information it's going to be very difficult to troubleshoot this, please provide more code.

Related

Laravel orWhere usage

I have the following query:
$foundItem = ItemDrop::where('zone_id',$this->user->zone_id)
->where('find_rate','>=',$itemChance)
->orderBy('find_rate','desc')
->take(1);
In my database, I set zone_id = "-1" if I want the ItemDrop to be available in all zones.
So I've been thinking how I can add it to my query..
$foundItem = ItemDrop::where('zone_id',$this->user->zone_id)
->orWhere('zone_id',"-1")
->where('find_rate','>=',$itemChance)
->orderBy('find_rate','desc')
->take(1);
but it doesn't feel right and probably will not work correctly, because I have 2 Wheres and the OrWhere should be included only with the first where: where('zone_id',$this->user->zone_id).
How I can get all records of ItemDrop with zone_id -1 AND $this->user->zone_id?
How my DESIRED query would look like without Laravel:
SELECT * FROM ItemDrops WHERE( zone_id = "-1" || zone_id = $this->user->zone_id) && find_rate >= $itemChance
Try this:
$foundItem = ItemDrop::where(function($query){
$query->where('zone_id',$this->user->zone_id)
->orWhere('zone_id',"-1");
})->where('find_rate','>=',$itemChance)
->orderBy('find_rate','desc') ->take(1);
You can use an anonymous function in orWhere to do this. Try something like this:
$foundItem = ItemDrop::where('zone_id',$this->user->zone_id)
->orWhere( function ($query) {
$query->where('zone_id',"-1");
})
->orderBy('find_rate','desc')
->take(1);
Hope it helps...

Doctrine create subquery with bound params

I am trying to construct a query that will basically pull all entries whose id's have 2 particular entries in another table so I am trying the below:
$query = $this->createQuery('e');
$subquery1 = $query->createSubquery('sea')
->select('sea.entry_id')
->from('Table sea')
->addWhere('sea.form_element_id = ?', $element)
->addWhere('sea.answer = ?', $answer)
->getDQL();
$subquery2 = $query->createSubquery('sea2')
->select('sea2.entry_id')
->from('Table sea2')
->addwhere('sea2.form_element_id = ?', $element2)
->addWhere('sea2.answer = ?', $answer2)
->getDQL();
$query->addWhere('e.id IN ?', $subquery1)
->addWhere('e.id IN ?', $subquery2);
return $query->execute();
However this is gives me an error on bound params.
What is the correct ways of constructing such subqueries?
NOTE that if I dont bind the params in the subqueries it works fine.
$nestedQuery = " id IN (SELECT sea.entry_id from table sea where sea.form_element_id = ? and sea.answer = ?) "
. " and id IN (SELECT sea2.entry_id from table sea2 where sea2.form_element_id = ? and sea2.answer = ?)";
return $this->findBySql($nestedQuery, array($param1, $param2, $param3, $param4));
That obviously returns a doctrine collection but you can do getFirst or loop through the returned objects or even use the Hydrator to get an array!

Laravel4 raw statement in the middle of complex where

I have a quite complex search method which handles the $input array from a controller, the thing is that I want to perform a custom SQL statement in the middle of it, for example:
$input['myField'] = array('condition' => 'rawStatement', value => 'AND WHERE LEFT(field,9) = 10`
and that would apply into my busy-conditions-method-builder
You can see the method at
http://pastebin.com/BNUKk2Xd
I'm trying to apply it on lines 52-54 but cant seem to get it working.
I know this is an old question but looking at your pastbin you have to chain your query like.
$query = User::join('user_personal','users.id','=','user_personal.user_id');
# Join user askings
$query = $query->leftJoin('user_askings','users.id','=','user_askings.user_id');
$query = ..........
$query = $query->orderBy('users.profile_score','DESC');
$query = $query->groupBy('users.id')->paginate(32);
return $query;

Conditional IF statement in a PHP Doctrine 1.2 SET statement

I would like find the correct syntax for the SET line:
Doctrine_Query::create()
->update('Media m')
->set('m.fallback IF(m.id = ?, 1, 0)', $id) <-- not correct
->execute();
Thanks for any help!
I think that could be done with two queries:
Doctrine_Query::create()
->update('Media m')
->set('m.fallback', 1)
->where('m.id = ?', $id)
->execute();
Doctrine_Query::create()
->update('Media m')
->set('m.fallback', 0)
->where('m.id != ?', $id)
->execute();
I don't know if it suits you, but at least that will do what you want. May not work out of the box, as I don't have Doctrine 1.2 at hand, so can't test this. But I think the idea is clear :)

How to order by count in Doctrine 2?

I'm trying to group my entity by a field (year) and do a count of it.
Code:
public function countYear()
{
$qb = $this->getEntityManager()->createQueryBuilder();
$qb->select('b.year, COUNT(b.id)')
->from('\My\Entity\Album', 'b')
->where('b.year IS NOT NULL')
->addOrderBy('sclr1', 'DESC')
->addGroupBy('b.year');
$query = $qb->getQuery();
die($query->getSQL());
$result = $query->execute();
//die(print_r($result));
return $result;
}
I can't seem to say COUNT(b.id) AS count as it gives an error, and
I do not know what to use as the addOrderby(???, 'DESC') value?
There are many bugs and workarounds required to achieve order by expressions as of v2.3.0 or below:
The order by clause does not support expressions, but you can add a field with the expression to the select and order by it. So it's worth repeating that Tjorriemorrie's own solution actually works:
$qb->select('b.year, COUNT(b.id) AS mycount')
->from('\My\Entity\Album', 'b')
->where('b.year IS NOT NULL')
->orderBy('mycount', 'DESC')
->groupBy('b.year');
Doctrine chokes on equality (e.g. =, LIKE, IS NULL) in the select expression. For those cases the only solution I have found is to use a subselect or self-join:
$qb->select('b, (SELECT count(t.id) FROM \My\Entity\Album AS t '.
'WHERE t.id=b.id AND b.title LIKE :search) AS isTitleMatch')
->from('\My\Entity\Album', 'b')
->where('b.title LIKE :search')
->andWhere('b.description LIKE :search')
->orderBy('isTitleMatch', 'DESC');
To suppress the additional field from the result, you can declare it AS HIDDEN. This way you can use it in the order by without having it in the result.
$qb->select('b.year, COUNT(b.id) AS HIDDEN mycount')
->from('\My\Entity\Album', 'b')
->where('b.year IS NOT NULL')
->orderBy('mycount', 'DESC')
->groupBy('b.year');
what is the error you get when using COUNT(b.id) AS count? it might be because count is a reserved word. try COUNT(b.id) AS idCount, or similar.
alternatively, try $qb->addOrderby('COUNT(b.id)', 'DESC');.
what is your database system (mysql, postgresql, ...)?
If you want your Repository method to return an Entity you cannot use ->select(), but you can use ->addSelect() with a hidden select.
$qb = $this->createQueryBuilder('q')
->addSelect('COUNT(q.id) AS HIDDEN counter')
->orderBy('counter');
$result = $qb->getQuery()->getResult();
$result will be an entity class object.
Please try this code for ci 2 + doctrine 2
$where = " ";
$order_by = " ";
$row = $this->doctrine->em->createQuery("select a from company_group\models\Post a "
.$where." ".$order_by."")
->setMaxResults($data['limit'])
->setFirstResult($data['offset'])
->getResult();`

Resources