Frage

Wenn ich so etwas tun möchte (beachten Sie die Ablauflinie):

$duration=24; //in hours

$reset=new PasswordReset();
$reset->code=md5(uniqid());
$reset->expires="now() + interval $duration hours";
$reset->User=$user;
$reset->save();

Wie kann ich die Doktrin dazu bringen, sie nicht zu zitieren, bevor ich sie an postgreSQL sende? Ich weiß, dass ich das in PHP tun könnte, aber ich würde gerne als zukünftige Referenz wissen.

War es hilfreich?

Lösung

Vielleicht möchten Sie sich ansehen Verwendung von Expressionswerten

Das angegebene Beispiel sieht so aus (Zitat des Dokuments) :

$user = new User();
$user->username = 'jwage';
$user->updated_at = new Doctrine_Expression('NOW()');
$user->save();

Und generiert diese SQL -Abfrage:

INSERT INTO user (username, updated_at_) VALUES ('jwage', NOW())

Ich nehme an, es würde in Ihrem Fall tun?
(Ich habe hier kein Doktrin-fähiges Projekt, also kann ich also nicht für Sie testen.)


Als Nebenbemerkung: Ich habe keinen PostgreSQL -Server zum Testen; Aber was Sie vorschlagen, funktioniert bei MySQL nicht: Sie müssen verwenden. "now() + interval 2 hour", und nicht "now() + interval 2 hours" - Trotzdem weiß ich nichts über PG


Nach dem Kommentar bearbeiten

Ergh, du hast Recht, das ist keine korrekte Lösung. Es funktioniert nicht :-(

Nun ... interessante Frage, also habe ich ein bisschen mehr gegraben und bin zum Quellcode der Doktrin gegangen. Ich denke, ich habe vielleicht etwas Interessantes gefunden.

Wenn Sie sich die Quelle von ansehen Doctrine_Query_Where::parseValue Quelle, Sie werden diesen Teil des Codes bemerken:

// 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

Ich habe absolut nicht versucht, aber das könnte interessant sein ...

Vielleicht könnten Sie so etwas tun:

$reset->expires="SQL:(now() + interval $duration hours)";

Wenn Sie das versuchen, bin ich sehr daran interessiert zu wissen, ob es funktionieren würde!
Könnte eines Tages nützlich sein ;-)

Übrigens, es scheint in verwendet zu werden Doctrine_Search zu ; Wenn Sie sich dieses ansehen, funktioniert es vielleicht ohne die Klammern wie folgt:

$reset->expires="SQL:now() + interval $duration hours";

Nun ... ich hoffe, diesmal hilft es ... weil ich nicht etwas anderes sehe, um das zu tun, was Sie versuchen zu bekommen (Und Google hilft mir auch nicht ^^)


Bearbeiten Sie nach dem zweiten (dritten, falls ich meinen) Kommentar.
Ich werde das zum Laufen bringen ... sonst werde ich nicht gut schlafen ^^

Nun, ich hätte vielleicht einen Weg gefunden (Und diesmal habe ich es getestet ^^) ; Nicht wirklich so großartig, wie man es gerne hätte, aber für Updates scheint es trotzdem zu funktionieren ...

Nehmen wir an, ich habe eine Tabelle auf diese Weise erstellt:

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;

Die entsprechende Modellklasse sieht so aus:
Wahrscheinlich nicht perfekt: Es ist eine Testklasse, die ich für etwas anderes geschrieben habe, das ich mutiert habe, um zu diesem zu passen ^^

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,
             ));
    }
}

Ich werde zwei Zeilen in diese Tabelle einfügen:

$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();

Das bringt mir diese Daten von SQL:
Übrigens: Ich habe keinen PG -Server, also teste ich alles mit MySQL - sollte auch an PG arbeiten, immer noch ...

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)

Also zwei Zeilen mit Daten vor langer Zeit in der Vergangenheit.


Lassen Sie uns nun nur die Zeile Nr. 1 abrufen:

$testBefore = Doctrine::getTable('Test')->find(1);
var_dump($testBefore->toArray());

Ich bekomme diese Art von Ausgabe:

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)


Und jetzt der interessante Teil: Lassen Sie uns diese Zeile mit einem Ausdruck wie dem, den Sie zur Verfügung gestellt haben, aktualisieren um das zu setzen date_field Wert :

$query = new Doctrine_Query();

$query->update('test')
    ->set('date_field', 'NOW() - interval 2 hour')
    ->where('id = ?', 1)
    ->execute();

var_dump($query->getSql());

Die SQL, die ich als Ausgabe bekomme, ist dieser:

string 'UPDATE test SET date_field = NOW() - interval 2 hour WHERE id = ?' (length=65)

Was sieht so aus wie das, was du willst, wenn ich mich nicht irre ;-)


Und nur, um sicher zu sein, holen wir unsere Linie noch einmal:

$testAfter = Doctrine::getTable('Test')->find(1);
var_dump($testAfter->toArray());

Und ich bekomme dieses Ergebnis:

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)

In Anbetracht des Datums und der Uhrzeit scheint es, dass dies funktioniert hat - Hoorray!

Und zwar, lassen Sie uns die Daten direkt aus der DB abfragen:

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)

Und ... Yeeeep!


Nun, jetzt die nicht so guten Teile: Um diese Syntax zu verwenden, musste ich die Abfrage "von Hand" erstellen, um die zu verwenden set() Methode, anstatt es "schön" mit der Modellklasse und der save() Methode :-(

Es liegt jetzt an Ihnen, Sie zu sehen, die in Ihre Modellklasse integriert werden könnten ... viel Spaß damit ;-)

Und wenn Sie eines Tages einen Weg finden, um Ausdrücke wie diesen in anderen Teilen der Abfrage zu verwenden, oder um es sauberer zu machen, würde ich es wirklich zu schätzen wissen, wenn Sie einen Kommentar veröffentlichen könnten, um es mich wissen zu lassen ;-)


Und, Zeit, Zeit, ich hoffe aufrichtig, dass ich den Weg gefunden habe ^^

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top