Merge the new (simpler and more robust) versioning and refactoring functionality into the main branch.
A few notes on the design:
state transitions for the Signature objects attached to a storage are encapsulated in the new SigAdapter class that groups together responsibilities that were previously scattered across the RelAdapter and Storage classes
every change to the schema on the client side is immediately synchronized with the server. That is, the current "ground truth" signatures are pulled from the server and applied to the local storage, and only then does the schema change from the client get applied (if it is compatible with the updated state). This way, any schema change is validated for compatibility against the current "true" state of the schema.
This precludes a few more complex / less desirable scenarios that could be possible under a delayed sync design, where clients would have to resolve "merge conflicts" (e.g., if two clients rename the same function in different ways), or could otherwise end up in states requiring extra logic to sync.
the client waits for the server to successfully write the new signatures before committing changes to the local database. This precludes clients from computing with schemas that have not been acknowledged by (and so potentially not persisted on) the server. This precludes another class of merge conflicts (where e.g. two users locally define functions with the same name, but get issued different UIDs for the two).
Merge the new (simpler and more robust) versioning and refactoring functionality into the main branch.
A few notes on the design:
Signature
objects attached to a storage are encapsulated in the newSigAdapter
class that groups together responsibilities that were previously scattered across theRelAdapter
andStorage
classes