{
    "href": "/post/2019/12/11/atlas-postgresql-and-returning/",
    "relId": "2019/12/11/atlas-postgresql-and-returning",
    "title": "Atlas, PostgreSQL, and RETURNING",
    "author": "pmjones",
    "created": "2019-12-11 19:53:29 UTC",
    "updated": [
        "2019-12-11 19:53:29 UTC",
        "2019-12-11 20:02:14 UTC"
    ],
    "tags": [
        {
            "href": "/tag/php/",
            "relId": "php",
            "title": "PHP",
            "author": null,
            "created": null,
            "updated": [],
            "markup": "markdown"
        },
        {
            "href": "/tag/programming/",
            "relId": "programming",
            "title": "Programming",
            "author": null,
            "created": null,
            "updated": [],
            "markup": "markdown"
        },
        {
            "href": "/tag/atlas/",
            "relId": "atlas",
            "title": "Atlas",
            "author": null,
            "created": "2020-09-21 14:37:38 UTC",
            "updated": [
                "2020-09-21 14:37:38 UTC",
                "2023-06-22 02:17:41 UTC"
            ],
            "markup": "markdown"
        }
    ],
    "markup": "markdown",
    "html": "<p>One of the powerful features of PostgreSQL is its <code>RETURNING</code> clause. For\nexample, if you have a table like this ...</p>\n<pre><code class=\"language-sql\">CREATE TABLE articles (\n    article_id SERIAL PRIMARY KEY,\n    title      VARCHAR(255) NOT NULL,\n    -- ...\n    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n);\n</code></pre>\n<p>... and you insert a row using <a href=\"http://atlasphp.io/cassini/query/\">Atlas.Query</a> with a <code>RETURNING</code> clause ...</p>\n<pre><code class=\"language-php\">/** @var $insert \\Atlas\\Query\\Insert */\n$insert\n    -&gt;into('articles')\n    -&gt;columns(['title' =&gt; 'My Article'])\n    -&gt;returning('created_at');\n\n$pdoStatement = $insert-&gt;perform();\n</code></pre>\n<p>... then you can fetch the <code>RETURNING</code> column values from the <em>PDOStatement</em>\nresult:</p>\n<pre><code class=\"language-php\">$returning = $pdoStatement-&gt;fetch(PDO::FETCH_ASSOC);\nvar_export($returning);\n// ['created_at' =&gt; (the postgresql timestamp)]\n</code></pre>\n<p>If you have an <a href=\"http://atlasphp.io/cassini/table/\">Atlas.Table</a> data gateway for that table, you can make use of\n<code>RETURNING</code> in your <em>TableEvents</em> classes to populate database-provided values\ninto your <em>Row</em> objects automatically.</p>\n<p>To do so, add a <code>RETURNING</code> clause in the <code>modifyInsertRow()</code> method, then\nretrieve the values into the <em>Row</em> in the <code>afterInsertRow()</code> method:</p>\n<pre><code class=\"language-php\">// ...\n\nclass ArticleTableEvents extends TableEvents\n{\n    public function modifyInsertRow(\n        Table $table,\n        Row $row,\n        Insert $insert\n    ) : void\n    {\n        $insert-&gt;returning('created_at');\n    }\n\n    public function afterInsertRow(\n        Table $table,\n        Row $row,\n        Insert $insert,\n        PDOStatement $pdoStatement\n    ) : void\n    {\n        $returning = $pdoStatement-&gt;fetch(PDO::FETCH_ASSOC);\n        $row-&gt;created_at = $returning['created_at'];\n    }\n}\n</code></pre>\n<p>Now when a <em>Row</em> gets inserted through the <em>Table</em> data gateway, the\n<code>created_at</code> value will be populated automatically.</p>\n<pre><code class=\"language-php\">/** @var $tableLocator \\Atlas\\Table\\TableLocator */\n$articleTable = $tableLocator-&gt;get(ArticleTable::CLASS);\n$article = $articlesTable-&gt;newRow();\n$article-&gt;title = 'bar';\n$articleTable-&gt;insertRow($article);\necho $article-&gt;created_at; // the postgresql timestamp\n</code></pre>\n<p>You can do the same for updates as well, using <code>modifyUpdateRow()</code> and\n<code>afterUpdateRow()</code>.</p>\n<p>Bonus: becuase it uses both Atlas.Table and Atlas.Query, this functionality is\navailable \"for free\" in <a href=\"http://atlasphp.io/cassini/orm/\">Atlas.Orm</a>!</p>\n"
}
