The purpose of this is data safety. If there ever was a broken model
that corrupted data previously it would have ruined everything if it
coincided with a schema migration. Now this is much less likely.
This will be needed for database upgrades going forward. For example, an
old session without an update timestamp will not be visible in the index
that will soon be added. But since the UI will switch to that index, it
is paramount that all sessions are part of that.
The session model was built with that in mind, and has the corresponding
"update" logic. However, for that to matter old records first need to be
readded to the database.
It was gettig tedious to add the change tracking logic in all of the
methods. And since there likely will be many more such methods, I have
now extracted that bit into its own function.
As I noted in commit 85b9c2459c I noticed
that the testing of the invalidity of invalid struct "deserialization"
was not sound. That was because if one error was not actually thrown,
the test would still be satisfied by the following error. However, if
only that specific thing was wrong, no error would be thrown and an
invalid struct would be accepted.
Therefore I now changed those tests to also check the exception type and
its message. This means that if an exception is missing, it is
immediately picked up.
I also found out that one exception was actually wrong. I had mistyped
`TypeError` as `TypError`. Funnily enough that still causes an exception
to be thrown at that location, but a `ReferenceError` instead of the
`TypeError`. Such bugs should now be more easily noticable.