toMap method
toMap returns a map
Implementation
@override
Future<List<Map<String?, dynamic>>> toMap() async {
if (_offset != null && _limit == null) {
return throw UnsupportedError(
'You need to pass LIMIT when using OFFSET\n'
'Use: dao.limit(x).offset(x) instead of dao.offset(x)',
);
}
if (_having.isNotEmpty && _group.isEmpty) {
return throw UnsupportedError(
'You need to pass GROUP BY when using HAVING\n'
'Use: dao.having(x).group(x) instead of dao.having(x)',
);
}
if (_or.isNotEmpty && _where.isEmpty) {
return throw UnsupportedError(
'You need to pass WHERE when using OR\n'
'Use: dao.where(x).or(x) instead of dao.or(x)',
);
}
final builder = _copyQueryWith();
final completer = Completer<List<Map<String, dynamic>>>()
..complete(database!.rawQuery(builder.sql, builder.arguments));
if (isLogger!) Logger.query(type, completer.future, builder);
/// use mapping to convert `QueryRow` into `Map` so we can edit that list
final items = await completer.future.then(
(values) => values.map((value) {
var item = Map<String?, dynamic>.from(value);
/// Search for any join to convert join to nested attributes
for (final relation in relations) {
final join = _joins.find((join) => join.type == relation.dao!.type);
final include =
_includes.find((include) => include!.type == relation.dao!.type);
if (join != null) item.nest('${join.type}'.toCamelCase());
/// nest item if no include
if (include == null) {
final foreignKey = schema.foreignKeys.find(
(fk) => fk.reference!.table == relation.dao!.schema.table,
);
if (foreignKey != null) {
item.nest('${relation.dao!.type}'.toCamelCase());
}
}
}
return item;
}).toList(),
);
/// include associations
for (final include in _includes) {
final Relation<DataAccessObject<dynamic>>? relation = relations.find(
(relation) => relation.dao!.schema.table == include!.schema.table);
if (kDebugMode) {
print(relation);
}
if (relation is BelongsTo) {
final foreignKey = schema.foreignKeys.find(
(fk) => fk.reference!.table == include!.schema.table,
);
/// collect ids to avoid duplication
final foreignKeys =
items.map((item) => item[foreignKey!.parent]).toSet().toList();
// if not empty
if (foreignKeys.isNotEmpty) {
/// if length is only one record then use a simple where statment
if (foreignKeys.length == 1) {
include!.where({include.schema.primaryKey: foreignKeys.first});
}
/// else use where in
else {
include!.where({
'${include.schema.primaryKey} IN (${List.filled(foreignKeys.length, '?').join(',')})':
foreignKeys
}).limit(foreignKeys.length);
}
final associations = await include.toMap();
/// add all associations to object for
for (final item in items) {
final Map<String?, dynamic>? association = associations.find(
(association) {
final primaryKey = association[include.schema.primaryKey];
/// search for `primaryKey` that matches item `foreignKey`
return primaryKey == item[foreignKey!.parent];
},
);
item['${include.type}'.toCamelCase()] = association;
}
}
} else {
final foreignKey = relation!.dao!.schema.foreignKeys.find(
(fk) => fk.reference!.table == schema.table,
);
/// collect ids to avoid duplication
final primaryKeys =
items.map((item) => item[schema.primaryKey]).toSet().toList();
// if not empty
if (primaryKeys.isNotEmpty) {
/// if length is only one record then use a simple where statment
if (primaryKeys.length == 1) {
include!.where({foreignKey!.parent: primaryKeys.first});
} else {
include!.where({
'${foreignKey!.parent} IN (${List.filled(primaryKeys.length, '?').join(',')})':
primaryKeys
}).limit(primaryKeys.length);
}
final associations = await include.toMap();
for (final item in items) {
/// assign association to parent
if (relation is HasOne) {
item['${include.type}'.toCamelCase()] = associations.find(
(association) {
/// search for `primaryKey` that matches item `foreignKey`
return association[include.schema.primaryKey] ==
item[include.schema.primaryKey];
},
);
}
// just removed || relation is ProxyHasMany
else if (relation is HasMany) {
item[include.schema.table] = associations;
}
if (kDebugMode) {
print('item: $item');
}
}
}
}
break;
}
clear();
return items;
}