Factor sqlalchemy out of job_listener()

Add functions for updating jobs in the db to db.py, refactor
web.job_listener() to call these instead of doing its own sqlalchemy.

This is another step towards encapsulating the db code in db.py.

This makes it clearer (from looking at db.py) what the model actually is
- what db tables and columns we have, and how they change over time in
different conditions. Things like "mark a job as completed successfully" and
"mark as job as failed with an error" are now a small set of nice functions
with names and docstrings.

This also makes the job_listener() code shorter and much more readable.
Factor sqlalchemy out of run_synchronous_job()

Refactor web.run_synchronous_job() to call db.py's new methods for
updating jobs, instead of constructing its own dict and calling
web.update_job().

This makes run_synchronous_job() much simpler and easier to read.

Delete web.update_job(), no longer used.