insert method

  1. @override
Future insert(
  1. Map<String?, Object?> values
)
override

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();
}