Begin the pain
This commit is contained in:
parent
1875bac7cf
commit
160c6ff0f0
6 changed files with 34 additions and 112 deletions
26
bdb/keys.go
26
bdb/keys.go
|
@ -3,7 +3,6 @@ package bdb
|
|||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var rgxAutoIncColumn = regexp.MustCompile(`^nextval\(.*\)`)
|
||||
|
@ -90,28 +89,3 @@ func SQLColDefStrings(defs []SQLColumnDef) []string {
|
|||
|
||||
return strs
|
||||
}
|
||||
|
||||
// AutoIncPrimaryKey returns the auto-increment primary key column name or an
|
||||
// empty string.
|
||||
func AutoIncPrimaryKey(cols []Column, pkey *PrimaryKey) *Column {
|
||||
if pkey == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, pkeyColumn := range pkey.Columns {
|
||||
for _, c := range cols {
|
||||
if c.Name != pkeyColumn {
|
||||
continue
|
||||
}
|
||||
|
||||
if !rgxAutoIncColumn.MatchString(c.Default) || c.Nullable ||
|
||||
!(strings.HasPrefix(c.Type, "int") || strings.HasPrefix(c.Type, "uint")) {
|
||||
continue
|
||||
}
|
||||
|
||||
return &c
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -50,55 +50,3 @@ func TestSQLDefStrings(t *testing.T) {
|
|||
t.Error("wrong str:", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAutoIncPrimaryKey(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := map[string]struct {
|
||||
Ok bool
|
||||
Expect Column
|
||||
Pkey *PrimaryKey
|
||||
Columns []Column
|
||||
}{
|
||||
"nillcase": {
|
||||
Ok: false,
|
||||
Pkey: nil,
|
||||
Columns: nil,
|
||||
},
|
||||
"easycase": {
|
||||
Ok: true,
|
||||
Expect: Column{Name: "one", Type: "int32", Nullable: false, Default: `nextval('abc'::regclass)`},
|
||||
Pkey: &PrimaryKey{Name: "pkey", Columns: []string{"one"}},
|
||||
Columns: []Column{{Name: "one", Type: "int32", Nullable: false, Default: `nextval('abc'::regclass)`}},
|
||||
},
|
||||
"missingcase": {
|
||||
Ok: false,
|
||||
Pkey: &PrimaryKey{Name: "pkey", Columns: []string{"two"}},
|
||||
Columns: []Column{{Name: "one", Type: "int32", Nullable: false, Default: `nextval('abc'::regclass)`}},
|
||||
},
|
||||
"wrongtype": {
|
||||
Ok: false,
|
||||
Pkey: &PrimaryKey{Name: "pkey", Columns: []string{"one"}},
|
||||
Columns: []Column{{Name: "one", Type: "string", Nullable: false, Default: `nextval('abc'::regclass)`}},
|
||||
},
|
||||
"nodefault": {
|
||||
Ok: false,
|
||||
Pkey: &PrimaryKey{Name: "pkey", Columns: []string{"one"}},
|
||||
Columns: []Column{{Name: "one", Type: "string", Nullable: false, Default: ``}},
|
||||
},
|
||||
"nullable": {
|
||||
Ok: false,
|
||||
Pkey: &PrimaryKey{Name: "pkey", Columns: []string{"one"}},
|
||||
Columns: []Column{{Name: "one", Type: "string", Nullable: true, Default: `nextval('abc'::regclass)`}},
|
||||
},
|
||||
}
|
||||
|
||||
for testName, test := range tests {
|
||||
pkey := AutoIncPrimaryKey(test.Columns, test.Pkey)
|
||||
if ok := (pkey != nil); ok != test.Ok {
|
||||
t.Errorf("%s) found state was wrong, want: %t, got: %t", testName, test.Ok, ok)
|
||||
} else if test.Ok && *pkey != test.Expect {
|
||||
t.Errorf("%s) wrong primary key, want: %#v, got %#v", testName, test.Expect, pkey)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -172,7 +172,6 @@ var templateFunctions = template.FuncMap{
|
|||
"filterColumnsByAutoIncrement": bdb.FilterColumnsByAutoIncrement,
|
||||
"filterColumnsByValidated": bdb.FilterColumnsByValidated,
|
||||
"filterColumnsByUnique": bdb.FilterColumnsByUnique,
|
||||
"autoIncPrimaryKey": bdb.AutoIncPrimaryKey,
|
||||
"sqlColDefinitions": bdb.SQLColDefinitions,
|
||||
"sqlColDefStrings": bdb.SQLColDefStrings,
|
||||
"columnNames": bdb.ColumnNames,
|
||||
|
|
|
@ -9,7 +9,7 @@ var (
|
|||
{{$varNameSingular}}UniqueColumns = []string{{"{"}}{{.Table.Columns | filterColumnsByUnique | columnNames | stringMap .StringFuncs.quoteWrap | join ", "}}{{"}"}}
|
||||
{{$varNameSingular}}PrimaryKeyColumns = []string{{"{"}}{{.Table.PKey.Columns | stringMap .StringFuncs.quoteWrap | join ", "}}{{"}"}}
|
||||
{{$varNameSingular}}AutoIncrementColumns = []string{{"{"}}{{.Table.Columns | filterColumnsByAutoIncrement true | columnNames | stringMap .StringFuncs.quoteWrap | join "," }}{{"}"}}
|
||||
{{$varNameSingular}}AutoIncPrimaryKey = "{{- with autoIncPrimaryKey .Table.Columns .Table.PKey -}}{{.Name}}{{- end -}}"
|
||||
{{$varNameSingular}}AutoIncPrimaryKeys = []string{{"{"}}{{.Table.Columns | filterColumnsByPrimaryKey .Table.PKey | filterColumnsByDefault true | columnNames | join ", "}}{{"}"}}
|
||||
)
|
||||
|
||||
type (
|
||||
|
|
|
@ -41,34 +41,34 @@ func (o *{{$tableNameSingular}}) Insert(exec boil.Executor, whitelist ... string
|
|||
ins := fmt.Sprintf(`INSERT INTO {{.Table.Name}} ("%s") VALUES (%s)`, strings.Join(wl, `","`), strmangle.Placeholders(len(wl), 1, 1))
|
||||
|
||||
{{if driverUsesLastInsertID .DriverName}}
|
||||
if len(returnColumns) != 0 {
|
||||
result, err := exec.Exec(ins, boil.GetStructValues(o, wl...)...)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "{{.PkgName}}: unable to insert into {{.Table.Name}}")
|
||||
}
|
||||
if boil.DebugMode {
|
||||
fmt.Fprintln(boil.DebugWriter, ins)
|
||||
fmt.Fprintln(boil.DebugWriter, boil.GetStructValues(o, wl...))
|
||||
}
|
||||
|
||||
lastId, err := result.lastInsertId()
|
||||
if err != nil || lastId == 0 {
|
||||
sel := fmt.Sprintf(`SELECT %s FROM {{.Table.Name}} WHERE %s`, strings.Join(returnColumns, `","`), strmangle.WhereClause(1, wl))
|
||||
rows, err := exec.Query(sel, boil.GetStructValues(o, wl...)...)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "{{.PkgName}}: unable to insert into {{.Table.Name}}")
|
||||
}
|
||||
defer rows.Close()
|
||||
result, err := exec.Exec(ins, boil.GetStructValues(o, wl...)...)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "{{.PkgName}}: unable to insert into {{.Table.Name}}")
|
||||
}
|
||||
|
||||
i := 0
|
||||
ptrs := boil.GetStructPointers(o, returnColumns...)
|
||||
for rows.Next() {
|
||||
if err := rows.Scan(ptrs[i]); err != nil {
|
||||
return errors.Wrapf(err, "{{.PkgName}}: unable to get result of insert, scan failed for column %s index %d\n\n%#v", returnColumns[i], i, ptrs)
|
||||
}
|
||||
i++
|
||||
}
|
||||
} else if {{$varNameSingular}}AutoIncPrimKey != "" {
|
||||
sel := fmt.Sprintf(`SELECT %s FROM {{.Table.Name}} WHERE %s=$1`, strings.Join(returnColumns, ","), {{$varNameSingular}}AutoIncPrimaryKey, lastId)
|
||||
}
|
||||
} else {
|
||||
_, err = exec.Exec(ins, boil.GetStructValues(o, wl...)...)
|
||||
if len(returnColumns) == 0 {
|
||||
return o.doAfterCreateHooks()
|
||||
}
|
||||
|
||||
lastId, err := result.lastInsertId()
|
||||
if err != nil || lastId == 0 {
|
||||
return ErrSyncFail
|
||||
}
|
||||
|
||||
if len({{$varNameSingular}}AutoIncPrimaryKeys) != 1 {
|
||||
return ErrSyncFail
|
||||
}
|
||||
|
||||
pkey := {{$varNameSingular}}AutoIncPrimaryKeys[0]
|
||||
sel := fmt.Sprintf(`SELECT %s FROM {{.Table.Name}} WHERE %s`, strings.Join(returnColumns, `","`), strmangle.WhereClause(1, pkey))
|
||||
err := exec.QueryRow(sel, lastId).Scan(boil.GetStructPointers(o, returnColumns...))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "{{.PkgName}}: unable to populate default values for {{.Table.Name}}")
|
||||
}
|
||||
{{else}}
|
||||
if len(returnColumns) != 0 {
|
||||
|
@ -77,7 +77,6 @@ func (o *{{$tableNameSingular}}) Insert(exec boil.Executor, whitelist ... string
|
|||
} else {
|
||||
_, err = exec.Exec(ins, boil.GetStructValues(o, wl...)...)
|
||||
}
|
||||
{{end}}
|
||||
|
||||
if boil.DebugMode {
|
||||
fmt.Fprintln(boil.DebugWriter, ins)
|
||||
|
@ -87,12 +86,9 @@ func (o *{{$tableNameSingular}}) Insert(exec boil.Executor, whitelist ... string
|
|||
if err != nil {
|
||||
return errors.Wrap(err, "{{.PkgName}}: unable to insert into {{.Table.Name}}")
|
||||
}
|
||||
{{end}}
|
||||
|
||||
if err := o.doAfterCreateHooks(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return o.doAfterCreateHooks()
|
||||
}
|
||||
|
||||
// generateInsertColumns generates the whitelist columns and return columns for an insert statement
|
||||
|
|
|
@ -7,3 +7,8 @@ type upsertData struct {
|
|||
whitelist []string
|
||||
returning []string
|
||||
}
|
||||
|
||||
// ErrSyncFail occurs during insert when the record could not be retrieved in
|
||||
// order to populate default value information. This usually happens when LastInsertId
|
||||
// fails or there was a primary key configuration that was not resolvable.
|
||||
var ErrSyncFail = errors.New("{{.PkgName}}: failed to synchronize data after insert")
|
||||
|
|
Loading…
Add table
Reference in a new issue