This PR changes the `users#show` endpoint to use Diesel instead of
rust-postgres, (and adds a test for that endpoint). I chose that
endpoint as it seemed likely to touch as few things as possible, but
enough to require setting up Diesel connection pooling, and testing.
I have also ported over the migrations to use Diesel's migration
infrastructure. The migration files (except the final migration) were
generated programatically. Any non-reversible migrations were not dumped
as these contained procedural data updates which aren't relevant to
setting up a new database.
`cargo run --bin migrate` will move all the entries in the old
migrations table into the one used by Diesel. That function is brittle
since it relies on Diesel internals. However, it really only matters for
existing contributors (and one deploy to Heroku), so when that function
breaks we can just delete it.
I've added an additional migration to make the schema compatible with
`infer_schema!`, which doesn't support tables that have no primary key.
I'm not using `infer_schema!` just yet, as it doesn't work with non-core
types and there are some tsvector columns.
I re-ordered the columns on the `User` struct, as diesel emits an
explicit select clause and then fetches columns by index rather than by
name. This means that the order has to match how it was defined to
Diesel (which in the case of `infer_schema!` will be the database
definition order). If we don't want this restriction, we can replace the
`infer_schema!` call with manual `table!` calls (which can be
automatically generated by `diesel print-schema`), and have the columns
ordered there to match the struct.
Differences to note
-------------------
The rust-postgres connection is set to require TLS when the env var
`HEROKU` is set. In Diesel, this would be to add `?sslmode=require` onto
the database URL. I'm unsure if heroku-postgres URLs already have this
or not, so I have not added any explicit code for that. It's a question
that should be answered before this is deployed.
Additionally, I chose not to automatically wrap each request in a
transaction. It's unneccessary most of the time, and seems like it was
only done to make testing easier. Since Diesel has explicit support for
"run tests in a transaction that never commits", we don't need that
here.