Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use ExtractParameters in handlers #2620

Merged
merged 51 commits into from
May 15, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
2a00d4e
WIP
May 11, 2023
700578c
WIP
May 11, 2023
d79ca7b
WIP
May 12, 2023
d5a893a
WIP
May 12, 2023
f82c865
WIP
May 12, 2023
55e9886
WIP
May 12, 2023
0d3890a
WIP
May 12, 2023
7dbe529
WIP
May 12, 2023
8e36366
Merge branch 'main' into issue-2465-use-extract-parameters
May 12, 2023
231713d
WIP
May 12, 2023
3c523db
Merge remote-tracking branch 'origin/issue-2465-use-extract-parameter…
May 12, 2023
c15c98d
WIP
May 12, 2023
47aa007
WIP
May 12, 2023
2474769
WIP
May 12, 2023
4e382e7
WIP
May 12, 2023
cf5ebef
WIP
May 12, 2023
13d3ec8
WIP
May 13, 2023
e92d5fe
WIP
May 13, 2023
64cbdc6
WIP
May 13, 2023
c3c9612
WIP
May 13, 2023
f6e030e
WIP
May 13, 2023
803d0dd
WIP
May 13, 2023
24222bf
WIP
May 13, 2023
a936f8e
WIP
May 13, 2023
55ee65a
WIP
May 13, 2023
359df69
WIP
May 13, 2023
7efb5c0
WIP
May 13, 2023
5925d9d
WIP
May 13, 2023
e35623d
WIP
May 13, 2023
de26fdd
Merge branch 'main' into issue-2465-use-extract-parameters
May 13, 2023
d783193
WIP
May 13, 2023
ce83ef1
Merge remote-tracking branch 'origin/issue-2465-use-extract-parameter…
May 13, 2023
89c42b5
WIP
May 13, 2023
5e194e3
WIP
May 13, 2023
d87e607
WIP
May 13, 2023
af3e0c4
WIP
May 13, 2023
54c194f
WIP
May 13, 2023
439bb7b
WIP
May 13, 2023
f002283
WIP
May 13, 2023
6f09db4
WIP
May 13, 2023
a7caeb0
WIP
May 13, 2023
2f350ba
WIP
May 13, 2023
b74bd94
Update internal/handlers/commonparams/params.go
May 15, 2023
57ffa78
WIP
May 15, 2023
faac1c4
Merge remote-tracking branch 'origin/issue-2465-use-extract-parameter…
May 15, 2023
2db00ce
WIP
May 15, 2023
bd52204
Merge branch 'main' into issue-2465-use-extract-parameters
May 15, 2023
4f58b74
Update internal/handlers/commonparams/extract_params.go
May 15, 2023
07e2d6d
WIP
May 15, 2023
902acdd
Merge remote-tracking branch 'origin/issue-2465-use-extract-parameter…
May 15, 2023
c5ae8d5
WIP
May 15, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
WIP
  • Loading branch information
