import 'annotations.dart'; import 'query.dart'; /// Builds a SQL `JOIN` query. class JoinBuilder { final JoinType type; final Query from; final String key, value, op, alias; final bool aliasAllFields; /// A callback to produces the expression to join against, i.e. /// a table name, or the result of compiling a query. final String Function() to; final List<String> additionalFields; JoinBuilder(this.type, this.from, this.to, this.key, this.value, {this.op = '=', this.alias, this.additionalFields = const [], this.aliasAllFields = false}) { assert(to != null, 'computation of this join threw an error, and returned null.'); } String get fieldName { var v = value; if (aliasAllFields) { v = '${alias}_$v'; } var right = '${from.tableName}.$v'; if (alias != null) right = '$alias.$v'; return right; } String nameFor(String name) { if (aliasAllFields) name = '${alias}_$name'; var right = '${from.tableName}.$name'; if (alias != null) right = '$alias.$name'; return right; } String compile(Set<String> trampoline) { var compiledTo = to(); if (compiledTo == null) return null; var b = StringBuffer(); var left = '${from.tableName}.$key'; var right = fieldName; switch (type) { case JoinType.inner: b.write(' INNER JOIN'); break; case JoinType.left: b.write(' LEFT JOIN'); break; case JoinType.right: b.write(' RIGHT JOIN'); break; case JoinType.full: b.write(' FULL OUTER JOIN'); break; case JoinType.self: b.write(' SELF JOIN'); break; } b.write(' $compiledTo'); if (alias != null) b.write(' $alias'); b.write(' ON $left$op$right'); return b.toString(); } }