Need round DateTime from query params for correct build cache key #5495

Closed
opened 2026-01-22 15:09:10 +01:00 by admin · 5 comments
Owner

Originally created by @peter-gribanov on GitHub (Apr 7, 2017).

Originally assigned to: @Ocramius on GitHub.

This query is not be cached because the cache key builder use seconds from query parameter:

$result = $article_rep
    ->createQueryBuilder('a')
    ->where('date_publication <= :now')
    ->setParameter('now', new \DateTime())
    ->getQuery()
    ->setResultCacheLifetime(600)
    ->getResult()
;

Of course, the use of the current time in the query does not allow it to be cached, and therefore it is necessary to use conditionally the current time.

Need round DateTime from params

foreach ($query->getParameters() as $parameter) {
    if ($parameter->getValue() instanceof \DateTime) {
        // round down so that the results do not include data that should not be there.
        $date = clone $parameter->getValue();
        $date->setTimestamp(floor($date->getTimestamp() / $this->cacheLifetime) * $this->cacheLifetime);

        // ...
    }
}

You can say that this is not your task, but this is the task of the persistence layer, not the layer of business logic.

It looks very strange:

$cacheLifetime = 600;

$now = new \DateTime();
$now->setTimestamp(floor($now->getTimestamp() / $cacheLifetime) * $cacheLifetime);

$result = $article_rep
    ->createQueryBuilder('a')
    ->where('date_publication <= :now')
    ->setParameter('now', $now)
    ->getQuery()
    ->setResultCacheLifetime($cacheLifetime)
    ->getResult()
;

Now i am forced to use this approach, but i do not like it at all.

Originally created by @peter-gribanov on GitHub (Apr 7, 2017). Originally assigned to: @Ocramius on GitHub. This query is not be cached because the cache key builder use seconds from query parameter: ```php $result = $article_rep ->createQueryBuilder('a') ->where('date_publication <= :now') ->setParameter('now', new \DateTime()) ->getQuery() ->setResultCacheLifetime(600) ->getResult() ; ``` *Of course, the use of the current time in the query does not allow it to be cached, and therefore it is necessary to use conditionally the current time.* Need round DateTime from params ```php foreach ($query->getParameters() as $parameter) { if ($parameter->getValue() instanceof \DateTime) { // round down so that the results do not include data that should not be there. $date = clone $parameter->getValue(); $date->setTimestamp(floor($date->getTimestamp() / $this->cacheLifetime) * $this->cacheLifetime); // ... } } ``` You can say that this is not your task, but this is the task of the persistence layer, not the layer of business logic. It looks very strange: ```php $cacheLifetime = 600; $now = new \DateTime(); $now->setTimestamp(floor($now->getTimestamp() / $cacheLifetime) * $cacheLifetime); $result = $article_rep ->createQueryBuilder('a') ->where('date_publication <= :now') ->setParameter('now', $now) ->getQuery() ->setResultCacheLifetime($cacheLifetime) ->getResult() ; ``` Now i am forced to use this approach, but i do not like it at all.
admin added the Invalid label 2026-01-22 15:09:10 +01:00
admin closed this issue 2026-01-22 15:09:11 +01:00
Author
Owner

@peter-gribanov commented on GitHub (Apr 7, 2017):

I could create a simple the Conditionally Current Time object for this:

class ConditionallyCurrentTime extends \DateTime
{
    public function __construct($roundToSeconds, \DateTimeZone $timezone = null)
    {
        parent::__construct('now', $timezone);

        $this->setTimestamp(floor($this->getTimestamp() / $roundToSeconds) * $roundToSeconds);
    }
}

But it's doesn't work if i use the pattern Specification, because the parameters can be determined at different levels of the specification aggregator.

@peter-gribanov commented on GitHub (Apr 7, 2017): I could create a simple the Conditionally Current Time object for this: ```php class ConditionallyCurrentTime extends \DateTime { public function __construct($roundToSeconds, \DateTimeZone $timezone = null) { parent::__construct('now', $timezone); $this->setTimestamp(floor($this->getTimestamp() / $roundToSeconds) * $roundToSeconds); } } ``` But it's doesn't work if i use the pattern [Specification](https://github.com/Happyr/Doctrine-Specification), because the parameters can be determined at different levels of the specification aggregator.
Author
Owner

@Ocramius commented on GitHub (Apr 7, 2017):

This is 100% not the problem of the ORM.

We just take parameters and make a cache key from them, a d cannot round nor apply any assumptions on what the parameters mean.

Please use a fixed value such as midnight today or similar instead.

Closing as invalid

@Ocramius commented on GitHub (Apr 7, 2017): This is 100% not the problem of the ORM. We just take parameters and make a cache key from them, a d cannot round nor apply any assumptions on what the parameters mean. Please use a fixed value such as `midnight today` or similar instead. Closing as `invalid`
Author
Owner

@holtkamp commented on GitHub (Apr 7, 2017):

@peter-gribanov what about using a 'constant' like a DQL function, I guess CURRENT_TIMESTAMP() does the trick 😉

@holtkamp commented on GitHub (Apr 7, 2017): @peter-gribanov what about using a 'constant' like a [DQL function](http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html#dql-functions), I guess ```CURRENT_TIMESTAMP()``` does the trick 😉
Author
Owner

@Ocramius commented on GitHub (Apr 7, 2017):

@holtkamp that is still broken: now your query isn't idempotent anymore, and therefore not cacheable by definition. Even the rdbms won't cache such a query at low level...

@Ocramius commented on GitHub (Apr 7, 2017): @holtkamp that is still broken: now your query isn't idempotent anymore, and therefore not cacheable by definition. Even the rdbms won't cache such a query at low level...
Author
Owner

@holtkamp commented on GitHub (Apr 7, 2017):

@Ocramius aah, sorry, yeah, this involves result cache. I had the query cache in mind... Nevermind then!

@holtkamp commented on GitHub (Apr 7, 2017): @Ocramius aah, sorry, yeah, this involves result cache. I had the query cache in mind... Nevermind then!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#5495