Skip to content

Commit

Permalink
support role:"ref" for pointer-like generic types
Browse files Browse the repository at this point in the history
  • Loading branch information
mitranim committed Apr 1, 2022
1 parent c8fed17 commit fca238a
Show file tree
Hide file tree
Showing 21 changed files with 324 additions and 311 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module github.com/mitranim/sqlb

go 1.17
go 1.18
6 changes: 6 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,12 @@ func Example_composition() {

## Changelog

### v0.6.0

* Support `role:"ref"` struct field annotation for pointer-like generic types.

* Require Go 1.18.

### v0.5.3

Added `SliceCommaAppender`.
Expand Down
12 changes: 6 additions & 6 deletions sqlb.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ expression-encoding panics and convert them to errors.
All `Expr` types in this package also implement `Appender` and `fmt.Stringer`.
*/
type Expr interface {
AppendExpr([]byte, []interface{}) ([]byte, []interface{})
AppendExpr([]byte, []any) ([]byte, []any)
}

/*
Expand All @@ -24,7 +24,7 @@ input in order to be a valid expression. Implemented by preparsed query types,
namely by `Prep`.
*/
type ParamExpr interface {
AppendParamExpr([]byte, []interface{}, ArgDict) ([]byte, []interface{})
AppendParamExpr([]byte, []any, ArgDict) ([]byte, []any)
}

/*
Expand All @@ -43,8 +43,8 @@ validate used/unused arguments.
type ArgDict interface {
IsEmpty() bool
Len() int
GotOrdinal(int) (interface{}, bool)
GotNamed(string) (interface{}, bool)
GotOrdinal(int) (any, bool)
GotNamed(string) (any, bool)
}

/*
Expand Down Expand Up @@ -89,15 +89,15 @@ question "is this field present?".
Secretly supported by struct-scanning expressions such as `StructInsert`,
`StructAssign`, `StructValues`, `Cond`, and more. These types attempt to upcast
the inner value to `Sparse`, falling back on using the inner value as-is. This
allows to correctly implement REST PATCH semantics by using only the fields
allows to correctly implement REST "PATCH" semantics by using only the fields
that were present in a particular HTTP request, while keeping this
functionality optional.
Concrete implementation: `Partial`.
*/
type Sparse interface {
Filter
Get() interface{}
Get() any
}

/*
Expand Down
4 changes: 2 additions & 2 deletions sqlb_array.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func (self ArrayAppender) Append(buf []byte) []byte {
return buf
}

func (self ArrayAppender) Get() interface{} { return self.String() }
func (self ArrayAppender) Get() any { return self.String() }

func (self ArrayAppender) Value() (driver.Value, error) { return self.Get(), nil }

Expand Down Expand Up @@ -69,7 +69,7 @@ leading comma, double comma, or leading trailing comma, unless they were
explicitly generated by the inner encoders. Compare `CommaAppender` which
itself is a slice.
*/
type SliceCommaAppender [1]interface{}
type SliceCommaAppender [1]any

// Implement `fmt.Stringer` by calling `.Append`.
func (self SliceCommaAppender) String() string { return AppenderString(&self) }
Expand Down
18 changes: 9 additions & 9 deletions sqlb_bui.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ buffers.
func MakeBui(textCap, argsCap int) Bui {
return Bui{
make([]byte, 0, textCap),
make([]interface{}, 0, argsCap),
make([]any, 0, argsCap),
}
}

Expand All @@ -20,12 +20,12 @@ allow future Go versions to optimize it away completely.
*/
type Bui struct {
Text []byte
Args []interface{}
Args []any
}

// Returns text and args as-is. Useful shortcut for passing them to
// `AppendExpr`.
func (self Bui) Get() ([]byte, []interface{}) {
func (self Bui) Get() ([]byte, []any) {
return self.Text, self.Args
}

Expand All @@ -36,14 +36,14 @@ interface-induced allocation:
bui.Set(SomeExpr{}.AppendExpr(bui.Get()))
*/
func (self *Bui) Set(text []byte, args []interface{}) {
func (self *Bui) Set(text []byte, args []any) {
self.Text = text
self.Args = args
}

// Shortcut for `self.String(), self.Args`. Go database drivers tend to require
// `string, []interface{}` as inputs for queries and statements.
func (self Bui) Reify() (string, []interface{}) {
// `string, []any` as inputs for queries and statements.
func (self Bui) Reify() (string, []any) {
return self.String(), self.Args
}

Expand Down Expand Up @@ -127,7 +127,7 @@ func (self *Bui) Param(val OrdinalParam) {

// Appends an arg to the inner slice of args, returning the corresponding
// ordinal parameter that should be appended to the text.
func (self *Bui) Arg(val interface{}) OrdinalParam {
func (self *Bui) Arg(val any) OrdinalParam {
self.Args = append(self.Args, val)
return OrdinalParam(len(self.Args))
}
Expand All @@ -138,7 +138,7 @@ Appends an arbitrary value. If the value implements `Expr`, this calls
Otherwise, appends an argument to the inner slice of args, and the
corresponding ordinal parameter such as "$1"/"$2"/.../"$N" to the text.
*/
func (self *Bui) Any(val interface{}) {
func (self *Bui) Any(val any) {
impl, _ := val.(Expr)
if impl != nil {
self.Expr(impl)
Expand All @@ -165,7 +165,7 @@ Appends an arbitrary value or sub-expression. Like `(*Bui).Any`, but if the
value implements `Expr`, this uses `(*Bui).SubExpr` in order to parenthesize
the sub-expression.
*/
func (self *Bui) SubAny(val interface{}) {
func (self *Bui) SubAny(val any) {
impl, _ := val.(Expr)
if impl != nil {
self.SubExpr(impl)
Expand Down
20 changes: 10 additions & 10 deletions sqlb_dict.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ package sqlb
import r "reflect"

/*
Variant of `[]interface{}` conforming to the `ArgDict` interface. Supports only
Variant of `[]any` conforming to the `ArgDict` interface. Supports only
ordinal parameters, not named parameters. Used for `StrQ`. See the `ListQ`
shortcut.
*/
type List []interface{}
type List []any

// Implement part of the `ArgDict` interface.
func (self List) IsEmpty() bool { return self.Len() == 0 }
Expand All @@ -16,15 +16,15 @@ func (self List) IsEmpty() bool { return self.Len() == 0 }
func (self List) Len() int { return len(self) }

// Implement part of the `ArgDict` interface.
func (self List) GotOrdinal(key int) (interface{}, bool) {
func (self List) GotOrdinal(key int) (any, bool) {
if key >= 0 && key < len(self) {
return self[key], true
}
return nil, false
}

// Implement part of the `ArgDict` interface. Always returns `nil, false`.
func (self List) GotNamed(string) (interface{}, bool) { return nil, false }
func (self List) GotNamed(string) (any, bool) { return nil, false }

// Implement `OrdinalRanger` to automatically validate used/unused arguments.
func (self List) RangeOrdinal(fun func(int)) {
Expand All @@ -36,11 +36,11 @@ func (self List) RangeOrdinal(fun func(int)) {
}

/*
Variant of `map[string]interface{}` conforming to the `ArgDict` interface.
Variant of `map[string]any` conforming to the `ArgDict` interface.
Supports only named parameters, not ordinal parameters. Used for `StrQ`. See
the `DictQ` shortcut.
*/
type Dict map[string]interface{}
type Dict map[string]any

// Implement part of the `ArgDict` interface.
func (self Dict) IsEmpty() bool { return self.Len() == 0 }
Expand All @@ -49,10 +49,10 @@ func (self Dict) IsEmpty() bool { return self.Len() == 0 }
func (self Dict) Len() int { return len(self) }

// Implement part of the `ArgDict` interface. Always returns `nil, false`.
func (self Dict) GotOrdinal(int) (interface{}, bool) { return nil, false }
func (self Dict) GotOrdinal(int) (any, bool) { return nil, false }

// Implement part of the `ArgDict` interface.
func (self Dict) GotNamed(key string) (interface{}, bool) {
func (self Dict) GotNamed(key string) (any, bool) {
val, ok := self[key]
return val, ok
}
Expand Down Expand Up @@ -84,10 +84,10 @@ func (self StructDict) IsEmpty() bool {
func (self StructDict) Len() int { return 0 }

// Implement part of the `ArgDict` interface. Always returns `nil, false`.
func (self StructDict) GotOrdinal(int) (interface{}, bool) { return nil, false }
func (self StructDict) GotOrdinal(int) (any, bool) { return nil, false }

// Implement part of the `ArgDict` interface.
func (self StructDict) GotNamed(key string) (interface{}, bool) {
func (self StructDict) GotNamed(key string) (any, bool) {
/**
(Tested in Go 1.17.)
Expand Down
10 changes: 5 additions & 5 deletions sqlb_err.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,29 +167,29 @@ func errUnusedNamed(val NamedParam) ErrUnusedArgument {
}}
}

func errExpectedX(desc, while string, val interface{}) ErrInvalidInput {
func errExpectedX(desc, while string, val any) ErrInvalidInput {
return ErrInvalidInput{Err{
while,
fmt.Errorf(`expected %v, found %v`, desc, val),
}}
}

func errExpectedSlice(while string, val interface{}) ErrInvalidInput {
func errExpectedSlice(while string, val any) ErrInvalidInput {
return errExpectedX(`slice`, while, val)
}

func errExpectedStruct(while string, val interface{}) ErrInvalidInput {
func errExpectedStruct(while string, val any) ErrInvalidInput {
return errExpectedX(`struct`, while, val)
}

func errUnexpectedArgs(desc, input interface{}) ErrInvalidInput {
func errUnexpectedArgs(desc, input any) ErrInvalidInput {
return ErrInvalidInput{Err{
`building SQL expression`,
fmt.Errorf(`%v expected no arguments, got %#v`, desc, input),
}}
}

func errMissingArgs(desc interface{}) ErrInvalidInput {
func errMissingArgs(desc any) ErrInvalidInput {
return ErrInvalidInput{Err{
`building SQL expression`,
fmt.Errorf(`%v expected arguments, got none`, desc),
Expand Down
Loading

0 comments on commit fca238a

Please sign in to comment.