diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c9def35..b3072272 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -131,6 +131,8 @@ Versioning](http://semver.org/spec/v2.0.0.html) except to the first release. - Tests with crud 1.4.0 (#336) - Tests with case sensitive SQL (#341) - Splice update operation accepts 3 arguments instead of 5 (#348) +- A slice of custom types could be used as a slice of tuples and objects for + `crud.*ManyRequest/crud.*ObjectManyRequest` (#365) ## [1.12.0] - 2023-06-07 diff --git a/crud/example_test.go b/crud/example_test.go index c043bd5f..9377ce3d 100644 --- a/crud/example_test.go +++ b/crud/example_test.go @@ -85,6 +85,81 @@ func ExampleResult_rowsCustomType() { // [{{} 2010 45 bla}] } +// ExampleTuples_customType demonstrates how to use a slice of objects of a +// custom type as Tuples to make a ReplaceManyRequest. +func ExampleTuples()_customType { + conn := exampleConnect() + + // The type will be encoded/decoded as an array. + type Tuple struct { + _msgpack struct{} `msgpack:",asArray"` //nolint: structcheck,unused + Id uint64 + BucketId *uint64 + Name string + } + req := crud.MakeReplaceManyRequest(exampleSpace).Tuples([]Tuple{ + Tuple{ + Id: 2010, + BucketId: nil, + Name: "bla", + }, + }) + + ret := crud.MakeResult(reflect.TypeOf(Tuple{})) + if err := conn.Do(req).GetTyped(&ret); err != nil { + fmt.Printf("Failed to execute request: %s", err) + return + } + + fmt.Println(ret.Metadata) + rows := ret.Rows.([]Tuple) + fmt.Println(rows[0].Id) + fmt.Println(*rows[0].BucketId) + fmt.Println(rows[0].Name) + // Output: + // [{id unsigned false} {bucket_id unsigned true} {name string false}] + // 2010 + // 45 + // bla +} + +// ExampleObjects_customType demonstrates how to use a slice of objects of +// a custom type as Objects to make a ReplaceObjectManyRequest. +func ExampleObjects_customType() { + conn := exampleConnect() + + // The type will be encoded/decoded as a map. + type Tuple struct { + Id uint64 `msgpack:"id,omitempty"` + BucketId *uint64 `msgpack:"bucket_id,omitempty"` + Name string `msgpack:"name,omitempty"` + } + req := crud.MakeReplaceObjectManyRequest(exampleSpace).Objects([]Tuple{ + Tuple{ + Id: 2010, + BucketId: nil, + Name: "bla", + }, + }) + + ret := crud.MakeResult(reflect.TypeOf(Tuple{})) + if err := conn.Do(req).GetTyped(&ret); err != nil { + fmt.Printf("Failed to execute request: %s", err) + return + } + + fmt.Println(ret.Metadata) + rows := ret.Rows.([]Tuple) + fmt.Println(rows[0].Id) + fmt.Println(*rows[0].BucketId) + fmt.Println(rows[0].Name) + // Output: + // [{id unsigned false} {bucket_id unsigned true} {name string false}] + // 2010 + // 45 + // bla +} + // ExampleResult_operationData demonstrates how to obtain information // about erroneous objects from crud.Error using `OperationData` field. func ExampleResult_operationData() { diff --git a/crud/insert_many.go b/crud/insert_many.go index 602e210d..866c1ceb 100644 --- a/crud/insert_many.go +++ b/crud/insert_many.go @@ -15,14 +15,14 @@ type InsertManyOpts = OperationManyOpts // `crud.insert_many` for execution by a Connection. type InsertManyRequest struct { spaceRequest - tuples []Tuple + tuples Tuples opts InsertManyOpts } type insertManyArgs struct { _msgpack struct{} `msgpack:",asArray"` //nolint: structcheck,unused Space string - Tuples []Tuple + Tuples Tuples Opts InsertManyOpts } @@ -37,7 +37,7 @@ func MakeInsertManyRequest(space string) InsertManyRequest { // Tuples sets the tuples for the InsertManyRequest request. // Note: default value is nil. -func (req InsertManyRequest) Tuples(tuples []Tuple) InsertManyRequest { +func (req InsertManyRequest) Tuples(tuples Tuples) InsertManyRequest { req.tuples = tuples return req } @@ -73,14 +73,14 @@ type InsertObjectManyOpts = OperationObjectManyOpts // `crud.insert_object_many` for execution by a Connection. type InsertObjectManyRequest struct { spaceRequest - objects []Object + objects Objects opts InsertObjectManyOpts } type insertObjectManyArgs struct { _msgpack struct{} `msgpack:",asArray"` //nolint: structcheck,unused Space string - Objects []Object + Objects Objects Opts InsertObjectManyOpts } @@ -95,7 +95,7 @@ func MakeInsertObjectManyRequest(space string) InsertObjectManyRequest { // Objects sets the objects for the InsertObjectManyRequest request. // Note: default value is nil. -func (req InsertObjectManyRequest) Objects(objects []Object) InsertObjectManyRequest { +func (req InsertObjectManyRequest) Objects(objects Objects) InsertObjectManyRequest { req.objects = objects return req } diff --git a/crud/object.go b/crud/object.go index 3f266a7e..769ddb0d 100644 --- a/crud/object.go +++ b/crud/object.go @@ -4,10 +4,14 @@ import ( "github.com/vmihailenco/msgpack/v5" ) -// Object is an interface to describe object for CRUD methods. -type Object interface { - EncodeMsgpack(enc *msgpack.Encoder) -} +// Object is an interface to describe object for CRUD methods. It can be any +// type that msgpack can encode as a map. +type Object = interface{} + +// Objects is a type to describe an array of object for CRUD methods. It can be +// any type that msgpack can encode, but encoded data must be an array of +// objects. +type Objects = interface{} // MapObject is a type to describe object as a map. type MapObject map[string]interface{} diff --git a/crud/replace_many.go b/crud/replace_many.go index 77c94771..5a5143ef 100644 --- a/crud/replace_many.go +++ b/crud/replace_many.go @@ -15,14 +15,14 @@ type ReplaceManyOpts = OperationManyOpts // `crud.replace_many` for execution by a Connection. type ReplaceManyRequest struct { spaceRequest - tuples []Tuple + tuples Tuples opts ReplaceManyOpts } type replaceManyArgs struct { _msgpack struct{} `msgpack:",asArray"` //nolint: structcheck,unused Space string - Tuples []Tuple + Tuples Tuples Opts ReplaceManyOpts } @@ -37,7 +37,7 @@ func MakeReplaceManyRequest(space string) ReplaceManyRequest { // Tuples sets the tuples for the ReplaceManyRequest request. // Note: default value is nil. -func (req ReplaceManyRequest) Tuples(tuples []Tuple) ReplaceManyRequest { +func (req ReplaceManyRequest) Tuples(tuples Tuples) ReplaceManyRequest { req.tuples = tuples return req } @@ -73,14 +73,14 @@ type ReplaceObjectManyOpts = OperationObjectManyOpts // `crud.replace_object_many` for execution by a Connection. type ReplaceObjectManyRequest struct { spaceRequest - objects []Object + objects Objects opts ReplaceObjectManyOpts } type replaceObjectManyArgs struct { _msgpack struct{} `msgpack:",asArray"` //nolint: structcheck,unused Space string - Objects []Object + Objects Objects Opts ReplaceObjectManyOpts } @@ -95,7 +95,7 @@ func MakeReplaceObjectManyRequest(space string) ReplaceObjectManyRequest { // Objects sets the tuple for the ReplaceObjectManyRequest request. // Note: default value is nil. -func (req ReplaceObjectManyRequest) Objects(objects []Object) ReplaceObjectManyRequest { +func (req ReplaceObjectManyRequest) Objects(objects Objects) ReplaceObjectManyRequest { req.objects = objects return req } diff --git a/crud/tuple.go b/crud/tuple.go index 61291cbb..ef4413c2 100644 --- a/crud/tuple.go +++ b/crud/tuple.go @@ -1,5 +1,10 @@ package crud // Tuple is a type to describe tuple for CRUD methods. It can be any type that -// msgpask can encode. +// msgpask can encode as an array. type Tuple = interface{} + +// Tuples is a type to describe an array of tuples for CRUD methods. It can be +// any type that msgpack can encode, but encoded data must be an array of +// tuples. +type Tuples = interface{}