insert method
Method insert same as create but expects a map entry
Implementation
@override
Future<dynamic> insert(Map<String?, Object?> values) async {
Map<String, Object?>? mapValue = values.cast<String, Object?>();
Future<dynamic> call() async {
final builder = SqlBuilder.insert(schema.table!, mapValue);
final completer = Completer<dynamic>()
..complete(database!.rawInsert(builder.sql, builder.arguments));
if (isLogger!) Logger.insert(type, completer.future, builder);
final id = await completer.future;
// assign primary key to values if not exists
if (values[schema.primaryKey!] == null) values[schema.primaryKey!] = id;
/// assign primary key to values
return values[schema.primaryKey!];
}
for (final relation in relations) {
if (relation is BelongsTo) {
if (kDebugMode) {
print('$type ${relation.runtimeType}');
}
if (kDebugMode) {
print('values $values');
}
final association = values.remove('${relation.dao!.type}'.toCamelCase())
as Map<String?, dynamic>?;
if (association != null) {
final Relation<DataAccessObject<dynamic>>? assocationRelation =
relation.dao!.relations
.find((rel) => rel.dao!.schema.table == schema.table);
/// Convert relation to [has-one] or [has-many]
/// and use insert which will trigger later the relation
if (assocationRelation is HasOne) {
association['$type'.toCamelCase()] = values;
} else if (assocationRelation is HasMany) {
association[schema.table] = [values];
}
return relation.dao!.insert(association);
}
} else if (relation is HasOne) {
if (kDebugMode) {
print('$type ${relation.runtimeType}');
}
final association = values.remove('${relation.dao!.type}'.toCamelCase())
as Map<String?, dynamic>?;
/// insert master will add id into values
await call();
if (values[schema.primaryKey] == -1) {
return throw Exception(
'Something went wrong while inserting $runtimeType',
);
}
if (association != null) {
final foreignKey = relation.dao!.schema.foreignKeys.find(
(fk) => fk.reference!.table == schema.table,
);
if (foreignKey != null) {
association[foreignKey.parent] = values[schema.primaryKey];
await relation.dao!.insert(association);
/// Set `null` relation attribute to avoid `null` exception while converting
values['$relation.dao.type}'.toCamelCase()] = null;
// master['$type'.toCamelCase()] = association;
/// add association to master
// values['$type'.toCamelCase()] =await relation.dao.insert(association);
// print();
if (kDebugMode) {
print(association);
}
return values[schema.primaryKey];
} else {
throw Exception(
'''
$runtimeType: could not find foreign key for ${schema.table}\n
Make sure to add HasOne<${relation.dao!.type}> in $runtimeType
''',
);
}
}
} else if (relation is HasMany) {
if (kDebugMode) {
print('$runtimeType has_many ${relation.dao!.type} via '
'${relation.dao!.schema.table}');
}
/// Make sure to remove `relation` object from master
final associations = values.remove(relation.dao!.schema.table)
as List<Map<String?, dynamic>>?;
/// insert master will fill id in values
await call();
/// make sure that insert was success
if (values[schema.primaryKey] == -1) {
return throw Exception(
'Something went wrong while inserting $runtimeType',
);
}
if (associations != null) {
/// load foreign key
final foreignKey = relation.dao!.schema.foreignKeys.find(
(fk) => fk.reference!.table == schema.table,
);
if (foreignKey != null) {
for (final association in associations) {
association[foreignKey.parent] = values[schema.primaryKey];
}
// association['$type'.toCamelCase()] = values;
await relation.dao!.insertAll(associations);
/// Set empty relation attribute to avoid `null` exception while converting
values[relation.dao!.schema.table] = [];
return values[schema.primaryKey];
} else {
throw Exception(
'''
$runtimeType: could not find foreign key for ${schema.table}
Make sure to add HasMany<${relation.dao!.type}> in $runtimeType
''',
);
}
}
}
}
return call();
}