Alias all fields in child queries
This commit is contained in:
parent
2a8a186bca
commit
8222230c8a
5 changed files with 43 additions and 13 deletions
|
@ -1,3 +1,7 @@
|
|||
# 2.1.0-beta.1
|
||||
* Calls to `leftJoin`, etc. alias all fields in a child query, to prevent
|
||||
`ambiguous column a0.id` errors.
|
||||
|
||||
# 2.1.0-beta
|
||||
* Split the formerly 600+ line `src/query.dart` up into
|
||||
separate files.
|
||||
|
|
|
@ -6,6 +6,7 @@ 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.
|
||||
|
@ -13,34 +14,37 @@ class JoinBuilder {
|
|||
final List<String> additionalFields;
|
||||
|
||||
JoinBuilder(this.type, this.from, this.to, this.key, this.value,
|
||||
{this.op = '=', this.alias, this.additionalFields = const []}) {
|
||||
{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 right = '$to.$value';
|
||||
if (alias != null) right = '$alias.$value';
|
||||
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) {
|
||||
var right = '$to.$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) {
|
||||
print(
|
||||
'NULLLLL $to; from $from; key: $key, value: $value, addl: $additionalFields');
|
||||
}
|
||||
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');
|
||||
|
|
|
@ -151,10 +151,17 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
|
|||
|
||||
var to = _compileJoin(tableName, trampoline);
|
||||
if (to != null) {
|
||||
var alias = _joinAlias(trampoline);
|
||||
if (tableName is Query) {
|
||||
for (var field in tableName.fields) {
|
||||
tableName.aliases[field] = '${alias}_$field';
|
||||
}
|
||||
}
|
||||
_joins.add(JoinBuilder(type, this, to, localKey, foreignKey,
|
||||
op: op,
|
||||
alias: _joinAlias(trampoline),
|
||||
additionalFields: additionalFields));
|
||||
alias: alias,
|
||||
additionalFields: additionalFields,
|
||||
aliasAllFields: tableName is Query));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -228,6 +235,13 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
|
|||
var ss = includeTableName ? '$tableName.$s' : s;
|
||||
var cast = casts[s];
|
||||
if (cast != null) ss = 'CAST ($ss AS $cast)';
|
||||
if (aliases.containsKey(s)) {
|
||||
if (cast != null) {
|
||||
ss = '($ss) AS ${aliases[s]}';
|
||||
} else {
|
||||
ss = '$ss AS ${aliases[s]}';
|
||||
}
|
||||
}
|
||||
return ss;
|
||||
}));
|
||||
_joins.forEach((j) {
|
||||
|
|
|
@ -7,6 +7,9 @@ abstract class QueryBase<T> {
|
|||
/// Casts to perform when querying the database.
|
||||
Map<String, String> get casts => {};
|
||||
|
||||
/// `AS` aliases to inject into the query, if any.
|
||||
Map<String, String> aliases = {};
|
||||
|
||||
/// Values to insert into a prepared statement.
|
||||
final Map<String, dynamic> substitutionValues = {};
|
||||
|
||||
|
@ -21,7 +24,12 @@ abstract class QueryBase<T> {
|
|||
/// A String of all [fields], joined by a comma (`,`).
|
||||
String get fieldSet => fields.map((k) {
|
||||
var cast = casts[k];
|
||||
return cast == null ? k : 'CAST ($k AS $cast)';
|
||||
if (!aliases.containsKey(k)) {
|
||||
return cast == null ? k : 'CAST ($k AS $cast)';
|
||||
} else {
|
||||
var inner = cast == null ? k : '(CAST ($k AS $cast))';
|
||||
return '$inner AS ${aliases[k]}';
|
||||
}
|
||||
}).join(', ');
|
||||
|
||||
String compile(Set<String> trampoline,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
name: angel_orm
|
||||
version: 2.1.0-beta
|
||||
version: 2.1.0-beta.1
|
||||
description: Runtime support for Angel's ORM. Includes base classes for queries.
|
||||
author: Tobe O <thosakwe@gmail.com>
|
||||
homepage: https://github.com/angel-dart/orm
|
||||
|
|
Loading…
Reference in a new issue