Update golangci-lint and turn it on in CI
This commit is contained in:
committed by
Sylwia Szunejko
parent
a9ab270196
commit
ab80d70106
15
.github/workflows/main.yml
vendored
15
.github/workflows/main.yml
vendored
@@ -17,7 +17,8 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Git Checkout
|
- name: Git Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: '0'
|
||||||
- name: Install Go 1.17
|
- name: Install Go 1.17
|
||||||
uses: actions/setup-go@v3
|
uses: actions/setup-go@v3
|
||||||
with:
|
with:
|
||||||
@@ -33,17 +34,13 @@ jobs:
|
|||||||
${{ runner.os }}-go-
|
${{ runner.os }}-go-
|
||||||
|
|
||||||
- name: Make Directory for GOBIN
|
- name: Make Directory for GOBIN
|
||||||
run: mkdir -p ${GOBIN}
|
run: mkdir -p "${GOBIN}"
|
||||||
|
|
||||||
- name: Download Dependencies
|
- name: Download Dependencies
|
||||||
run: make get-deps
|
run: git --version && make get-deps && make get-tools
|
||||||
|
|
||||||
# - name: Lint
|
- name: Lint
|
||||||
# uses: golangci/golangci-lint-action@v3
|
run: make check
|
||||||
# with:
|
|
||||||
# version: v1.45.2
|
|
||||||
|
|
||||||
- run: go vet ./...
|
|
||||||
|
|
||||||
- name: Run Scylla Container
|
- name: Run Scylla Container
|
||||||
run: make run-scylla
|
run: make run-scylla
|
||||||
|
|||||||
@@ -1,8 +1,23 @@
|
|||||||
run:
|
run:
|
||||||
deadline: 5m
|
deadline: 5m
|
||||||
tests: false
|
tests: true
|
||||||
|
allow-parallel-runners: true
|
||||||
|
modules-download-mode: readonly
|
||||||
|
build-tags: [ all, integration ]
|
||||||
|
|
||||||
linters-settings:
|
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:
|
errcheck:
|
||||||
check-blank: true
|
check-blank: true
|
||||||
gocognit:
|
gocognit:
|
||||||
@@ -23,22 +38,43 @@ linters-settings:
|
|||||||
line-length: 180
|
line-length: 180
|
||||||
|
|
||||||
linters:
|
linters:
|
||||||
enable-all: true
|
disable-all: true
|
||||||
disable:
|
enable:
|
||||||
- funlen
|
- errcheck
|
||||||
- gas
|
- gocritic
|
||||||
- gochecknoglobals
|
- gofumpt
|
||||||
- gochecknoinits
|
- goheader
|
||||||
- gomnd
|
- goimports
|
||||||
- interfacer
|
- gosimple
|
||||||
- maligned
|
- govet
|
||||||
- nakedret
|
- ineffassign
|
||||||
- prealloc
|
- lll
|
||||||
- wsl
|
- misspell
|
||||||
|
- predeclared
|
||||||
|
- revive
|
||||||
|
- staticcheck
|
||||||
|
- thelper
|
||||||
|
- tparallel
|
||||||
|
- typecheck
|
||||||
|
- unused
|
||||||
|
- forbidigo
|
||||||
|
|
||||||
issues:
|
issues:
|
||||||
|
new: true
|
||||||
|
new-from-rev: origin/master
|
||||||
exclude-use-default: false
|
exclude-use-default: false
|
||||||
exclude:
|
exclude:
|
||||||
- composite literal uses unkeyed fields
|
- composite literal uses unkeyed fields
|
||||||
- Error return value of `.+\.Close` is not checked
|
- Error return value of `.+\.Close` is not checked
|
||||||
- method Json should be JSON
|
- method Json should be JSON
|
||||||
|
exclude-rules:
|
||||||
|
- path: (.*_test.go|migrate/example|gocqlxtest/)
|
||||||
|
linters:
|
||||||
|
- fieldalignment
|
||||||
|
- govet
|
||||||
|
- errcheck
|
||||||
|
- path: doc_test.go
|
||||||
|
linters:
|
||||||
|
- unused
|
||||||
|
- revive
|
||||||
|
|
||||||
|
|||||||
14
Makefile
14
Makefile
@@ -28,6 +28,12 @@ fmt:
|
|||||||
check:
|
check:
|
||||||
@$(GOBIN)/golangci-lint run ./...
|
@$(GOBIN)/golangci-lint run ./...
|
||||||
|
|
||||||
|
.PHONY: fix
|
||||||
|
fix:
|
||||||
|
@$(GOBIN)/golangci-lint run --fix ./...
|
||||||
|
@fieldalignment -V=full >/dev/null 2>&1 || go install golang.org/x/tools/go/analysis/passes/fieldalignment/cmd/fieldalignment@v0.11.0
|
||||||
|
@$(GOBIN)/fieldalignment -test=false -fix ./...
|
||||||
|
|
||||||
GOTEST := go test -cpu $(GOTEST_CPU) -count=1 -cover -race -tags all
|
GOTEST := go test -cpu $(GOTEST_CPU) -count=1 -cover -race -tags all
|
||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
@@ -51,12 +57,12 @@ run-examples:
|
|||||||
run-scylla:
|
run-scylla:
|
||||||
@echo "==> Running test instance of Scylla $(SCYLLA_VERSION)"
|
@echo "==> Running test instance of Scylla $(SCYLLA_VERSION)"
|
||||||
@docker pull scylladb/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)
|
@docker run --name gocqlx-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
|
@until docker exec gocqlx-scylla cqlsh -e "DESCRIBE SCHEMA"; do sleep 2; done
|
||||||
|
|
||||||
.PHONY: stop-scylla
|
.PHONY: stop-scylla
|
||||||
stop-scylla:
|
stop-scylla:
|
||||||
@docker stop scylla
|
@docker stop gocqlx-scylla
|
||||||
|
|
||||||
.PHONY: get-deps
|
.PHONY: get-deps
|
||||||
get-deps:
|
get-deps:
|
||||||
@@ -69,4 +75,4 @@ endef
|
|||||||
.PHONY: get-tools
|
.PHONY: get-tools
|
||||||
get-tools:
|
get-tools:
|
||||||
@echo "==> Installing tools at $(GOBIN)..."
|
@echo "==> Installing tools at $(GOBIN)..."
|
||||||
@$(call dl_tgz,golangci-lint,https://github.com/golangci/golangci-lint/releases/download/v1.45.2/golangci-lint-v1.45.2-linux-amd64.tar.gz)
|
@$(call dl_tgz,golangci-lint,https://github.com/golangci/golangci-lint/releases/download/v1.59.1/golangci-lint-1.59.1-linux-amd64.tar.gz)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"github.com/gocql/gocql"
|
"github.com/gocql/gocql"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Batch is a wrapper around gocql.Batch
|
||||||
type Batch struct {
|
type Batch struct {
|
||||||
*gocql.Batch
|
*gocql.Batch
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
|
|
||||||
"github.com/gocql/gocql"
|
"github.com/gocql/gocql"
|
||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
|
|
||||||
"github.com/scylladb/gocqlx/v2"
|
"github.com/scylladb/gocqlx/v2"
|
||||||
"github.com/scylladb/gocqlx/v2/gocqlxtest"
|
"github.com/scylladb/gocqlx/v2/gocqlxtest"
|
||||||
"github.com/scylladb/gocqlx/v2/qb"
|
"github.com/scylladb/gocqlx/v2/qb"
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/scylladb/gocqlx/v2"
|
"github.com/scylladb/gocqlx/v2"
|
||||||
. "github.com/scylladb/gocqlx/v2/gocqlxtest"
|
"github.com/scylladb/gocqlx/v2/gocqlxtest"
|
||||||
"github.com/scylladb/gocqlx/v2/qb"
|
"github.com/scylladb/gocqlx/v2/qb"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ var benchPersonCols = []string{"id", "first_name", "last_name", "email", "gender
|
|||||||
// BenchmarkBaseGocqlInsert performs standard insert.
|
// BenchmarkBaseGocqlInsert performs standard insert.
|
||||||
func BenchmarkBaseGocqlInsert(b *testing.B) {
|
func BenchmarkBaseGocqlInsert(b *testing.B) {
|
||||||
people := loadFixtures()
|
people := loadFixtures()
|
||||||
session := CreateSession(b)
|
session := gocqlxtest.CreateSession(b)
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
|
|
||||||
if err := session.ExecStmt(benchPersonSchema); err != nil {
|
if err := session.ExecStmt(benchPersonSchema); err != nil {
|
||||||
@@ -69,7 +69,7 @@ func BenchmarkBaseGocqlInsert(b *testing.B) {
|
|||||||
// BenchmarkGocqlInsert performs insert with struct binding.
|
// BenchmarkGocqlInsert performs insert with struct binding.
|
||||||
func BenchmarkGocqlxInsert(b *testing.B) {
|
func BenchmarkGocqlxInsert(b *testing.B) {
|
||||||
people := loadFixtures()
|
people := loadFixtures()
|
||||||
session := CreateSession(b)
|
session := gocqlxtest.CreateSession(b)
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
|
|
||||||
if err := session.ExecStmt(benchPersonSchema); err != nil {
|
if err := session.ExecStmt(benchPersonSchema); err != nil {
|
||||||
@@ -96,7 +96,7 @@ func BenchmarkGocqlxInsert(b *testing.B) {
|
|||||||
// BenchmarkBaseGocqlGet performs standard scan.
|
// BenchmarkBaseGocqlGet performs standard scan.
|
||||||
func BenchmarkBaseGocqlGet(b *testing.B) {
|
func BenchmarkBaseGocqlGet(b *testing.B) {
|
||||||
people := loadFixtures()
|
people := loadFixtures()
|
||||||
session := CreateSession(b)
|
session := gocqlxtest.CreateSession(b)
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
|
|
||||||
initTable(b, session, people)
|
initTable(b, session, people)
|
||||||
@@ -119,7 +119,7 @@ func BenchmarkBaseGocqlGet(b *testing.B) {
|
|||||||
// BenchmarkGocqlxGet performs get.
|
// BenchmarkGocqlxGet performs get.
|
||||||
func BenchmarkGocqlxGet(b *testing.B) {
|
func BenchmarkGocqlxGet(b *testing.B) {
|
||||||
people := loadFixtures()
|
people := loadFixtures()
|
||||||
session := CreateSession(b)
|
session := gocqlxtest.CreateSession(b)
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
|
|
||||||
initTable(b, session, people)
|
initTable(b, session, people)
|
||||||
@@ -147,7 +147,7 @@ func BenchmarkGocqlxGet(b *testing.B) {
|
|||||||
// pointers.
|
// pointers.
|
||||||
func BenchmarkBaseGocqlSelect(b *testing.B) {
|
func BenchmarkBaseGocqlSelect(b *testing.B) {
|
||||||
people := loadFixtures()
|
people := loadFixtures()
|
||||||
session := CreateSession(b)
|
session := gocqlxtest.CreateSession(b)
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
|
|
||||||
initTable(b, session, people)
|
initTable(b, session, people)
|
||||||
@@ -162,7 +162,7 @@ func BenchmarkBaseGocqlSelect(b *testing.B) {
|
|||||||
v := make([]*benchPerson, 100)
|
v := make([]*benchPerson, 100)
|
||||||
p := new(benchPerson)
|
p := new(benchPerson)
|
||||||
for iter.Scan(&p.ID, &p.FirstName, &p.LastName, &p.Email, &p.Gender, &p.IPAddress) {
|
for iter.Scan(&p.ID, &p.FirstName, &p.LastName, &p.Email, &p.Gender, &p.IPAddress) {
|
||||||
v = append(v, p)
|
v = append(v, p) // nolint:staticcheck
|
||||||
p = new(benchPerson)
|
p = new(benchPerson)
|
||||||
}
|
}
|
||||||
if err := iter.Close(); err != nil {
|
if err := iter.Close(); err != nil {
|
||||||
@@ -174,7 +174,7 @@ func BenchmarkBaseGocqlSelect(b *testing.B) {
|
|||||||
// BenchmarkGocqlSelect performs select to a slice pointers.
|
// BenchmarkGocqlSelect performs select to a slice pointers.
|
||||||
func BenchmarkGocqlxSelect(b *testing.B) {
|
func BenchmarkGocqlxSelect(b *testing.B) {
|
||||||
people := loadFixtures()
|
people := loadFixtures()
|
||||||
session := CreateSession(b)
|
session := gocqlxtest.CreateSession(b)
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
|
|
||||||
initTable(b, session, people)
|
initTable(b, session, people)
|
||||||
@@ -212,6 +212,8 @@ func loadFixtures() []*benchPerson {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func initTable(b *testing.B, session gocqlx.Session, people []*benchPerson) {
|
func initTable(b *testing.B, session gocqlx.Session, people []*benchPerson) {
|
||||||
|
b.Helper()
|
||||||
|
|
||||||
if err := session.ExecStmt(benchPersonSchema); err != nil {
|
if err := session.ExecStmt(benchPersonSchema); err != nil {
|
||||||
b.Fatal(err)
|
b.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,9 +74,9 @@ func mapScyllaToGoType(s string) string {
|
|||||||
|
|
||||||
typeStr := "struct {\n"
|
typeStr := "struct {\n"
|
||||||
for i, t := range types {
|
for i, t := range types {
|
||||||
typeStr = typeStr + "\t\tField" + strconv.Itoa(i+1) + " " + mapScyllaToGoType(t) + "\n"
|
typeStr += "\t\tField" + strconv.Itoa(i+1) + " " + mapScyllaToGoType(t) + "\n"
|
||||||
}
|
}
|
||||||
typeStr = typeStr + "\t}"
|
typeStr += "\t}"
|
||||||
|
|
||||||
return typeStr
|
return typeStr
|
||||||
}
|
}
|
||||||
@@ -96,8 +96,8 @@ func typeToString(t interface{}) string {
|
|||||||
return t.(gocql.NativeType).String()
|
return t.(gocql.NativeType).String()
|
||||||
case "gocql.CollectionType":
|
case "gocql.CollectionType":
|
||||||
collectionType := t.(gocql.CollectionType).String()
|
collectionType := t.(gocql.CollectionType).String()
|
||||||
collectionType = strings.Replace(collectionType, "(", "<", -1)
|
collectionType = strings.ReplaceAll(collectionType, "(", "<")
|
||||||
collectionType = strings.Replace(collectionType, ")", ">", -1)
|
collectionType = strings.ReplaceAll(collectionType, ")", ">")
|
||||||
return collectionType
|
return collectionType
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("Did not expect %v type in user defined type", tType))
|
panic(fmt.Sprintf("Did not expect %v type in user defined type", tType))
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/gocql/gocql"
|
"github.com/gocql/gocql"
|
||||||
|
|
||||||
"github.com/scylladb/gocqlx/v2"
|
"github.com/scylladb/gocqlx/v2"
|
||||||
_ "github.com/scylladb/gocqlx/v2/table"
|
_ "github.com/scylladb/gocqlx/v2/table"
|
||||||
)
|
)
|
||||||
@@ -31,10 +32,8 @@ var (
|
|||||||
flagIgnoreIndexes = cmd.Bool("ignore-indexes", false, "don't generate types for indexes")
|
flagIgnoreIndexes = cmd.Bool("ignore-indexes", false, "don't generate types for indexes")
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
//go:embed keyspace.tmpl
|
||||||
//go:embed keyspace.tmpl
|
var keyspaceTmpl string
|
||||||
keyspaceTmpl string
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
err := cmd.Parse(os.Args[1:])
|
err := cmd.Parse(os.Args[1:])
|
||||||
@@ -80,7 +79,6 @@ func renderTemplate(md *gocql.KeyspaceMetadata) ([]byte, error) {
|
|||||||
Funcs(template.FuncMap{"mapScyllaToGoType": mapScyllaToGoType}).
|
Funcs(template.FuncMap{"mapScyllaToGoType": mapScyllaToGoType}).
|
||||||
Funcs(template.FuncMap{"typeToString": typeToString}).
|
Funcs(template.FuncMap{"typeToString": typeToString}).
|
||||||
Parse(keyspaceTmpl)
|
Parse(keyspaceTmpl)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln("unable to parse models template:", err)
|
log.Fatalln("unable to parse models template:", err)
|
||||||
}
|
}
|
||||||
@@ -169,7 +167,7 @@ func existsInSlice(s []string, v string) bool {
|
|||||||
// The second element contains the name of the type.
|
// The second element contains the name of the type.
|
||||||
//
|
//
|
||||||
// [["<my_type,", "my_type"] ["my_other_type>", "my_other_type"]]
|
// [["<my_type,", "my_type"] ["my_other_type>", "my_other_type"]]
|
||||||
var userTypes = regexp.MustCompile(`(?:<|\s)(\w+)(?:>|,)`) // match all types contained in set<X>, list<X>, tuple<A, B> etc.
|
var userTypes = regexp.MustCompile(`(?:<|\s)(\w+)[>,]`) // match all types contained in set<X>, list<X>, tuple<A, B> etc.
|
||||||
|
|
||||||
// usedInTables reports whether the typeName is used in any of columns of the provided tables.
|
// usedInTables reports whether the typeName is used in any of columns of the provided tables.
|
||||||
func usedInTables(typeName string, tables map[string]*gocql.TableMetadata) bool {
|
func usedInTables(typeName string, tables map[string]*gocql.TableMetadata) bool {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
|
|
||||||
"github.com/gocql/gocql"
|
"github.com/gocql/gocql"
|
||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
|
|
||||||
"github.com/scylladb/gocqlx/v2/gocqlxtest"
|
"github.com/scylladb/gocqlx/v2/gocqlxtest"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -12,13 +12,13 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/scylladb/gocqlx/v2/dbutil"
|
"github.com/scylladb/gocqlx/v2/dbutil"
|
||||||
. "github.com/scylladb/gocqlx/v2/gocqlxtest"
|
"github.com/scylladb/gocqlx/v2/gocqlxtest"
|
||||||
"github.com/scylladb/gocqlx/v2/qb"
|
"github.com/scylladb/gocqlx/v2/qb"
|
||||||
"github.com/scylladb/gocqlx/v2/table"
|
"github.com/scylladb/gocqlx/v2/table"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRewriteTableTTL(t *testing.T) {
|
func TestRewriteTableTTL(t *testing.T) {
|
||||||
session := CreateSession(t)
|
session := gocqlxtest.CreateSession(t)
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
|
|
||||||
if err := session.ExecStmt(`CREATE TABLE gocqlx_test.rewrite_table (testtext text PRIMARY KEY)`); err != nil {
|
if err := session.ExecStmt(`CREATE TABLE gocqlx_test.rewrite_table (testtext text PRIMARY KEY)`); err != nil {
|
||||||
@@ -61,7 +61,7 @@ func TestRewriteTableTTL(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestRewriteTableClone(t *testing.T) {
|
func TestRewriteTableClone(t *testing.T) {
|
||||||
session := CreateSession(t)
|
session := gocqlxtest.CreateSession(t)
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
|
|
||||||
if err := session.ExecStmt(`CREATE TABLE gocqlx_test.rewrite_table_clone_src (testtext text PRIMARY KEY, testint int)`); err != nil {
|
if err := session.ExecStmt(`CREATE TABLE gocqlx_test.rewrite_table_clone_src (testtext text PRIMARY KEY, testint int)`); err != nil {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ package gocqlx_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gocql/gocql"
|
"github.com/gocql/gocql"
|
||||||
|
|
||||||
"github.com/scylladb/gocqlx/v2"
|
"github.com/scylladb/gocqlx/v2"
|
||||||
"github.com/scylladb/gocqlx/v2/qb"
|
"github.com/scylladb/gocqlx/v2/qb"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -14,12 +14,13 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gocql/gocql"
|
"github.com/gocql/gocql"
|
||||||
|
"golang.org/x/sync/errgroup"
|
||||||
|
"gopkg.in/inf.v0"
|
||||||
|
|
||||||
"github.com/scylladb/gocqlx/v2"
|
"github.com/scylladb/gocqlx/v2"
|
||||||
"github.com/scylladb/gocqlx/v2/gocqlxtest"
|
"github.com/scylladb/gocqlx/v2/gocqlxtest"
|
||||||
"github.com/scylladb/gocqlx/v2/qb"
|
"github.com/scylladb/gocqlx/v2/qb"
|
||||||
"github.com/scylladb/gocqlx/v2/table"
|
"github.com/scylladb/gocqlx/v2/table"
|
||||||
"golang.org/x/sync/errgroup"
|
|
||||||
"gopkg.in/inf.v0"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Running examples locally:
|
// Running examples locally:
|
||||||
@@ -43,7 +44,7 @@ func TestExample(t *testing.T) {
|
|||||||
datatypesBlob(t, session)
|
datatypesBlob(t, session)
|
||||||
datatypesUserDefinedType(t, session)
|
datatypesUserDefinedType(t, session)
|
||||||
datatypesUserDefinedTypeWrapper(t, session)
|
datatypesUserDefinedTypeWrapper(t, session)
|
||||||
datatypesJson(t, session)
|
datatypesJSON(t, session)
|
||||||
|
|
||||||
pagingForwardPaging(t, session)
|
pagingForwardPaging(t, session)
|
||||||
pagingEfficientFullTableScan(t, session)
|
pagingEfficientFullTableScan(t, session)
|
||||||
@@ -73,6 +74,8 @@ type PlaylistItem struct {
|
|||||||
// queries. It uses "BindStruct" function for parameter binding and "Select"
|
// queries. It uses "BindStruct" function for parameter binding and "Select"
|
||||||
// function for loading data to a slice.
|
// function for loading data to a slice.
|
||||||
func basicCreateAndPopulateKeyspace(t *testing.T, session gocqlx.Session, keyspace string) {
|
func basicCreateAndPopulateKeyspace(t *testing.T, session gocqlx.Session, keyspace string) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
err := session.ExecStmt(fmt.Sprintf(
|
err := session.ExecStmt(fmt.Sprintf(
|
||||||
`CREATE KEYSPACE IF NOT EXISTS %s WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}`,
|
`CREATE KEYSPACE IF NOT EXISTS %s WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}`,
|
||||||
keyspace,
|
keyspace,
|
||||||
@@ -162,6 +165,8 @@ func basicCreateAndPopulateKeyspace(t *testing.T, session gocqlx.Session, keyspa
|
|||||||
// queries with all types. It uses "BindStruct" function for parameter binding and "Select"
|
// queries with all types. It uses "BindStruct" function for parameter binding and "Select"
|
||||||
// function for loading data to a slice.
|
// function for loading data to a slice.
|
||||||
func createAndPopulateKeyspaceAllTypes(t *testing.T, session gocqlx.Session) {
|
func createAndPopulateKeyspaceAllTypes(t *testing.T, session gocqlx.Session) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
err := session.ExecStmt(`CREATE KEYSPACE IF NOT EXISTS examples WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}`)
|
err := session.ExecStmt(`CREATE KEYSPACE IF NOT EXISTS examples WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("create keyspace:", err)
|
t.Fatal("create keyspace:", err)
|
||||||
@@ -178,7 +183,7 @@ func createAndPopulateKeyspaceAllTypes(t *testing.T, session gocqlx.Session) {
|
|||||||
DoublE float64
|
DoublE float64
|
||||||
DuratioN gocql.Duration
|
DuratioN gocql.Duration
|
||||||
FloaT float32
|
FloaT float32
|
||||||
Id [16]byte
|
ID [16]byte
|
||||||
InT int32
|
InT int32
|
||||||
IneT string
|
IneT string
|
||||||
ListInt []int32
|
ListInt []int32
|
||||||
@@ -256,14 +261,16 @@ func createAndPopulateKeyspaceAllTypes(t *testing.T, session gocqlx.Session) {
|
|||||||
|
|
||||||
// Insert song using query builder.
|
// Insert song using query builder.
|
||||||
insertCheckTypes := qb.Insert("examples.check_types").
|
insertCheckTypes := qb.Insert("examples.check_types").
|
||||||
Columns("asci_i", "big_int", "blo_b", "boolea_n", "dat_e", "decima_l", "doubl_e", "duratio_n", "floa_t", "ine_t", "in_t", "small_int", "tex_t", "tim_e", "timestam_p", "timeuui_d", "tiny_int", "id", "var_char", "var_int", "map_int_text", "list_int", "set_int").Query(session)
|
Columns("asci_i", "big_int", "blo_b", "boolea_n", "dat_e", "decima_l", "doubl_e", "duratio_n", "floa_t",
|
||||||
|
"ine_t", "in_t", "small_int", "tex_t", "tim_e", "timestam_p", "timeuui_d", "tiny_int", "id", "var_char",
|
||||||
|
"var_int", "map_int_text", "list_int", "set_int").Query(session)
|
||||||
|
|
||||||
var byteId [16]byte
|
var byteID [16]byte
|
||||||
id := []byte("756716f7-2e54-4715-9f00-91dcbea6cf50")
|
id := []byte("756716f7-2e54-4715-9f00-91dcbea6cf50")
|
||||||
copy(byteId[:], id)
|
copy(byteID[:], id)
|
||||||
|
|
||||||
date := time.Date(2021, time.December, 11, 10, 23, 0, 0, time.UTC)
|
date := time.Date(2021, time.December, 11, 10, 23, 0, 0, time.UTC)
|
||||||
var double float64 = 1.2
|
var double float64 = 1.2 // nolint:revive
|
||||||
var float float32 = 1.3
|
var float float32 = 1.3
|
||||||
var integer int32 = 123
|
var integer int32 = 123
|
||||||
listInt := []int32{1, 2, 3}
|
listInt := []int32{1, 2, 3}
|
||||||
@@ -286,7 +293,7 @@ func createAndPopulateKeyspaceAllTypes(t *testing.T, session gocqlx.Session) {
|
|||||||
DoublE: double,
|
DoublE: double,
|
||||||
DuratioN: gocql.Duration{Months: 1, Days: 1, Nanoseconds: 86400},
|
DuratioN: gocql.Duration{Months: 1, Days: 1, Nanoseconds: 86400},
|
||||||
FloaT: float,
|
FloaT: float,
|
||||||
Id: byteId,
|
ID: byteID,
|
||||||
InT: integer,
|
InT: integer,
|
||||||
IneT: "127.0.0.1",
|
IneT: "127.0.0.1",
|
||||||
ListInt: listInt,
|
ListInt: listInt,
|
||||||
@@ -309,7 +316,7 @@ func createAndPopulateKeyspaceAllTypes(t *testing.T, session gocqlx.Session) {
|
|||||||
queryCheckTypes := checkTypesTable.SelectQuery(session)
|
queryCheckTypes := checkTypesTable.SelectQuery(session)
|
||||||
|
|
||||||
queryCheckTypes.BindStruct(&CheckTypesStruct{
|
queryCheckTypes.BindStruct(&CheckTypesStruct{
|
||||||
Id: byteId,
|
ID: byteID,
|
||||||
})
|
})
|
||||||
|
|
||||||
var items []*CheckTypesStruct
|
var items []*CheckTypesStruct
|
||||||
@@ -325,6 +332,8 @@ func createAndPopulateKeyspaceAllTypes(t *testing.T, session gocqlx.Session) {
|
|||||||
// This example shows how to load a single value using "Get" function.
|
// This example shows how to load a single value using "Get" function.
|
||||||
// Get can also work with UDTs and types that implement gocql marshalling functions.
|
// Get can also work with UDTs and types that implement gocql marshalling functions.
|
||||||
func basicReadScyllaVersion(t *testing.T, session gocqlx.Session) {
|
func basicReadScyllaVersion(t *testing.T, session gocqlx.Session) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
var releaseVersion string
|
var releaseVersion string
|
||||||
|
|
||||||
err := session.Query("SELECT release_version FROM system.local", nil).Get(&releaseVersion)
|
err := session.Query("SELECT release_version FROM system.local", nil).Get(&releaseVersion)
|
||||||
@@ -340,6 +349,8 @@ func basicReadScyllaVersion(t *testing.T, session gocqlx.Session) {
|
|||||||
// to handle situations where driver returns more coluns that we are ready to
|
// to handle situations where driver returns more coluns that we are ready to
|
||||||
// consume.
|
// consume.
|
||||||
func datatypesBlob(t *testing.T, session gocqlx.Session) {
|
func datatypesBlob(t *testing.T, session gocqlx.Session) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
err := session.ExecStmt(`CREATE KEYSPACE IF NOT EXISTS examples WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}`)
|
err := session.ExecStmt(`CREATE KEYSPACE IF NOT EXISTS examples WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("create keyspace:", err)
|
t.Fatal("create keyspace:", err)
|
||||||
@@ -392,6 +403,8 @@ type Coordinates struct {
|
|||||||
// This example shows how to add User Defined Type marshalling capabilities by
|
// This example shows how to add User Defined Type marshalling capabilities by
|
||||||
// adding a single line - embedding gocqlx.UDT.
|
// adding a single line - embedding gocqlx.UDT.
|
||||||
func datatypesUserDefinedType(t *testing.T, session gocqlx.Session) {
|
func datatypesUserDefinedType(t *testing.T, session gocqlx.Session) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
err := session.ExecStmt(`CREATE KEYSPACE IF NOT EXISTS examples WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}`)
|
err := session.ExecStmt(`CREATE KEYSPACE IF NOT EXISTS examples WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("create keyspace:", err)
|
t.Fatal("create keyspace:", err)
|
||||||
@@ -446,6 +459,8 @@ type coordinates struct {
|
|||||||
// types that we cannot modify, like library or transfer objects, without
|
// types that we cannot modify, like library or transfer objects, without
|
||||||
// rewriting them in runtime.
|
// rewriting them in runtime.
|
||||||
func datatypesUserDefinedTypeWrapper(t *testing.T, session gocqlx.Session) {
|
func datatypesUserDefinedTypeWrapper(t *testing.T, session gocqlx.Session) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
err := session.ExecStmt(`CREATE KEYSPACE IF NOT EXISTS examples WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}`)
|
err := session.ExecStmt(`CREATE KEYSPACE IF NOT EXISTS examples WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("create keyspace:", err)
|
t.Fatal("create keyspace:", err)
|
||||||
@@ -501,7 +516,9 @@ func datatypesUserDefinedTypeWrapper(t *testing.T, session gocqlx.Session) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This example shows how to use query builder to work with
|
// This example shows how to use query builder to work with
|
||||||
func datatypesJson(t *testing.T, session gocqlx.Session) {
|
func datatypesJSON(t *testing.T, session gocqlx.Session) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
err := session.ExecStmt(`CREATE KEYSPACE IF NOT EXISTS examples WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}`)
|
err := session.ExecStmt(`CREATE KEYSPACE IF NOT EXISTS examples WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("create keyspace:", err)
|
t.Fatal("create keyspace:", err)
|
||||||
@@ -524,17 +541,17 @@ func datatypesJson(t *testing.T, session gocqlx.Session) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// fromJson lets you provide individual columns as JSON:
|
// fromJson lets you provide individual columns as JSON:
|
||||||
insertFromJson := qb.Insert("examples.querybuilder_json").
|
insertFromJSON := qb.Insert("examples.querybuilder_json").
|
||||||
Columns("id", "name").
|
Columns("id", "name").
|
||||||
FuncColumn("specs", qb.Fn("fromJson", "json")).
|
FuncColumn("specs", qb.Fn("fromJson", "json")).
|
||||||
Query(session)
|
Query(session)
|
||||||
|
|
||||||
insertFromJson.BindMap(qb.M{
|
insertFromJSON.BindMap(qb.M{
|
||||||
"id": 3,
|
"id": 3,
|
||||||
"name": "Screen",
|
"name": "Screen",
|
||||||
"json": `{ "size": "24-inch" }`,
|
"json": `{ "size": "24-inch" }`,
|
||||||
})
|
})
|
||||||
if err := insertFromJson.Exec(); err != nil {
|
if err := insertFromJSON.Exec(); err != nil {
|
||||||
t.Fatal("Exec() failed:", err)
|
t.Fatal("Exec() failed:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -559,12 +576,12 @@ func datatypesJson(t *testing.T, session gocqlx.Session) {
|
|||||||
|
|
||||||
row := &struct {
|
row := &struct {
|
||||||
ID int
|
ID int
|
||||||
JsonSpecs string
|
JSONSpecs string
|
||||||
}{}
|
}{}
|
||||||
if err := q.Get(row); err != nil {
|
if err := q.Get(row); err != nil {
|
||||||
t.Fatal("Get() failed:", err)
|
t.Fatal("Get() failed:", err)
|
||||||
}
|
}
|
||||||
t.Logf("Entry #%d's specs as JSON: %s", row.ID, row.JsonSpecs)
|
t.Logf("Entry #%d's specs as JSON: %s", row.ID, row.JSONSpecs)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Video struct {
|
type Video struct {
|
||||||
@@ -600,6 +617,8 @@ func pagingFillTable(t *testing.T, insert *gocqlx.Queryx) {
|
|||||||
// This example shows how to use stateful paging and how "Select" function
|
// This example shows how to use stateful paging and how "Select" function
|
||||||
// can be used to fetch single page only.
|
// can be used to fetch single page only.
|
||||||
func pagingForwardPaging(t *testing.T, session gocqlx.Session) {
|
func pagingForwardPaging(t *testing.T, session gocqlx.Session) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
err := session.ExecStmt(`CREATE KEYSPACE IF NOT EXISTS examples WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}`)
|
err := session.ExecStmt(`CREATE KEYSPACE IF NOT EXISTS examples WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("create keyspace:", err)
|
t.Fatal("create keyspace:", err)
|
||||||
@@ -669,6 +688,8 @@ func pagingForwardPaging(t *testing.T, session gocqlx.Session) {
|
|||||||
//
|
//
|
||||||
// [1] https://www.scylladb.com/2017/02/13/efficient-full-table-scans-with-scylla-1-6/.
|
// [1] https://www.scylladb.com/2017/02/13/efficient-full-table-scans-with-scylla-1-6/.
|
||||||
func pagingEfficientFullTableScan(t *testing.T, session gocqlx.Session) {
|
func pagingEfficientFullTableScan(t *testing.T, session gocqlx.Session) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
err := session.ExecStmt(`CREATE KEYSPACE IF NOT EXISTS examples WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}`)
|
err := session.ExecStmt(`CREATE KEYSPACE IF NOT EXISTS examples WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("create keyspace:", err)
|
t.Fatal("create keyspace:", err)
|
||||||
@@ -779,6 +800,8 @@ func pagingEfficientFullTableScan(t *testing.T, session gocqlx.Session) {
|
|||||||
// Compare-And-Set (CAS) functions.
|
// Compare-And-Set (CAS) functions.
|
||||||
// See: https://docs.scylladb.com/using-scylla/lwt/ for more details.
|
// See: https://docs.scylladb.com/using-scylla/lwt/ for more details.
|
||||||
func lwtLock(t *testing.T, session gocqlx.Session) {
|
func lwtLock(t *testing.T, session gocqlx.Session) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
err := session.ExecStmt(`CREATE KEYSPACE IF NOT EXISTS examples WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}`)
|
err := session.ExecStmt(`CREATE KEYSPACE IF NOT EXISTS examples WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("create keyspace:", err)
|
t.Fatal("create keyspace:", err)
|
||||||
@@ -878,6 +901,8 @@ func lwtLock(t *testing.T, session gocqlx.Session) {
|
|||||||
// This example shows how to reuse the same insert statement with
|
// This example shows how to reuse the same insert statement with
|
||||||
// partially filled parameters without generating tombstones for empty columns.
|
// partially filled parameters without generating tombstones for empty columns.
|
||||||
func unsetEmptyValues(t *testing.T, session gocqlx.Session) {
|
func unsetEmptyValues(t *testing.T, session gocqlx.Session) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
err := session.ExecStmt(`CREATE KEYSPACE IF NOT EXISTS examples WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}`)
|
err := session.ExecStmt(`CREATE KEYSPACE IF NOT EXISTS examples WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("create keyspace:", err)
|
t.Fatal("create keyspace:", err)
|
||||||
|
|||||||
5
go.sum
5
go.sum
@@ -3,13 +3,8 @@ github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCS
|
|||||||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
|
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/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.0/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/gocql/gocql v0.0.0-20211015133455-b225f9b53fa1 h1:px9qUCy/RNJNsfCam4m2IxWGxNuimkrioEF0vrrbPsg=
|
github.com/gocql/gocql v0.0.0-20211015133455-b225f9b53fa1 h1:px9qUCy/RNJNsfCam4m2IxWGxNuimkrioEF0vrrbPsg=
|
||||||
github.com/gocql/gocql v0.0.0-20211015133455-b225f9b53fa1/go.mod h1:3gM2c4D3AnkISwBxGnMMsS8Oy4y2lhbPRsH4xnJrHG8=
|
github.com/gocql/gocql v0.0.0-20211015133455-b225f9b53fa1/go.mod h1:3gM2c4D3AnkISwBxGnMMsS8Oy4y2lhbPRsH4xnJrHG8=
|
||||||
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/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gocql/gocql"
|
"github.com/gocql/gocql"
|
||||||
|
|
||||||
"github.com/scylladb/gocqlx/v2"
|
"github.com/scylladb/gocqlx/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -31,8 +32,10 @@ var initOnce sync.Once
|
|||||||
|
|
||||||
// CreateSession creates a new gocqlx session from flags.
|
// CreateSession creates a new gocqlx session from flags.
|
||||||
func CreateSession(tb testing.TB) gocqlx.Session {
|
func CreateSession(tb testing.TB) gocqlx.Session {
|
||||||
|
tb.Helper()
|
||||||
|
|
||||||
cluster := CreateCluster()
|
cluster := CreateCluster()
|
||||||
return createSessionFromCluster(cluster, tb)
|
return createSessionFromCluster(tb, cluster)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateCluster creates gocql ClusterConfig from flags.
|
// CreateCluster creates gocql ClusterConfig from flags.
|
||||||
@@ -92,7 +95,8 @@ func CreateKeyspace(cluster *gocql.ClusterConfig, keyspace string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createSessionFromCluster(cluster *gocql.ClusterConfig, tb testing.TB) gocqlx.Session {
|
func createSessionFromCluster(tb testing.TB, cluster *gocql.ClusterConfig) gocqlx.Session {
|
||||||
|
tb.Helper()
|
||||||
if !flag.Parsed() {
|
if !flag.Parsed() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
}
|
}
|
||||||
|
|||||||
15
iterx.go
15
iterx.go
@@ -19,17 +19,16 @@ var DefaultUnsafe bool
|
|||||||
|
|
||||||
// Iterx is a wrapper around gocql.Iter which adds struct scanning capabilities.
|
// Iterx is a wrapper around gocql.Iter which adds struct scanning capabilities.
|
||||||
type Iterx struct {
|
type Iterx struct {
|
||||||
|
err error
|
||||||
*gocql.Iter
|
*gocql.Iter
|
||||||
Mapper *reflectx.Mapper
|
Mapper *reflectx.Mapper
|
||||||
|
|
||||||
|
// Cache memory for a rows during iteration in structScan.
|
||||||
|
fields [][]int
|
||||||
|
values []interface{}
|
||||||
unsafe bool
|
unsafe bool
|
||||||
structOnly bool
|
structOnly bool
|
||||||
applied 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
|
// Unsafe forces the iterator to ignore missing fields. By default when scanning
|
||||||
@@ -206,9 +205,9 @@ func (iter *Iterx) scanAll(dest interface{}) bool {
|
|||||||
|
|
||||||
// isScannable takes the reflect.Type and the actual dest value and returns
|
// isScannable takes the reflect.Type and the actual dest value and returns
|
||||||
// whether or not it's Scannable. t is scannable if:
|
// whether or not it's Scannable. t is scannable if:
|
||||||
// * ptr to t implements gocql.Unmarshaler, gocql.UDTUnmarshaler or UDT
|
// - ptr to t implements gocql.Unmarshaler, gocql.UDTUnmarshaler or UDT
|
||||||
// * it is not a struct
|
// - it is not a struct
|
||||||
// * it has no exported fields
|
// - it has no exported fields
|
||||||
func (iter *Iterx) isScannable(t reflect.Type) bool {
|
func (iter *Iterx) isScannable(t reflect.Type) bool {
|
||||||
ptr := reflect.PtrTo(t)
|
ptr := reflect.PtrTo(t)
|
||||||
switch {
|
switch {
|
||||||
|
|||||||
@@ -16,10 +16,11 @@ import (
|
|||||||
"github.com/gocql/gocql"
|
"github.com/gocql/gocql"
|
||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
"github.com/google/go-cmp/cmp/cmpopts"
|
"github.com/google/go-cmp/cmp/cmpopts"
|
||||||
"github.com/scylladb/gocqlx/v2"
|
|
||||||
. "github.com/scylladb/gocqlx/v2/gocqlxtest"
|
|
||||||
"github.com/scylladb/gocqlx/v2/qb"
|
|
||||||
"gopkg.in/inf.v0"
|
"gopkg.in/inf.v0"
|
||||||
|
|
||||||
|
"github.com/scylladb/gocqlx/v2"
|
||||||
|
"github.com/scylladb/gocqlx/v2/gocqlxtest"
|
||||||
|
"github.com/scylladb/gocqlx/v2/qb"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FullName struct {
|
type FullName struct {
|
||||||
@@ -48,7 +49,7 @@ type FullNamePtrUDT struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestIterxStruct(t *testing.T) {
|
func TestIterxStruct(t *testing.T) {
|
||||||
session := CreateSession(t)
|
session := gocqlxtest.CreateSession(t)
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
|
|
||||||
if err := session.ExecStmt(`CREATE TYPE gocqlx_test.FullName (first_Name text, last_name text)`); err != nil {
|
if err := session.ExecStmt(`CREATE TYPE gocqlx_test.FullName (first_Name text, last_name text)`); err != nil {
|
||||||
@@ -125,7 +126,10 @@ func TestIterxStruct(t *testing.T) {
|
|||||||
Testptrudt: FullNamePtrUDT{FullName: &FullName{FirstName: "John", LastName: "Doe"}},
|
Testptrudt: FullNamePtrUDT{FullName: &FullName{FirstName: "John", LastName: "Doe"}},
|
||||||
}
|
}
|
||||||
|
|
||||||
const insertStmt = `INSERT INTO struct_table (testuuid, testtimestamp, testvarchar, testbigint, testblob, testbool, testfloat,testdouble, testint, testdecimal, testlist, testset, testmap, testvarint, testinet, testcustom, testudt, testptrudt) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
|
const insertStmt = `INSERT INTO struct_table (
|
||||||
|
testuuid, testtimestamp, testvarchar, testbigint, testblob, testbool, testfloat, testdouble,
|
||||||
|
testint, testdecimal, testlist, testset, testmap, testvarint, testinet, testcustom, testudt, testptrudt
|
||||||
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
|
||||||
|
|
||||||
if err := session.Query(insertStmt, nil).Bind(
|
if err := session.Query(insertStmt, nil).Bind(
|
||||||
m.Testuuid,
|
m.Testuuid,
|
||||||
@@ -212,7 +216,7 @@ func TestIterxStruct(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestIterxScannable(t *testing.T) {
|
func TestIterxScannable(t *testing.T) {
|
||||||
session := CreateSession(t)
|
session := gocqlxtest.CreateSession(t)
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
|
|
||||||
if err := session.ExecStmt(`CREATE TABLE gocqlx_test.scannable_table (testfullname text PRIMARY KEY)`); err != nil {
|
if err := session.ExecStmt(`CREATE TABLE gocqlx_test.scannable_table (testfullname text PRIMARY KEY)`); err != nil {
|
||||||
@@ -265,7 +269,7 @@ func TestIterxScannable(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestIterxStructOnly(t *testing.T) {
|
func TestIterxStructOnly(t *testing.T) {
|
||||||
session := CreateSession(t)
|
session := gocqlxtest.CreateSession(t)
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
|
|
||||||
if err := session.ExecStmt(`CREATE TABLE gocqlx_test.struct_only_table (first_name text, last_name text, PRIMARY KEY (first_name, last_name))`); err != nil {
|
if err := session.ExecStmt(`CREATE TABLE gocqlx_test.struct_only_table (first_name text, last_name text, PRIMARY KEY (first_name, last_name))`); err != nil {
|
||||||
@@ -336,7 +340,7 @@ func TestIterxStructOnly(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestIterxStructOnlyUDT(t *testing.T) {
|
func TestIterxStructOnlyUDT(t *testing.T) {
|
||||||
session := CreateSession(t)
|
session := gocqlxtest.CreateSession(t)
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
|
|
||||||
if err := session.ExecStmt(`CREATE TABLE gocqlx_test.struct_only_udt_table (first_name text, last_name text, PRIMARY KEY (first_name, last_name))`); err != nil {
|
if err := session.ExecStmt(`CREATE TABLE gocqlx_test.struct_only_udt_table (first_name text, last_name text, PRIMARY KEY (first_name, last_name))`); err != nil {
|
||||||
@@ -412,7 +416,7 @@ func TestIterxStructOnlyUDT(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestIterxUnsafe(t *testing.T) {
|
func TestIterxUnsafe(t *testing.T) {
|
||||||
session := CreateSession(t)
|
session := gocqlxtest.CreateSession(t)
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
|
|
||||||
if err := session.ExecStmt(`CREATE TABLE gocqlx_test.unsafe_table (testtext text PRIMARY KEY, testtextunbound text)`); err != nil {
|
if err := session.ExecStmt(`CREATE TABLE gocqlx_test.unsafe_table (testtext text PRIMARY KEY, testtextunbound text)`); err != nil {
|
||||||
@@ -499,7 +503,7 @@ func TestIterxUnsafe(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestIterxNotFound(t *testing.T) {
|
func TestIterxNotFound(t *testing.T) {
|
||||||
session := CreateSession(t)
|
session := gocqlxtest.CreateSession(t)
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
|
|
||||||
if err := session.ExecStmt(`CREATE TABLE gocqlx_test.not_found_table (testtext text PRIMARY KEY)`); err != nil {
|
if err := session.ExecStmt(`CREATE TABLE gocqlx_test.not_found_table (testtext text PRIMARY KEY)`); err != nil {
|
||||||
@@ -547,7 +551,7 @@ func TestIterxNotFound(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestIterxErrorOnNil(t *testing.T) {
|
func TestIterxErrorOnNil(t *testing.T) {
|
||||||
session := CreateSession(t)
|
session := gocqlxtest.CreateSession(t)
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
|
|
||||||
if err := session.ExecStmt(`CREATE TABLE gocqlx_test.nil_table (testtext text PRIMARY KEY)`); err != nil {
|
if err := session.ExecStmt(`CREATE TABLE gocqlx_test.nil_table (testtext text PRIMARY KEY)`); err != nil {
|
||||||
@@ -582,7 +586,7 @@ func TestIterxErrorOnNil(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestIterxPaging(t *testing.T) {
|
func TestIterxPaging(t *testing.T) {
|
||||||
session := CreateSession(t)
|
session := gocqlxtest.CreateSession(t)
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
|
|
||||||
if err := session.ExecStmt(`CREATE TABLE gocqlx_test.paging_table (id int PRIMARY KEY, val int)`); err != nil {
|
if err := session.ExecStmt(`CREATE TABLE gocqlx_test.paging_table (id int PRIMARY KEY, val int)`); err != nil {
|
||||||
@@ -625,7 +629,7 @@ func TestIterxPaging(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestIterxCAS(t *testing.T) {
|
func TestIterxCAS(t *testing.T) {
|
||||||
session := CreateSession(t)
|
session := gocqlxtest.CreateSession(t)
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a ALv2-style
|
// Use of this source code is governed by a ALv2-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build all || integration
|
||||||
// +build all integration
|
// +build all integration
|
||||||
|
|
||||||
package cql
|
package cql
|
||||||
@@ -9,5 +10,6 @@ package cql
|
|||||||
import "embed"
|
import "embed"
|
||||||
|
|
||||||
// Files contains *.cql schema migration files.
|
// Files contains *.cql schema migration files.
|
||||||
|
//
|
||||||
//go:embed *.cql
|
//go:embed *.cql
|
||||||
var Files embed.FS
|
var Files embed.FS
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a ALv2-style
|
// Use of this source code is governed by a ALv2-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build all || integration
|
||||||
// +build all integration
|
// +build all integration
|
||||||
|
|
||||||
package example
|
package example
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ package migrate
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
@@ -20,6 +19,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gocql/gocql"
|
"github.com/gocql/gocql"
|
||||||
|
|
||||||
"github.com/scylladb/gocqlx/v2"
|
"github.com/scylladb/gocqlx/v2"
|
||||||
"github.com/scylladb/gocqlx/v2/qb"
|
"github.com/scylladb/gocqlx/v2/qb"
|
||||||
)
|
)
|
||||||
@@ -58,11 +58,11 @@ const (
|
|||||||
|
|
||||||
// Info contains information on migration applied on a database.
|
// Info contains information on migration applied on a database.
|
||||||
type Info struct {
|
type Info struct {
|
||||||
|
StartTime time.Time
|
||||||
|
EndTime time.Time
|
||||||
Name string
|
Name string
|
||||||
Checksum string
|
Checksum string
|
||||||
Done int
|
Done int
|
||||||
StartTime time.Time
|
|
||||||
EndTime time.Time
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// List provides a listing of applied migrations.
|
// List provides a listing of applied migrations.
|
||||||
@@ -128,8 +128,7 @@ func FromFS(ctx context.Context, session gocqlx.Session, f fs.FS) error {
|
|||||||
|
|
||||||
for i := 0; i < len(dbm); i++ {
|
for i := 0; i < len(dbm); i++ {
|
||||||
if dbm[i].Name != fm[i] {
|
if dbm[i].Name != fm[i] {
|
||||||
fmt.Println(dbm[i].Name, fm[i], i)
|
return fmt.Errorf("inconsistent migrations found, expected %q got %q at %d", fm[i], dbm[i].Name, i)
|
||||||
return errors.New("inconsistent migrations")
|
|
||||||
}
|
}
|
||||||
c, err := fileChecksum(f, fm[i])
|
c, err := fileChecksum(f, fm[i])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -15,8 +15,9 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/psanford/memfs"
|
"github.com/psanford/memfs"
|
||||||
|
|
||||||
"github.com/scylladb/gocqlx/v2"
|
"github.com/scylladb/gocqlx/v2"
|
||||||
. "github.com/scylladb/gocqlx/v2/gocqlxtest"
|
"github.com/scylladb/gocqlx/v2/gocqlxtest"
|
||||||
"github.com/scylladb/gocqlx/v2/migrate"
|
"github.com/scylladb/gocqlx/v2/migrate"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -45,7 +46,7 @@ func recreateTables(tb testing.TB, session gocqlx.Session) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMigration(t *testing.T) {
|
func TestMigration(t *testing.T) {
|
||||||
session := CreateSession(t)
|
session := gocqlxtest.CreateSession(t)
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
recreateTables(t, session)
|
recreateTables(t, session)
|
||||||
|
|
||||||
@@ -91,7 +92,7 @@ func TestMigration(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMigrationNoSemicolon(t *testing.T) {
|
func TestMigrationNoSemicolon(t *testing.T) {
|
||||||
session := CreateSession(t)
|
session := gocqlxtest.CreateSession(t)
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
recreateTables(t, session)
|
recreateTables(t, session)
|
||||||
|
|
||||||
@@ -171,11 +172,11 @@ func TestMigrationCallback(t *testing.T) {
|
|||||||
migrate.Callback = func(ctx context.Context, session gocqlx.Session, ev migrate.CallbackEvent, name string) error {
|
migrate.Callback = func(ctx context.Context, session gocqlx.Session, ev migrate.CallbackEvent, name string) error {
|
||||||
switch ev {
|
switch ev {
|
||||||
case migrate.BeforeMigration:
|
case migrate.BeforeMigration:
|
||||||
beforeCalled += 1
|
beforeCalled++
|
||||||
case migrate.AfterMigration:
|
case migrate.AfterMigration:
|
||||||
afterCalled += 1
|
afterCalled++
|
||||||
case migrate.CallComment:
|
case migrate.CallComment:
|
||||||
inCalled += 1
|
inCalled++
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -191,6 +192,8 @@ func TestMigrationCallback(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
assertCallbacks := func(t *testing.T, before, afer, in int) {
|
assertCallbacks := func(t *testing.T, before, afer, in int) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
if beforeCalled != before {
|
if beforeCalled != before {
|
||||||
t.Fatalf("expected %d before calls got %d", before, beforeCalled)
|
t.Fatalf("expected %d before calls got %d", before, beforeCalled)
|
||||||
}
|
}
|
||||||
@@ -202,7 +205,7 @@ func TestMigrationCallback(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
session := CreateSession(t)
|
session := gocqlxtest.CreateSession(t)
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
recreateTables(t, session)
|
recreateTables(t, session)
|
||||||
|
|
||||||
|
|||||||
16
qb/batch.go
16
qb/batch.go
@@ -18,21 +18,21 @@ import (
|
|||||||
|
|
||||||
// BatchBuilder builds CQL BATCH statements.
|
// BatchBuilder builds CQL BATCH statements.
|
||||||
type BatchBuilder struct {
|
type BatchBuilder struct {
|
||||||
unlogged bool
|
|
||||||
counter bool
|
|
||||||
using using
|
|
||||||
stmts []string
|
stmts []string
|
||||||
names []string
|
names []string
|
||||||
|
using using
|
||||||
|
unlogged bool
|
||||||
|
counter bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Batch returns a new BatchBuilder.
|
// Batch returns a new BatchBuilder.
|
||||||
// BatchBuilder encapsulates batch cqls as one ordinary gocql.Query for convenience.
|
// BatchBuilder encapsulates batch cqls as one ordinary gocql.Query for convenience.
|
||||||
// Below are the limitations of encapsulating batch cqls based on gocql.Query instead of gocql.Batch:
|
// Below are the limitations of encapsulating batch cqls based on gocql.Query instead of gocql.Batch:
|
||||||
// * gocql.Batch has some more batch specific check, such as BatchSize(65535).
|
// - gocql.Batch has some more batch specific check, such as BatchSize(65535).
|
||||||
// * gocql.Batch use BatchObserver instead of QueryObserver.
|
// - gocql.Batch use BatchObserver instead of QueryObserver.
|
||||||
// * gocql.Batch has cancelBatch call back.
|
// - gocql.Batch has cancelBatch call back.
|
||||||
// * gocql.Batch prepares the included statements separately, which is more efficient.
|
// - gocql.Batch prepares the included statements separately, which is more efficient.
|
||||||
// In contrast, gocqlx.qb.BatchBuilder, which is based on gocql.Query, prepares the whole batch statements as one ordinary query.
|
// In contrast, gocqlx.qb.BatchBuilder, which is based on gocql.Query, prepares the whole batch statements as one ordinary query.
|
||||||
//
|
//
|
||||||
// Deprecated: Please use gocql.Session.NewBatch() instead.
|
// Deprecated: Please use gocql.Session.NewBatch() instead.
|
||||||
func Batch() *BatchBuilder {
|
func Batch() *BatchBuilder {
|
||||||
|
|||||||
@@ -39,7 +39,8 @@ func TestBatchBuilder(t *testing.T) {
|
|||||||
B: Batch().
|
B: Batch().
|
||||||
AddWithPrefix("a", m).
|
AddWithPrefix("a", m).
|
||||||
AddWithPrefix("b", m),
|
AddWithPrefix("b", m),
|
||||||
S: "BEGIN BATCH INSERT INTO cycling.cyclist_name (id,user_uuid,firstname) VALUES (?,?,?) ; INSERT INTO cycling.cyclist_name (id,user_uuid,firstname) VALUES (?,?,?) ; APPLY BATCH ",
|
S: "BEGIN BATCH INSERT INTO cycling.cyclist_name (id,user_uuid,firstname) VALUES (?,?,?) ; " +
|
||||||
|
"INSERT INTO cycling.cyclist_name (id,user_uuid,firstname) VALUES (?,?,?) ; APPLY BATCH ",
|
||||||
N: []string{"a.id", "a.user_uuid", "a.firstname", "b.id", "b.user_uuid", "b.firstname"},
|
N: []string{"a.id", "a.user_uuid", "a.firstname", "b.id", "b.user_uuid", "b.firstname"},
|
||||||
},
|
},
|
||||||
// Add UNLOGGED
|
// Add UNLOGGED
|
||||||
@@ -64,7 +65,7 @@ func TestBatchBuilder(t *testing.T) {
|
|||||||
},
|
},
|
||||||
// Add TIMESTAMP
|
// Add TIMESTAMP
|
||||||
{
|
{
|
||||||
B: Batch().Timestamp(time.Date(2005, 05, 05, 0, 0, 0, 0, time.UTC)),
|
B: Batch().Timestamp(time.Date(2005, 5, 5, 0, 0, 0, 0, time.UTC)),
|
||||||
S: "BEGIN BATCH USING TIMESTAMP 1115251200000000 APPLY BATCH ",
|
S: "BEGIN BATCH USING TIMESTAMP 1115251200000000 APPLY BATCH ",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -26,9 +26,9 @@ const (
|
|||||||
|
|
||||||
// Cmp if a filtering comparator that is used in WHERE and IF clauses.
|
// Cmp if a filtering comparator that is used in WHERE and IF clauses.
|
||||||
type Cmp struct {
|
type Cmp struct {
|
||||||
op op
|
|
||||||
column string
|
|
||||||
value value
|
value value
|
||||||
|
column string
|
||||||
|
op op
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c Cmp) writeCql(cql *bytes.Buffer) (names []string) {
|
func (c Cmp) writeCql(cql *bytes.Buffer) (names []string) {
|
||||||
|
|||||||
@@ -165,8 +165,6 @@ func TestCmp(t *testing.T) {
|
|||||||
S: "like LIKE (?,?)",
|
S: "like LIKE (?,?)",
|
||||||
N: []string{"name[0]", "name[1]"},
|
N: []string{"name[0]", "name[1]"},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
// Custom bind names on tuples
|
// Custom bind names on tuples
|
||||||
{
|
{
|
||||||
C: EqTupleNamed("eq", 2, "name"),
|
C: EqTupleNamed("eq", 2, "name"),
|
||||||
|
|||||||
@@ -19,9 +19,9 @@ import (
|
|||||||
type DeleteBuilder struct {
|
type DeleteBuilder struct {
|
||||||
table string
|
table string
|
||||||
columns columns
|
columns columns
|
||||||
using using
|
|
||||||
where where
|
where where
|
||||||
_if _if
|
_if _if
|
||||||
|
using using
|
||||||
exists bool
|
exists bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ func TestDeleteBuilder(t *testing.T) {
|
|||||||
},
|
},
|
||||||
// Add TIMESTAMP
|
// Add TIMESTAMP
|
||||||
{
|
{
|
||||||
B: Delete("cycling.cyclist_name").Where(w).Timestamp(time.Date(2005, 05, 05, 0, 0, 0, 0, time.UTC)),
|
B: Delete("cycling.cyclist_name").Where(w).Timestamp(time.Date(2005, 5, 5, 0, 0, 0, 0, time.UTC)),
|
||||||
S: "DELETE FROM cycling.cyclist_name USING TIMESTAMP 1115251200000000 WHERE id=? ",
|
S: "DELETE FROM cycling.cyclist_name USING TIMESTAMP 1115251200000000 WHERE id=? ",
|
||||||
N: []string{"expr"},
|
N: []string{"expr"},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -17,16 +17,16 @@ import (
|
|||||||
|
|
||||||
// initializer specifies an value for a column in an insert operation.
|
// initializer specifies an value for a column in an insert operation.
|
||||||
type initializer struct {
|
type initializer struct {
|
||||||
column string
|
|
||||||
value value
|
value value
|
||||||
|
column string
|
||||||
}
|
}
|
||||||
|
|
||||||
// InsertBuilder builds CQL INSERT statements.
|
// InsertBuilder builds CQL INSERT statements.
|
||||||
type InsertBuilder struct {
|
type InsertBuilder struct {
|
||||||
table string
|
table string
|
||||||
columns []initializer
|
columns []initializer
|
||||||
unique bool
|
|
||||||
using using
|
using using
|
||||||
|
unique bool
|
||||||
json bool
|
json bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ func TestInsertBuilder(t *testing.T) {
|
|||||||
N []string
|
N []string
|
||||||
S string
|
S string
|
||||||
}{
|
}{
|
||||||
|
|
||||||
// Basic test for insert
|
// Basic test for insert
|
||||||
{
|
{
|
||||||
B: Insert("cycling.cyclist_name").Columns("id", "user_uuid", "firstname"),
|
B: Insert("cycling.cyclist_name").Columns("id", "user_uuid", "firstname"),
|
||||||
@@ -67,7 +66,7 @@ func TestInsertBuilder(t *testing.T) {
|
|||||||
},
|
},
|
||||||
// Add TIMESTAMP
|
// Add TIMESTAMP
|
||||||
{
|
{
|
||||||
B: Insert("cycling.cyclist_name").Columns("id", "user_uuid", "firstname").Timestamp(time.Date(2005, 05, 05, 0, 0, 0, 0, time.UTC)),
|
B: Insert("cycling.cyclist_name").Columns("id", "user_uuid", "firstname").Timestamp(time.Date(2005, 5, 5, 0, 0, 0, 0, time.UTC)),
|
||||||
S: "INSERT INTO cycling.cyclist_name (id,user_uuid,firstname) VALUES (?,?,?) USING TIMESTAMP 1115251200000000 ",
|
S: "INSERT INTO cycling.cyclist_name (id,user_uuid,firstname) VALUES (?,?,?) USING TIMESTAMP 1115251200000000 ",
|
||||||
N: []string{"id", "user_uuid", "firstname"},
|
N: []string{"id", "user_uuid", "firstname"},
|
||||||
},
|
},
|
||||||
@@ -78,7 +77,7 @@ func TestInsertBuilder(t *testing.T) {
|
|||||||
},
|
},
|
||||||
// Add TIMESTAMP
|
// Add TIMESTAMP
|
||||||
{
|
{
|
||||||
B: Insert("cycling.cyclist_name").Columns("id", "user_uuid", "firstname").Timestamp(time.Date(2005, 05, 05, 0, 0, 0, 0, time.UTC)),
|
B: Insert("cycling.cyclist_name").Columns("id", "user_uuid", "firstname").Timestamp(time.Date(2005, 5, 5, 0, 0, 0, 0, time.UTC)),
|
||||||
S: "INSERT INTO cycling.cyclist_name (id,user_uuid,firstname) VALUES (?,?,?) USING TIMESTAMP 1115251200000000 ",
|
S: "INSERT INTO cycling.cyclist_name (id,user_uuid,firstname) VALUES (?,?,?) USING TIMESTAMP 1115251200000000 ",
|
||||||
N: []string{"id", "user_uuid", "firstname"},
|
N: []string{"id", "user_uuid", "firstname"},
|
||||||
},
|
},
|
||||||
@@ -89,7 +88,7 @@ func TestInsertBuilder(t *testing.T) {
|
|||||||
},
|
},
|
||||||
// Add TIMESTAMP
|
// Add TIMESTAMP
|
||||||
{
|
{
|
||||||
B: Insert("cycling.cyclist_name").Columns("id", "user_uuid", "firstname").Timestamp(time.Date(2005, 05, 05, 0, 0, 0, 0, time.UTC)),
|
B: Insert("cycling.cyclist_name").Columns("id", "user_uuid", "firstname").Timestamp(time.Date(2005, 5, 5, 0, 0, 0, 0, time.UTC)),
|
||||||
S: "INSERT INTO cycling.cyclist_name (id,user_uuid,firstname) VALUES (?,?,?) USING TIMESTAMP 1115251200000000 ",
|
S: "INSERT INTO cycling.cyclist_name (id,user_uuid,firstname) VALUES (?,?,?) USING TIMESTAMP 1115251200000000 ",
|
||||||
N: []string{"id", "user_uuid", "firstname"},
|
N: []string{"id", "user_uuid", "firstname"},
|
||||||
},
|
},
|
||||||
|
|||||||
12
qb/select.go
12
qb/select.go
@@ -34,15 +34,15 @@ func (o Order) String() string {
|
|||||||
|
|
||||||
// SelectBuilder builds CQL SELECT statements.
|
// SelectBuilder builds CQL SELECT statements.
|
||||||
type SelectBuilder struct {
|
type SelectBuilder struct {
|
||||||
|
limit limit
|
||||||
|
limitPerPartition limit
|
||||||
table string
|
table string
|
||||||
columns columns
|
|
||||||
distinct columns
|
|
||||||
using using
|
|
||||||
where where
|
where where
|
||||||
groupBy columns
|
groupBy columns
|
||||||
orderBy columns
|
orderBy columns
|
||||||
limit limit
|
columns columns
|
||||||
limitPerPartition limit
|
distinct columns
|
||||||
|
using using
|
||||||
allowFiltering bool
|
allowFiltering bool
|
||||||
bypassCache bool
|
bypassCache bool
|
||||||
json bool
|
json bool
|
||||||
@@ -132,7 +132,7 @@ func (b *SelectBuilder) From(table string) *SelectBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Json sets the clause of the query.
|
// Json sets the clause of the query.
|
||||||
func (b *SelectBuilder) Json() *SelectBuilder {
|
func (b *SelectBuilder) Json() *SelectBuilder { // nolint: revive
|
||||||
b.json = true
|
b.json = true
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,10 +32,10 @@ func (a assignment) writeCql(cql *bytes.Buffer) (names []string) {
|
|||||||
// UpdateBuilder builds CQL UPDATE statements.
|
// UpdateBuilder builds CQL UPDATE statements.
|
||||||
type UpdateBuilder struct {
|
type UpdateBuilder struct {
|
||||||
table string
|
table string
|
||||||
using using
|
|
||||||
assignments []assignment
|
assignments []assignment
|
||||||
where where
|
where where
|
||||||
_if _if
|
_if _if
|
||||||
|
using using
|
||||||
exists bool
|
exists bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ func TestUpdateBuilder(t *testing.T) {
|
|||||||
},
|
},
|
||||||
// Add TIMESTAMP
|
// Add TIMESTAMP
|
||||||
{
|
{
|
||||||
B: Update("cycling.cyclist_name").Set("id", "user_uuid", "firstname").Where(w).Timestamp(time.Date(2005, 05, 05, 0, 0, 0, 0, time.UTC)),
|
B: Update("cycling.cyclist_name").Set("id", "user_uuid", "firstname").Where(w).Timestamp(time.Date(2005, 5, 5, 0, 0, 0, 0, time.UTC)),
|
||||||
S: "UPDATE cycling.cyclist_name USING TIMESTAMP 1115251200000000 SET id=?,user_uuid=?,firstname=? WHERE id=? ",
|
S: "UPDATE cycling.cyclist_name USING TIMESTAMP 1115251200000000 SET id=?,user_uuid=?,firstname=? WHERE id=? ",
|
||||||
N: []string{"id", "user_uuid", "firstname", "expr"},
|
N: []string{"id", "user_uuid", "firstname", "expr"},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -21,12 +21,12 @@ func Timestamp(t time.Time) int64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type using struct {
|
type using struct {
|
||||||
ttl int64
|
|
||||||
ttlName string
|
ttlName string
|
||||||
timestamp int64
|
|
||||||
timestampName string
|
timestampName string
|
||||||
timeout time.Duration
|
|
||||||
timeoutName string
|
timeoutName string
|
||||||
|
ttl int64
|
||||||
|
timestamp int64
|
||||||
|
timeout time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *using) TTL(d time.Duration) *using {
|
func (u *using) TTL(d time.Duration) *using {
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ func TestUsing(t *testing.T) {
|
|||||||
},
|
},
|
||||||
// Timestamp
|
// Timestamp
|
||||||
{
|
{
|
||||||
B: new(using).Timestamp(time.Date(2005, 05, 05, 0, 0, 0, 0, time.UTC)),
|
B: new(using).Timestamp(time.Date(2005, 5, 5, 0, 0, 0, 0, time.UTC)),
|
||||||
S: "USING TIMESTAMP 1115251200000000 ",
|
S: "USING TIMESTAMP 1115251200000000 ",
|
||||||
},
|
},
|
||||||
// TimestampNamed
|
// TimestampNamed
|
||||||
@@ -65,7 +65,7 @@ func TestUsing(t *testing.T) {
|
|||||||
},
|
},
|
||||||
// TTL Timestamp
|
// TTL Timestamp
|
||||||
{
|
{
|
||||||
B: new(using).TTL(time.Second).Timestamp(time.Date(2005, 05, 05, 0, 0, 0, 0, time.UTC)),
|
B: new(using).TTL(time.Second).Timestamp(time.Date(2005, 5, 5, 0, 0, 0, 0, time.UTC)),
|
||||||
S: "USING TTL 1 AND TIMESTAMP 1115251200000000 ",
|
S: "USING TTL 1 AND TIMESTAMP 1115251200000000 ",
|
||||||
},
|
},
|
||||||
// TTL TimestampNamed
|
// TTL TimestampNamed
|
||||||
@@ -82,7 +82,7 @@ func TestUsing(t *testing.T) {
|
|||||||
},
|
},
|
||||||
// TTLNamed Timestamp
|
// TTLNamed Timestamp
|
||||||
{
|
{
|
||||||
B: new(using).TTLNamed("ttl").Timestamp(time.Date(2005, 05, 05, 0, 0, 0, 0, time.UTC)),
|
B: new(using).TTLNamed("ttl").Timestamp(time.Date(2005, 5, 5, 0, 0, 0, 0, time.UTC)),
|
||||||
S: "USING TTL ? AND TIMESTAMP 1115251200000000 ",
|
S: "USING TTL ? AND TIMESTAMP 1115251200000000 ",
|
||||||
N: []string{"ttl"},
|
N: []string{"ttl"},
|
||||||
},
|
},
|
||||||
@@ -99,7 +99,7 @@ func TestUsing(t *testing.T) {
|
|||||||
},
|
},
|
||||||
// TTL Timestamp Timeout
|
// TTL Timestamp Timeout
|
||||||
{
|
{
|
||||||
B: new(using).TTL(time.Second).Timestamp(time.Date(2005, 05, 05, 0, 0, 0, 0, time.UTC)).Timeout(time.Second),
|
B: new(using).TTL(time.Second).Timestamp(time.Date(2005, 5, 5, 0, 0, 0, 0, time.UTC)).Timeout(time.Second),
|
||||||
S: "USING TTL 1 AND TIMESTAMP 1115251200000000 AND TIMEOUT 1s ",
|
S: "USING TTL 1 AND TIMESTAMP 1115251200000000 AND TIMEOUT 1s ",
|
||||||
},
|
},
|
||||||
// TTL with no duration
|
// TTL with no duration
|
||||||
@@ -129,13 +129,13 @@ func TestUsing(t *testing.T) {
|
|||||||
},
|
},
|
||||||
// Timestamp TimestampNamed
|
// Timestamp TimestampNamed
|
||||||
{
|
{
|
||||||
B: new(using).Timestamp(time.Date(2005, 05, 05, 0, 0, 0, 0, time.UTC)).TimestampNamed("ts"),
|
B: new(using).Timestamp(time.Date(2005, 5, 5, 0, 0, 0, 0, time.UTC)).TimestampNamed("ts"),
|
||||||
S: "USING TIMESTAMP ? ",
|
S: "USING TIMESTAMP ? ",
|
||||||
N: []string{"ts"},
|
N: []string{"ts"},
|
||||||
},
|
},
|
||||||
// TimestampNamed Timestamp
|
// TimestampNamed Timestamp
|
||||||
{
|
{
|
||||||
B: new(using).TimestampNamed("ts").Timestamp(time.Date(2005, 05, 05, 0, 0, 0, 0, time.UTC)),
|
B: new(using).TimestampNamed("ts").Timestamp(time.Date(2005, 5, 5, 0, 0, 0, 0, time.UTC)),
|
||||||
S: "USING TIMESTAMP 1115251200000000 ",
|
S: "USING TIMESTAMP 1115251200000000 ",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
11
queryx.go
11
queryx.go
@@ -90,12 +90,11 @@ func allowedBindRune(b byte) bool {
|
|||||||
|
|
||||||
// Queryx is a wrapper around gocql.Query which adds struct binding capabilities.
|
// Queryx is a wrapper around gocql.Query which adds struct binding capabilities.
|
||||||
type Queryx struct {
|
type Queryx struct {
|
||||||
*gocql.Query
|
err error
|
||||||
Names []string
|
tr Transformer
|
||||||
Mapper *reflectx.Mapper
|
Mapper *reflectx.Mapper
|
||||||
|
*gocql.Query
|
||||||
tr Transformer
|
Names []string
|
||||||
err error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Query creates a new Queryx from gocql.Query using a default mapper.
|
// Query creates a new Queryx from gocql.Query using a default mapper.
|
||||||
@@ -151,7 +150,7 @@ func (q *Queryx) bindStructArgs(arg0 interface{}, arg1 map[string]interface{}) (
|
|||||||
|
|
||||||
// grab the indirected value of arg
|
// grab the indirected value of arg
|
||||||
v := reflect.ValueOf(arg0)
|
v := reflect.ValueOf(arg0)
|
||||||
for v = reflect.ValueOf(arg0); v.Kind() == reflect.Ptr; {
|
for v.Kind() == reflect.Ptr {
|
||||||
v = v.Elem()
|
v = v.Elem()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,8 @@ func NewSession(session *gocql.Session) Session {
|
|||||||
// the created session to gocqlx.Session.
|
// the created session to gocqlx.Session.
|
||||||
//
|
//
|
||||||
// Example:
|
// Example:
|
||||||
// session, err := gocqlx.WrapSession(cluster.CreateSession())
|
//
|
||||||
|
// session, err := gocqlx.WrapSession(cluster.CreateSession())
|
||||||
func WrapSession(session *gocql.Session, err error) (Session, error) {
|
func WrapSession(session *gocql.Session, err error) (Session, error) {
|
||||||
return Session{
|
return Session{
|
||||||
Session: session,
|
Session: session,
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
|
|
||||||
"github.com/scylladb/gocqlx/v2/qb"
|
"github.com/scylladb/gocqlx/v2/qb"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user