Skip to content

Commit

Permalink
fix on new Duplicate method
Browse files Browse the repository at this point in the history
  • Loading branch information
kataras committed Sep 18, 2023
1 parent 7a982af commit ca8162d
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 6 deletions.
4 changes: 3 additions & 1 deletion desc/argument.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,9 @@ func filterArguments(args Arguments, filter func(arg Argument) bool) Arguments {

// FilterArgumentsForInsert takes a slice of arguments and returns a slice of arguments for insert.
func filterArgumentsForFullUpdate(args Arguments) Arguments {
return filterArguments(args, func(arg Argument) bool { return !arg.Column.IsGenerated() })
return filterArguments(args, func(arg Argument) bool {
return !arg.Column.IsGenerated() && !arg.Column.Presenter // && !arg.Column.Unscannable
})
}

// extractPrimaryKeyValues takes a table definition and a slice of reflect values of structs
Expand Down
2 changes: 1 addition & 1 deletion desc/column.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ type (
// Unique indexes can really improve the performance on big data select queries
// Read more at: https://www.postgresql.org/docs/current/indexes-unique.html
UniqueIndex string // an optional name for a unique index on the column
// If true then create table and insert query will omit this column.
// If true then create table, insert, update and duplicate queries will omit this column.
Presenter bool
// If true then insert query will omit this column.
AutoGenerated bool
Expand Down
2 changes: 1 addition & 1 deletion desc/duplicate_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func BuildDuplicateQuery(td *Table, idPtr any) (string, error) {
// (name, tag, source_id)
b.WriteByte(leftParenLiteral)

columns := td.ListColumnsWithoutGenerated()
columns := td.listColumnsForSelectWithoutGenerated()
for i, c := range columns {
if i > 0 {
b.WriteByte(',')
Expand Down
40 changes: 37 additions & 3 deletions desc/scanner.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package desc

import (
"errors"
"fmt"
"reflect"

Expand Down Expand Up @@ -84,12 +85,25 @@ func ConvertRowsToStruct(td *Table, rows pgx.Rows, valuePtr interface{}) error {
if td.Strict {
return fmt.Errorf("struct doesn't have corresponding row field: %s (strict check)", rows.FieldDescriptions()[i].Name) // return an error if the struct doesn't have a field for a column
} else {
scanTargets[i] = &nullScanner{}
scanTargets[i] = &noOpScanner{}
}
}
}

if err = rows.Scan(scanTargets...); err != nil {
// Help developer to find what field was errored:
var scanArgErr pgx.ScanArgError
if errors.As(err, &scanArgErr) {
if len(td.Columns) > scanArgErr.ColumnIndex {
col := td.Columns[scanArgErr.ColumnIndex]
destColumnName := col.Name
err = fmt.Errorf("%w: field: %s.%s (%s): column: %s.%s",
err,
col.Table.StructName, col.FieldName, col.FieldType.String(),
col.TableName, destColumnName)
}
}

return err // return an error if scanning the row data failed
}

Expand Down Expand Up @@ -127,16 +141,36 @@ func findScanTargets(dstElemValue reflect.Value, td *Table, fieldDescs []pgconn.
}
}

if col.Type == UUID && col.Nullable {
scanTargets[i] = &nullableScanner{
uuidFieldPtr: dstElemValue.FieldByIndex(col.FieldIndex),
}

continue
}

// get the scan target by using the field index and taking the address and interface of the struct field
scanTargets[i] = dstElemValue.FieldByIndex(col.FieldIndex).Addr().Interface()
}

return scanTargets, nil // return the scan targets and nil error
}

type nullScanner struct{}
type noOpScanner struct{}

func (t *noOpScanner) Scan(src interface{}) error { return nil }

type nullableScanner struct { // useful for UUIDs with null values.
uuidFieldPtr reflect.Value
}

func (t *nullableScanner) Scan(src interface{}) error {
if src == nil {
return nil
}

t.uuidFieldPtr.Set(reflect.ValueOf(src))

func (t *nullScanner) Scan(src interface{}) error {
return nil
}

Expand Down
18 changes: 18 additions & 0 deletions desc/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,24 @@ func (td *Table) ListColumnsWithoutGenerated() []*Column {
return columns
}

func (td *Table) listColumnsForSelectWithoutGenerated() []*Column {
columns := make([]*Column, 0, len(td.Columns))

for _, c := range td.Columns {
if c.IsGenerated() {
continue
}

if c.Presenter {
continue
}

columns = append(columns, c)
}

return columns
}

// ListColumnNames returns the column names of the table definition.
func (td *Table) ListColumnNames() []string {
names := make([]string, 0, len(td.Columns))
Expand Down

0 comments on commit ca8162d

Please sign in to comment.