I'm trying to pull a value from my DB in the field 'action', it is a JSON string however I'm storing it as a single value for now, this is it:
'command'=>'get','target'=>'location'
However when I pull it from the DB it includes the field name, which I don't want, see below:
[{"action":"'command'=>'get','target'=>'location'"}]
My code is here:
$em = $this->getDoctrine()->getManager();
$query = $em->createQueryBuilder();
$q = $query->select('z.action')
->from('AppBundle:ZeusUsers', 'z')
->where('z.id = ?1')
->setParameter(1, $id)
->getQuery();
$action = $q->getResult();
return new Response(json_encode($action));
So I just need to know how to grab the field value not including the field name?
try this method getSingleScalarResult()
but remember that if it wouldn't find anything it will throw exception
http://doctrine-orm.readthedocs.org/en/latest/reference/dql-doctrine-query-language.html#single-scalar-hydration
You want to use getSingleResult() instead of getResult() to get value of your field. It will throw exception if there are no results found or there are more than one result (setMaxResults(1) will remedy this part) though.
https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/AbstractQuery.php#L802
Related
I have 2 Entities
User
Article
and a “likedByUsers” Many To Many relationship between both.
When I show an article, I want to know if the user has liked it so a heart icon is shown.
I've got this in the ArticleRepository:
public function findOneBySlug($slug,$userId): ?Pack
{
return $this->createQueryBuilder('p')
->andWhere('p.slug = :val')
->setParameter('val', $slug)
->addSelect('COUNT(u) AS userLike', 'p')
->leftJoin("p.users", 'u', 'WITH', 'u.id = :userId')
->setParameter('userId', $userId)
->getQuery()
->getOneOrNullResult()
;
}
But it throws an error:
Return value of App\Repository\ArticleRepository::findOneBySlug() must be
an instance of App\Entity\Article or null, array returned
I want to add "userLike" (bool) to the Article returned entity. Anyone can help me out?
calling addSelect(...) on a query builder might change the return type / format.
in your particular case, the former db result was something like [... all the article properties ...] which hydration and the getOneOrNullResult turns into one Article or null.
the new format looks like
[... all the article properties ..., userlike], which hydration turns into [Article, userlike] which can't possibly turned into one Article or a null result, because it's a "more complex" array.
So you have to use a different result fetcher. Depending on what the caller of your function expects as a return value (I would expect an article ^^) you maybe should rename the function or add a virtual property on article to hide the userlike or something, so you can return just the Article or null.
So the solution that I would choose:
$result = $this->createQueryBuilder(...)
//...
->getSingleResult();
if(!$result) {
// empty result, obviously
return $result;
}
// $result[0] is usually the object.
$result[0]->userLike = $result['userLike'];
// or $result[0]->setUserLike($result['userLike'])
return $result[0];
btw: $this->createQueryBuilder($alias) in a repository automatically calls ->select($alias), so you don't have to addSelect('... userLike', 'p') and just do addSelect('... userLike')
I'm beginner in laravel and I'm trying to run comparison queries given in the database.
I saved a field date that is implemented by a form together with other fields including the name.
I tried to query the name and it works all regularly with this code below.
I would like to retrieve all the rows that have the name variable as the field name that I pass (and here it seems to work) and then only those with the field date that have the specified month at the number that I pass as variable $month.
what would be the right form to do this?
thanks
Piero
public function filterparamenter(){
$name = request('name');
$month = request('$month');
$query = subagente::all();
$query = $query->where('subagente', $subagente);
$query = $query->whereMonth('data', $month)->get();
Method Illuminate\Database\Eloquent\Collection::whereMonth does not exist.
Using ::all() returns a Collection, which has a ->where() method, but ->whereMonth() is only available on Eloquent's Builder class. Change your code as follows:
$query = subagente::query();
$query = $query->where('subagente', $subagente);
$query = $query->whereMonth('data', $month)->get();
Or, more compact:
$results = subagente::where("subagente", $subagente)
->whereMonth("data", $month)
-get();
Using ::query() or ::where() to start your query will generate a Builder instance, which you can chain addition clauses (->where(), ->whereMonth(), etc) on before calling ->get() to return a Collection of subagente records.
Side note, should "data" be "date"?
I'm trying to create a simple chatbox in symfony2 / doctrine 2.
For testing I'm checking for new messages every 5 seconds, so in my query I try to get all messages by getting all messages with a datetime greater than the current one minus 5 seconds.
I try to do so the following way, but it returns all messages in the database instead of the ones posted in the last 5 seconds
$em = $this->getDoctrine()->getManager();
$qb = $em->createQueryBuilder();
$qb->select('m')
->from('ChatboxBundle:ChatMessage', 'm')
->where(':new > :last')
->setParameter('new', 'm.postdate' )
->setParameter('last', new \DateTime('-5 second'), \Doctrine\DBAL\Types\Type::DATETIME);
$updatedata = $qb->getQuery()->getResult();
Any ideas on what I'm doing wrong?
m.postdate is a field name and therefore shouldn't be passed in as a parameter. Try this
$qb = $em->createQueryBuilder();
$qb->select('m')
->from('ChatboxBundle:ChatMessage', 'm')
->where('m.postdate > :last')
->setParameter('last', new \DateTime('-5 second'), \Doctrine\DBAL\Types\Type::DATETIME);
$updatedata = $qb->getQuery()->getResult();
Note thats You don't need to use \Doctrine\DBAL\Types\Type::DATETIME
The doc say :
Calling setParameter() automatically infers which type you are setting as value. This works for integers, arrays of strings/integers, DateTime instances and for managed entities. If you want to set a type explicitly you can call the third argument to setParameter() explicitly. It accepts either a PDO type or a DBAL Type name for conversion.
I want to set null to a field in doctrine and here is the sentence
$em = $this->getDoctrine()->getManager();
$qb = $em->createQueryBuilder();
$query = $qb->update('Model\Example', 'u')->set('u.deletedAt', ':deletedAt')
->where("u.id IN (:ids)")->setParameter('deletedAt', null)
->setParameter('ids', $ids)
->getQuery();
$query->execute();
i think that this code should do the job, but im getting this exception
An exception occurred while executing 'UPDATE example SET deleted_at = ?
WHERE (id IN (?)) AND (example.deleted_at IS NULL)' with params
[null, "5,6"]: SQLSTATE[22P02]: Invalid text representation: 7 ERROR:
la sintaxis de entrada no es válida para integer: «5,6»
first of all why doctrine is adding that AND (example.deleted_at IS NULL) am i doing something wrong ?
Your original query looks like it should work. I duplicated and tested with:
$em = $this->getService('doctrine.orm.entity_manager');
$qb = $em->createQueryBuilder();
$qb->update('Cerad\Bundle\PersonBundle\Entity\Person','person');
$qb->set('person.verified',':verified');
$qb->setParameter('verified',null);
$qb->where('person.id IN (:ids)');
$qb->setParameter('ids',array(1,2,3));
echo $qb->getQuery()->getSql(); // UPDATE persons SET verified = ? WHERE id IN (?)
$qb->getQuery()->execute();
Works as expected.
Are you sure you copy/pasted your exact code? No editing after the fact? Verify your ids array really is an array of integers. That is the only spot I could see where there might be an issue. And do make sure your error is coming from the code you posted. Maybe something else is going on? Try isolating your code in a command object. And of course deletedAt has it's is nullable set to true?
There is no real need to use the expr object for this case. Doctrine 2 correctly handles arrays for IN statements.
====================================
I suspect you have $ids = '5,6'? Try setting it to: $ids = array(5,6); Though even with a string I don't see how it's messing up the query.
When you set the value with PHP null script , it's not understood for doctrine because when transforming to the native sql ,he will not replace null with null value as string , so to resolve , pass the null value as string like
$qb->set('q.deletedAt','NULL');
thanks #Cerad the problem was that i was using the soft-delete extension from StofDoctrineExtensionsBundle and the bundle was adding the soft delete filter, so i just disabled the soft delete filter and now it works as expected,posting the solution many thanks.
$em = $this->getDoctrine()->getManager();
$em->getFilters()->disable('softdeleteable'); // this was the problem when you use the soft delete extension you need to disable the filter if you want to reactivate deleted records
$qb = $em->createQueryBuilder();
$qb->update('Model\Example', 'q');
$qb->set('q.deletedAt',':deletedAt');
$qb->setParameter('deletedAt',null);
$qb->where("q.id IN (:ids)");
$qb->setParameter('ids', $ids);
the problem is that you $ids is a string. you can make:
$arrayOfIds = explode(",", $ids);
and after in you update query:
->setParameter('ids', $arrayOfIds)
I am able to fetch my data from database by using this structure:
$user = $this->getDoctrine()
->getRepository('AcmeDemoBundle:Emails')
->find(8081);
When I do that, I am able to get my data like this:
$user->getColumnNameHere();
Basically I am able to use Entity Class.
But if I want to use QueryBuilder instead of find I am only getting associative arrays.
$product->createQueryBuilder('p')
->setMaxResults(1)
->where('p.idx = :idx')
->select('p.columnNameHere')
->setParameter('idx', 8081)
->orderBy('p.idx', 'DESC')
->getQuery();
$product = $query->getResult();
$product returnds as array. Is it possible to fetch it withj Entity Managaer Class? If yes, how?
I digg the documentation but it seems not possible or not exist in the doc or I'm just blind :)
Yes you can, usually using:
$repository
->createQueryBuilder('p')
->getQuery()
->execute()
;
This should return you an array of entities.
If you want to get a single entity result, use either getSingleResult or getOneOrNullResult:
$repository
->createQueryBuilder('p')
->getQuery()
->getOneOrNullResult()
;
Warning: These method can potentially throw NonUniqueResultException.
Edit: Ok, so the question was about partial objects: http://docs.doctrine-project.org/en/latest/reference/partial-objects.html
you can get an object instead of array by using "Partial Objects".
here is a tested example with DoctrineORM 2.2.2:
// create query builder
// $em is the EntityManager
$qb = $em->createQueryBuilder();
// specify the fields to fetch (unselected fields will have a null value)
$qb->select ('partial p.{id,pubDate,title,summary}')
->from ('Project\Entity\Post', 'p')
->where ('p.isActive = 1')
->orderBy ('p.pubDate', 'desc');
$q = $qb->getQuery();
$result = $q->getResult();
var_dump($result); // => object
If you wish to return an object from your original query:
$product->createQueryBuilder('p')
->setMaxResults(1)
->where('p.idx = :idx')
->select('p.columnNameHere')
->setParameter('idx', 8081)
->orderBy('p.idx', 'DESC')
->getQuery();
$product = $query->getResult();
Remove this line
->select('p.columnNameHere')
As soon as you use select, it will return an array...
getResult() method returns a collection (an array) of entities. Use getSingleResult() if you're going to fetch only one object.
EDIT:
Oh, I just noticed that you want to fetch a single field of a single object. Use getSingleScalarResult() as #Florian suggests.