| 1693 | } |
| 1694 | |
| 1695 | func (g *graph) addM2MEdges(ctx context.Context, ids []driver.Value, edges EdgeSpecs) error { |
| 1696 | // Insert all M2M edges from the same type at once. |
| 1697 | // The EdgeSpec is the same for all members in a group. |
| 1698 | tables := edges.GroupTable() |
| 1699 | for _, table := range edgeKeys(tables) { |
| 1700 | var ( |
| 1701 | edges = tables[table] |
| 1702 | columns = edges[0].Columns |
| 1703 | values = make([]any, 0, len(edges[0].Target.Fields)) |
| 1704 | ) |
| 1705 | // Additional fields, such as edge-schema fields. Note, we use the first index, |
| 1706 | // because Ent generates the same spec fields for all edges from the same type. |
| 1707 | for _, f := range edges[0].Target.Fields { |
| 1708 | values = append(values, f.Value) |
| 1709 | columns = append(columns, f.Column) |
| 1710 | } |
| 1711 | insert := g.builder.Insert(table).Columns(columns...) |
| 1712 | if edges[0].Schema != "" { |
| 1713 | // If the Schema field was provided to the EdgeSpec (by the |
| 1714 | // generated code), it should be the same for all EdgeSpecs. |
| 1715 | insert.Schema(edges[0].Schema) |
| 1716 | } |
| 1717 | for _, edge := range edges { |
| 1718 | pk1, pk2 := ids, edge.Target.Nodes |
| 1719 | if edge.Inverse { |
| 1720 | pk1, pk2 = pk2, pk1 |
| 1721 | } |
| 1722 | for _, pair := range product(pk1, pk2) { |
| 1723 | insert.Values(append([]any{pair[0], pair[1]}, values...)...) |
| 1724 | if edge.Bidi { |
| 1725 | insert.Values(append([]any{pair[1], pair[0]}, values...)...) |
| 1726 | } |
| 1727 | } |
| 1728 | } |
| 1729 | // Ignore conflicts only if edges do not contain extra fields, because these fields |
| 1730 | // can hold different values on different insertions (e.g. time.Now() or uuid.New()). |
| 1731 | if len(edges[0].Target.Fields) == 0 { |
| 1732 | insert.OnConflict(sql.DoNothing()) |
| 1733 | } |
| 1734 | query, args := insert.Query() |
| 1735 | if err := g.tx.Exec(ctx, query, args, nil); err != nil { |
| 1736 | return fmt.Errorf("add m2m edge for table %s: %w", table, err) |
| 1737 | } |
| 1738 | } |
| 1739 | return nil |
| 1740 | } |
| 1741 | |
| 1742 | func (g *graph) batchAddM2M(ctx context.Context, spec *BatchCreateSpec) error { |
| 1743 | tables := make(map[string]*sql.InsertBuilder) |