github.com/Ali-iotechsys/sqlboiler/v4@v4.0.0-20221208124957-6aec9a5f1f71/drivers/sqlboiler-mssql/driver/override/main/17_upsert.go.tpl (about) 1 {{- if or (not .Table.IsView) .Table.ViewCapabilities.CanUpsert -}} 2 {{- $alias := .Aliases.Table .Table.Name}} 3 {{- $schemaTable := .Table.Name | .SchemaTable}} 4 {{if .AddGlobal -}} 5 // UpsertG attempts an insert, and does an update or ignore on conflict. 6 func (o *{{$alias.UpSingular}}) UpsertG({{if not .NoContext}}ctx context.Context, {{end -}} updateColumns, insertColumns boil.Columns) error { 7 return o.Upsert({{if .NoContext}}boil.GetDB(){{else}}ctx, boil.GetContextDB(){{end}}, updateColumns, insertColumns) 8 } 9 10 {{end -}} 11 12 {{if and .AddGlobal .AddPanic -}} 13 // UpsertGP attempts an insert, and does an update or ignore on conflict. Panics on error. 14 func (o *{{$alias.UpSingular}}) UpsertGP({{if not .NoContext}}ctx context.Context, {{end -}} updateColumns, insertColumns boil.Columns) { 15 if err := o.Upsert({{if .NoContext}}boil.GetDB(){{else}}ctx, boil.GetContextDB(){{end}}, updateColumns, insertColumns); err != nil { 16 panic(boil.WrapErr(err)) 17 } 18 } 19 20 {{end -}} 21 22 {{if .AddPanic -}} 23 // UpsertP attempts an insert using an executor, and does an update or ignore on conflict. 24 // UpsertP panics on error. 25 func (o *{{$alias.UpSingular}}) UpsertP({{if .NoContext}}exec boil.Executor{{else}}ctx context.Context, exec boil.ContextExecutor{{end}}, updateColumns, insertColumns boil.Columns) { 26 if err := o.Upsert({{if not .NoContext}}ctx, {{end -}} exec, updateColumns, insertColumns); err != nil { 27 panic(boil.WrapErr(err)) 28 } 29 } 30 31 {{end -}} 32 33 // Upsert attempts an insert using an executor, and does an update or ignore on conflict. 34 func (o *{{$alias.UpSingular}}) Upsert({{if .NoContext}}exec boil.Executor{{else}}ctx context.Context, exec boil.ContextExecutor{{end}}, updateColumns, insertColumns boil.Columns) error { 35 if o == nil { 36 return errors.New("{{.PkgName}}: no {{.Table.Name}} provided for upsert") 37 } 38 39 {{- template "timestamp_upsert_helper" . }} 40 41 {{if not .NoHooks -}} 42 if err := o.doBeforeUpsertHooks({{if not .NoContext}}ctx, {{end -}} exec); err != nil { 43 return err 44 } 45 {{- end}} 46 47 nzDefaults := queries.NonZeroDefaultSet({{$alias.DownSingular}}ColumnsWithDefault, o) 48 49 // Build cache key in-line uglily - mysql vs psql problems 50 buf := strmangle.GetBuffer() 51 buf.WriteString(strconv.Itoa(updateColumns.Kind)) 52 for _, c := range updateColumns.Cols { 53 buf.WriteString(c) 54 } 55 buf.WriteByte('.') 56 buf.WriteString(strconv.Itoa(insertColumns.Kind)) 57 for _, c := range insertColumns.Cols { 58 buf.WriteString(c) 59 } 60 buf.WriteByte('.') 61 for _, c := range nzDefaults { 62 buf.WriteString(c) 63 } 64 key := buf.String() 65 strmangle.PutBuffer(buf) 66 67 {{$alias.DownSingular}}UpsertCacheMut.RLock() 68 cache, cached := {{$alias.DownSingular}}UpsertCache[key] 69 {{$alias.DownSingular}}UpsertCacheMut.RUnlock() 70 71 var err error 72 73 if !cached { 74 insert, ret := insertColumns.InsertColumnSet( 75 {{$alias.DownSingular}}AllColumns, 76 {{$alias.DownSingular}}ColumnsWithDefault, 77 {{$alias.DownSingular}}ColumnsWithoutDefault, 78 nzDefaults, 79 ) 80 {{if filterColumnsByAuto true .Table.Columns }} 81 insert = strmangle.SetComplement(insert, {{$alias.DownSingular}}GeneratedColumns) 82 {{end}} 83 84 for i, v := range insert { 85 if strmangle.ContainsAny({{$alias.DownSingular}}PrimaryKeyColumns, v) && strmangle.ContainsAny({{$alias.DownSingular}}ColumnsWithDefault, v) { 86 insert = append(insert[:i], insert[i+1:]...) 87 } 88 } 89 if len(insert) == 0 { 90 return errors.New("{{.PkgName}}: unable to upsert {{.Table.Name}}, could not build insert column list") 91 } 92 93 update := updateColumns.UpdateColumnSet( 94 {{$alias.DownSingular}}AllColumns, 95 {{$alias.DownSingular}}PrimaryKeyColumns, 96 ) 97 {{if filterColumnsByAuto true .Table.Columns }} 98 insert = strmangle.SetComplement(insert, {{$alias.DownSingular}}GeneratedColumns) 99 {{end}} 100 101 if !updateColumns.IsNone() && len(update) == 0 { 102 return errors.New("{{.PkgName}}: unable to upsert {{.Table.Name}}, could not build update column list") 103 } 104 105 cache.query = buildUpsertQueryMSSQL(dialect, "{{$schemaTable}}", {{$alias.DownSingular}}PrimaryKeyColumns, update, insert, ret) 106 107 whitelist := make([]string, len({{$alias.DownSingular}}PrimaryKeyColumns)) 108 copy(whitelist, {{$alias.DownSingular}}PrimaryKeyColumns) 109 whitelist = append(whitelist, update...) 110 whitelist = append(whitelist, insert...) 111 112 cache.valueMapping, err = queries.BindMapping({{$alias.DownSingular}}Type, {{$alias.DownSingular}}Mapping, whitelist) 113 if err != nil { 114 return err 115 } 116 if len(ret) != 0 { 117 cache.retMapping, err = queries.BindMapping({{$alias.DownSingular}}Type, {{$alias.DownSingular}}Mapping, ret) 118 if err != nil { 119 return err 120 } 121 } 122 } 123 124 value := reflect.Indirect(reflect.ValueOf(o)) 125 vals := queries.ValuesFromMapping(value, cache.valueMapping) 126 var returns []interface{} 127 if len(cache.retMapping) != 0 { 128 returns = queries.PtrsFromMapping(value, cache.retMapping) 129 } 130 131 {{if .NoContext -}} 132 if boil.DebugMode { 133 fmt.Fprintln(boil.DebugWriter, cache.query) 134 fmt.Fprintln(boil.DebugWriter, vals) 135 } 136 {{else -}} 137 if boil.IsDebug(ctx) { 138 writer := boil.DebugWriterFrom(ctx) 139 fmt.Fprintln(writer, cache.query) 140 fmt.Fprintln(writer, vals) 141 } 142 {{end -}} 143 144 if len(cache.retMapping) != 0 { 145 {{if .NoContext -}} 146 err = exec.QueryRow(cache.query, vals...).Scan(returns...) 147 {{else -}} 148 err = exec.QueryRowContext(ctx, cache.query, vals...).Scan(returns...) 149 {{end -}} 150 if errors.Is(err, sql.ErrNoRows) { 151 err = nil // MSSQL doesn't return anything when there's no update 152 } 153 } else { 154 {{if .NoContext -}} 155 _, err = exec.Exec(cache.query, vals...) 156 {{else -}} 157 _, err = exec.ExecContext(ctx, cache.query, vals...) 158 {{end -}} 159 } 160 if err != nil { 161 return errors.Wrap(err, "{{.PkgName}}: unable to upsert {{.Table.Name}}") 162 } 163 164 if !cached { 165 {{$alias.DownSingular}}UpsertCacheMut.Lock() 166 {{$alias.DownSingular}}UpsertCache[key] = cache 167 {{$alias.DownSingular}}UpsertCacheMut.Unlock() 168 } 169 170 {{if not .NoHooks -}} 171 return o.doAfterUpsertHooks({{if not .NoContext}}ctx, {{end -}} exec) 172 {{- else -}} 173 return nil 174 {{- end}} 175 } 176 {{end}}