drift icon indicating copy to clipboard operation
drift copied to clipboard

Dart selects: Make chaining more fluent

Open simolus3 opened this issue 5 years ago • 1 comments

Currently, to form a more complicated Dart query, one would write

(select(table)
  ..orderBy([(row) => OrderingTerm.asc(row.id)])
  ..limit(10))
  .watch();

That's not good, but it quickly gets worse when using joins and mapping the result query:

return ((select(table)
          ..orderBy([(row) => OrderingTerm.asc(row.content.length)])
          ..where((row) => row.id.isBetweenValues(5, 40)))
        .join([innerJoin(another, another.foo.equalsExp(table.bar)])
          ..limit(10))
    .map((r) => r.readTable(another))
    .watchSingle();

Even though it's discouraged by "Efficient Dart", I'd argue this query would be much easier to write when ignoring avoid_returning_this. If orderBy, where and limit just returned their instances, nesting would be removed entirely:

return select(table)
  .orderBy([(row) => OrderingTerm.asc(row.content.length)])
  .where((row) => row.id.isBetweenValues(5, 40))
  .join([innerJoin(another, another.foo.equalsExp(table.bar)])
  .limit(10)
  .map((r) => r.readTable(another))
  .watchSingle();

simolus3 avatar Jan 23 '20 14:01 simolus3

Hm, dartfmt is weird with list literals in method chains:

await db
    .select(todos)
    .where((t) => t.id.isSmallerThanValue(3))
    .orderBy([(t) => OrderingTerm(expression: t.title)]).join([
  innerJoin(categories, categories.id.equalsExp(todos.category))
]).get();

This kind of defeats the whole purpose - maybe we should just recommend to split complex queries into multiple statements...

simolus3 avatar Jan 23 '20 18:01 simolus3