{
    "href": "/post/2017/10/03/atlas-orm-2-0-0-beta1-released/",
    "relId": "2017/10/03/atlas-orm-2-0-0-beta1-released",
    "title": "Atlas.Orm 2.0.0-beta1 Released",
    "author": "pmjones",
    "markup": "html",
    "tags": [
        {
            "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"
        },
        {
            "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"
        }
    ],
    "created": "2017-10-03 14:56:28 UTC",
    "updated": [
        "2017-10-03 14:56:28 UTC"
    ],
    "html": "<p>I am very happy to announce that I have just released 2.0.0-beta1 of <a href=\"https://github.com/atlasphp/Atlas.Orm\">Atlas</a>, a data mapper for your SQL persistence model. You can get it via Composer as <a href=\"https://packagist.org/packages/atlas/orm\">atlas/orm</a>. This new major version requires PHP 7.1 and uses typehints, but best of all, it is backwards compatible with existing 1.x generated Atlas classes!</p>\n<p>I.</p>\n<p>The original motivation for starting the 2.x series was an edge-case bug. Atlas lets you open and manage transactions across multiple connections simultaneously; different table classes can point to different database connections. Atlas also lets you save an entire Record and all of its related fields with a single call to the <code>persist()</code> Mapper or Transaction method.</p>\n<p>However, in 1.x, executing a <code>Transaction::persist()</code> call does not work properly when the relationships are mapped across connections that are not the same as the main Record. This is because the Transaction begins on the main Record connection, but does not have access to the connections for related records, and so cannot track them.</p>\n<p>Admittedly, this is an uncommon operation, but ought to be supported properly. The only way to fix it was to break backwards compatibility on the Table and Transaction classes, both on their constructors and on their internal operations, by introducing a new ConnectionManager for them to use for connection and transaction management.</p>\n<p>II.</p>\n<p>As long as backwards compatibility breaks were going to happen anyway, that created the opportunity to upgrade the package to use PHP 7.1 and typehints. But even with that in mind \u2026</p>\n<ul>\n<li>\n<p>You <em>do not</em> need to modify or regenerate any classes generated from 1.x (although if you have overridden class methods in custom classes, you <em>may</em> need to modify that code to add typehints).</p>\n</li>\n<li>\n<p>Atlas 2.x continues to use Aura.Sql and Aura.SqlQuery 2.x, so you <em>do not</em> need to change any queries from Atlas 1.x.</p>\n</li>\n<li>\n<p>You <em>do not</em> need to change any calls to AtlasContainer for setup.</p>\n</li>\n</ul>\n<p>So, the majority of existing code using Atlas 1.x should not have to change at all after upgrading to 2.x.</p>\n<p>III.</p>\n<p>There are some minor but breaking changes to the return values of some Atlas calls; these are a result of using typehints, especially nullable types.</p>\n<p>First, the following methods now return <code>null</code> (instead of <code>false</code>) when they fail:</p>\n<ul>\n<li>Atlas::fetchRecord()</li>\n<li>Atlas::fetchRecordBy()</li>\n<li>Mapper::fetchRecord()</li>\n<li>Mapper::fetchRecordBy()</li>\n<li>MapperSelect::fetchRecord()</li>\n<li>RecordSet::getOneBy()</li>\n<li>RecordSet::removeOneBy()</li>\n<li>Table::fetchRow()</li>\n<li>Table::updateRowPerform()</li>\n<li>TableSelect::fetchOne()</li>\n<li>TableSelect::fetchRow()</li>\n</ul>\n<p>Checking for loosely false-ish return values will continue to work in 2.x as it did in 1.x, but if you were checking strictly for <code>false</code> you now need to check strictly for <code>null</code> \u2013 or switch to loose checking. (Note that values for a missing <em>related</em> record field are still <code>false</code>, not <code>null</code>. That is, a related field value of <code>null</code> still indicates \u201cthere was no attempt to fetch a related record,\u201d while <code>false</code> still indicates \u201cthere was an attempt to fetch a related record, but it did not exist.\u201d)</p>\n<p>Second, the following methods will now <em>always</em> return a RecordSet, even when no records are found. (Previously, they would return an empty array when no records were found.)</p>\n<ul>\n<li>Atlas::fetchRecordSet()</li>\n<li>Atlas::fetchRecordSetBy()</li>\n<li>Mapper::fetchRecordSet()</li>\n<li>Mapper::fetchRecordSetBy()</li>\n<li>MapperSelect::fetchRecordSet()</li>\n</ul>\n<p>Whereas previously you would check for an empty array or loosely false-ish value as the return value, you should now call <code>isEmpty()</code> on the returned RecordSet.</p>\n<p>That is the extent of user-facing backwards compatibility breaks.</p>\n<p>IV.</p>\n<p>There is one major new piece in 2.x: the table-level ConnectionManager. It is in charge of transaction management for table operations, and allows easy setting of read and write connections to be used for specific tables if desired.</p>\n<p>It also allows for on-the-fly replacement of \u201cread\u201d connections with \u201cwrite\u201d connections. You can specify that this should\u2026</p>\n<ul>\n<li>\n<em>never</em> happen (the default)</li>\n<li>\n<em>always</em> happen (which is useful in GET-after-POST situations when latency is high for master-slave replication), or</li>\n<li>happen only when a table has started writing back to the database (which is useful for synchronizing reads with writes while in a transaction)</li>\n</ul>\n<p>Other than that, you should not have to deal with the ConnectionManager directly, but it\u2019s good to know what\u2019s going on under the hood.</p>\n<p>V.</p>\n<p>Although this is a major release, the user-facing backwards-compatibility changes are very limited, so it should be an easy migration from 1.x.  There is very little new functionality, so I\u2019m releasing this as a beta instead of an alpha. I have yet to update the official documentation site, but the in-package docs are fully up-to-date.</p>\n<p>I can think of no reason to expect significant API changes between now and a stable release, which should arrive in the next couple of weeks if there are no substantial bug reports.</p>\n<p>Thanks for reading, and I hope that <a href=\"https://github.com/atlasphp/Atlas.Orm\">Atlas</a> can help you out on your next project!</p>\n"
}
