github.com/Ali-iotechsys/sqlboiler/v4@v4.0.0-20221208124957-6aec9a5f1f71/templates/main/12_relationship_to_many_setops.go.tpl (about)

     1  {{- if or .Table.IsJoinTable .Table.IsView -}}
     2  {{- else -}}
     3  	{{- $table := .Table -}}
     4  	{{- range $rel := .Table.ToManyRelationships -}}
     5  		{{- $ltable := $.Aliases.Table $rel.Table -}}
     6  		{{- $ftable := $.Aliases.Table $rel.ForeignTable -}}
     7  		{{- $relAlias := $.Aliases.ManyRelationship $rel.ForeignTable $rel.Name $rel.JoinTable $rel.JoinLocalFKeyName -}}
     8  		{{- $col := $ltable.Column $rel.Column -}}
     9  		{{- $fcol := $ftable.Column $rel.ForeignColumn -}}
    10  		{{- $usesPrimitives := usesPrimitives $.Tables $rel.Table $rel.Column $rel.ForeignTable $rel.ForeignColumn -}}
    11  		{{- $schemaForeignTable := $rel.ForeignTable | $.SchemaTable }}
    12  		{{- $foreignPKeyCols := (getTable $.Tables $rel.ForeignTable).PKey.Columns }}
    13  {{if $.AddGlobal -}}
    14  // Add{{$relAlias.Local}}G adds the given related objects to the existing relationships
    15  // of the {{$table.Name | singular}}, optionally inserting them as new records.
    16  // Appends related to o.R.{{$relAlias.Local}}.
    17  {{- if not $.NoBackReferencing}}
    18  // Sets related.R.{{$relAlias.Foreign}} appropriately.
    19  {{- end}}
    20  // Uses the global database handle.
    21  func (o *{{$ltable.UpSingular}}) Add{{$relAlias.Local}}G({{if not $.NoContext}}ctx context.Context, {{end -}} insert bool, related ...*{{$ftable.UpSingular}}) error {
    22  	return o.Add{{$relAlias.Local}}({{if $.NoContext}}boil.GetDB(){{else}}ctx, boil.GetContextDB(){{end}}, insert, related...)
    23  }
    24  
    25  {{end -}}
    26  
    27  {{if $.AddPanic -}}
    28  // Add{{$relAlias.Local}}P adds the given related objects to the existing relationships
    29  // of the {{$table.Name | singular}}, optionally inserting them as new records.
    30  // Appends related to o.R.{{$relAlias.Local}}.
    31  {{- if not $.NoBackReferencing}}
    32  // Sets related.R.{{$relAlias.Foreign}} appropriately.
    33  {{- end}}
    34  // Panics on error.
    35  func (o *{{$ltable.UpSingular}}) Add{{$relAlias.Local}}P({{if $.NoContext}}exec boil.Executor{{else}}ctx context.Context, exec boil.ContextExecutor{{end}}, insert bool, related ...*{{$ftable.UpSingular}}) {
    36  	if err := o.Add{{$relAlias.Local}}({{if not $.NoContext}}ctx, {{end -}} exec, insert, related...); err != nil {
    37  		panic(boil.WrapErr(err))
    38  	}
    39  }
    40  
    41  {{end -}}
    42  
    43  {{if and $.AddGlobal $.AddPanic -}}
    44  // Add{{$relAlias.Local}}GP adds the given related objects to the existing relationships
    45  // of the {{$table.Name | singular}}, optionally inserting them as new records.
    46  // Appends related to o.R.{{$relAlias.Local}}.
    47  {{- if not $.NoBackReferencing}}
    48  // Sets related.R.{{$relAlias.Foreign}} appropriately.
    49  {{- end}}
    50  // Uses the global database handle and panics on error.
    51  func (o *{{$ltable.UpSingular}}) Add{{$relAlias.Local}}GP({{if not $.NoContext}}ctx context.Context, {{end -}} insert bool, related ...*{{$ftable.UpSingular}}) {
    52  	if err := o.Add{{$relAlias.Local}}({{if $.NoContext}}boil.GetDB(){{else}}ctx, boil.GetContextDB(){{end}}, insert, related...); err != nil {
    53  		panic(boil.WrapErr(err))
    54  	}
    55  }
    56  
    57  {{end -}}
    58  
    59  // Add{{$relAlias.Local}} adds the given related objects to the existing relationships
    60  // of the {{$table.Name | singular}}, optionally inserting them as new records.
    61  // Appends related to o.R.{{$relAlias.Local}}.
    62  {{- if not $.NoBackReferencing}}
    63  // Sets related.R.{{$relAlias.Foreign}} appropriately.
    64  {{- end}}
    65  func (o *{{$ltable.UpSingular}}) Add{{$relAlias.Local}}({{if $.NoContext}}exec boil.Executor{{else}}ctx context.Context, exec boil.ContextExecutor{{end}}, insert bool, related ...*{{$ftable.UpSingular}}) error {
    66  	var err error
    67  	for _, rel := range related {
    68  		if insert {
    69  			{{if not .ToJoinTable -}}
    70  				{{if $usesPrimitives -}}
    71  			rel.{{$fcol}} = o.{{$col}}
    72  				{{else -}}
    73  			queries.Assign(&rel.{{$fcol}}, o.{{$col}})
    74  				{{end -}}
    75  			{{end -}}
    76  
    77  			if err = rel.Insert({{if not $.NoContext}}ctx, {{end -}} exec, boil.Infer()); err != nil {
    78  				return errors.Wrap(err, "failed to insert into foreign table")
    79  			}
    80  		}{{if not .ToJoinTable}} else {
    81  			updateQuery := fmt.Sprintf(
    82  				"UPDATE {{$schemaForeignTable}} SET %s WHERE %s",
    83  				strmangle.SetParamNames("{{$.LQ}}", "{{$.RQ}}", {{if $.Dialect.UseIndexPlaceholders}}1{{else}}0{{end}}, []string{{"{"}}"{{.ForeignColumn}}"{{"}"}}),
    84  				strmangle.WhereClause("{{$.LQ}}", "{{$.RQ}}", {{if $.Dialect.UseIndexPlaceholders}}2{{else}}0{{end}}, {{$ftable.DownSingular}}PrimaryKeyColumns),
    85  			)
    86  			values := []interface{}{o.{{$col}}, rel.{{$foreignPKeyCols | stringMap (aliasCols $ftable) | join ", rel."}}{{"}"}}
    87  
    88  			{{if $.NoContext -}}
    89  			if boil.DebugMode {
    90  				fmt.Fprintln(boil.DebugWriter, updateQuery)
    91  				fmt.Fprintln(boil.DebugWriter, values)
    92  			}
    93  			{{else -}}
    94  			if boil.IsDebug(ctx) {
    95  		writer := boil.DebugWriterFrom(ctx)
    96  				fmt.Fprintln(writer, updateQuery)
    97  				fmt.Fprintln(writer, values)
    98  			}
    99  			{{end -}}
   100  
   101  			{{if $.NoContext -}}
   102  			if _, err = exec.Exec(updateQuery, values...); err != nil {
   103  			{{else -}}
   104  			if _, err = exec.ExecContext(ctx, updateQuery, values...); err != nil {
   105  			{{end -}}
   106  				return errors.Wrap(err, "failed to update foreign table")
   107  			}
   108  
   109  			{{if $usesPrimitives -}}
   110  			rel.{{$fcol}} = o.{{$col}}
   111  			{{else -}}
   112  			queries.Assign(&rel.{{$fcol}}, o.{{$col}})
   113  			{{end -}}
   114  		}{{end -}}
   115  	}
   116  
   117  	{{if .ToJoinTable -}}
   118  	for _, rel := range related {
   119  		query := "insert into {{.JoinTable | $.SchemaTable}} ({{.JoinLocalColumn | $.Quotes}}, {{.JoinForeignColumn | $.Quotes}}) values {{if $.Dialect.UseIndexPlaceholders}}($1, $2){{else}}(?, ?){{end}}"
   120  		values := []interface{}{{"{"}}o.{{$col}}, rel.{{$fcol}}}
   121  
   122  		{{if $.NoContext -}}
   123  		if boil.DebugMode {
   124  			fmt.Fprintln(boil.DebugWriter, query)
   125  			fmt.Fprintln(boil.DebugWriter, values)
   126  		}
   127  		{{else -}}
   128  		if boil.IsDebug(ctx) {
   129  		writer := boil.DebugWriterFrom(ctx)
   130  			fmt.Fprintln(writer, query)
   131  			fmt.Fprintln(writer, values)
   132  		}
   133  		{{end -}}
   134  
   135  		{{if $.NoContext -}}
   136  		_, err = exec.Exec(query, values...)
   137  		{{else -}}
   138  		_, err = exec.ExecContext(ctx, query, values...)
   139  		{{end -}}
   140  		if err != nil {
   141  			return errors.Wrap(err, "failed to insert into join table")
   142  		}
   143  	}
   144  	{{end -}}
   145  
   146  	if o.R == nil {
   147  		o.R = &{{$ltable.DownSingular}}R{
   148  			{{$relAlias.Local}}: related,
   149  		}
   150  	} else {
   151  		o.R.{{$relAlias.Local}} = append(o.R.{{$relAlias.Local}}, related...)
   152  	}
   153  
   154  	{{if not $.NoBackReferencing -}}
   155  	{{if .ToJoinTable -}}
   156  	for _, rel := range related {
   157  		if rel.R == nil {
   158  			rel.R = &{{$ftable.DownSingular}}R{
   159  				{{$relAlias.Foreign}}: {{$ltable.UpSingular}}Slice{{"{"}}o{{"}"}},
   160  			}
   161  		} else {
   162  			rel.R.{{$relAlias.Foreign}} = append(rel.R.{{$relAlias.Foreign}}, o)
   163  		}
   164  	}
   165  	{{else -}}
   166  	for _, rel := range related {
   167  		if rel.R == nil {
   168  			rel.R = &{{$ftable.DownSingular}}R{
   169  				{{$relAlias.Foreign}}: o,
   170  			}
   171  		} else {
   172  			rel.R.{{$relAlias.Foreign}} = o
   173  		}
   174  	}
   175  	{{end -}}
   176  	{{end -}}
   177  
   178  	return nil
   179  }
   180  
   181  			{{- if (or .ForeignColumnNullable .ToJoinTable)}}
   182  {{if $.AddGlobal -}}
   183  // Set{{$relAlias.Local}}G removes all previously related items of the
   184  // {{$table.Name | singular}} replacing them completely with the passed
   185  // in related items, optionally inserting them as new records.
   186  // Sets o.R.{{$relAlias.Foreign}}'s {{$relAlias.Local}} accordingly.
   187  // Replaces o.R.{{$relAlias.Local}} with related.
   188  {{- if not $.NoBackReferencing}}
   189  // Sets related.R.{{$relAlias.Foreign}}'s {{$relAlias.Local}} accordingly.
   190  {{- end}}
   191  // Uses the global database handle.
   192  func (o *{{$ltable.UpSingular}}) Set{{$relAlias.Local}}G({{if not $.NoContext}}ctx context.Context, {{end -}} insert bool, related ...*{{$ftable.UpSingular}}) error {
   193  	return o.Set{{$relAlias.Local}}({{if $.NoContext}}boil.GetDB(){{else}}ctx, boil.GetContextDB(){{end}}, insert, related...)
   194  }
   195  
   196  {{end -}}
   197  
   198  {{if $.AddPanic -}}
   199  // Set{{$relAlias.Local}}P removes all previously related items of the
   200  // {{$table.Name | singular}} replacing them completely with the passed
   201  // in related items, optionally inserting them as new records.
   202  // Sets o.R.{{$relAlias.Foreign}}'s {{$relAlias.Local}} accordingly.
   203  // Replaces o.R.{{$relAlias.Local}} with related.
   204  {{- if not $.NoBackReferencing}}
   205  // Sets related.R.{{$relAlias.Foreign}}'s {{$relAlias.Local}} accordingly.
   206  {{- end}}
   207  // Panics on error.
   208  func (o *{{$ltable.UpSingular}}) Set{{$relAlias.Local}}P({{if $.NoContext}}exec boil.Executor{{else}}ctx context.Context, exec boil.ContextExecutor{{end}}, insert bool, related ...*{{$ftable.UpSingular}}) {
   209  	if err := o.Set{{$relAlias.Local}}({{if not $.NoContext}}ctx, {{end -}} exec, insert, related...); err != nil {
   210  		panic(boil.WrapErr(err))
   211  	}
   212  }
   213  
   214  {{end -}}
   215  
   216  {{if and $.AddGlobal $.AddPanic -}}
   217  // Set{{$relAlias.Local}}GP removes all previously related items of the
   218  // {{$table.Name | singular}} replacing them completely with the passed
   219  // in related items, optionally inserting them as new records.
   220  // Sets o.R.{{$relAlias.Foreign}}'s {{$relAlias.Local}} accordingly.
   221  // Replaces o.R.{{$relAlias.Local}} with related.
   222  {{- if not $.NoBackReferencing}}
   223  // Sets related.R.{{$relAlias.Foreign}}'s {{$relAlias.Local}} accordingly.
   224  {{- end}}
   225  // Uses the global database handle and panics on error.
   226  func (o *{{$ltable.UpSingular}}) Set{{$relAlias.Local}}GP({{if not $.NoContext}}ctx context.Context, {{end -}} insert bool, related ...*{{$ftable.UpSingular}}) {
   227  	if err := o.Set{{$relAlias.Local}}({{if $.NoContext}}boil.GetDB(){{else}}ctx, boil.GetContextDB(){{end}}, insert, related...); err != nil {
   228  		panic(boil.WrapErr(err))
   229  	}
   230  }
   231  
   232  {{end -}}
   233  
   234  // Set{{$relAlias.Local}} removes all previously related items of the
   235  // {{$table.Name | singular}} replacing them completely with the passed
   236  // in related items, optionally inserting them as new records.
   237  // Sets o.R.{{$relAlias.Foreign}}'s {{$relAlias.Local}} accordingly.
   238  // Replaces o.R.{{$relAlias.Local}} with related.
   239  {{- if not $.NoBackReferencing}}
   240  // Sets related.R.{{$relAlias.Foreign}}'s {{$relAlias.Local}} accordingly.
   241  {{- end}}
   242  func (o *{{$ltable.UpSingular}}) Set{{$relAlias.Local}}({{if $.NoContext}}exec boil.Executor{{else}}ctx context.Context, exec boil.ContextExecutor{{end}}, insert bool, related ...*{{$ftable.UpSingular}}) error {
   243  	{{if .ToJoinTable -}}
   244  	query := "delete from {{.JoinTable | $.SchemaTable}} where {{.JoinLocalColumn | $.Quotes}} = {{if $.Dialect.UseIndexPlaceholders}}$1{{else}}?{{end}}"
   245  	values := []interface{}{{"{"}}o.{{$col}}}
   246  	{{else -}}
   247  	query := "update {{.ForeignTable | $.SchemaTable}} set {{.ForeignColumn | $.Quotes}} = null where {{.ForeignColumn | $.Quotes}} = {{if $.Dialect.UseIndexPlaceholders}}$1{{else}}?{{end}}"
   248  	values := []interface{}{{"{"}}o.{{$col}}}
   249  	{{end -}}
   250  	{{if $.NoContext -}}
   251  	if boil.DebugMode {
   252  		fmt.Fprintln(boil.DebugWriter, query)
   253  		fmt.Fprintln(boil.DebugWriter, values)
   254  	}
   255  	{{else -}}
   256  	if boil.IsDebug(ctx) {
   257  		writer := boil.DebugWriterFrom(ctx)
   258  		fmt.Fprintln(writer, query)
   259  		fmt.Fprintln(writer, values)
   260  	}
   261  	{{end -}}
   262  
   263  	{{if $.NoContext -}}
   264  	_, err := exec.Exec(query, values...)
   265  	{{else -}}
   266  	_, err := exec.ExecContext(ctx, query, values...)
   267  	{{end -}}
   268  	if err != nil {
   269  		return errors.Wrap(err, "failed to remove relationships before set")
   270  	}
   271  
   272  	{{if and .ToJoinTable (not $.NoBackReferencing) -}}
   273  	remove{{$relAlias.Local}}From{{$relAlias.Foreign}}Slice(o, related)
   274  	if o.R != nil {
   275  		o.R.{{$relAlias.Local}} = nil
   276  	}
   277  	{{else -}}
   278  	if o.R != nil {
   279  		{{if not $.NoBackReferencing -}}
   280  		for _, rel := range o.R.{{$relAlias.Local}} {
   281  			queries.SetScanner(&rel.{{$fcol}}, nil)
   282  			if rel.R == nil {
   283  				continue
   284  			}
   285  
   286  			rel.R.{{$relAlias.Foreign}} = nil
   287  		}
   288  		{{end -}}
   289  
   290  		o.R.{{$relAlias.Local}} = nil
   291  	}
   292  	{{- end}}
   293  
   294  	return o.Add{{$relAlias.Local}}({{if not $.NoContext}}ctx, {{end -}} exec, insert, related...)
   295  }
   296  
   297  {{if $.AddGlobal -}}
   298  // Remove{{$relAlias.Local}}G relationships from objects passed in.
   299  // Removes related items from R.{{$relAlias.Local}} (uses pointer comparison, removal does not keep order)
   300  {{- if not $.NoBackReferencing}}
   301  // Sets related.R.{{$relAlias.Foreign}}.
   302  {{- end}}
   303  // Uses the global database handle.
   304  func (o *{{$ltable.UpSingular}}) Remove{{$relAlias.Local}}G({{if not $.NoContext}}ctx context.Context, {{end -}} related ...*{{$ftable.UpSingular}}) error {
   305  	return o.Remove{{$relAlias.Local}}({{if $.NoContext}}boil.GetDB(){{else}}ctx, boil.GetContextDB(){{end}}, related...)
   306  }
   307  
   308  {{end -}}
   309  
   310  {{if $.AddPanic -}}
   311  // Remove{{$relAlias.Local}}P relationships from objects passed in.
   312  // Removes related items from R.{{$relAlias.Local}} (uses pointer comparison, removal does not keep order)
   313  {{- if not $.NoBackReferencing}}
   314  // Sets related.R.{{$relAlias.Foreign}}.
   315  {{- end}}
   316  // Panics on error.
   317  func (o *{{$ltable.UpSingular}}) Remove{{$relAlias.Local}}P({{if $.NoContext}}exec boil.Executor{{else}}ctx context.Context, exec boil.ContextExecutor{{end}}, related ...*{{$ftable.UpSingular}}) {
   318  	if err := o.Remove{{$relAlias.Local}}({{if not $.NoContext}}ctx, {{end -}} exec, related...); err != nil {
   319  		panic(boil.WrapErr(err))
   320  	}
   321  }
   322  
   323  {{end -}}
   324  
   325  {{if and $.AddGlobal $.AddPanic -}}
   326  // Remove{{$relAlias.Local}}GP relationships from objects passed in.
   327  // Removes related items from R.{{$relAlias.Local}} (uses pointer comparison, removal does not keep order)
   328  {{- if not $.NoBackReferencing}}
   329  // Sets related.R.{{$relAlias.Foreign}}.
   330  {{- end}}
   331  // Uses the global database handle and panics on error.
   332  func (o *{{$ltable.UpSingular}}) Remove{{$relAlias.Local}}GP({{if not $.NoContext}}ctx context.Context, {{end -}} related ...*{{$ftable.UpSingular}}) {
   333  	if err := o.Remove{{$relAlias.Local}}({{if $.NoContext}}boil.GetDB(){{else}}ctx, boil.GetContextDB(){{end}}, related...); err != nil {
   334  		panic(boil.WrapErr(err))
   335  	}
   336  }
   337  
   338  {{end -}}
   339  
   340  // Remove{{$relAlias.Local}} relationships from objects passed in.
   341  // Removes related items from R.{{$relAlias.Local}} (uses pointer comparison, removal does not keep order)
   342  {{- if not $.NoBackReferencing}}
   343  // Sets related.R.{{$relAlias.Foreign}}.
   344  {{- end}}
   345  func (o *{{$ltable.UpSingular}}) Remove{{$relAlias.Local}}({{if $.NoContext}}exec boil.Executor{{else}}ctx context.Context, exec boil.ContextExecutor{{end}}, related ...*{{$ftable.UpSingular}}) error {
   346  	if len(related) == 0 {
   347  		return nil
   348  	}
   349  
   350  	var err error
   351  	{{if .ToJoinTable -}}
   352  	query := fmt.Sprintf(
   353  		"delete from {{.JoinTable | $.SchemaTable}} where {{.JoinLocalColumn | $.Quotes}} = {{if $.Dialect.UseIndexPlaceholders}}$1{{else}}?{{end}} and {{.JoinForeignColumn | $.Quotes}} in (%s)",
   354  		strmangle.Placeholders(dialect.UseIndexPlaceholders, len(related), 2, 1),
   355  	)
   356  	values := []interface{}{{"{"}}o.{{$col}}}
   357  	for _, rel := range related {
   358  		values = append(values, rel.{{$fcol}})
   359  	}
   360  
   361  	{{if $.NoContext -}}
   362  	if boil.DebugMode {
   363  		fmt.Fprintln(boil.DebugWriter, query)
   364  		fmt.Fprintln(boil.DebugWriter, values)
   365  	}
   366  	{{else -}}
   367  	if boil.IsDebug(ctx) {
   368  		writer := boil.DebugWriterFrom(ctx)
   369  		fmt.Fprintln(writer, query)
   370  		fmt.Fprintln(writer, values)
   371  	}
   372  	{{end -}}
   373  
   374  	{{if $.NoContext -}}
   375  	_, err = exec.Exec(query, values...)
   376  	{{else -}}
   377  	_, err = exec.ExecContext(ctx, query, values...)
   378  	{{end -}}
   379  	if err != nil {
   380  		return errors.Wrap(err, "failed to remove relationships before set")
   381  	}
   382  	{{else -}}
   383  	for _, rel := range related {
   384  		queries.SetScanner(&rel.{{$fcol}}, nil)
   385  		{{if and (not .ToJoinTable) (not $.NoBackReferencing) -}}
   386  		if rel.R != nil {
   387  			rel.R.{{$relAlias.Foreign}} = nil
   388  		}
   389  		{{end -}}
   390  		if {{if not $.NoRowsAffected}}_, {{end -}} err = rel.Update({{if not $.NoContext}}ctx, {{end -}} exec, boil.Whitelist("{{.ForeignColumn}}")); err != nil {
   391  			return err
   392  		}
   393  	}
   394  	{{end -}}
   395  
   396  	{{if and .ToJoinTable (not $.NoBackReferencing) -}}
   397  	remove{{$relAlias.Local}}From{{$relAlias.Foreign}}Slice(o, related)
   398  	{{end -}}
   399  	if o.R == nil {
   400  		return nil
   401  	}
   402  
   403  	for _, rel := range related {
   404  		for i, ri := range o.R.{{$relAlias.Local}} {
   405  			if rel != ri {
   406  				continue
   407  			}
   408  
   409  			ln := len(o.R.{{$relAlias.Local}})
   410  			if ln > 1 && i < ln-1 {
   411  				o.R.{{$relAlias.Local}}[i] = o.R.{{$relAlias.Local}}[ln-1]
   412  			}
   413  			o.R.{{$relAlias.Local}} = o.R.{{$relAlias.Local}}[:ln-1]
   414  			break
   415  		}
   416  	}
   417  
   418  	return nil
   419  }
   420  
   421  {{if and .ToJoinTable (not $.NoBackReferencing) -}}
   422  func remove{{$relAlias.Local}}From{{$relAlias.Foreign}}Slice(o *{{$ltable.UpSingular}}, related []*{{$ftable.UpSingular}}) {
   423  	for _, rel := range related {
   424  		if rel.R == nil {
   425  			continue
   426  		}
   427  		for i, ri := range rel.R.{{$relAlias.Foreign}} {
   428  			{{if $usesPrimitives -}}
   429  			if o.{{$col}} != ri.{{$col}} {
   430  			{{else -}}
   431  			if !queries.Equal(o.{{$col}}, ri.{{$col}}) {
   432  			{{end -}}
   433  				continue
   434  			}
   435  
   436  			ln := len(rel.R.{{$relAlias.Foreign}})
   437  			if ln > 1 && i < ln-1 {
   438  				rel.R.{{$relAlias.Foreign}}[i] = rel.R.{{$relAlias.Foreign}}[ln-1]
   439  			}
   440  			rel.R.{{$relAlias.Foreign}} = rel.R.{{$relAlias.Foreign}}[:ln-1]
   441  			break
   442  		}
   443  	}
   444  }
   445  				{{end -}}{{- /* if ToJoinTable */ -}}
   446  			{{- end -}}{{- /* if nullable foreign key */ -}}
   447  	{{- end -}}{{- /* range relationships */ -}}
   448  {{- end -}}{{- /* if IsJoinTable */ -}}