Skip to content

Commit

Permalink
release 0.109.0
Browse files Browse the repository at this point in the history
  • Loading branch information
stfnmllr committed Oct 19, 2022
1 parent 100a850 commit 7cd5634
Show file tree
Hide file tree
Showing 59 changed files with 976 additions and 1,424 deletions.
24 changes: 0 additions & 24 deletions .drone.yml

This file was deleted.

3 changes: 0 additions & 3 deletions .drone.yml.license

This file was deleted.

22 changes: 11 additions & 11 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ jobs:

steps:

- uses: actions/checkout@v2
- uses: actions/checkout@v3

- name: Setup go
uses: actions/setup-go@v2
uses: actions/setup-go@v3
with:
go-version: '1.19'

Expand All @@ -25,7 +25,7 @@ jobs:
matrix:
goos: [linux]
goarch: [amd64, arm, arm64, s390x]
go: [ '1.19', '1.18', '1.17' ]
go: ['1.19', '1.18']
fail-fast: false

name: Go ${{ matrix.go }} ${{ matrix.goos }} ${{ matrix.goarch }} build
Expand All @@ -42,10 +42,10 @@ jobs:
sudo apt-get update
sudo apt-get -y install qemu-user
- uses: actions/checkout@v2
- uses: actions/checkout@v3

- name: Setup go
uses: actions/setup-go@v2
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go }}

Expand All @@ -69,17 +69,17 @@ jobs:
runs-on: macos-latest
strategy:
matrix:
go: [ '1.19', '1.18', '1.17' ]
go: ['1.19', '1.18']
fail-fast: false

name: Go ${{ matrix.go }} macOS

steps:

- uses: actions/checkout@v2
- uses: actions/checkout@v3

- name: Setup go
uses: actions/setup-go@v2
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go }}

Expand All @@ -103,17 +103,17 @@ jobs:
runs-on: windows-latest
strategy:
matrix:
go: [ '1.19', '1.18', '1.17' ]
go: ['1.19', '1.18']
fail-fast: false

name: Go ${{ matrix.go }} Windows

steps:

- uses: actions/checkout@v2
- uses: actions/checkout@v3

- name: Setup go
uses: actions/setup-go@v2
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go }}

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/reuse.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: REUSE Compliance Check
uses: fsfe/reuse-action@v1.1
9 changes: 3 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ all:
@echo execute tests on latest go version
go test ./...
@echo execute tests on older supported go versions
go1.17.13 test ./...
go1.18.5 test ./...
go1.18.7 test ./...
@echo "reuse (license) check"
reuse lint

Expand All @@ -31,10 +30,8 @@ tools:

#install additional go versions
go:
go install golang.org/dl/go1.17.13@latest
go1.17.13 download
go install golang.org/dl/go1.18.5@latest
go1.18.5 download
go install golang.org/dl/go1.18.7@latest
go1.18.7 download

#install fsfe reuse tool (https://git.fsfe.org/reuse/tool)
# pre-conditions:
Expand Down
10 changes: 10 additions & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
Release Notes
=============

## Release 0.109

#### Release Notes

- Moved prometheus collector from ./driver/prometheus to ./prometheus (incompatible change)
- Removed deprecated /driver/hdb package
- Dropped support of Go language versions < Go 1.18
- Added bulk function execute (experimental - please see Example_fctInsert())
- Upgraded dependencies (see go.mod)

## Release 0.108

Release 0.108.3 (upgrade urgency: low)
Expand Down
240 changes: 240 additions & 0 deletions driver/args.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
// SPDX-FileCopyrightText: 2014-2022 SAP SE
//
// SPDX-License-Identifier: Apache-2.0

package driver

import (
"database/sql"
"database/sql/driver"
"errors"
"fmt"
"reflect"
)

// ErrEndOfRows is the error to be returned using a function based bulk exec to indicate
// the end of rows.
var ErrEndOfRows = errors.New("end of rows")

type argsScanner interface {
scan(nvargs []driver.NamedValue) error
}

type singleArgs struct {
i int
nvargs []driver.NamedValue
}

func (it *singleArgs) scan(nvargs []driver.NamedValue) error {
if it.i != 0 {
return ErrEndOfRows
}
copy(nvargs, it.nvargs)
it.i++
return nil
}

type multiArgs struct {
i int
nvargs []driver.NamedValue
}

func (it *multiArgs) scan(nvargs []driver.NamedValue) error {
if it.i >= len(it.nvargs) {
return ErrEndOfRows
}
n := copy(nvargs, it.nvargs[it.i:])
it.i += n
return nil
}

type fctArgs struct {
init bool
fct func(args []any) error
args []any
}

