graph-node
graph-node copied to clipboard
Migrate to Diesel 2.0.0
Official announcement: https://diesel.rs/news/2_0_0_release.html Changelog: https://diesel.rs/changelog.html Migration guide: https://diesel.rs/guides/migration_guide.html
Migrating to Diesel 2.0.0 is desirable because we'd enjoy support for the latest features, as well as up-to-date community examples and guides. Some minor performance improvements are expected as well.
I'm providing a list of the main migration painpoints that are relevant for graph-node, identified during exploratory work in the filippo/diesel-2 branch. This list may not be complete and I haven't delved deep into some of these, thus I'm not sure how much more hidden complexity there is, if any. Checked items are those that I managed to fully resolve, unchecked items need more work (and they're by far the most complex).
-
[x] Derive attributes: all attributes in the form of
#[sql_type = "diesel::sql_types::Numeric"]must become#[diesel(sql_type = diesel::sql_types::Numeric)]. This is trivial and can be done via search and replace. -
[ ]
RunQueryDslmethods (and many others) now require mutable references to connections. I'd imagine this requires to turnConnection::conninto aMaybeOwnedMutand changing mostselfandconnreferences to mutable; we can also explore less intrusive solutions like aRefCell. -
[x]
.eq(any(...))calls should be replaced with.eq_any(...). See what the migration guide says. -
[x] Update
diesel-derive-enumto a Diesel 2.0.0 -compatible version (2.0.0.-rc.0is currently out, with2.0.0expected soon). -
[x] Update
diesel-dynamic-schemato>= 0.2.0. -
[x] Update
diesel_migrationsanddiesel_derivesto>= 2.0.0. -
[ ]
QueryFragment::walk_astnow takes extra lifetime parameters, e.g.:impl<'a> QueryFragment<Pg> for BlockRangeLowerBoundClause<'a> { fn walk_ast<'b>(&'b self, out: AstPass<'_, 'b, Pg>) -> QueryResult<()> { out.unsafe_to_cache_prepared(); out.push_sql("lower(x) = "); // ... Ok(()) } }This creates a problem when binding values, e.g.:
out.push_bind_param::<Text, _>(&s). While Diesel 1.4 would in this example require aString, Diesel 2.0 requires a&'b String. As far as I can tell, this means we must precompute all variables that we wish to bind and store them alongsideSelfupon its instantiation.Most of this also applies to all of our own methods and functions that take an
AstPass, even outside ofQueryFragmentimplementations. -
[ ] Slightly different type signature for the
ToSqlandFromSqltraits. While there's migration examples in the migration guide, I suspect there to be lifetime issues similar toQueryFragment. -
[x] Literal SQL (
diesel::dsl::sql) now requires an explicit type parameter in most situations, as it can't be inferred as easily. -
[x] Types that derive
diesel_derive_enum::DbEnum(onlySubgraphHealth, I believe) now needs the extra attribute#[DieselTypePath = "MappingType"]. Readdiesel_derive_enum's README for info. -
[x]
conn.execute(raw_query_string)now becomessql_query(raw_query_string).execute(conn). -
[x] Whenever doing a
ORDER BY count(*), the literal SQLsql::<Integer>("count(*)")hack to get around Diesel's aggregate rules doesn't seems to work anymore. Replacing the literal SQL withcount_star()and calling.group_by()before.select()seems to do the trick. -
[x]
DatabaseErrorKind::__Unknownis nowDatabaseErrorKind::Unknown. -
[ ] More restrictive type bounds for all
LoadQueryimplementors. This macro seems to provide the necessary trait implementations so that$typfalls under wildcard trait implementation rules:macro_rules! impl_load_query { ( $typ:ident ) => { impl<'a, Conn> RunQueryDsl<Conn> for $typ<'a> {} impl<'a> QueryId for $typ<'a> { type QueryId = (); const HAS_STATIC_QUERY_ID: bool = false; } impl<'a> Query for $typ<'a> { type SqlType = diesel::sql_types::Untyped; } }; }It compiles, but I haven't checked whether the resulting trait implementation behaves the same.