Using Expression Values をご覧ください。
与えられた例は次のようになります(ドキュメントを引用):
$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";
ええと...今回は役に立てば幸いです...あなたが取得しようとしているものを実行する他の方法があまり見当たらないからです(そしてグーグルも私を助けません^^)
2番目(私の場合は3番目)のコメントの後に編集します。
私はこれを機能させます...そうしないと、よく眠れません^^
まあ、私は方法を見つけたかもしれません(そして、今回はそれをテストしました ^^ ) ; 思ったほど素晴らしいものではありませんが、とにかく更新については、うまくいっているようです...
この方法で作成されたテーブルがあるとしましょう:
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,
));
}
}
このテーブルに次の 2 行を挿入します。
$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)
つまり、過去のはるか昔の日付を持つ 2 行です。
さて、確かに、行 #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)
日付と時刻を考えると、これはうまくいったようです-万歳!
そして、確かに、DB から直接データをクエリしましょう:
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()
:- (
モデルクラスに統合できるかどうかはあなた次第です...それを楽しんでください;-)
そして、いつか、クエリの他の部分でこのような式を使用する方法、またはよりクリーンな方法を見つける方法を見つけた場合は、コメントを投稿して教えていただければ幸いです;-)
そして、今回は、道が見つかったことを心から願っています^^