func (it *fctArgs) scan(nvargs []driver.NamedValue) error {
if !it.init {
it.args = make([]any, len(nvargs))
it.init = false
}
err := it.fct(it.args)
if err != nil {
return err
}
for i := 0; i < len(nvargs); i++ {
nvargs[i] = convertToNamedValue(i, it.args[i])
}
return nil
}

func convertToNamedValue(idx int, arg any) driver.NamedValue {
switch t := arg.(type) {
case sql.NamedArg:
return driver.NamedValue{Name: t.Name, Ordinal: idx + 1, Value: t.Value}
default:
return driver.NamedValue{Ordinal: idx + 1, Value: arg}
}
}

type anyListArgs struct {
i int
list []any
}

func (it *anyListArgs) scan(nvargs []driver.NamedValue) error {
if it.i >= len(it.list) {
return ErrEndOfRows
}
nvargs[0] = convertToNamedValue(0, it.list[it.i])
it.i++
return nil
}

type anyTableArgs struct {
i int
table [][]any
}

func (it *anyTableArgs) scan(nvargs []driver.NamedValue) error {
if it.i >= len(it.table) {
return ErrEndOfRows
}
for j := 0; j < len(nvargs); j++ {
nvargs[j] = convertToNamedValue(j, it.table[it.i][j])
}
it.i++
return nil
}

type genListArgs struct {
i int
list reflect.Value
}

func (it *genListArgs) scan(nvargs []driver.NamedValue) error {
if it.i >= it.list.Len() {
return ErrEndOfRows
}
nvargs[0] = convertToNamedValue(0, it.list.Index(it.i).Interface())
it.i++
return nil
}

type genTableArgs struct {
i int
table reflect.Value
}

func (it *genTableArgs) scan(nvargs []driver.NamedValue) error {
if it.i >= it.table.Len() {
return ErrEndOfRows
}
list := it.table.Index(it.i)
for j := 0; j < len(nvargs); j++ {
nvargs[j] = convertToNamedValue(j, list.Index(j).Interface())
}
it.i++
return nil
}

func isList(v any) (any, bool) {
rv := reflect.ValueOf(v)
switch rv.Kind() {
case reflect.Array, reflect.Slice:
// but do not allow slice, array of bytes
if rv.Type().Elem().Kind() == reflect.Uint8 {
return nil, false
}
return rv.Interface(), true
case reflect.Ptr:
return isList(rv.Elem().Interface())
default:
return nil, false
}
}

func isTable(v any) (any, bool) {
rv := reflect.ValueOf(v)
switch rv.Kind() {
case reflect.Array, reflect.Slice:
if list, ok := isList(rv.Elem().Interface()); ok {
return list, true
}
return nil, false
case reflect.Ptr:
return isTable(rv.Elem().Interface())
default:
return nil, false
}
}

type argsMismatchError struct {
numArg int
numPrm int
}

func newArgsMismatchError(numArg, numPrm int) *argsMismatchError {
return &argsMismatchError{numArg: numArg, numPrm: numPrm}
}

func (e *argsMismatchError) Error() string {
return fmt.Sprintf("argument parameter mismatch - number of arguments %d number of parameters %d", e.numArg, e.numPrm)
}

func newArgsScanner(numField int, nvargs []driver.NamedValue) (argsScanner, error) {
numArg := len(nvargs)

switch numArg {

case 0:
if numField == 0 {
return nil, nil
}
return nil, newArgsMismatchError(numArg, numField)

case 1:
arg := nvargs[0].Value

switch numField {
case 0:
return nil, newArgsMismatchError(numArg, numField)
case 1:
if v, ok := arg.(func(args []any) error); ok {
return &fctArgs{fct: v}, nil
}
if v, ok := arg.([]any); ok {
return &anyListArgs{list: v}, nil
}
if v, ok := isList(arg); ok {
return &genListArgs{list: reflect.ValueOf(v)}, nil
}
return &singleArgs{nvargs: nvargs}, nil
default:
if v, ok := arg.(func(args []any) error); ok {
return &fctArgs{fct: v}, nil
}
if v, ok := arg.([][]any); ok {
return &anyTableArgs{table: v}, nil
}
if v, ok := isTable(arg); ok {
return &genTableArgs{table: reflect.ValueOf(v)}, nil
}
return nil, fmt.Errorf("invalid argument type %T", arg)
}

default:
if numField == 0 {
return nil, newArgsMismatchError(numArg, numField)
}
switch {
case numArg == numField:
return &singleArgs{nvargs: nvargs}, nil
case numArg%numField == 0:
return &multiArgs{nvargs: nvargs}, nil
default:
return nil, newArgsMismatchError(numArg, numField)
}
}
}
Loading

0 comments on commit 7cd5634

Please sign in to comment.