Fix many-to-many
This commit is contained in:
parent
2948304df1
commit
5442ba6f2f
8 changed files with 162 additions and 89 deletions
|
@ -31,7 +31,12 @@ class JoinBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
String compile(Set<String> trampoline) {
|
String compile(Set<String> trampoline) {
|
||||||
if (to == null) return null;
|
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 b = StringBuffer();
|
||||||
var left = '${from.tableName}.$key';
|
var left = '${from.tableName}.$key';
|
||||||
var right = fieldName;
|
var right = fieldName;
|
||||||
|
@ -54,7 +59,7 @@ class JoinBuilder {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
b.write(' ${to()}');
|
b.write(' $compiledTo');
|
||||||
if (alias != null) b.write(' $alias');
|
if (alias != null) b.write(' $alias');
|
||||||
b.write(' ON $left$op$right');
|
b.write(' ON $left$op$right');
|
||||||
return b.toString();
|
return b.toString();
|
||||||
|
|
|
@ -219,6 +219,8 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
|
||||||
b.write(' ');
|
b.write(' ');
|
||||||
List<String> f;
|
List<String> f;
|
||||||
|
|
||||||
|
var compiledJoins = <JoinBuilder, String>{};
|
||||||
|
|
||||||
if (fields == null) {
|
if (fields == null) {
|
||||||
f = ['*'];
|
f = ['*'];
|
||||||
} else {
|
} else {
|
||||||
|
@ -229,10 +231,16 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
|
||||||
return ss;
|
return ss;
|
||||||
}));
|
}));
|
||||||
_joins.forEach((j) {
|
_joins.forEach((j) {
|
||||||
|
var c = compiledJoins[j] = j.compile(trampoline);
|
||||||
|
if (c != null) {
|
||||||
var additional = j.additionalFields.map(j.nameFor).toList();
|
var additional = j.additionalFields.map(j.nameFor).toList();
|
||||||
// if (!additional.contains(j.fieldName))
|
|
||||||
// additional.insert(0, j.fieldName);
|
|
||||||
f.addAll(additional);
|
f.addAll(additional);
|
||||||
|
} else {
|
||||||
|
// If compilation failed, fill in NULL placeholders.
|
||||||
|
for (var i = 0; i < j.additionalFields.length; i++) {
|
||||||
|
f.add('NULL');
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (withFields) b.write(f.join(', '));
|
if (withFields) b.write(f.join(', '));
|
||||||
|
@ -243,7 +251,7 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
|
||||||
if (preamble == null) {
|
if (preamble == null) {
|
||||||
if (_crossJoin != null) b.write(' CROSS JOIN $_crossJoin');
|
if (_crossJoin != null) b.write(' CROSS JOIN $_crossJoin');
|
||||||
for (var join in _joins) {
|
for (var join in _joins) {
|
||||||
var c = join.compile(trampoline);
|
var c = compiledJoins[join];
|
||||||
if (c != null) b.write(' $c');
|
if (c != null) b.write(' $c');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ import 'dart:async';
|
||||||
import 'package:analyzer/dart/constant/value.dart';
|
import 'package:analyzer/dart/constant/value.dart';
|
||||||
import 'package:analyzer/dart/element/element.dart';
|
import 'package:analyzer/dart/element/element.dart';
|
||||||
import 'package:analyzer/dart/element/type.dart';
|
import 'package:analyzer/dart/element/type.dart';
|
||||||
import 'package:analyzer/src/dart/constant/value.dart';
|
|
||||||
import 'package:angel_model/angel_model.dart';
|
import 'package:angel_model/angel_model.dart';
|
||||||
import 'package:angel_orm/angel_orm.dart';
|
import 'package:angel_orm/angel_orm.dart';
|
||||||
import 'package:angel_serialize/angel_serialize.dart';
|
import 'package:angel_serialize/angel_serialize.dart';
|
||||||
|
|
|
@ -281,6 +281,7 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
.assign(queryWhereType.newInstance([refer('this')])),
|
.assign(queryWhereType.newInstance([refer('this')])),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Note: this is where subquery fields for relations are added.
|
||||||
ctx.relations.forEach((fieldName, relation) {
|
ctx.relations.forEach((fieldName, relation) {
|
||||||
//var name = ctx.buildContext.resolveFieldName(fieldName);
|
//var name = ctx.buildContext.resolveFieldName(fieldName);
|
||||||
if (relation.type == RelationshipType.belongsTo ||
|
if (relation.type == RelationshipType.belongsTo ||
|
||||||
|
@ -289,15 +290,74 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
var foreign = relation.throughContext ?? relation.foreign;
|
var foreign = relation.throughContext ?? relation.foreign;
|
||||||
|
|
||||||
// If this is a many-to-many, add the fields from the other object.
|
// If this is a many-to-many, add the fields from the other object.
|
||||||
var additionalFields = relation.foreign.effectiveFields
|
|
||||||
// .where((f) => f.name != 'id' || !isSpecialId(ctx, f))
|
var additionalStrs = relation.foreign.effectiveFields.map((f) =>
|
||||||
.map((f) => literalString(relation.foreign.buildContext
|
relation.foreign.buildContext.resolveFieldName(f.name));
|
||||||
.resolveFieldName(f.name)));
|
var additionalFields = additionalStrs.map(literalString);
|
||||||
|
|
||||||
var joinArgs = [relation.localKey, relation.foreignKey]
|
var joinArgs = [relation.localKey, relation.foreignKey]
|
||||||
.map(literalString)
|
.map(literalString)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
|
// In the case of a many-to-many, we don't generate a subquery field,
|
||||||
|
// as it easily leads to stack overflows.
|
||||||
|
if (relation.isManyToMany) {
|
||||||
|
// We can't simply join against the "through" table; this itself must
|
||||||
|
// be a join.
|
||||||
|
// (SELECT role_users.role_id, <user_fields>
|
||||||
|
// FROM users
|
||||||
|
// LEFT JOIN role_users ON role_users.user_id=users.id)
|
||||||
|
var foreignFields = additionalStrs
|
||||||
|
.map((f) => '${relation.foreign.tableName}.$f');
|
||||||
|
var b = StringBuffer('(SELECT ');
|
||||||
|
// role_users.role_id
|
||||||
|
b.write('${relation.throughContext.tableName}');
|
||||||
|
b.write('.${relation.foreignKey}');
|
||||||
|
// , <user_fields>
|
||||||
|
b.write(foreignFields.isEmpty
|
||||||
|
? ''
|
||||||
|
: ', ' + foreignFields.join(', '));
|
||||||
|
// FROM users
|
||||||
|
b.write(' FROM ');
|
||||||
|
b.write(relation.foreign.tableName);
|
||||||
|
// LEFT JOIN role_users
|
||||||
|
b.write(' LEFT JOIN ${relation.throughContext.tableName}');
|
||||||
|
// Figure out which field on the "through" table points to users (foreign).
|
||||||
|
var throughRelation =
|
||||||
|
relation.throughContext.relations.values.firstWhere((e) {
|
||||||
|
return e.foreignTable == relation.foreign.tableName;
|
||||||
|
}, orElse: () {
|
||||||
|
// _Role has a many-to-many to _User through _RoleUser, but
|
||||||
|
// _RoleUser has no relation pointing to _User.
|
||||||
|
var b = StringBuffer();
|
||||||
|
b.write(ctx.buildContext.modelClassName);
|
||||||
|
b.write('has a many-to-many relationship to ');
|
||||||
|
b.write(relation.foreign.buildContext.modelClassName);
|
||||||
|
b.write(' through ');
|
||||||
|
b.write(
|
||||||
|
relation.throughContext.buildContext.modelClassName);
|
||||||
|
b.write(', but ');
|
||||||
|
b.write(
|
||||||
|
relation.throughContext.buildContext.modelClassName);
|
||||||
|
b.write('has no relation pointing to ');
|
||||||
|
b.write(relation.foreign.buildContext.modelClassName);
|
||||||
|
b.write('.');
|
||||||
|
throw b.toString();
|
||||||
|
});
|
||||||
|
|
||||||
|
// ON role_users.user_id=users.id)
|
||||||
|
b.write(' ON ');
|
||||||
|
b.write('${relation.throughContext.tableName}');
|
||||||
|
b.write('.');
|
||||||
|
b.write(throughRelation.localKey);
|
||||||
|
b.write('=');
|
||||||
|
b.write(relation.foreign.tableName);
|
||||||
|
b.write('.');
|
||||||
|
b.write(throughRelation.foreignKey);
|
||||||
|
b.write(')');
|
||||||
|
|
||||||
|
joinArgs.insert(0, literalString(b.toString()));
|
||||||
|
} else {
|
||||||
// In the past, we would either do a join on the table name
|
// In the past, we would either do a join on the table name
|
||||||
// itself, or create an instance of a query.
|
// itself, or create an instance of a query.
|
||||||
//
|
//
|
||||||
|
@ -305,7 +365,7 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
// join, so that users can customize the generated query.
|
// join, so that users can customize the generated query.
|
||||||
//
|
//
|
||||||
// There'll be a private `_field`, and then a getter, named `field`,
|
// There'll be a private `_field`, and then a getter, named `field`,
|
||||||
// that returns the subqueryb object.
|
// that returns the subquery object.
|
||||||
var foreignQueryType = refer(
|
var foreignQueryType = refer(
|
||||||
foreign.buildContext.modelClassNameRecase.pascalCase +
|
foreign.buildContext.modelClassNameRecase.pascalCase +
|
||||||
'Query');
|
'Query');
|
||||||
|
@ -326,6 +386,7 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
});
|
});
|
||||||
joinArgs.insert(
|
joinArgs.insert(
|
||||||
0, refer('_$fieldName').assign(queryInstantiation));
|
0, refer('_$fieldName').assign(queryInstantiation));
|
||||||
|
}
|
||||||
|
|
||||||
var joinType = relation.joinTypeString;
|
var joinType = relation.joinTypeString;
|
||||||
b.addExpression(refer(joinType).call(joinArgs, {
|
b.addExpression(refer(joinType).call(joinArgs, {
|
||||||
|
|
|
@ -3,6 +3,7 @@ import 'dart:io';
|
||||||
import 'package:angel_orm/angel_orm.dart';
|
import 'package:angel_orm/angel_orm.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
import 'models/user.dart';
|
import 'models/user.dart';
|
||||||
|
import 'util.dart';
|
||||||
|
|
||||||
manyToManyTests(FutureOr<QueryExecutor> Function() createExecutor,
|
manyToManyTests(FutureOr<QueryExecutor> Function() createExecutor,
|
||||||
{FutureOr<void> Function(QueryExecutor) close}) {
|
{FutureOr<void> Function(QueryExecutor) close}) {
|
||||||
|
@ -61,6 +62,7 @@ manyToManyTests(FutureOr<QueryExecutor> Function() createExecutor,
|
||||||
print('=== THOSAKWE: ${thosakwe?.toJson()}');
|
print('=== THOSAKWE: ${thosakwe?.toJson()}');
|
||||||
|
|
||||||
// Allow thosakwe to publish...
|
// Allow thosakwe to publish...
|
||||||
|
printSeparator('Allow thosakwe to publish');
|
||||||
var thosakwePubQuery = RoleUserQuery();
|
var thosakwePubQuery = RoleUserQuery();
|
||||||
thosakwePubQuery.values
|
thosakwePubQuery.values
|
||||||
..userId = int.parse(thosakwe.id)
|
..userId = int.parse(thosakwe.id)
|
||||||
|
@ -68,6 +70,7 @@ manyToManyTests(FutureOr<QueryExecutor> Function() createExecutor,
|
||||||
await thosakwePubQuery.insert(executor);
|
await thosakwePubQuery.insert(executor);
|
||||||
|
|
||||||
// Allow thosakwe to subscribe...
|
// Allow thosakwe to subscribe...
|
||||||
|
printSeparator('Allow thosakwe to subscribe');
|
||||||
var thosakweSubQuery = RoleUserQuery();
|
var thosakweSubQuery = RoleUserQuery();
|
||||||
thosakweSubQuery.values
|
thosakweSubQuery.values
|
||||||
..userId = int.parse(thosakwe.id)
|
..userId = int.parse(thosakwe.id)
|
||||||
|
@ -78,8 +81,8 @@ manyToManyTests(FutureOr<QueryExecutor> Function() createExecutor,
|
||||||
// await dumpQuery('select * from users;');
|
// await dumpQuery('select * from users;');
|
||||||
// await dumpQuery('select * from roles;');
|
// await dumpQuery('select * from roles;');
|
||||||
// await dumpQuery('select * from role_users;');
|
// await dumpQuery('select * from role_users;');
|
||||||
var query = RoleQuery()..where.id.equals(canPub.idAsInt);
|
// var query = RoleQuery()..where.id.equals(canPub.idAsInt);
|
||||||
await dumpQuery(query.compile(Set()));
|
// await dumpQuery(query.compile(Set()));
|
||||||
|
|
||||||
print('\n');
|
print('\n');
|
||||||
print('==================================================');
|
print('==================================================');
|
||||||
|
@ -95,6 +98,7 @@ manyToManyTests(FutureOr<QueryExecutor> Function() createExecutor,
|
||||||
}
|
}
|
||||||
|
|
||||||
test('fetch roles for user', () async {
|
test('fetch roles for user', () async {
|
||||||
|
printSeparator('Fetch roles for user test');
|
||||||
var user = await fetchThosakwe();
|
var user = await fetchThosakwe();
|
||||||
expect(user.roles, hasLength(2));
|
expect(user.roles, hasLength(2));
|
||||||
expect(user.roles, contains(canPub));
|
expect(user.roles, contains(canPub));
|
||||||
|
@ -108,4 +112,21 @@ manyToManyTests(FutureOr<QueryExecutor> Function() createExecutor,
|
||||||
expect(r.users.toList(), [thosakwe]);
|
expect(r.users.toList(), [thosakwe]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('only fetches linked', () async {
|
||||||
|
// Create a new user. The roles list should be empty,
|
||||||
|
// be there are no related rules.
|
||||||
|
var userQuery = UserQuery();
|
||||||
|
userQuery.values
|
||||||
|
..username = 'Prince'
|
||||||
|
..password = 'Rogers'
|
||||||
|
..email = 'Nelson';
|
||||||
|
var user = await userQuery.insert(executor);
|
||||||
|
expect(user.roles, isEmpty);
|
||||||
|
|
||||||
|
// Fetch again, just to be doubly sure.
|
||||||
|
var query = UserQuery()..where.id.equals(user.idAsInt);
|
||||||
|
var fetched = await query.getOne(executor);
|
||||||
|
expect(fetched.roles, isEmpty);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,8 +64,10 @@ class RoleQuery extends Query<Role, RoleQueryWhere> {
|
||||||
trampoline ??= Set();
|
trampoline ??= Set();
|
||||||
trampoline.add(tableName);
|
trampoline.add(tableName);
|
||||||
_where = RoleQueryWhere(this);
|
_where = RoleQueryWhere(this);
|
||||||
leftJoin(_users = RoleUserQuery(trampoline: trampoline, parent: this),
|
leftJoin(
|
||||||
'role', 'role_role',
|
'(SELECT role_users.role_role , users.email, users.name, users.password FROM users LEFT JOIN role_users ON role_users.user_email=users.email)',
|
||||||
|
'role',
|
||||||
|
'role_role',
|
||||||
additionalFields: const ['email', 'name', 'password'],
|
additionalFields: const ['email', 'name', 'password'],
|
||||||
trampoline: trampoline);
|
trampoline: trampoline);
|
||||||
}
|
}
|
||||||
|
@ -75,8 +77,6 @@ class RoleQuery extends Query<Role, RoleQueryWhere> {
|
||||||
|
|
||||||
RoleQueryWhere _where;
|
RoleQueryWhere _where;
|
||||||
|
|
||||||
RoleUserQuery _users;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
get casts {
|
get casts {
|
||||||
return {};
|
return {};
|
||||||
|
@ -119,10 +119,6 @@ class RoleQuery extends Query<Role, RoleQueryWhere> {
|
||||||
return parseRow(row);
|
return parseRow(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
RoleUserQuery get users {
|
|
||||||
return _users;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool canCompile(trampoline) {
|
bool canCompile(trampoline) {
|
||||||
return (!(trampoline.contains('roles') &&
|
return (!(trampoline.contains('roles') &&
|
||||||
|
@ -338,9 +334,12 @@ class UserQuery extends Query<User, UserQueryWhere> {
|
||||||
trampoline ??= Set();
|
trampoline ??= Set();
|
||||||
trampoline.add(tableName);
|
trampoline.add(tableName);
|
||||||
_where = UserQueryWhere(this);
|
_where = UserQueryWhere(this);
|
||||||
leftJoin(_roles = RoleUserQuery(trampoline: trampoline, parent: this),
|
leftJoin(
|
||||||
'email', 'user_email',
|
'(SELECT role_users.user_email , roles.role FROM roles LEFT JOIN role_users ON role_users.role_role=roles.role)',
|
||||||
additionalFields: const ['role'], trampoline: trampoline);
|
'email',
|
||||||
|
'user_email',
|
||||||
|
additionalFields: const ['role'],
|
||||||
|
trampoline: trampoline);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -348,8 +347,6 @@ class UserQuery extends Query<User, UserQueryWhere> {
|
||||||
|
|
||||||
UserQueryWhere _where;
|
UserQueryWhere _where;
|
||||||
|
|
||||||
RoleUserQuery _roles;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
get casts {
|
get casts {
|
||||||
return {};
|
return {};
|
||||||
|
@ -395,10 +392,6 @@ class UserQuery extends Query<User, UserQueryWhere> {
|
||||||
return parseRow(row);
|
return parseRow(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
RoleUserQuery get roles {
|
|
||||||
return _roles;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool canCompile(trampoline) {
|
bool canCompile(trampoline) {
|
||||||
return (!(trampoline.contains('users') &&
|
return (!(trampoline.contains('users') &&
|
||||||
|
|
|
@ -208,9 +208,12 @@ class WeirdJoinQuery extends Query<WeirdJoin, WeirdJoinQueryWhere> {
|
||||||
leftJoin(_numbas = NumbaQuery(trampoline: trampoline, parent: this), 'id',
|
leftJoin(_numbas = NumbaQuery(trampoline: trampoline, parent: this), 'id',
|
||||||
'parent',
|
'parent',
|
||||||
additionalFields: const ['i', 'parent'], trampoline: trampoline);
|
additionalFields: const ['i', 'parent'], trampoline: trampoline);
|
||||||
leftJoin(_foos = FooPivotQuery(trampoline: trampoline, parent: this), 'id',
|
leftJoin(
|
||||||
|
'(SELECT foo_pivots.weird_join_id , foos.bar FROM foos LEFT JOIN foo_pivots ON foo_pivots.foo_bar=foos.bar)',
|
||||||
|
'id',
|
||||||
'weird_join_id',
|
'weird_join_id',
|
||||||
additionalFields: const ['bar'], trampoline: trampoline);
|
additionalFields: const ['bar'],
|
||||||
|
trampoline: trampoline);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -224,8 +227,6 @@ class WeirdJoinQuery extends Query<WeirdJoin, WeirdJoinQueryWhere> {
|
||||||
|
|
||||||
NumbaQuery _numbas;
|
NumbaQuery _numbas;
|
||||||
|
|
||||||
FooPivotQuery _foos;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
get casts {
|
get casts {
|
||||||
return {};
|
return {};
|
||||||
|
@ -294,10 +295,6 @@ class WeirdJoinQuery extends Query<WeirdJoin, WeirdJoinQueryWhere> {
|
||||||
return _numbas;
|
return _numbas;
|
||||||
}
|
}
|
||||||
|
|
||||||
FooPivotQuery get foos {
|
|
||||||
return _foos;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool canCompile(trampoline) {
|
bool canCompile(trampoline) {
|
||||||
return (!(trampoline.contains('weird_joins') &&
|
return (!(trampoline.contains('weird_joins') &&
|
||||||
|
@ -612,9 +609,12 @@ class FooQuery extends Query<Foo, FooQueryWhere> {
|
||||||
trampoline ??= Set();
|
trampoline ??= Set();
|
||||||
trampoline.add(tableName);
|
trampoline.add(tableName);
|
||||||
_where = FooQueryWhere(this);
|
_where = FooQueryWhere(this);
|
||||||
leftJoin(_weirdJoins = FooPivotQuery(trampoline: trampoline, parent: this),
|
leftJoin(
|
||||||
'bar', 'foo_bar',
|
'(SELECT foo_pivots.foo_bar , weird_joins.id, weird_joins.join_name FROM weird_joins LEFT JOIN foo_pivots ON foo_pivots.weird_join_id=weird_joins.id)',
|
||||||
additionalFields: const ['id', 'join_name'], trampoline: trampoline);
|
'bar',
|
||||||
|
'foo_bar',
|
||||||
|
additionalFields: const ['id', 'join_name'],
|
||||||
|
trampoline: trampoline);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -622,8 +622,6 @@ class FooQuery extends Query<Foo, FooQueryWhere> {
|
||||||
|
|
||||||
FooQueryWhere _where;
|
FooQueryWhere _where;
|
||||||
|
|
||||||
FooPivotQuery _weirdJoins;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
get casts {
|
get casts {
|
||||||
return {};
|
return {};
|
||||||
|
@ -666,10 +664,6 @@ class FooQuery extends Query<Foo, FooQueryWhere> {
|
||||||
return parseRow(row);
|
return parseRow(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
FooPivotQuery get weirdJoins {
|
|
||||||
return _weirdJoins;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool canCompile(trampoline) {
|
bool canCompile(trampoline) {
|
||||||
return (!(trampoline.contains('foos') &&
|
return (!(trampoline.contains('foos') &&
|
||||||
|
|
|
@ -66,7 +66,9 @@ class UserQuery extends Query<User, UserQueryWhere> {
|
||||||
trampoline ??= Set();
|
trampoline ??= Set();
|
||||||
trampoline.add(tableName);
|
trampoline.add(tableName);
|
||||||
_where = UserQueryWhere(this);
|
_where = UserQueryWhere(this);
|
||||||
leftJoin(_roles = RoleUserQuery(trampoline: trampoline, parent: this), 'id',
|
leftJoin(
|
||||||
|
'(SELECT role_users.user_id , roles.id, roles.created_at, roles.updated_at, roles.name FROM roles LEFT JOIN role_users ON role_users.role_id=roles.id)',
|
||||||
|
'id',
|
||||||
'user_id',
|
'user_id',
|
||||||
additionalFields: const ['id', 'created_at', 'updated_at', 'name'],
|
additionalFields: const ['id', 'created_at', 'updated_at', 'name'],
|
||||||
trampoline: trampoline);
|
trampoline: trampoline);
|
||||||
|
@ -77,8 +79,6 @@ class UserQuery extends Query<User, UserQueryWhere> {
|
||||||
|
|
||||||
UserQueryWhere _where;
|
UserQueryWhere _where;
|
||||||
|
|
||||||
RoleUserQuery _roles;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
get casts {
|
get casts {
|
||||||
return {};
|
return {};
|
||||||
|
@ -134,10 +134,6 @@ class UserQuery extends Query<User, UserQueryWhere> {
|
||||||
return parseRow(row);
|
return parseRow(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
RoleUserQuery get roles {
|
|
||||||
return _roles;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool canCompile(trampoline) {
|
bool canCompile(trampoline) {
|
||||||
return (!(trampoline.contains('users') &&
|
return (!(trampoline.contains('users') &&
|
||||||
|
@ -405,7 +401,9 @@ class RoleQuery extends Query<Role, RoleQueryWhere> {
|
||||||
trampoline ??= Set();
|
trampoline ??= Set();
|
||||||
trampoline.add(tableName);
|
trampoline.add(tableName);
|
||||||
_where = RoleQueryWhere(this);
|
_where = RoleQueryWhere(this);
|
||||||
leftJoin(_users = RoleUserQuery(trampoline: trampoline, parent: this), 'id',
|
leftJoin(
|
||||||
|
'(SELECT role_users.role_id , users.id, users.created_at, users.updated_at, users.username, users.password, users.email FROM users LEFT JOIN role_users ON role_users.user_id=users.id)',
|
||||||
|
'id',
|
||||||
'role_id',
|
'role_id',
|
||||||
additionalFields: const [
|
additionalFields: const [
|
||||||
'id',
|
'id',
|
||||||
|
@ -423,8 +421,6 @@ class RoleQuery extends Query<Role, RoleQueryWhere> {
|
||||||
|
|
||||||
RoleQueryWhere _where;
|
RoleQueryWhere _where;
|
||||||
|
|
||||||
RoleUserQuery _users;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
get casts {
|
get casts {
|
||||||
return {};
|
return {};
|
||||||
|
@ -471,10 +467,6 @@ class RoleQuery extends Query<Role, RoleQueryWhere> {
|
||||||
return parseRow(row);
|
return parseRow(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
RoleUserQuery get users {
|
|
||||||
return _users;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool canCompile(trampoline) {
|
bool canCompile(trampoline) {
|
||||||
return (!(trampoline.contains('roles') &&
|
return (!(trampoline.contains('roles') &&
|
||||||
|
|
Loading…
Reference in a new issue