mountetna / magma

Data server with friendly data loaders
GNU General Public License v2.0
5 stars 2 forks source link

Consolidate Revision and RecordEntry classes #196

Open graft opened 3 years ago

graft commented 3 years ago

Recently we resolved #40, which changed the /update endpoint to use Magma::Loader. This created some rather difficult situations in the code, much coupling between classes and lack of clarity about who is doing what. Herein I will attempt to summarize some of these issues; I will briefly allude to the others.

The inputs to /update are wrapped in the Magma::Revision class, which previously would use Sequel::Model.update to handle making changes. Recently we replaced this with using the Magma::Loader class, which uses Sequel::Model.insert instead to do bulk insertions. The result is a data transit that looks something like this:

json => UpdateController => Revision => RecordEntry => entry hash => Sequel::Model.insert

Once the insertion is made, the results are reported out into a Magma::Payload:

Revision => Payload => json

However, this export is done via Revision, not Loader/RecordEntry.

Each of the transitions is managed by methods in the Attribute classes, which must transform each of the values in a record differently to accomplish each transition. The result is a lot of coupling: the controller, Revision, Loader and each of the attributes are all passed back and forth, and much ugliness ensues.

The main cause of this mess is the redundancy between the Revision class and the RecordEntry class. Crucially, the Revision wraps a single record (reflecting its use of the atomic Sequel::Model.update), while the Loader wraps the entire set of revisions, that is, a set of records for each model (reflecting its use of the bulk Sequel::Model.insert). The Loader, in fact, uses the RecordEntry class for wrapping individual records - this class is responsible for formulating the raw insertion hash used by insert. The Revision, therefore, must pass values into RecordEntry, which it does using the misnamed Magma::Attribute#revision_to_loader, while the RecordEntry formulates valid insertions using Magma::Attribute#entry.

To improve the situation, we may move whatever logic exists in Revision into RecordEntry, which can be instantiated directly in the UpdateController. The Revision and all of its associated Attribute methods can be removed - whatever careful formatting work remains can be done by Magma::Attribute#entry.

Since RecordEntry already receives the results of Sequel::Model.insert, the Loader may also now report directly out to the Payload, rather than having the more ignorant Revision attempt to do so.