Compare commits
10 Commits
25cee51cac
...
d9ec9f889d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d9ec9f889d | ||
|
|
b5ec0d955f | ||
|
|
38001d64ac | ||
|
|
96f0b49bdd | ||
|
|
20fef0caf4 | ||
|
|
ce13945e3f | ||
|
|
acb61eb06f | ||
|
|
cdd1c07b35 | ||
|
|
2dd6668d11 | ||
|
|
101d498909 |
4
.github/workflows/main.yml
vendored
4
.github/workflows/main.yml
vendored
@@ -29,10 +29,10 @@ jobs:
|
||||
with:
|
||||
fetch-depth: '0'
|
||||
|
||||
- name: Install Go 1.20
|
||||
- name: Install Go 1.25
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: "1.20"
|
||||
go-version: 1.25
|
||||
|
||||
- name: Cache Dependencies
|
||||
uses: actions/cache@v4
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -17,3 +17,7 @@ vendor
|
||||
|
||||
cmd/schemagen/schemagen
|
||||
cmd/schemagen/testdata/go.sum
|
||||
|
||||
# Claude / AI assistant metadata
|
||||
CLAUDE.md
|
||||
.claude/
|
||||
118
.golangci.yml
118
.golangci.yml
@@ -1,51 +1,32 @@
|
||||
run:
|
||||
deadline: 5m
|
||||
tests: true
|
||||
allow-parallel-runners: true
|
||||
modules-download-mode: readonly
|
||||
build-tags: [ all, integration ]
|
||||
version: "2"
|
||||
|
||||
linters-settings:
|
||||
revive:
|
||||
rules:
|
||||
- name: package-comments
|
||||
disabled: true
|
||||
goimports:
|
||||
local-prefixes: github.com/scylladb/gocqlx
|
||||
gofumpt:
|
||||
extra-rules: true
|
||||
govet:
|
||||
enable-all: true
|
||||
disable:
|
||||
- shadow
|
||||
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
|
||||
formatters:
|
||||
enable:
|
||||
- goimports
|
||||
|
||||
settings:
|
||||
goimports:
|
||||
local-prefixes:
|
||||
- github.com/scylladb/gocqlx
|
||||
golines:
|
||||
max-len: 120
|
||||
gofumpt:
|
||||
extra-rules: true
|
||||
|
||||
linters:
|
||||
disable-all: true
|
||||
exclusions:
|
||||
rules:
|
||||
- path: '(.+)_test\.go'
|
||||
text: "fieldalignment"
|
||||
linters:
|
||||
- govet
|
||||
|
||||
default: none
|
||||
enable:
|
||||
- nolintlint
|
||||
- errcheck
|
||||
- gocritic
|
||||
- gofumpt
|
||||
- goheader
|
||||
- goimports
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
- lll
|
||||
@@ -55,26 +36,41 @@ linters:
|
||||
- staticcheck
|
||||
- thelper
|
||||
- tparallel
|
||||
- typecheck
|
||||
- unused
|
||||
- forbidigo
|
||||
settings:
|
||||
revive:
|
||||
rules:
|
||||
- name: package-comments
|
||||
disabled: true
|
||||
govet:
|
||||
enable-all: true
|
||||
disable:
|
||||
- shadow
|
||||
errcheck:
|
||||
check-blank: false
|
||||
gocognit:
|
||||
min-complexity: 50
|
||||
gocritic:
|
||||
enabled-tags:
|
||||
- diagnostic
|
||||
- performance
|
||||
- style
|
||||
disabled-checks:
|
||||
- commentedOutCode
|
||||
- evalOrder
|
||||
- hugeParam
|
||||
- importShadow
|
||||
- yodaStyleExpr
|
||||
- whyNoLint
|
||||
lll:
|
||||
line-length: 180
|
||||
nolintlint:
|
||||
allow-no-explanation: [ golines ]
|
||||
require-explanation: true
|
||||
require-specific: true
|
||||
|
||||
issues:
|
||||
new: true
|
||||
new-from-rev: origin/master
|
||||
exclude-use-default: false
|
||||
exclude:
|
||||
- composite literal uses unkeyed fields
|
||||
- Error return value of `.+\.Close` is not checked
|
||||
- method Json should be JSON
|
||||
exclude-rules:
|
||||
- path: (.*_test.go|migrate/example|gocqlxtest/)
|
||||
linters:
|
||||
- fieldalignment
|
||||
- govet
|
||||
- errcheck
|
||||
- path: doc_test.go
|
||||
linters:
|
||||
- unused
|
||||
- revive
|
||||
|
||||
run:
|
||||
build-tags:
|
||||
- integration
|
||||
- all
|
||||
13
Makefile
13
Makefile
@@ -24,8 +24,7 @@ export PATH := $(GOBIN):$(PATH)
|
||||
GOOS := $(shell uname | tr '[:upper:]' '[:lower:]')
|
||||
GOARCH := $(shell go env GOARCH)
|
||||
|
||||
GOLANGCI_VERSION := 1.64.8
|
||||
FIELDALIGNMENT_VERSION := 0.24.0
|
||||
GOLANGCI_VERSION := 2.5.0
|
||||
|
||||
ifeq ($(GOARCH),arm64)
|
||||
GOLANGCI_DOWNLOAD_URL := "https://github.com/golangci/golangci-lint/releases/download/v$(GOLANGCI_VERSION)/golangci-lint-$(GOLANGCI_VERSION)-$(GOOS)-arm64.tar.gz"
|
||||
@@ -97,7 +96,6 @@ get-deps:
|
||||
get-tools:
|
||||
@echo "==> Installing tools at $(GOBIN)..."
|
||||
@$(MAKE) install-golangci-lint
|
||||
@$(MAKE) install-fieldalignment
|
||||
|
||||
.require-golangci-lint:
|
||||
ifeq ($(shell if golangci-lint --version 2>/dev/null | grep ${GOLANGCI_VERSION} 1>/dev/null 2>&1; then echo "ok"; else echo "need-install"; fi), need-install)
|
||||
@@ -108,15 +106,6 @@ install-golangci-lint:
|
||||
@echo "==> Installing golangci-lint ${GOLANGCI_VERSION} at $(GOBIN)..."
|
||||
$(call dl_tgz,golangci-lint,$(GOLANGCI_DOWNLOAD_URL))
|
||||
|
||||
.require-fieldalignment:
|
||||
ifeq ($(shell if fieldalignment -V=full 1>/dev/null 2>&1; then echo "ok"; else echo "need-install"; fi), need-install)
|
||||
$(MAKE) install-golangci-lint
|
||||
endif
|
||||
|
||||
install-fieldalignment:
|
||||
@echo "==> Installing fieldalignment ${FIELDALIGNMENT_VERSION} at $(GOBIN)..."
|
||||
@go install golang.org/x/tools/go/analysis/passes/fieldalignment/cmd/fieldalignment@v${FIELDALIGNMENT_VERSION}
|
||||
|
||||
define dl_tgz
|
||||
@mkdir "$(GOBIN)" 2>/dev/null || true
|
||||
@echo "Downloading $(GOBIN)/$(1)";
|
||||
|
||||
43
README.md
43
README.md
@@ -11,7 +11,7 @@ If you are using GocqlX v3.0.0 or newer, you must ensure your `go.mod` includes
|
||||
|
||||
```go
|
||||
// Use the latest version of scylladb/gocql; check for updates at https://github.com/scylladb/gocql/releases
|
||||
replace github.com/gocql/gocql => github.com/scylladb/gocql v1.15.3
|
||||
replace github.com/gocql/gocql => github.com/scylladb/gocql v1.16.0
|
||||
```
|
||||
|
||||
This is required because GocqlX relies on ScyllaDB-specific extensions and bug fixes introduced in the gocql fork. Attempting to use the standard gocql driver with GocqlX v3.0.0+ may lead to build or runtime issues.
|
||||
@@ -30,8 +30,18 @@ Subpackages provide additional functionality:
|
||||
* 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
|
||||
## Installation GocqlX
|
||||
|
||||
Add GocqlX to your Go module:
|
||||
|
||||
```bash
|
||||
go get github.com/scylladb/gocqlx/v3
|
||||
```
|
||||
|
||||
## Installation schemagen
|
||||
|
||||
Unfortunately you can't install it via `go install`, since `go.mod` contains `replace` directive.
|
||||
So, you have to check it out and install manually:
|
||||
```bash
|
||||
git clone git@github.com:scylladb/gocqlx.git
|
||||
cd gocqlx/cmd/schemagen/
|
||||
@@ -40,16 +50,31 @@ go install .
|
||||
|
||||
## Getting started
|
||||
|
||||
First, import the required packages:
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/gocql/gocql"
|
||||
"github.com/scylladb/gocqlx/v3"
|
||||
"github.com/scylladb/gocqlx/v3/qb"
|
||||
"github.com/scylladb/gocqlx/v3/table"
|
||||
)
|
||||
```
|
||||
|
||||
Wrap gocql Session:
|
||||
|
||||
```go
|
||||
// Create gocql cluster.
|
||||
cluster := gocql.NewCluster(hosts...)
|
||||
// Wrap session on creation, gocqlx session embeds gocql.Session pointer.
|
||||
// Wrap session on creation, gocqlx session embeds gocql.Session pointer.
|
||||
session, err := gocqlx.WrapSession(cluster.CreateSession())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer session.Close()
|
||||
```
|
||||
|
||||
Specify table model:
|
||||
@@ -90,7 +115,7 @@ p := Person{
|
||||
}
|
||||
q := session.Query(personTable.Insert()).BindStruct(p)
|
||||
if err := q.ExecRelease(); err != nil {
|
||||
t.Fatal(err)
|
||||
log.Fatal(err)
|
||||
}
|
||||
```
|
||||
|
||||
@@ -104,9 +129,9 @@ p := Person{
|
||||
}
|
||||
q := session.Query(personTable.Get()).BindStruct(p)
|
||||
if err := q.GetRelease(&p); err != nil {
|
||||
t.Fatal(err)
|
||||
log.Fatal(err)
|
||||
}
|
||||
t.Log(p)
|
||||
fmt.Println(p)
|
||||
// stdout: {Michał Matczuk [michal@scylladb.com]}
|
||||
```
|
||||
|
||||
@@ -116,9 +141,9 @@ Load all rows in to a slice:
|
||||
var people []Person
|
||||
q := session.Query(personTable.Select()).BindMap(qb.M{"first_name": "Michał"})
|
||||
if err := q.SelectRelease(&people); err != nil {
|
||||
t.Fatal(err)
|
||||
log.Fatal(err)
|
||||
}
|
||||
t.Log(people)
|
||||
fmt.Println(people)
|
||||
// stdout: [{Michał Matczuk [michal@scylladb.com]}]
|
||||
```
|
||||
|
||||
|
||||
@@ -162,12 +162,13 @@ func BenchmarkBaseGocqlSelect(b *testing.B) {
|
||||
v := make([]*benchPerson, 100)
|
||||
p := new(benchPerson)
|
||||
for iter.Scan(&p.ID, &p.FirstName, &p.LastName, &p.Email, &p.Gender, &p.IPAddress) {
|
||||
v = append(v, p) // nolint:staticcheck
|
||||
v = append(v, p)
|
||||
p = new(benchPerson)
|
||||
}
|
||||
if err := iter.Close(); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
_ = v
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ func camelize(s string) string {
|
||||
|
||||
l := len(buf)
|
||||
for i := 0; i < l; i++ {
|
||||
if !(allowedBindRune(buf[i]) || buf[i] == '_') {
|
||||
if !allowedBindRune(buf[i]) && buf[i] != '_' {
|
||||
panic(fmt.Sprint("not allowed name ", s))
|
||||
}
|
||||
|
||||
|
||||
8
cmd/schemagen/testdata/go.mod
vendored
8
cmd/schemagen/testdata/go.mod
vendored
@@ -1,21 +1,21 @@
|
||||
module schemagentest
|
||||
|
||||
go 1.21
|
||||
go 1.25.0
|
||||
|
||||
require (
|
||||
github.com/gocql/gocql v1.7.0
|
||||
github.com/google/go-cmp v0.7.0
|
||||
github.com/scylladb/gocqlx/v3 v3.0.0
|
||||
github.com/scylladb/gocqlx/v3 v3.0.4
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/klauspost/compress v1.17.9 // indirect
|
||||
github.com/klauspost/compress v1.18.1 // indirect
|
||||
github.com/scylladb/go-reflectx v1.0.1 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
)
|
||||
|
||||
replace (
|
||||
github.com/gocql/gocql => github.com/scylladb/gocql v1.15.3
|
||||
github.com/gocql/gocql => github.com/scylladb/gocql v1.17.0
|
||||
github.com/scylladb/gocqlx/v3 => ../../..
|
||||
)
|
||||
|
||||
55
cmd/schemagen/testdata/go.sum
vendored
55
cmd/schemagen/testdata/go.sum
vendored
@@ -1,53 +1,30 @@
|
||||
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/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
|
||||
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/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
|
||||
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
||||
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
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/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co=
|
||||
github.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdBnrBd8Nrxr+0=
|
||||
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/scylladb/gocql v1.15.1 h1:t75NkDFys0XxipPsnTrSEbwx8B8R/jTUt5OAY9W7i+c=
|
||||
github.com/scylladb/gocql v1.15.1/go.mod h1:+rInt+HjERaMEYC4N8LocQQEAdREhYKU4QPkE00K5dA=
|
||||
github.com/scylladb/gocql v1.15.2 h1:Vv7iaIyTMMjMtux1INQMi0waH8j8O/ppKS6JcM1vh14=
|
||||
github.com/scylladb/gocql v1.15.2/go.mod h1:+rInt+HjERaMEYC4N8LocQQEAdREhYKU4QPkE00K5dA=
|
||||
github.com/scylladb/gocql v1.15.3/go.mod h1:+rInt+HjERaMEYC4N8LocQQEAdREhYKU4QPkE00K5dA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
golang.org/x/net v0.0.0-20220526153639-5463443f8c37 h1:lUkvobShwKsOesNfWWlCS5q7fnbG1MEliIzwu886fn8=
|
||||
golang.org/x/net v0.0.0-20220526153639-5463443f8c37/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
github.com/scylladb/gocql v1.16.1 h1:mxqUoOoHPrhzBNN+S0X195N+wCPZ5nrstfFz4QtBaZs=
|
||||
github.com/scylladb/gocql v1.16.1/go.mod h1:MSg2nr90XMcU0doVnISX3OtarTac5tSCGk6Q6QJd6oQ=
|
||||
github.com/scylladb/gocql v1.17.0 h1:sSjNTgSoC90+1XYXOMeWsQ8+AZbFYQWcspuScmUT53E=
|
||||
github.com/scylladb/gocql v1.17.0/go.mod h1:0VgVuYnAPOoYN17KXkYdWDxhL2/rH3V3vOisPMngpAw=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
|
||||
go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=
|
||||
golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4=
|
||||
golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
|
||||
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
|
||||
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
|
||||
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
|
||||
sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
|
||||
sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=
|
||||
|
||||
@@ -29,6 +29,8 @@ func ExampleUDT() {
|
||||
FirstName string
|
||||
LastName string
|
||||
}
|
||||
|
||||
_ = FullName{}
|
||||
}
|
||||
|
||||
func ExampleUDT_wraper() {
|
||||
@@ -42,4 +44,6 @@ func ExampleUDT_wraper() {
|
||||
gocqlx.UDT
|
||||
*FullName
|
||||
}
|
||||
|
||||
_ = FullNameUDT{}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ func TestExample(t *testing.T) {
|
||||
}
|
||||
defer session.Close()
|
||||
|
||||
session.ExecStmt(`DROP KEYSPACE examples`)
|
||||
_ = session.ExecStmt(`DROP KEYSPACE examples`)
|
||||
|
||||
basicCreateAndPopulateKeyspace(t, session, "examples")
|
||||
createAndPopulateKeyspaceAllTypes(t, session)
|
||||
@@ -270,7 +270,7 @@ func createAndPopulateKeyspaceAllTypes(t *testing.T, session gocqlx.Session) {
|
||||
copy(byteID[:], id)
|
||||
|
||||
date := time.Date(2021, time.December, 11, 10, 23, 0, 0, time.UTC)
|
||||
var double float64 = 1.2 // nolint:revive
|
||||
var double float64 = 1.2 //nolint:staticcheck // type needs to be enforces
|
||||
var float float32 = 1.3
|
||||
var integer int32 = 123
|
||||
listInt := []int32{1, 2, 3}
|
||||
|
||||
8
go.mod
8
go.mod
@@ -1,19 +1,19 @@
|
||||
module github.com/scylladb/gocqlx/v3
|
||||
|
||||
go 1.21
|
||||
go 1.25.0
|
||||
|
||||
require (
|
||||
github.com/gocql/gocql v1.7.0
|
||||
github.com/google/go-cmp v0.7.0
|
||||
github.com/psanford/memfs v0.0.0-20241019191636-4ef911798f9b
|
||||
github.com/scylladb/go-reflectx v1.0.1
|
||||
golang.org/x/sync v0.11.0
|
||||
golang.org/x/sync v0.18.0
|
||||
gopkg.in/inf.v0 v0.9.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/klauspost/compress v1.17.9 // indirect
|
||||
github.com/klauspost/compress v1.18.1 // indirect
|
||||
)
|
||||
|
||||
replace github.com/gocql/gocql => github.com/scylladb/gocql v1.15.3
|
||||
replace github.com/gocql/gocql => github.com/scylladb/gocql v1.17.0
|
||||
|
||||
59
go.sum
59
go.sum
@@ -1,54 +1,45 @@
|
||||
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k=
|
||||
github.com/bitly/go-hostpool v0.1.1 h1:SsovT4BFqgJQBAESkk2QgeeL7bqKq9oJie8JnD00R+Q=
|
||||
github.com/bitly/go-hostpool v0.1.1/go.mod h1:iwXQOF7+y3cO8vituSqGpBYf02TYTzxK4S2c4rf4cJs=
|
||||
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/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/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
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/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
||||
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
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/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co=
|
||||
github.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdBnrBd8Nrxr+0=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
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/psanford/memfs v0.0.0-20241019191636-4ef911798f9b h1:xzjEJAHum+mV5Dd5KyohRlCyP03o4yq6vNpEUtAJQzI=
|
||||
github.com/psanford/memfs v0.0.0-20241019191636-4ef911798f9b/go.mod h1:tcaRap0jS3eifrEEllL6ZMd9dg8IlDpi2S1oARrQ+NI=
|
||||
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/gocql v1.15.3 h1:0vJT5pm7g5v8/pCs3tuXuRAfSRWvc1kib8J846Z+Z4g=
|
||||
github.com/scylladb/gocql v1.15.3/go.mod h1:+rInt+HjERaMEYC4N8LocQQEAdREhYKU4QPkE00K5dA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
golang.org/x/net v0.0.0-20220526153639-5463443f8c37 h1:lUkvobShwKsOesNfWWlCS5q7fnbG1MEliIzwu886fn8=
|
||||
golang.org/x/net v0.0.0-20220526153639-5463443f8c37/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
|
||||
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
github.com/scylladb/gocql v1.16.1 h1:mxqUoOoHPrhzBNN+S0X195N+wCPZ5nrstfFz4QtBaZs=
|
||||
github.com/scylladb/gocql v1.16.1/go.mod h1:MSg2nr90XMcU0doVnISX3OtarTac5tSCGk6Q6QJd6oQ=
|
||||
github.com/scylladb/gocql v1.17.0 h1:sSjNTgSoC90+1XYXOMeWsQ8+AZbFYQWcspuScmUT53E=
|
||||
github.com/scylladb/gocql v1.17.0/go.mod h1:0VgVuYnAPOoYN17KXkYdWDxhL2/rH3V3vOisPMngpAw=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
|
||||
go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=
|
||||
golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4=
|
||||
golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
|
||||
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
|
||||
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
|
||||
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
|
||||
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
|
||||
sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
|
||||
sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=
|
||||
|
||||
@@ -20,15 +20,15 @@ func structOnlyError(t reflect.Type) error {
|
||||
return fmt.Errorf("expected a struct but got %s", t.Kind())
|
||||
}
|
||||
|
||||
if isUnmarshaller := reflect.PtrTo(t).Implements(unmarshallerInterface); isUnmarshaller {
|
||||
if isUnmarshaller := reflect.PointerTo(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 {
|
||||
if isUDTUnmarshaller := reflect.PointerTo(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 {
|
||||
if isAutoUDT := reflect.PointerTo(t).Implements(autoUDTInterface); isAutoUDT {
|
||||
return fmt.Errorf("expected a struct but the provided struct type %s implements gocqlx.UDT", t.Name())
|
||||
}
|
||||
|
||||
|
||||
10
iterx.go
10
iterx.go
@@ -62,7 +62,7 @@ func (iter *Iterx) StructOnly() *Iterx {
|
||||
// If no rows were selected, ErrNotFound is returned.
|
||||
func (iter *Iterx) Get(dest interface{}) error {
|
||||
iter.scanAny(dest)
|
||||
iter.Close()
|
||||
_ = iter.Close()
|
||||
|
||||
return iter.checkErrAndNotFound()
|
||||
}
|
||||
@@ -119,7 +119,7 @@ func (iter *Iterx) scanAny(dest interface{}) bool {
|
||||
// If no rows were selected, ErrNotFound is NOT returned.
|
||||
func (iter *Iterx) Select(dest interface{}) error {
|
||||
iter.scanAll(dest)
|
||||
iter.Close()
|
||||
_ = iter.Close()
|
||||
|
||||
return iter.err
|
||||
}
|
||||
@@ -209,7 +209,7 @@ func (iter *Iterx) scanAll(dest interface{}) bool {
|
||||
// - it is not a struct
|
||||
// - it has no exported fields
|
||||
func (iter *Iterx) isScannable(t reflect.Type) bool {
|
||||
ptr := reflect.PtrTo(t)
|
||||
ptr := reflect.PointerTo(t)
|
||||
switch {
|
||||
case ptr.Implements(unmarshallerInterface):
|
||||
return true
|
||||
@@ -260,7 +260,7 @@ func (iter *Iterx) structScan(value reflect.Value) bool {
|
||||
}
|
||||
|
||||
if iter.fields == nil {
|
||||
columns := columnNames(iter.Iter.Columns())
|
||||
columns := columnNames(iter.Columns())
|
||||
cas := len(columns) > 0 && columns[0] == appliedColumn
|
||||
|
||||
iter.fields = iter.Mapper.TraversalsByName(value.Type(), columns)
|
||||
@@ -342,7 +342,7 @@ func (iter *Iterx) Close() error {
|
||||
func (iter *Iterx) checkErrAndNotFound() error {
|
||||
if iter.err != nil {
|
||||
return iter.err
|
||||
} else if iter.Iter.NumRows() == 0 {
|
||||
} else if iter.NumRows() == 0 {
|
||||
return gocql.ErrNotFound
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -260,7 +260,7 @@ func TestIterxUDT(t *testing.T) {
|
||||
}
|
||||
|
||||
t.Cleanup(func() {
|
||||
session.Query(deleteStmt, nil).Bind(testuuid).ExecRelease() // nolint:errcheck
|
||||
_ = session.Query(deleteStmt, nil).Bind(testuuid).ExecRelease()
|
||||
})
|
||||
|
||||
t.Run("insert-bind", func(t *testing.T) {
|
||||
@@ -930,7 +930,9 @@ func TestIterxPaging(t *testing.T) {
|
||||
AllowFiltering().
|
||||
Columns("id", "val").ToCql()
|
||||
iter := session.Query(stmt, names).Bind(100).PageSize(10).Iter()
|
||||
defer iter.Close()
|
||||
defer func() {
|
||||
_ = iter.Close()
|
||||
}()
|
||||
|
||||
var cnt int
|
||||
for {
|
||||
|
||||
@@ -23,7 +23,9 @@ func fileChecksum(f fs.FS, path string) (string, error) {
|
||||
if err != nil {
|
||||
return "", nil
|
||||
}
|
||||
defer file.Close()
|
||||
defer func() {
|
||||
_ = file.Close()
|
||||
}()
|
||||
|
||||
h := md5.New()
|
||||
if _, err := io.Copy(h, file); err != nil {
|
||||
|
||||
@@ -3,3 +3,7 @@ package migrate
|
||||
func IsCallback(stmt string) (name string) {
|
||||
return isCallback(stmt)
|
||||
}
|
||||
|
||||
func IsComment(stmt string) bool {
|
||||
return isComment(stmt)
|
||||
}
|
||||
|
||||
@@ -201,6 +201,23 @@ func FromFS(ctx context.Context, session gocqlx.Session, f fs.FS) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// applyMigration executes a single migration file by parsing and applying its statements.
|
||||
// It handles three types of content in migration files:
|
||||
// - SQL statements: executed against the database
|
||||
// - Callback commands: processed via registered callback handlers (format: -- CALL function_name;)
|
||||
// - Regular comments: silently skipped (format: -- any comment text)
|
||||
//
|
||||
// The function maintains migration state by tracking the number of completed statements,
|
||||
// allowing for resumption of partially completed migrations.
|
||||
//
|
||||
// Parameters:
|
||||
// - ctx: context for cancellation and timeouts
|
||||
// - session: database session for executing statements
|
||||
// - f: filesystem containing the migration file
|
||||
// - path: path to the migration file within the filesystem
|
||||
// - done: number of statements already completed (for resuming partial migrations)
|
||||
//
|
||||
// Returns an error if the migration fails at any point.
|
||||
func applyMigration(ctx context.Context, session gocqlx.Session, f fs.FS, path string, done int) error {
|
||||
file, err := f.Open(path)
|
||||
if err != nil {
|
||||
@@ -208,7 +225,7 @@ func applyMigration(ctx context.Context, session gocqlx.Session, f fs.FS, path s
|
||||
}
|
||||
|
||||
b, err := io.ReadAll(file)
|
||||
file.Close()
|
||||
_ = file.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -272,19 +289,23 @@ func applyMigration(ctx context.Context, session gocqlx.Session, f fs.FS, path s
|
||||
// trim new lines and all whitespace characters
|
||||
stmt = strings.TrimSpace(stmt)
|
||||
|
||||
// Process statement based on its type
|
||||
if cb := isCallback(stmt); cb != "" {
|
||||
// Handle callback commands (e.g., "-- CALL function_name;")
|
||||
if Callback == nil {
|
||||
return fmt.Errorf("statement %d: missing callback handler while trying to call %s", i, cb)
|
||||
}
|
||||
if err := Callback(ctx, session, CallComment, cb); err != nil {
|
||||
return fmt.Errorf("callback %s: %s", cb, err)
|
||||
}
|
||||
} else {
|
||||
} else if stmt != "" && !isComment(stmt) {
|
||||
// Execute SQL statements (skip empty statements and comments)
|
||||
q := session.ContextQuery(ctx, stmt, nil).RetryPolicy(nil)
|
||||
if err := q.ExecRelease(); err != nil {
|
||||
return fmt.Errorf("statement %d: %s", i, err)
|
||||
}
|
||||
}
|
||||
// Regular comments and empty statements are silently skipped
|
||||
|
||||
// update info
|
||||
info.Done = i
|
||||
@@ -315,3 +336,10 @@ func isCallback(stmt string) (name string) {
|
||||
}
|
||||
return s[1]
|
||||
}
|
||||
|
||||
// isComment returns true if the statement is a SQL comment that should be ignored.
|
||||
// It distinguishes between regular comments (which should be skipped) and
|
||||
// callback commands (which should be processed).
|
||||
func isComment(stmt string) bool {
|
||||
return strings.HasPrefix(stmt, "--") && isCallback(stmt) == ""
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ func TestPending(t *testing.T) {
|
||||
defer recreateTables(t, session)
|
||||
|
||||
f := memfs.New()
|
||||
writeFile(f, 0, fmt.Sprintf(insertMigrate, 0)+";")
|
||||
writeFile(t, f, 0, fmt.Sprintf(insertMigrate, 0)+";")
|
||||
|
||||
pending, err := migrate.Pending(ctx, session, f)
|
||||
if err != nil {
|
||||
@@ -80,7 +80,7 @@ func TestPending(t *testing.T) {
|
||||
}
|
||||
|
||||
for i := 1; i < 3; i++ {
|
||||
writeFile(f, i, fmt.Sprintf(insertMigrate, i)+";")
|
||||
writeFile(t, f, i, fmt.Sprintf(insertMigrate, i)+";")
|
||||
}
|
||||
|
||||
pending, err = migrate.Pending(ctx, session, f)
|
||||
@@ -101,7 +101,7 @@ func TestMigration(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
t.Run("init", func(t *testing.T) {
|
||||
if err := migrate.FromFS(ctx, session, makeTestFS(2)); err != nil {
|
||||
if err := migrate.FromFS(ctx, session, makeTestFS(t, 2)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if c := countMigrations(t, session); c != 2 {
|
||||
@@ -110,7 +110,7 @@ func TestMigration(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("update", func(t *testing.T) {
|
||||
if err := migrate.FromFS(ctx, session, makeTestFS(4)); err != nil {
|
||||
if err := migrate.FromFS(ctx, session, makeTestFS(t, 4)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if c := countMigrations(t, session); c != 4 {
|
||||
@@ -119,7 +119,7 @@ func TestMigration(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("ahead", func(t *testing.T) {
|
||||
err := migrate.FromFS(ctx, session, makeTestFS(2))
|
||||
err := migrate.FromFS(ctx, session, makeTestFS(t, 2))
|
||||
if err == nil || !strings.Contains(err.Error(), "ahead") {
|
||||
t.Fatal("expected error")
|
||||
} else {
|
||||
@@ -128,8 +128,8 @@ func TestMigration(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("tempered with file", func(t *testing.T) {
|
||||
f := makeTestFS(4)
|
||||
writeFile(f, 3, "SELECT * FROM bla;")
|
||||
f := makeTestFS(t, 4)
|
||||
writeFile(t, f, 3, "SELECT * FROM bla;")
|
||||
|
||||
if err := migrate.FromFS(ctx, session, f); err == nil || !strings.Contains(err.Error(), "tampered") {
|
||||
t.Fatal("expected error")
|
||||
@@ -148,8 +148,11 @@ func TestMigrationNoSemicolon(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
f := makeTestFS(0)
|
||||
f.WriteFile("0.cql", []byte(fmt.Sprintf(insertMigrate, 0)+";"+fmt.Sprintf(insertMigrate, 1)), fs.ModePerm)
|
||||
f := makeTestFS(t, 0)
|
||||
err := f.WriteFile("0.cql", []byte(fmt.Sprintf(insertMigrate, 0)+";"+fmt.Sprintf(insertMigrate, 1)), fs.ModePerm)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
if err := migrate.FromFS(ctx, session, f); err != nil {
|
||||
@@ -160,6 +163,32 @@ func TestMigrationNoSemicolon(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestMigrationWithTrailingComment(t *testing.T) {
|
||||
session := gocqlxtest.CreateSession(t)
|
||||
defer session.Close()
|
||||
recreateTables(t, session)
|
||||
|
||||
if err := session.ExecStmt(migrateSchema); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
f := makeTestFS(t, 0)
|
||||
// Create a migration with a trailing comment (this should reproduce the issue)
|
||||
migrationContent := fmt.Sprintf(insertMigrate, 0) + "; -- ttl 1 hour"
|
||||
err := f.WriteFile("0.cql", []byte(migrationContent), fs.ModePerm)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
if err := migrate.FromFS(ctx, session, f); err != nil {
|
||||
t.Fatal("Migration should succeed with trailing comment, but got error:", err)
|
||||
}
|
||||
if c := countMigrations(t, session); c != 1 {
|
||||
t.Fatal("expected 1 migration got", c)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsCallback(t *testing.T) {
|
||||
table := []struct {
|
||||
Name string
|
||||
@@ -211,6 +240,60 @@ func TestIsCallback(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsComment(t *testing.T) {
|
||||
table := []struct {
|
||||
Name string
|
||||
Stmt string
|
||||
IsComment bool
|
||||
}{
|
||||
{
|
||||
Name: "CQL statement",
|
||||
Stmt: "SELECT * from X;",
|
||||
IsComment: false,
|
||||
},
|
||||
{
|
||||
Name: "Regular comment",
|
||||
Stmt: "-- This is a comment",
|
||||
IsComment: true,
|
||||
},
|
||||
{
|
||||
Name: "Comment with additional text",
|
||||
Stmt: "-- ttl 1 hour",
|
||||
IsComment: true,
|
||||
},
|
||||
{
|
||||
Name: "Callback command (not a regular comment)",
|
||||
Stmt: "-- CALL Foo;",
|
||||
IsComment: false,
|
||||
},
|
||||
{
|
||||
Name: "Callback with spaces (not a regular comment)",
|
||||
Stmt: "-- CALL Bar;",
|
||||
IsComment: false,
|
||||
},
|
||||
{
|
||||
Name: "Empty statement",
|
||||
Stmt: "",
|
||||
IsComment: false,
|
||||
},
|
||||
{
|
||||
Name: "Whitespace only",
|
||||
Stmt: " ",
|
||||
IsComment: false,
|
||||
},
|
||||
}
|
||||
|
||||
for i := range table {
|
||||
test := table[i]
|
||||
t.Run(test.Name, func(t *testing.T) {
|
||||
result := migrate.IsComment(test.Stmt)
|
||||
if result != test.IsComment {
|
||||
t.Errorf("IsComment(%q) = %v, expected %v", test.Stmt, result, test.IsComment)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMigrationCallback(t *testing.T) {
|
||||
var (
|
||||
beforeCalled int
|
||||
@@ -264,7 +347,7 @@ func TestMigrationCallback(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
t.Run("init", func(t *testing.T) {
|
||||
f := makeTestFS(2)
|
||||
f := makeTestFS(t, 2)
|
||||
reset()
|
||||
|
||||
if err := migrate.FromFS(ctx, session, f); err != nil {
|
||||
@@ -274,7 +357,7 @@ func TestMigrationCallback(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("no duplicate calls", func(t *testing.T) {
|
||||
f := makeTestFS(4)
|
||||
f := makeTestFS(t, 4)
|
||||
reset()
|
||||
|
||||
if err := migrate.FromFS(ctx, session, f); err != nil {
|
||||
@@ -284,9 +367,9 @@ func TestMigrationCallback(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("in calls", func(t *testing.T) {
|
||||
f := makeTestFS(4)
|
||||
writeFile(f, 4, "\n-- CALL Foo;\n")
|
||||
writeFile(f, 5, "\n-- CALL Bar;\n")
|
||||
f := makeTestFS(t, 4)
|
||||
writeFile(t, f, 4, "\n-- CALL Foo;\n")
|
||||
writeFile(t, f, 5, "\n-- CALL Bar;\n")
|
||||
reset()
|
||||
|
||||
if err := migrate.FromFS(ctx, session, f); err != nil {
|
||||
@@ -306,14 +389,19 @@ func countMigrations(tb testing.TB, session gocqlx.Session) int {
|
||||
return v
|
||||
}
|
||||
|
||||
func makeTestFS(n int) *memfs.FS {
|
||||
func makeTestFS(tb testing.TB, n int) *memfs.FS {
|
||||
tb.Helper()
|
||||
f := memfs.New()
|
||||
for i := 0; i < n; i++ {
|
||||
writeFile(f, i, fmt.Sprintf(insertMigrate, i)+";")
|
||||
writeFile(tb, f, i, fmt.Sprintf(insertMigrate, i)+";")
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
func writeFile(f *memfs.FS, i int, text string) {
|
||||
f.WriteFile(fmt.Sprint(i, ".cql"), []byte(text), fs.ModePerm)
|
||||
func writeFile(tb testing.TB, f *memfs.FS, i int, text string) {
|
||||
tb.Helper()
|
||||
err := f.WriteFile(fmt.Sprint(i, ".cql"), []byte(text), fs.ModePerm)
|
||||
if err != nil {
|
||||
tb.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ func (b *SelectBuilder) From(table string) *SelectBuilder {
|
||||
}
|
||||
|
||||
// Json sets the clause of the query.
|
||||
func (b *SelectBuilder) Json() *SelectBuilder { // nolint: revive
|
||||
func (b *SelectBuilder) Json() *SelectBuilder {
|
||||
b.json = true
|
||||
return b
|
||||
}
|
||||
|
||||
@@ -181,7 +181,7 @@ func (q *Queryx) bindStructArgs(arg0 interface{}, arg1 map[string]interface{}) (
|
||||
|
||||
err := q.Mapper.TraversalsByNameFunc(v.Type(), q.Names, func(i int, t []int) error {
|
||||
if len(t) != 0 {
|
||||
val := reflectx.FieldByIndexesReadOnly(v, t) // nolint:scopelint
|
||||
val := reflectx.FieldByIndexesReadOnly(v, t)
|
||||
arglist = append(arglist, val.Interface())
|
||||
} else {
|
||||
val, ok := arg1[q.Names[i]]
|
||||
|
||||
@@ -16,7 +16,10 @@ func BenchmarkCompileNamedQuery(b *testing.B) {
|
||||
q := []byte("INSERT INTO cycling.cyclist_name (id, user_uuid, firstname, stars) VALUES (:id, :user_uuid, :firstname, :stars)")
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
gocqlx.CompileNamedQuery(q)
|
||||
_, _, err := gocqlx.CompileNamedQuery(q)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,51 +3,5 @@
|
||||
"extends": [
|
||||
"config:recommended"
|
||||
],
|
||||
"schedule": [
|
||||
"every weekend"
|
||||
],
|
||||
"labels": [
|
||||
"renovate",
|
||||
"dependencies"
|
||||
],
|
||||
"enabledManagers": [
|
||||
"gomod",
|
||||
"github-actions",
|
||||
"helm-values"
|
||||
],
|
||||
"packageRules": [
|
||||
{
|
||||
"groupName": "All dependencies",
|
||||
"groupSlug": "all-dependencies",
|
||||
"matchManagers": [
|
||||
"gomod"
|
||||
],
|
||||
"matchPackageNames": [
|
||||
"!github.com/scylladb/gocql"
|
||||
],
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"groupName": "all non-major dependencies",
|
||||
"groupSlug": "all-minor-patch",
|
||||
"matchPackageNames": [
|
||||
"*"
|
||||
],
|
||||
"matchUpdateTypes": [
|
||||
"minor",
|
||||
"patch"
|
||||
],
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"matchPackageNames": [
|
||||
"github.com/scylladb/gocql"
|
||||
],
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"vulnerabilityAlerts": {
|
||||
"enabled": true
|
||||
},
|
||||
"osvVulnerabilityAlerts": true
|
||||
"prConcurrentLimit": 2
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ type Table struct {
|
||||
}
|
||||
|
||||
// New creates new Table based on table schema read from Metadata.
|
||||
func New(m Metadata) *Table { // nolint: gocritic
|
||||
func New(m Metadata) *Table {
|
||||
t := &Table{
|
||||
metadata: m,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user