112 lines
No EOL
3 KiB
Smarty
112 lines
No EOL
3 KiB
Smarty
{{- $tableNamePlural := .Table.Name | plural | titleCase -}}
|
|
{{- $tableNameSingular := .Table.Name | singular | titleCase -}}
|
|
{{- if .Table.IsJoinTable -}}
|
|
{{- else -}}
|
|
{{- $dot := . }}
|
|
// Merge combines two {{$tableNamePlural}} into one. The primary record will be kept, and the secondary will be deleted.
|
|
func Merge{{$tableNamePlural}}(exec boil.Executor, primaryID uint64, secondaryID uint64) (err error) {
|
|
tx, ok := exec.(boil.Transactor)
|
|
if !ok {
|
|
txdb, ok := exec.(boil.Beginner)
|
|
if !ok {
|
|
return errors.New("database does not support transactions")
|
|
}
|
|
|
|
tx, err = txdb.Begin()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
defer func() {
|
|
if p := recover(); p != nil {
|
|
tx.Rollback()
|
|
panic(p) // Rollback, then propagate panic
|
|
} else if err != nil {
|
|
tx.Rollback()
|
|
} else {
|
|
err = tx.Commit()
|
|
}
|
|
}()
|
|
}
|
|
|
|
primary, err := Find{{$tableNameSingular}}(tx, primaryID)
|
|
if err != nil {
|
|
return err
|
|
} else if primary == nil {
|
|
return errors.New("Primary {{$tableNameSingular}} not found")
|
|
}
|
|
|
|
secondary, err := Find{{$tableNameSingular}}(tx, secondaryID)
|
|
if err != nil {
|
|
return err
|
|
} else if secondary == nil {
|
|
return errors.New("Secondary {{$tableNameSingular}} not found")
|
|
}
|
|
|
|
foreignKeys := []foreignKey{
|
|
{{- range .Tables -}}
|
|
{{- range .FKeys -}}
|
|
{{- if eq $dot.Table.Name .ForeignTable }}
|
|
{foreignTable: "{{.Table}}", foreignColumn: "{{.Column}}"},
|
|
{{- end -}}
|
|
{{- end -}}
|
|
{{- end }}
|
|
}
|
|
|
|
conflictingKeys := []conflictingUniqueKey{
|
|
{{- range .Tables -}}
|
|
{{- $table := . -}}
|
|
{{- range .FKeys -}}
|
|
{{- $fk := . -}}
|
|
{{- if eq $dot.Table.Name .ForeignTable -}}
|
|
{{- range $table.UKeys -}}
|
|
{{- if setInclude $fk.Column .Columns }}
|
|
{table: "{{$fk.Table}}", objectIdColumn: "{{$fk.Column}}", columns: []string{`{{ .Columns | join "`,`" }}`}},
|
|
{{- end -}}
|
|
{{- end -}}
|
|
{{- end -}}
|
|
{{- end -}}
|
|
{{- end }}
|
|
}
|
|
|
|
sqlTx, ok := tx.(*sql.Tx)
|
|
if !ok {
|
|
return errors.New("tx must be an sql.Tx")
|
|
}
|
|
|
|
err = mergeModels(sqlTx, primaryID, secondaryID, foreignKeys, conflictingKeys)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
pr := reflect.ValueOf(primary)
|
|
sr := reflect.ValueOf(secondary)
|
|
// for any column thats null on the primary and not null on the secondary, copy from secondary to primary
|
|
for i := 0; i < sr.Elem().NumField(); i++ {
|
|
pf := pr.Elem().Field(i)
|
|
sf := sr.Elem().Field(i)
|
|
if sf.IsValid() {
|
|
if nullable, ok := sf.Interface().(null.Nullable); ok && !nullable.IsNull() && pf.Interface().(null.Nullable).IsNull() {
|
|
pf.Set(sf)
|
|
}
|
|
}
|
|
}
|
|
|
|
err = primary.Update(tx)
|
|
if err != nil {
|
|
return errors.WithStack(err)
|
|
}
|
|
|
|
err = secondary.Delete(tx)
|
|
if err != nil {
|
|
return errors.WithStack(err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Merge combines two {{$tableNamePlural}} into one. The primary record will be kept, and the secondary will be deleted.
|
|
func Merge{{$tableNamePlural}}G(primaryID uint64, secondaryID uint64) error {
|
|
return Merge{{$tableNamePlural}}(boil.GetDB(), primaryID, secondaryID)
|
|
}
|
|
{{- end -}}{{/* join table */}} |