platform/angel_orm/lib/src/join_builder.dart
2019-10-12 14:36:24 -04:00

71 lines
1.8 KiB
Dart

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();
}
}