| 1652 | } |
| 1653 | |
| 1654 | func (g *graph) clearM2MEdges(ctx context.Context, ids []driver.Value, edges EdgeSpecs) error { |
| 1655 | // Remove all M2M edges from the same type at once. |
| 1656 | // The EdgeSpec is the same for all members in a group. |
| 1657 | tables := edges.GroupTable() |
| 1658 | for _, table := range edgeKeys(tables) { |
| 1659 | edges := tables[table] |
| 1660 | preds := make([]*sql.Predicate, 0, len(edges)) |
| 1661 | for _, edge := range edges { |
| 1662 | fromC, toC := edge.Columns[0], edge.Columns[1] |
| 1663 | if edge.Inverse { |
| 1664 | fromC, toC = toC, fromC |
| 1665 | } |
| 1666 | // If there are no specific edges (to target-nodes) to remove, |
| 1667 | // clear all edges that go out (or come in) from the nodes. |
| 1668 | if len(edge.Target.Nodes) == 0 { |
| 1669 | preds = append(preds, matchID(fromC, ids)) |
| 1670 | if edge.Bidi { |
| 1671 | preds = append(preds, matchID(toC, ids)) |
| 1672 | } |
| 1673 | } else { |
| 1674 | pk1, pk2 := ids, edge.Target.Nodes |
| 1675 | preds = append(preds, matchIDs(fromC, pk1, toC, pk2)) |
| 1676 | if edge.Bidi { |
| 1677 | preds = append(preds, matchIDs(toC, pk1, fromC, pk2)) |
| 1678 | } |
| 1679 | } |
| 1680 | } |
| 1681 | deleter := g.builder.Delete(table).Where(sql.Or(preds...)) |
| 1682 | if edges[0].Schema != "" { |
| 1683 | // If the Schema field was provided to the EdgeSpec (by the |
| 1684 | // generated code), it should be the same for all EdgeSpecs. |
| 1685 | deleter.Schema(edges[0].Schema) |
| 1686 | } |
| 1687 | query, args := deleter.Query() |
| 1688 | if err := g.tx.Exec(ctx, query, args, nil); err != nil { |
| 1689 | return fmt.Errorf("remove m2m edge for table %s: %w", table, err) |
| 1690 | } |
| 1691 | } |
| 1692 | return nil |
| 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. |