Improve attribute tracking, allow update of PKs

By capturing the original value of the attributes and allowing to commit
or reset them as desired, the code becomes simpler and we allow
ourselves to constrain record-scoped queries to the **original** value
of their primary keys. This is important so that users don't
accidentally find themselves doing something like:

    record1 = repo.fetch(1)
    record2 = repo.fetch(2)
    record1.id = 2
    repo.delete(record1) # Actually deletes record2

It also allows us to let users change values of primary keys and have an
update query run properly (assuming, of course, no constraints are
violated by the changes).