Doctrine query builder ~ datetime - php

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.

Related

Data comparison in laravel

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"?

Symfony JSON output including field name

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

Symfony 2 Doctrine COUNT

I have in my table "Artiste" one column "valideAdmin" who takes value 1 or 0.
I try to make a simple count to return the number of entries in my table where "valideAdmin" is to 1:
$repo = $this ->getDoctrine()
->getManager()
->getRepository('ProjectMainBundle:Artiste');
$qb = $repo->createQueryBuilder('valideAdmin');
$qb->select('COUNT(valideAdmin)');
$qb->where('valideAdmin=1');
$count = $qb->getQuery()->getSingleScalarResult();
return array(
'count' => $count
);
But it always "1" who's return...
Without where clause, I have the total count of the entries of the table, but valideAdmin can be 0 or 1. I only want the count number where valideAdmin=1
Thanks for help
createQueryBuilder()'s first parameter is the alias that you want your entity to take (ie.: a short name to be used to refer to your entity in the query).
What you need to do is set a proper alias for your entity (for example a for Artiste) and then COUNT() the instances of your entity where the property (not the column) valideAdmin is set to one:
$repo = $this ->getDoctrine()
->getManager()
->getRepository('ProjectMainBundle:Artiste');
$qb = $repo->createQueryBuilder('a');
$qb->select('COUNT(a)');
$qb->where('a.valideAdmin = :valideAdmin');
$qb->setParameter('valideAdmin', 1);
$count = $qb->getQuery()->getSingleScalarResult();
Remember that DQL runs queries on entities. The DQL your write is then translated into SQL to query the underlying data source after.
Also you can fetch all date then use of COUNT function in PHP
This method has an advantage.You do not have to use a complex query.
You have all the information with count columns
$repositoryArtiste = $this->getDoctrine()
->getRepository('ProjectMainBundle:Artiste');
$queryArtiste= $repositoryArtiste->createQueryBuilder('a')
->Where('a.valideAdmin = :valideAdmin')
->setParameter('valideAdmin',1)
->getQuery();
$Artiste = $queryArtiste->getResult();
var_dump(count($Artiste));

How to update a field in doctrine to set it null

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)

Doctrine ORM, two different querys produce the same result set

I'm using Doctrine 1.2 and Symfony 1.4.
In my action, I have two different query that return different result set. Somehow the second query seem to change the result (or the reference?) of the first one and I don't have any clue why..
Here is an example:
$this->categories = Doctrine_Query::create()
->from('Categorie AS c')
->innerJoin('c.Activite AS a')
->where('a.archive = ?', false)
->execute();
print_r($this->categories->toArray()); // Return $this->categories results, normal behavior.
$this->evil_query = Doctrine_Query::create()
->from('Categorie AS c')
->innerJoin('c.Activite AS a')
->where('a.archive = ?', true)
->execute();
print_r($this->categories->toArray()); // Should be the same as before, but it return $this->evil_query results instead!
Why Doctrine behave this way ? It's totally driving me crazy. Thanks!
To make it simple it seem like the Query 2 are hijacking the Query 1 result.
Use something like this between queries ($em - entity manager):
$em->clear(); // Detaches all objects from Doctrine!
http://docs.doctrine-project.org/en/2.0.x/reference/batch-processing.html
In the API docs for the toArray() method in Doctrine_Collection it says:
Mimics the result of a $query->execute(array(), Doctrine_Core::HYDRATE_ARRAY);
I suspect to answer this question to your satisfaction you're going to have to go through the source code.
This seems like it has to be an issue of $this->categories and $this->evil_query pointing to the same place. What are the results of $this->evil_query === $this->categories and $this->evil_query == $this->categories?
Hubert, have you tried storing the query into a separate variable and then calling the execute() method on it?
I mean something like:
$good_query = Doctrine_Query::create()
->from('...')
->innerJoin('...')
->where('...', false)
;
$evil_query = Doctrine_Query::create()
->from('...')
->innerJoin('...')
->where('...', true)
;
$this->categories = $good_query->execute();
$this->evil_query = $evil_query->execute();
It seems like both attributes (categories and evil_query) are pointing at the same object.
Erm, after both queries you print_r the result of the first query - change the last line to print_r($this->evil_query->toArray()); to see the difference :)

Categories