Возможно, вы захотите взглянуть на Использование значений выражений
Данный пример выглядит следующим образом (цитирование документа) :
$user = new User();
$user->username = 'jwage';
$user->updated_at = new Doctrine_Expression('NOW()');
$user->save();
И генерирует этот SQL-запрос:
INSERT INTO user (username, updated_at_) VALUES ('jwage', NOW())
Полагаю, это подойдет, в вашем случае?
(у меня нет проекта с поддержкой Doctrine, поэтому я не могу проверить его для вас)
Как примечание: у меня нет сервера PostGreSQL для тестирования; но то, что вы предлагаете, не работает на MySQL: похоже, вы должны использовать «now() + interval 2 hour
», а не «now() + interval 2 hours
» - тем не менее, я не знаю о PG
РЕДАКТИРОВАТЬ после комментария
Э-э, вы правы, это не правильное решение; это не работает : - (
Ну ... Интересный вопрос, поэтому я выкопал еще немного и пошел к исходному коду Doctrine; Я думаю, что мог найти что-то интересное.
Если вы посмотрите на источник Doctrine_Query_Where::parseValue
, вы увидите эту часть кода:
// If custom sql for custom subquery
// You can specify SQL: followed by any valid sql expression
// FROM User u WHERE u.id = SQL:(select id from user where id = 1)
} elseif (substr($trimmed, 0, 4) == 'SQL:') {
$rightExpr = '(' . substr($trimmed, 4) . ')';
// simple in expression found
Я абсолютно не пробовал, но это может быть интересно ...
Может быть, вы могли бы сделать что-то вроде этого:
$reset->expires="SQL:(now() + interval $duration hours)";
Если вы попробуете это, мне очень интересно знать, сработает ли это!
Может быть полезно, один день или другой; -)
Кстати, похоже, он также используется в Doctrine_Search
; Глядя на этот, может быть, он будет работать без скобок, например:
$reset->expires="SQL:now() + interval $duration hours";
Ну ... Надеюсь, на этот раз это поможет ... Потому что я не вижу другого способа сделать то, что вы пытаетесь получить (и Google тоже мне не помогает ^^ )
РЕДАКТИРОВАТЬ после второго (третьего, если считать мой) комментария.
Я получу это работает ... иначе я не буду хорошо спать ^^
Ну, я мог бы найти способ (и на этот раз я его проверил ^^) ; на самом деле не так хорошо, как хотелось бы, но, в любом случае, похоже, что обновления работают ...
Допустим, у меня есть таблица, созданная таким образом:
CREATE TABLE `test1`.`test` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(32) NOT NULL,
`value` varchar(128) NOT NULL,
`date_field` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Соответствующий класс модели выглядит так:
Вероятно, не идеально: это тестовый класс, который я написал для чего-то другого, который я мутировал, чтобы соответствовать этому ^^
class Test extends Doctrine_Record
{
public function setTableDefinition()
{
$this->setTableName('test');
$this->hasColumn('id', 'integer', 4, array(
'type' => 'integer',
'length' => 4,
'unsigned' => 0,
'primary' => true,
'autoincrement' => true,
));
$this->hasColumn('name', 'string', 32, array(
'type' => 'string',
'length' => 32,
'fixed' => false,
'notnull' => true,
));
$this->hasColumn('value', 'string', 128, array(
'type' => 'string',
'length' => 128,
'fixed' => false,
'primary' => false,
'notnull' => true,
'autoincrement' => false,
));
$this->hasColumn('date_field', 'integer', 4, array(
'type' => 'timestamp',
'notnull' => true,
));
}
}
Я вставлю две строки в эту таблицу:
$test = new Test();
$test->name = 'Test 1';
$test->value = 'My Value 1';
$test->date_field = "2009-01-30 08:30:00";
$test->save();
$test = new Test();
$test->name = 'Test 2';
$test->value = 'My Value 2';
$test->date_field = "2009-02-05 08:30:00";
$test->save();
Который получает эти данные из SQL:
Кстати: у меня нет pg-сервера, поэтому я все протестирую с MySQL - все равно должно работать и на pg ...
mysql> select * from test;
+----+--------+------------+---------------------+
| id | name | value | date_field |
+----+--------+------------+---------------------+
| 1 | Test 1 | My Value 1 | 2009-01-30 08:30:00 |
| 2 | Test 2 | My Value 2 | 2009-02-05 08:30:00 |
+----+--------+------------+---------------------+
2 rows in set (0.00 sec)
Итак, две строки с датами в прошлом.
Теперь, чтобы быть уверенным, давайте просто возьмем строку # 1:
$testBefore = Doctrine::getTable('Test')->find(1);
var_dump($testBefore->toArray());
Я получаю такой вывод:
array
'id' => string '1' (length=1)
'name' => string 'Test 1' (length=6)
'value' => string 'My Value 1' (length=10)
'date_field' => string '2009-01-30 08:30:00' (length=19)
А теперь интересная часть: давайте обновим эту строку, используя выражение, подобное тому, которое вы указали , чтобы установить значение date_field
:
$query = new Doctrine_Query();
$query->update('test')
->set('date_field', 'NOW() - interval 2 hour')
->where('id = ?', 1)
->execute();
var_dump($query->getSql());
SQL, который я получаю в качестве вывода, это:
string 'UPDATE test SET date_field = NOW() - interval 2 hour WHERE id = ?' (length=65)
Какой вид, что вы хотите, если я не ошибаюсь; -)
И, чтобы быть уверенным, давайте еще раз приведем нашу строку:
$testAfter = Doctrine::getTable('Test')->find(1);
var_dump($testAfter->toArray());
И я получаю такой результат:
array
'id' => string '1' (length=1)
'name' => string 'Test 1' (length=6)
'value' => string 'My Value 1' (length=10)
'date_field' => string '2009-08-04 21:26:30' (length=19)
Учитывая дату и время, кажется, это сработало - ура!
И, конечно, давайте запросим данные непосредственно из БД:
mysql> select * from test;
+----+--------+------------+---------------------+
| id | name | value | date_field |
+----+--------+------------+---------------------+
| 1 | Test 1 | My Value 1 | 2009-08-04 21:26:30 |
| 2 | Test 2 | My Value 2 | 2009-02-05 08:30:00 |
+----+--------+------------+---------------------+
2 rows in set (0.00 sec)
И ... Даааа!
Что ж, теперь не очень хорошие части: чтобы использовать этот синтаксис, мне нужно было создать запрос «вручную», использовать метод set()
, вместо того, чтобы «делать его красиво» с классом модели и save()
метод: - (
Теперь вам предстоит увидеть вас, которых можно интегрировать в ваш модельный класс ... Веселитесь с этим; -)
И если вы когда-нибудь найдете способ использовать выражения, подобные этому, в других частях запроса или сделать это более понятным способом, я был бы очень признателен, если бы вы могли опубликовать комментарий, чтобы сообщить мне ; -)
И в этот раз я искренне надеюсь, что нашел способ ^^