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
|
# 2.1.0-beta
|
||||||
* Split the formerly 600+ line `src/query.dart` up into
|
* Split the formerly 600+ line `src/query.dart` up into
|
||||||
separate files.
|
separate files.
|
||||||
|
|
|
@ -6,6 +6,7 @@ class JoinBuilder {
|
||||||
final JoinType type;
|
final JoinType type;
|
||||||
final Query from;
|
final Query from;
|
||||||
final String key, value, op, alias;
|
final String key, value, op, alias;
|
||||||
|
final bool aliasAllFields;
|
||||||
|
|
||||||
/// A callback to produces the expression to join against, i.e.
|
/// A callback to produces the expression to join against, i.e.
|
||||||
/// a table name, or the result of compiling a query.
|
/// a table name, or the result of compiling a query.
|
||||||
|
@ -13,34 +14,37 @@ class JoinBuilder {
|
||||||
final List<String> additionalFields;
|
final List<String> additionalFields;
|
||||||
|
|
||||||
JoinBuilder(this.type, this.from, this.to, this.key, this.value,
|
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,
|
assert(to != null,
|
||||||
'computation of this join threw an error, and returned null.');
|
'computation of this join threw an error, and returned null.');
|
||||||
}
|
}
|
||||||
|
|
||||||
String get fieldName {
|
String get fieldName {
|
||||||
var right = '$to.$value';
|
var v = value;
|
||||||
if (alias != null) right = '$alias.$value';
|
if (aliasAllFields) {
|
||||||
|
v = '${alias}_$v';
|
||||||
|
}
|
||||||
|
var right = '${from.tableName}.$v';
|
||||||
|
if (alias != null) right = '$alias.$v';
|
||||||
return right;
|
return right;
|
||||||
}
|
}
|
||||||
|
|
||||||
String nameFor(String name) {
|
String nameFor(String name) {
|
||||||
var right = '$to.$name';
|
if (aliasAllFields) name = '${alias}_$name';
|
||||||
|
var right = '${from.tableName}.$name';
|
||||||
if (alias != null) right = '$alias.$name';
|
if (alias != null) right = '$alias.$name';
|
||||||
return right;
|
return right;
|
||||||
}
|
}
|
||||||
|
|
||||||
String compile(Set<String> trampoline) {
|
String compile(Set<String> trampoline) {
|
||||||
var compiledTo = to();
|
var compiledTo = to();
|
||||||
if (compiledTo == null) {
|
|
||||||
print(
|
|
||||||
'NULLLLL $to; from $from; key: $key, value: $value, addl: $additionalFields');
|
|
||||||
}
|
|
||||||
if (compiledTo == null) return null;
|
if (compiledTo == null) return null;
|
||||||
var b = StringBuffer();
|
var b = StringBuffer();
|
||||||
var left = '${from.tableName}.$key';
|
var left = '${from.tableName}.$key';
|
||||||
var right = fieldName;
|
var right = fieldName;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case JoinType.inner:
|
case JoinType.inner:
|
||||||
b.write(' INNER JOIN');
|
b.write(' INNER JOIN');
|
||||||
|
|
|
@ -151,10 +151,17 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
|
||||||
|
|
||||||
var to = _compileJoin(tableName, trampoline);
|
var to = _compileJoin(tableName, trampoline);
|
||||||
if (to != null) {
|
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,
|
_joins.add(JoinBuilder(type, this, to, localKey, foreignKey,
|
||||||
op: op,
|
op: op,
|
||||||
alias: _joinAlias(trampoline),
|
alias: alias,
|
||||||
additionalFields: additionalFields));
|
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 ss = includeTableName ? '$tableName.$s' : s;
|
||||||
var cast = casts[s];
|
var cast = casts[s];
|
||||||
if (cast != null) ss = 'CAST ($ss AS $cast)';
|
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;
|
return ss;
|
||||||
}));
|
}));
|
||||||
_joins.forEach((j) {
|
_joins.forEach((j) {
|
||||||
|
|
|
@ -7,6 +7,9 @@ abstract class QueryBase<T> {
|
||||||
/// Casts to perform when querying the database.
|
/// Casts to perform when querying the database.
|
||||||
Map<String, String> get casts => {};
|
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.
|
/// Values to insert into a prepared statement.
|
||||||
final Map<String, dynamic> substitutionValues = {};
|
final Map<String, dynamic> substitutionValues = {};
|
||||||
|
|
||||||
|
@ -21,7 +24,12 @@ abstract class QueryBase<T> {
|
||||||
/// A String of all [fields], joined by a comma (`,`).
|
/// A String of all [fields], joined by a comma (`,`).
|
||||||
String get fieldSet => fields.map((k) {
|
String get fieldSet => fields.map((k) {
|
||||||
var cast = casts[k];
|
var cast = casts[k];
|
||||||
|
if (!aliases.containsKey(k)) {
|
||||||
return cast == null ? k : 'CAST ($k AS $cast)';
|
return cast == null ? k : 'CAST ($k AS $cast)';
|
||||||
|
} else {
|
||||||
|
var inner = cast == null ? k : '(CAST ($k AS $cast))';
|
||||||
|
return '$inner AS ${aliases[k]}';
|
||||||
|
}
|
||||||
}).join(', ');
|
}).join(', ');
|
||||||
|
|
||||||
String compile(Set<String> trampoline,
|
String compile(Set<String> trampoline,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
name: angel_orm
|
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.
|
description: Runtime support for Angel's ORM. Includes base classes for queries.
|
||||||
author: Tobe O <thosakwe@gmail.com>
|
author: Tobe O <thosakwe@gmail.com>
|
||||||
homepage: https://github.com/angel-dart/orm
|
homepage: https://github.com/angel-dart/orm
|
||||||
|
|
Loading…
Reference in a new issue