The database abstraction makes use of "handles", which represent a row in the database (e.g. a user account or character). The data is read from the database into the instance, can then be worked with in the rest of the codebase, and if there were any changes, they are written back to the database in the handle's destructor.
This model relies on the assumption that at any given moment in time, there cannot be two handles of the same entry active; if they were, there would be conflicts and those could lead to bugs.
The code has been written already with this in mind, but in this set of changes, we introduce a runtime check that enforces that constraint. If it is violated, the code will CHECK-fail. We also had to fix some parts of the code that actually violated the assumption, although mostly with read-only handles and in tests.
The database abstraction makes use of "handles", which represent a row in the database (e.g. a user account or character). The data is read from the database into the instance, can then be worked with in the rest of the codebase, and if there were any changes, they are written back to the database in the handle's destructor.
This model relies on the assumption that at any given moment in time, there cannot be two handles of the same entry active; if they were, there would be conflicts and those could lead to bugs.
The code has been written already with this in mind, but in this set of changes, we introduce a runtime check that enforces that constraint. If it is violated, the code will
CHECK
-fail. We also had to fix some parts of the code that actually violated the assumption, although mostly with read-only handles and in tests.