Dmitry committed May 12, 2023
commit 4e382e7904f61dd058e5d1780aaa3f94f5d45cf6
44 changes: 37 additions & 7 deletions internal/handlers/common/findandmodify.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,15 @@ type FindAndModifyParams struct {
Comment string `ferretdb:"comment,opt"`
Query *types.Document `ferretdb:"query,opt"`
Sort *types.Document `ferretdb:"sort,opt"`
Update *types.Document `ferretdb:"update,opt"`
UpdateValue any `ferretdb:"update,opt"`
Remove bool `ferretdb:"remove,opt"`
Upsert bool `ferretdb:"upsert,opt"`
ReturnNewDocument bool `ferretdb:"new,opt"`
MaxTimeMS int64 `ferretdb:"maxTimeMS,opt"`

Update *types.Document `ferretdb:"-"`
Aggregation *types.Array `ferretdb:"-"`

HasUpdateOperators bool `ferretdb:"-"`

Let *types.Document `ferretdb:"let,unimplemented"`
Expand Down Expand Up @@ -91,24 +94,51 @@ func GetFindAndModifyParams(doc *types.Document, l *zap.Logger) (*FindAndModifyP
return nil, err
}

if params.Update != nil && params.Remove {
if params.UpdateValue == nil && !params.Remove {
return nil, commonerrors.NewCommandErrorMsg(
commonerrors.ErrFailedToParse,
"Cannot specify both an update and remove=true",
"Either an update or remove=true must be specified",
)
}

if params.Upsert && params.Remove {
if params.ReturnNewDocument && params.Remove {
return nil, commonerrors.NewCommandErrorMsg(
commonerrors.ErrFailedToParse,
"Cannot specify both upsert=true and remove=true",
"Cannot specify both new=true and remove=true; 'remove' always returns the deleted document",
)
}

if params.ReturnNewDocument && params.Remove {
if params.UpdateValue != nil {
switch updateParam := params.UpdateValue.(type) {
case *types.Document:
params.Update = updateParam
case *types.Array:
// TODO aggregation pipeline stages metrics
return nil, commonerrors.NewCommandErrorMsgWithArgument(
commonerrors.ErrNotImplemented,
"Aggregation pipelines are not supported yet",
"update",
)
default:
return nil, commonerrors.NewCommandErrorMsgWithArgument(
commonerrors.ErrFailedToParse,
"Update argument must be either an object or an array",
"update",
)
}
}

if params.Update != nil && params.Remove {
return nil, commonerrors.NewCommandErrorMsg(
commonerrors.ErrFailedToParse,
"Cannot specify both new=true and remove=true; 'remove' always returns the deleted document",
"Cannot specify both an update and remove=true",
)
}

if params.Upsert && params.Remove {
return nil, commonerrors.NewCommandErrorMsg(
commonerrors.ErrFailedToParse,
"Cannot specify both upsert=true and remove=true",
)
}

Expand Down
32 changes: 0 additions & 32 deletions internal/handlers/common/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,38 +82,6 @@ func GetOptionalNullParam[T types.Type](doc *types.Document, key string, default
return v, err
}

// GetBoolOptionalParam returns doc's bool value for key.
// Non-zero double, long, and int values return true.
// Zero values for those types, as well as nulls and missing fields, return false.
// Other types return a protocol error.
func GetBoolOptionalParam(doc *types.Document, key string) (bool, error) {
v, _ := doc.Get(key)
if v == nil {
return false, nil
}

switch v := v.(type) {
case float64:
return v != 0, nil
case bool:
return v, nil
case types.NullType:
return false, nil
case int32:
return v != 0, nil
case int64:
return v != 0, nil
default:
msg := fmt.Sprintf(
`BSON field '%s' is the wrong type '%s', expected types '[bool, long, int, decimal, double]'`,
key,
commonparams.AliasFromType(v),
)

return false, commonerrors.NewCommandErrorMsgWithArgument(commonerrors.ErrTypeMismatch, msg, key)
}
}

// AssertType asserts value's type, returning protocol error for unexpected types.
//
// If a custom error is needed, use a normal Go type assertion instead:
Expand Down
8 changes: 5 additions & 3 deletions internal/handlers/common/update_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,11 @@ func GetUpdateParams(document *types.Document, l *zap.Logger) (*UpdatesParams, e
return nil, err
}

for _, update := range params.Updates {
if err := ValidateUpdateOperators(document.Command(), update.Update); err != nil {
return nil, err
if params.Updates != nil {
for _, update := range params.Updates {
if err := ValidateUpdateOperators(document.Command(), update.Update); err != nil {
return nil, err
}
}
}

Expand Down
14 changes: 14 additions & 0 deletions internal/handlers/commonparams/extract_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,15 @@ func setStructField(elem *reflect.Value, i int, command, key string, val any, l
return err
}
case reflect.String, reflect.Bool, reflect.Struct, reflect.Pointer, reflect.Interface:
if command == "findAndModify" && key == "new" {
settable, err = GetBoolOptionalParam(val, key)
if err != nil {
return err
}

break
}

settable = val
case reflect.Slice:
array, ok := val.(*types.Array)
Expand Down Expand Up @@ -308,6 +317,11 @@ func setStructField(elem *reflect.Value, i int, command, key string, val any, l
)
}

if command == "findAndModify" && key == "update" {
fv.Set(reflect.ValueOf(v.Interface()))
return nil
}

return commonerrors.NewCommandErrorMsgWithArgument(
commonerrors.ErrTypeMismatch,
fmt.Sprintf(
Expand Down
27 changes: 27 additions & 0 deletions internal/handlers/commonparams/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,30 @@ func GetOptionalPositiveNumber(key string, value any) (int64, error) {

return param, nil
}

// GetBoolOptionalParam returns doc's bool value for key.
w84thesun marked this conversation as resolved.
Show resolved Hide resolved
// Non-zero double, long, and int values return true.
// Zero values for those types, as well as nulls and missing fields, return false.
// Other types return a protocol error.
func GetBoolOptionalParam(v any, key string) (bool, error) {
w84thesun marked this conversation as resolved.
Show resolved Hide resolved
switch v := v.(type) {
case float64:
return v != 0, nil
case bool:
return v, nil
case types.NullType:
return false, nil
case int32:
return v != 0, nil
case int64:
return v != 0, nil
default:
msg := fmt.Sprintf(
`BSON field '%s' is the wrong type '%s', expected types '[bool, long, int, decimal, double]'`,
key,
AliasFromType(v),
)

return false, commonerrors.NewCommandErrorMsgWithArgument(commonerrors.ErrTypeMismatch, msg, key)
}
}
18 changes: 12 additions & 6 deletions internal/handlers/pg/msg_getparameter.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (

"github.com/FerretDB/FerretDB/internal/handlers/common"
"github.com/FerretDB/FerretDB/internal/handlers/commonerrors"
"github.com/FerretDB/FerretDB/internal/handlers/commonparams"
"github.com/FerretDB/FerretDB/internal/types"
"github.com/FerretDB/FerretDB/internal/util/iterator"
"github.com/FerretDB/FerretDB/internal/util/lazyerrors"
Expand Down Expand Up @@ -130,13 +131,18 @@ func extractParam(document *types.Document) (showDetails, allParameters bool, er
}

if param, ok := getPrm.(*types.Document); ok {
showDetails, err = common.GetBoolOptionalParam(param, "showDetails")
if err != nil {
return false, false, lazyerrors.Error(err)
if v, _ := param.Get("showDetails"); v != nil {
showDetails, err = commonparams.GetBoolOptionalParam(v, "showDetails")
if err != nil {
return false, false, lazyerrors.Error(err)
}
}
allParameters, err = common.GetBoolOptionalParam(param, "allParameters")
if err != nil {
return false, false, lazyerrors.Error(err)
if v, _ := document.Get("allParameters"); v != nil {

allParameters, err = commonparams.GetBoolOptionalParam(v, "allParameters")
if err != nil {
return false, false, lazyerrors.Error(err)
}
}
}
if getPrm == "*" {
Expand Down
10 changes: 7 additions & 3 deletions internal/handlers/pg/msg_listcollections.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/jackc/pgx/v5"

"github.com/FerretDB/FerretDB/internal/handlers/common"
"github.com/FerretDB/FerretDB/internal/handlers/commonparams"
"github.com/FerretDB/FerretDB/internal/handlers/pg/pgdb"
"github.com/FerretDB/FerretDB/internal/types"
"github.com/FerretDB/FerretDB/internal/util/lazyerrors"
Expand Down Expand Up @@ -52,9 +53,12 @@ func (h *Handler) MsgListCollections(ctx context.Context, msg *wire.OpMsg) (*wir
return nil, err
}

nameOnly, err := common.GetBoolOptionalParam(document, "nameOnly")
if err != nil {
return nil, err
var nameOnly bool
if v, _ := document.Get("nameOnly"); v != nil {
nameOnly, err = commonparams.GetBoolOptionalParam(v, "nameOnly")
if err != nil {
return nil, err
}
}

var names []string
Expand Down
10 changes: 7 additions & 3 deletions internal/handlers/pg/msg_listdatabases.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/jackc/pgx/v5"

"github.com/FerretDB/FerretDB/internal/handlers/common"
"github.com/FerretDB/FerretDB/internal/handlers/commonparams"
"github.com/FerretDB/FerretDB/internal/handlers/pg/pgdb"
"github.com/FerretDB/FerretDB/internal/types"
"github.com/FerretDB/FerretDB/internal/util/lazyerrors"
Expand All @@ -46,9 +47,12 @@ func (h *Handler) MsgListDatabases(ctx context.Context, msg *wire.OpMsg) (*wire.

common.Ignored(document, h.L, "comment", "authorizedDatabases")

nameOnly, err := common.GetBoolOptionalParam(document, "nameOnly")
if err != nil {
return nil, err
var nameOnly bool
if v, _ := document.Get("nameOnly"); v != nil {
nameOnly, err = commonparams.GetBoolOptionalParam(v, "nameOnly")
if err != nil {
return nil, err
}
}

var totalSize int64
Expand Down
10 changes: 7 additions & 3 deletions internal/handlers/tigris/msg_listcollections.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"sort"

"github.com/FerretDB/FerretDB/internal/handlers/common"
"github.com/FerretDB/FerretDB/internal/handlers/commonparams"
"github.com/FerretDB/FerretDB/internal/types"
"github.com/FerretDB/FerretDB/internal/util/lazyerrors"
"github.com/FerretDB/FerretDB/internal/util/must"
Expand Down Expand Up @@ -49,9 +50,12 @@ func (h *Handler) MsgListCollections(ctx context.Context, msg *wire.OpMsg) (*wir
return nil, err
}

nameOnly, err := common.GetBoolOptionalParam(document, "nameOnly")
if err != nil {
return nil, err
var nameOnly bool
if v, _ := document.Get("nameOnly"); v != nil {
nameOnly, err = commonparams.GetBoolOptionalParam(v, "nameOnly")
if err != nil {
return nil, err
}
}

names, err := dbPool.Driver.UseDatabase(db).ListCollections(ctx)
Expand Down
10 changes: 7 additions & 3 deletions internal/handlers/tigris/msg_listdatabases.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"context"

"github.com/FerretDB/FerretDB/internal/handlers/common"
"github.com/FerretDB/FerretDB/internal/handlers/commonparams"
"github.com/FerretDB/FerretDB/internal/handlers/tigris/tigrisdb"
"github.com/FerretDB/FerretDB/internal/types"
"github.com/FerretDB/FerretDB/internal/util/lazyerrors"
Expand Down Expand Up @@ -49,9 +50,12 @@ func (h *Handler) MsgListDatabases(ctx context.Context, msg *wire.OpMsg) (*wire.
return nil, err
}

nameOnly, err := common.GetBoolOptionalParam(document, "nameOnly")
if err != nil {
return nil, err
var nameOnly bool
if v, _ := document.Get("nameOnly"); v != nil {
nameOnly, err = commonparams.GetBoolOptionalParam(v, "nameOnly")
if err != nil {
return nil, err
}
}

var totalSize int64
Expand Down