diff --git a/go.mod b/go.mod index 7f0cf72387f..f5df5279ce5 100644 --- a/go.mod +++ b/go.mod @@ -19,6 +19,7 @@ require ( github.com/go-openapi/swag v0.19.5 github.com/go-openapi/validate v0.19.8 github.com/gocql/gocql v0.0.0-20200815110948-5378c8f664e9 + github.com/golang/snappy v0.0.1 // indirect github.com/google/go-cmp v0.5.2 github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed github.com/hashicorp/go-version v1.2.1 @@ -30,7 +31,6 @@ require ( github.com/pkg/errors v0.9.1 github.com/scylladb/go-log v0.0.4 github.com/scylladb/go-set v1.0.2 - github.com/scylladb/gocqlx/v2 v2.2.0 github.com/shurcooL/githubv4 v0.0.0-20201206200315-234843c633fa github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a // indirect github.com/spf13/cobra v1.1.1 diff --git a/go.sum b/go.sum index f0f695524a7..4e756b028b7 100644 --- a/go.sum +++ b/go.sum @@ -253,7 +253,6 @@ github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gobuffalo/flect v0.2.0 h1:EWCvMGGxOjsgwlWaP+f4+Hh6yrrte7JeFL2S6b+0hdM= github.com/gobuffalo/flect v0.2.0/go.mod h1:W3K3X9ksuZfir8f/LrfVtWmCDQFfayuylOJ7sz/Fj80= -github.com/gocql/gocql v0.0.0-20200131111108-92af2e088537/go.mod h1:DL0ekTmBSTdlNF25Orwt/JMzqIq3EJ4MVa/J/uK64OY= github.com/gocql/gocql v0.0.0-20200815110948-5378c8f664e9 h1:SBOCi413wRa7i5ZET6dmeg8iqpKO/hE+buwIZ7WhNg4= github.com/gocql/gocql v0.0.0-20200815110948-5378c8f664e9/go.mod h1:DL0ekTmBSTdlNF25Orwt/JMzqIq3EJ4MVa/J/uK64OY= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -511,12 +510,8 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/scylladb/go-log v0.0.4 h1:/bzRRcdQueZGOAxvRmvAiaPutgyde45KG53cfOfVnTY= github.com/scylladb/go-log v0.0.4/go.mod h1:77kz90eX2HHKZUL4Os8on7+8t1CmF6oiSqsgX9Hg+30= -github.com/scylladb/go-reflectx v1.0.1 h1:b917wZM7189pZdlND9PbIJ6NQxfDPfBvUaQ7cjj1iZQ= -github.com/scylladb/go-reflectx v1.0.1/go.mod h1:rWnOfDIRWBGN0miMLIcoPt/Dhi2doCMZqwMCJ3KupFc= github.com/scylladb/go-set v1.0.2 h1:SkvlMCKhP0wyyct6j+0IHJkBkSZL+TDzZ4E7f7BCcRE= github.com/scylladb/go-set v1.0.2/go.mod h1:DkpGd78rljTxKAnTDPFqXSGxvETQnJyuSOQwsHycqfs= -github.com/scylladb/gocqlx/v2 v2.2.0 h1:dJ2+HrmMkY1sSOXI2eVkcvA01RFJX9KDOkKob+E/v+A= -github.com/scylladb/gocqlx/v2 v2.2.0/go.mod h1:G1Cuw/NcqM0Mnj5zTRihdx7aW3yBk9zxR+XqCV3aCAA= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= @@ -709,8 +704,6 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/pkg/controllers/cluster/actions/upgrade_version.go b/pkg/controllers/cluster/actions/upgrade_version.go index 4adff747256..0fa12359a1b 100644 --- a/pkg/controllers/cluster/actions/upgrade_version.go +++ b/pkg/controllers/cluster/actions/upgrade_version.go @@ -5,15 +5,12 @@ import ( "fmt" "reflect" "sort" - "strings" "time" "github.com/blang/semver" - "github.com/gocql/gocql" "github.com/pkg/errors" "github.com/scylladb/go-log" "github.com/scylladb/go-set/strset" - "github.com/scylladb/gocqlx/v2" scyllav1 "github.com/scylladb/scylla-operator/pkg/api/scylla/v1" "github.com/scylladb/scylla-operator/pkg/controllers/cluster/resource" "github.com/scylladb/scylla-operator/pkg/controllers/cluster/util" @@ -39,9 +36,8 @@ const ( ) type ClusterVersionUpgrade struct { - Cluster *scyllav1.ScyllaCluster - ScyllaClient *scyllaclient.Client - ClusterSession CQLSession + Cluster *scyllav1.ScyllaCluster + ScyllaClient *scyllaclient.Client ipMapping map[string]string pollInterval time.Duration @@ -72,15 +68,6 @@ var ScyllaClientForClusterFunc = func(ctx context.Context, cc client.Client, hos return scyllaclient.NewClient(cfg, logger) } -type CQLSession interface { - AwaitSchemaAgreement(ctx context.Context) error -} - -var NewSessionFunc = func(hosts []string) (CQLSession, error) { - cluster := gocql.NewCluster(hosts...) - return gocqlx.WrapSession(cluster.CreateSession()) -} - func (a *ClusterVersionUpgrade) nonMaintenanceHosts(ctx context.Context) ([]string, error) { var hosts []string for _, r := range a.Cluster.Spec.Datacenter.Racks { @@ -171,11 +158,6 @@ func (a *ClusterVersionUpgrade) genericUpgrade(ctx context.Context) error { return errors.Wrap(err, "create scylla client") } - a.ClusterSession, err = NewSessionFunc(hosts) - if err != nil { - return errors.Wrap(err, "create scylla session") - } - if err := a.fsm().Transition(ctx); err != nil { return errors.Wrap(err, "upgrade fsm transition") } @@ -391,13 +373,7 @@ func (a *ClusterVersionUpgrade) beginUpgrade(ctx context.Context) (fsm.Event, er func (a *ClusterVersionUpgrade) checkSchemaAgreement(ctx context.Context) (fsm.Event, error) { if err := wait.PollImmediate(a.pollInterval, actionTimeout, func() (bool, error) { - if err := a.ClusterSession.AwaitSchemaAgreement(ctx); err != nil { - if strings.Contains(err.Error(), "cluster schema versions not consistent") { - return false, nil - } - return false, err - } - return true, nil + return a.ScyllaClient.HasSchemaAgreement(ctx) }); err != nil { return ActionFailure, errors.Wrap(err, "await schema agreement") } diff --git a/pkg/scyllaclient/client.go b/pkg/scyllaclient/client.go index da21ecddea1..2586cf2f3e7 100644 --- a/pkg/scyllaclient/client.go +++ b/pkg/scyllaclient/client.go @@ -288,6 +288,19 @@ func (c *Client) IsNativeTransportEnabled(ctx context.Context, host string) (boo return resp.Payload, nil } +func (c *Client) HasSchemaAgreement(ctx context.Context) (bool, error) { + resp, err := c.scyllaOps.StorageProxySchemaVersionsGet(&scyllaOperations.StorageProxySchemaVersionsGetParams{Context: ctx}) + if err != nil { + return false, err + } + versions := map[string]struct{}{} + for _, kv := range resp.Payload { + versions[kv.Key] = struct{}{} + } + + return len(versions) == 1, nil +} + func DefaultTransport() *http.Transport { return &http.Transport{ Proxy: http.ProxyFromEnvironment, diff --git a/pkg/test/integration/scylla.go b/pkg/test/integration/scylla.go index 4cfe4995db8..8ddbf7fc3fb 100644 --- a/pkg/test/integration/scylla.go +++ b/pkg/test/integration/scylla.go @@ -73,6 +73,8 @@ func (s *ScyllaFake) handler(w http.ResponseWriter, r *http.Request) { s.drainRequests++ case r.URL.Path == "/storage_service/operation_mode" && r.Method == http.MethodGet: fmt.Fprintf(w, "%q", s.operationalMode) + case r.URL.Path == "/storage_proxy/schema_versions" && r.Method == http.MethodGet: + fmt.Fprintf(w, `[{"key": "e478e0ca-08f6-39ac-bc9d-a50283aaf200", "value": ["1.1.1.1", "2.2.2.2"]}]`) } } diff --git a/test/integration/upgrade_version_test.go b/test/integration/upgrade_version_test.go index f225926655c..7a5e1923eeb 100644 --- a/test/integration/upgrade_version_test.go +++ b/test/integration/upgrade_version_test.go @@ -109,7 +109,6 @@ var _ = Describe("Cluster controller", func() { scylla *scyllav1.ScyllaCluster sstStub *integration.StatefulSetOperatorStub - originalActionsNewSessionFunc func(hosts []string) (actions.CQLSession, error) originalActionsScyllaClientForClusterFunc func(ctx context.Context, cc client.Client, hosts []string, logger log.Logger) (*scyllaclient.Client, error) ) @@ -132,12 +131,10 @@ var _ = Describe("Cluster controller", func() { Expect(sstStub.CreatePods(ctx, scylla)).To(Succeed()) } - originalActionsNewSessionFunc = actions.NewSessionFunc originalActionsScyllaClientForClusterFunc = actions.ScyllaClientForClusterFunc }) AfterEach(func() { - actions.NewSessionFunc = originalActionsNewSessionFunc actions.ScyllaClientForClusterFunc = originalActionsScyllaClientForClusterFunc Expect(testEnv.Delete(ctx, scylla)).To(Succeed()) }) @@ -182,10 +179,6 @@ var _ = Describe("Cluster controller", func() { return http.DefaultClient.Do(req) })) - actions.NewSessionFunc = func(hosts []string) (actions.CQLSession, error) { - return cqlSessionStub{}, nil - } - actions.ScyllaClientForClusterFunc = func(ctx context.Context, cc client.Client, hosts []string, logger log.Logger) (*scyllaclient.Client, error) { cfg := scyllaclient.DefaultConfig(scyllaAddr) cfg.Transport = hrt @@ -332,11 +325,3 @@ func markPodReady(pods *corev1.PodList, idx int) error { return nil } - -type cqlSessionStub struct { -} - -func (c cqlSessionStub) AwaitSchemaAgreement(ctx context.Context) error { - // Always succeed - return nil -} diff --git a/vendor/github.com/scylladb/go-reflectx/.golangci.yml b/vendor/github.com/scylladb/go-reflectx/.golangci.yml deleted file mode 100644 index 6a351eef713..00000000000 --- a/vendor/github.com/scylladb/go-reflectx/.golangci.yml +++ /dev/null @@ -1,21 +0,0 @@ -run: - deadline: 5m - tests: false - silent: true - -linters-settings: - lll: - line-length: 180 - -linters: - enable-all: true - disable: - - dupl - - gas - - interfacer - -issues: - exclude-use-default: false - exclude: - - composite literal uses unkeyed fields - - Error return value of `.+\.Close` is not checked diff --git a/vendor/github.com/scylladb/go-reflectx/.travis.yml b/vendor/github.com/scylladb/go-reflectx/.travis.yml deleted file mode 100644 index 5bce879e04c..00000000000 --- a/vendor/github.com/scylladb/go-reflectx/.travis.yml +++ /dev/null @@ -1,10 +0,0 @@ -sudo: false -language: go -go: -- 1.11.x - -install: -- make get-deps get-tools - -script: -- make diff --git a/vendor/github.com/scylladb/go-reflectx/LICENSE b/vendor/github.com/scylladb/go-reflectx/LICENSE deleted file mode 100644 index 4947287f7b5..00000000000 --- a/vendor/github.com/scylladb/go-reflectx/LICENSE +++ /dev/null @@ -1,177 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/vendor/github.com/scylladb/go-reflectx/Makefile b/vendor/github.com/scylladb/go-reflectx/Makefile deleted file mode 100644 index 4395e8eaed3..00000000000 --- a/vendor/github.com/scylladb/go-reflectx/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -all: check test - -ifndef GOBIN -export GOBIN := $(GOPATH)/bin -endif - -define dl - @curl -sSq -L $(2) -o $(GOBIN)/$(1) && chmod u+x $(GOBIN)/$(1) -endef - -define dl_tgz - @curl -sSq -L $(2) | tar zxf - --strip 1 -C $(GOBIN) --wildcards '*/$(1)' -endef - -.PHONY: fmt -fmt: - @go fmt ./... - -.PHONY: check -check: - @$(GOBIN)/golangci-lint run ./... - -.PHONY: test -test: - go test -cover -race ./... - -.PHONY: bench -bench: - @go test -tags all -run=XXX -bench=. -benchmem ./... - -.PHONY: get-deps -get-deps: - go get -t ./... - -.PHONY: get-tools -get-tools: - @echo "==> Installing tools at $(GOBIN)..." - @$(call dl_tgz,golangci-lint,https://github.com/golangci/golangci-lint/releases/download/v1.13.1/golangci-lint-1.13.1-linux-amd64.tar.gz) diff --git a/vendor/github.com/scylladb/go-reflectx/README.md b/vendor/github.com/scylladb/go-reflectx/README.md deleted file mode 100644 index 6c342761508..00000000000 --- a/vendor/github.com/scylladb/go-reflectx/README.md +++ /dev/null @@ -1,49 +0,0 @@ -# Reflectx [![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/scylladb/go-reflectx) [![Go Report Card](https://goreportcard.com/badge/github.com/scylladb/go-reflectx)](https://goreportcard.com/report/github.com/scylladb/go-reflectx) [![Build Status](https://travis-ci.org/scylladb/go-reflectx.svg?branch=master)](https://travis-ci.org/scylladb/go-reflectx) - -Package reflectx implements extensions to the standard reflect lib suitable for implementing marshalling and unmarshalling packages. -The main Mapper type allows for Go-compatible named attribute access, including accessing embedded struct attributes and the ability to use functions and struct tags to customize field names. - -This is a standalone version of `reflectx` package that originates from an SQL row to struct mapper [sqlx](https://github.com/jmoiron/sqlx). -We are using it at [Scylla gocqlx](https://github.com/scylladb/gocqlx) for scanning of CQL results to structs and slices. - -## Example - -This example demonstrates usage of the reflectx package to automatically bind URL parameters to a request model. - -```go -type RequestContext struct { - SessionID string `http:"sid"` -} - -type SearchRequest struct { - RequestContext - Labels []string `http:"l"` - MaxResults int `http:"max"` - Exact bool `http:"x"` -} - -func Search(w http.ResponseWriter, r *http.Request) { - // URL /search?sid=id&l=foo&l=bar&max=100&x=true - if err := r.ParseForm(); err != nil { - w.WriteHeader(http.StatusBadRequest) - return - } - var data SearchRequest - if err := bindParams(r, &data); err != nil { - w.WriteHeader(http.StatusBadRequest) - return - } - log.Printf("%+v", data) // "RequestContext:{SessionID:id} Labels:[foo bar] MaxResults:100 Exact:true}" -} -``` - -See the full example in [example_test.go](example_test.go). - -## License - -Copyright (C) 2019 ScyllaDB - -This project is distributed under the Apache 2.0 license. See the [LICENSE](https://github.com/scylladb/go-reflectx/blob/master/LICENSE) file for details. -It contains software from: - -* [sqlx project](https://github.com/jmoiron/sqlx), licensed under the MIT license diff --git a/vendor/github.com/scylladb/go-reflectx/reflect.go b/vendor/github.com/scylladb/go-reflectx/reflect.go deleted file mode 100644 index e160f734348..00000000000 --- a/vendor/github.com/scylladb/go-reflectx/reflect.go +++ /dev/null @@ -1,439 +0,0 @@ -// Copyright (C) 2019 ScyllaDB -// Use of this source code is governed by a ALv2-style -// license that can be found in the LICENSE file. -// Copyright (C) github.com/jmoiron/sqlx authors, licensed under the MIT license. - -// Package reflectx implements extensions to the standard reflect lib suitable -// for implementing marshalling and unmarshalling packages. The main Mapper type -// allows for Go-compatible named attribute access, including accessing embedded -// struct attributes and the ability to use functions and struct tags to -// customize field names. -// -package reflectx - -import ( - "reflect" - "runtime" - "strings" - "sync" -) - -// A FieldInfo is metadata for a struct field. -type FieldInfo struct { - Index []int - Path string - Field reflect.StructField - Zero reflect.Value - Name string - Options map[string]string - Embedded bool - Children []*FieldInfo - Parent *FieldInfo -} - -// A StructMap is an index of field metadata for a struct. -type StructMap struct { - Tree *FieldInfo - Index []*FieldInfo - Paths map[string]*FieldInfo - Names map[string]*FieldInfo -} - -// GetByPath returns a *FieldInfo for a given string path. -func (f StructMap) GetByPath(path string) *FieldInfo { - return f.Paths[path] -} - -// GetByTraversal returns a *FieldInfo for a given integer path. It is -// analogous to reflect.FieldByIndex, but using the cached traversal -// rather than re-executing the reflect machinery each time. -func (f StructMap) GetByTraversal(index []int) *FieldInfo { - if len(index) == 0 { - return nil - } - - tree := f.Tree - for _, i := range index { - if i >= len(tree.Children) || tree.Children[i] == nil { - return nil - } - tree = tree.Children[i] - } - return tree -} - -// Mapper is a general purpose mapper of names to struct fields. A Mapper -// behaves like most marshallers in the standard library, obeying a field tag -// for name mapping but also providing a basic transform function. -type Mapper struct { - cache sync.Map // map[reflect.Type]*StructMap - tagName string - tagMapFunc func(string) string - mapFunc func(string) string -} - -// NewMapper returns a new mapper using the tagName as its struct field tag. -// If tagName is the empty string, it is ignored. -func NewMapper(tagName string) *Mapper { - return &Mapper{ - tagName: tagName, - } -} - -// NewMapperTagFunc returns a new mapper which contains a mapper for field names -// AND a mapper for tag values. This is useful for tags like json which can -// have values like "name,omitempty". -func NewMapperTagFunc(tagName string, mapFunc, tagMapFunc func(string) string) *Mapper { - return &Mapper{ - tagName: tagName, - mapFunc: mapFunc, - tagMapFunc: tagMapFunc, - } -} - -// NewMapperFunc returns a new mapper which optionally obeys a field tag and -// a struct field name mapper func given by f. Tags will take precedence, but -// for any other field, the mapped name will be f(field.Name) -func NewMapperFunc(tagName string, f func(string) string) *Mapper { - return &Mapper{ - tagName: tagName, - mapFunc: f, - } -} - -// TypeMap returns a mapping of field strings to int slices representing -// the traversal down the struct to reach the field. -func (m *Mapper) TypeMap(t reflect.Type) *StructMap { - if mapping, ok := m.cache.Load(t); ok { - return mapping.(*StructMap) - } - - mapping, _ := m.cache.LoadOrStore(t, getMapping(t, m.tagName, m.mapFunc, m.tagMapFunc)) - - return mapping.(*StructMap) -} - -// FieldMap returns the mapper's mapping of field names to reflect values. Panics -// if v's Kind is not Struct, or v is not Indirectable to a struct kind. -func (m *Mapper) FieldMap(v reflect.Value) map[string]reflect.Value { - v = reflect.Indirect(v) - mustBe(v, reflect.Struct) - - r := map[string]reflect.Value{} - tm := m.TypeMap(v.Type()) - for tagName, fi := range tm.Names { - r[tagName] = FieldByIndexes(v, fi.Index) - } - return r -} - -// FieldByName returns a field by its mapped name as a reflect.Value. -// Panics if v's Kind is not Struct or v is not Indirectable to a struct Kind. -// Returns zero Value if the name is not found. -func (m *Mapper) FieldByName(v reflect.Value, name string) reflect.Value { - v = reflect.Indirect(v) - mustBe(v, reflect.Struct) - - tm := m.TypeMap(v.Type()) - fi, ok := tm.Names[name] - if !ok { - return v - } - return FieldByIndexes(v, fi.Index) -} - -// FieldsByName returns a slice of values corresponding to the slice of names -// for the value. Panics if v's Kind is not Struct or v is not Indirectable -// to a struct Kind. Returns zero Value for each name not found. -func (m *Mapper) FieldsByName(v reflect.Value, names []string) []reflect.Value { - v = reflect.Indirect(v) - mustBe(v, reflect.Struct) - - tm := m.TypeMap(v.Type()) - vals := make([]reflect.Value, 0, len(names)) - for _, name := range names { - fi, ok := tm.Names[name] - if !ok { - vals = append(vals, *new(reflect.Value)) - } else { - vals = append(vals, FieldByIndexes(v, fi.Index)) - } - } - return vals -} - -// TraversalsByName returns a slice of int slices which represent the struct -// traversals for each mapped name. Panics if t is not a struct or Indirectable -// to a struct. Returns empty int slice for each name not found. -func (m *Mapper) TraversalsByName(t reflect.Type, names []string) [][]int { - r := make([][]int, 0, len(names)) - m.TraversalsByNameFunc(t, names, func(_ int, i []int) error { // nolint - if i == nil { - r = append(r, []int{}) - } else { - r = append(r, i) - } - - return nil - }) - return r -} - -// TraversalsByNameFunc traverses the mapped names and calls fn with the index of -// each name and the struct traversal represented by that name. Panics if t is not -// a struct or Indirectable to a struct. Returns the first error returned by fn or nil. -func (m *Mapper) TraversalsByNameFunc(t reflect.Type, names []string, fn func(int, []int) error) error { - t = Deref(t) - mustBe(t, reflect.Struct) - tm := m.TypeMap(t) - for i, name := range names { - fi, ok := tm.Names[name] - if !ok { - if err := fn(i, nil); err != nil { - return err - } - } else { - if err := fn(i, fi.Index); err != nil { - return err - } - } - } - return nil -} - -// FieldByIndexes returns a value for the field given by the struct traversal -// for the given value. -func FieldByIndexes(v reflect.Value, indexes []int) reflect.Value { - for _, i := range indexes { - v = reflect.Indirect(v).Field(i) - // if this is a pointer and it's nil, allocate a new value and set it - if v.Kind() == reflect.Ptr && v.IsNil() { - alloc := reflect.New(Deref(v.Type())) - v.Set(alloc) - } - if v.Kind() == reflect.Map && v.IsNil() { - v.Set(reflect.MakeMap(v.Type())) - } - } - return v -} - -// FieldByIndexesReadOnly returns a value for a particular struct traversal, -// but is not concerned with allocating nil pointers because the value is -// going to be used for reading and not setting. -func FieldByIndexesReadOnly(v reflect.Value, indexes []int) reflect.Value { - for _, i := range indexes { - v = reflect.Indirect(v).Field(i) - } - return v -} - -// Deref is Indirect for reflect.Types -func Deref(t reflect.Type) reflect.Type { - if t.Kind() == reflect.Ptr { - t = t.Elem() - } - return t -} - -// -- helpers & utilities -- - -type kinder interface { - Kind() reflect.Kind -} - -// mustBe checks a value against a kind, panicing with a reflect.ValueError -// if the kind isn't that which is required. -func mustBe(v kinder, expected reflect.Kind) { // nolint: unparam - if k := v.Kind(); k != expected { - panic(&reflect.ValueError{Method: methodName(), Kind: k}) - } -} - -// methodName returns the caller of the function calling methodName -func methodName() string { - pc, _, _, _ := runtime.Caller(2) - f := runtime.FuncForPC(pc) - if f == nil { - return "unknown method" - } - return f.Name() -} - -type typeQueue struct { - t reflect.Type - fi *FieldInfo - pp string // Parent path -} - -// A copying append that creates a new slice each time. -func apnd(is []int, i int) []int { - x := make([]int, len(is)+1) - copy(x, is) - x[len(x)-1] = i - return x -} - -type mapf func(string) string - -// parseName parses the tag and the target name for the given field using -// the tagName (eg 'json' for `json:"foo"` tags), mapFunc for mapping the -// field's name to a target name, and tagMapFunc for mapping the tag to -// a target name. -func parseName(field reflect.StructField, tagName string, mapFunc, tagMapFunc mapf) (tag, fieldName string) { - // first, set the fieldName to the field's name - fieldName = field.Name - // if a mapFunc is set, use that to override the fieldName - if mapFunc != nil { - fieldName = mapFunc(fieldName) - } - - // if there's no tag to look for, return the field name - if tagName == "" { - return "", fieldName - } - - // if this tag is not set using the normal convention in the tag, - // then return the fieldname.. this check is done because according - // to the reflect documentation: - // If the tag does not have the conventional format, - // the value returned by Get is unspecified. - // which doesn't sound great. - if !strings.Contains(string(field.Tag), tagName+":") { - return "", fieldName - } - - // at this point we're fairly sure that we have a tag, so lets pull it out - tag = field.Tag.Get(tagName) - - // if we have a mapper function, call it on the whole tag - // XXX: this is a change from the old version, which pulled out the name - // before the tagMapFunc could be run, but I think this is the right way - if tagMapFunc != nil { - tag = tagMapFunc(tag) - } - - // finally, split the options from the name - parts := strings.Split(tag, ",") - fieldName = parts[0] - - return tag, fieldName -} - -// parseOptions parses options out of a tag string, skipping the name -func parseOptions(tag string) map[string]string { - parts := strings.Split(tag, ",") - options := make(map[string]string, len(parts)) - if len(parts) > 1 { - for _, opt := range parts[1:] { - // short circuit potentially expensive split op - if strings.Contains(opt, "=") { - kv := strings.Split(opt, "=") - options[kv[0]] = kv[1] - continue - } - options[opt] = "" - } - } - return options -} - -// getMapping returns a mapping for the t type, using the tagName, mapFunc and -// tagMapFunc to determine the canonical names of fields. -func getMapping(t reflect.Type, tagName string, mapFunc, tagMapFunc mapf) *StructMap { - m := []*FieldInfo{} - - root := &FieldInfo{} - queue := []typeQueue{} - queue = append(queue, typeQueue{Deref(t), root, ""}) - -QueueLoop: - for len(queue) != 0 { - // pop the first item off of the queue - tq := queue[0] - queue = queue[1:] - - // ignore recursive field - for p := tq.fi.Parent; p != nil; p = p.Parent { - if tq.fi.Field.Type == p.Field.Type { - continue QueueLoop - } - } - - nChildren := 0 - if tq.t.Kind() == reflect.Struct { - nChildren = tq.t.NumField() - } - tq.fi.Children = make([]*FieldInfo, nChildren) - - // iterate through all of its fields - for fieldPos := 0; fieldPos < nChildren; fieldPos++ { - - f := tq.t.Field(fieldPos) - - // parse the tag and the target name using the mapping options for this field - tag, name := parseName(f, tagName, mapFunc, tagMapFunc) - - // if the name is "-", disabled via a tag, skip it - if name == "-" { - continue - } - - fi := FieldInfo{ - Field: f, - Name: name, - Zero: reflect.New(f.Type).Elem(), - Options: parseOptions(tag), - } - - // if the path is empty this path is just the name - if tq.pp == "" { - fi.Path = fi.Name - } else { - fi.Path = tq.pp + "." + fi.Name - } - - // skip unexported fields - if len(f.PkgPath) != 0 && !f.Anonymous { - continue - } - - // bfs search of anonymous embedded structs - if f.Anonymous { - pp := tq.pp - if tag != "" { - pp = fi.Path - } - - fi.Embedded = true - fi.Index = apnd(tq.fi.Index, fieldPos) - nChildren := 0 - ft := Deref(f.Type) - if ft.Kind() == reflect.Struct { - nChildren = ft.NumField() - } - fi.Children = make([]*FieldInfo, nChildren) - queue = append(queue, typeQueue{Deref(f.Type), &fi, pp}) - } else if fi.Zero.Kind() == reflect.Struct || (fi.Zero.Kind() == reflect.Ptr && fi.Zero.Type().Elem().Kind() == reflect.Struct) { - fi.Index = apnd(tq.fi.Index, fieldPos) - fi.Children = make([]*FieldInfo, Deref(f.Type).NumField()) - queue = append(queue, typeQueue{Deref(f.Type), &fi, fi.Path}) - } - - fi.Index = apnd(tq.fi.Index, fieldPos) - fi.Parent = tq.fi - tq.fi.Children[fieldPos] = &fi - m = append(m, &fi) - } - } - - flds := &StructMap{Index: m, Tree: root, Paths: map[string]*FieldInfo{}, Names: map[string]*FieldInfo{}} - for _, fi := range flds.Index { - flds.Paths[fi.Path] = fi - if fi.Name != "" && !fi.Embedded { - flds.Names[fi.Path] = fi - } - } - - return flds -} diff --git a/vendor/github.com/scylladb/go-reflectx/transform.go b/vendor/github.com/scylladb/go-reflectx/transform.go deleted file mode 100644 index c2170137711..00000000000 --- a/vendor/github.com/scylladb/go-reflectx/transform.go +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2019 ScyllaDB -// Use of this source code is governed by a ALv2-style -// license that can be found in the LICENSE file. - -package reflectx - -import ( - "fmt" - "unicode" -) - -// CamelToSnakeASCII converts camel case strings to snake case. For performance -// reasons it only works with ASCII strings. -func CamelToSnakeASCII(s string) string { - buf := []byte(s) - out := make([]byte, 0, len(buf)+3) - - l := len(buf) - for i := 0; i < l; i++ { - if !(allowedBindRune(buf[i]) || buf[i] == '_') { - panic(fmt.Sprint("not allowed name ", s)) - } - - b := rune(buf[i]) - - if unicode.IsUpper(b) { - if i > 0 && buf[i-1] != '_' && (unicode.IsLower(rune(buf[i-1])) || (i+1 < l && unicode.IsLower(rune(buf[i+1])))) { - out = append(out, '_') - } - b = unicode.ToLower(b) - } - - out = append(out, byte(b)) - } - - return string(out) -} - -func allowedBindRune(b byte) bool { - return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || (b >= '0' && b <= '9') -} diff --git a/vendor/github.com/scylladb/gocqlx/v2/.gitignore b/vendor/github.com/scylladb/gocqlx/v2/.gitignore deleted file mode 100644 index a1a3fb9c994..00000000000 --- a/vendor/github.com/scylladb/gocqlx/v2/.gitignore +++ /dev/null @@ -1,16 +0,0 @@ -# Binaries for programs and plugins -*.exe -*.dll -*.so -*.dylib - -# Test binary, build with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Go vendor dir -vendor -# GoLand IDE -.idea/ diff --git a/vendor/github.com/scylladb/gocqlx/v2/.golangci.yml b/vendor/github.com/scylladb/gocqlx/v2/.golangci.yml deleted file mode 100644 index d2a90a862a5..00000000000 --- a/vendor/github.com/scylladb/gocqlx/v2/.golangci.yml +++ /dev/null @@ -1,44 +0,0 @@ -run: - deadline: 5m - tests: false - -linters-settings: - errcheck: - check-blank: true - gocognit: - min-complexity: 50 - gocritic: - enabled-tags: - - diagnostic - - performance - - style - disabled-checks: - - commentedOutCode - - evalOrder - - hugeParam - - importShadow - - yodaStyleExpr - - whyNoLint - lll: - line-length: 180 - -linters: - enable-all: true - disable: - - funlen - - gas - - gochecknoglobals - - gochecknoinits - - gomnd - - interfacer - - maligned - - nakedret - - prealloc - - wsl - -issues: - exclude-use-default: false - exclude: - - composite literal uses unkeyed fields - - Error return value of `.+\.Close` is not checked - - method Json should be JSON diff --git a/vendor/github.com/scylladb/gocqlx/v2/LICENSE b/vendor/github.com/scylladb/gocqlx/v2/LICENSE deleted file mode 100644 index 4947287f7b5..00000000000 --- a/vendor/github.com/scylladb/gocqlx/v2/LICENSE +++ /dev/null @@ -1,177 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/vendor/github.com/scylladb/gocqlx/v2/Makefile b/vendor/github.com/scylladb/gocqlx/v2/Makefile deleted file mode 100644 index f2a0e0f2ea8..00000000000 --- a/vendor/github.com/scylladb/gocqlx/v2/Makefile +++ /dev/null @@ -1,66 +0,0 @@ -all: check test - -ifndef SCYLLA_VERSION -SCYLLA_VERSION := latest -endif - -ifndef SCYLLA_CPU -SCYLLA_CPU := 0 -endif - -ifndef GOTEST_CPU -GOTEST_CPU := 1 -endif - -ifndef GOBIN -GOBIN := $(GOPATH)/bin -endif - -.PHONY: fmt -fmt: - @go fmt ./... - -.PHONY: check -check: - @$(GOBIN)/golangci-lint run ./... - -GOTEST := go test -cpu $(GOTEST_CPU) -count=1 -cover -race -tags all - -.PHONY: test -test: - @$(GOTEST) . - @$(GOTEST) ./migrate - @$(GOTEST) ./qb - @$(GOTEST) ./table - -.PHONY: bench -bench: - @go test -cpu $(GOTEST_CPU) -tags all -run=XXX -bench=. -benchmem ./... - -.PHONY: run-examples -run-examples: - @go test -tags all -v -run=Example - -.PHONY: run-scylla -run-scylla: - @echo "==> Running test instance of Scylla $(SCYLLA_VERSION)" - @docker pull scylladb/scylla:$(SCYLLA_VERSION) - @docker run --name scylla -p 9042:9042 --cpuset-cpus=$(SCYLLA_CPU) --memory 1G --rm -d scylladb/scylla:$(SCYLLA_VERSION) - @until docker exec scylla cqlsh -e "DESCRIBE SCHEMA"; do sleep 2; done - -.PHONY: stop-scylla -stop-scylla: - @docker stop scylla - -.PHONY: get-deps -get-deps: - @go mod download - -define dl_tgz - @curl -sSq -L $(2) | tar zxf - --strip 1 -C $(GOBIN) --wildcards '*/$(1)' -endef - -.PHONY: get-tools -get-tools: - @echo "==> Installing tools at $(GOBIN)..." - @$(call dl_tgz,golangci-lint,https://github.com/golangci/golangci-lint/releases/download/v1.24.0/golangci-lint-1.24.0-linux-amd64.tar.gz) diff --git a/vendor/github.com/scylladb/gocqlx/v2/README.md b/vendor/github.com/scylladb/gocqlx/v2/README.md deleted file mode 100644 index 9113ba3bcc3..00000000000 --- a/vendor/github.com/scylladb/gocqlx/v2/README.md +++ /dev/null @@ -1,147 +0,0 @@ - # 🚀 GocqlX [![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/scylladb/gocqlx) [![Go Report Card](https://goreportcard.com/badge/github.com/scylladb/gocqlx)](https://goreportcard.com/report/github.com/scylladb/gocqlx) [![Build Status](https://travis-ci.org/scylladb/gocqlx.svg?branch=master)](https://travis-ci.org/scylladb/gocqlx) - -GocqlX makes working with Scylla easy and less error-prone. -It’s inspired by [Sqlx](https://github.com/jmoiron/sqlx), a tool for working with SQL databases, but it goes beyond what Sqlx provides. - -## Features - -* Binding query parameters from struct fields, map, or both -* Scanning query results into structs based on field names -* Convenient functions for common tasks such as loading a single row into a struct or all rows into a slice (list) of structs -* Making any struct a UDT without implementing marshalling functions -* GocqlX is fast. Its performance is comparable to raw driver. You can find some benchmarks [here](#performance). - -Subpackages provide additional functionality: - -* CQL query builder ([package qb](https://github.com/scylladb/gocqlx/blob/master/qb)) -* CRUD operations based on table model ([package table](https://github.com/scylladb/gocqlx/blob/master/table)) -* Database migrations ([package migrate](https://github.com/scylladb/gocqlx/blob/master/migrate)) - -## Installation - -```bash - go get -u github.com/scylladb/gocqlx/v2 -``` - -## Getting started - -Wrap gocql Session: - -```go -// Create gocql cluster. -cluster := gocql.NewCluster(hosts...) -// Wrap session on creation, gocqlx session embeds gocql.Session pointer. -session, err := gocqlx.WrapSession(cluster.CreateSession()) -if err != nil { - t.Fatal(err) -} -``` - -Specify table model: - -```go -// metadata specifies table name and columns it must be in sync with schema. -var personMetadata = table.Metadata{ - Name: "person", - Columns: []string{"first_name", "last_name", "email"}, - PartKey: []string{"first_name"}, - SortKey: []string{"last_name"}, -} - -// personTable allows for simple CRUD operations based on personMetadata. -var personTable = table.New(personMetadata) - -// Person represents a row in person table. -// Field names are converted to camel case by default, no need to add special tags. -// If you want to disable a field add `db:"-"` tag, it will not be persisted. -type Person struct { - FirstName string - LastName string - Email []string -} -``` - -Bind data from a struct and insert a row: - -```go -p := Person{ - "Michał", - "Matczuk", - []string{"michal@scylladb.com"}, -} -q := session.Query(personTable.Insert()).BindStruct(p) -if err := q.ExecRelease(); err != nil { - t.Fatal(err) -} -``` - -Load a single row to a struct: - -```go -p := Person{ - "Michał", - "Matczuk", - nil, // no email -} -q := session.Query(personTable.Get()).BindStruct(p) -if err := q.GetRelease(&p); err != nil { - t.Fatal(err) -} -t.Log(p) -// stdout: {Michał Matczuk [michal@scylladb.com]} -``` - -Load all rows in to a slice: - -```go -var people []Person -q := session.Query(personTable.Select()).BindMap(qb.M{"first_name": "Michał"}) -if err := q.SelectRelease(&people); err != nil { - t.Fatal(err) -} -t.Log(people) -// stdout: [{Michał Matczuk [michal@scylladb.com]}] -``` - -## Examples - -You can find lots of examples in [example_test.go](https://github.com/scylladb/gocqlx/blob/master/example_test.go). - -Go and run them locally: - -```bash -make run-scylla -make run-examples -``` - -## Performance - -GocqlX performance is comparable to the raw `gocql` driver. -Below benchmark results running on my laptop. - -``` -BenchmarkBaseGocqlInsert 2392 427491 ns/op 7804 B/op 39 allocs/op -BenchmarkGocqlxInsert 2479 435995 ns/op 7803 B/op 39 allocs/op -BenchmarkBaseGocqlGet 2853 452384 ns/op 7309 B/op 35 allocs/op -BenchmarkGocqlxGet 2706 442645 ns/op 7646 B/op 38 allocs/op -BenchmarkBaseGocqlSelect 747 1664365 ns/op 49415 B/op 927 allocs/op -BenchmarkGocqlxSelect 667 1877859 ns/op 42521 B/op 932 allocs/op -``` - -See the benchmark in [benchmark_test.go](https://github.com/scylladb/gocqlx/blob/master/benchmark_test.go). - -## License - -Copyright (C) 2017 ScyllaDB - -This project is distributed under the Apache 2.0 license. See the [LICENSE](https://github.com/scylladb/gocqlx/blob/master/LICENSE) file for details. -It contains software from: - -* [gocql project](https://github.com/gocql/gocql), licensed under the BSD license -* [sqlx project](https://github.com/jmoiron/sqlx), licensed under the MIT license - -Apache®, Apache Cassandra® are either registered trademarks or trademarks of -the Apache Software Foundation in the United States and/or other countries. -No endorsement by The Apache Software Foundation is implied by the use of these marks. - -GitHub star is always appreciated! diff --git a/vendor/github.com/scylladb/gocqlx/v2/doc.go b/vendor/github.com/scylladb/gocqlx/v2/doc.go deleted file mode 100644 index 33a36df0760..00000000000 --- a/vendor/github.com/scylladb/gocqlx/v2/doc.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (C) 2017 ScyllaDB -// Use of this source code is governed by a ALv2-style -// license that can be found in the LICENSE file. - -// Package gocqlx makes working with Scylla easy and error prone without sacrificing performance. -// It’s inspired by Sqlx, a tool for working with SQL databases, but it goes beyond what Sqlx provides. -// -// For more details consult README. -package gocqlx diff --git a/vendor/github.com/scylladb/gocqlx/v2/go.mod b/vendor/github.com/scylladb/gocqlx/v2/go.mod deleted file mode 100644 index b27440e7ca2..00000000000 --- a/vendor/github.com/scylladb/gocqlx/v2/go.mod +++ /dev/null @@ -1,13 +0,0 @@ -module github.com/scylladb/gocqlx/v2 - -require ( - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/gocql/gocql v0.0.0-20200131111108-92af2e088537 - github.com/golang/snappy v0.0.1 // indirect - github.com/google/go-cmp v0.2.0 - github.com/scylladb/go-reflectx v1.0.1 - golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a - gopkg.in/inf.v0 v0.9.1 -) - -go 1.13 diff --git a/vendor/github.com/scylladb/gocqlx/v2/go.sum b/vendor/github.com/scylladb/gocqlx/v2/go.sum deleted file mode 100644 index e0c1551346d..00000000000 --- a/vendor/github.com/scylladb/gocqlx/v2/go.sum +++ /dev/null @@ -1,34 +0,0 @@ -github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY= -github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= -github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= -github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/gocql/gocql v0.0.0-20200131111108-92af2e088537 h1:NaMut1fdw76YYX/TPinSAbai4DShF5tPort3bHpET6g= -github.com/gocql/gocql v0.0.0-20200131111108-92af2e088537/go.mod h1:DL0ekTmBSTdlNF25Orwt/JMzqIq3EJ4MVa/J/uK64OY= -github.com/golang/snappy v0.0.0-20170215233205-553a64147049 h1:K9KHZbXKpGydfDN0aZrsoHpLJlZsBrGMFWbgLDGnPZk= -github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= -github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/scylladb/go-reflectx v1.0.1 h1:b917wZM7189pZdlND9PbIJ6NQxfDPfBvUaQ7cjj1iZQ= -github.com/scylladb/go-reflectx v1.0.1/go.mod h1:rWnOfDIRWBGN0miMLIcoPt/Dhi2doCMZqwMCJ3KupFc= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a h1:WXEvlFVvvGxCJLG6REjsT03iWnKLEWinaScsxF2Vm2o= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= diff --git a/vendor/github.com/scylladb/gocqlx/v2/gocqlx.go b/vendor/github.com/scylladb/gocqlx/v2/gocqlx.go deleted file mode 100644 index edcc06ab97e..00000000000 --- a/vendor/github.com/scylladb/gocqlx/v2/gocqlx.go +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (C) 2017 ScyllaDB -// Use of this source code is governed by a ALv2-style -// license that can be found in the LICENSE file. - -package gocqlx - -import ( - "errors" - "fmt" - "reflect" - - "github.com/gocql/gocql" - "github.com/scylladb/go-reflectx" -) - -// structOnlyError returns an error appropriate for type when a non-scannable -// struct is expected but something else is given. -func structOnlyError(t reflect.Type) error { - if isStruct := t.Kind() == reflect.Struct; !isStruct { - return fmt.Errorf("expected a struct but got %s", t.Kind()) - } - - if isUnmarshaller := reflect.PtrTo(t).Implements(unmarshallerInterface); isUnmarshaller { - return fmt.Errorf("expected a struct but the provided struct type %s implements gocql.Unmarshaler", t.Name()) - } - - if isUDTUnmarshaller := reflect.PtrTo(t).Implements(udtUnmarshallerInterface); isUDTUnmarshaller { - return fmt.Errorf("expected a struct but the provided struct type %s implements gocql.UDTUnmarshaler", t.Name()) - } - - if isAutoUDT := reflect.PtrTo(t).Implements(autoUDTInterface); isAutoUDT { - return fmt.Errorf("expected a struct but the provided struct type %s implements gocqlx.UDT", t.Name()) - } - - return fmt.Errorf("expected a struct, but struct %s has no exported fields", t.Name()) -} - -// reflect helpers - -var ( - unmarshallerInterface = reflect.TypeOf((*gocql.Unmarshaler)(nil)).Elem() - udtUnmarshallerInterface = reflect.TypeOf((*gocql.UDTUnmarshaler)(nil)).Elem() - autoUDTInterface = reflect.TypeOf((*UDT)(nil)).Elem() -) - -func baseType(t reflect.Type, expected reflect.Kind) (reflect.Type, error) { - t = reflectx.Deref(t) - if t.Kind() != expected { - return nil, fmt.Errorf("expected %s but got %s", expected, t.Kind()) - } - return t, nil -} - -func missingFields(transversals [][]int) (field int, err error) { - for i, t := range transversals { - if len(t) == 0 { - return i, errors.New("missing field") - } - } - return 0, nil -} diff --git a/vendor/github.com/scylladb/gocqlx/v2/iterx.go b/vendor/github.com/scylladb/gocqlx/v2/iterx.go deleted file mode 100644 index 54f37ddbc26..00000000000 --- a/vendor/github.com/scylladb/gocqlx/v2/iterx.go +++ /dev/null @@ -1,350 +0,0 @@ -// Copyright (C) 2017 ScyllaDB -// Use of this source code is governed by a ALv2-style -// license that can be found in the LICENSE file. - -package gocqlx - -import ( - "errors" - "fmt" - "reflect" - - "github.com/gocql/gocql" - "github.com/scylladb/go-reflectx" -) - -// DefaultUnsafe enables the behavior of forcing the iterator to ignore -// missing fields for all queries. See Unsafe below for more information. -var DefaultUnsafe bool - -// Iterx is a wrapper around gocql.Iter which adds struct scanning capabilities. -type Iterx struct { - *gocql.Iter - Mapper *reflectx.Mapper - - unsafe bool - structOnly bool - applied bool - err error - - // Cache memory for a rows during iteration in structScan. - fields [][]int - values []interface{} -} - -// Unsafe forces the iterator to ignore missing fields. By default when scanning -// a struct if result row has a column that cannot be mapped to any destination -// field an error is reported. With unsafe such columns are ignored. -func (iter *Iterx) Unsafe() *Iterx { - iter.unsafe = true - return iter -} - -// StructOnly forces the iterator to treat a single-argument struct as -// non-scannable. This is is useful if you need to scan a row into a struct -// that also implements gocql.UDTUnmarshaler or in rare cases gocql.Unmarshaler. -func (iter *Iterx) StructOnly() *Iterx { - iter.structOnly = true - return iter -} - -// Get scans first row into a destination and closes the iterator. -// -// If the destination type is a struct pointer, then StructScan will be -// used. -// If the destination is some other type, then the row must only have one column -// which can scan into that type. -// This includes types that implement gocql.Unmarshaler and gocql.UDTUnmarshaler. -// -// If you'd like to treat a type that implements gocql.Unmarshaler or -// gocql.UDTUnmarshaler as an ordinary struct you should call -// StructOnly().Get(dest) instead. -// -// If no rows were selected, ErrNotFound is returned. -func (iter *Iterx) Get(dest interface{}) error { - iter.scanAny(dest) - iter.Close() - - return iter.checkErrAndNotFound() -} - -func (iter *Iterx) scanAny(dest interface{}) bool { - value := reflect.ValueOf(dest) - - if value.Kind() != reflect.Ptr { - iter.err = fmt.Errorf("expected a pointer but got %T", dest) - return false - } - if value.IsNil() { - iter.err = errors.New("expected a pointer but got nil") - return false - } - - base := reflectx.Deref(value.Type()) - scannable := iter.isScannable(base) - - if iter.structOnly && scannable { - if base.Kind() == reflect.Struct { - scannable = false - } else { - iter.err = structOnlyError(base) - return false - } - } - - if scannable && len(iter.Columns()) > 1 { - iter.err = fmt.Errorf("expected 1 column in result while scanning scannable type %s but got %d", base.Kind(), len(iter.Columns())) - return false - } - - if scannable { - return iter.scan(value) - } - - return iter.structScan(value) -} - -// Select scans all rows into a destination, which must be a pointer to slice -// of any type, and closes the iterator. -// -// If the destination slice type is a struct, then StructScan will be used -// on each row. -// If the destination is some other type, then each row must only have one -// column which can scan into that type. -// This includes types that implement gocql.Unmarshaler and gocql.UDTUnmarshaler. -// -// If you'd like to treat a type that implements gocql.Unmarshaler or -// gocql.UDTUnmarshaler as an ordinary struct you should call -// StructOnly().Select(dest) instead. -// -// If no rows were selected, ErrNotFound is NOT returned. -func (iter *Iterx) Select(dest interface{}) error { - iter.scanAll(dest) - iter.Close() - - return iter.err -} - -func (iter *Iterx) scanAll(dest interface{}) bool { - value := reflect.ValueOf(dest) - - // json.Unmarshal returns errors for these - if value.Kind() != reflect.Ptr { - iter.err = fmt.Errorf("expected a pointer but got %T", dest) - return false - } - if value.IsNil() { - iter.err = errors.New("expected a pointer but got nil") - return false - } - - slice, err := baseType(value.Type(), reflect.Slice) - if err != nil { - iter.err = err - return false - } - - isPtr := slice.Elem().Kind() == reflect.Ptr - base := reflectx.Deref(slice.Elem()) - scannable := iter.isScannable(base) - - if iter.structOnly && scannable { - if base.Kind() == reflect.Struct { - scannable = false - } else { - iter.err = structOnlyError(base) - return false - } - } - - // if it's a base type make sure it only has 1 column; if not return an error - if scannable && len(iter.Columns()) > 1 { - iter.err = fmt.Errorf("expected 1 column in result while scanning scannable type %s but got %d", base.Kind(), len(iter.Columns())) - return false - } - - var ( - alloc bool - v reflect.Value - vp reflect.Value - ok bool - ) - for { - // create a new struct type (which returns PtrTo) and indirect it - vp = reflect.New(base) - - // scan into the struct field pointers - if !scannable { - ok = iter.structScan(vp) - } else { - ok = iter.scan(vp) - } - if !ok { - break - } - - // allocate memory for the page data - if !alloc { - v = reflect.MakeSlice(slice, 0, iter.NumRows()) - alloc = true - } - - if isPtr { - v = reflect.Append(v, vp) - } else { - v = reflect.Append(v, reflect.Indirect(vp)) - } - } - - // update dest if allocated slice - if alloc { - reflect.Indirect(value).Set(v) - } - - return true -} - -// isScannable takes the reflect.Type and the actual dest value and returns -// whether or not it's Scannable. t is scannable if: -// * ptr to t implements gocql.Unmarshaler, gocql.UDTUnmarshaler or UDT -// * it is not a struct -// * it has no exported fields -func (iter *Iterx) isScannable(t reflect.Type) bool { - ptr := reflect.PtrTo(t) - switch { - case ptr.Implements(unmarshallerInterface): - return true - case ptr.Implements(udtUnmarshallerInterface): - return true - case ptr.Implements(autoUDTInterface): - return true - case t.Kind() != reflect.Struct: - return true - default: - return len(iter.Mapper.TypeMap(t).Index) == 0 - } -} - -func (iter *Iterx) scan(value reflect.Value) bool { - if value.Kind() != reflect.Ptr { - panic("value must be a pointer") - } - return iter.Iter.Scan(udtWrapValue(value, iter.Mapper, iter.unsafe)) -} - -// StructScan is like gocql.Iter.Scan, but scans a single row into a single -// struct. Use this and iterate manually when the memory load of Select() might -// be prohibitive. StructScan caches the reflect work of matching up column -// positions to fields to avoid that overhead per scan, which means it is not -// safe to run StructScan on the same Iterx instance with different struct -// types. -func (iter *Iterx) StructScan(dest interface{}) bool { - value := reflect.ValueOf(dest) - - if value.Kind() != reflect.Ptr { - iter.err = fmt.Errorf("expected a pointer but got %T", dest) - return false - } - if value.IsNil() { - iter.err = errors.New("expected a pointer but got nil") - return false - } - - return iter.structScan(value) -} - -const appliedColumn = "[applied]" - -func (iter *Iterx) structScan(value reflect.Value) bool { - if value.Kind() != reflect.Ptr { - panic("value must be a pointer") - } - - if iter.fields == nil { - columns := columnNames(iter.Iter.Columns()) - cas := len(columns) > 0 && columns[0] == appliedColumn - - iter.fields = iter.Mapper.TraversalsByName(value.Type(), columns) - // if we are not unsafe and it's not CAS query and are missing fields, return an error - if !iter.unsafe && !cas { - if f, err := missingFields(iter.fields); err != nil { - iter.err = fmt.Errorf("missing destination name %q in %s", columns[f], reflect.Indirect(value).Type()) - return false - } - } - iter.values = make([]interface{}, len(columns)) - if cas { - iter.values[0] = &iter.applied - } - } - - if err := iter.fieldsByTraversal(value, iter.fields, iter.values); err != nil { - iter.err = err - return false - } - - // scan into the struct field pointers and append to our results - return iter.Iter.Scan(iter.values...) -} - -// fieldsByName fills a values interface with fields from the passed value based -// on the traversals in int. -// We write this instead of using FieldsByName to save allocations and map -// lookups when iterating over many rows. -// Empty traversals will get an interface pointer. -func (iter *Iterx) fieldsByTraversal(value reflect.Value, traversals [][]int, values []interface{}) error { - value = reflect.Indirect(value) - if value.Kind() != reflect.Struct { - return fmt.Errorf("expected a struct but got %s", value.Type()) - } - - for i, traversal := range traversals { - if len(traversal) == 0 { - continue - } - f := reflectx.FieldByIndexes(value, traversal).Addr() - values[i] = udtWrapValue(f, iter.Mapper, iter.unsafe) - } - - return nil -} - -func columnNames(ci []gocql.ColumnInfo) []string { - r := make([]string, len(ci)) - for i, column := range ci { - r[i] = column.Name - } - return r -} - -// Scan consumes the next row of the iterator and copies the columns of the -// current row into the values pointed at by dest. Use nil as a dest value -// to skip the corresponding column. Scan might send additional queries -// to the database to retrieve the next set of rows if paging was enabled. -// -// Scan returns true if the row was successfully unmarshaled or false if the -// end of the result set was reached or if an error occurred. Close should -// be called afterwards to retrieve any potential errors. -func (iter *Iterx) Scan(dest ...interface{}) bool { - return iter.Iter.Scan(udtWrapSlice(iter.Mapper, iter.unsafe, dest)...) -} - -// Close closes the iterator and returns any errors that happened during -// the query or the iteration. -func (iter *Iterx) Close() error { - err := iter.Iter.Close() - if iter.err == nil { - iter.err = err - } - return iter.err -} - -// checkErrAndNotFound handle error and NotFound in one method. -func (iter *Iterx) checkErrAndNotFound() error { - if iter.err != nil { - return iter.err - } else if iter.Iter.NumRows() == 0 { - return gocql.ErrNotFound - } - return nil -} diff --git a/vendor/github.com/scylladb/gocqlx/v2/mapper.go b/vendor/github.com/scylladb/gocqlx/v2/mapper.go deleted file mode 100644 index ba24e125511..00000000000 --- a/vendor/github.com/scylladb/gocqlx/v2/mapper.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (C) 2017 ScyllaDB -// Use of this source code is governed by a ALv2-style -// license that can be found in the LICENSE file. - -package gocqlx - -import ( - "github.com/scylladb/go-reflectx" -) - -// DefaultMapper uses `db` tag and automatically converts struct field names to -// snake case. It can be set to whatever you want, but it is encouraged to be -// set before gocqlx is used as name-to-field mappings are cached after first -// use on a type. -// -// A custom mapper can always be set per Sessionm, Query and Iter. -var DefaultMapper = reflectx.NewMapperFunc("db", reflectx.CamelToSnakeASCII) diff --git a/vendor/github.com/scylladb/gocqlx/v2/queryx.go b/vendor/github.com/scylladb/gocqlx/v2/queryx.go deleted file mode 100644 index 741561dfdee..00000000000 --- a/vendor/github.com/scylladb/gocqlx/v2/queryx.go +++ /dev/null @@ -1,320 +0,0 @@ -// Copyright (C) 2017 ScyllaDB -// Use of this source code is governed by a ALv2-style -// license that can be found in the LICENSE file. - -package gocqlx - -import ( - "bytes" - "errors" - "fmt" - "reflect" - "strconv" - - "github.com/gocql/gocql" - "github.com/scylladb/go-reflectx" -) - -// CompileNamedQueryString translates query with named parameters in a form -// ':' to query with '?' placeholders and a list of parameter names. -// If you need to use ':' in a query, i.e. with maps or UDTs use '::' instead. -func CompileNamedQueryString(qs string) (stmt string, names []string, err error) { - return CompileNamedQuery([]byte(qs)) -} - -// CompileNamedQuery translates query with named parameters in a form -// ':' to query with '?' placeholders and a list of parameter names. -// If you need to use ':' in a query, i.e. with maps or UDTs use '::' instead. -func CompileNamedQuery(qs []byte) (stmt string, names []string, err error) { - // guess number of names - n := bytes.Count(qs, []byte(":")) - if n == 0 { - return "", nil, errors.New("expected a named query") - } - names = make([]string, 0, n) - rebound := make([]byte, 0, len(qs)) - - inName := false - last := len(qs) - 1 - name := make([]byte, 0, 10) - - for i, b := range qs { - // a ':' while we're in a name is an error - switch { - case b == ':': - // if this is the second ':' in a '::' escape sequence, append a ':' - if inName && i > 0 && qs[i-1] == ':' { - rebound = append(rebound, ':') - inName = false - continue - } else if inName { - err = errors.New("unexpected `:` while reading named param at " + strconv.Itoa(i)) - return stmt, names, err - } - inName = true - name = []byte{} - // if we're in a name, and this is an allowed character, continue - case inName && (allowedBindRune(b) || b == '_' || b == '.') && i != last: - // append the byte to the name if we are in a name and not on the last byte - name = append(name, b) - // if we're in a name and it's not an allowed character, the name is done - case inName: - inName = false - // if this is the final byte of the string and it is part of the name, then - // make sure to add it to the name - if i == last && allowedBindRune(b) { - name = append(name, b) - } - // add the string representation to the names list - names = append(names, string(name)) - // add a proper bindvar for the bindType - rebound = append(rebound, '?') - // add this byte to string unless it was not part of the name - if i != last { - rebound = append(rebound, b) - } else if !allowedBindRune(b) { - rebound = append(rebound, b) - } - default: - // this is a normal byte and should just go onto the rebound query - rebound = append(rebound, b) - } - } - - return string(rebound), names, err -} - -func allowedBindRune(b byte) bool { - return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || (b >= '0' && b <= '9') -} - -// Queryx is a wrapper around gocql.Query which adds struct binding capabilities. -type Queryx struct { - *gocql.Query - Names []string - Mapper *reflectx.Mapper - err error -} - -// Query creates a new Queryx from gocql.Query using a default mapper. -// -// Deprecated: Use gocqlx.Session.Query API instead. -func Query(q *gocql.Query, names []string) *Queryx { - return &Queryx{ - Query: q, - Names: names, - Mapper: DefaultMapper, - } -} - -// BindStruct binds query named parameters to values from arg using mapper. If -// value cannot be found error is reported. -func (q *Queryx) BindStruct(arg interface{}) *Queryx { - arglist, err := bindStructArgs(q.Names, arg, nil, q.Mapper) - if err != nil { - q.err = fmt.Errorf("bind error: %s", err) - } else { - q.err = nil - q.Bind(arglist...) - } - - return q -} - -// BindStructMap binds query named parameters to values from arg0 and arg1 -// using a mapper. If value cannot be found in arg0 it's looked up in arg1 -// before reporting an error. -func (q *Queryx) BindStructMap(arg0 interface{}, arg1 map[string]interface{}) *Queryx { - arglist, err := bindStructArgs(q.Names, arg0, arg1, q.Mapper) - if err != nil { - q.err = fmt.Errorf("bind error: %s", err) - } else { - q.err = nil - q.Bind(arglist...) - } - - return q -} - -func bindStructArgs(names []string, arg0 interface{}, arg1 map[string]interface{}, m *reflectx.Mapper) ([]interface{}, error) { - arglist := make([]interface{}, 0, len(names)) - - // grab the indirected value of arg - v := reflect.ValueOf(arg0) - for v = reflect.ValueOf(arg0); v.Kind() == reflect.Ptr; { - v = v.Elem() - } - - err := m.TraversalsByNameFunc(v.Type(), names, func(i int, t []int) error { - if len(t) != 0 { - val := reflectx.FieldByIndexesReadOnly(v, t) // nolint:scopelint - arglist = append(arglist, val.Interface()) - } else { - val, ok := arg1[names[i]] - if !ok { - return fmt.Errorf("could not find name %q in %#v and %#v", names[i], arg0, arg1) - } - arglist = append(arglist, val) - } - - return nil - }) - - return arglist, err -} - -// BindMap binds query named parameters using map. -func (q *Queryx) BindMap(arg map[string]interface{}) *Queryx { - arglist, err := bindMapArgs(q.Names, arg) - if err != nil { - q.err = fmt.Errorf("bind error: %s", err) - } else { - q.err = nil - q.Bind(arglist...) - } - - return q -} - -func bindMapArgs(names []string, arg map[string]interface{}) ([]interface{}, error) { - arglist := make([]interface{}, 0, len(names)) - - for _, name := range names { - val, ok := arg[name] - if !ok { - return arglist, fmt.Errorf("could not find name %q in %#v", name, arg) - } - arglist = append(arglist, val) - } - return arglist, nil -} - -// Bind sets query arguments of query. This can also be used to rebind new query arguments -// to an existing query instance. -func (q *Queryx) Bind(v ...interface{}) *Queryx { - q.Query.Bind(udtWrapSlice(q.Mapper, DefaultUnsafe, v)...) - return q -} - -// Err returns any binding errors. -func (q *Queryx) Err() error { - return q.err -} - -// Exec executes the query without returning any rows. -func (q *Queryx) Exec() error { - if q.err != nil { - return q.err - } - return q.Query.Exec() -} - -// ExecRelease calls Exec and releases the query, a released query cannot be -// reused. -func (q *Queryx) ExecRelease() error { - defer q.Release() - return q.Exec() -} - -// ExecCAS executes the Lightweight Transaction query, returns whether query was applied. -// See: https://docs.scylladb.com/using-scylla/lwt/ for more details. -func (q *Queryx) ExecCAS() (applied bool, err error) { - iter := q.Iter().StructOnly() - if err := iter.Get(&struct{}{}); err != nil { - return false, err - } - return iter.applied, iter.Close() -} - -// ExecCASRelease calls ExecCAS and releases the query, a released query cannot be -// reused. -func (q *Queryx) ExecCASRelease() (bool, error) { - defer q.Release() - return q.ExecCAS() -} - -// Get scans first row into a destination and closes the iterator. -// -// If the destination type is a struct pointer, then Iter.StructScan will be -// used. -// If the destination is some other type, then the row must only have one column -// which can scan into that type. -// This includes types that implement gocql.Unmarshaler and gocql.UDTUnmarshaler. -// -// If you'd like to treat a type that implements gocql.Unmarshaler or -// gocql.UDTUnmarshaler as an ordinary struct you should call -// Iter().StructOnly().Get(dest) instead. -// -// If no rows were selected, ErrNotFound is returned. -func (q *Queryx) Get(dest interface{}) error { - if q.err != nil { - return q.err - } - return q.Iter().Get(dest) -} - -// GetRelease calls Get and releases the query, a released query cannot be -// reused. -func (q *Queryx) GetRelease(dest interface{}) error { - defer q.Release() - return q.Get(dest) -} - -// GetCAS executes a lightweight transaction. -// If the transaction fails because the existing values did not match, -// the previous values will be stored in dest object. -// See: https://docs.scylladb.com/using-scylla/lwt/ for more details. -func (q *Queryx) GetCAS(dest interface{}) (applied bool, err error) { - iter := q.Iter() - if err := iter.Get(dest); err != nil { - return false, err - } - - return iter.applied, iter.Close() -} - -// GetCASRelease calls GetCAS and releases the query, a released query cannot be -// reused. -func (q *Queryx) GetCASRelease(dest interface{}) (bool, error) { - defer q.Release() - return q.GetCAS(dest) -} - -// Select scans all rows into a destination, which must be a pointer to slice -// of any type, and closes the iterator. -// -// If the destination slice type is a struct, then Iter.StructScan will be used -// on each row. -// If the destination is some other type, then each row must only have one -// column which can scan into that type. -// This includes types that implement gocql.Unmarshaler and gocql.UDTUnmarshaler. -// -// If you'd like to treat a type that implements gocql.Unmarshaler or -// gocql.UDTUnmarshaler as an ordinary struct you should call -// Iter().StructOnly().Select(dest) instead. -// -// If no rows were selected, ErrNotFound is NOT returned. -func (q *Queryx) Select(dest interface{}) error { - if q.err != nil { - return q.err - } - return q.Iter().Select(dest) -} - -// SelectRelease calls Select and releases the query, a released query cannot be -// reused. -func (q *Queryx) SelectRelease(dest interface{}) error { - defer q.Release() - return q.Select(dest) -} - -// Iter returns Iterx instance for the query. It should be used when data is too -// big to be loaded with Select in order to do row by row iteration. -// See Iterx StructScan function. -func (q *Queryx) Iter() *Iterx { - return &Iterx{ - Iter: q.Query.Iter(), - Mapper: q.Mapper, - unsafe: DefaultUnsafe, - } -} diff --git a/vendor/github.com/scylladb/gocqlx/v2/queryx_wrap.go b/vendor/github.com/scylladb/gocqlx/v2/queryx_wrap.go deleted file mode 100644 index e63bb4a24bb..00000000000 --- a/vendor/github.com/scylladb/gocqlx/v2/queryx_wrap.go +++ /dev/null @@ -1,149 +0,0 @@ -// Copyright (C) 2017 ScyllaDB -// Use of this source code is governed by a ALv2-style -// license that can be found in the LICENSE file. - -package gocqlx - -import ( - "context" - - "github.com/gocql/gocql" -) - -// This file contains wrappers around gocql.Query that make Queryx expose the -// same interface but return *Queryx, this should be inlined by compiler. - -// Consistency sets the consistency level for this query. If no consistency -// level have been set, the default consistency level of the cluster -// is used. -func (q *Queryx) Consistency(c gocql.Consistency) *Queryx { - q.Query.Consistency(c) - return q -} - -// CustomPayload sets the custom payload level for this query. -func (q *Queryx) CustomPayload(customPayload map[string][]byte) *Queryx { - q.Query.CustomPayload(customPayload) - return q -} - -// Trace enables tracing of this query. Look at the documentation of the -// Tracer interface to learn more about tracing. -func (q *Queryx) Trace(trace gocql.Tracer) *Queryx { - q.Query.Trace(trace) - return q -} - -// Observer enables query-level observer on this query. -// The provided observer will be called every time this query is executed. -func (q *Queryx) Observer(observer gocql.QueryObserver) *Queryx { - q.Query.Observer(observer) - return q -} - -// PageSize will tell the iterator to fetch the result in pages of size n. -// This is useful for iterating over large result sets, but setting the -// page size too low might decrease the performance. This feature is only -// available in Cassandra 2 and onwards. -func (q *Queryx) PageSize(n int) *Queryx { - q.Query.PageSize(n) - return q -} - -// DefaultTimestamp will enable the with default timestamp flag on the query. -// If enable, this will replace the server side assigned -// timestamp as default timestamp. Note that a timestamp in the query itself -// will still override this timestamp. This is entirely optional. -// -// Only available on protocol >= 3 -func (q *Queryx) DefaultTimestamp(enable bool) *Queryx { - q.Query.DefaultTimestamp(enable) - return q -} - -// WithTimestamp will enable the with default timestamp flag on the query -// like DefaultTimestamp does. But also allows to define value for timestamp. -// It works the same way as USING TIMESTAMP in the query itself, but -// should not break prepared query optimization -// -// Only available on protocol >= 3 -func (q *Queryx) WithTimestamp(timestamp int64) *Queryx { - q.Query.WithTimestamp(timestamp) - return q -} - -// RoutingKey sets the routing key to use when a token aware connection -// pool is used to optimize the routing of this query. -func (q *Queryx) RoutingKey(routingKey []byte) *Queryx { - q.Query.RoutingKey(routingKey) - return q -} - -// WithContext returns a shallow copy of q with its context -// set to ctx. -// -// The provided context controls the entire lifetime of executing a -// query, queries will be canceled and return once the context is -// canceled. -func (q *Queryx) WithContext(ctx context.Context) *Queryx { - q.Query = q.Query.WithContext(ctx) - return q -} - -// Prefetch sets the default threshold for pre-fetching new pages. If -// there are only p*pageSize rows remaining, the next page will be requested -// automatically. -func (q *Queryx) Prefetch(p float64) *Queryx { - q.Query.Prefetch(p) - return q -} - -// RetryPolicy sets the policy to use when retrying the query. -func (q *Queryx) RetryPolicy(r gocql.RetryPolicy) *Queryx { - q.Query.RetryPolicy(r) - return q -} - -// SetSpeculativeExecutionPolicy sets the execution policy. -func (q *Queryx) SetSpeculativeExecutionPolicy(sp gocql.SpeculativeExecutionPolicy) *Queryx { - q.Query.SetSpeculativeExecutionPolicy(sp) - return q -} - -// Idempotent marks the query as being idempotent or not depending on -// the value. -func (q *Queryx) Idempotent(value bool) *Queryx { - q.Query.Idempotent(value) - return q -} - -// SerialConsistency sets the consistency level for the -// serial phase of conditional updates. That consistency can only be -// either SERIAL or LOCAL_SERIAL and if not present, it defaults to -// SERIAL. This option will be ignored for anything else that a -// conditional update/insert. -func (q *Queryx) SerialConsistency(cons gocql.SerialConsistency) *Queryx { - q.Query.SerialConsistency(cons) - return q -} - -// PageState sets the paging state for the query to resume paging from a specific -// point in time. Setting this will disable to query paging for this query, and -// must be used for all subsequent pages. -func (q *Queryx) PageState(state []byte) *Queryx { - q.Query.PageState(state) - return q -} - -// NoSkipMetadata will override the internal result metadata cache so that the driver does not -// send skip_metadata for queries, this means that the result will always contain -// the metadata to parse the rows and will not reuse the metadata from the prepared -// staement. This should only be used to work around cassandra bugs, such as when using -// CAS operations which do not end in Cas. -// -// See https://issues.apache.org/jira/browse/CASSANDRA-11099 -// https://github.com/gocql/gocql/issues/612 -func (q *Queryx) NoSkipMetadata() *Queryx { - q.Query.NoSkipMetadata() - return q -} diff --git a/vendor/github.com/scylladb/gocqlx/v2/session.go b/vendor/github.com/scylladb/gocqlx/v2/session.go deleted file mode 100644 index 66e86da6243..00000000000 --- a/vendor/github.com/scylladb/gocqlx/v2/session.go +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (C) 2017 ScyllaDB -// Use of this source code is governed by a ALv2-style -// license that can be found in the LICENSE file. - -package gocqlx - -import ( - "context" - - "github.com/gocql/gocql" - "github.com/scylladb/go-reflectx" -) - -// Session wraps gocql.Session and provides a modified Query function that -// returns Queryx instance. -// The original Session instance can be accessed as Session. -// The default mapper uses `db` tag and automatically converts struct field -// names to snake case. If needed package reflectx provides constructors -// for other types of mappers. -type Session struct { - *gocql.Session - Mapper *reflectx.Mapper -} - -// NewSession wraps existing gocql.session. -func NewSession(session *gocql.Session) Session { - return Session{ - Session: session, - Mapper: DefaultMapper, - } -} - -// WrapSession should be called on CreateSession() gocql function to convert -// the created session to gocqlx.Session. -// -// Example: -// session, err := gocqlx.WrapSession(cluster.CreateSession()) -func WrapSession(session *gocql.Session, err error) (Session, error) { - return Session{ - Session: session, - Mapper: DefaultMapper, - }, err -} - -// ContextQuery is a helper function that allows to pass context when creating -// a query, see the "Query" function . -func (s Session) ContextQuery(ctx context.Context, stmt string, names []string) *Queryx { - return &Queryx{ - Query: s.Session.Query(stmt).WithContext(ctx), - Names: names, - Mapper: s.Mapper, - } -} - -// Query creates a new Queryx using the session mapper. -// The stmt and names parameters are typically result of a query builder -// (package qb) ToCql() function or come from table model (package table). -// The names parameter is a list of query parameters' names and it's used for -// binding. -func (s Session) Query(stmt string, names []string) *Queryx { - return &Queryx{ - Query: s.Session.Query(stmt), - Names: names, - Mapper: s.Mapper, - } -} - -// ExecStmt creates query and executes the given statement. -func (s Session) ExecStmt(stmt string) error { - return s.Query(stmt, nil).ExecRelease() -} diff --git a/vendor/github.com/scylladb/gocqlx/v2/udt.go b/vendor/github.com/scylladb/gocqlx/v2/udt.go deleted file mode 100644 index e17ac069734..00000000000 --- a/vendor/github.com/scylladb/gocqlx/v2/udt.go +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (C) 2017 ScyllaDB -// Use of this source code is governed by a ALv2-style -// license that can be found in the LICENSE file. - -package gocqlx - -import ( - "fmt" - "reflect" - - "github.com/gocql/gocql" - "github.com/scylladb/go-reflectx" -) - -// UDT is a marker interface that needs to be embedded in a struct if you want -// to marshal or unmarshal it as a User Defined Type. -type UDT interface { - udt() -} - -var ( - _ gocql.UDTMarshaler = udt{} - _ gocql.UDTUnmarshaler = udt{} -) - -type udt struct { - value reflect.Value - field map[string]reflect.Value - unsafe bool -} - -func makeUDT(value reflect.Value, mapper *reflectx.Mapper, unsafe bool) udt { - return udt{ - value: value, - field: mapper.FieldMap(value), - unsafe: unsafe, - } -} - -func (u udt) MarshalUDT(name string, info gocql.TypeInfo) ([]byte, error) { - value, ok := u.field[name] - if !ok { - return nil, fmt.Errorf("missing name %q in %s", name, u.value.Type()) - } - - return gocql.Marshal(info, value.Interface()) -} - -func (u udt) UnmarshalUDT(name string, info gocql.TypeInfo, data []byte) error { - value, ok := u.field[name] - if !ok && !u.unsafe { - return fmt.Errorf("missing name %q in %s", name, u.value.Type()) - } - - return gocql.Unmarshal(info, data, value.Addr().Interface()) -} - -// udtWrapValue adds UDT wrapper if needed. -func udtWrapValue(value reflect.Value, mapper *reflectx.Mapper, unsafe bool) interface{} { - if value.Type().Implements(autoUDTInterface) { - return makeUDT(value, mapper, unsafe) - } - return value.Interface() -} - -// udtWrapSlice adds UDT wrapper if needed. -func udtWrapSlice(mapper *reflectx.Mapper, unsafe bool, v []interface{}) []interface{} { - for i := range v { - if _, ok := v[i].(UDT); ok { - v[i] = makeUDT(reflect.ValueOf(v[i]), mapper, unsafe) - } - } - return v -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 445f3fb558b..491eb1288bb 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -170,6 +170,7 @@ github.com/golang/protobuf/ptypes/any github.com/golang/protobuf/ptypes/duration github.com/golang/protobuf/ptypes/timestamp # github.com/golang/snappy v0.0.1 +## explicit github.com/golang/snappy # github.com/google/go-cmp v0.5.2 ## explicit @@ -302,14 +303,9 @@ github.com/russross/blackfriday # github.com/scylladb/go-log v0.0.4 ## explicit github.com/scylladb/go-log -# github.com/scylladb/go-reflectx v1.0.1 -github.com/scylladb/go-reflectx # github.com/scylladb/go-set v1.0.2 ## explicit github.com/scylladb/go-set/strset -# github.com/scylladb/gocqlx/v2 v2.2.0 -## explicit -github.com/scylladb/gocqlx/v2 # github.com/sergi/go-diff v1.1.0 github.com/sergi/go-diff/diffmatchpatch # github.com/shurcooL/githubv4 v0.0.0-20201206200315-234843c633fa