mirror of
https://github.com/VinGarcia/ksql.git
synced 2025-09-04 19:36:56 +00:00
Compare commits
193 Commits
adapters/k
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
a06a19aa97 | ||
|
dadb4199ee | ||
|
112b70414f | ||
|
4a767c28f6 | ||
|
66d563fbed | ||
|
58219f85fe | ||
|
ced2b49252 | ||
|
67eaef9a13 | ||
|
e9865d66df | ||
|
f1c6f32051 | ||
|
24b9313323 | ||
|
688344f710 | ||
|
0a95b40908 | ||
|
d84d079b99 | ||
|
3f0e9b9a3e | ||
|
661630db8d | ||
|
d5ddb163ee | ||
|
be21a80750 | ||
|
31dfbeca3f | ||
|
4352f659c1 | ||
|
658d47173a | ||
|
4b5464c1de | ||
|
dcee1a01a4 | ||
|
81026c8aac | ||
|
bb48d77d81 | ||
|
14b1ba47d3 | ||
|
64ddb22a00 | ||
|
0a313c19a4 | ||
|
13542463ba | ||
|
e67ef737e7 | ||
|
fd2459e4de | ||
|
a3523821a1 | ||
|
6356f35a7c | ||
|
9f12a3691f | ||
|
9b08319441 | ||
|
f25b9b75d0 | ||
|
2c01567fbe | ||
|
b5fcd7fa86 | ||
|
fb8e8141d4 | ||
|
9a006cd25c | ||
|
c2e1138806 | ||
|
06fe81e064 | ||
|
d933794459 | ||
|
2b1dd6db3d | ||
|
32f8e680c5 | ||
|
35b6882317 | ||
|
860b1cc9a0 | ||
|
cf25954f0b | ||
|
758f81e3fb | ||
|
a20099519f | ||
|
d06de92a12 | ||
|
8ead71532e | ||
|
6d74c98eac | ||
|
10dc044002 | ||
|
2446ddc984 | ||
|
7c33cc8d2d | ||
|
bae3ba2902 | ||
|
e070ebd039 | ||
|
7ba6537ed9 | ||
|
edaf3af2d2 | ||
|
9a065de4a5 | ||
|
8d57a16f9c | ||
|
7edbd04ceb | ||
|
8198548deb | ||
|
ecd2ea45aa | ||
|
22a26aeb18 | ||
|
077033b3ff | ||
|
fca1450031 | ||
|
4fbfe36dcd | ||
|
fc0c52e608 | ||
|
c97a3a6996 | ||
|
a42c454387 | ||
|
c37835ef44 | ||
|
e6b5eced70 | ||
|
a5444ff198 | ||
|
70fcedb8eb | ||
|
5513a0c68d | ||
|
08247e5b82 | ||
|
d65216479a | ||
|
186c11b2cd | ||
|
c55ba119a3 | ||
|
324933fff9 | ||
|
ac97982e65 | ||
|
c810da865e | ||
|
e9cf2c5f32 | ||
|
fae106916c | ||
|
9311b4a17d | ||
|
a9487aae55 | ||
|
78976c1f42 | ||
|
a015743b72 | ||
|
5c5885d1a3 | ||
|
0362d5ace0 | ||
|
482f979db7 | ||
|
e312b134fb | ||
|
ec1f5f6151 | ||
|
94d41d437e | ||
|
1a73a49a4a | ||
|
dbc106eef2 | ||
|
1ee2768edb | ||
|
8f45498f58 | ||
|
84b4b86383 | ||
|
e8df0d0c27 | ||
|
ce5c0f2890 | ||
|
c676e8f799 | ||
|
deec35c2b5 | ||
|
f183327eec | ||
|
ddd9a4dec5 | ||
|
9efa78a619 | ||
|
24599e6644 | ||
|
0f2ce0a685 | ||
|
475955bb33 | ||
|
749466d29a | ||
|
9f2ffa84f6 | ||
|
6ff67201c9 | ||
|
226b906746 | ||
|
743d021f7a | ||
|
1a1f198803 | ||
|
88167361c1 | ||
|
4598800f87 | ||
|
211fddf4ee | ||
|
259b3a228a | ||
|
37b26debeb | ||
|
53ae836dc2 | ||
|
8f24194630 | ||
|
d8fa0557e9 | ||
|
d6aa694f82 | ||
|
e7896dc16e | ||
|
340a320281 | ||
|
83cf354f35 | ||
|
f4cac02602 | ||
|
13c6f3cbc6 | ||
|
aca042b94b | ||
|
af37427192 | ||
|
6c0f8ae6b1 | ||
|
c5043c9ff2 | ||
|
5bfb5cd92a | ||
|
d2c90f4e42 | ||
|
e519b3db27 | ||
|
b2e146d5e8 | ||
|
dd8a45c5d5 | ||
|
a7f12b34a5 | ||
|
4890563c27 | ||
|
ad516d5e1f | ||
|
136ee66fe9 | ||
|
e48f82c255 | ||
|
5a7fd93467 | ||
|
511abf659d | ||
|
f41edb427d | ||
|
0d73ac9a18 | ||
|
57c0f4cade | ||
|
ae76cd5768 | ||
|
8538d99468 | ||
|
60233e04a8 | ||
|
fc2b32d919 | ||
|
3a9971628a | ||
|
c46ad0f92c | ||
|
8cba3efa2d | ||
|
7661ba0314 | ||
|
3a0e9b6da3 | ||
|
9e94445cdc | ||
|
41f4d5487b | ||
|
cb15295e46 | ||
|
a5b33135d1 | ||
|
f95cd2b7b2 | ||
|
67ad75242a | ||
|
86dd623eac | ||
|
8620600d01 | ||
|
4b37adc905 | ||
|
74cb87bea0 | ||
|
0e95506343 | ||
|
56c1ed54da | ||
|
b08934f34e | ||
|
f155607beb | ||
|
96dc1a5c53 | ||
|
d73528bd8b | ||
|
45d8ef4491 | ||
|
25e77f3f36 | ||
|
a8dcbd1aaa | ||
|
06b8855621 | ||
|
b5f2deac02 | ||
|
eb1f85f8bb | ||
|
84d523967b | ||
|
c9a73d8ad1 | ||
|
9161634e7b | ||
|
b088ae0d26 | ||
|
3d34bae47e | ||
|
ed1e5ec27d | ||
|
33e0918c14 | ||
|
fc1b4d9a3b | ||
|
62a19e30ac | ||
|
12c774a26f | ||
|
b710dd7559 | ||
|
8fdd674c1b |
1
.github/FUNDING.yml
vendored
Normal file
1
.github/FUNDING.yml
vendored
Normal file
@ -0,0 +1 @@
|
||||
github: vingarcia
|
26
.github/workflows/ci.yml
vendored
26
.github/workflows/ci.yml
vendored
@ -1,12 +1,19 @@
|
||||
name: CI
|
||||
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
push: {}
|
||||
pull_request:
|
||||
types: [opened, reopened]
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '>=1.23'
|
||||
- name: Pull Postgres
|
||||
run: docker pull postgres:14.0
|
||||
- name: Pull MariaDB
|
||||
@ -17,12 +24,15 @@ jobs:
|
||||
run: go version
|
||||
- name: Run linters
|
||||
run: go vet ./... && go install honnef.co/go/tools/cmd/staticcheck@latest && bash -c "$(go env GOPATH)/bin/staticcheck ./..."
|
||||
- name: Run Tests
|
||||
- name: Run Tests Against current latest versions
|
||||
run: ./scripts/run-all-tests.sh
|
||||
- name: Run Coverage
|
||||
run: bash <(curl -s https://codecov.io/bash)
|
||||
env:
|
||||
CODECOV_TOKEN: 36be8ba6-7ef1-4ec2-b607-67c1055a62ad
|
||||
|
||||
- name: Run Tests Against current branch
|
||||
run: |
|
||||
cp go.work.example go.work
|
||||
./scripts/run-all-tests.sh
|
||||
- name: Upload results to Codecov
|
||||
uses: codecov/codecov-action@v5
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
|
||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,3 +1,5 @@
|
||||
.make.setup
|
||||
**/*coverage.txt
|
||||
**/coverage.txt
|
||||
go.work
|
||||
go.work.sum
|
||||
benchmark.tmp
|
||||
|
66
Makefile
66
Makefile
@ -3,44 +3,70 @@ path=./...
|
||||
|
||||
GOBIN=$(shell go env GOPATH)/bin
|
||||
|
||||
TIME=1s
|
||||
TIME=5s
|
||||
|
||||
# If your tests are timing out you probably need to run
|
||||
# the recipe below once just so all images are cached:
|
||||
pre-download-all-images:
|
||||
docker pull postgres:14.0
|
||||
docker pull mcr.microsoft.com/mssql/server:2022-latest
|
||||
docker pull mariadb:10.8
|
||||
|
||||
test: setup go-mod-tidy
|
||||
$(GOBIN)/richgo test $(path) $(args)
|
||||
@( cd benchmarks ; $(GOBIN)/richgo test $(path) $(args) )
|
||||
@( cd examples ; $(GOBIN)/richgo test $(path) $(args) )
|
||||
@( cd adapters/kpgx ; $(GOBIN)/richgo test $(path) $(args) )
|
||||
@( cd adapters/kmysql ; $(GOBIN)/richgo test $(path) $(args) )
|
||||
@( cd adapters/ksqlserver ; $(GOBIN)/richgo test $(path) $(args) )
|
||||
@( cd adapters/ksqlite3 ; $(GOBIN)/richgo test $(path) $(args) )
|
||||
@( cd adapters/kpgx ; $(GOBIN)/richgo test $(path) $(args) -timeout=60s )
|
||||
@( cd adapters/kpgx5 ; $(GOBIN)/richgo test $(path) $(args) -timeout=60s )
|
||||
@( cd adapters/kmysql ; $(GOBIN)/richgo test $(path) $(args) -timeout=60s )
|
||||
@( cd adapters/kpostgres ; $(GOBIN)/richgo test $(path) $(args) -timeout=60s )
|
||||
@( cd adapters/ksqlserver ; $(GOBIN)/richgo test $(path) $(args) -timeout=60s )
|
||||
@( cd adapters/ksqlite3 ; $(GOBIN)/richgo test $(path) $(args) -timeout=60s )
|
||||
@( cd adapters/modernc-ksqlite ; $(GOBIN)/richgo test $(path) $(args) -timeout=60s )
|
||||
|
||||
benchmark.tmp: bench
|
||||
bench: go-mod-tidy
|
||||
cd benchmarks && go test -bench=. -benchtime=$(TIME)
|
||||
@echo "Benchmark executed at: $$(date --iso)"
|
||||
@echo "Benchmark executed on commit: $$(git rev-parse HEAD)"
|
||||
@make --no-print-directory -C benchmarks TIME=$(TIME) | tee benchmark.tmp
|
||||
@echo "Benchmark executed at: $$(date --iso)" | tee -a benchmark.tmp
|
||||
@echo "Benchmark executed on commit: $$(git rev-parse HEAD)" | tee -a benchmark.tmp
|
||||
|
||||
readme: benchmark.tmp readme.template.md
|
||||
go run scripts/build-readme-from-template.go readme.template.md
|
||||
|
||||
lint: setup go-mod-tidy
|
||||
@$(GOBIN)/staticcheck $(path) $(args)
|
||||
@go vet $(path) $(args)
|
||||
@make --no-print-directory -C benchmarks
|
||||
@make --no-print-directory -C benchmarks lint
|
||||
@echo "StaticCheck & Go Vet found no problems on your code!"
|
||||
|
||||
# Run go mod tidy for all submodules:
|
||||
tidy: go-mod-tidy
|
||||
go-mod-tidy:
|
||||
find . -name go.mod -execdir go mod tidy \;
|
||||
|
||||
# Update adapters to use a new ksql tag
|
||||
version=
|
||||
# Create new tag and update adapters to use a new ksql tag:
|
||||
version=v1.12.3
|
||||
update:
|
||||
git tag $(version)
|
||||
git push origin master $(version)
|
||||
find adapters -name go.mod -execdir go get github.com/vingarcia/ksql@$(version) \;
|
||||
(cd examples; go get github.com/vingarcia/ksql@$(version))
|
||||
(cd benchmarks; go get github.com/vingarcia/ksql@$(version))
|
||||
make go-mod-tidy
|
||||
git commit -am 'Update adapters to use version $(version)'
|
||||
git push origin master
|
||||
for dir in $$(ls adapters); do git tag adapters/$$dir/$(version); done
|
||||
for dir in $$(ls adapters); do git push origin master adapters/$$dir/$(version); done
|
||||
for dir in $$(ls adapters); do git push origin adapters/$$dir/$(version); done
|
||||
|
||||
gen: mock
|
||||
mock: setup
|
||||
$(GOBIN)/mockgen -package=exampleservice -source=contracts.go -destination=examples/example_service/mocks.go
|
||||
|
||||
setup: $(GOBIN)/richgo $(GOBIN)/staticcheck $(GOBIN)/mockgen
|
||||
setup: $(GOBIN)/richgo $(GOBIN)/staticcheck $(GOBIN)/mockgen go.work
|
||||
|
||||
go.work:
|
||||
go work init
|
||||
go work use -r .
|
||||
|
||||
$(GOBIN)/richgo:
|
||||
go install github.com/kyoh86/richgo@latest
|
||||
@ -53,5 +79,15 @@ $(GOBIN)/mockgen:
|
||||
go install github.com/golang/mock/mockgen@latest
|
||||
|
||||
# Running examples:
|
||||
exampleservice: mock
|
||||
$(GOPATH)/bin/richgo test ./examples/example_service/...
|
||||
example_service: mock
|
||||
$(GOBIN)/richgo test ./examples/example_service/.
|
||||
|
||||
example_logger: mock
|
||||
go run ./examples/logging_queries/.
|
||||
|
||||
example_overview: mock
|
||||
go run ./examples/overview/.
|
||||
|
||||
PG_URL=
|
||||
pgxsupport:
|
||||
go run ./examples/pgxsupport/.
|
||||
|
371
README.md
371
README.md
@ -1,35 +1,56 @@
|
||||
|
||||
[](https://github.com/VinGarcia/ksql/actions/workflows/ci.yml)
|
||||
[](https://codecov.io/gh/VinGarcia/ksql)
|
||||
[](https://pkg.go.dev/github.com/vingarcia/ksql)
|
||||

|
||||
|
||||
# KSQL the Keep it Simple SQL library
|
||||
|
||||
KSQL was created to offer an actually simple and satisfactory
|
||||
tool for interacting with SQL Databases in Golang.
|
||||
|
||||
The core idea on KSQL is to offer an easy to use interface,
|
||||
the actual comunication with the database is decoupled so we can use
|
||||
KSQL on top of `pgx`, `database/sql` and possibly other tools.
|
||||
You can even create you own backend adapter for KSQL which is
|
||||
The core goal of KSQL is not to offer new features that
|
||||
are unavailable on other libraries (although we do have some),
|
||||
but to offer a well-thought and well-planned API so that users
|
||||
have an easier time, learning, debugging, and avoiding common pitfalls.
|
||||
|
||||
KSQL is also decoupled from its backend so that
|
||||
the actual communication with the database is performed by
|
||||
well-known and trusted technologies, namely: `pgx` and `database/sql`.
|
||||
You can even create your own backend adapter for KSQL which is
|
||||
useful in some situations.
|
||||
|
||||
In this README you will find examples for "Getting Started" with the library,
|
||||
for more advanced use-cases [please read our Wiki](https://github.com/VinGarcia/ksql/wiki).
|
||||
|
||||
## Outstanding Features
|
||||
|
||||
- Every operation returns errors a single time, so its easier to handle them
|
||||
- Helper functions for everyday operations, namely: Insert, Patch and Delete
|
||||
- Generic and powerful functions for Querying and Scanning data into structs
|
||||
- Works on top of existing battle-tested libraries such as `database/sql` and `pgx`
|
||||
- Supports `sql.Scanner` and `sql.Valuer` and also all `pgx` special types (when using `kpgx`)
|
||||
- And many other features designed to make your life easier
|
||||
|
||||
## Open to Work
|
||||
|
||||
Hi! I'm currently looking for new opportunities as a Senior Software or Platform Engineer—preferably working with Golang, backend systems, or open-source infrastructure. If you're hiring or know someone who is, feel free to reach out: vingarcia00@gmail.com or on [LinkedIn](https://www.linkedin.com/in/vingarcia00/).
|
||||
|
||||
## Let's start with some Code:
|
||||
|
||||
This short example below is a TLDR version for illustrating how easy it is to use KSQL.
|
||||
This short example below is a TLDR version to illustrate how easy it is to use KSQL.
|
||||
|
||||
You will find more complete examples on the sections below.
|
||||
You will find more complete examples in the sections below.
|
||||
|
||||
> This example is available on ./examples/overview/main.go if you want to run it
|
||||
|
||||
```golang
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/vingarcia/ksql"
|
||||
"github.com/vingarcia/ksql/adapters/kpgx"
|
||||
@ -38,14 +59,37 @@ import (
|
||||
var UsersTable = ksql.NewTable("users", "user_id")
|
||||
|
||||
type User struct {
|
||||
ID int `ksql:"user_id"`
|
||||
Name string `ksql:"name"`
|
||||
Type string `ksql:"type"`
|
||||
ID int `ksql:"user_id"`
|
||||
Name string `ksql:"name"`
|
||||
Type string `ksql:"type"`
|
||||
Posts []Post
|
||||
}
|
||||
|
||||
// Post have a many to one relationship with User
|
||||
var PostsTable = ksql.NewTable("posts", "post_id")
|
||||
|
||||
type Post struct {
|
||||
ID int `ksql:"post_id"`
|
||||
UserID int `ksql:"user_id"`
|
||||
Title string `ksql:"title"`
|
||||
Text string `ksql:"text"`
|
||||
}
|
||||
|
||||
// Address have a one to one relationship with User
|
||||
var AddressesTable = ksql.NewTable("addresses", "id")
|
||||
|
||||
type Address struct {
|
||||
ID int `ksql:"id"`
|
||||
UserID int `ksql:"user_id"`
|
||||
FullAddr string `ksql:"full_addr"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
ctx := context.Background()
|
||||
db, err := kpgx.New(ctx, os.Getenv("POSTGRES_URL"), ksql.Config{})
|
||||
dbURL, closeDB := startExampleDB(ctx)
|
||||
defer closeDB()
|
||||
|
||||
db, err := kpgx.New(ctx, dbURL, ksql.Config{})
|
||||
if err != nil {
|
||||
log.Fatalf("unable connect to database: %s", err)
|
||||
}
|
||||
@ -54,10 +98,10 @@ func main() {
|
||||
// For querying only some attributes you can
|
||||
// create a custom struct like this:
|
||||
var count []struct {
|
||||
Count string `ksql:"count"`
|
||||
Type string `ksql:"type"`
|
||||
Count int `ksql:"count"`
|
||||
Type string `ksql:"type"`
|
||||
}
|
||||
err = db.Query(ctx, &count, "SELECT type, count(*) as count FROM users WHERE type = $1 GROUP BY type", "admin")
|
||||
err = db.Query(ctx, &count, "SELECT type, count(*) as count FROM users GROUP BY type")
|
||||
if err != nil {
|
||||
log.Fatalf("unable to query users: %s", err)
|
||||
}
|
||||
@ -66,25 +110,98 @@ func main() {
|
||||
|
||||
// For loading entities from the database KSQL can build
|
||||
// the SELECT part of the query for you if you omit it like this:
|
||||
var users []User
|
||||
err = db.Query(ctx, &users, "FROM users WHERE type = $1", "admin")
|
||||
var adminUsers []User
|
||||
err = db.Query(ctx, &adminUsers, "FROM users WHERE type = $1", "admin")
|
||||
if err != nil {
|
||||
log.Fatalf("unable to query admin users: %s", err)
|
||||
}
|
||||
|
||||
fmt.Println("admin users:", adminUsers)
|
||||
|
||||
// A nice way of loading the posts of a user might be like this:
|
||||
var user User
|
||||
err = errors.Join(
|
||||
db.QueryOne(ctx, &user, "FROM users WHERE user_id = $1", 42),
|
||||
db.Query(ctx, &user.Posts, "FROM posts WHERE user_id = $1", user.ID),
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatalf("unable to query users: %s", err)
|
||||
}
|
||||
|
||||
fmt.Println("users:", users)
|
||||
fmt.Println("user with posts:", user)
|
||||
|
||||
// You can retrieve data from joined tables like this
|
||||
// (notice you can either use the name of the table or the alias you choose for it in the query):
|
||||
var rows []struct {
|
||||
OneUser User `tablename:"users"`
|
||||
OneAddress Address `tablename:"addr"`
|
||||
}
|
||||
err = db.Query(ctx, &rows,
|
||||
`FROM users
|
||||
JOIN addresses addr
|
||||
ON users.user_id = addr.user_id`,
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatalf("unable to query users: %s", err)
|
||||
}
|
||||
|
||||
fmt.Println("rows of joined tables:", rows)
|
||||
}
|
||||
```
|
||||
|
||||
We currently have 4 constructors available,
|
||||
one of them is illustrated above (`kpgx.New()`),
|
||||
the other ones have the exact same signature
|
||||
but work on different databases, they are:
|
||||
> Note: In the example above we are using the `$1`, `$2` and `$3` as placeholders on the query
|
||||
> because this example is meant to run on top of Postgres.
|
||||
>
|
||||
> If you are running on top of MySQL or SQLite use `?` instead, and if you are running
|
||||
> on top of SQLServer use `@p1`, `@p2` and `@p3` instead.
|
||||
|
||||
- `kpgx.New(ctx, os.Getenv("POSTGRES_URL"), ksql.Config{})` for Postgres, it works on top of `pgxpool`
|
||||
- `kmysql.New(ctx, os.Getenv("POSTGRES_URL"), ksql.Config{})` for MySQL, it works on top of `database/sql`
|
||||
- `ksqlserver.New(ctx, os.Getenv("POSTGRES_URL"), ksql.Config{})` for SQLServer, it works on top of `database/sql`
|
||||
- `ksqlite3.New(ctx, os.Getenv("POSTGRES_URL"), ksql.Config{})` for SQLite3, it works on top of `database/sql`
|
||||
## Supported Adapters:
|
||||
|
||||
We support a few different adapters,
|
||||
one of them is illustrated above (`kpgx`),
|
||||
the other ones have the exact same signature
|
||||
but work on different databases or driver versions,
|
||||
they are:
|
||||
|
||||
- `kpgx.New(ctx, os.Getenv("DATABASE_URL"), ksql.Config{})` for Postgres, it works on top of `pgxpool`
|
||||
and [pgx](https://github.com/jackc/pgx) version 4, download it with:
|
||||
|
||||
```bash
|
||||
go get github.com/vingarcia/ksql/adapters/kpgx
|
||||
```
|
||||
- `kpgx5.New(ctx, os.Getenv("DATABASE_URL"), ksql.Config{})` for Postgres, it works on top of `pgxpool`
|
||||
and [pgx](https://github.com/jackc/pgx) version 5, download it with:
|
||||
|
||||
```bash
|
||||
go get github.com/vingarcia/ksql/adapters/kpgx5
|
||||
```
|
||||
- `kmysql.New(ctx, os.Getenv("DATABASE_URL"), ksql.Config{})` for MySQL, it works on top of `database/sql`,
|
||||
download it with:
|
||||
|
||||
```bash
|
||||
go get github.com/vingarcia/ksql/adapters/kmysql
|
||||
```
|
||||
- `ksqlserver.New(ctx, os.Getenv("DATABASE_URL"), ksql.Config{})` for SQLServer, it works on top of `database/sql`,
|
||||
download it with:
|
||||
|
||||
```bash
|
||||
go get github.com/vingarcia/ksql/adapters/ksqlserver
|
||||
```
|
||||
- `ksqlite3.New(ctx, os.Getenv("DATBAASE_PATH"), ksql.Config{})` for SQLite3, it works on top of `database/sql`
|
||||
and [mattn/go-sqlite3](https://github.com/mattn/go-sqlite3) which relies on CGO, download it with:
|
||||
|
||||
```bash
|
||||
go get github.com/vingarcia/ksql/adapters/ksqlite3
|
||||
```
|
||||
- `ksqlite.New(ctx, os.Getenv("DATABASE_PATH"), ksql.Config{})` for SQLite, it works on top of `database/sql`
|
||||
and [modernc.org/sqlite](https://modernc.org/sqlite) which does not require CGO, download it with:
|
||||
|
||||
```bash
|
||||
go get github.com/vingarcia/ksql/adapters/modernc-ksqlite
|
||||
```
|
||||
|
||||
For more detailed examples see:
|
||||
- `./examples/all_adapters/all_adapters.go`
|
||||
|
||||
## The KSQL Interface
|
||||
|
||||
@ -94,7 +211,7 @@ and it is also used for making it easy to mock the whole library if needed.
|
||||
This interface is declared in the project as `ksql.Provider` and is displayed below.
|
||||
|
||||
We plan on keeping it very simple with a small number
|
||||
of well thought functions that cover all use-cases,
|
||||
of well-thought functions that cover all use cases,
|
||||
so don't expect many additions:
|
||||
|
||||
```go
|
||||
@ -111,14 +228,14 @@ type Provider interface {
|
||||
QueryOne(ctx context.Context, record interface{}, query string, params ...interface{}) error
|
||||
QueryChunks(ctx context.Context, parser ChunkParser) error
|
||||
|
||||
Exec(ctx context.Context, query string, params ...interface{}) (rowsAffected int64, _ error)
|
||||
Exec(ctx context.Context, query string, params ...interface{}) (Result, error)
|
||||
Transaction(ctx context.Context, fn func(Provider) error) error
|
||||
}
|
||||
```
|
||||
|
||||
## Using KSQL
|
||||
|
||||
In the example below we'll cover all the most common use-cases such as:
|
||||
In the example below we'll cover all the most common use cases such as:
|
||||
|
||||
1. Inserting records
|
||||
2. Updating records
|
||||
@ -133,7 +250,7 @@ More advanced use cases are illustrated on their own pages on [our Wiki](https:/
|
||||
- [Reusing Existing Structs on Queries with JOINs](https://github.com/VinGarcia/ksql/wiki/Reusing-Existing-Structs-on-Queries-with-JOINs)
|
||||
- [Testing Tools and `ksql.Mock`](https://github.com/VinGarcia/ksql/wiki/Testing-Tools-and-ksql.Mock)
|
||||
|
||||
For the more common use-cases please read the example below,
|
||||
For the more common use cases please read the example below,
|
||||
which is also available [here](./examples/crud/crud.go)
|
||||
if you want to compile it yourself.
|
||||
|
||||
@ -143,23 +260,35 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/vingarcia/ksql"
|
||||
"github.com/vingarcia/ksql/adapters/ksqlite3"
|
||||
"github.com/vingarcia/ksql/nullable"
|
||||
)
|
||||
|
||||
// User ...
|
||||
type User struct {
|
||||
ID int `ksql:"id"`
|
||||
Name string `ksql:"name"`
|
||||
Age int `ksql:"age"`
|
||||
|
||||
// This field will be saved as JSON in the database
|
||||
// The following attributes are making use of the KSQL Modifiers,
|
||||
// you can find more about them on our Wiki:
|
||||
//
|
||||
// - https://github.com/VinGarcia/ksql/wiki/Modifiers
|
||||
//
|
||||
|
||||
// The `json` modifier will save the address as JSON in the database
|
||||
Address Address `ksql:"address,json"`
|
||||
|
||||
// The timeNowUTC modifier will set this field to `time.Now().UTC()` before saving it:
|
||||
UpdatedAt time.Time `ksql:"updated_at,timeNowUTC"`
|
||||
|
||||
// The timeNowUTC/skipUpdates modifier will set this field to `time.Now().UTC()` only
|
||||
// when first creating it and ignore it during updates.
|
||||
CreatedAt time.Time `ksql:"created_at,timeNowUTC/skipUpdates"`
|
||||
}
|
||||
|
||||
// PartialUpdateUser ...
|
||||
type PartialUpdateUser struct {
|
||||
ID int `ksql:"id"`
|
||||
Name *string `ksql:"name"`
|
||||
@ -167,7 +296,6 @@ type PartialUpdateUser struct {
|
||||
Address *Address `ksql:"address,json"`
|
||||
}
|
||||
|
||||
// Address ...
|
||||
type Address struct {
|
||||
State string `json:"state"`
|
||||
City string `json:"city"`
|
||||
@ -180,15 +308,6 @@ var UsersTable = ksql.NewTable("users")
|
||||
func main() {
|
||||
ctx := context.Background()
|
||||
|
||||
// The available adapters are:
|
||||
// - kpgx.New(ctx, connURL, ksql.Config{})
|
||||
// - kmysql.New(ctx, connURL, ksql.Config{})
|
||||
// - ksqlserver.New(ctx, connURL, ksql.Config{})
|
||||
// - ksqlite3.New(ctx, connURL, ksql.Config{})
|
||||
//
|
||||
// For more detailed examples see:
|
||||
// - `./examples/all_adapters/all_adapters.go`
|
||||
//
|
||||
// In this example we'll use sqlite3:
|
||||
db, err := ksqlite3.New(ctx, "/tmp/hello.sqlite", ksql.Config{
|
||||
MaxOpenConns: 1,
|
||||
@ -204,7 +323,9 @@ func main() {
|
||||
id INTEGER PRIMARY KEY,
|
||||
age INTEGER,
|
||||
name TEXT,
|
||||
address BLOB
|
||||
address BLOB,
|
||||
created_at DATETIME,
|
||||
updated_at DATETIME
|
||||
)`)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
@ -289,6 +410,8 @@ func main() {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
fmt.Printf("Users: %#v\n", users)
|
||||
|
||||
// Making transactions:
|
||||
err = db.Transaction(ctx, func(db ksql.Provider) error {
|
||||
var cris2 User
|
||||
@ -304,7 +427,7 @@ func main() {
|
||||
})
|
||||
if err != nil {
|
||||
// This will also cause an automatic rollback and then panic again
|
||||
// so that we don't hide the panic inside the KissSQL library
|
||||
// so that we don't hide the panic inside the KSQL library
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
@ -314,16 +437,49 @@ func main() {
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
fmt.Printf("Users: %#v\n", users)
|
||||
}
|
||||
```
|
||||
|
||||
## Benchmark Comparison
|
||||
|
||||
The results of the benchmark are good:
|
||||
they show that KSQL is in practical terms,
|
||||
as fast as sqlx which was our goal from the start.
|
||||
The results of the benchmark are good for KSQL, but not flawless.
|
||||
|
||||
The next section summarizes the results so its more comprehensible,
|
||||
but if you prefer to read the raw benchmark data just scroll down to the
|
||||
[Benchmark Results](https://github.com/VinGarcia/ksql#benchmark-results) section.
|
||||
|
||||
### Summary
|
||||
|
||||
For transparency purposes this summary will focus
|
||||
at the benchmark showing the _worst_ results for KSQL
|
||||
which is querying multiple lines, this is the summary:
|
||||
|
||||
Comparing KSQL running on top of `database/sql` with `sqlx`, `sqlx` is
|
||||
5% faster than KSQL, which is in practical terms an insignificant difference.
|
||||
And if KSQL is running on top of `pgx` then KSQL becomes 42% faster
|
||||
because `pgx` is significantly faster than `sqlx`.
|
||||
Finally if you are using `sqlx` with prepared statements everytime
|
||||
then `sqlx` is 7.5% faster than KSQL on top of `pgx`.
|
||||
|
||||
So between KSQL vs `sqlx` the performance difference is very small, and
|
||||
if you are using Postgres odds are KSQL will be much faster.
|
||||
|
||||
Comparing KSQL running on top of `pgx` with `pgx` itself, KSQL
|
||||
is 13.66% slower (on average), which is not insignificant but isn't much either.
|
||||
|
||||
Comparing KSQL running on top `pgx` with `gorm`, KSQL is
|
||||
11.87% faster than `gorm` or inversely `gorm` is 13.4% slower.
|
||||
|
||||
> It is worth noting that KSQL is only caching of prepared statements
|
||||
> when using postgres, because this is performed by `pgx`, and this
|
||||
> means that when using MySQL, SQLServer or SQLite, if you plan
|
||||
> on also using prepared statements other libaries such as `sqlx` will
|
||||
> be significantly faster than KSQL.
|
||||
>
|
||||
> We are working on adding support for cached prepared statements for
|
||||
> these other databases in the future.
|
||||
|
||||
### Benchmark Results
|
||||
|
||||
To understand the benchmark below you must know
|
||||
that all tests are performed using Postgres 12.1 and
|
||||
@ -335,18 +491,20 @@ that we are comparing the following tools:
|
||||
- `sqlx`
|
||||
- `pgx` (with `pgxpool`)
|
||||
- `gorm`
|
||||
- `sqlc`
|
||||
- `sqlboiler`
|
||||
|
||||
For each of these tools we are running 3 different queries:
|
||||
For each of these tools, we are running 3 different queries:
|
||||
|
||||
The `insert-one` query looks like:
|
||||
The `insert-one` query looks like this:
|
||||
|
||||
`INSERT INTO users (name, age) VALUES ($1, $2) RETURNING id`
|
||||
|
||||
The `single-row` query looks like:
|
||||
The `single-row` query looks like this:
|
||||
|
||||
`SELECT id, name, age FROM users OFFSET $1 LIMIT 1`
|
||||
|
||||
The `multiple-rows` query looks like:
|
||||
The `multiple-rows` query looks like this:
|
||||
|
||||
`SELECT id, name, age FROM users OFFSET $1 LIMIT 10`
|
||||
|
||||
@ -358,36 +516,49 @@ Without further ado, here are the results:
|
||||
|
||||
```bash
|
||||
$ make bench TIME=5s
|
||||
cd benchmarks && go test -bench=. -benchtime=5s
|
||||
sqlc generate
|
||||
go test -bench=. -benchtime=5s
|
||||
goos: linux
|
||||
goarch: amd64
|
||||
pkg: github.com/vingarcia/ksql/benchmarks
|
||||
cpu: Intel(R) Core(TM) i7-10750H CPU @ 2.60GHz
|
||||
BenchmarkInsert/ksql/sql-adapter/insert-one-12 9181 630987 ns/op
|
||||
BenchmarkInsert/ksql/pgx-adapter/insert-one-12 10000 554494 ns/op
|
||||
BenchmarkInsert/sql/insert-one-12 9130 628353 ns/op
|
||||
BenchmarkInsert/sql/prep-statements/insert-one-12 10000 555724 ns/op
|
||||
BenchmarkInsert/sqlx/insert-one-12 9346 630891 ns/op
|
||||
BenchmarkInsert/pgxpool/insert-one-12 10000 558666 ns/op
|
||||
BenchmarkInsert/gorm/insert-one-12 8822 670264 ns/op
|
||||
BenchmarkQuery/ksql/sql-adapter/single-row-12 41002 142869 ns/op
|
||||
BenchmarkQuery/ksql/sql-adapter/multiple-rows-12 38989 154036 ns/op
|
||||
BenchmarkQuery/ksql/pgx-adapter/single-row-12 95594 65885 ns/op
|
||||
BenchmarkQuery/ksql/pgx-adapter/multiple-rows-12 74559 78792 ns/op
|
||||
BenchmarkQuery/sql/single-row-12 42746 139622 ns/op
|
||||
BenchmarkQuery/sql/multiple-rows-12 41036 144600 ns/op
|
||||
BenchmarkQuery/sql/prep-statements/single-row-12 95922 64532 ns/op
|
||||
BenchmarkQuery/sql/prep-statements/multiple-rows-12 84481 71378 ns/op
|
||||
BenchmarkQuery/sqlx/single-row-12 42567 142479 ns/op
|
||||
BenchmarkQuery/sqlx/multiple-rows-12 40503 146865 ns/op
|
||||
BenchmarkQuery/pgxpool/single-row-12 91155 63803 ns/op
|
||||
BenchmarkQuery/pgxpool/multiple-rows-12 82599 69758 ns/op
|
||||
BenchmarkQuery/gorm/single-row-12 85747 69912 ns/op
|
||||
BenchmarkQuery/gorm/multiple-rows-12 67530 87910 ns/op
|
||||
BenchmarkInsert/ksql/sql-adapter/insert-one-12 9711 618727 ns/op
|
||||
BenchmarkInsert/ksql/pgx-adapter/insert-one-12 10000 555967 ns/op
|
||||
BenchmarkInsert/sql/insert-one-12 9450 624334 ns/op
|
||||
BenchmarkInsert/sql/prep-stmt/insert-one-12 10000 555119 ns/op
|
||||
BenchmarkInsert/sqlx/insert-one-12 9552 632986 ns/op
|
||||
BenchmarkInsert/sqlx/prep-stmt/insert-one-12 10000 560244 ns/op
|
||||
BenchmarkInsert/pgxpool/insert-one-12 10000 553535 ns/op
|
||||
BenchmarkInsert/gorm/insert-one-12 9231 668423 ns/op
|
||||
BenchmarkInsert/sqlc/insert-one-12 9589 632277 ns/op
|
||||
BenchmarkInsert/sqlc/prep-stmt/insert-one-12 10803 560301 ns/op
|
||||
BenchmarkInsert/sqlboiler/insert-one-12 9790 631464 ns/op
|
||||
BenchmarkQuery/ksql/sql-adapter/single-row-12 44436 131191 ns/op
|
||||
BenchmarkQuery/ksql/sql-adapter/multiple-rows-12 42087 143795 ns/op
|
||||
BenchmarkQuery/ksql/pgx-adapter/single-row-12 86192 65447 ns/op
|
||||
BenchmarkQuery/ksql/pgx-adapter/multiple-rows-12 74106 79004 ns/op
|
||||
BenchmarkQuery/sql/single-row-12 44719 134491 ns/op
|
||||
BenchmarkQuery/sql/multiple-rows-12 43218 138309 ns/op
|
||||
BenchmarkQuery/sql/prep-stmt/single-row-12 89328 64162 ns/op
|
||||
BenchmarkQuery/sql/prep-stmt/multiple-rows-12 84282 71454 ns/op
|
||||
BenchmarkQuery/sqlx/single-row-12 44118 132928 ns/op
|
||||
BenchmarkQuery/sqlx/multiple-rows-12 43824 137235 ns/op
|
||||
BenchmarkQuery/sqlx/prep-stmt/single-row-12 87570 66610 ns/op
|
||||
BenchmarkQuery/sqlx/prep-stmt/multiple-rows-12 82202 72660 ns/op
|
||||
BenchmarkQuery/pgxpool/single-row-12 94034 63373 ns/op
|
||||
BenchmarkQuery/pgxpool/multiple-rows-12 86275 70275 ns/op
|
||||
BenchmarkQuery/gorm/single-row-12 83052 71539 ns/op
|
||||
BenchmarkQuery/gorm/multiple-rows-12 62636 89652 ns/op
|
||||
BenchmarkQuery/sqlc/single-row-12 44329 132659 ns/op
|
||||
BenchmarkQuery/sqlc/multiple-rows-12 44440 139026 ns/op
|
||||
BenchmarkQuery/sqlc/prep-stmt/single-row-12 91486 66679 ns/op
|
||||
BenchmarkQuery/sqlc/prep-stmt/multiple-rows-12 78583 72583 ns/op
|
||||
BenchmarkQuery/sqlboiler/single-row-12 70030 87089 ns/op
|
||||
BenchmarkQuery/sqlboiler/multiple-rows-12 69961 84376 ns/op
|
||||
PASS
|
||||
ok github.com/vingarcia/ksql/benchmarks 139.589s
|
||||
Benchmark executed at: 2022-07-04
|
||||
Benchmark executed on commit: 589ad0a6934a7d4c2d89796203e55e76f5466d75
|
||||
ok github.com/vingarcia/ksql/benchmarks 221.596s
|
||||
Benchmark executed at: 2023-10-22
|
||||
Benchmark executed on commit: 35b6882317e82de7773fb3908332e8ac3d127010
|
||||
```
|
||||
|
||||
## Running the KSQL tests (for contributors)
|
||||
@ -403,43 +574,37 @@ which means that:
|
||||
$ sudo usermod <your_username> -aG docker
|
||||
```
|
||||
And then restart your login session (or just reboot)
|
||||
- Finally run `make pre-download-all-images` only once so your tests don't
|
||||
timeout downloading the database images.
|
||||
|
||||
After that you can just run the tests by using:
|
||||
After that, you can just run the tests by using:
|
||||
|
||||
```bash
|
||||
make test
|
||||
```
|
||||
|
||||
But it is recommended to first download the required images using:
|
||||
|
||||
```bash
|
||||
docker pull postgres:14.0
|
||||
docker pull mysql:8.0.27
|
||||
docker pull mcr.microsoft.com/mssql/server:2017-latest
|
||||
```
|
||||
|
||||
Otherwise the first attempt to run the tests will
|
||||
spend a long time downloading these images
|
||||
and then fail because the `TestMain()` function
|
||||
is configured to kill the containers after 20 seconds.
|
||||
|
||||
## TODO List
|
||||
|
||||
- Add support for serializing structs as other formats such as YAML
|
||||
- Add an `Upsert` helper method
|
||||
- Try to implement an automatic prepared statements cache like pgx does.
|
||||
- Update `ksqltest.FillStructWith` to work with `ksql:"..,json"` tagged attributes
|
||||
- Create a way for users to submit user defined dialects
|
||||
- Improve error messages (ongoing)
|
||||
- Add support for the Patch function to work with maps for partial updates
|
||||
- Add support for the Insert function to work with maps
|
||||
- Add support for a `ksql.Array(params ...interface{})` for allowing queries like this:
|
||||
`db.Query(ctx, &user, "SELECT * FROM user WHERE id in (?)", ksql.Array(1,2,3))`
|
||||
- Improve docs about `ksql.Mock`
|
||||
- Finish the `kbuilder` package
|
||||
|
||||
## Optimization Oportunities
|
||||
## Optimization Opportunities
|
||||
|
||||
- Test if using a pointer on the field info is faster or not
|
||||
- Consider passing the cached structInfo as argument for all the functions that use it,
|
||||
- Consider passing the cached structInfo as an argument for all the functions that use it,
|
||||
so that we don't need to get it more than once in the same call.
|
||||
- Use a cache to store often used queries (like pgx)
|
||||
- Use a cache to store often-used queries (like pgx)
|
||||
- Preload the insert method for all dialects inside `ksql.NewTable()`
|
||||
- Use prepared statements for the helper functions, `Update`, `Insert` and `Delete`.
|
||||
|
||||
## Features for a possible V2
|
||||
|
||||
- Change the `.Transaction(db ksql.Provider)` to a `.Transaction(ctx context.Context)`
|
||||
- Make the `.Query()` method to return a `type Query interface { One(); All(); Chunks(); }`
|
||||
- Have an `Update()` method that updates without ignoring NULLs as `Patch()` does
|
||||
- Have a new Modifier `skipNullUpdates` so that the Update function will do the job of the `Patch`
|
||||
- Remove the `Patch` function.
|
||||
- Rename `NewTable()` to just `Table()` so it feels right to declare it inline when convenient
|
||||
|
@ -4,19 +4,9 @@ go 1.14
|
||||
|
||||
require (
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
github.com/Microsoft/go-winio v0.5.2 // indirect
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
|
||||
github.com/containerd/continuity v0.2.2 // indirect
|
||||
github.com/docker/go-connections v0.4.0 // indirect
|
||||
github.com/go-sql-driver/mysql v1.6.0
|
||||
github.com/gotestyourself/gotestyourself v2.2.0+incompatible // indirect
|
||||
github.com/google/go-cmp v0.5.6 // indirect
|
||||
github.com/lib/pq v1.10.4 // indirect
|
||||
github.com/opencontainers/image-spec v1.0.2 // indirect
|
||||
github.com/opencontainers/runc v1.1.0 // indirect
|
||||
github.com/ory/dockertest v3.3.5+incompatible
|
||||
github.com/vingarcia/ksql v1.4.7
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect
|
||||
golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86 // indirect
|
||||
gotest.tools v2.2.0+incompatible // indirect
|
||||
github.com/ory/dockertest/v3 v3.10.0
|
||||
github.com/vingarcia/ksql v1.12.3
|
||||
)
|
||||
|
@ -1,227 +1,208 @@
|
||||
bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512/go.mod h1:FbcW6z/2VytnFDhZfumh8Ss8zxHE6qpMP5sHTRe0EaM=
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||
github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
|
||||
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
||||
github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
|
||||
github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4=
|
||||
github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E=
|
||||
github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
|
||||
github.com/containerd/continuity v0.2.2 h1:QSqfxcn8c+12slxwu00AtzXrsami0MJb/MQs9lOLHLA=
|
||||
github.com/containerd/continuity v0.2.2/go.mod h1:pWygW9u7LtS1o4N/Tn0FoCFDIXZ7rxcMX7HX1Dmibvk=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg=
|
||||
github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM=
|
||||
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
|
||||
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
||||
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/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/docker/cli v20.10.17+incompatible h1:eO2KS7ZFeov5UJeaDmIs1NFEDRf32PaqRpvoEkKBy5M=
|
||||
github.com/docker/cli v20.10.17+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/docker v20.10.7+incompatible h1:Z6O9Nhsjv+ayUEeI1IojKbYcsGdgYSNqxe1s2MYzUhQ=
|
||||
github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
|
||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
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.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gotestyourself/gotestyourself v2.2.0+incompatible h1:AQwinXlbQR2HvPjQZOmDhRqsv5mZf+Jb1RnSLxcqZcI=
|
||||
github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
||||
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk=
|
||||
github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
|
||||
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
|
||||
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 h1:rzf0wL0CHVc8CEsgyygG0Mn9CNCCPZqOPaz8RiiHYQk=
|
||||
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc=
|
||||
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
|
||||
github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/opencontainers/runc v1.1.0 h1:O9+X96OcDjkmmZyfaG996kV7yq8HsoU2h1XRRQcefG8=
|
||||
github.com/opencontainers/runc v1.1.0/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc=
|
||||
github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs=
|
||||
github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg=
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
|
||||
github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA=
|
||||
github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/ory/dockertest/v3 v3.10.0 h1:4K3z2VMe8Woe++invjaTB7VRyQXQy5UY+loujO4aNE4=
|
||||
github.com/ory/dockertest/v3 v3.10.0/go.mod h1:nr57ZbRWMqfsdGdFNLHz5jjNdDb7VVFnzAeW1n5N1Lg=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
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/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
|
||||
github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/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/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
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.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/vingarcia/ksql v1.4.7 h1:Gt9uz5ScL/lJxVa9DlA+4QaUWAOaSz1ZjUJDn8neLAI=
|
||||
github.com/vingarcia/ksql v1.4.7/go.mod h1:EVxEK3x6igVSFLDLLaymc25soqn3fSsZ0hrAryKtfCg=
|
||||
github.com/vingarcia/ksql v1.12.3 h1:1LVRGW39XPaYltPHNQsvHms+bWHp8e99sxQx+aEXDMQ=
|
||||
github.com/vingarcia/ksql v1.12.3/go.mod h1:DHp/nhVu1nHpBBXH/FRw6JLgIcvcM3+uo2+PfUNdo0g=
|
||||
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
|
||||
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86 h1:A9i04dxx7Cribqbs8jf3FQLogkL/CV2YN7hj9KWJCkc=
|
||||
golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220405210540-1e041c57c461/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
|
||||
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||
gotest.tools/v3 v3.3.0 h1:MfDY1b1/0xN1CyMlQDac0ziEy9zJQd9CXBRRDHw2jJo=
|
||||
gotest.tools/v3 v3.3.0/go.mod h1:Mcr9QNxkg0uMvy/YElmo4SpXgJKWgQvYrT7Kw5RzJ1A=
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"database/sql"
|
||||
|
||||
"github.com/vingarcia/ksql"
|
||||
"github.com/vingarcia/ksql/sqldialect"
|
||||
|
||||
// This is imported here so the user don't
|
||||
// have to worry about it when he uses it.
|
||||
@ -13,10 +14,10 @@ import (
|
||||
|
||||
// NewFromSQLDB builds a ksql.DB from a *sql.DB instance
|
||||
func NewFromSQLDB(db *sql.DB) (ksql.DB, error) {
|
||||
return ksql.NewWithAdapter(NewSQLAdapter(db), "mysql")
|
||||
return ksql.NewWithAdapter(NewSQLAdapter(db), sqldialect.MysqlDialect{})
|
||||
}
|
||||
|
||||
// New instantiates a new KissSQL client using the "mysql" driver
|
||||
// New instantiates a new KSQL client using the "mysql" driver
|
||||
func New(
|
||||
_ context.Context,
|
||||
connectionString string,
|
||||
@ -34,5 +35,5 @@ func New(
|
||||
|
||||
db.SetMaxOpenConns(config.MaxOpenConns)
|
||||
|
||||
return ksql.NewWithAdapter(NewSQLAdapter(db), "mysql")
|
||||
return ksql.NewWithAdapter(NewSQLAdapter(db), sqldialect.MysqlDialect{})
|
||||
}
|
||||
|
@ -8,16 +8,17 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ory/dockertest"
|
||||
"github.com/ory/dockertest/docker"
|
||||
"github.com/ory/dockertest/v3"
|
||||
"github.com/ory/dockertest/v3/docker"
|
||||
"github.com/vingarcia/ksql"
|
||||
"github.com/vingarcia/ksql/sqldialect"
|
||||
)
|
||||
|
||||
func TestAdapter(t *testing.T) {
|
||||
mysqlURL, closeMySQL := startMySQLDB("ksql")
|
||||
defer closeMySQL()
|
||||
|
||||
ksql.RunTestsForAdapter(t, "kmysql", "mysql", mysqlURL, func(t *testing.T) (ksql.DBAdapter, io.Closer) {
|
||||
ksql.RunTestsForAdapter(t, "kmysql", sqldialect.MysqlDialect{}, mysqlURL, func(t *testing.T) (ksql.DBAdapter, io.Closer) {
|
||||
db, err := sql.Open("mysql", mysqlURL)
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
@ -27,6 +28,8 @@ func TestAdapter(t *testing.T) {
|
||||
}
|
||||
|
||||
func startMySQLDB(dbName string) (databaseURL string, closer func()) {
|
||||
startTime := time.Now()
|
||||
|
||||
// uses a sensible default on windows (tcp/http) and linux/osx (socket)
|
||||
pool, err := dockertest.NewPool("")
|
||||
if err != nil {
|
||||
@ -54,7 +57,7 @@ func startMySQLDB(dbName string) (databaseURL string, closer func()) {
|
||||
}
|
||||
|
||||
hostAndPort := resource.GetHostPort("3306/tcp")
|
||||
databaseUrl := fmt.Sprintf("root:mysql@(%s)/%s?timeout=30s", hostAndPort, dbName)
|
||||
databaseUrl := fmt.Sprintf("root:mysql@(%s)/%s?timeout=30s&parseTime=true", hostAndPort, dbName)
|
||||
|
||||
fmt.Println("Connecting to mariadb on url: ", databaseUrl)
|
||||
|
||||
@ -63,7 +66,7 @@ func startMySQLDB(dbName string) (databaseURL string, closer func()) {
|
||||
var sqlDB *sql.DB
|
||||
// exponential backoff-retry, because the application in the container might not be ready to accept connections yet
|
||||
pool.MaxWait = 10 * time.Second
|
||||
pool.Retry(func() error {
|
||||
err = pool.Retry(func() error {
|
||||
sqlDB, err = sql.Open("mysql", databaseUrl)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -71,10 +74,12 @@ func startMySQLDB(dbName string) (databaseURL string, closer func()) {
|
||||
return sqlDB.Ping()
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalf("Could not connect to docker: %s", err)
|
||||
log.Fatalf("Could not connect to docker after %v: %s", time.Since(startTime), err)
|
||||
}
|
||||
sqlDB.Close()
|
||||
|
||||
fmt.Printf("db ready to run in %v", time.Since(startTime))
|
||||
|
||||
return databaseUrl, func() {
|
||||
if err := pool.Purge(resource); err != nil {
|
||||
log.Fatalf("Could not purge resource: %s", err)
|
||||
|
@ -3,6 +3,9 @@ package kmysql
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/vingarcia/ksql"
|
||||
)
|
||||
@ -29,7 +32,8 @@ func (s SQLAdapter) ExecContext(ctx context.Context, query string, args ...inter
|
||||
|
||||
// QueryContext implements the DBAdapter interface
|
||||
func (s SQLAdapter) QueryContext(ctx context.Context, query string, args ...interface{}) (ksql.Rows, error) {
|
||||
return s.DB.QueryContext(ctx, query, args...)
|
||||
rows, err := s.DB.QueryContext(ctx, query, args...)
|
||||
return SQLRows{rows}, err
|
||||
}
|
||||
|
||||
// BeginTx implements the Tx interface
|
||||
@ -56,7 +60,8 @@ func (s SQLTx) ExecContext(ctx context.Context, query string, args ...interface{
|
||||
|
||||
// QueryContext implements the Tx interface
|
||||
func (s SQLTx) QueryContext(ctx context.Context, query string, args ...interface{}) (ksql.Rows, error) {
|
||||
return s.Tx.QueryContext(ctx, query, args...)
|
||||
rows, err := s.Tx.QueryContext(ctx, query, args...)
|
||||
return SQLRows{rows}, err
|
||||
}
|
||||
|
||||
// Rollback implements the Tx interface
|
||||
@ -70,3 +75,40 @@ func (s SQLTx) Commit(ctx context.Context) error {
|
||||
}
|
||||
|
||||
var _ ksql.Tx = SQLTx{}
|
||||
|
||||
// SQLRows implements the ksql.Rows interface and is used to help
|
||||
// the SQLAdapter to implement the ksql.DBAdapter interface.
|
||||
type SQLRows struct {
|
||||
*sql.Rows
|
||||
}
|
||||
|
||||
var _ ksql.Rows = SQLRows{}
|
||||
|
||||
// Scan implements the ksql.Rows interface
|
||||
func (p SQLRows) Scan(args ...interface{}) error {
|
||||
err := p.Rows.Scan(args...)
|
||||
if err != nil {
|
||||
// Since this is the error flow we decided it would be ok
|
||||
// to spend a little bit more time parsing this error in order
|
||||
// to produce better error messages.
|
||||
//
|
||||
// If the parsing fails we just return the error unchanged.
|
||||
const scanErrPrefix = "sql: Scan error on column index "
|
||||
var errMsg = err.Error()
|
||||
if strings.HasPrefix(errMsg, scanErrPrefix) {
|
||||
i := len(scanErrPrefix)
|
||||
for unicode.IsDigit(rune(errMsg[i])) {
|
||||
i++
|
||||
}
|
||||
colIndex, convErr := strconv.Atoi(errMsg[len(scanErrPrefix):i])
|
||||
if convErr == nil {
|
||||
return ksql.ScanArgError{
|
||||
ColumnIndex: colIndex,
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
@ -4,18 +4,11 @@ go 1.14
|
||||
|
||||
require (
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
github.com/Microsoft/go-winio v0.5.2 // indirect
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
|
||||
github.com/containerd/continuity v0.2.2 // indirect
|
||||
github.com/docker/go-connections v0.4.0 // indirect
|
||||
github.com/gotestyourself/gotestyourself v2.2.0+incompatible // indirect
|
||||
github.com/jackc/pgconn v1.10.0
|
||||
github.com/jackc/pgx/v4 v4.13.0
|
||||
github.com/lib/pq v1.10.4
|
||||
github.com/opencontainers/image-spec v1.0.2 // indirect
|
||||
github.com/opencontainers/runc v1.1.0 // indirect
|
||||
github.com/ory/dockertest v3.3.5+incompatible
|
||||
github.com/vingarcia/ksql v1.4.7
|
||||
gotest.tools v2.2.0+incompatible // indirect
|
||||
github.com/google/go-cmp v0.5.6 // indirect
|
||||
github.com/jackc/pgconn v1.14.1
|
||||
github.com/jackc/pgx/v4 v4.18.1
|
||||
github.com/ory/dockertest/v3 v3.10.0
|
||||
github.com/stretchr/testify v1.8.4 // indirect
|
||||
github.com/vingarcia/ksql v1.12.3
|
||||
golang.org/x/crypto v0.12.0 // indirect
|
||||
)
|
||||
|
@ -1,89 +1,67 @@
|
||||
bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512/go.mod h1:FbcW6z/2VytnFDhZfumh8Ss8zxHE6qpMP5sHTRe0EaM=
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
|
||||
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
||||
github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||
github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
|
||||
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
||||
github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
|
||||
github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4=
|
||||
github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E=
|
||||
github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
|
||||
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
|
||||
github.com/containerd/continuity v0.2.2 h1:QSqfxcn8c+12slxwu00AtzXrsami0MJb/MQs9lOLHLA=
|
||||
github.com/containerd/continuity v0.2.2/go.mod h1:pWygW9u7LtS1o4N/Tn0FoCFDIXZ7rxcMX7HX1Dmibvk=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg=
|
||||
github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
|
||||
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
||||
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/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/docker/cli v20.10.17+incompatible h1:eO2KS7ZFeov5UJeaDmIs1NFEDRf32PaqRpvoEkKBy5M=
|
||||
github.com/docker/cli v20.10.17+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/docker v20.10.7+incompatible h1:Z6O9Nhsjv+ayUEeI1IojKbYcsGdgYSNqxe1s2MYzUhQ=
|
||||
github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
|
||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
|
||||
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
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.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gotestyourself/gotestyourself v2.2.0+incompatible h1:AQwinXlbQR2HvPjQZOmDhRqsv5mZf+Jb1RnSLxcqZcI=
|
||||
github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
||||
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=
|
||||
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
|
||||
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||
@ -95,8 +73,9 @@ github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsU
|
||||
github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o=
|
||||
github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY=
|
||||
github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
|
||||
github.com/jackc/pgconn v1.10.0 h1:4EYhlDVEMsJ30nNj0mmgwIUXoq7e9sMJrVC2ED6QlCU=
|
||||
github.com/jackc/pgconn v1.10.0/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
|
||||
github.com/jackc/pgconn v1.14.0/go.mod h1:9mBNlny0UvkgJdCDvdVHYSjI+8tD2rnKK69Wz8ti++E=
|
||||
github.com/jackc/pgconn v1.14.1 h1:smbxIaZA08n6YuxEX1sDyjV/qkbtUtkH20qLkR9MUR4=
|
||||
github.com/jackc/pgconn v1.14.1/go.mod h1:9mBNlny0UvkgJdCDvdVHYSjI+8tD2rnKK69Wz8ti++E=
|
||||
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
|
||||
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
|
||||
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
|
||||
@ -112,133 +91,124 @@ github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
|
||||
github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||
github.com/jackc/pgproto3/v2 v2.1.1 h1:7PQ/4gLoqnl87ZxL7xjO0DR5gYuviDCZxQJsUlFW1eI=
|
||||
github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg=
|
||||
github.com/jackc/pgproto3/v2 v2.3.2 h1:7eY55bdBeCz1F2fTzSz69QC+pG46jYq9/jtSPiJ5nn0=
|
||||
github.com/jackc/pgproto3/v2 v2.3.2/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=
|
||||
github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
|
||||
github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
|
||||
github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM=
|
||||
github.com/jackc/pgtype v1.8.1 h1:9k0IXtdJXHJbyAWQgbWr1lU+MEhPXZz6RIXxfR5oxXs=
|
||||
github.com/jackc/pgtype v1.8.1/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
|
||||
github.com/jackc/pgtype v1.14.0 h1:y+xUdabmyMkJLyApYuPj38mW+aAIqCe5uuBB51rH3Vw=
|
||||
github.com/jackc/pgtype v1.14.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
|
||||
github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
|
||||
github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
|
||||
github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
|
||||
github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs=
|
||||
github.com/jackc/pgx/v4 v4.13.0 h1:JCjhT5vmhMAf/YwBHLvrBn4OGdIQBiFG6ym8Zmdx570=
|
||||
github.com/jackc/pgx/v4 v4.13.0/go.mod h1:9P4X524sErlaxj0XSGZk7s+LD0eOyu1ZDUrrpznYDF0=
|
||||
github.com/jackc/pgx/v4 v4.18.1 h1:YP7G1KABtKpB5IHrO9vYwSrCOhs7p3uqhvhhQBptya0=
|
||||
github.com/jackc/pgx/v4 v4.18.1/go.mod h1:FydWkUyadDmdNH/mHnGob881GawxeEm7TcMCzkb+qQE=
|
||||
github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v1.1.3 h1:JnPg/5Q9xVJGfjsO5CPUOjnJps1JaRUm8I9FXVCFK94=
|
||||
github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/jackc/puddle v1.3.0 h1:eHK/5clGOatcjX3oWGBO/MpxpbHzSwud5EWTSCI+MX0=
|
||||
github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8=
|
||||
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk=
|
||||
github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
|
||||
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
|
||||
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 h1:rzf0wL0CHVc8CEsgyygG0Mn9CNCCPZqOPaz8RiiHYQk=
|
||||
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc=
|
||||
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
|
||||
github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/opencontainers/runc v1.1.0 h1:O9+X96OcDjkmmZyfaG996kV7yq8HsoU2h1XRRQcefG8=
|
||||
github.com/opencontainers/runc v1.1.0/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc=
|
||||
github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs=
|
||||
github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg=
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
|
||||
github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA=
|
||||
github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/ory/dockertest/v3 v3.10.0 h1:4K3z2VMe8Woe++invjaTB7VRyQXQy5UY+loujO4aNE4=
|
||||
github.com/ory/dockertest/v3 v3.10.0/go.mod h1:nr57ZbRWMqfsdGdFNLHz5jjNdDb7VVFnzAeW1n5N1Lg=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
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/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
||||
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
|
||||
github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
|
||||
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
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/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
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.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/vingarcia/ksql v1.4.7 h1:Gt9uz5ScL/lJxVa9DlA+4QaUWAOaSz1ZjUJDn8neLAI=
|
||||
github.com/vingarcia/ksql v1.4.7/go.mod h1:EVxEK3x6igVSFLDLLaymc25soqn3fSsZ0hrAryKtfCg=
|
||||
github.com/vingarcia/ksql v1.12.3 h1:1LVRGW39XPaYltPHNQsvHms+bWHp8e99sxQx+aEXDMQ=
|
||||
github.com/vingarcia/ksql v1.12.3/go.mod h1:DHp/nhVu1nHpBBXH/FRw6JLgIcvcM3+uo2+PfUNdo0g=
|
||||
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
@ -250,7 +220,6 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9E
|
||||
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
@ -259,34 +228,40 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
|
||||
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
|
||||
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -296,36 +271,62 @@ golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c h1:DHcbWVXeY+0Y8HHKR+rbLwnoh2F4tNCY7rTiHJ30RmA=
|
||||
golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220405210540-1e041c57c461/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
|
||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
|
||||
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
|
||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@ -333,25 +334,22 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||
gotest.tools/v3 v3.3.0 h1:MfDY1b1/0xN1CyMlQDac0ziEy9zJQd9CXBRRDHw2jJo=
|
||||
gotest.tools/v3 v3.3.0/go.mod h1:Mcr9QNxkg0uMvy/YElmo4SpXgJKWgQvYrT7Kw5RzJ1A=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
|
@ -5,15 +5,12 @@ import (
|
||||
|
||||
"github.com/jackc/pgx/v4/pgxpool"
|
||||
"github.com/vingarcia/ksql"
|
||||
|
||||
// This is imported here so the user don't
|
||||
// have to worry about it when he uses it.
|
||||
_ "github.com/lib/pq"
|
||||
"github.com/vingarcia/ksql/sqldialect"
|
||||
)
|
||||
|
||||
// NewFromPgxPool builds a ksql.DB from a *pgxpool.Pool instance
|
||||
func NewFromPgxPool(pool *pgxpool.Pool) (db ksql.DB, err error) {
|
||||
return ksql.NewWithAdapter(NewPGXAdapter(pool), "postgres")
|
||||
return ksql.NewWithAdapter(NewPGXAdapter(pool), sqldialect.PostgresDialect{})
|
||||
}
|
||||
|
||||
// New instantiates a new ksql.Client using pgx as the backend driver
|
||||
@ -39,6 +36,6 @@ func New(
|
||||
return ksql.DB{}, err
|
||||
}
|
||||
|
||||
db, err = ksql.NewWithAdapter(NewPGXAdapter(pool), "postgres")
|
||||
db, err = ksql.NewWithAdapter(NewPGXAdapter(pool), sqldialect.PostgresDialect{})
|
||||
return db, err
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package kpgx
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
@ -10,17 +9,20 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v4/pgxpool"
|
||||
"github.com/ory/dockertest"
|
||||
"github.com/ory/dockertest/docker"
|
||||
"github.com/ory/dockertest/v3"
|
||||
"github.com/ory/dockertest/v3/docker"
|
||||
"github.com/vingarcia/ksql"
|
||||
"github.com/vingarcia/ksql/sqldialect"
|
||||
)
|
||||
|
||||
func TestAdapter(t *testing.T) {
|
||||
postgresURL, closePostgres := startPostgresDB("ksql")
|
||||
ctx := context.Background()
|
||||
|
||||
postgresURL, closePostgres := startPostgresDB(ctx, "ksql")
|
||||
defer closePostgres()
|
||||
|
||||
ksql.RunTestsForAdapter(t, "kpgx", "postgres", postgresURL, func(t *testing.T) (ksql.DBAdapter, io.Closer) {
|
||||
pool, err := pgxpool.Connect(context.TODO(), postgresURL)
|
||||
ksql.RunTestsForAdapter(t, "kpgx", sqldialect.PostgresDialect{}, postgresURL, func(t *testing.T) (ksql.DBAdapter, io.Closer) {
|
||||
pool, err := pgxpool.Connect(ctx, postgresURL)
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
@ -37,15 +39,17 @@ func (c closerAdapter) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func startPostgresDB(dbName string) (databaseURL string, closer func()) {
|
||||
func startPostgresDB(ctx context.Context, dbName string) (databaseURL string, closer func()) {
|
||||
startTime := time.Now()
|
||||
|
||||
// uses a sensible default on windows (tcp/http) and linux/osx (socket)
|
||||
pool, err := dockertest.NewPool("")
|
||||
dockerPool, err := dockertest.NewPool("")
|
||||
if err != nil {
|
||||
log.Fatalf("Could not connect to docker: %s", err)
|
||||
}
|
||||
|
||||
// pulls an image, creates a container based on it and runs it
|
||||
resource, err := pool.RunWithOptions(
|
||||
resource, err := dockerPool.RunWithOptions(
|
||||
&dockertest.RunOptions{
|
||||
Repository: "postgres",
|
||||
Tag: "14.0",
|
||||
@ -73,23 +77,26 @@ func startPostgresDB(dbName string) (databaseURL string, closer func()) {
|
||||
|
||||
resource.Expire(40) // Tell docker to hard kill the container in 40 seconds
|
||||
|
||||
var sqlDB *sql.DB
|
||||
var sqlDB *pgxpool.Pool
|
||||
// exponential backoff-retry, because the application in the container might not be ready to accept connections yet
|
||||
pool.MaxWait = 10 * time.Second
|
||||
pool.Retry(func() error {
|
||||
sqlDB, err = sql.Open("postgres", databaseUrl)
|
||||
dockerPool.MaxWait = 10 * time.Second
|
||||
err = dockerPool.Retry(func() error {
|
||||
sqlDB, err = pgxpool.Connect(ctx, databaseUrl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return sqlDB.Ping()
|
||||
|
||||
return sqlDB.Ping(ctx)
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalf("Could not connect to docker: %s", err)
|
||||
log.Fatalf("Could not connect to docker after %v: %s", time.Since(startTime), err)
|
||||
}
|
||||
sqlDB.Close()
|
||||
|
||||
fmt.Printf("db ready to run in %v", time.Since(startTime))
|
||||
|
||||
return databaseUrl, func() {
|
||||
if err := pool.Purge(resource); err != nil {
|
||||
if err := dockerPool.Purge(resource); err != nil {
|
||||
log.Fatalf("Could not purge resource: %s", err)
|
||||
}
|
||||
}
|
||||
|
@ -96,14 +96,27 @@ func (p PGXTx) Commit(ctx context.Context) error {
|
||||
|
||||
var _ ksql.Tx = PGXTx{}
|
||||
|
||||
// PGXRows implements the Rows interface and is used to help
|
||||
// the PGXAdapter to implement the DBAdapter interface.
|
||||
// PGXRows implements the ksql.Rows interface and is used to help
|
||||
// the PGXAdapter to implement the ksql.DBAdapter interface.
|
||||
type PGXRows struct {
|
||||
pgx.Rows
|
||||
}
|
||||
|
||||
var _ ksql.Rows = PGXRows{}
|
||||
|
||||
// Scan implements the ksql.Rows interface
|
||||
func (p PGXRows) Scan(args ...interface{}) error {
|
||||
err := p.Rows.Scan(args...)
|
||||
if scanErr, ok := err.(pgx.ScanArgError); ok {
|
||||
return ksql.ScanArgError{
|
||||
Err: scanErr.Err,
|
||||
ColumnIndex: scanErr.ColumnIndex,
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Columns implements the Rows interface
|
||||
func (p PGXRows) Columns() ([]string, error) {
|
||||
var names []string
|
||||
|
15
adapters/kpgx5/go.mod
Normal file
15
adapters/kpgx5/go.mod
Normal file
@ -0,0 +1,15 @@
|
||||
module github.com/vingarcia/ksql/adapters/kpgx5
|
||||
|
||||
go 1.14
|
||||
|
||||
require (
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
github.com/google/go-cmp v0.5.6 // indirect
|
||||
github.com/jackc/pgx/v5 v5.4.3
|
||||
github.com/lib/pq v1.10.9 // indirect
|
||||
github.com/ory/dockertest/v3 v3.10.0
|
||||
github.com/stretchr/testify v1.8.4 // indirect
|
||||
github.com/vingarcia/ksql v1.12.3
|
||||
golang.org/x/crypto v0.12.0 // indirect
|
||||
golang.org/x/sync v0.3.0 // indirect
|
||||
)
|
230
adapters/kpgx5/go.sum
Normal file
230
adapters/kpgx5/go.sum
Normal file
@ -0,0 +1,230 @@
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
||||
github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
|
||||
github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
|
||||
github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4=
|
||||
github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E=
|
||||
github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA=
|
||||
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
|
||||
github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg=
|
||||
github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM=
|
||||
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
|
||||
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
||||
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/docker/cli v20.10.17+incompatible h1:eO2KS7ZFeov5UJeaDmIs1NFEDRf32PaqRpvoEkKBy5M=
|
||||
github.com/docker/cli v20.10.17+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/docker v20.10.7+incompatible h1:Z6O9Nhsjv+ayUEeI1IojKbYcsGdgYSNqxe1s2MYzUhQ=
|
||||
github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
|
||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
|
||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
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.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
||||
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgx/v5 v5.4.3 h1:cxFyXhxlvAifxnkKKdlxv8XqUf59tDlYjnV5YYfsJJY=
|
||||
github.com/jackc/pgx/v5 v5.4.3/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA=
|
||||
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
|
||||
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
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/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
|
||||
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
|
||||
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 h1:rzf0wL0CHVc8CEsgyygG0Mn9CNCCPZqOPaz8RiiHYQk=
|
||||
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc=
|
||||
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
|
||||
github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs=
|
||||
github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg=
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
|
||||
github.com/ory/dockertest/v3 v3.10.0 h1:4K3z2VMe8Woe++invjaTB7VRyQXQy5UY+loujO4aNE4=
|
||||
github.com/ory/dockertest/v3 v3.10.0/go.mod h1:nr57ZbRWMqfsdGdFNLHz5jjNdDb7VVFnzAeW1n5N1Lg=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
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/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
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/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
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.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/vingarcia/ksql v1.12.3 h1:1LVRGW39XPaYltPHNQsvHms+bWHp8e99sxQx+aEXDMQ=
|
||||
github.com/vingarcia/ksql v1.12.3/go.mod h1:DHp/nhVu1nHpBBXH/FRw6JLgIcvcM3+uo2+PfUNdo0g=
|
||||
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
|
||||
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
|
||||
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
|
||||
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
|
||||
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220405210540-1e041c57c461/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
|
||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
|
||||
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
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=
|
||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||
gotest.tools/v3 v3.3.0 h1:MfDY1b1/0xN1CyMlQDac0ziEy9zJQd9CXBRRDHw2jJo=
|
||||
gotest.tools/v3 v3.3.0/go.mod h1:Mcr9QNxkg0uMvy/YElmo4SpXgJKWgQvYrT7Kw5RzJ1A=
|
40
adapters/kpgx5/kpgx.go
Normal file
40
adapters/kpgx5/kpgx.go
Normal file
@ -0,0 +1,40 @@
|
||||
package kpgx
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
"github.com/vingarcia/ksql"
|
||||
"github.com/vingarcia/ksql/sqldialect"
|
||||
)
|
||||
|
||||
// NewFromPgxPool builds a ksql.DB from a *pgxpool.Pool instance
|
||||
func NewFromPgxPool(pool *pgxpool.Pool) (db ksql.DB, err error) {
|
||||
return ksql.NewWithAdapter(NewPGXAdapter(pool), sqldialect.PostgresDialect{})
|
||||
}
|
||||
|
||||
// New instantiates a new ksql.Client using pgx as the backend driver
|
||||
func New(
|
||||
ctx context.Context,
|
||||
connectionString string,
|
||||
config ksql.Config,
|
||||
) (db ksql.DB, err error) {
|
||||
config.SetDefaultValues()
|
||||
|
||||
pgxConf, err := pgxpool.ParseConfig(connectionString)
|
||||
if err != nil {
|
||||
return ksql.DB{}, err
|
||||
}
|
||||
|
||||
pgxConf.MaxConns = int32(config.MaxOpenConns)
|
||||
|
||||
pool, err := pgxpool.NewWithConfig(ctx, pgxConf)
|
||||
if err != nil {
|
||||
return ksql.DB{}, err
|
||||
}
|
||||
if err = pool.Ping(ctx); err != nil {
|
||||
return ksql.DB{}, err
|
||||
}
|
||||
|
||||
return ksql.NewWithAdapter(NewPGXAdapter(pool), sqldialect.PostgresDialect{})
|
||||
}
|
103
adapters/kpgx5/kpgx_test.go
Normal file
103
adapters/kpgx5/kpgx_test.go
Normal file
@ -0,0 +1,103 @@
|
||||
package kpgx
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
"github.com/ory/dockertest/v3"
|
||||
"github.com/ory/dockertest/v3/docker"
|
||||
"github.com/vingarcia/ksql"
|
||||
"github.com/vingarcia/ksql/sqldialect"
|
||||
)
|
||||
|
||||
func TestAdapter(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
postgresURL, closePostgres := startPostgresDB(ctx, "ksql")
|
||||
defer closePostgres()
|
||||
|
||||
ksql.RunTestsForAdapter(t, "kpgx5", sqldialect.PostgresDialect{}, postgresURL, func(t *testing.T) (ksql.DBAdapter, io.Closer) {
|
||||
pool, err := pgxpool.New(ctx, postgresURL)
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
return PGXAdapter{pool}, closerAdapter{close: pool.Close}
|
||||
})
|
||||
}
|
||||
|
||||
type closerAdapter struct {
|
||||
close func()
|
||||
}
|
||||
|
||||
func (c closerAdapter) Close() error {
|
||||
c.close()
|
||||
return nil
|
||||
}
|
||||
|
||||
func startPostgresDB(ctx context.Context, dbName string) (databaseURL string, closer func()) {
|
||||
startTime := time.Now()
|
||||
|
||||
// uses a sensible default on windows (tcp/http) and linux/osx (socket)
|
||||
pool, err := dockertest.NewPool("")
|
||||
if err != nil {
|
||||
log.Fatalf("Could not connect to docker: %s", err)
|
||||
}
|
||||
|
||||
// pulls an image, creates a container based on it and runs it
|
||||
resource, err := pool.RunWithOptions(
|
||||
&dockertest.RunOptions{
|
||||
Repository: "postgres",
|
||||
Tag: "14.0",
|
||||
Env: []string{
|
||||
"POSTGRES_PASSWORD=postgres",
|
||||
"POSTGRES_USER=postgres",
|
||||
"POSTGRES_DB=" + dbName,
|
||||
"listen_addresses = '*'",
|
||||
},
|
||||
},
|
||||
func(config *docker.HostConfig) {
|
||||
// set AutoRemove to true so that stopped container goes away by itself
|
||||
config.AutoRemove = true
|
||||
config.RestartPolicy = docker.RestartPolicy{Name: "no"}
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatalf("Could not start resource: %s", err)
|
||||
}
|
||||
|
||||
hostAndPort := resource.GetHostPort("5432/tcp")
|
||||
databaseUrl := fmt.Sprintf("postgres://postgres:postgres@%s/%s?sslmode=disable", hostAndPort, dbName)
|
||||
|
||||
fmt.Println("Connecting to postgres on url: ", databaseUrl)
|
||||
|
||||
resource.Expire(40) // Tell docker to hard kill the container in 40 seconds
|
||||
|
||||
var sqlDB *pgxpool.Pool
|
||||
// exponential backoff-retry, because the application in the container might not be ready to accept connections yet
|
||||
pool.MaxWait = 10 * time.Second
|
||||
err = pool.Retry(func() error {
|
||||
sqlDB, err = pgxpool.New(ctx, databaseUrl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sqlDB.Ping(ctx)
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalf("Could not connect to docker after %v: %s", time.Since(startTime), err)
|
||||
}
|
||||
sqlDB.Close()
|
||||
|
||||
fmt.Printf("db ready to run in %v", time.Since(startTime))
|
||||
|
||||
return databaseUrl, func() {
|
||||
if err := pool.Purge(resource); err != nil {
|
||||
log.Fatalf("Could not purge resource: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
133
adapters/kpgx5/pgx_adapter.go
Normal file
133
adapters/kpgx5/pgx_adapter.go
Normal file
@ -0,0 +1,133 @@
|
||||
package kpgx
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgconn"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
"github.com/vingarcia/ksql"
|
||||
)
|
||||
|
||||
// PGXAdapter adapts the sql.DB type to be compatible with the `DBAdapter` interface
|
||||
type PGXAdapter struct {
|
||||
db *pgxpool.Pool
|
||||
}
|
||||
|
||||
// NewPGXAdapter instantiates a new pgx adapter
|
||||
func NewPGXAdapter(db *pgxpool.Pool) PGXAdapter {
|
||||
return PGXAdapter{
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
var _ ksql.DBAdapter = PGXAdapter{}
|
||||
|
||||
// ExecContext implements the DBAdapter interface
|
||||
func (p PGXAdapter) ExecContext(ctx context.Context, query string, args ...interface{}) (ksql.Result, error) {
|
||||
result, err := p.db.Exec(ctx, query, args...)
|
||||
return PGXResult{result}, err
|
||||
}
|
||||
|
||||
// QueryContext implements the DBAdapter interface
|
||||
func (p PGXAdapter) QueryContext(ctx context.Context, query string, args ...interface{}) (ksql.Rows, error) {
|
||||
rows, err := p.db.Query(ctx, query, args...)
|
||||
return PGXRows{rows}, err
|
||||
}
|
||||
|
||||
// BeginTx implements the Tx interface
|
||||
func (p PGXAdapter) BeginTx(ctx context.Context) (ksql.Tx, error) {
|
||||
tx, err := p.db.Begin(ctx)
|
||||
return PGXTx{tx}, err
|
||||
}
|
||||
|
||||
// Close implements the io.Closer interface
|
||||
func (p PGXAdapter) Close() error {
|
||||
p.db.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
// PGXResult is used to implement the DBAdapter interface and implements
|
||||
// the Result interface
|
||||
type PGXResult struct {
|
||||
tag pgconn.CommandTag
|
||||
}
|
||||
|
||||
// RowsAffected implements the Result interface
|
||||
func (p PGXResult) RowsAffected() (int64, error) {
|
||||
return p.tag.RowsAffected(), nil
|
||||
}
|
||||
|
||||
// LastInsertId implements the Result interface
|
||||
func (p PGXResult) LastInsertId() (int64, error) {
|
||||
return 0, fmt.Errorf(
|
||||
"LastInsertId is not implemented in the pgx adapter, use the `RETURNING` statement instead",
|
||||
)
|
||||
}
|
||||
|
||||
// PGXTx is used to implement the DBAdapter interface and implements
|
||||
// the Tx interface
|
||||
type PGXTx struct {
|
||||
tx pgx.Tx
|
||||
}
|
||||
|
||||
// ExecContext implements the Tx interface
|
||||
func (p PGXTx) ExecContext(ctx context.Context, query string, args ...interface{}) (ksql.Result, error) {
|
||||
result, err := p.tx.Exec(ctx, query, args...)
|
||||
return PGXResult{result}, err
|
||||
}
|
||||
|
||||
// QueryContext implements the Tx interface
|
||||
func (p PGXTx) QueryContext(ctx context.Context, query string, args ...interface{}) (ksql.Rows, error) {
|
||||
rows, err := p.tx.Query(ctx, query, args...)
|
||||
return PGXRows{rows}, err
|
||||
}
|
||||
|
||||
// Rollback implements the Tx interface
|
||||
func (p PGXTx) Rollback(ctx context.Context) error {
|
||||
return p.tx.Rollback(ctx)
|
||||
}
|
||||
|
||||
// Commit implements the Tx interface
|
||||
func (p PGXTx) Commit(ctx context.Context) error {
|
||||
return p.tx.Commit(ctx)
|
||||
}
|
||||
|
||||
var _ ksql.Tx = PGXTx{}
|
||||
|
||||
// PGXRows implements the ksql.Rows interface and is used to help
|
||||
// the PGXAdapter to implement the ksql.DBAdapter interface.
|
||||
type PGXRows struct {
|
||||
pgx.Rows
|
||||
}
|
||||
|
||||
var _ ksql.Rows = PGXRows{}
|
||||
|
||||
// Scan implements the ksql.Rows interface
|
||||
func (p PGXRows) Scan(args ...interface{}) error {
|
||||
err := p.Rows.Scan(args...)
|
||||
if scanErr, ok := err.(pgx.ScanArgError); ok {
|
||||
return ksql.ScanArgError{
|
||||
Err: scanErr.Err,
|
||||
ColumnIndex: scanErr.ColumnIndex,
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Columns implements the Rows interface
|
||||
func (p PGXRows) Columns() ([]string, error) {
|
||||
var names []string
|
||||
for _, desc := range p.Rows.FieldDescriptions() {
|
||||
names = append(names, string(desc.Name))
|
||||
}
|
||||
return names, nil
|
||||
}
|
||||
|
||||
// Close implements the Rows interface
|
||||
func (p PGXRows) Close() error {
|
||||
p.Rows.Close()
|
||||
return nil
|
||||
}
|
11
adapters/kpostgres/go.mod
Normal file
11
adapters/kpostgres/go.mod
Normal file
@ -0,0 +1,11 @@
|
||||
module github.com/vingarcia/ksql/adapters/kpostgres
|
||||
|
||||
go 1.14
|
||||
|
||||
require (
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
github.com/google/go-cmp v0.5.6 // indirect
|
||||
github.com/lib/pq v1.10.4
|
||||
github.com/ory/dockertest/v3 v3.10.0
|
||||
github.com/vingarcia/ksql v1.12.3
|
||||
)
|
208
adapters/kpostgres/go.sum
Normal file
208
adapters/kpostgres/go.sum
Normal file
@ -0,0 +1,208 @@
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
||||
github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
|
||||
github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
|
||||
github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4=
|
||||
github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E=
|
||||
github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA=
|
||||
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
|
||||
github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg=
|
||||
github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM=
|
||||
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
|
||||
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
||||
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/docker/cli v20.10.17+incompatible h1:eO2KS7ZFeov5UJeaDmIs1NFEDRf32PaqRpvoEkKBy5M=
|
||||
github.com/docker/cli v20.10.17+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/docker v20.10.7+incompatible h1:Z6O9Nhsjv+ayUEeI1IojKbYcsGdgYSNqxe1s2MYzUhQ=
|
||||
github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
|
||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
|
||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
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.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
||||
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
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/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk=
|
||||
github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
|
||||
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
|
||||
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 h1:rzf0wL0CHVc8CEsgyygG0Mn9CNCCPZqOPaz8RiiHYQk=
|
||||
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc=
|
||||
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
|
||||
github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs=
|
||||
github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg=
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
|
||||
github.com/ory/dockertest/v3 v3.10.0 h1:4K3z2VMe8Woe++invjaTB7VRyQXQy5UY+loujO4aNE4=
|
||||
github.com/ory/dockertest/v3 v3.10.0/go.mod h1:nr57ZbRWMqfsdGdFNLHz5jjNdDb7VVFnzAeW1n5N1Lg=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
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/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
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/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
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.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/vingarcia/ksql v1.12.3 h1:1LVRGW39XPaYltPHNQsvHms+bWHp8e99sxQx+aEXDMQ=
|
||||
github.com/vingarcia/ksql v1.12.3/go.mod h1:DHp/nhVu1nHpBBXH/FRw6JLgIcvcM3+uo2+PfUNdo0g=
|
||||
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
|
||||
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220405210540-1e041c57c461/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
|
||||
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
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=
|
||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||
gotest.tools/v3 v3.3.0 h1:MfDY1b1/0xN1CyMlQDac0ziEy9zJQd9CXBRRDHw2jJo=
|
||||
gotest.tools/v3 v3.3.0/go.mod h1:Mcr9QNxkg0uMvy/YElmo4SpXgJKWgQvYrT7Kw5RzJ1A=
|
13
adapters/kpostgres/kpostgres.go
Normal file
13
adapters/kpostgres/kpostgres.go
Normal file
@ -0,0 +1,13 @@
|
||||
package kpostgres
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
|
||||
"github.com/vingarcia/ksql"
|
||||
"github.com/vingarcia/ksql/sqldialect"
|
||||
)
|
||||
|
||||
// NewFromSQLDB builds a ksql.DB from a *sql.DB instance
|
||||
func NewFromSQLDB(db *sql.DB) (ksql.DB, error) {
|
||||
return ksql.NewWithAdapter(NewSQLAdapter(db), sqldialect.PostgresDialect{})
|
||||
}
|
95
adapters/kpostgres/kpostgres_test.go
Normal file
95
adapters/kpostgres/kpostgres_test.go
Normal file
@ -0,0 +1,95 @@
|
||||
package kpostgres
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
_ "github.com/lib/pq"
|
||||
"github.com/ory/dockertest/v3"
|
||||
"github.com/ory/dockertest/v3/docker"
|
||||
"github.com/vingarcia/ksql"
|
||||
"github.com/vingarcia/ksql/sqldialect"
|
||||
)
|
||||
|
||||
func TestSQLAdapter(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
postgresURL, closePostgres := startPostgresDB(ctx, "ksql")
|
||||
defer closePostgres()
|
||||
|
||||
ksql.RunTestsForAdapter(t, "kpostgres", sqldialect.PostgresDialect{}, postgresURL, func(t *testing.T) (ksql.DBAdapter, io.Closer) {
|
||||
sqldb, err := sql.Open("postgres", postgresURL)
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
return SQLAdapter{sqldb}, sqldb
|
||||
})
|
||||
}
|
||||
|
||||
func startPostgresDB(ctx context.Context, dbName string) (databaseURL string, closer func()) {
|
||||
startTime := time.Now()
|
||||
// uses a sensible default on windows (tcp/http) and linux/osx (socket)
|
||||
dockerPool, err := dockertest.NewPool("")
|
||||
if err != nil {
|
||||
log.Fatalf("Could not connect to docker: %s", err)
|
||||
}
|
||||
|
||||
// pulls an image, creates a container based on it and runs it
|
||||
resource, err := dockerPool.RunWithOptions(
|
||||
&dockertest.RunOptions{
|
||||
Repository: "postgres",
|
||||
Tag: "14.0",
|
||||
Env: []string{
|
||||
"POSTGRES_PASSWORD=postgres",
|
||||
"POSTGRES_USER=postgres",
|
||||
"POSTGRES_DB=" + dbName,
|
||||
"listen_addresses = '*'",
|
||||
},
|
||||
},
|
||||
func(config *docker.HostConfig) {
|
||||
// set AutoRemove to true so that stopped container goes away by itself
|
||||
config.AutoRemove = true
|
||||
config.RestartPolicy = docker.RestartPolicy{Name: "no"}
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatalf("Could not start resource: %s", err)
|
||||
}
|
||||
|
||||
hostAndPort := resource.GetHostPort("5432/tcp")
|
||||
databaseUrl := fmt.Sprintf("postgres://postgres:postgres@%s/%s?sslmode=disable", hostAndPort, dbName)
|
||||
|
||||
fmt.Println("Connecting to postgres on url: ", databaseUrl)
|
||||
|
||||
resource.Expire(40) // Tell docker to hard kill the container in 40 seconds
|
||||
|
||||
var sqlDB *sql.DB
|
||||
// exponential backoff-retry, because the application in the container might not be ready to accept connections yet
|
||||
dockerPool.MaxWait = 10 * time.Second
|
||||
err = dockerPool.Retry(func() error {
|
||||
sqlDB, err = sql.Open("postgres", databaseUrl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sqlDB.Ping()
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalf("Could not connect to docker after %v: %s", time.Since(startTime), err)
|
||||
}
|
||||
sqlDB.Close()
|
||||
|
||||
fmt.Printf("db ready to run in %v", time.Since(startTime))
|
||||
|
||||
return databaseUrl, func() {
|
||||
if err := dockerPool.Purge(resource); err != nil {
|
||||
log.Fatalf("Could not purge resource: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
114
adapters/kpostgres/sql_adapter.go
Normal file
114
adapters/kpostgres/sql_adapter.go
Normal file
@ -0,0 +1,114 @@
|
||||
package kpostgres
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
|
||||
"github.com/vingarcia/ksql"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
// SQLAdapter adapts the sql.DB type to be compatible with the `DBAdapter` interface
|
||||
type SQLAdapter struct {
|
||||
*sql.DB
|
||||
}
|
||||
|
||||
var _ ksql.DBAdapter = SQLAdapter{}
|
||||
|
||||
// NewSQLAdapter returns a new instance of SQLAdapter with
|
||||
// the provided database instance.
|
||||
func NewSQLAdapter(db *sql.DB) SQLAdapter {
|
||||
return SQLAdapter{
|
||||
DB: db,
|
||||
}
|
||||
}
|
||||
|
||||
// ExecContext implements the DBAdapter interface
|
||||
func (s SQLAdapter) ExecContext(ctx context.Context, query string, args ...interface{}) (ksql.Result, error) {
|
||||
return s.DB.ExecContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
// QueryContext implements the DBAdapter interface
|
||||
func (s SQLAdapter) QueryContext(ctx context.Context, query string, args ...interface{}) (ksql.Rows, error) {
|
||||
rows, err := s.DB.QueryContext(ctx, query, args...)
|
||||
return SQLRows{rows}, err
|
||||
}
|
||||
|
||||
// BeginTx implements the Tx interface
|
||||
func (s SQLAdapter) BeginTx(ctx context.Context) (ksql.Tx, error) {
|
||||
tx, err := s.DB.BeginTx(ctx, nil)
|
||||
return SQLTx{Tx: tx}, err
|
||||
}
|
||||
|
||||
// Close implements the io.Closer interface
|
||||
func (s SQLAdapter) Close() error {
|
||||
return s.DB.Close()
|
||||
}
|
||||
|
||||
// SQLTx is used to implement the DBAdapter interface and implements
|
||||
// the Tx interface
|
||||
type SQLTx struct {
|
||||
*sql.Tx
|
||||
}
|
||||
|
||||
// ExecContext implements the Tx interface
|
||||
func (s SQLTx) ExecContext(ctx context.Context, query string, args ...interface{}) (ksql.Result, error) {
|
||||
return s.Tx.ExecContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
// QueryContext implements the Tx interface
|
||||
func (s SQLTx) QueryContext(ctx context.Context, query string, args ...interface{}) (ksql.Rows, error) {
|
||||
rows, err := s.Tx.QueryContext(ctx, query, args...)
|
||||
return SQLRows{rows}, err
|
||||
}
|
||||
|
||||
// Rollback implements the Tx interface
|
||||
func (s SQLTx) Rollback(ctx context.Context) error {
|
||||
return s.Tx.Rollback()
|
||||
}
|
||||
|
||||
// Commit implements the Tx interface
|
||||
func (s SQLTx) Commit(ctx context.Context) error {
|
||||
return s.Tx.Commit()
|
||||
}
|
||||
|
||||
var _ ksql.Tx = SQLTx{}
|
||||
|
||||
// SQLRows implements the ksql.Rows interface and is used to help
|
||||
// the SQLAdapter to implement the ksql.DBAdapter interface.
|
||||
type SQLRows struct {
|
||||
*sql.Rows
|
||||
}
|
||||
|
||||
var _ ksql.Rows = SQLRows{}
|
||||
|
||||
// Scan implements the ksql.Rows interface
|
||||
func (p SQLRows) Scan(args ...interface{}) error {
|
||||
err := p.Rows.Scan(args...)
|
||||
if err != nil {
|
||||
// Since this is the error flow we decided it would be ok
|
||||
// to spend a little bit more time parsing this error in order
|
||||
// to produce better error messages.
|
||||
//
|
||||
// If the parsing fails we just return the error unchanged.
|
||||
const scanErrPrefix = "sql: Scan error on column index "
|
||||
var errMsg = err.Error()
|
||||
if strings.HasPrefix(errMsg, scanErrPrefix) {
|
||||
i := len(scanErrPrefix)
|
||||
for unicode.IsDigit(rune(errMsg[i])) {
|
||||
i++
|
||||
}
|
||||
colIndex, convErr := strconv.Atoi(errMsg[len(scanErrPrefix):i])
|
||||
if convErr == nil {
|
||||
return ksql.ScanArgError{
|
||||
ColumnIndex: colIndex,
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
@ -4,5 +4,5 @@ go 1.14
|
||||
|
||||
require (
|
||||
github.com/mattn/go-sqlite3 v1.14.12
|
||||
github.com/vingarcia/ksql v1.4.7
|
||||
github.com/vingarcia/ksql v1.12.3
|
||||
)
|
||||
|
@ -1,24 +1,35 @@
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
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/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/mattn/go-sqlite3 v1.14.12 h1:TJ1bhYJPV44phC+IMu1u2K/i5RriLTPe+yc68XDJ1Z0=
|
||||
github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
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/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/vingarcia/ksql v1.4.7 h1:Gt9uz5ScL/lJxVa9DlA+4QaUWAOaSz1ZjUJDn8neLAI=
|
||||
github.com/vingarcia/ksql v1.4.7/go.mod h1:EVxEK3x6igVSFLDLLaymc25soqn3fSsZ0hrAryKtfCg=
|
||||
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/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.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/vingarcia/ksql v1.12.3 h1:1LVRGW39XPaYltPHNQsvHms+bWHp8e99sxQx+aEXDMQ=
|
||||
github.com/vingarcia/ksql v1.12.3/go.mod h1:DHp/nhVu1nHpBBXH/FRw6JLgIcvcM3+uo2+PfUNdo0g=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
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=
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"database/sql"
|
||||
|
||||
"github.com/vingarcia/ksql"
|
||||
"github.com/vingarcia/ksql/sqldialect"
|
||||
|
||||
// This is imported here so the user don't
|
||||
// have to worry about it when he uses it.
|
||||
@ -13,10 +14,10 @@ import (
|
||||
|
||||
// NewFromSQLDB builds a ksql.DB from a *sql.DB instance
|
||||
func NewFromSQLDB(db *sql.DB) (ksql.DB, error) {
|
||||
return ksql.NewWithAdapter(NewSQLAdapter(db), "sqlite3")
|
||||
return ksql.NewWithAdapter(NewSQLAdapter(db), sqldialect.Sqlite3Dialect{})
|
||||
}
|
||||
|
||||
// New instantiates a new KissSQL client using the "sqlite3" driver
|
||||
// New instantiates a new KSQL client using the "sqlite3" driver
|
||||
func New(
|
||||
_ context.Context,
|
||||
connectionString string,
|
||||
@ -34,5 +35,5 @@ func New(
|
||||
|
||||
db.SetMaxOpenConns(config.MaxOpenConns)
|
||||
|
||||
return ksql.NewWithAdapter(NewSQLAdapter(db), "sqlite3")
|
||||
return ksql.NewWithAdapter(NewSQLAdapter(db), sqldialect.Sqlite3Dialect{})
|
||||
}
|
||||
|
@ -6,10 +6,11 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/vingarcia/ksql"
|
||||
"github.com/vingarcia/ksql/sqldialect"
|
||||
)
|
||||
|
||||
func TestAdapter(t *testing.T) {
|
||||
ksql.RunTestsForAdapter(t, "ksqlite", "sqlite3", "/tmp/ksql.db", func(t *testing.T) (ksql.DBAdapter, io.Closer) {
|
||||
ksql.RunTestsForAdapter(t, "ksqlite3", sqldialect.Sqlite3Dialect{}, "/tmp/ksql.db", func(t *testing.T) (ksql.DBAdapter, io.Closer) {
|
||||
db, err := sql.Open("sqlite3", "/tmp/ksql.db")
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
|
@ -3,6 +3,9 @@ package ksqlite3
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/vingarcia/ksql"
|
||||
)
|
||||
@ -29,7 +32,8 @@ func (s SQLAdapter) ExecContext(ctx context.Context, query string, args ...inter
|
||||
|
||||
// QueryContext implements the DBAdapter interface
|
||||
func (s SQLAdapter) QueryContext(ctx context.Context, query string, args ...interface{}) (ksql.Rows, error) {
|
||||
return s.DB.QueryContext(ctx, query, args...)
|
||||
rows, err := s.DB.QueryContext(ctx, query, args...)
|
||||
return SQLRows{rows}, err
|
||||
}
|
||||
|
||||
// BeginTx implements the Tx interface
|
||||
@ -56,7 +60,8 @@ func (s SQLTx) ExecContext(ctx context.Context, query string, args ...interface{
|
||||
|
||||
// QueryContext implements the Tx interface
|
||||
func (s SQLTx) QueryContext(ctx context.Context, query string, args ...interface{}) (ksql.Rows, error) {
|
||||
return s.Tx.QueryContext(ctx, query, args...)
|
||||
rows, err := s.Tx.QueryContext(ctx, query, args...)
|
||||
return SQLRows{rows}, err
|
||||
}
|
||||
|
||||
// Rollback implements the Tx interface
|
||||
@ -70,3 +75,40 @@ func (s SQLTx) Commit(ctx context.Context) error {
|
||||
}
|
||||
|
||||
var _ ksql.Tx = SQLTx{}
|
||||
|
||||
// SQLRows implements the ksql.Rows interface and is used to help
|
||||
// the SQLAdapter to implement the ksql.DBAdapter interface.
|
||||
type SQLRows struct {
|
||||
*sql.Rows
|
||||
}
|
||||
|
||||
var _ ksql.Rows = SQLRows{}
|
||||
|
||||
// Scan implements the ksql.Rows interface
|
||||
func (p SQLRows) Scan(args ...interface{}) error {
|
||||
err := p.Rows.Scan(args...)
|
||||
if err != nil {
|
||||
// Since this is the error flow we decided it would be ok
|
||||
// to spend a little bit more time parsing this error in order
|
||||
// to produce better error messages.
|
||||
//
|
||||
// If the parsing fails we just return the error unchanged.
|
||||
const scanErrPrefix = "sql: Scan error on column index "
|
||||
var errMsg = err.Error()
|
||||
if strings.HasPrefix(errMsg, scanErrPrefix) {
|
||||
i := len(scanErrPrefix)
|
||||
for unicode.IsDigit(rune(errMsg[i])) {
|
||||
i++
|
||||
}
|
||||
colIndex, convErr := strconv.Atoi(errMsg[len(scanErrPrefix):i])
|
||||
if convErr == nil {
|
||||
return ksql.ScanArgError{
|
||||
ColumnIndex: colIndex,
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
@ -4,18 +4,9 @@ go 1.14
|
||||
|
||||
require (
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
github.com/Microsoft/go-winio v0.5.2 // indirect
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
|
||||
github.com/containerd/continuity v0.2.2 // indirect
|
||||
github.com/denisenkom/go-mssqldb v0.10.0
|
||||
github.com/docker/go-connections v0.4.0 // indirect
|
||||
github.com/gotestyourself/gotestyourself v2.2.0+incompatible // indirect
|
||||
github.com/google/go-cmp v0.5.6 // indirect
|
||||
github.com/lib/pq v1.10.4 // indirect
|
||||
github.com/opencontainers/image-spec v1.0.2 // indirect
|
||||
github.com/opencontainers/runc v1.1.0 // indirect
|
||||
github.com/ory/dockertest v3.3.5+incompatible
|
||||
github.com/vingarcia/ksql v1.4.7
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect
|
||||
gotest.tools v2.2.0+incompatible // indirect
|
||||
github.com/ory/dockertest/v3 v3.10.0
|
||||
github.com/vingarcia/ksql v1.12.3
|
||||
)
|
||||
|
@ -1,230 +1,214 @@
|
||||
bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512/go.mod h1:FbcW6z/2VytnFDhZfumh8Ss8zxHE6qpMP5sHTRe0EaM=
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||
github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
|
||||
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
||||
github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
|
||||
github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4=
|
||||
github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E=
|
||||
github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
|
||||
github.com/containerd/continuity v0.2.2 h1:QSqfxcn8c+12slxwu00AtzXrsami0MJb/MQs9lOLHLA=
|
||||
github.com/containerd/continuity v0.2.2/go.mod h1:pWygW9u7LtS1o4N/Tn0FoCFDIXZ7rxcMX7HX1Dmibvk=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg=
|
||||
github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM=
|
||||
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
|
||||
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
||||
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/denisenkom/go-mssqldb v0.10.0 h1:QykgLZBorFE95+gO3u9esLd0BmbvpWp0/waNNZfHBM8=
|
||||
github.com/denisenkom/go-mssqldb v0.10.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/docker/cli v20.10.17+incompatible h1:eO2KS7ZFeov5UJeaDmIs1NFEDRf32PaqRpvoEkKBy5M=
|
||||
github.com/docker/cli v20.10.17+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/docker v20.10.7+incompatible h1:Z6O9Nhsjv+ayUEeI1IojKbYcsGdgYSNqxe1s2MYzUhQ=
|
||||
github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
|
||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
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.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gotestyourself/gotestyourself v2.2.0+incompatible h1:AQwinXlbQR2HvPjQZOmDhRqsv5mZf+Jb1RnSLxcqZcI=
|
||||
github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
||||
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk=
|
||||
github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
|
||||
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
|
||||
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 h1:rzf0wL0CHVc8CEsgyygG0Mn9CNCCPZqOPaz8RiiHYQk=
|
||||
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc=
|
||||
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
|
||||
github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/opencontainers/runc v1.1.0 h1:O9+X96OcDjkmmZyfaG996kV7yq8HsoU2h1XRRQcefG8=
|
||||
github.com/opencontainers/runc v1.1.0/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc=
|
||||
github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs=
|
||||
github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg=
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
|
||||
github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA=
|
||||
github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/ory/dockertest/v3 v3.10.0 h1:4K3z2VMe8Woe++invjaTB7VRyQXQy5UY+loujO4aNE4=
|
||||
github.com/ory/dockertest/v3 v3.10.0/go.mod h1:nr57ZbRWMqfsdGdFNLHz5jjNdDb7VVFnzAeW1n5N1Lg=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
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/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
|
||||
github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/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/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
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.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/vingarcia/ksql v1.4.7 h1:Gt9uz5ScL/lJxVa9DlA+4QaUWAOaSz1ZjUJDn8neLAI=
|
||||
github.com/vingarcia/ksql v1.4.7/go.mod h1:EVxEK3x6igVSFLDLLaymc25soqn3fSsZ0hrAryKtfCg=
|
||||
github.com/vingarcia/ksql v1.12.3 h1:1LVRGW39XPaYltPHNQsvHms+bWHp8e99sxQx+aEXDMQ=
|
||||
github.com/vingarcia/ksql v1.12.3/go.mod h1:DHp/nhVu1nHpBBXH/FRw6JLgIcvcM3+uo2+PfUNdo0g=
|
||||
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c h1:Vj5n4GlwjmQteupaxJ9+0FNOmBrHfq7vN4btdGoDZgI=
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
|
||||
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220405210540-1e041c57c461/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
|
||||
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||
gotest.tools/v3 v3.3.0 h1:MfDY1b1/0xN1CyMlQDac0ziEy9zJQd9CXBRRDHw2jJo=
|
||||
gotest.tools/v3 v3.3.0/go.mod h1:Mcr9QNxkg0uMvy/YElmo4SpXgJKWgQvYrT7Kw5RzJ1A=
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"database/sql"
|
||||
|
||||
"github.com/vingarcia/ksql"
|
||||
"github.com/vingarcia/ksql/sqldialect"
|
||||
|
||||
// This is imported here so the user don't
|
||||
// have to worry about it when he uses it.
|
||||
@ -13,10 +14,10 @@ import (
|
||||
|
||||
// NewFromSQLDB builds a ksql.DB from a *sql.DB instance
|
||||
func NewFromSQLDB(db *sql.DB) (ksql.DB, error) {
|
||||
return ksql.NewWithAdapter(NewSQLAdapter(db), "sqlserver")
|
||||
return ksql.NewWithAdapter(NewSQLAdapter(db), sqldialect.SqlserverDialect{})
|
||||
}
|
||||
|
||||
// New instantiates a new KissSQL client using the "sqlserver" driver
|
||||
// New instantiates a new KSQL client using the "sqlserver" driver
|
||||
func New(
|
||||
_ context.Context,
|
||||
connectionString string,
|
||||
@ -34,5 +35,5 @@ func New(
|
||||
|
||||
db.SetMaxOpenConns(config.MaxOpenConns)
|
||||
|
||||
return ksql.NewWithAdapter(NewSQLAdapter(db), "sqlserver")
|
||||
return ksql.NewWithAdapter(NewSQLAdapter(db), sqldialect.SqlserverDialect{})
|
||||
}
|
||||
|
@ -8,16 +8,17 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ory/dockertest"
|
||||
"github.com/ory/dockertest/docker"
|
||||
"github.com/ory/dockertest/v3"
|
||||
"github.com/ory/dockertest/v3/docker"
|
||||
"github.com/vingarcia/ksql"
|
||||
"github.com/vingarcia/ksql/sqldialect"
|
||||
)
|
||||
|
||||
func TestAdapter(t *testing.T) {
|
||||
sqlServerURL, closeSQLServer := startSQLServerDB("ksql")
|
||||
defer closeSQLServer()
|
||||
|
||||
ksql.RunTestsForAdapter(t, "ksqlserver", "sqlserver", sqlServerURL, func(t *testing.T) (ksql.DBAdapter, io.Closer) {
|
||||
ksql.RunTestsForAdapter(t, "ksqlserver", sqldialect.SqlserverDialect{}, sqlServerURL, func(t *testing.T) (ksql.DBAdapter, io.Closer) {
|
||||
db, err := sql.Open("sqlserver", sqlServerURL)
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
@ -27,6 +28,8 @@ func TestAdapter(t *testing.T) {
|
||||
}
|
||||
|
||||
func startSQLServerDB(dbName string) (databaseURL string, closer func()) {
|
||||
startTime := time.Now()
|
||||
|
||||
// uses a sensible default on windows (tcp/http) and linux/osx (socket)
|
||||
pool, err := dockertest.NewPool("")
|
||||
if err != nil {
|
||||
@ -63,7 +66,7 @@ func startSQLServerDB(dbName string) (databaseURL string, closer func()) {
|
||||
var sqlDB *sql.DB
|
||||
// exponential backoff-retry, because the application in the container might not be ready to accept connections yet
|
||||
pool.MaxWait = 10 * time.Second
|
||||
pool.Retry(func() error {
|
||||
err = pool.Retry(func() error {
|
||||
sqlDB, err = sql.Open("sqlserver", databaseUrl)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -71,13 +74,18 @@ func startSQLServerDB(dbName string) (databaseURL string, closer func()) {
|
||||
return sqlDB.Ping()
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalf("Could not connect to docker: %s", err)
|
||||
log.Fatalf("Could not connect to docker after %v: %s", time.Since(startTime), err)
|
||||
}
|
||||
sqlDB.Close()
|
||||
|
||||
fmt.Printf("db ready to run in %v", time.Since(startTime))
|
||||
|
||||
// SQLServer keeps failing frequently, lets try to wait a little before returning:
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
|
||||
return databaseUrl, func() {
|
||||
if err := pool.Purge(resource); err != nil {
|
||||
log.Fatalf("Could not purge resource: %s", err)
|
||||
fmt.Printf("Could not purge resource: %s\n", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,9 @@ package ksqlserver
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/vingarcia/ksql"
|
||||
)
|
||||
@ -29,7 +32,8 @@ func (s SQLAdapter) ExecContext(ctx context.Context, query string, args ...inter
|
||||
|
||||
// QueryContext implements the DBAdapter interface
|
||||
func (s SQLAdapter) QueryContext(ctx context.Context, query string, args ...interface{}) (ksql.Rows, error) {
|
||||
return s.DB.QueryContext(ctx, query, args...)
|
||||
rows, err := s.DB.QueryContext(ctx, query, args...)
|
||||
return SQLRows{rows}, err
|
||||
}
|
||||
|
||||
// BeginTx implements the Tx interface
|
||||
@ -56,7 +60,8 @@ func (s SQLTx) ExecContext(ctx context.Context, query string, args ...interface{
|
||||
|
||||
// QueryContext implements the Tx interface
|
||||
func (s SQLTx) QueryContext(ctx context.Context, query string, args ...interface{}) (ksql.Rows, error) {
|
||||
return s.Tx.QueryContext(ctx, query, args...)
|
||||
rows, err := s.Tx.QueryContext(ctx, query, args...)
|
||||
return SQLRows{rows}, err
|
||||
}
|
||||
|
||||
// Rollback implements the Tx interface
|
||||
@ -70,3 +75,40 @@ func (s SQLTx) Commit(ctx context.Context) error {
|
||||
}
|
||||
|
||||
var _ ksql.Tx = SQLTx{}
|
||||
|
||||
// SQLRows implements the ksql.Rows interface and is used to help
|
||||
// the SQLAdapter to implement the ksql.DBAdapter interface.
|
||||
type SQLRows struct {
|
||||
*sql.Rows
|
||||
}
|
||||
|
||||
var _ ksql.Rows = SQLRows{}
|
||||
|
||||
// Scan implements the ksql.Rows interface
|
||||
func (p SQLRows) Scan(args ...interface{}) error {
|
||||
err := p.Rows.Scan(args...)
|
||||
if err != nil {
|
||||
// Since this is the error flow we decided it would be ok
|
||||
// to spend a little bit more time parsing this error in order
|
||||
// to produce better error messages.
|
||||
//
|
||||
// If the parsing fails we just return the error unchanged.
|
||||
const scanErrPrefix = "sql: Scan error on column index "
|
||||
var errMsg = err.Error()
|
||||
if strings.HasPrefix(errMsg, scanErrPrefix) {
|
||||
i := len(scanErrPrefix)
|
||||
for unicode.IsDigit(rune(errMsg[i])) {
|
||||
i++
|
||||
}
|
||||
colIndex, convErr := strconv.Atoi(errMsg[len(scanErrPrefix):i])
|
||||
if convErr == nil {
|
||||
return ksql.ScanArgError{
|
||||
ColumnIndex: colIndex,
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
10
adapters/modernc-ksqlite/go.mod
Normal file
10
adapters/modernc-ksqlite/go.mod
Normal file
@ -0,0 +1,10 @@
|
||||
module github.com/vingarcia/ksql/adapters/modernc-ksqlite
|
||||
|
||||
go 1.14
|
||||
|
||||
require (
|
||||
github.com/vingarcia/ksql v1.12.3
|
||||
golang.org/x/sys v0.7.0 // indirect
|
||||
golang.org/x/tools v0.7.0 // indirect
|
||||
modernc.org/sqlite v1.26.0
|
||||
)
|
154
adapters/modernc-ksqlite/go.sum
Normal file
154
adapters/modernc-ksqlite/go.sum
Normal file
@ -0,0 +1,154 @@
|
||||
github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY=
|
||||
github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic=
|
||||
github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
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/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
|
||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
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/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
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/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
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/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.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/vingarcia/ksql v1.12.3 h1:1LVRGW39XPaYltPHNQsvHms+bWHp8e99sxQx+aEXDMQ=
|
||||
github.com/vingarcia/ksql v1.12.3/go.mod h1:DHp/nhVu1nHpBBXH/FRw6JLgIcvcM3+uo2+PfUNdo0g=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
|
||||
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
|
||||
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
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=
|
||||
lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
||||
lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI=
|
||||
lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
||||
modernc.org/cc/v3 v3.37.0/go.mod h1:vtL+3mdHx/wcj3iEGz84rQa8vEqR6XM84v5Lcvfph20=
|
||||
modernc.org/cc/v3 v3.40.0 h1:P3g79IUS/93SYhtoeaHW+kRCIrYaxJ27MFPv+7kaTOw=
|
||||
modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0=
|
||||
modernc.org/ccgo/v3 v3.0.0-20220904174949-82d86e1b6d56/go.mod h1:YSXjPL62P2AMSxBphRHPn7IkzhVHqkvOnRKAKh+W6ZI=
|
||||
modernc.org/ccgo/v3 v3.16.13-0.20221017192402-261537637ce8/go.mod h1:fUB3Vn0nVPReA+7IG7yZDfjv1TMWjhQP8gCxrFAtL5g=
|
||||
modernc.org/ccgo/v3 v3.16.13 h1:Mkgdzl46i5F/CNR/Kj80Ri59hC8TKAhZrYSaqvkwzUw=
|
||||
modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY=
|
||||
modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk=
|
||||
modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
|
||||
modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM=
|
||||
modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
|
||||
modernc.org/libc v1.17.4/go.mod h1:WNg2ZH56rDEwdropAJeZPQkXmDwh+JCA1s/htl6r2fA=
|
||||
modernc.org/libc v1.20.3/go.mod h1:ZRfIaEkgrYgZDl6pa4W39HgN5G/yDW+NRmNKZBDFrk0=
|
||||
modernc.org/libc v1.21.4/go.mod h1:przBsL5RDOZajTVslkugzLBj1evTue36jEomFQOoYuI=
|
||||
modernc.org/libc v1.22.5/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY=
|
||||
modernc.org/libc v1.24.1 h1:uvJSeCKL/AgzBo2yYIPPTy82v21KgGnizcGYfBHaNuM=
|
||||
modernc.org/libc v1.24.1/go.mod h1:FmfO1RLrU3MHJfyi9eYYmZBfi/R+tqZ6+hQ3yQQUkak=
|
||||
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
|
||||
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/memory v1.3.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
||||
modernc.org/memory v1.4.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
||||
modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
||||
modernc.org/memory v1.6.0 h1:i6mzavxrE9a30whzMfwf7XWVODx2r5OYXvU46cirX7o=
|
||||
modernc.org/memory v1.6.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
||||
modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
|
||||
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/sqlite v1.26.0 h1:SocQdLRSYlA8W99V8YH0NES75thx19d9sB/aFc4R8Lw=
|
||||
modernc.org/sqlite v1.26.0/go.mod h1:FL3pVXie73rg3Rii6V/u5BoHlSoyeZeIgKZEgHARyCU=
|
||||
modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY=
|
||||
modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw=
|
||||
modernc.org/tcl v1.15.2 h1:C4ybAYCGJw968e+Me18oW55kD/FexcHbqH2xak1ROSY=
|
||||
modernc.org/tcl v1.15.2/go.mod h1:3+k/ZaEbKrC8ePv8zJWPtBSW0V7Gg9g8rkmhI1Kfs3c=
|
||||
modernc.org/token v1.0.1 h1:A3qvTqOwexpfZZeyI0FeGPDlSWX5pjZu9hF4lU+EKWg=
|
||||
modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
modernc.org/z v1.7.3 h1:zDJf6iHjrnB+WRD88stbXokugjyc0/pB91ri1gO6LZY=
|
||||
modernc.org/z v1.7.3/go.mod h1:Ipv4tsdxZRbQyLq9Q1M6gdbkxYzdlrciF2Hi/lS7nWE=
|
39
adapters/modernc-ksqlite/ksqlite.go
Normal file
39
adapters/modernc-ksqlite/ksqlite.go
Normal file
@ -0,0 +1,39 @@
|
||||
package ksqlite
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
|
||||
"github.com/vingarcia/ksql"
|
||||
"github.com/vingarcia/ksql/sqldialect"
|
||||
|
||||
// This is imported here so the user don't
|
||||
// have to worry about it when he uses it.
|
||||
_ "modernc.org/sqlite"
|
||||
)
|
||||
|
||||
// NewFromSQLDB builds a ksql.DB from a *sql.DB instance
|
||||
func NewFromSQLDB(db *sql.DB) (ksql.DB, error) {
|
||||
return ksql.NewWithAdapter(NewSQLAdapter(db), sqldialect.Sqlite3Dialect{})
|
||||
}
|
||||
|
||||
// New instantiates a new KSQL client using the "sqlite3" driver
|
||||
func New(
|
||||
_ context.Context,
|
||||
connectionString string,
|
||||
config ksql.Config,
|
||||
) (ksql.DB, error) {
|
||||
config.SetDefaultValues()
|
||||
|
||||
db, err := sql.Open("sqlite", connectionString)
|
||||
if err != nil {
|
||||
return ksql.DB{}, err
|
||||
}
|
||||
if err = db.Ping(); err != nil {
|
||||
return ksql.DB{}, err
|
||||
}
|
||||
|
||||
db.SetMaxOpenConns(config.MaxOpenConns)
|
||||
|
||||
return ksql.NewWithAdapter(NewSQLAdapter(db), sqldialect.Sqlite3Dialect{})
|
||||
}
|
20
adapters/modernc-ksqlite/ksqlite_test.go
Normal file
20
adapters/modernc-ksqlite/ksqlite_test.go
Normal file
@ -0,0 +1,20 @@
|
||||
package ksqlite
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
"github.com/vingarcia/ksql"
|
||||
"github.com/vingarcia/ksql/sqldialect"
|
||||
)
|
||||
|
||||
func TestAdapter(t *testing.T) {
|
||||
ksql.RunTestsForAdapter(t, "modernc-ksqlite", sqldialect.Sqlite3Dialect{}, "/tmp/modernc-ksqlite.db", func(t *testing.T) (ksql.DBAdapter, io.Closer) {
|
||||
db, err := sql.Open("sqlite", "/tmp/modernc-ksqlite.db")
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
return SQLAdapter{db}, db
|
||||
})
|
||||
}
|
114
adapters/modernc-ksqlite/sql_adapter.go
Normal file
114
adapters/modernc-ksqlite/sql_adapter.go
Normal file
@ -0,0 +1,114 @@
|
||||
package ksqlite
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/vingarcia/ksql"
|
||||
)
|
||||
|
||||
// SQLAdapter adapts the sql.DB type to be compatible with the `DBAdapter` interface
|
||||
type SQLAdapter struct {
|
||||
*sql.DB
|
||||
}
|
||||
|
||||
var _ ksql.DBAdapter = SQLAdapter{}
|
||||
|
||||
// NewSQLAdapter returns a new instance of SQLAdapter with
|
||||
// the provided database instance.
|
||||
func NewSQLAdapter(db *sql.DB) SQLAdapter {
|
||||
return SQLAdapter{
|
||||
DB: db,
|
||||
}
|
||||
}
|
||||
|
||||
// ExecContext implements the DBAdapter interface
|
||||
func (s SQLAdapter) ExecContext(ctx context.Context, query string, args ...interface{}) (ksql.Result, error) {
|
||||
return s.DB.ExecContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
// QueryContext implements the DBAdapter interface
|
||||
func (s SQLAdapter) QueryContext(ctx context.Context, query string, args ...interface{}) (ksql.Rows, error) {
|
||||
rows, err := s.DB.QueryContext(ctx, query, args...)
|
||||
return SQLRows{rows}, err
|
||||
}
|
||||
|
||||
// BeginTx implements the Tx interface
|
||||
func (s SQLAdapter) BeginTx(ctx context.Context) (ksql.Tx, error) {
|
||||
tx, err := s.DB.BeginTx(ctx, nil)
|
||||
return SQLTx{Tx: tx}, err
|
||||
}
|
||||
|
||||
// Close implements the io.Closer interface
|
||||
func (s SQLAdapter) Close() error {
|
||||
return s.DB.Close()
|
||||
}
|
||||
|
||||
// SQLTx is used to implement the DBAdapter interface and implements
|
||||
// the Tx interface
|
||||
type SQLTx struct {
|
||||
*sql.Tx
|
||||
}
|
||||
|
||||
// ExecContext implements the Tx interface
|
||||
func (s SQLTx) ExecContext(ctx context.Context, query string, args ...interface{}) (ksql.Result, error) {
|
||||
return s.Tx.ExecContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
// QueryContext implements the Tx interface
|
||||
func (s SQLTx) QueryContext(ctx context.Context, query string, args ...interface{}) (ksql.Rows, error) {
|
||||
rows, err := s.Tx.QueryContext(ctx, query, args...)
|
||||
return SQLRows{rows}, err
|
||||
}
|
||||
|
||||
// Rollback implements the Tx interface
|
||||
func (s SQLTx) Rollback(ctx context.Context) error {
|
||||
return s.Tx.Rollback()
|
||||
}
|
||||
|
||||
// Commit implements the Tx interface
|
||||
func (s SQLTx) Commit(ctx context.Context) error {
|
||||
return s.Tx.Commit()
|
||||
}
|
||||
|
||||
var _ ksql.Tx = SQLTx{}
|
||||
|
||||
// SQLRows implements the ksql.Rows interface and is used to help
|
||||
// the SQLAdapter to implement the ksql.DBAdapter interface.
|
||||
type SQLRows struct {
|
||||
*sql.Rows
|
||||
}
|
||||
|
||||
var _ ksql.Rows = SQLRows{}
|
||||
|
||||
// Scan implements the ksql.Rows interface
|
||||
func (p SQLRows) Scan(args ...interface{}) error {
|
||||
err := p.Rows.Scan(args...)
|
||||
if err != nil {
|
||||
// Since this is the error flow we decided it would be ok
|
||||
// to spend a little bit more time parsing this error in order
|
||||
// to produce better error messages.
|
||||
//
|
||||
// If the parsing fails we just return the error unchanged.
|
||||
const scanErrPrefix = "sql: Scan error on column index "
|
||||
var errMsg = err.Error()
|
||||
if strings.HasPrefix(errMsg, scanErrPrefix) {
|
||||
i := len(scanErrPrefix)
|
||||
for unicode.IsDigit(rune(errMsg[i])) {
|
||||
i++
|
||||
}
|
||||
colIndex, convErr := strconv.Atoi(errMsg[len(scanErrPrefix):i])
|
||||
if convErr == nil {
|
||||
return ksql.ScanArgError{
|
||||
ColumnIndex: colIndex,
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
@ -1,6 +1,28 @@
|
||||
|
||||
GOBIN=$(shell go env GOPATH)/bin
|
||||
|
||||
lint:
|
||||
TIME=1s
|
||||
bench: gen
|
||||
go test -bench=. -benchtime=$(TIME)
|
||||
|
||||
lint: gen
|
||||
@$(GOBIN)/staticcheck ./...
|
||||
@go vet ./...
|
||||
|
||||
gen: sqlcfiles
|
||||
|
||||
sqlcfiles: $(GOBIN)/sqlc sqlc.yaml schema.sql sqlcgen/queries.sql
|
||||
sqlc generate
|
||||
|
||||
# This recipe requires the ksql database to be setup
|
||||
# exactly as described in the `sqlboiler.toml` file, that's
|
||||
# why it is not running automatically before each benchmark.
|
||||
sqlboilerfiles: $(GOBIN)/sqlboiler
|
||||
sqlboiler psql -c sqlboiler.toml --wipe --no-tests
|
||||
|
||||
$(GOBIN)/sqlc:
|
||||
go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest
|
||||
|
||||
$(GOBIN)/sqlboiler:
|
||||
go install github.com/volatiletech/sqlboiler/v4@latest
|
||||
go install github.com/volatiletech/sqlboiler/v4/drivers/sqlboiler-psql@latest
|
||||
|
@ -7,11 +7,18 @@ import (
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
_ "embed"
|
||||
|
||||
"github.com/jackc/pgx/v4/pgxpool"
|
||||
"github.com/jmoiron/sqlx"
|
||||
_ "github.com/lib/pq"
|
||||
"github.com/vingarcia/ksql"
|
||||
"github.com/vingarcia/ksql/adapters/kpgx"
|
||||
"github.com/vingarcia/ksql/benchmarks/sqlboilergen"
|
||||
"github.com/vingarcia/ksql/benchmarks/sqlcgen"
|
||||
"github.com/vingarcia/ksql/sqldialect"
|
||||
"github.com/volatiletech/sqlboiler/v4/boil"
|
||||
"github.com/volatiletech/sqlboiler/v4/queries/qm"
|
||||
"gorm.io/driver/postgres"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
@ -36,7 +43,7 @@ func BenchmarkInsert(b *testing.B) {
|
||||
b.Fatalf("error connecting to database: %s", err)
|
||||
}
|
||||
db.SetMaxOpenConns(1)
|
||||
ksqlDB, err := ksql.NewWithAdapter(NewSQLAdapter(db), driver)
|
||||
ksqlDB, err := ksql.NewWithAdapter(NewSQLAdapter(db), sqldialect.PostgresDialect{})
|
||||
if err != nil {
|
||||
b.Fatalf("error creating ksql client: %s", err)
|
||||
}
|
||||
@ -125,7 +132,7 @@ func BenchmarkInsert(b *testing.B) {
|
||||
})
|
||||
})
|
||||
|
||||
b.Run("sql/prep-statements", func(b *testing.B) {
|
||||
b.Run("sql/prep-stmt", func(b *testing.B) {
|
||||
sqlDB, err := sql.Open(driver, connStr)
|
||||
if err != nil {
|
||||
b.Fatalf("error creating sql client: %s", err)
|
||||
@ -207,6 +214,48 @@ func BenchmarkInsert(b *testing.B) {
|
||||
})
|
||||
})
|
||||
|
||||
b.Run("sqlx/prep-stmt", func(b *testing.B) {
|
||||
sqlxDB, err := sqlx.Open(driver, connStr)
|
||||
if err != nil {
|
||||
b.Fatalf("error creating sqlx client: %s", err)
|
||||
}
|
||||
sqlxDB.SetMaxOpenConns(1)
|
||||
|
||||
err = recreateTable(connStr)
|
||||
if err != nil {
|
||||
b.Fatalf("error creating table: %s", err.Error())
|
||||
}
|
||||
|
||||
insertOne, err := sqlxDB.Prepare(`INSERT INTO users(name, age) VALUES ($1, $2) RETURNING id`)
|
||||
if err != nil {
|
||||
b.Fatalf("could not prepare sql insert query: %s", err.Error())
|
||||
}
|
||||
|
||||
b.Run("insert-one", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
user := User{
|
||||
Name: strconv.Itoa(i),
|
||||
Age: i,
|
||||
}
|
||||
rows, err := insertOne.QueryContext(ctx, user.Name, user.Age)
|
||||
if err != nil {
|
||||
b.Fatalf("insert error: %s", err.Error())
|
||||
}
|
||||
if !rows.Next() {
|
||||
b.Fatalf("missing id from inserted record")
|
||||
}
|
||||
err = rows.Scan(&user.ID)
|
||||
if err != nil {
|
||||
b.Fatalf("error scanning rows")
|
||||
}
|
||||
err = rows.Close()
|
||||
if err != nil {
|
||||
b.Fatalf("error closing rows")
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
b.Run("pgxpool", func(b *testing.B) {
|
||||
pgxConf, err := pgxpool.ParseConfig(connStr)
|
||||
if err != nil {
|
||||
@ -272,6 +321,91 @@ func BenchmarkInsert(b *testing.B) {
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
b.Run("sqlc", func(b *testing.B) {
|
||||
sqlDB, err := sql.Open(driver, connStr)
|
||||
if err != nil {
|
||||
b.Fatalf("error creating sql client: %s", err)
|
||||
}
|
||||
sqlDB.SetMaxOpenConns(1)
|
||||
|
||||
sqlcDB := sqlcgen.New(sqlDB)
|
||||
|
||||
err = recreateTable(connStr)
|
||||
if err != nil {
|
||||
b.Fatalf("error creating table: %s", err.Error())
|
||||
}
|
||||
|
||||
b.Run("insert-one", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
user := sqlcgen.InsertUserParams{
|
||||
Name: strconv.Itoa(i),
|
||||
Age: int32(i),
|
||||
}
|
||||
_, err := sqlcDB.InsertUser(ctx, user)
|
||||
if err != nil {
|
||||
b.Fatalf("insert error: %s", err.Error())
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
b.Run("sqlc/prep-stmt", func(b *testing.B) {
|
||||
sqlDB, err := sql.Open(driver, connStr)
|
||||
if err != nil {
|
||||
b.Fatalf("error creating sql client: %s", err)
|
||||
}
|
||||
sqlDB.SetMaxOpenConns(1)
|
||||
|
||||
sqlcDB, err := sqlcgen.Prepare(ctx, sqlDB)
|
||||
if err != nil {
|
||||
b.Fatalf("error preparing sqlc statements: %s", err)
|
||||
}
|
||||
|
||||
err = recreateTable(connStr)
|
||||
if err != nil {
|
||||
b.Fatalf("error creating table: %s", err.Error())
|
||||
}
|
||||
|
||||
b.Run("insert-one", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
user := sqlcgen.InsertUserParams{
|
||||
Name: strconv.Itoa(i),
|
||||
Age: int32(i),
|
||||
}
|
||||
_, err := sqlcDB.InsertUser(ctx, user)
|
||||
if err != nil {
|
||||
b.Fatalf("insert error: %s", err.Error())
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
b.Run("sqlboiler", func(b *testing.B) {
|
||||
sqlDB, err := sql.Open(driver, connStr)
|
||||
if err != nil {
|
||||
b.Fatalf("error creating sql client: %s", err)
|
||||
}
|
||||
sqlDB.SetMaxOpenConns(1)
|
||||
|
||||
err = recreateTable(connStr)
|
||||
if err != nil {
|
||||
b.Fatalf("error creating table: %s", err.Error())
|
||||
}
|
||||
|
||||
b.Run("insert-one", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
user := sqlboilergen.User{
|
||||
Name: strconv.Itoa(i),
|
||||
Age: i,
|
||||
}
|
||||
err := user.Insert(ctx, sqlDB, boil.Infer())
|
||||
if err != nil {
|
||||
b.Fatalf("insert error: %s", err.Error())
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkQuery(b *testing.B) {
|
||||
@ -292,7 +426,7 @@ func BenchmarkQuery(b *testing.B) {
|
||||
b.Fatalf("error connecting to database: %s", err)
|
||||
}
|
||||
db.SetMaxOpenConns(1)
|
||||
ksqlDB, err := ksql.NewWithAdapter(NewSQLAdapter(db), driver)
|
||||
ksqlDB, err := ksql.NewWithAdapter(NewSQLAdapter(db), sqldialect.PostgresDialect{})
|
||||
if err != nil {
|
||||
b.Fatalf("error creating ksql client: %s", err)
|
||||
}
|
||||
@ -441,7 +575,7 @@ func BenchmarkQuery(b *testing.B) {
|
||||
})
|
||||
})
|
||||
|
||||
b.Run("sql/prep-statements", func(b *testing.B) {
|
||||
b.Run("sql/prep-stmt", func(b *testing.B) {
|
||||
sqlDB, err := sql.Open(driver, connStr)
|
||||
if err != nil {
|
||||
b.Fatalf("error creating sql client: %s", err)
|
||||
@ -587,6 +721,84 @@ func BenchmarkQuery(b *testing.B) {
|
||||
})
|
||||
})
|
||||
|
||||
b.Run("sqlx/prep-stmt", func(b *testing.B) {
|
||||
sqlxDB, err := sqlx.Open(driver, connStr)
|
||||
if err != nil {
|
||||
b.Fatalf("error creating sqlx client: %s", err)
|
||||
}
|
||||
sqlxDB.SetMaxOpenConns(1)
|
||||
|
||||
err = recreateTable(connStr)
|
||||
if err != nil {
|
||||
b.Fatalf("error creating table: %s", err.Error())
|
||||
}
|
||||
|
||||
err = insertUsers(connStr, 100)
|
||||
if err != nil {
|
||||
b.Fatalf("error inserting users: %s", err.Error())
|
||||
}
|
||||
|
||||
singleRow, err := sqlxDB.Preparex(`SELECT id, name, age FROM users OFFSET $1 LIMIT 1`)
|
||||
if err != nil {
|
||||
b.Fatalf("error preparing sql statement for single row: %s", err.Error())
|
||||
}
|
||||
|
||||
multipleRows, err := sqlxDB.Preparex(`SELECT id, name, age FROM users OFFSET $1 LIMIT 10`)
|
||||
if err != nil {
|
||||
b.Fatalf("error preparing sql statement for multiple rows: %s", err.Error())
|
||||
}
|
||||
|
||||
b.Run("single-row", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
var user User
|
||||
rows, err := singleRow.QueryxContext(ctx, i%100)
|
||||
if err != nil {
|
||||
b.Fatalf("query error: %s", err.Error())
|
||||
}
|
||||
if !rows.Next() {
|
||||
b.Fatalf("missing user from inserted record, offset: %d", i%100)
|
||||
}
|
||||
err = rows.StructScan(&user)
|
||||
if err != nil {
|
||||
b.Fatalf("error scanning rows")
|
||||
}
|
||||
err = rows.Close()
|
||||
if err != nil {
|
||||
b.Fatalf("error closing rows")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
b.Run("multiple-rows", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
var users []User
|
||||
rows, err := multipleRows.QueryxContext(ctx, i%90)
|
||||
if err != nil {
|
||||
b.Fatalf("query error: %s", err.Error())
|
||||
}
|
||||
for j := 0; j < 10; j++ {
|
||||
if !rows.Next() {
|
||||
b.Fatalf("missing user from inserted record, offset: %d", i%90)
|
||||
}
|
||||
var user User
|
||||
rows.StructScan(&user)
|
||||
if err != nil {
|
||||
b.Fatalf("error scanning rows")
|
||||
}
|
||||
users = append(users, user)
|
||||
}
|
||||
if len(users) < 10 {
|
||||
b.Fatalf("expected 10 scanned users, but got: %d", len(users))
|
||||
}
|
||||
|
||||
err = rows.Close()
|
||||
if err != nil {
|
||||
b.Fatalf("error closing rows")
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
b.Run("pgxpool", func(b *testing.B) {
|
||||
pgxConf, err := pgxpool.ParseConfig(connStr)
|
||||
if err != nil {
|
||||
@ -693,8 +905,126 @@ func BenchmarkQuery(b *testing.B) {
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
b.Run("sqlc", func(b *testing.B) {
|
||||
sqlDB, err := sql.Open(driver, connStr)
|
||||
if err != nil {
|
||||
b.Fatalf("error creating sql client: %s", err)
|
||||
}
|
||||
sqlDB.SetMaxOpenConns(1)
|
||||
|
||||
sqlcDB := sqlcgen.New(sqlDB)
|
||||
|
||||
err = recreateTable(connStr)
|
||||
if err != nil {
|
||||
b.Fatalf("error creating table: %s", err.Error())
|
||||
}
|
||||
|
||||
err = insertUsers(connStr, 100)
|
||||
if err != nil {
|
||||
b.Fatalf("error inserting users: %s", err.Error())
|
||||
}
|
||||
|
||||
b.Run("single-row", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err := sqlcDB.GetUser(ctx, int32(i%100))
|
||||
if err != nil {
|
||||
b.Fatalf("query error: %s", err.Error())
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
b.Run("multiple-rows", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err := sqlcDB.List10Users(ctx, int32(i%90))
|
||||
if err != nil {
|
||||
b.Fatalf("query error: %s", err.Error())
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
b.Run("sqlc/prep-stmt", func(b *testing.B) {
|
||||
sqlDB, err := sql.Open(driver, connStr)
|
||||
if err != nil {
|
||||
b.Fatalf("error creating sql client: %s", err)
|
||||
}
|
||||
sqlDB.SetMaxOpenConns(1)
|
||||
|
||||
sqlcDB, err := sqlcgen.Prepare(ctx, sqlDB)
|
||||
if err != nil {
|
||||
b.Fatalf("error preparing sqlc statements: %s", err)
|
||||
}
|
||||
|
||||
err = recreateTable(connStr)
|
||||
if err != nil {
|
||||
b.Fatalf("error creating table: %s", err.Error())
|
||||
}
|
||||
|
||||
err = insertUsers(connStr, 100)
|
||||
if err != nil {
|
||||
b.Fatalf("error inserting users: %s", err.Error())
|
||||
}
|
||||
|
||||
b.Run("single-row", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err := sqlcDB.GetUser(ctx, int32(i%100))
|
||||
if err != nil {
|
||||
b.Fatalf("query error: %s", err.Error())
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
b.Run("multiple-rows", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err := sqlcDB.List10Users(ctx, int32(i%90))
|
||||
if err != nil {
|
||||
b.Fatalf("query error: %s", err.Error())
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
b.Run("sqlboiler", func(b *testing.B) {
|
||||
sqlDB, err := sql.Open(driver, connStr)
|
||||
if err != nil {
|
||||
b.Fatalf("error creating sql client: %s", err)
|
||||
}
|
||||
sqlDB.SetMaxOpenConns(1)
|
||||
|
||||
err = recreateTable(connStr)
|
||||
if err != nil {
|
||||
b.Fatalf("error creating table: %s", err.Error())
|
||||
}
|
||||
|
||||
err = insertUsers(connStr, 100)
|
||||
if err != nil {
|
||||
b.Fatalf("error inserting users: %s", err.Error())
|
||||
}
|
||||
|
||||
b.Run("single-row", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err := sqlboilergen.Users(qm.Select("id", "name", "age"), qm.Offset(i%100), qm.Limit(1)).One(ctx, sqlDB)
|
||||
if err != nil {
|
||||
b.Fatalf("query error: %s", err.Error())
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
b.Run("multiple-rows", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err := sqlboilergen.Users(qm.Select("id", "name", "age"), qm.Offset(i%90), qm.Limit(10)).One(ctx, sqlDB)
|
||||
if err != nil {
|
||||
b.Fatalf("query error: %s", err.Error())
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
//go:embed schema.sql
|
||||
var createTablesSQL string
|
||||
|
||||
func recreateTable(connStr string) error {
|
||||
db, err := sql.Open("postgres", connStr)
|
||||
if err != nil {
|
||||
@ -704,11 +1034,7 @@ func recreateTable(connStr string) error {
|
||||
|
||||
db.Exec(`DROP TABLE users`)
|
||||
|
||||
_, err = db.Exec(`CREATE TABLE users (
|
||||
id serial PRIMARY KEY,
|
||||
age INT,
|
||||
name VARCHAR(50)
|
||||
)`)
|
||||
_, err = db.Exec(createTablesSQL)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create new users table: %s", err.Error())
|
||||
}
|
||||
|
@ -1,17 +1,47 @@
|
||||
module github.com/vingarcia/ksql/benchmarks
|
||||
|
||||
go 1.14
|
||||
go 1.22
|
||||
|
||||
toolchain go1.22.1
|
||||
|
||||
require (
|
||||
github.com/jackc/pgx/v4 v4.13.0
|
||||
github.com/friendsofgo/errors v0.9.2
|
||||
github.com/jackc/pgx/v4 v4.18.1
|
||||
github.com/jmoiron/sqlx v1.3.4
|
||||
github.com/lib/pq v1.10.4
|
||||
github.com/vingarcia/ksql v1.4.7
|
||||
github.com/lib/pq v1.10.9
|
||||
github.com/vingarcia/ksql v1.12.3
|
||||
github.com/vingarcia/ksql/adapters/kpgx v0.0.0-00010101000000-000000000000
|
||||
github.com/volatiletech/sqlboiler/v4 v4.12.0
|
||||
github.com/volatiletech/strmangle v0.0.4
|
||||
gorm.io/driver/postgres v1.2.2
|
||||
gorm.io/gorm v1.22.3
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/go-sql-driver/mysql v1.8.1 // indirect
|
||||
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
|
||||
github.com/jackc/pgconn v1.14.1 // indirect
|
||||
github.com/jackc/pgio v1.0.0 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgproto3/v2 v2.3.2 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||
github.com/jackc/pgtype v1.14.0 // indirect
|
||||
github.com/jackc/puddle v1.3.0 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.2 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.12 // indirect
|
||||
github.com/ory/dockertest/v3 v3.11.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/spf13/cast v1.4.1 // indirect
|
||||
github.com/stretchr/testify v1.9.0 // indirect
|
||||
github.com/volatiletech/inflect v0.0.1 // indirect
|
||||
golang.org/x/crypto v0.27.0 // indirect
|
||||
golang.org/x/text v0.18.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
replace (
|
||||
github.com/vingarcia/ksql => ../
|
||||
github.com/vingarcia/ksql/adapters/kpgx => ../adapters/kpgx/
|
||||
|
File diff suppressed because it is too large
Load Diff
6
benchmarks/schema.sql
Normal file
6
benchmarks/schema.sql
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
CREATE TABLE users (
|
||||
id serial PRIMARY KEY,
|
||||
name VARCHAR(50) NOT NULL,
|
||||
age INT NOT NULL
|
||||
);
|
14
benchmarks/sqlboiler.toml
Normal file
14
benchmarks/sqlboiler.toml
Normal file
@ -0,0 +1,14 @@
|
||||
output = "sqlboilergen"
|
||||
pkgname = "sqlboilergen"
|
||||
wipe = true
|
||||
no-tests = true
|
||||
add-enum-types = true
|
||||
|
||||
[psql]
|
||||
dbname = "ksql"
|
||||
host = "localhost"
|
||||
port = 5432
|
||||
user = "postgres"
|
||||
pass = "postgres"
|
||||
blacklist = ["migrations", "other"]
|
||||
sslmode = "disable"
|
33
benchmarks/sqlboilergen/boil_queries.go
Normal file
33
benchmarks/sqlboilergen/boil_queries.go
Normal file
@ -0,0 +1,33 @@
|
||||
// Code generated by SQLBoiler 4.12.0 (https://github.com/volatiletech/sqlboiler). DO NOT EDIT.
|
||||
// This file is meant to be re-generated in place and/or deleted at any time.
|
||||
|
||||
package sqlboilergen
|
||||
|
||||
import (
|
||||
"github.com/volatiletech/sqlboiler/v4/drivers"
|
||||
"github.com/volatiletech/sqlboiler/v4/queries"
|
||||
"github.com/volatiletech/sqlboiler/v4/queries/qm"
|
||||
)
|
||||
|
||||
var dialect = drivers.Dialect{
|
||||
LQ: 0x22,
|
||||
RQ: 0x22,
|
||||
|
||||
UseIndexPlaceholders: true,
|
||||
UseLastInsertID: false,
|
||||
UseSchema: false,
|
||||
UseDefaultKeyword: true,
|
||||
UseAutoColumns: false,
|
||||
UseTopClause: false,
|
||||
UseOutputClause: false,
|
||||
UseCaseWhenExistsClause: false,
|
||||
}
|
||||
|
||||
// NewQuery initializes a new Query using the passed in QueryMods
|
||||
func NewQuery(mods ...qm.QueryMod) *queries.Query {
|
||||
q := &queries.Query{}
|
||||
queries.SetDialect(q, &dialect)
|
||||
qm.Apply(q, mods...)
|
||||
|
||||
return q
|
||||
}
|
12
benchmarks/sqlboilergen/boil_table_names.go
Normal file
12
benchmarks/sqlboilergen/boil_table_names.go
Normal file
@ -0,0 +1,12 @@
|
||||
// Code generated by SQLBoiler 4.12.0 (https://github.com/volatiletech/sqlboiler). DO NOT EDIT.
|
||||
// This file is meant to be re-generated in place and/or deleted at any time.
|
||||
|
||||
package sqlboilergen
|
||||
|
||||
var TableNames = struct {
|
||||
Users string
|
||||
UsersPermissions string
|
||||
}{
|
||||
Users: "users",
|
||||
UsersPermissions: "users_permissions",
|
||||
}
|
52
benchmarks/sqlboilergen/boil_types.go
Normal file
52
benchmarks/sqlboilergen/boil_types.go
Normal file
@ -0,0 +1,52 @@
|
||||
// Code generated by SQLBoiler 4.12.0 (https://github.com/volatiletech/sqlboiler). DO NOT EDIT.
|
||||
// This file is meant to be re-generated in place and/or deleted at any time.
|
||||
|
||||
package sqlboilergen
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/friendsofgo/errors"
|
||||
"github.com/volatiletech/sqlboiler/v4/boil"
|
||||
"github.com/volatiletech/strmangle"
|
||||
)
|
||||
|
||||
// M type is for providing columns and column values to UpdateAll.
|
||||
type M map[string]interface{}
|
||||
|
||||
// ErrSyncFail occurs during insert when the record could not be retrieved in
|
||||
// order to populate default value information. This usually happens when LastInsertId
|
||||
// fails or there was a primary key configuration that was not resolvable.
|
||||
var ErrSyncFail = errors.New("sqlboilergen: failed to synchronize data after insert")
|
||||
|
||||
type insertCache struct {
|
||||
query string
|
||||
retQuery string
|
||||
valueMapping []uint64
|
||||
retMapping []uint64
|
||||
}
|
||||
|
||||
type updateCache struct {
|
||||
query string
|
||||
valueMapping []uint64
|
||||
}
|
||||
|
||||
func makeCacheKey(cols boil.Columns, nzDefaults []string) string {
|
||||
buf := strmangle.GetBuffer()
|
||||
|
||||
buf.WriteString(strconv.Itoa(cols.Kind))
|
||||
for _, w := range cols.Cols {
|
||||
buf.WriteString(w)
|
||||
}
|
||||
|
||||
if len(nzDefaults) != 0 {
|
||||
buf.WriteByte('.')
|
||||
}
|
||||
for _, nz := range nzDefaults {
|
||||
buf.WriteString(nz)
|
||||
}
|
||||
|
||||
str := buf.String()
|
||||
strmangle.PutBuffer(buf)
|
||||
return str
|
||||
}
|
7
benchmarks/sqlboilergen/boil_view_names.go
Normal file
7
benchmarks/sqlboilergen/boil_view_names.go
Normal file
@ -0,0 +1,7 @@
|
||||
// Code generated by SQLBoiler 4.12.0 (https://github.com/volatiletech/sqlboiler). DO NOT EDIT.
|
||||
// This file is meant to be re-generated in place and/or deleted at any time.
|
||||
|
||||
package sqlboilergen
|
||||
|
||||
var ViewNames = struct {
|
||||
}{}
|
61
benchmarks/sqlboilergen/psql_upsert.go
Normal file
61
benchmarks/sqlboilergen/psql_upsert.go
Normal file
@ -0,0 +1,61 @@
|
||||
// Code generated by SQLBoiler 4.12.0 (https://github.com/volatiletech/sqlboiler). DO NOT EDIT.
|
||||
// This file is meant to be re-generated in place and/or deleted at any time.
|
||||
|
||||
package sqlboilergen
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/volatiletech/sqlboiler/v4/drivers"
|
||||
"github.com/volatiletech/strmangle"
|
||||
)
|
||||
|
||||
// buildUpsertQueryPostgres builds a SQL statement string using the upsertData provided.
|
||||
func buildUpsertQueryPostgres(dia drivers.Dialect, tableName string, updateOnConflict bool, ret, update, conflict, whitelist []string) string {
|
||||
conflict = strmangle.IdentQuoteSlice(dia.LQ, dia.RQ, conflict)
|
||||
whitelist = strmangle.IdentQuoteSlice(dia.LQ, dia.RQ, whitelist)
|
||||
ret = strmangle.IdentQuoteSlice(dia.LQ, dia.RQ, ret)
|
||||
|
||||
buf := strmangle.GetBuffer()
|
||||
defer strmangle.PutBuffer(buf)
|
||||
|
||||
columns := "DEFAULT VALUES"
|
||||
if len(whitelist) != 0 {
|
||||
columns = fmt.Sprintf("(%s) VALUES (%s)",
|
||||
strings.Join(whitelist, ", "),
|
||||
strmangle.Placeholders(dia.UseIndexPlaceholders, len(whitelist), 1, 1))
|
||||
}
|
||||
|
||||
fmt.Fprintf(
|
||||
buf,
|
||||
"INSERT INTO %s %s ON CONFLICT ",
|
||||
tableName,
|
||||
columns,
|
||||
)
|
||||
|
||||
if !updateOnConflict || len(update) == 0 {
|
||||
buf.WriteString("DO NOTHING")
|
||||
} else {
|
||||
buf.WriteByte('(')
|
||||
buf.WriteString(strings.Join(conflict, ", "))
|
||||
buf.WriteString(") DO UPDATE SET ")
|
||||
|
||||
for i, v := range update {
|
||||
if i != 0 {
|
||||
buf.WriteByte(',')
|
||||
}
|
||||
quoted := strmangle.IdentQuote(dia.LQ, dia.RQ, v)
|
||||
buf.WriteString(quoted)
|
||||
buf.WriteString(" = EXCLUDED.")
|
||||
buf.WriteString(quoted)
|
||||
}
|
||||
}
|
||||
|
||||
if len(ret) != 0 {
|
||||
buf.WriteString(" RETURNING ")
|
||||
buf.WriteString(strings.Join(ret, ", "))
|
||||
}
|
||||
|
||||
return buf.String()
|
||||
}
|
943
benchmarks/sqlboilergen/users.go
Normal file
943
benchmarks/sqlboilergen/users.go
Normal file
@ -0,0 +1,943 @@
|
||||
// Code generated by SQLBoiler 4.12.0 (https://github.com/volatiletech/sqlboiler). DO NOT EDIT.
|
||||
// This file is meant to be re-generated in place and/or deleted at any time.
|
||||
|
||||
package sqlboilergen
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/friendsofgo/errors"
|
||||
"github.com/volatiletech/sqlboiler/v4/boil"
|
||||
"github.com/volatiletech/sqlboiler/v4/queries"
|
||||
"github.com/volatiletech/sqlboiler/v4/queries/qm"
|
||||
"github.com/volatiletech/sqlboiler/v4/queries/qmhelper"
|
||||
"github.com/volatiletech/strmangle"
|
||||
)
|
||||
|
||||
// User is an object representing the database table.
|
||||
type User struct {
|
||||
ID int `boil:"id" json:"id" toml:"id" yaml:"id"`
|
||||
Age int `boil:"age" json:"age" toml:"age" yaml:"age"`
|
||||
Name string `boil:"name" json:"name" toml:"name" yaml:"name"`
|
||||
|
||||
R *userR `boil:"-" json:"-" toml:"-" yaml:"-"`
|
||||
L userL `boil:"-" json:"-" toml:"-" yaml:"-"`
|
||||
}
|
||||
|
||||
var UserColumns = struct {
|
||||
ID string
|
||||
Age string
|
||||
Name string
|
||||
}{
|
||||
ID: "id",
|
||||
Age: "age",
|
||||
Name: "name",
|
||||
}
|
||||
|
||||
var UserTableColumns = struct {
|
||||
ID string
|
||||
Age string
|
||||
Name string
|
||||
}{
|
||||
ID: "users.id",
|
||||
Age: "users.age",
|
||||
Name: "users.name",
|
||||
}
|
||||
|
||||
// Generated where
|
||||
|
||||
type whereHelperint struct{ field string }
|
||||
|
||||
func (w whereHelperint) EQ(x int) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.EQ, x) }
|
||||
func (w whereHelperint) NEQ(x int) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.NEQ, x) }
|
||||
func (w whereHelperint) LT(x int) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.LT, x) }
|
||||
func (w whereHelperint) LTE(x int) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.LTE, x) }
|
||||
func (w whereHelperint) GT(x int) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.GT, x) }
|
||||
func (w whereHelperint) GTE(x int) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.GTE, x) }
|
||||
func (w whereHelperint) IN(slice []int) qm.QueryMod {
|
||||
values := make([]interface{}, 0, len(slice))
|
||||
for _, value := range slice {
|
||||
values = append(values, value)
|
||||
}
|
||||
return qm.WhereIn(fmt.Sprintf("%s IN ?", w.field), values...)
|
||||
}
|
||||
func (w whereHelperint) NIN(slice []int) qm.QueryMod {
|
||||
values := make([]interface{}, 0, len(slice))
|
||||
for _, value := range slice {
|
||||
values = append(values, value)
|
||||
}
|
||||
return qm.WhereNotIn(fmt.Sprintf("%s NOT IN ?", w.field), values...)
|
||||
}
|
||||
|
||||
type whereHelperstring struct{ field string }
|
||||
|
||||
func (w whereHelperstring) EQ(x string) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.EQ, x) }
|
||||
func (w whereHelperstring) NEQ(x string) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.NEQ, x) }
|
||||
func (w whereHelperstring) LT(x string) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.LT, x) }
|
||||
func (w whereHelperstring) LTE(x string) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.LTE, x) }
|
||||
func (w whereHelperstring) GT(x string) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.GT, x) }
|
||||
func (w whereHelperstring) GTE(x string) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.GTE, x) }
|
||||
func (w whereHelperstring) IN(slice []string) qm.QueryMod {
|
||||
values := make([]interface{}, 0, len(slice))
|
||||
for _, value := range slice {
|
||||
values = append(values, value)
|
||||
}
|
||||
return qm.WhereIn(fmt.Sprintf("%s IN ?", w.field), values...)
|
||||
}
|
||||
func (w whereHelperstring) NIN(slice []string) qm.QueryMod {
|
||||
values := make([]interface{}, 0, len(slice))
|
||||
for _, value := range slice {
|
||||
values = append(values, value)
|
||||
}
|
||||
return qm.WhereNotIn(fmt.Sprintf("%s NOT IN ?", w.field), values...)
|
||||
}
|
||||
|
||||
var UserWhere = struct {
|
||||
ID whereHelperint
|
||||
Age whereHelperint
|
||||
Name whereHelperstring
|
||||
}{
|
||||
ID: whereHelperint{field: "\"users\".\"id\""},
|
||||
Age: whereHelperint{field: "\"users\".\"age\""},
|
||||
Name: whereHelperstring{field: "\"users\".\"name\""},
|
||||
}
|
||||
|
||||
// UserRels is where relationship names are stored.
|
||||
var UserRels = struct {
|
||||
}{}
|
||||
|
||||
// userR is where relationships are stored.
|
||||
type userR struct {
|
||||
}
|
||||
|
||||
// NewStruct creates a new relationship struct
|
||||
func (*userR) NewStruct() *userR {
|
||||
return &userR{}
|
||||
}
|
||||
|
||||
// userL is where Load methods for each relationship are stored.
|
||||
type userL struct{}
|
||||
|
||||
var (
|
||||
userAllColumns = []string{"id", "age", "name"}
|
||||
userColumnsWithoutDefault = []string{"age", "name"}
|
||||
userColumnsWithDefault = []string{"id"}
|
||||
userPrimaryKeyColumns = []string{"id"}
|
||||
userGeneratedColumns = []string{}
|
||||
)
|
||||
|
||||
type (
|
||||
// UserSlice is an alias for a slice of pointers to User.
|
||||
// This should almost always be used instead of []User.
|
||||
UserSlice []*User
|
||||
// UserHook is the signature for custom User hook methods
|
||||
UserHook func(context.Context, boil.ContextExecutor, *User) error
|
||||
|
||||
userQuery struct {
|
||||
*queries.Query
|
||||
}
|
||||
)
|
||||
|
||||
// Cache for insert, update and upsert
|
||||
var (
|
||||
userType = reflect.TypeOf(&User{})
|
||||
userMapping = queries.MakeStructMapping(userType)
|
||||
userPrimaryKeyMapping, _ = queries.BindMapping(userType, userMapping, userPrimaryKeyColumns)
|
||||
userInsertCacheMut sync.RWMutex
|
||||
userInsertCache = make(map[string]insertCache)
|
||||
userUpdateCacheMut sync.RWMutex
|
||||
userUpdateCache = make(map[string]updateCache)
|
||||
userUpsertCacheMut sync.RWMutex
|
||||
userUpsertCache = make(map[string]insertCache)
|
||||
)
|
||||
|
||||
var (
|
||||
// Force time package dependency for automated UpdatedAt/CreatedAt.
|
||||
_ = time.Second
|
||||
// Force qmhelper dependency for where clause generation (which doesn't
|
||||
// always happen)
|
||||
_ = qmhelper.Where
|
||||
)
|
||||
|
||||
var userAfterSelectHooks []UserHook
|
||||
|
||||
var userBeforeInsertHooks []UserHook
|
||||
var userAfterInsertHooks []UserHook
|
||||
|
||||
var userBeforeUpdateHooks []UserHook
|
||||
var userAfterUpdateHooks []UserHook
|
||||
|
||||
var userBeforeDeleteHooks []UserHook
|
||||
var userAfterDeleteHooks []UserHook
|
||||
|
||||
var userBeforeUpsertHooks []UserHook
|
||||
var userAfterUpsertHooks []UserHook
|
||||
|
||||
// doAfterSelectHooks executes all "after Select" hooks.
|
||||
func (o *User) doAfterSelectHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range userAfterSelectHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// doBeforeInsertHooks executes all "before insert" hooks.
|
||||
func (o *User) doBeforeInsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range userBeforeInsertHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// doAfterInsertHooks executes all "after Insert" hooks.
|
||||
func (o *User) doAfterInsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range userAfterInsertHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// doBeforeUpdateHooks executes all "before Update" hooks.
|
||||
func (o *User) doBeforeUpdateHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range userBeforeUpdateHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// doAfterUpdateHooks executes all "after Update" hooks.
|
||||
func (o *User) doAfterUpdateHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range userAfterUpdateHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// doBeforeDeleteHooks executes all "before Delete" hooks.
|
||||
func (o *User) doBeforeDeleteHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range userBeforeDeleteHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// doAfterDeleteHooks executes all "after Delete" hooks.
|
||||
func (o *User) doAfterDeleteHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range userAfterDeleteHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// doBeforeUpsertHooks executes all "before Upsert" hooks.
|
||||
func (o *User) doBeforeUpsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range userBeforeUpsertHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// doAfterUpsertHooks executes all "after Upsert" hooks.
|
||||
func (o *User) doAfterUpsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range userAfterUpsertHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddUserHook registers your hook function for all future operations.
|
||||
func AddUserHook(hookPoint boil.HookPoint, userHook UserHook) {
|
||||
switch hookPoint {
|
||||
case boil.AfterSelectHook:
|
||||
userAfterSelectHooks = append(userAfterSelectHooks, userHook)
|
||||
case boil.BeforeInsertHook:
|
||||
userBeforeInsertHooks = append(userBeforeInsertHooks, userHook)
|
||||
case boil.AfterInsertHook:
|
||||
userAfterInsertHooks = append(userAfterInsertHooks, userHook)
|
||||
case boil.BeforeUpdateHook:
|
||||
userBeforeUpdateHooks = append(userBeforeUpdateHooks, userHook)
|
||||
case boil.AfterUpdateHook:
|
||||
userAfterUpdateHooks = append(userAfterUpdateHooks, userHook)
|
||||
case boil.BeforeDeleteHook:
|
||||
userBeforeDeleteHooks = append(userBeforeDeleteHooks, userHook)
|
||||
case boil.AfterDeleteHook:
|
||||
userAfterDeleteHooks = append(userAfterDeleteHooks, userHook)
|
||||
case boil.BeforeUpsertHook:
|
||||
userBeforeUpsertHooks = append(userBeforeUpsertHooks, userHook)
|
||||
case boil.AfterUpsertHook:
|
||||
userAfterUpsertHooks = append(userAfterUpsertHooks, userHook)
|
||||
}
|
||||
}
|
||||
|
||||
// One returns a single user record from the query.
|
||||
func (q userQuery) One(ctx context.Context, exec boil.ContextExecutor) (*User, error) {
|
||||
o := &User{}
|
||||
|
||||
queries.SetLimit(q.Query, 1)
|
||||
|
||||
err := q.Bind(ctx, exec, o)
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return nil, sql.ErrNoRows
|
||||
}
|
||||
return nil, errors.Wrap(err, "sqlboilergen: failed to execute a one query for users")
|
||||
}
|
||||
|
||||
if err := o.doAfterSelectHooks(ctx, exec); err != nil {
|
||||
return o, err
|
||||
}
|
||||
|
||||
return o, nil
|
||||
}
|
||||
|
||||
// All returns all User records from the query.
|
||||
func (q userQuery) All(ctx context.Context, exec boil.ContextExecutor) (UserSlice, error) {
|
||||
var o []*User
|
||||
|
||||
err := q.Bind(ctx, exec, &o)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "sqlboilergen: failed to assign all query results to User slice")
|
||||
}
|
||||
|
||||
if len(userAfterSelectHooks) != 0 {
|
||||
for _, obj := range o {
|
||||
if err := obj.doAfterSelectHooks(ctx, exec); err != nil {
|
||||
return o, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return o, nil
|
||||
}
|
||||
|
||||
// Count returns the count of all User records in the query.
|
||||
func (q userQuery) Count(ctx context.Context, exec boil.ContextExecutor) (int64, error) {
|
||||
var count int64
|
||||
|
||||
queries.SetSelect(q.Query, nil)
|
||||
queries.SetCount(q.Query)
|
||||
|
||||
err := q.Query.QueryRowContext(ctx, exec).Scan(&count)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "sqlboilergen: failed to count users rows")
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// Exists checks if the row exists in the table.
|
||||
func (q userQuery) Exists(ctx context.Context, exec boil.ContextExecutor) (bool, error) {
|
||||
var count int64
|
||||
|
||||
queries.SetSelect(q.Query, nil)
|
||||
queries.SetCount(q.Query)
|
||||
queries.SetLimit(q.Query, 1)
|
||||
|
||||
err := q.Query.QueryRowContext(ctx, exec).Scan(&count)
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "sqlboilergen: failed to check if users exists")
|
||||
}
|
||||
|
||||
return count > 0, nil
|
||||
}
|
||||
|
||||
// Users retrieves all the records using an executor.
|
||||
func Users(mods ...qm.QueryMod) userQuery {
|
||||
mods = append(mods, qm.From("\"users\""))
|
||||
q := NewQuery(mods...)
|
||||
if len(queries.GetSelect(q)) == 0 {
|
||||
queries.SetSelect(q, []string{"\"users\".*"})
|
||||
}
|
||||
|
||||
return userQuery{q}
|
||||
}
|
||||
|
||||
// FindUser retrieves a single record by ID with an executor.
|
||||
// If selectCols is empty Find will return all columns.
|
||||
func FindUser(ctx context.Context, exec boil.ContextExecutor, iD int, selectCols ...string) (*User, error) {
|
||||
userObj := &User{}
|
||||
|
||||
sel := "*"
|
||||
if len(selectCols) > 0 {
|
||||
sel = strings.Join(strmangle.IdentQuoteSlice(dialect.LQ, dialect.RQ, selectCols), ",")
|
||||
}
|
||||
query := fmt.Sprintf(
|
||||
"select %s from \"users\" where \"id\"=$1", sel,
|
||||
)
|
||||
|
||||
q := queries.Raw(query, iD)
|
||||
|
||||
err := q.Bind(ctx, exec, userObj)
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return nil, sql.ErrNoRows
|
||||
}
|
||||
return nil, errors.Wrap(err, "sqlboilergen: unable to select from users")
|
||||
}
|
||||
|
||||
if err = userObj.doAfterSelectHooks(ctx, exec); err != nil {
|
||||
return userObj, err
|
||||
}
|
||||
|
||||
return userObj, nil
|
||||
}
|
||||
|
||||
// Insert a single record using an executor.
|
||||
// See boil.Columns.InsertColumnSet documentation to understand column list inference for inserts.
|
||||
func (o *User) Insert(ctx context.Context, exec boil.ContextExecutor, columns boil.Columns) error {
|
||||
if o == nil {
|
||||
return errors.New("sqlboilergen: no users provided for insertion")
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
if err := o.doBeforeInsertHooks(ctx, exec); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nzDefaults := queries.NonZeroDefaultSet(userColumnsWithDefault, o)
|
||||
|
||||
key := makeCacheKey(columns, nzDefaults)
|
||||
userInsertCacheMut.RLock()
|
||||
cache, cached := userInsertCache[key]
|
||||
userInsertCacheMut.RUnlock()
|
||||
|
||||
if !cached {
|
||||
wl, returnColumns := columns.InsertColumnSet(
|
||||
userAllColumns,
|
||||
userColumnsWithDefault,
|
||||
userColumnsWithoutDefault,
|
||||
nzDefaults,
|
||||
)
|
||||
|
||||
cache.valueMapping, err = queries.BindMapping(userType, userMapping, wl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cache.retMapping, err = queries.BindMapping(userType, userMapping, returnColumns)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(wl) != 0 {
|
||||
cache.query = fmt.Sprintf("INSERT INTO \"users\" (\"%s\") %%sVALUES (%s)%%s", strings.Join(wl, "\",\""), strmangle.Placeholders(dialect.UseIndexPlaceholders, len(wl), 1, 1))
|
||||
} else {
|
||||
cache.query = "INSERT INTO \"users\" %sDEFAULT VALUES%s"
|
||||
}
|
||||
|
||||
var queryOutput, queryReturning string
|
||||
|
||||
if len(cache.retMapping) != 0 {
|
||||
queryReturning = fmt.Sprintf(" RETURNING \"%s\"", strings.Join(returnColumns, "\",\""))
|
||||
}
|
||||
|
||||
cache.query = fmt.Sprintf(cache.query, queryOutput, queryReturning)
|
||||
}
|
||||
|
||||
value := reflect.Indirect(reflect.ValueOf(o))
|
||||
vals := queries.ValuesFromMapping(value, cache.valueMapping)
|
||||
|
||||
if boil.IsDebug(ctx) {
|
||||
writer := boil.DebugWriterFrom(ctx)
|
||||
fmt.Fprintln(writer, cache.query)
|
||||
fmt.Fprintln(writer, vals)
|
||||
}
|
||||
|
||||
if len(cache.retMapping) != 0 {
|
||||
err = exec.QueryRowContext(ctx, cache.query, vals...).Scan(queries.PtrsFromMapping(value, cache.retMapping)...)
|
||||
} else {
|
||||
_, err = exec.ExecContext(ctx, cache.query, vals...)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "sqlboilergen: unable to insert into users")
|
||||
}
|
||||
|
||||
if !cached {
|
||||
userInsertCacheMut.Lock()
|
||||
userInsertCache[key] = cache
|
||||
userInsertCacheMut.Unlock()
|
||||
}
|
||||
|
||||
return o.doAfterInsertHooks(ctx, exec)
|
||||
}
|
||||
|
||||
// Update uses an executor to update the User.
|
||||
// See boil.Columns.UpdateColumnSet documentation to understand column list inference for updates.
|
||||
// Update does not automatically update the record in case of default values. Use .Reload() to refresh the records.
|
||||
func (o *User) Update(ctx context.Context, exec boil.ContextExecutor, columns boil.Columns) (int64, error) {
|
||||
var err error
|
||||
if err = o.doBeforeUpdateHooks(ctx, exec); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
key := makeCacheKey(columns, nil)
|
||||
userUpdateCacheMut.RLock()
|
||||
cache, cached := userUpdateCache[key]
|
||||
userUpdateCacheMut.RUnlock()
|
||||
|
||||
if !cached {
|
||||
wl := columns.UpdateColumnSet(
|
||||
userAllColumns,
|
||||
userPrimaryKeyColumns,
|
||||
)
|
||||
|
||||
if !columns.IsWhitelist() {
|
||||
wl = strmangle.SetComplement(wl, []string{"created_at"})
|
||||
}
|
||||
if len(wl) == 0 {
|
||||
return 0, errors.New("sqlboilergen: unable to update users, could not build whitelist")
|
||||
}
|
||||
|
||||
cache.query = fmt.Sprintf("UPDATE \"users\" SET %s WHERE %s",
|
||||
strmangle.SetParamNames("\"", "\"", 1, wl),
|
||||
strmangle.WhereClause("\"", "\"", len(wl)+1, userPrimaryKeyColumns),
|
||||
)
|
||||
cache.valueMapping, err = queries.BindMapping(userType, userMapping, append(wl, userPrimaryKeyColumns...))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
values := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(o)), cache.valueMapping)
|
||||
|
||||
if boil.IsDebug(ctx) {
|
||||
writer := boil.DebugWriterFrom(ctx)
|
||||
fmt.Fprintln(writer, cache.query)
|
||||
fmt.Fprintln(writer, values)
|
||||
}
|
||||
var result sql.Result
|
||||
result, err = exec.ExecContext(ctx, cache.query, values...)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "sqlboilergen: unable to update users row")
|
||||
}
|
||||
|
||||
rowsAff, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "sqlboilergen: failed to get rows affected by update for users")
|
||||
}
|
||||
|
||||
if !cached {
|
||||
userUpdateCacheMut.Lock()
|
||||
userUpdateCache[key] = cache
|
||||
userUpdateCacheMut.Unlock()
|
||||
}
|
||||
|
||||
return rowsAff, o.doAfterUpdateHooks(ctx, exec)
|
||||
}
|
||||
|
||||
// UpdateAll updates all rows with the specified column values.
|
||||
func (q userQuery) UpdateAll(ctx context.Context, exec boil.ContextExecutor, cols M) (int64, error) {
|
||||
queries.SetUpdate(q.Query, cols)
|
||||
|
||||
result, err := q.Query.ExecContext(ctx, exec)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "sqlboilergen: unable to update all for users")
|
||||
}
|
||||
|
||||
rowsAff, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "sqlboilergen: unable to retrieve rows affected for users")
|
||||
}
|
||||
|
||||
return rowsAff, nil
|
||||
}
|
||||
|
||||
// UpdateAll updates all rows with the specified column values, using an executor.
|
||||
func (o UserSlice) UpdateAll(ctx context.Context, exec boil.ContextExecutor, cols M) (int64, error) {
|
||||
ln := int64(len(o))
|
||||
if ln == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
if len(cols) == 0 {
|
||||
return 0, errors.New("sqlboilergen: update all requires at least one column argument")
|
||||
}
|
||||
|
||||
colNames := make([]string, len(cols))
|
||||
args := make([]interface{}, len(cols))
|
||||
|
||||
i := 0
|
||||
for name, value := range cols {
|
||||
colNames[i] = name
|
||||
args[i] = value
|
||||
i++
|
||||
}
|
||||
|
||||
// Append all of the primary key values for each column
|
||||
for _, obj := range o {
|
||||
pkeyArgs := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(obj)), userPrimaryKeyMapping)
|
||||
args = append(args, pkeyArgs...)
|
||||
}
|
||||
|
||||
sql := fmt.Sprintf("UPDATE \"users\" SET %s WHERE %s",
|
||||
strmangle.SetParamNames("\"", "\"", 1, colNames),
|
||||
strmangle.WhereClauseRepeated(string(dialect.LQ), string(dialect.RQ), len(colNames)+1, userPrimaryKeyColumns, len(o)))
|
||||
|
||||
if boil.IsDebug(ctx) {
|
||||
writer := boil.DebugWriterFrom(ctx)
|
||||
fmt.Fprintln(writer, sql)
|
||||
fmt.Fprintln(writer, args...)
|
||||
}
|
||||
result, err := exec.ExecContext(ctx, sql, args...)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "sqlboilergen: unable to update all in user slice")
|
||||
}
|
||||
|
||||
rowsAff, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "sqlboilergen: unable to retrieve rows affected all in update all user")
|
||||
}
|
||||
return rowsAff, nil
|
||||
}
|
||||
|
||||
// Upsert attempts an insert using an executor, and does an update or ignore on conflict.
|
||||
// See boil.Columns documentation for how to properly use updateColumns and insertColumns.
|
||||
func (o *User) Upsert(ctx context.Context, exec boil.ContextExecutor, updateOnConflict bool, conflictColumns []string, updateColumns, insertColumns boil.Columns) error {
|
||||
if o == nil {
|
||||
return errors.New("sqlboilergen: no users provided for upsert")
|
||||
}
|
||||
|
||||
if err := o.doBeforeUpsertHooks(ctx, exec); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nzDefaults := queries.NonZeroDefaultSet(userColumnsWithDefault, o)
|
||||
|
||||
// Build cache key in-line uglily - mysql vs psql problems
|
||||
buf := strmangle.GetBuffer()
|
||||
if updateOnConflict {
|
||||
buf.WriteByte('t')
|
||||
} else {
|
||||
buf.WriteByte('f')
|
||||
}
|
||||
buf.WriteByte('.')
|
||||
for _, c := range conflictColumns {
|
||||
buf.WriteString(c)
|
||||
}
|
||||
buf.WriteByte('.')
|
||||
buf.WriteString(strconv.Itoa(updateColumns.Kind))
|
||||
for _, c := range updateColumns.Cols {
|
||||
buf.WriteString(c)
|
||||
}
|
||||
buf.WriteByte('.')
|
||||
buf.WriteString(strconv.Itoa(insertColumns.Kind))
|
||||
for _, c := range insertColumns.Cols {
|
||||
buf.WriteString(c)
|
||||
}
|
||||
buf.WriteByte('.')
|
||||
for _, c := range nzDefaults {
|
||||
buf.WriteString(c)
|
||||
}
|
||||
key := buf.String()
|
||||
strmangle.PutBuffer(buf)
|
||||
|
||||
userUpsertCacheMut.RLock()
|
||||
cache, cached := userUpsertCache[key]
|
||||
userUpsertCacheMut.RUnlock()
|
||||
|
||||
var err error
|
||||
|
||||
if !cached {
|
||||
insert, ret := insertColumns.InsertColumnSet(
|
||||
userAllColumns,
|
||||
userColumnsWithDefault,
|
||||
userColumnsWithoutDefault,
|
||||
nzDefaults,
|
||||
)
|
||||
|
||||
update := updateColumns.UpdateColumnSet(
|
||||
userAllColumns,
|
||||
userPrimaryKeyColumns,
|
||||
)
|
||||
|
||||
if updateOnConflict && len(update) == 0 {
|
||||
return errors.New("sqlboilergen: unable to upsert users, could not build update column list")
|
||||
}
|
||||
|
||||
conflict := conflictColumns
|
||||
if len(conflict) == 0 {
|
||||
conflict = make([]string, len(userPrimaryKeyColumns))
|
||||
copy(conflict, userPrimaryKeyColumns)
|
||||
}
|
||||
cache.query = buildUpsertQueryPostgres(dialect, "\"users\"", updateOnConflict, ret, update, conflict, insert)
|
||||
|
||||
cache.valueMapping, err = queries.BindMapping(userType, userMapping, insert)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(ret) != 0 {
|
||||
cache.retMapping, err = queries.BindMapping(userType, userMapping, ret)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
value := reflect.Indirect(reflect.ValueOf(o))
|
||||
vals := queries.ValuesFromMapping(value, cache.valueMapping)
|
||||
var returns []interface{}
|
||||
if len(cache.retMapping) != 0 {
|
||||
returns = queries.PtrsFromMapping(value, cache.retMapping)
|
||||
}
|
||||
|
||||
if boil.IsDebug(ctx) {
|
||||
writer := boil.DebugWriterFrom(ctx)
|
||||
fmt.Fprintln(writer, cache.query)
|
||||
fmt.Fprintln(writer, vals)
|
||||
}
|
||||
if len(cache.retMapping) != 0 {
|
||||
err = exec.QueryRowContext(ctx, cache.query, vals...).Scan(returns...)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
err = nil // Postgres doesn't return anything when there's no update
|
||||
}
|
||||
} else {
|
||||
_, err = exec.ExecContext(ctx, cache.query, vals...)
|
||||
}
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "sqlboilergen: unable to upsert users")
|
||||
}
|
||||
|
||||
if !cached {
|
||||
userUpsertCacheMut.Lock()
|
||||
userUpsertCache[key] = cache
|
||||
userUpsertCacheMut.Unlock()
|
||||
}
|
||||
|
||||
return o.doAfterUpsertHooks(ctx, exec)
|
||||
}
|
||||
|
||||
// Delete deletes a single User record with an executor.
|
||||
// Delete will match against the primary key column to find the record to delete.
|
||||
func (o *User) Delete(ctx context.Context, exec boil.ContextExecutor) (int64, error) {
|
||||
if o == nil {
|
||||
return 0, errors.New("sqlboilergen: no User provided for delete")
|
||||
}
|
||||
|
||||
if err := o.doBeforeDeleteHooks(ctx, exec); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
args := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(o)), userPrimaryKeyMapping)
|
||||
sql := "DELETE FROM \"users\" WHERE \"id\"=$1"
|
||||
|
||||
if boil.IsDebug(ctx) {
|
||||
writer := boil.DebugWriterFrom(ctx)
|
||||
fmt.Fprintln(writer, sql)
|
||||
fmt.Fprintln(writer, args...)
|
||||
}
|
||||
result, err := exec.ExecContext(ctx, sql, args...)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "sqlboilergen: unable to delete from users")
|
||||
}
|
||||
|
||||
rowsAff, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "sqlboilergen: failed to get rows affected by delete for users")
|
||||
}
|
||||
|
||||
if err := o.doAfterDeleteHooks(ctx, exec); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return rowsAff, nil
|
||||
}
|
||||
|
||||
// DeleteAll deletes all matching rows.
|
||||
func (q userQuery) DeleteAll(ctx context.Context, exec boil.ContextExecutor) (int64, error) {
|
||||
if q.Query == nil {
|
||||
return 0, errors.New("sqlboilergen: no userQuery provided for delete all")
|
||||
}
|
||||
|
||||
queries.SetDelete(q.Query)
|
||||
|
||||
result, err := q.Query.ExecContext(ctx, exec)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "sqlboilergen: unable to delete all from users")
|
||||
}
|
||||
|
||||
rowsAff, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "sqlboilergen: failed to get rows affected by deleteall for users")
|
||||
}
|
||||
|
||||
return rowsAff, nil
|
||||
}
|
||||
|
||||
// DeleteAll deletes all rows in the slice, using an executor.
|
||||
func (o UserSlice) DeleteAll(ctx context.Context, exec boil.ContextExecutor) (int64, error) {
|
||||
if len(o) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
if len(userBeforeDeleteHooks) != 0 {
|
||||
for _, obj := range o {
|
||||
if err := obj.doBeforeDeleteHooks(ctx, exec); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var args []interface{}
|
||||
for _, obj := range o {
|
||||
pkeyArgs := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(obj)), userPrimaryKeyMapping)
|
||||
args = append(args, pkeyArgs...)
|
||||
}
|
||||
|
||||
sql := "DELETE FROM \"users\" WHERE " +
|
||||
strmangle.WhereClauseRepeated(string(dialect.LQ), string(dialect.RQ), 1, userPrimaryKeyColumns, len(o))
|
||||
|
||||
if boil.IsDebug(ctx) {
|
||||
writer := boil.DebugWriterFrom(ctx)
|
||||
fmt.Fprintln(writer, sql)
|
||||
fmt.Fprintln(writer, args)
|
||||
}
|
||||
result, err := exec.ExecContext(ctx, sql, args...)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "sqlboilergen: unable to delete all from user slice")
|
||||
}
|
||||
|
||||
rowsAff, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "sqlboilergen: failed to get rows affected by deleteall for users")
|
||||
}
|
||||
|
||||
if len(userAfterDeleteHooks) != 0 {
|
||||
for _, obj := range o {
|
||||
if err := obj.doAfterDeleteHooks(ctx, exec); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rowsAff, nil
|
||||
}
|
||||
|
||||
// Reload refetches the object from the database
|
||||
// using the primary keys with an executor.
|
||||
func (o *User) Reload(ctx context.Context, exec boil.ContextExecutor) error {
|
||||
ret, err := FindUser(ctx, exec, o.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*o = *ret
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReloadAll refetches every row with matching primary key column values
|
||||
// and overwrites the original object slice with the newly updated slice.
|
||||
func (o *UserSlice) ReloadAll(ctx context.Context, exec boil.ContextExecutor) error {
|
||||
if o == nil || len(*o) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
slice := UserSlice{}
|
||||
var args []interface{}
|
||||
for _, obj := range *o {
|
||||
pkeyArgs := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(obj)), userPrimaryKeyMapping)
|
||||
args = append(args, pkeyArgs...)
|
||||
}
|
||||
|
||||
sql := "SELECT \"users\".* FROM \"users\" WHERE " +
|
||||
strmangle.WhereClauseRepeated(string(dialect.LQ), string(dialect.RQ), 1, userPrimaryKeyColumns, len(*o))
|
||||
|
||||
q := queries.Raw(sql, args...)
|
||||
|
||||
err := q.Bind(ctx, exec, &slice)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "sqlboilergen: unable to reload all in UserSlice")
|
||||
}
|
||||
|
||||
*o = slice
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UserExists checks if the User row exists.
|
||||
func UserExists(ctx context.Context, exec boil.ContextExecutor, iD int) (bool, error) {
|
||||
var exists bool
|
||||
sql := "select exists(select 1 from \"users\" where \"id\"=$1 limit 1)"
|
||||
|
||||
if boil.IsDebug(ctx) {
|
||||
writer := boil.DebugWriterFrom(ctx)
|
||||
fmt.Fprintln(writer, sql)
|
||||
fmt.Fprintln(writer, iD)
|
||||
}
|
||||
row := exec.QueryRowContext(ctx, sql, iD)
|
||||
|
||||
err := row.Scan(&exists)
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "sqlboilergen: unable to check if users exists")
|
||||
}
|
||||
|
||||
return exists, nil
|
||||
}
|
890
benchmarks/sqlboilergen/users_permissions.go
Normal file
890
benchmarks/sqlboilergen/users_permissions.go
Normal file
@ -0,0 +1,890 @@
|
||||
// Code generated by SQLBoiler 4.12.0 (https://github.com/volatiletech/sqlboiler). DO NOT EDIT.
|
||||
// This file is meant to be re-generated in place and/or deleted at any time.
|
||||
|
||||
package sqlboilergen
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/friendsofgo/errors"
|
||||
"github.com/volatiletech/sqlboiler/v4/boil"
|
||||
"github.com/volatiletech/sqlboiler/v4/queries"
|
||||
"github.com/volatiletech/sqlboiler/v4/queries/qm"
|
||||
"github.com/volatiletech/sqlboiler/v4/queries/qmhelper"
|
||||
"github.com/volatiletech/strmangle"
|
||||
)
|
||||
|
||||
// UsersPermission is an object representing the database table.
|
||||
type UsersPermission struct {
|
||||
UserID int `boil:"user_id" json:"user_id" toml:"user_id" yaml:"user_id"`
|
||||
PostID int `boil:"post_id" json:"post_id" toml:"post_id" yaml:"post_id"`
|
||||
|
||||
R *usersPermissionR `boil:"-" json:"-" toml:"-" yaml:"-"`
|
||||
L usersPermissionL `boil:"-" json:"-" toml:"-" yaml:"-"`
|
||||
}
|
||||
|
||||
var UsersPermissionColumns = struct {
|
||||
UserID string
|
||||
PostID string
|
||||
}{
|
||||
UserID: "user_id",
|
||||
PostID: "post_id",
|
||||
}
|
||||
|
||||
var UsersPermissionTableColumns = struct {
|
||||
UserID string
|
||||
PostID string
|
||||
}{
|
||||
UserID: "users_permissions.user_id",
|
||||
PostID: "users_permissions.post_id",
|
||||
}
|
||||
|
||||
// Generated where
|
||||
|
||||
var UsersPermissionWhere = struct {
|
||||
UserID whereHelperint
|
||||
PostID whereHelperint
|
||||
}{
|
||||
UserID: whereHelperint{field: "\"users_permissions\".\"user_id\""},
|
||||
PostID: whereHelperint{field: "\"users_permissions\".\"post_id\""},
|
||||
}
|
||||
|
||||
// UsersPermissionRels is where relationship names are stored.
|
||||
var UsersPermissionRels = struct {
|
||||
}{}
|
||||
|
||||
// usersPermissionR is where relationships are stored.
|
||||
type usersPermissionR struct {
|
||||
}
|
||||
|
||||
// NewStruct creates a new relationship struct
|
||||
func (*usersPermissionR) NewStruct() *usersPermissionR {
|
||||
return &usersPermissionR{}
|
||||
}
|
||||
|
||||
// usersPermissionL is where Load methods for each relationship are stored.
|
||||
type usersPermissionL struct{}
|
||||
|
||||
var (
|
||||
usersPermissionAllColumns = []string{"user_id", "post_id"}
|
||||
usersPermissionColumnsWithoutDefault = []string{"user_id", "post_id"}
|
||||
usersPermissionColumnsWithDefault = []string{}
|
||||
usersPermissionPrimaryKeyColumns = []string{"user_id", "post_id"}
|
||||
usersPermissionGeneratedColumns = []string{}
|
||||
)
|
||||
|
||||
type (
|
||||
// UsersPermissionSlice is an alias for a slice of pointers to UsersPermission.
|
||||
// This should almost always be used instead of []UsersPermission.
|
||||
UsersPermissionSlice []*UsersPermission
|
||||
// UsersPermissionHook is the signature for custom UsersPermission hook methods
|
||||
UsersPermissionHook func(context.Context, boil.ContextExecutor, *UsersPermission) error
|
||||
|
||||
usersPermissionQuery struct {
|
||||
*queries.Query
|
||||
}
|
||||
)
|
||||
|
||||
// Cache for insert, update and upsert
|
||||
var (
|
||||
usersPermissionType = reflect.TypeOf(&UsersPermission{})
|
||||
usersPermissionMapping = queries.MakeStructMapping(usersPermissionType)
|
||||
usersPermissionPrimaryKeyMapping, _ = queries.BindMapping(usersPermissionType, usersPermissionMapping, usersPermissionPrimaryKeyColumns)
|
||||
usersPermissionInsertCacheMut sync.RWMutex
|
||||
usersPermissionInsertCache = make(map[string]insertCache)
|
||||
usersPermissionUpdateCacheMut sync.RWMutex
|
||||
usersPermissionUpdateCache = make(map[string]updateCache)
|
||||
usersPermissionUpsertCacheMut sync.RWMutex
|
||||
usersPermissionUpsertCache = make(map[string]insertCache)
|
||||
)
|
||||
|
||||
var (
|
||||
// Force time package dependency for automated UpdatedAt/CreatedAt.
|
||||
_ = time.Second
|
||||
// Force qmhelper dependency for where clause generation (which doesn't
|
||||
// always happen)
|
||||
_ = qmhelper.Where
|
||||
)
|
||||
|
||||
var usersPermissionAfterSelectHooks []UsersPermissionHook
|
||||
|
||||
var usersPermissionBeforeInsertHooks []UsersPermissionHook
|
||||
var usersPermissionAfterInsertHooks []UsersPermissionHook
|
||||
|
||||
var usersPermissionBeforeUpdateHooks []UsersPermissionHook
|
||||
var usersPermissionAfterUpdateHooks []UsersPermissionHook
|
||||
|
||||
var usersPermissionBeforeDeleteHooks []UsersPermissionHook
|
||||
var usersPermissionAfterDeleteHooks []UsersPermissionHook
|
||||
|
||||
var usersPermissionBeforeUpsertHooks []UsersPermissionHook
|
||||
var usersPermissionAfterUpsertHooks []UsersPermissionHook
|
||||
|
||||
// doAfterSelectHooks executes all "after Select" hooks.
|
||||
func (o *UsersPermission) doAfterSelectHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range usersPermissionAfterSelectHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// doBeforeInsertHooks executes all "before insert" hooks.
|
||||
func (o *UsersPermission) doBeforeInsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range usersPermissionBeforeInsertHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// doAfterInsertHooks executes all "after Insert" hooks.
|
||||
func (o *UsersPermission) doAfterInsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range usersPermissionAfterInsertHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// doBeforeUpdateHooks executes all "before Update" hooks.
|
||||
func (o *UsersPermission) doBeforeUpdateHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range usersPermissionBeforeUpdateHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// doAfterUpdateHooks executes all "after Update" hooks.
|
||||
func (o *UsersPermission) doAfterUpdateHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range usersPermissionAfterUpdateHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// doBeforeDeleteHooks executes all "before Delete" hooks.
|
||||
func (o *UsersPermission) doBeforeDeleteHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range usersPermissionBeforeDeleteHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// doAfterDeleteHooks executes all "after Delete" hooks.
|
||||
func (o *UsersPermission) doAfterDeleteHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range usersPermissionAfterDeleteHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// doBeforeUpsertHooks executes all "before Upsert" hooks.
|
||||
func (o *UsersPermission) doBeforeUpsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range usersPermissionBeforeUpsertHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// doAfterUpsertHooks executes all "after Upsert" hooks.
|
||||
func (o *UsersPermission) doAfterUpsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range usersPermissionAfterUpsertHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddUsersPermissionHook registers your hook function for all future operations.
|
||||
func AddUsersPermissionHook(hookPoint boil.HookPoint, usersPermissionHook UsersPermissionHook) {
|
||||
switch hookPoint {
|
||||
case boil.AfterSelectHook:
|
||||
usersPermissionAfterSelectHooks = append(usersPermissionAfterSelectHooks, usersPermissionHook)
|
||||
case boil.BeforeInsertHook:
|
||||
usersPermissionBeforeInsertHooks = append(usersPermissionBeforeInsertHooks, usersPermissionHook)
|
||||
case boil.AfterInsertHook:
|
||||
usersPermissionAfterInsertHooks = append(usersPermissionAfterInsertHooks, usersPermissionHook)
|
||||
case boil.BeforeUpdateHook:
|
||||
usersPermissionBeforeUpdateHooks = append(usersPermissionBeforeUpdateHooks, usersPermissionHook)
|
||||
case boil.AfterUpdateHook:
|
||||
usersPermissionAfterUpdateHooks = append(usersPermissionAfterUpdateHooks, usersPermissionHook)
|
||||
case boil.BeforeDeleteHook:
|
||||
usersPermissionBeforeDeleteHooks = append(usersPermissionBeforeDeleteHooks, usersPermissionHook)
|
||||
case boil.AfterDeleteHook:
|
||||
usersPermissionAfterDeleteHooks = append(usersPermissionAfterDeleteHooks, usersPermissionHook)
|
||||
case boil.BeforeUpsertHook:
|
||||
usersPermissionBeforeUpsertHooks = append(usersPermissionBeforeUpsertHooks, usersPermissionHook)
|
||||
case boil.AfterUpsertHook:
|
||||
usersPermissionAfterUpsertHooks = append(usersPermissionAfterUpsertHooks, usersPermissionHook)
|
||||
}
|
||||
}
|
||||
|
||||
// One returns a single usersPermission record from the query.
|
||||
func (q usersPermissionQuery) One(ctx context.Context, exec boil.ContextExecutor) (*UsersPermission, error) {
|
||||
o := &UsersPermission{}
|
||||
|
||||
queries.SetLimit(q.Query, 1)
|
||||
|
||||
err := q.Bind(ctx, exec, o)
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return nil, sql.ErrNoRows
|
||||
}
|
||||
return nil, errors.Wrap(err, "sqlboilergen: failed to execute a one query for users_permissions")
|
||||
}
|
||||
|
||||
if err := o.doAfterSelectHooks(ctx, exec); err != nil {
|
||||
return o, err
|
||||
}
|
||||
|
||||
return o, nil
|
||||
}
|
||||
|
||||
// All returns all UsersPermission records from the query.
|
||||
func (q usersPermissionQuery) All(ctx context.Context, exec boil.ContextExecutor) (UsersPermissionSlice, error) {
|
||||
var o []*UsersPermission
|
||||
|
||||
err := q.Bind(ctx, exec, &o)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "sqlboilergen: failed to assign all query results to UsersPermission slice")
|
||||
}
|
||||
|
||||
if len(usersPermissionAfterSelectHooks) != 0 {
|
||||
for _, obj := range o {
|
||||
if err := obj.doAfterSelectHooks(ctx, exec); err != nil {
|
||||
return o, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return o, nil
|
||||
}
|
||||
|
||||
// Count returns the count of all UsersPermission records in the query.
|
||||
func (q usersPermissionQuery) Count(ctx context.Context, exec boil.ContextExecutor) (int64, error) {
|
||||
var count int64
|
||||
|
||||
queries.SetSelect(q.Query, nil)
|
||||
queries.SetCount(q.Query)
|
||||
|
||||
err := q.Query.QueryRowContext(ctx, exec).Scan(&count)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "sqlboilergen: failed to count users_permissions rows")
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// Exists checks if the row exists in the table.
|
||||
func (q usersPermissionQuery) Exists(ctx context.Context, exec boil.ContextExecutor) (bool, error) {
|
||||
var count int64
|
||||
|
||||
queries.SetSelect(q.Query, nil)
|
||||
queries.SetCount(q.Query)
|
||||
queries.SetLimit(q.Query, 1)
|
||||
|
||||
err := q.Query.QueryRowContext(ctx, exec).Scan(&count)
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "sqlboilergen: failed to check if users_permissions exists")
|
||||
}
|
||||
|
||||
return count > 0, nil
|
||||
}
|
||||
|
||||
// UsersPermissions retrieves all the records using an executor.
|
||||
func UsersPermissions(mods ...qm.QueryMod) usersPermissionQuery {
|
||||
mods = append(mods, qm.From("\"users_permissions\""))
|
||||
q := NewQuery(mods...)
|
||||
if len(queries.GetSelect(q)) == 0 {
|
||||
queries.SetSelect(q, []string{"\"users_permissions\".*"})
|
||||
}
|
||||
|
||||
return usersPermissionQuery{q}
|
||||
}
|
||||
|
||||
// FindUsersPermission retrieves a single record by ID with an executor.
|
||||
// If selectCols is empty Find will return all columns.
|
||||
func FindUsersPermission(ctx context.Context, exec boil.ContextExecutor, userID int, postID int, selectCols ...string) (*UsersPermission, error) {
|
||||
usersPermissionObj := &UsersPermission{}
|
||||
|
||||
sel := "*"
|
||||
if len(selectCols) > 0 {
|
||||
sel = strings.Join(strmangle.IdentQuoteSlice(dialect.LQ, dialect.RQ, selectCols), ",")
|
||||
}
|
||||
query := fmt.Sprintf(
|
||||
"select %s from \"users_permissions\" where \"user_id\"=$1 AND \"post_id\"=$2", sel,
|
||||
)
|
||||
|
||||
q := queries.Raw(query, userID, postID)
|
||||
|
||||
err := q.Bind(ctx, exec, usersPermissionObj)
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return nil, sql.ErrNoRows
|
||||
}
|
||||
return nil, errors.Wrap(err, "sqlboilergen: unable to select from users_permissions")
|
||||
}
|
||||
|
||||
if err = usersPermissionObj.doAfterSelectHooks(ctx, exec); err != nil {
|
||||
return usersPermissionObj, err
|
||||
}
|
||||
|
||||
return usersPermissionObj, nil
|
||||
}
|
||||
|
||||
// Insert a single record using an executor.
|
||||
// See boil.Columns.InsertColumnSet documentation to understand column list inference for inserts.
|
||||
func (o *UsersPermission) Insert(ctx context.Context, exec boil.ContextExecutor, columns boil.Columns) error {
|
||||
if o == nil {
|
||||
return errors.New("sqlboilergen: no users_permissions provided for insertion")
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
if err := o.doBeforeInsertHooks(ctx, exec); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nzDefaults := queries.NonZeroDefaultSet(usersPermissionColumnsWithDefault, o)
|
||||
|
||||
key := makeCacheKey(columns, nzDefaults)
|
||||
usersPermissionInsertCacheMut.RLock()
|
||||
cache, cached := usersPermissionInsertCache[key]
|
||||
usersPermissionInsertCacheMut.RUnlock()
|
||||
|
||||
if !cached {
|
||||
wl, returnColumns := columns.InsertColumnSet(
|
||||
usersPermissionAllColumns,
|
||||
usersPermissionColumnsWithDefault,
|
||||
usersPermissionColumnsWithoutDefault,
|
||||
nzDefaults,
|
||||
)
|
||||
|
||||
cache.valueMapping, err = queries.BindMapping(usersPermissionType, usersPermissionMapping, wl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cache.retMapping, err = queries.BindMapping(usersPermissionType, usersPermissionMapping, returnColumns)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(wl) != 0 {
|
||||
cache.query = fmt.Sprintf("INSERT INTO \"users_permissions\" (\"%s\") %%sVALUES (%s)%%s", strings.Join(wl, "\",\""), strmangle.Placeholders(dialect.UseIndexPlaceholders, len(wl), 1, 1))
|
||||
} else {
|
||||
cache.query = "INSERT INTO \"users_permissions\" %sDEFAULT VALUES%s"
|
||||
}
|
||||
|
||||
var queryOutput, queryReturning string
|
||||
|
||||
if len(cache.retMapping) != 0 {
|
||||
queryReturning = fmt.Sprintf(" RETURNING \"%s\"", strings.Join(returnColumns, "\",\""))
|
||||
}
|
||||
|
||||
cache.query = fmt.Sprintf(cache.query, queryOutput, queryReturning)
|
||||
}
|
||||
|
||||
value := reflect.Indirect(reflect.ValueOf(o))
|
||||
vals := queries.ValuesFromMapping(value, cache.valueMapping)
|
||||
|
||||
if boil.IsDebug(ctx) {
|
||||
writer := boil.DebugWriterFrom(ctx)
|
||||
fmt.Fprintln(writer, cache.query)
|
||||
fmt.Fprintln(writer, vals)
|
||||
}
|
||||
|
||||
if len(cache.retMapping) != 0 {
|
||||
err = exec.QueryRowContext(ctx, cache.query, vals...).Scan(queries.PtrsFromMapping(value, cache.retMapping)...)
|
||||
} else {
|
||||
_, err = exec.ExecContext(ctx, cache.query, vals...)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "sqlboilergen: unable to insert into users_permissions")
|
||||
}
|
||||
|
||||
if !cached {
|
||||
usersPermissionInsertCacheMut.Lock()
|
||||
usersPermissionInsertCache[key] = cache
|
||||
usersPermissionInsertCacheMut.Unlock()
|
||||
}
|
||||
|
||||
return o.doAfterInsertHooks(ctx, exec)
|
||||
}
|
||||
|
||||
// Update uses an executor to update the UsersPermission.
|
||||
// See boil.Columns.UpdateColumnSet documentation to understand column list inference for updates.
|
||||
// Update does not automatically update the record in case of default values. Use .Reload() to refresh the records.
|
||||
func (o *UsersPermission) Update(ctx context.Context, exec boil.ContextExecutor, columns boil.Columns) (int64, error) {
|
||||
var err error
|
||||
if err = o.doBeforeUpdateHooks(ctx, exec); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
key := makeCacheKey(columns, nil)
|
||||
usersPermissionUpdateCacheMut.RLock()
|
||||
cache, cached := usersPermissionUpdateCache[key]
|
||||
usersPermissionUpdateCacheMut.RUnlock()
|
||||
|
||||
if !cached {
|
||||
wl := columns.UpdateColumnSet(
|
||||
usersPermissionAllColumns,
|
||||
usersPermissionPrimaryKeyColumns,
|
||||
)
|
||||
|
||||
if !columns.IsWhitelist() {
|
||||
wl = strmangle.SetComplement(wl, []string{"created_at"})
|
||||
}
|
||||
if len(wl) == 0 {
|
||||
return 0, errors.New("sqlboilergen: unable to update users_permissions, could not build whitelist")
|
||||
}
|
||||
|
||||
cache.query = fmt.Sprintf("UPDATE \"users_permissions\" SET %s WHERE %s",
|
||||
strmangle.SetParamNames("\"", "\"", 1, wl),
|
||||
strmangle.WhereClause("\"", "\"", len(wl)+1, usersPermissionPrimaryKeyColumns),
|
||||
)
|
||||
cache.valueMapping, err = queries.BindMapping(usersPermissionType, usersPermissionMapping, append(wl, usersPermissionPrimaryKeyColumns...))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
values := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(o)), cache.valueMapping)
|
||||
|
||||
if boil.IsDebug(ctx) {
|
||||
writer := boil.DebugWriterFrom(ctx)
|
||||
fmt.Fprintln(writer, cache.query)
|
||||
fmt.Fprintln(writer, values)
|
||||
}
|
||||
var result sql.Result
|
||||
result, err = exec.ExecContext(ctx, cache.query, values...)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "sqlboilergen: unable to update users_permissions row")
|
||||
}
|
||||
|
||||
rowsAff, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "sqlboilergen: failed to get rows affected by update for users_permissions")
|
||||
}
|
||||
|
||||
if !cached {
|
||||
usersPermissionUpdateCacheMut.Lock()
|
||||
usersPermissionUpdateCache[key] = cache
|
||||
usersPermissionUpdateCacheMut.Unlock()
|
||||
}
|
||||
|
||||
return rowsAff, o.doAfterUpdateHooks(ctx, exec)
|
||||
}
|
||||
|
||||
// UpdateAll updates all rows with the specified column values.
|
||||
func (q usersPermissionQuery) UpdateAll(ctx context.Context, exec boil.ContextExecutor, cols M) (int64, error) {
|
||||
queries.SetUpdate(q.Query, cols)
|
||||
|
||||
result, err := q.Query.ExecContext(ctx, exec)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "sqlboilergen: unable to update all for users_permissions")
|
||||
}
|
||||
|
||||
rowsAff, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "sqlboilergen: unable to retrieve rows affected for users_permissions")
|
||||
}
|
||||
|
||||
return rowsAff, nil
|
||||
}
|
||||
|
||||
// UpdateAll updates all rows with the specified column values, using an executor.
|
||||
func (o UsersPermissionSlice) UpdateAll(ctx context.Context, exec boil.ContextExecutor, cols M) (int64, error) {
|
||||
ln := int64(len(o))
|
||||
if ln == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
if len(cols) == 0 {
|
||||
return 0, errors.New("sqlboilergen: update all requires at least one column argument")
|
||||
}
|
||||
|
||||
colNames := make([]string, len(cols))
|
||||
args := make([]interface{}, len(cols))
|
||||
|
||||
i := 0
|
||||
for name, value := range cols {
|
||||
colNames[i] = name
|
||||
args[i] = value
|
||||
i++
|
||||
}
|
||||
|
||||
// Append all of the primary key values for each column
|
||||
for _, obj := range o {
|
||||
pkeyArgs := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(obj)), usersPermissionPrimaryKeyMapping)
|
||||
args = append(args, pkeyArgs...)
|
||||
}
|
||||
|
||||
sql := fmt.Sprintf("UPDATE \"users_permissions\" SET %s WHERE %s",
|
||||
strmangle.SetParamNames("\"", "\"", 1, colNames),
|
||||
strmangle.WhereClauseRepeated(string(dialect.LQ), string(dialect.RQ), len(colNames)+1, usersPermissionPrimaryKeyColumns, len(o)))
|
||||
|
||||
if boil.IsDebug(ctx) {
|
||||
writer := boil.DebugWriterFrom(ctx)
|
||||
fmt.Fprintln(writer, sql)
|
||||
fmt.Fprintln(writer, args...)
|
||||
}
|
||||
result, err := exec.ExecContext(ctx, sql, args...)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "sqlboilergen: unable to update all in usersPermission slice")
|
||||
}
|
||||
|
||||
rowsAff, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "sqlboilergen: unable to retrieve rows affected all in update all usersPermission")
|
||||
}
|
||||
return rowsAff, nil
|
||||
}
|
||||
|
||||
// Upsert attempts an insert using an executor, and does an update or ignore on conflict.
|
||||
// See boil.Columns documentation for how to properly use updateColumns and insertColumns.
|
||||
func (o *UsersPermission) Upsert(ctx context.Context, exec boil.ContextExecutor, updateOnConflict bool, conflictColumns []string, updateColumns, insertColumns boil.Columns) error {
|
||||
if o == nil {
|
||||
return errors.New("sqlboilergen: no users_permissions provided for upsert")
|
||||
}
|
||||
|
||||
if err := o.doBeforeUpsertHooks(ctx, exec); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nzDefaults := queries.NonZeroDefaultSet(usersPermissionColumnsWithDefault, o)
|
||||
|
||||
// Build cache key in-line uglily - mysql vs psql problems
|
||||
buf := strmangle.GetBuffer()
|
||||
if updateOnConflict {
|
||||
buf.WriteByte('t')
|
||||
} else {
|
||||
buf.WriteByte('f')
|
||||
}
|
||||
buf.WriteByte('.')
|
||||
for _, c := range conflictColumns {
|
||||
buf.WriteString(c)
|
||||
}
|
||||
buf.WriteByte('.')
|
||||
buf.WriteString(strconv.Itoa(updateColumns.Kind))
|
||||
for _, c := range updateColumns.Cols {
|
||||
buf.WriteString(c)
|
||||
}
|
||||
buf.WriteByte('.')
|
||||
buf.WriteString(strconv.Itoa(insertColumns.Kind))
|
||||
for _, c := range insertColumns.Cols {
|
||||
buf.WriteString(c)
|
||||
}
|
||||
buf.WriteByte('.')
|
||||
for _, c := range nzDefaults {
|
||||
buf.WriteString(c)
|
||||
}
|
||||
key := buf.String()
|
||||
strmangle.PutBuffer(buf)
|
||||
|
||||
usersPermissionUpsertCacheMut.RLock()
|
||||
cache, cached := usersPermissionUpsertCache[key]
|
||||
usersPermissionUpsertCacheMut.RUnlock()
|
||||
|
||||
var err error
|
||||
|
||||
if !cached {
|
||||
insert, ret := insertColumns.InsertColumnSet(
|
||||
usersPermissionAllColumns,
|
||||
usersPermissionColumnsWithDefault,
|
||||
usersPermissionColumnsWithoutDefault,
|
||||
nzDefaults,
|
||||
)
|
||||
|
||||
update := updateColumns.UpdateColumnSet(
|
||||
usersPermissionAllColumns,
|
||||
usersPermissionPrimaryKeyColumns,
|
||||
)
|
||||
|
||||
if updateOnConflict && len(update) == 0 {
|
||||
return errors.New("sqlboilergen: unable to upsert users_permissions, could not build update column list")
|
||||
}
|
||||
|
||||
conflict := conflictColumns
|
||||
if len(conflict) == 0 {
|
||||
conflict = make([]string, len(usersPermissionPrimaryKeyColumns))
|
||||
copy(conflict, usersPermissionPrimaryKeyColumns)
|
||||
}
|
||||
cache.query = buildUpsertQueryPostgres(dialect, "\"users_permissions\"", updateOnConflict, ret, update, conflict, insert)
|
||||
|
||||
cache.valueMapping, err = queries.BindMapping(usersPermissionType, usersPermissionMapping, insert)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(ret) != 0 {
|
||||
cache.retMapping, err = queries.BindMapping(usersPermissionType, usersPermissionMapping, ret)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
value := reflect.Indirect(reflect.ValueOf(o))
|
||||
vals := queries.ValuesFromMapping(value, cache.valueMapping)
|
||||
var returns []interface{}
|
||||
if len(cache.retMapping) != 0 {
|
||||
returns = queries.PtrsFromMapping(value, cache.retMapping)
|
||||
}
|
||||
|
||||
if boil.IsDebug(ctx) {
|
||||
writer := boil.DebugWriterFrom(ctx)
|
||||
fmt.Fprintln(writer, cache.query)
|
||||
fmt.Fprintln(writer, vals)
|
||||
}
|
||||
if len(cache.retMapping) != 0 {
|
||||
err = exec.QueryRowContext(ctx, cache.query, vals...).Scan(returns...)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
err = nil // Postgres doesn't return anything when there's no update
|
||||
}
|
||||
} else {
|
||||
_, err = exec.ExecContext(ctx, cache.query, vals...)
|
||||
}
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "sqlboilergen: unable to upsert users_permissions")
|
||||
}
|
||||
|
||||
if !cached {
|
||||
usersPermissionUpsertCacheMut.Lock()
|
||||
usersPermissionUpsertCache[key] = cache
|
||||
usersPermissionUpsertCacheMut.Unlock()
|
||||
}
|
||||
|
||||
return o.doAfterUpsertHooks(ctx, exec)
|
||||
}
|
||||
|
||||
// Delete deletes a single UsersPermission record with an executor.
|
||||
// Delete will match against the primary key column to find the record to delete.
|
||||
func (o *UsersPermission) Delete(ctx context.Context, exec boil.ContextExecutor) (int64, error) {
|
||||
if o == nil {
|
||||
return 0, errors.New("sqlboilergen: no UsersPermission provided for delete")
|
||||
}
|
||||
|
||||
if err := o.doBeforeDeleteHooks(ctx, exec); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
args := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(o)), usersPermissionPrimaryKeyMapping)
|
||||
sql := "DELETE FROM \"users_permissions\" WHERE \"user_id\"=$1 AND \"post_id\"=$2"
|
||||
|
||||
if boil.IsDebug(ctx) {
|
||||
writer := boil.DebugWriterFrom(ctx)
|
||||
fmt.Fprintln(writer, sql)
|
||||
fmt.Fprintln(writer, args...)
|
||||
}
|
||||
result, err := exec.ExecContext(ctx, sql, args...)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "sqlboilergen: unable to delete from users_permissions")
|
||||
}
|
||||
|
||||
rowsAff, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "sqlboilergen: failed to get rows affected by delete for users_permissions")
|
||||
}
|
||||
|
||||
if err := o.doAfterDeleteHooks(ctx, exec); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return rowsAff, nil
|
||||
}
|
||||
|
||||
// DeleteAll deletes all matching rows.
|
||||
func (q usersPermissionQuery) DeleteAll(ctx context.Context, exec boil.ContextExecutor) (int64, error) {
|
||||
if q.Query == nil {
|
||||
return 0, errors.New("sqlboilergen: no usersPermissionQuery provided for delete all")
|
||||
}
|
||||
|
||||
queries.SetDelete(q.Query)
|
||||
|
||||
result, err := q.Query.ExecContext(ctx, exec)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "sqlboilergen: unable to delete all from users_permissions")
|
||||
}
|
||||
|
||||
rowsAff, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "sqlboilergen: failed to get rows affected by deleteall for users_permissions")
|
||||
}
|
||||
|
||||
return rowsAff, nil
|
||||
}
|
||||
|
||||
// DeleteAll deletes all rows in the slice, using an executor.
|
||||
func (o UsersPermissionSlice) DeleteAll(ctx context.Context, exec boil.ContextExecutor) (int64, error) {
|
||||
if len(o) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
if len(usersPermissionBeforeDeleteHooks) != 0 {
|
||||
for _, obj := range o {
|
||||
if err := obj.doBeforeDeleteHooks(ctx, exec); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var args []interface{}
|
||||
for _, obj := range o {
|
||||
pkeyArgs := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(obj)), usersPermissionPrimaryKeyMapping)
|
||||
args = append(args, pkeyArgs...)
|
||||
}
|
||||
|
||||
sql := "DELETE FROM \"users_permissions\" WHERE " +
|
||||
strmangle.WhereClauseRepeated(string(dialect.LQ), string(dialect.RQ), 1, usersPermissionPrimaryKeyColumns, len(o))
|
||||
|
||||
if boil.IsDebug(ctx) {
|
||||
writer := boil.DebugWriterFrom(ctx)
|
||||
fmt.Fprintln(writer, sql)
|
||||
fmt.Fprintln(writer, args)
|
||||
}
|
||||
result, err := exec.ExecContext(ctx, sql, args...)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "sqlboilergen: unable to delete all from usersPermission slice")
|
||||
}
|
||||
|
||||
rowsAff, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "sqlboilergen: failed to get rows affected by deleteall for users_permissions")
|
||||
}
|
||||
|
||||
if len(usersPermissionAfterDeleteHooks) != 0 {
|
||||
for _, obj := range o {
|
||||
if err := obj.doAfterDeleteHooks(ctx, exec); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rowsAff, nil
|
||||
}
|
||||
|
||||
// Reload refetches the object from the database
|
||||
// using the primary keys with an executor.
|
||||
func (o *UsersPermission) Reload(ctx context.Context, exec boil.ContextExecutor) error {
|
||||
ret, err := FindUsersPermission(ctx, exec, o.UserID, o.PostID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*o = *ret
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReloadAll refetches every row with matching primary key column values
|
||||
// and overwrites the original object slice with the newly updated slice.
|
||||
func (o *UsersPermissionSlice) ReloadAll(ctx context.Context, exec boil.ContextExecutor) error {
|
||||
if o == nil || len(*o) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
slice := UsersPermissionSlice{}
|
||||
var args []interface{}
|
||||
for _, obj := range *o {
|
||||
pkeyArgs := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(obj)), usersPermissionPrimaryKeyMapping)
|
||||
args = append(args, pkeyArgs...)
|
||||
}
|
||||
|
||||
sql := "SELECT \"users_permissions\".* FROM \"users_permissions\" WHERE " +
|
||||
strmangle.WhereClauseRepeated(string(dialect.LQ), string(dialect.RQ), 1, usersPermissionPrimaryKeyColumns, len(*o))
|
||||
|
||||
q := queries.Raw(sql, args...)
|
||||
|
||||
err := q.Bind(ctx, exec, &slice)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "sqlboilergen: unable to reload all in UsersPermissionSlice")
|
||||
}
|
||||
|
||||
*o = slice
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UsersPermissionExists checks if the UsersPermission row exists.
|
||||
func UsersPermissionExists(ctx context.Context, exec boil.ContextExecutor, userID int, postID int) (bool, error) {
|
||||
var exists bool
|
||||
sql := "select exists(select 1 from \"users_permissions\" where \"user_id\"=$1 AND \"post_id\"=$2 limit 1)"
|
||||
|
||||
if boil.IsDebug(ctx) {
|
||||
writer := boil.DebugWriterFrom(ctx)
|
||||
fmt.Fprintln(writer, sql)
|
||||
fmt.Fprintln(writer, userID, postID)
|
||||
}
|
||||
row := exec.QueryRowContext(ctx, sql, userID, postID)
|
||||
|
||||
err := row.Scan(&exists)
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "sqlboilergen: unable to check if users_permissions exists")
|
||||
}
|
||||
|
||||
return exists, nil
|
||||
}
|
8
benchmarks/sqlc.yaml
Normal file
8
benchmarks/sqlc.yaml
Normal file
@ -0,0 +1,8 @@
|
||||
version: 1
|
||||
packages:
|
||||
- path: "sqlcgen"
|
||||
name: "sqlcgen"
|
||||
engine: "postgresql"
|
||||
schema: "schema.sql"
|
||||
queries: "sqlcgen/queries.sql"
|
||||
emit_prepared_queries: true
|
108
benchmarks/sqlcgen/db.go
Normal file
108
benchmarks/sqlcgen/db.go
Normal file
@ -0,0 +1,108 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.29.0
|
||||
|
||||
package sqlcgen
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type DBTX interface {
|
||||
ExecContext(context.Context, string, ...interface{}) (sql.Result, error)
|
||||
PrepareContext(context.Context, string) (*sql.Stmt, error)
|
||||
QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error)
|
||||
QueryRowContext(context.Context, string, ...interface{}) *sql.Row
|
||||
}
|
||||
|
||||
func New(db DBTX) *Queries {
|
||||
return &Queries{db: db}
|
||||
}
|
||||
|
||||
func Prepare(ctx context.Context, db DBTX) (*Queries, error) {
|
||||
q := Queries{db: db}
|
||||
var err error
|
||||
if q.getUserStmt, err = db.PrepareContext(ctx, getUser); err != nil {
|
||||
return nil, fmt.Errorf("error preparing query GetUser: %w", err)
|
||||
}
|
||||
if q.insertUserStmt, err = db.PrepareContext(ctx, insertUser); err != nil {
|
||||
return nil, fmt.Errorf("error preparing query InsertUser: %w", err)
|
||||
}
|
||||
if q.list10UsersStmt, err = db.PrepareContext(ctx, list10Users); err != nil {
|
||||
return nil, fmt.Errorf("error preparing query List10Users: %w", err)
|
||||
}
|
||||
return &q, nil
|
||||
}
|
||||
|
||||
func (q *Queries) Close() error {
|
||||
var err error
|
||||
if q.getUserStmt != nil {
|
||||
if cerr := q.getUserStmt.Close(); cerr != nil {
|
||||
err = fmt.Errorf("error closing getUserStmt: %w", cerr)
|
||||
}
|
||||
}
|
||||
if q.insertUserStmt != nil {
|
||||
if cerr := q.insertUserStmt.Close(); cerr != nil {
|
||||
err = fmt.Errorf("error closing insertUserStmt: %w", cerr)
|
||||
}
|
||||
}
|
||||
if q.list10UsersStmt != nil {
|
||||
if cerr := q.list10UsersStmt.Close(); cerr != nil {
|
||||
err = fmt.Errorf("error closing list10UsersStmt: %w", cerr)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (q *Queries) exec(ctx context.Context, stmt *sql.Stmt, query string, args ...interface{}) (sql.Result, error) {
|
||||
switch {
|
||||
case stmt != nil && q.tx != nil:
|
||||
return q.tx.StmtContext(ctx, stmt).ExecContext(ctx, args...)
|
||||
case stmt != nil:
|
||||
return stmt.ExecContext(ctx, args...)
|
||||
default:
|
||||
return q.db.ExecContext(ctx, query, args...)
|
||||
}
|
||||
}
|
||||
|
||||
func (q *Queries) query(ctx context.Context, stmt *sql.Stmt, query string, args ...interface{}) (*sql.Rows, error) {
|
||||
switch {
|
||||
case stmt != nil && q.tx != nil:
|
||||
return q.tx.StmtContext(ctx, stmt).QueryContext(ctx, args...)
|
||||
case stmt != nil:
|
||||
return stmt.QueryContext(ctx, args...)
|
||||
default:
|
||||
return q.db.QueryContext(ctx, query, args...)
|
||||
}
|
||||
}
|
||||
|
||||
func (q *Queries) queryRow(ctx context.Context, stmt *sql.Stmt, query string, args ...interface{}) *sql.Row {
|
||||
switch {
|
||||
case stmt != nil && q.tx != nil:
|
||||
return q.tx.StmtContext(ctx, stmt).QueryRowContext(ctx, args...)
|
||||
case stmt != nil:
|
||||
return stmt.QueryRowContext(ctx, args...)
|
||||
default:
|
||||
return q.db.QueryRowContext(ctx, query, args...)
|
||||
}
|
||||
}
|
||||
|
||||
type Queries struct {
|
||||
db DBTX
|
||||
tx *sql.Tx
|
||||
getUserStmt *sql.Stmt
|
||||
insertUserStmt *sql.Stmt
|
||||
list10UsersStmt *sql.Stmt
|
||||
}
|
||||
|
||||
func (q *Queries) WithTx(tx *sql.Tx) *Queries {
|
||||
return &Queries{
|
||||
db: tx,
|
||||
tx: tx,
|
||||
getUserStmt: q.getUserStmt,
|
||||
insertUserStmt: q.insertUserStmt,
|
||||
list10UsersStmt: q.list10UsersStmt,
|
||||
}
|
||||
}
|
11
benchmarks/sqlcgen/models.go
Normal file
11
benchmarks/sqlcgen/models.go
Normal file
@ -0,0 +1,11 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.29.0
|
||||
|
||||
package sqlcgen
|
||||
|
||||
type User struct {
|
||||
ID int32
|
||||
Name string
|
||||
Age int32
|
||||
}
|
11
benchmarks/sqlcgen/queries.sql
Normal file
11
benchmarks/sqlcgen/queries.sql
Normal file
@ -0,0 +1,11 @@
|
||||
-- name: InsertUser :one
|
||||
INSERT INTO users(name, age)
|
||||
VALUES ($1, $2) RETURNING id;
|
||||
|
||||
-- name: GetUser :one
|
||||
SELECT id, name, age FROM users
|
||||
OFFSET $1 LIMIT 1;
|
||||
|
||||
-- name: List10Users :many
|
||||
SELECT id, name, age FROM users
|
||||
OFFSET $1 LIMIT 10;
|
67
benchmarks/sqlcgen/queries.sql.go
Normal file
67
benchmarks/sqlcgen/queries.sql.go
Normal file
@ -0,0 +1,67 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.29.0
|
||||
// source: queries.sql
|
||||
|
||||
package sqlcgen
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
const getUser = `-- name: GetUser :one
|
||||
SELECT id, name, age FROM users
|
||||
OFFSET $1 LIMIT 1
|
||||
`
|
||||
|
||||
func (q *Queries) GetUser(ctx context.Context, offset int32) (User, error) {
|
||||
row := q.queryRow(ctx, q.getUserStmt, getUser, offset)
|
||||
var i User
|
||||
err := row.Scan(&i.ID, &i.Name, &i.Age)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const insertUser = `-- name: InsertUser :one
|
||||
INSERT INTO users(name, age)
|
||||
VALUES ($1, $2) RETURNING id
|
||||
`
|
||||
|
||||
type InsertUserParams struct {
|
||||
Name string
|
||||
Age int32
|
||||
}
|
||||
|
||||
func (q *Queries) InsertUser(ctx context.Context, arg InsertUserParams) (int32, error) {
|
||||
row := q.queryRow(ctx, q.insertUserStmt, insertUser, arg.Name, arg.Age)
|
||||
var id int32
|
||||
err := row.Scan(&id)
|
||||
return id, err
|
||||
}
|
||||
|
||||
const list10Users = `-- name: List10Users :many
|
||||
SELECT id, name, age FROM users
|
||||
OFFSET $1 LIMIT 10
|
||||
`
|
||||
|
||||
func (q *Queries) List10Users(ctx context.Context, offset int32) ([]User, error) {
|
||||
rows, err := q.query(ctx, q.list10UsersStmt, list10Users, offset)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []User
|
||||
for rows.Next() {
|
||||
var i User
|
||||
if err := rows.Scan(&i.ID, &i.Name, &i.Age); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
@ -2,5 +2,7 @@ coverage:
|
||||
ignore:
|
||||
- "internal/**/*"
|
||||
- "examples/**/*"
|
||||
- "kbuilder/*"
|
||||
- "internal/kbuilder/*"
|
||||
- "kstructs/*"
|
||||
- "test_adapters.go"
|
||||
- "internal_mocks.go"
|
||||
|
39
contracts.go
39
contracts.go
@ -5,13 +5,31 @@ import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/vingarcia/ksql/sqldialect"
|
||||
)
|
||||
|
||||
// ErrRecordNotFound ...
|
||||
var ErrRecordNotFound error = errors.Wrap(sql.ErrNoRows, "ksql: the query returned no results")
|
||||
// ErrRecordNotFound informs that a given query failed because the record was not found.
|
||||
// This error can be returned by the following methods: Patch(), QueryOne() and Delete().
|
||||
var ErrRecordNotFound error = fmt.Errorf("ksql: the query returned no results: %w", sql.ErrNoRows)
|
||||
|
||||
// ErrAbortIteration ...
|
||||
// ErrNoValuesToUpdate informs the error of trying to make an update that would not change any attributes.
|
||||
//
|
||||
// This could happen if all the non-ID attributes of the struct are being ignored or if they don't exist.
|
||||
//
|
||||
// Since ID attributes are ignored by the Patch() method updating a struct that only have IDs will result in this error.
|
||||
// And this error will also occur if the struct does have some non-ID attributes but they are all being ignored.
|
||||
//
|
||||
// The reasons that can cause an attribute to be ignored in the Patch() function are:
|
||||
// (1) If it is a nil pointer, Patch() will just ignore it.
|
||||
// (2) If the attribute is using a modifier that contains the SkipUpdates flag.
|
||||
var ErrNoValuesToUpdate error = fmt.Errorf("ksql: the input struct contains no values to update")
|
||||
|
||||
// ErrRecordMissingIDs is returned by the Update or Delete functions if an input record does
|
||||
// not have all of the IDs described on the input table.
|
||||
var ErrRecordMissingIDs error = fmt.Errorf("ksql: missing required ID fields")
|
||||
|
||||
// ErrAbortIteration should be used inside the QueryChunks function to inform QueryChunks it should stop querying,
|
||||
// close the connection and return with no errors.
|
||||
var ErrAbortIteration error = fmt.Errorf("ksql: abort iteration, should only be used inside QueryChunks function")
|
||||
|
||||
// Provider describes the ksql public behavior.
|
||||
@ -23,9 +41,6 @@ type Provider interface {
|
||||
Patch(ctx context.Context, table Table, record interface{}) error
|
||||
Delete(ctx context.Context, table Table, idOrRecord interface{}) error
|
||||
|
||||
// Deprecated: use the Patch() method instead.
|
||||
Update(ctx context.Context, table Table, record interface{}) error
|
||||
|
||||
Query(ctx context.Context, records interface{}, query string, params ...interface{}) error
|
||||
QueryOne(ctx context.Context, record interface{}, query string, params ...interface{}) error
|
||||
QueryChunks(ctx context.Context, parser ChunkParser) error
|
||||
@ -38,7 +53,7 @@ type Provider interface {
|
||||
// deleting entities from the database by ID using the 3 helper functions
|
||||
// created for that purpose.
|
||||
type Table struct {
|
||||
// this name must be set in order to use the Insert, Delete and Update helper
|
||||
// this name must be set in order to use the Insert, Delete and Patch helper
|
||||
// functions. If you only intend to make queries or to use the Exec function
|
||||
// it is safe to leave this field unset.
|
||||
name string
|
||||
@ -55,7 +70,7 @@ type Table struct {
|
||||
// This Table is required only for using the helper methods:
|
||||
//
|
||||
// - Insert
|
||||
// - Update
|
||||
// - Patch
|
||||
// - Delete
|
||||
//
|
||||
// Passing multiple ID columns will be interpreted
|
||||
@ -89,14 +104,14 @@ func (t Table) validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t Table) insertMethodFor(dialect Dialect) insertMethod {
|
||||
func (t Table) insertMethodFor(dialect sqldialect.Provider) sqldialect.InsertMethod {
|
||||
if len(t.idColumns) == 1 {
|
||||
return dialect.InsertMethod()
|
||||
}
|
||||
|
||||
insertMethod := dialect.InsertMethod()
|
||||
if insertMethod == insertWithLastInsertID {
|
||||
return insertWithNoIDRetrieval
|
||||
if insertMethod == sqldialect.InsertWithLastInsertID {
|
||||
return sqldialect.InsertWithNoIDRetrieval
|
||||
}
|
||||
|
||||
return insertMethod
|
||||
|
115
dialect.go
115
dialect.go
@ -1,115 +0,0 @@
|
||||
package ksql
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type insertMethod int
|
||||
|
||||
const (
|
||||
insertWithReturning insertMethod = iota
|
||||
insertWithOutput
|
||||
insertWithLastInsertID
|
||||
insertWithNoIDRetrieval
|
||||
)
|
||||
|
||||
var supportedDialects = map[string]Dialect{
|
||||
"postgres": &postgresDialect{},
|
||||
"sqlite3": &sqlite3Dialect{},
|
||||
"mysql": &mysqlDialect{},
|
||||
"sqlserver": &sqlserverDialect{},
|
||||
}
|
||||
|
||||
// Dialect is used to represent the different ways
|
||||
// of writing SQL queries used by each SQL driver.
|
||||
type Dialect interface {
|
||||
InsertMethod() insertMethod
|
||||
Escape(str string) string
|
||||
Placeholder(idx int) string
|
||||
DriverName() string
|
||||
}
|
||||
|
||||
type postgresDialect struct{}
|
||||
|
||||
func (postgresDialect) DriverName() string {
|
||||
return "postgres"
|
||||
}
|
||||
|
||||
func (postgresDialect) InsertMethod() insertMethod {
|
||||
return insertWithReturning
|
||||
}
|
||||
|
||||
func (postgresDialect) Escape(str string) string {
|
||||
return `"` + str + `"`
|
||||
}
|
||||
|
||||
func (postgresDialect) Placeholder(idx int) string {
|
||||
return "$" + strconv.Itoa(idx+1)
|
||||
}
|
||||
|
||||
type sqlite3Dialect struct{}
|
||||
|
||||
func (sqlite3Dialect) DriverName() string {
|
||||
return "sqlite3"
|
||||
}
|
||||
|
||||
func (sqlite3Dialect) InsertMethod() insertMethod {
|
||||
return insertWithLastInsertID
|
||||
}
|
||||
|
||||
func (sqlite3Dialect) Escape(str string) string {
|
||||
return "`" + str + "`"
|
||||
}
|
||||
|
||||
func (sqlite3Dialect) Placeholder(idx int) string {
|
||||
return "?"
|
||||
}
|
||||
|
||||
// GetDriverDialect instantiantes the dialect for the
|
||||
// provided driver string, if the drive is not supported
|
||||
// it returns an error
|
||||
func GetDriverDialect(driver string) (Dialect, error) {
|
||||
dialect, found := supportedDialects[driver]
|
||||
if !found {
|
||||
return nil, fmt.Errorf("unsupported driver `%s`", driver)
|
||||
}
|
||||
|
||||
return dialect, nil
|
||||
}
|
||||
|
||||
type mysqlDialect struct{}
|
||||
|
||||
func (mysqlDialect) DriverName() string {
|
||||
return "mysql"
|
||||
}
|
||||
|
||||
func (mysqlDialect) InsertMethod() insertMethod {
|
||||
return insertWithLastInsertID
|
||||
}
|
||||
|
||||
func (mysqlDialect) Escape(str string) string {
|
||||
return "`" + str + "`"
|
||||
}
|
||||
|
||||
func (mysqlDialect) Placeholder(idx int) string {
|
||||
return "?"
|
||||
}
|
||||
|
||||
type sqlserverDialect struct{}
|
||||
|
||||
func (sqlserverDialect) DriverName() string {
|
||||
return "sqlserver"
|
||||
}
|
||||
|
||||
func (sqlserverDialect) InsertMethod() insertMethod {
|
||||
return insertWithOutput
|
||||
}
|
||||
|
||||
func (sqlserverDialect) Escape(str string) string {
|
||||
return `[` + str + `]`
|
||||
}
|
||||
|
||||
func (sqlserverDialect) Placeholder(idx int) string {
|
||||
return "@p" + strconv.Itoa(idx+1)
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
package ksql
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
tt "github.com/vingarcia/ksql/internal/testtools"
|
||||
)
|
||||
|
||||
func TestGetDriverDialect(t *testing.T) {
|
||||
t.Run("should work for all registered drivers", func(t *testing.T) {
|
||||
for drivername, expectedDialect := range supportedDialects {
|
||||
t.Run(drivername, func(t *testing.T) {
|
||||
dialect, err := GetDriverDialect(drivername)
|
||||
tt.AssertNoErr(t, err)
|
||||
tt.AssertEqual(t, dialect, expectedDialect)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should report error if no driver is found", func(t *testing.T) {
|
||||
_, err := GetDriverDialect("non-existing-driver")
|
||||
tt.AssertErrContains(t, err, "unsupported driver", "non-existing-driver")
|
||||
})
|
||||
}
|
@ -18,20 +18,25 @@ services:
|
||||
- POSTGRES_DB=${DB_NAME:-ksql}
|
||||
|
||||
mysql:
|
||||
image: mysql
|
||||
image: mariadb:10.8
|
||||
restart: always
|
||||
ports:
|
||||
- "127.0.0.1:3306:3306"
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: mysql
|
||||
MYSQL_DATABASE: ksql
|
||||
MARIADB_ROOT_PASSWORD: mysql
|
||||
MARIADB_DATABASE: ksql
|
||||
|
||||
sqlserver:
|
||||
image: microsoft/mssql-server-linux:2017-latest
|
||||
image: mcr.microsoft.com/mssql/server:2022-latest
|
||||
# The `always` option below will make sure this
|
||||
# container is started when you turn on your machine,
|
||||
# so you don't have to worry about it everytime.
|
||||
restart: always
|
||||
ports:
|
||||
# The 127.0.0.1 prefix makes sure this instance
|
||||
# cannot be accessed externally, so it is ok
|
||||
# for this instante to have no password.
|
||||
- "127.0.0.1:1433:1433"
|
||||
- "127.0.0.1:1434:1434"
|
||||
environment:
|
||||
SA_PASSWORD: "Sqls3rv3r"
|
||||
ACCEPT_EULA: "Y"
|
||||
- SA_PASSWORD=Sqls3rv3r
|
||||
- ACCEPT_EULA=Y
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"github.com/vingarcia/ksql/adapters/kpgx"
|
||||
"github.com/vingarcia/ksql/adapters/ksqlite3"
|
||||
"github.com/vingarcia/ksql/adapters/ksqlserver"
|
||||
ksqlite "github.com/vingarcia/ksql/adapters/modernc-ksqlite"
|
||||
)
|
||||
|
||||
// User ...
|
||||
@ -106,6 +107,26 @@ func main() {
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
// In the definition below, please note that BLOB is
|
||||
// the only type we can use in sqlite for storing JSON.
|
||||
_, err = db.Exec(ctx, `CREATE TABLE IF NOT EXISTS users (
|
||||
id INTEGER PRIMARY KEY,
|
||||
age INTEGER,
|
||||
name TEXT,
|
||||
address BLOB
|
||||
)`)
|
||||
if err != nil {
|
||||
log.Fatalf("unable to create users table: %s", err)
|
||||
}
|
||||
case "sqlite":
|
||||
db, err = ksqlite.New(ctx, "/tmp/ksql.modernc-sqlite", ksql.Config{
|
||||
MaxOpenConns: 1,
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalf("unable to open database: %s", err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
// In the definition below, please note that BLOB is
|
||||
// the only type we can use in sqlite for storing JSON.
|
||||
_, err = db.Exec(ctx, `CREATE TABLE IF NOT EXISTS users (
|
||||
|
@ -3,23 +3,35 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/vingarcia/ksql"
|
||||
"github.com/vingarcia/ksql/adapters/ksqlite3"
|
||||
"github.com/vingarcia/ksql/nullable"
|
||||
)
|
||||
|
||||
// User ...
|
||||
type User struct {
|
||||
ID int `ksql:"id"`
|
||||
Name string `ksql:"name"`
|
||||
Age int `ksql:"age"`
|
||||
|
||||
// This field will be saved as JSON in the database
|
||||
// The following attributes are making use of the KSQL Modifiers,
|
||||
// you can find more about them on our Wiki:
|
||||
//
|
||||
// - https://github.com/VinGarcia/ksql/wiki/Modifiers
|
||||
//
|
||||
|
||||
// The `json` modifier will save the address as JSON in the database
|
||||
Address Address `ksql:"address,json"`
|
||||
|
||||
// The timeNowUTC modifier will set this field to `time.Now().UTC()` before saving it:
|
||||
UpdatedAt time.Time `ksql:"updated_at,timeNowUTC"`
|
||||
|
||||
// The timeNowUTC/skipUpdates modifier will set this field to `time.Now().UTC()` only
|
||||
// when first creating it and ignore it during updates.
|
||||
CreatedAt time.Time `ksql:"created_at,timeNowUTC/skipUpdates"`
|
||||
}
|
||||
|
||||
// PartialUpdateUser ...
|
||||
type PartialUpdateUser struct {
|
||||
ID int `ksql:"id"`
|
||||
Name *string `ksql:"name"`
|
||||
@ -27,28 +39,18 @@ type PartialUpdateUser struct {
|
||||
Address *Address `ksql:"address,json"`
|
||||
}
|
||||
|
||||
// Address ...
|
||||
type Address struct {
|
||||
State string `json:"state"`
|
||||
City string `json:"city"`
|
||||
}
|
||||
|
||||
// UsersTable informs ksql the name of the table and that it can
|
||||
// UsersTable informs KSQL the name of the table and that it can
|
||||
// use the default value for the primary key column name: "id"
|
||||
var UsersTable = ksql.NewTable("users")
|
||||
|
||||
func main() {
|
||||
ctx := context.Background()
|
||||
|
||||
// The available adapters are:
|
||||
// - kpgx.New(ctx, connURL, ksql.Config{})
|
||||
// - kmysql.New(ctx, connURL, ksql.Config{})
|
||||
// - ksqlserver.New(ctx, connURL, ksql.Config{})
|
||||
// - ksqlite3.New(ctx, connURL, ksql.Config{})
|
||||
//
|
||||
// For more detailed examples see:
|
||||
// - `./examples/all_adapters/all_adapters.go`
|
||||
//
|
||||
// In this example we'll use sqlite3:
|
||||
db, err := ksqlite3.New(ctx, "/tmp/hello.sqlite", ksql.Config{
|
||||
MaxOpenConns: 1,
|
||||
@ -64,7 +66,9 @@ func main() {
|
||||
id INTEGER PRIMARY KEY,
|
||||
age INTEGER,
|
||||
name TEXT,
|
||||
address BLOB
|
||||
address BLOB,
|
||||
created_at DATETIME,
|
||||
updated_at DATETIME
|
||||
)`)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
@ -102,7 +106,7 @@ func main() {
|
||||
}
|
||||
|
||||
// Retrieving Cristina, note that if you omit the SELECT part of the query
|
||||
// ksql will build it for you (efficiently) based on the fields from the struct:
|
||||
// KSQL will build it for you (efficiently) based on the fields from the struct:
|
||||
var cris User
|
||||
err = db.QueryOne(ctx, &cris, "FROM users WHERE name = ? ORDER BY id", "Cristina")
|
||||
if err != nil {
|
||||
@ -149,6 +153,8 @@ func main() {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
fmt.Printf("Users: %#v\n", users)
|
||||
|
||||
// Making transactions:
|
||||
err = db.Transaction(ctx, func(db ksql.Provider) error {
|
||||
var cris2 User
|
||||
@ -164,7 +170,7 @@ func main() {
|
||||
})
|
||||
if err != nil {
|
||||
// This will also cause an automatic rollback and then panic again
|
||||
// so that we don't hide the panic inside the KissSQL library
|
||||
// so that we don't hide the panic inside the KSQL library
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
@ -174,6 +180,4 @@ func main() {
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
fmt.Printf("Users: %#v\n", users)
|
||||
}
|
||||
|
@ -162,17 +162,3 @@ func (mr *MockProviderMockRecorder) Transaction(ctx, fn interface{}) *gomock.Cal
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Transaction", reflect.TypeOf((*MockProvider)(nil).Transaction), ctx, fn)
|
||||
}
|
||||
|
||||
// Update mocks base method.
|
||||
func (m *MockProvider) Update(ctx context.Context, table ksql.Table, record interface{}) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Update", ctx, table, record)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Update indicates an expected call of Update.
|
||||
func (mr *MockProviderMockRecorder) Update(ctx, table, record interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockProvider)(nil).Update), ctx, table, record)
|
||||
}
|
||||
|
@ -1,21 +1,84 @@
|
||||
module alladapters
|
||||
|
||||
go 1.14
|
||||
go 1.22
|
||||
|
||||
replace (
|
||||
github.com/vingarcia/ksql => ../
|
||||
github.com/vingarcia/ksql/adapters/kmysql => ../adapters/kmysql
|
||||
github.com/vingarcia/ksql/adapters/kpgx => ../adapters/kpgx
|
||||
github.com/vingarcia/ksql/adapters/ksqlite3 => ../adapters/ksqlite3
|
||||
github.com/vingarcia/ksql/adapters/ksqlserver => ../adapters/ksqlserver
|
||||
)
|
||||
toolchain go1.22.1
|
||||
|
||||
require (
|
||||
github.com/golang/mock v1.6.0
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/vingarcia/ksql v1.4.7
|
||||
github.com/vingarcia/ksql/adapters/kmysql v0.0.0-00010101000000-000000000000
|
||||
github.com/vingarcia/ksql/adapters/kpgx v0.0.0-00010101000000-000000000000
|
||||
github.com/vingarcia/ksql/adapters/ksqlite3 v0.0.0-00010101000000-000000000000
|
||||
github.com/vingarcia/ksql/adapters/ksqlserver v0.0.0-00010101000000-000000000000
|
||||
github.com/jackc/pgtype v1.14.0
|
||||
github.com/jackc/pgx/v5 v5.7.1
|
||||
github.com/ory/dockertest/v3 v3.11.0
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/vingarcia/ksql v1.12.3
|
||||
github.com/vingarcia/ksql/adapters/kmysql v1.10.0
|
||||
github.com/vingarcia/ksql/adapters/kpgx v1.10.0
|
||||
github.com/vingarcia/ksql/adapters/ksqlite3 v1.10.0
|
||||
github.com/vingarcia/ksql/adapters/ksqlserver v1.10.0
|
||||
github.com/vingarcia/ksql/adapters/modernc-ksqlite v1.10.0
|
||||
)
|
||||
|
||||
require (
|
||||
dario.cat/mergo v1.0.0 // indirect
|
||||
filippo.io/edwards25519 v1.1.0 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||
github.com/containerd/continuity v0.4.3 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/denisenkom/go-mssqldb v0.10.0 // indirect
|
||||
github.com/docker/cli v26.1.4+incompatible // indirect
|
||||
github.com/docker/docker v27.1.1+incompatible // indirect
|
||||
github.com/docker/go-connections v0.5.0 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/go-sql-driver/mysql v1.8.1 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe // indirect
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
|
||||
github.com/jackc/pgconn v1.14.1 // indirect
|
||||
github.com/jackc/pgio v1.0.0 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgproto3/v2 v2.3.2 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||
github.com/jackc/pgx/v4 v4.18.1 // indirect
|
||||
github.com/jackc/puddle v1.3.0 // indirect
|
||||
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/mattn/go-isatty v0.0.16 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.16 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||
github.com/moby/term v0.5.0 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.0 // indirect
|
||||
github.com/opencontainers/runc v1.1.13 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
|
||||
golang.org/x/crypto v0.27.0 // indirect
|
||||
golang.org/x/mod v0.17.0 // indirect
|
||||
golang.org/x/sync v0.8.0 // indirect
|
||||
golang.org/x/sys v0.25.0 // indirect
|
||||
golang.org/x/text v0.18.0 // indirect
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
lukechampine.com/uint128 v1.2.0 // indirect
|
||||
modernc.org/cc/v3 v3.40.0 // indirect
|
||||
modernc.org/ccgo/v3 v3.16.13 // indirect
|
||||
modernc.org/libc v1.24.1 // indirect
|
||||
modernc.org/mathutil v1.5.0 // indirect
|
||||
modernc.org/memory v1.6.0 // indirect
|
||||
modernc.org/opt v0.1.3 // indirect
|
||||
modernc.org/sqlite v1.26.0 // indirect
|
||||
modernc.org/strutil v1.1.3 // indirect
|
||||
modernc.org/token v1.0.1 // indirect
|
||||
)
|
||||
|
261
examples/go.sum
261
examples/go.sum
@ -1,13 +1,18 @@
|
||||
bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512/go.mod h1:FbcW6z/2VytnFDhZfumh8Ss8zxHE6qpMP5sHTRe0EaM=
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
||||
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
|
||||
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
|
||||
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
||||
github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||
github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
|
||||
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
@ -18,15 +23,21 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E=
|
||||
github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY=
|
||||
github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic=
|
||||
github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
|
||||
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
|
||||
github.com/containerd/continuity v0.2.2 h1:QSqfxcn8c+12slxwu00AtzXrsami0MJb/MQs9lOLHLA=
|
||||
github.com/containerd/continuity v0.2.2/go.mod h1:pWygW9u7LtS1o4N/Tn0FoCFDIXZ7rxcMX7HX1Dmibvk=
|
||||
github.com/containerd/continuity v0.4.3 h1:6HVkalIp+2u1ZLH1J/pYX2oBVXlJZvh1X1A7bEZ9Su8=
|
||||
github.com/containerd/continuity v0.4.3/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
@ -37,6 +48,9 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
||||
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
||||
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=
|
||||
@ -45,11 +59,19 @@ github.com/denisenkom/go-mssqldb v0.10.0 h1:QykgLZBorFE95+gO3u9esLd0BmbvpWp0/waN
|
||||
github.com/denisenkom/go-mssqldb v0.10.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
github.com/docker/cli v26.1.4+incompatible h1:I8PHdc0MtxEADqYJZvhBrW9bo8gawKwwenxRM7/rLu8=
|
||||
github.com/docker/cli v26.1.4+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/docker v27.1.1+incompatible h1:hO/M4MtV36kzKldqnA37IWhebRA+LnqqcqDja6kVaKY=
|
||||
github.com/docker/docker v27.1.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
|
||||
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
|
||||
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
|
||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
@ -58,8 +80,9 @@ github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vb
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
||||
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
@ -67,6 +90,8 @@ github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPh
|
||||
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
@ -80,19 +105,28 @@ github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgj
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.5.3/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.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
|
||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gotestyourself/gotestyourself v2.2.0+incompatible h1:AQwinXlbQR2HvPjQZOmDhRqsv5mZf+Jb1RnSLxcqZcI=
|
||||
github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=
|
||||
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
|
||||
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||
github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
|
||||
@ -103,8 +137,9 @@ github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsU
|
||||
github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o=
|
||||
github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY=
|
||||
github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
|
||||
github.com/jackc/pgconn v1.10.0 h1:4EYhlDVEMsJ30nNj0mmgwIUXoq7e9sMJrVC2ED6QlCU=
|
||||
github.com/jackc/pgconn v1.10.0/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
|
||||
github.com/jackc/pgconn v1.14.0/go.mod h1:9mBNlny0UvkgJdCDvdVHYSjI+8tD2rnKK69Wz8ti++E=
|
||||
github.com/jackc/pgconn v1.14.1 h1:smbxIaZA08n6YuxEX1sDyjV/qkbtUtkH20qLkR9MUR4=
|
||||
github.com/jackc/pgconn v1.14.1/go.mod h1:9mBNlny0UvkgJdCDvdVHYSjI+8tD2rnKK69Wz8ti++E=
|
||||
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
|
||||
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
|
||||
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
|
||||
@ -113,78 +148,105 @@ github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65 h1:DadwsjnMwFjfWc9y5W
|
||||
github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak=
|
||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
github.com/jackc/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A=
|
||||
github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
|
||||
github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||
github.com/jackc/pgproto3/v2 v2.1.1 h1:7PQ/4gLoqnl87ZxL7xjO0DR5gYuviDCZxQJsUlFW1eI=
|
||||
github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg=
|
||||
github.com/jackc/pgproto3/v2 v2.3.2 h1:7eY55bdBeCz1F2fTzSz69QC+pG46jYq9/jtSPiJ5nn0=
|
||||
github.com/jackc/pgproto3/v2 v2.3.2/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=
|
||||
github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
|
||||
github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
|
||||
github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM=
|
||||
github.com/jackc/pgtype v1.8.1 h1:9k0IXtdJXHJbyAWQgbWr1lU+MEhPXZz6RIXxfR5oxXs=
|
||||
github.com/jackc/pgtype v1.8.1/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
|
||||
github.com/jackc/pgtype v1.14.0 h1:y+xUdabmyMkJLyApYuPj38mW+aAIqCe5uuBB51rH3Vw=
|
||||
github.com/jackc/pgtype v1.14.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
|
||||
github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
|
||||
github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
|
||||
github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
|
||||
github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs=
|
||||
github.com/jackc/pgx/v4 v4.13.0 h1:JCjhT5vmhMAf/YwBHLvrBn4OGdIQBiFG6ym8Zmdx570=
|
||||
github.com/jackc/pgx/v4 v4.13.0/go.mod h1:9P4X524sErlaxj0XSGZk7s+LD0eOyu1ZDUrrpznYDF0=
|
||||
github.com/jackc/pgx/v4 v4.18.1 h1:YP7G1KABtKpB5IHrO9vYwSrCOhs7p3uqhvhhQBptya0=
|
||||
github.com/jackc/pgx/v4 v4.18.1/go.mod h1:FydWkUyadDmdNH/mHnGob881GawxeEm7TcMCzkb+qQE=
|
||||
github.com/jackc/pgx/v5 v5.7.1 h1:x7SYsPBYDkHDksogeSmZZ5xzThcTgRz++I5E+ePFUcs=
|
||||
github.com/jackc/pgx/v5 v5.7.1/go.mod h1:e7O26IywZZ+naJtWWos6i6fvWK+29etgITqrqHLfoZA=
|
||||
github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v1.1.3 h1:JnPg/5Q9xVJGfjsO5CPUOjnJps1JaRUm8I9FXVCFK94=
|
||||
github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v1.3.0 h1:eHK/5clGOatcjX3oWGBO/MpxpbHzSwud5EWTSCI+MX0=
|
||||
github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
||||
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk=
|
||||
github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-sqlite3 v1.14.12 h1:TJ1bhYJPV44phC+IMu1u2K/i5RriLTPe+yc68XDJ1Z0=
|
||||
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
|
||||
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
|
||||
github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
|
||||
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
|
||||
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
|
||||
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
|
||||
github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/opencontainers/runc v1.1.0 h1:O9+X96OcDjkmmZyfaG996kV7yq8HsoU2h1XRRQcefG8=
|
||||
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
|
||||
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
|
||||
github.com/opencontainers/runc v1.1.0/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc=
|
||||
github.com/opencontainers/runc v1.1.13 h1:98S2srgG9vw0zWcDpFMn5TRrh8kLxa/5OFUstuUhmRs=
|
||||
github.com/opencontainers/runc v1.1.13/go.mod h1:R016aXacfp/gwQBYw2FDGa9m+n6atbLWrYY8hNMT/sA=
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
|
||||
github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA=
|
||||
github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs=
|
||||
github.com/ory/dockertest/v3 v3.11.0 h1:OiHcxKAvSDUwsEVh2BjxQQc/5EHz9n0va9awCtNGuyA=
|
||||
github.com/ory/dockertest/v3 v3.11.0/go.mod h1:VIPxS1gwT9NpPOrfD3rACs8Y9Z7yhzO4SB194iUDnUI=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@ -201,8 +263,13 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
||||
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
||||
@ -217,8 +284,9 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
@ -230,22 +298,52 @@ github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/y
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
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/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
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.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
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=
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/vingarcia/ksql v1.10.0/go.mod h1:b2hDFu+P/Ei7sf2Jh39ajnoOMmj9lzPmDq2QYIqD+dg=
|
||||
github.com/vingarcia/ksql v1.12.3 h1:1LVRGW39XPaYltPHNQsvHms+bWHp8e99sxQx+aEXDMQ=
|
||||
github.com/vingarcia/ksql v1.12.3/go.mod h1:DHp/nhVu1nHpBBXH/FRw6JLgIcvcM3+uo2+PfUNdo0g=
|
||||
github.com/vingarcia/ksql/adapters/kmysql v1.10.0 h1:mOW5I5Tce4tuLhbGuF4en8Lou8tK+3TZgJtqr3+PURI=
|
||||
github.com/vingarcia/ksql/adapters/kmysql v1.10.0/go.mod h1:0XfdHKGbbs0LO+mLPLjZ8668pnJgWX/WdWM17XFdmqw=
|
||||
github.com/vingarcia/ksql/adapters/kpgx v1.10.0 h1:HL08okK/0mxk7thiNu/kasDgkUNuSg2zQwbA1/lu720=
|
||||
github.com/vingarcia/ksql/adapters/kpgx v1.10.0/go.mod h1:ia5rXa7pCSTr1rjvRi44pyzP4qY5ii/V+aO/0959F88=
|
||||
github.com/vingarcia/ksql/adapters/ksqlite3 v1.10.0 h1:4itJ3CXGENOJ/DS6MC16KWRaauxE2957QjLa6hPU3B0=
|
||||
github.com/vingarcia/ksql/adapters/ksqlite3 v1.10.0/go.mod h1:R7FQjMYTpJM+aP+S3/gmyZvrevqkkaHiaYuzvQMacQs=
|
||||
github.com/vingarcia/ksql/adapters/ksqlserver v1.10.0 h1:0ckgsUeBsvZLqPUaPZiPnPgD/vWds2xKfAUGlWuxbIg=
|
||||
github.com/vingarcia/ksql/adapters/ksqlserver v1.10.0/go.mod h1:YQSyNbFT2xuU+Zh2EPRI9RcOpt8G2bT/5mp9anJI2RE=
|
||||
github.com/vingarcia/ksql/adapters/modernc-ksqlite v1.10.0 h1:beTB4s+ntu6g+LSr3APoctpN0jlqRtCg2iq7bue7FHE=
|
||||
github.com/vingarcia/ksql/adapters/modernc-ksqlite v1.10.0/go.mod h1:pJQ3//BhgRKJynCEi8lUiiPoheLdMOwvdKBp91KpgqM=
|
||||
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
@ -269,14 +367,24 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
|
||||
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
|
||||
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@ -285,18 +393,30 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@ -313,6 +433,7 @@ golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -323,18 +444,35 @@ golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86 h1:A9i04dxx7Cribqbs8jf3FQLogkL/CV2YN7hj9KWJCkc=
|
||||
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
||||
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
|
||||
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@ -347,13 +485,19 @@ golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtn
|
||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
@ -363,17 +507,64 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
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=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
|
||||
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
||||
lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI=
|
||||
lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
||||
modernc.org/cc/v3 v3.37.0/go.mod h1:vtL+3mdHx/wcj3iEGz84rQa8vEqR6XM84v5Lcvfph20=
|
||||
modernc.org/cc/v3 v3.40.0 h1:P3g79IUS/93SYhtoeaHW+kRCIrYaxJ27MFPv+7kaTOw=
|
||||
modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0=
|
||||
modernc.org/ccgo/v3 v3.0.0-20220904174949-82d86e1b6d56/go.mod h1:YSXjPL62P2AMSxBphRHPn7IkzhVHqkvOnRKAKh+W6ZI=
|
||||
modernc.org/ccgo/v3 v3.16.13-0.20221017192402-261537637ce8/go.mod h1:fUB3Vn0nVPReA+7IG7yZDfjv1TMWjhQP8gCxrFAtL5g=
|
||||
modernc.org/ccgo/v3 v3.16.13 h1:Mkgdzl46i5F/CNR/Kj80Ri59hC8TKAhZrYSaqvkwzUw=
|
||||
modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY=
|
||||
modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk=
|
||||
modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
|
||||
modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM=
|
||||
modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
|
||||
modernc.org/libc v1.17.4/go.mod h1:WNg2ZH56rDEwdropAJeZPQkXmDwh+JCA1s/htl6r2fA=
|
||||
modernc.org/libc v1.20.3/go.mod h1:ZRfIaEkgrYgZDl6pa4W39HgN5G/yDW+NRmNKZBDFrk0=
|
||||
modernc.org/libc v1.21.4/go.mod h1:przBsL5RDOZajTVslkugzLBj1evTue36jEomFQOoYuI=
|
||||
modernc.org/libc v1.22.5/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY=
|
||||
modernc.org/libc v1.24.1 h1:uvJSeCKL/AgzBo2yYIPPTy82v21KgGnizcGYfBHaNuM=
|
||||
modernc.org/libc v1.24.1/go.mod h1:FmfO1RLrU3MHJfyi9eYYmZBfi/R+tqZ6+hQ3yQQUkak=
|
||||
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
|
||||
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/memory v1.3.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
||||
modernc.org/memory v1.4.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
||||
modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
||||
modernc.org/memory v1.6.0 h1:i6mzavxrE9a30whzMfwf7XWVODx2r5OYXvU46cirX7o=
|
||||
modernc.org/memory v1.6.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
||||
modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
|
||||
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/sqlite v1.26.0 h1:SocQdLRSYlA8W99V8YH0NES75thx19d9sB/aFc4R8Lw=
|
||||
modernc.org/sqlite v1.26.0/go.mod h1:FL3pVXie73rg3Rii6V/u5BoHlSoyeZeIgKZEgHARyCU=
|
||||
modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY=
|
||||
modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw=
|
||||
modernc.org/tcl v1.15.2 h1:C4ybAYCGJw968e+Me18oW55kD/FexcHbqH2xak1ROSY=
|
||||
modernc.org/tcl v1.15.2/go.mod h1:3+k/ZaEbKrC8ePv8zJWPtBSW0V7Gg9g8rkmhI1Kfs3c=
|
||||
modernc.org/token v1.0.1 h1:A3qvTqOwexpfZZeyI0FeGPDlSWX5pjZu9hF4lU+EKWg=
|
||||
modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
modernc.org/z v1.7.3 h1:zDJf6iHjrnB+WRD88stbXokugjyc0/pB91ri1gO6LZY=
|
||||
modernc.org/z v1.7.3/go.mod h1:Ipv4tsdxZRbQyLq9Q1M6gdbkxYzdlrciF2Hi/lS7nWE=
|
||||
|
90
examples/insert_many/main.go
Normal file
90
examples/insert_many/main.go
Normal file
@ -0,0 +1,90 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/vingarcia/ksql"
|
||||
"github.com/vingarcia/ksql/adapters/ksqlite3"
|
||||
)
|
||||
|
||||
var UsersTable = ksql.NewTable("users")
|
||||
|
||||
type User struct {
|
||||
ID int `ksql:"id"`
|
||||
Name string `ksql:"name"`
|
||||
Age int `ksql:"age"`
|
||||
|
||||
UpdatedAt time.Time `ksql:"updated_at,timeNowUTC"`
|
||||
CreatedAt time.Time `ksql:"created_at,timeNowUTC/skipUpdates"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
ctx := context.Background()
|
||||
|
||||
db, err := ksqlite3.New(ctx, "/tmp/hello.sqlite", ksql.Config{
|
||||
MaxOpenConns: 1,
|
||||
})
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
// In the definition below, please note that BLOB is
|
||||
// the only type we can use in sqlite for storing JSON.
|
||||
_, err = db.Exec(ctx, `CREATE TABLE IF NOT EXISTS users (
|
||||
id INTEGER PRIMARY KEY,
|
||||
age INTEGER,
|
||||
name TEXT,
|
||||
address BLOB,
|
||||
created_at DATETIME,
|
||||
updated_at DATETIME
|
||||
)`)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
db.Exec(ctx, `DELETE FROM users`)
|
||||
|
||||
err = insertManyUsers(ctx, db, []User{
|
||||
{Name: "User1", Age: 22},
|
||||
{Name: "User2", Age: 32},
|
||||
{Name: "User3", Age: 42},
|
||||
})
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
var users []User
|
||||
err = db.Query(ctx, &users, `FROM users WHERE name like 'User%'`)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
b, err := json.MarshalIndent(users, "", " ")
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
fmt.Println("users:", string(b))
|
||||
}
|
||||
|
||||
func insertManyUsers(ctx context.Context, db ksql.Provider, users []User) error {
|
||||
if len(users) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
query := []string{}
|
||||
values := []interface{}{}
|
||||
|
||||
for i, user := range users {
|
||||
query = append(query, fmt.Sprintf(`($%d, $%d, $%d, $%d)`, i*5+1, i*5+2, i*5+3, i*5+4))
|
||||
values = append(values, user.Age, user.Name, time.Now().UTC(), time.Now().UTC())
|
||||
}
|
||||
|
||||
_, err := db.Exec(ctx, `INSERT INTO users (age, name, created_at, updated_at) VALUES `+strings.Join(query, ", "), values...)
|
||||
return err
|
||||
}
|
101
examples/logging_queries/main.go
Normal file
101
examples/logging_queries/main.go
Normal file
@ -0,0 +1,101 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/vingarcia/ksql"
|
||||
"github.com/vingarcia/ksql/adapters/ksqlite3"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
ID int `ksql:"id"`
|
||||
Name string `ksql:"name"`
|
||||
Age int `ksql:"age"`
|
||||
}
|
||||
|
||||
// UsersTable informs KSQL the name of the table and that it can
|
||||
// use the default value for the primary key column name: "id"
|
||||
var UsersTable = ksql.NewTable("users")
|
||||
|
||||
func main() {
|
||||
ctx := context.Background()
|
||||
|
||||
db, err := ksqlite3.New(ctx, "/tmp/hello.sqlite", ksql.Config{
|
||||
MaxOpenConns: 1,
|
||||
})
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
// After we inject a logger, all subsequent queries
|
||||
// will use this logger.
|
||||
//
|
||||
// You can also inject the ksql.ErrorLogger if you only
|
||||
// care about these logs when a query error happens.
|
||||
ctx = ksql.InjectLogger(ctx, ksql.Logger)
|
||||
|
||||
// This logs: {"query":"CREATE TABLE IF NOT EXISTS users (\n\t id INTEGER PRIMARY KEY,\n\t\tage INTEGER,\n\t\tname TEXT\n\t)","params":null}
|
||||
_, err = db.Exec(ctx, `CREATE TABLE IF NOT EXISTS users (
|
||||
id INTEGER PRIMARY KEY,
|
||||
age INTEGER,
|
||||
name TEXT
|
||||
)`)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
// This logs: {"query":"INSERT INTO `users` (`name`, `age`) VALUES (?, ?)","params":["Alison",22]}
|
||||
var alison = User{
|
||||
Name: "Alison",
|
||||
Age: 22,
|
||||
}
|
||||
err = db.Insert(ctx, UsersTable, &alison)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
// This logs: {"query":"SELECT `id`, `name`, `age` FROM users LIMIT 10","params":null}
|
||||
var users []User
|
||||
err = db.Query(ctx, &users, "FROM users LIMIT 10")
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
// This logs: {"query":"SELECT `id`, `name`, `age` FROM users WHERE age < ?","params":[42]}
|
||||
err = db.QueryChunks(ctx, ksql.ChunkParser{
|
||||
Query: "FROM users WHERE age < ?",
|
||||
Params: []interface{}{42},
|
||||
ChunkSize: 100,
|
||||
ForEachChunk: func(chunk []User) error {
|
||||
// Do nothing, since this is just an example
|
||||
return nil
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
// This logs: {"query":"SELECT `id`, `name`, `age` FROM users WHERE name = ?","params":["Alison"]}
|
||||
err = db.QueryOne(ctx, &alison, "FROM users WHERE name = ?", "Alison")
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
// This logs: {"query":"UPDATE `users` SET `name` = ?, `age` = ? WHERE `id` = ?","params":["Alison",23,1]}
|
||||
alison.Age++
|
||||
err = db.Patch(ctx, UsersTable, alison)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
// This logs: {"query":"DELETE FROM `users` WHERE `id` = ?","params":[1]}
|
||||
err = db.Delete(ctx, UsersTable, alison.ID)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
// Here we are provoking an error, so we can see an error on the log:
|
||||
_ = db.QueryOne(ctx, &alison, "not a valid query", "someFakeParams")
|
||||
// This logs: {"query":"not a valid query","params":["someFakeParams"],"error":"error running query: near \"not\": syntax error"}
|
||||
}
|
103
examples/overview/main.go
Normal file
103
examples/overview/main.go
Normal file
@ -0,0 +1,103 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/vingarcia/ksql"
|
||||
"github.com/vingarcia/ksql/adapters/kpgx"
|
||||
)
|
||||
|
||||
var UsersTable = ksql.NewTable("users", "user_id")
|
||||
|
||||
type User struct {
|
||||
ID int `ksql:"user_id"`
|
||||
Name string `ksql:"name"`
|
||||
Type string `ksql:"type"`
|
||||
Posts []Post
|
||||
}
|
||||
|
||||
// Post have a many to one relationship with User
|
||||
var PostsTable = ksql.NewTable("posts", "post_id")
|
||||
|
||||
type Post struct {
|
||||
ID int `ksql:"post_id"`
|
||||
UserID int `ksql:"user_id"`
|
||||
Title string `ksql:"title"`
|
||||
Text string `ksql:"text"`
|
||||
}
|
||||
|
||||
// Address have a one to one relationship with User
|
||||
var AddressesTable = ksql.NewTable("addresses", "id")
|
||||
|
||||
type Address struct {
|
||||
ID int `ksql:"id"`
|
||||
UserID int `ksql:"user_id"`
|
||||
FullAddr string `ksql:"full_addr"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
ctx := context.Background()
|
||||
dbURL, closeDB := startExampleDB(ctx)
|
||||
defer closeDB()
|
||||
|
||||
db, err := kpgx.New(ctx, dbURL, ksql.Config{})
|
||||
if err != nil {
|
||||
log.Fatalf("unable connect to database: %s", err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
// For querying only some attributes you can
|
||||
// create a custom struct like this:
|
||||
var count []struct {
|
||||
Count int `ksql:"count"`
|
||||
Type string `ksql:"type"`
|
||||
}
|
||||
err = db.Query(ctx, &count, "SELECT type, count(*) as count FROM users GROUP BY type")
|
||||
if err != nil {
|
||||
log.Fatalf("unable to query users: %s", err)
|
||||
}
|
||||
|
||||
fmt.Println("number of users by type:", count)
|
||||
|
||||
// For loading entities from the database KSQL can build
|
||||
// the SELECT part of the query for you if you omit it like this:
|
||||
var adminUsers []User
|
||||
err = db.Query(ctx, &adminUsers, "FROM users WHERE type = $1", "admin")
|
||||
if err != nil {
|
||||
log.Fatalf("unable to query admin users: %s", err)
|
||||
}
|
||||
|
||||
fmt.Println("admin users:", adminUsers)
|
||||
|
||||
// A nice way of loading the posts of a user might be like this:
|
||||
var user User
|
||||
err = errors.Join(
|
||||
db.QueryOne(ctx, &user, "FROM users WHERE user_id = $1", 42),
|
||||
db.Query(ctx, &user.Posts, "FROM posts WHERE user_id = $1", user.ID),
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatalf("unable to query users: %s", err)
|
||||
}
|
||||
|
||||
fmt.Println("user with posts:", user)
|
||||
|
||||
// You can retrieve data from joined tables like this
|
||||
// (notice you can either use the name of the table or the alias you choose for it in the query):
|
||||
var rows []struct {
|
||||
OneUser User `tablename:"users"`
|
||||
OneAddress Address `tablename:"addr"`
|
||||
}
|
||||
err = db.Query(ctx, &rows,
|
||||
`FROM users
|
||||
JOIN addresses addr
|
||||
ON users.user_id = addr.user_id`,
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatalf("unable to query users: %s", err)
|
||||
}
|
||||
|
||||
fmt.Println("rows of joined tables:", rows)
|
||||
}
|
165
examples/overview/start_db.go
Normal file
165
examples/overview/start_db.go
Normal file
@ -0,0 +1,165 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
"github.com/ory/dockertest/v3"
|
||||
"github.com/ory/dockertest/v3/docker"
|
||||
"github.com/vingarcia/ksql"
|
||||
"github.com/vingarcia/ksql/adapters/kpgx"
|
||||
)
|
||||
|
||||
func startExampleDB(ctx context.Context) (dbURL string, closer func()) {
|
||||
dbURL, closeDB := startPostgresDB(ctx)
|
||||
db, err := kpgx.New(ctx, dbURL, ksql.Config{})
|
||||
if err != nil {
|
||||
log.Fatalf("startExampleDB(): unable connect to database: %s", err)
|
||||
}
|
||||
|
||||
err = populateDatabase(ctx, db)
|
||||
if err != nil {
|
||||
log.Fatalf("startExampleDB(): error populating example database: %s", err)
|
||||
}
|
||||
|
||||
return dbURL, closeDB
|
||||
}
|
||||
|
||||
func populateDatabase(ctx context.Context, db ksql.DB) error {
|
||||
return errors.Join(
|
||||
exec(ctx, db,
|
||||
`CREATE TABLE users (
|
||||
user_id SERIAL PRIMARY KEY,
|
||||
name VARCHAR NOT NULL,
|
||||
type VARCHAR NOT NULL DEFAULT 'user'
|
||||
)`,
|
||||
),
|
||||
exec(ctx, db,
|
||||
`CREATE TABLE posts (
|
||||
post_id SERIAL PRIMARY KEY,
|
||||
user_id INT NOT NULL REFERENCES users(user_id),
|
||||
title VARCHAR NOT NULL,
|
||||
text VARCHAR NOT NULL
|
||||
)`,
|
||||
),
|
||||
exec(ctx, db,
|
||||
`CREATE TABLE addresses (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id INT NOT NULL REFERENCES users(user_id),
|
||||
full_addr VARCHAR NOT NULL
|
||||
)`,
|
||||
),
|
||||
db.Insert(ctx, UsersTable, &User{
|
||||
ID: 42,
|
||||
Name: "Julia",
|
||||
Type: "admin",
|
||||
}),
|
||||
db.Insert(ctx, UsersTable, &User{
|
||||
ID: 43,
|
||||
Name: "June",
|
||||
Type: "user",
|
||||
}),
|
||||
db.Insert(ctx, UsersTable, &User{
|
||||
ID: 44,
|
||||
Name: "Bob",
|
||||
Type: "user",
|
||||
}),
|
||||
db.Insert(ctx, PostsTable, &Post{
|
||||
Title: "Title1",
|
||||
Text: "How to create foo",
|
||||
UserID: 42,
|
||||
}),
|
||||
db.Insert(ctx, PostsTable, &Post{
|
||||
Title: "Title2",
|
||||
Text: "How to create foo",
|
||||
UserID: 42,
|
||||
}),
|
||||
db.Insert(ctx, PostsTable, &Post{
|
||||
Title: "Title3",
|
||||
Text: "How to create foo",
|
||||
UserID: 43,
|
||||
}),
|
||||
db.Insert(ctx, AddressesTable, &Address{
|
||||
UserID: 42,
|
||||
FullAddr: "Jorge das Flores St. 46",
|
||||
}),
|
||||
db.Insert(ctx, AddressesTable, &Address{
|
||||
UserID: 43,
|
||||
FullAddr: "Maria das Flores St. 47",
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
func exec(ctx context.Context, db ksql.DB, query string, params ...interface{}) error {
|
||||
_, err := db.Exec(ctx, query, params...)
|
||||
return err
|
||||
}
|
||||
|
||||
func startPostgresDB(ctx context.Context) (databaseURL string, closer func()) {
|
||||
dbName := "intro_db"
|
||||
|
||||
// uses a sensible default on windows (tcp/http) and linux/osx (socket)
|
||||
pool, err := dockertest.NewPool("")
|
||||
if err != nil {
|
||||
log.Fatalf("Could not connect to docker: %s", err)
|
||||
}
|
||||
|
||||
fmt.Println("the first time this example runs it will download postgres:14.0, which may take a long time")
|
||||
fmt.Println("if you want to see the download progress stop this program and run `docker pull postgres:14.0` instead")
|
||||
fmt.Println()
|
||||
|
||||
// pulls an image, creates a container based on it and runs it
|
||||
resource, err := pool.RunWithOptions(
|
||||
&dockertest.RunOptions{
|
||||
Repository: "postgres",
|
||||
Tag: "14.0",
|
||||
Env: []string{
|
||||
"POSTGRES_PASSWORD=postgres",
|
||||
"POSTGRES_USER=postgres",
|
||||
"POSTGRES_DB=" + dbName,
|
||||
"listen_addresses = '*'",
|
||||
},
|
||||
},
|
||||
func(config *docker.HostConfig) {
|
||||
// set AutoRemove to true so that stopped container goes away by itself
|
||||
config.AutoRemove = true
|
||||
config.RestartPolicy = docker.RestartPolicy{Name: "no"}
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatalf("Could not start resource: %s", err)
|
||||
}
|
||||
|
||||
hostAndPort := resource.GetHostPort("5432/tcp")
|
||||
databaseUrl := fmt.Sprintf("postgres://postgres:postgres@%s/%s?sslmode=disable", hostAndPort, dbName)
|
||||
|
||||
fmt.Println("Connecting to postgres on url: ", databaseUrl)
|
||||
|
||||
resource.Expire(40) // Tell docker to hard kill the container in 40 seconds
|
||||
|
||||
var sqlDB *pgxpool.Pool
|
||||
// exponential backoff-retry, because the application in the container might not be ready to accept connections yet
|
||||
pool.MaxWait = 10 * time.Second
|
||||
pool.Retry(func() error {
|
||||
sqlDB, err = pgxpool.New(ctx, databaseUrl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sqlDB.Ping(ctx)
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalf("Could not connect to docker: %s", err)
|
||||
}
|
||||
sqlDB.Close()
|
||||
|
||||
return databaseUrl, func() {
|
||||
if err := pool.Purge(resource); err != nil {
|
||||
log.Fatalf("Could not purge resource: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
111
examples/pgxsupport/main.go
Normal file
111
examples/pgxsupport/main.go
Normal file
@ -0,0 +1,111 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/jackc/pgtype"
|
||||
"github.com/vingarcia/ksql"
|
||||
"github.com/vingarcia/ksql/adapters/kpgx"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
ID int `ksql:"id"`
|
||||
Name string `ksql:"name"`
|
||||
}
|
||||
|
||||
type TeamMember struct {
|
||||
TeamID int `ksql:"team_id"`
|
||||
UserID int `ksql:"user_id"`
|
||||
}
|
||||
|
||||
var UsersTable = ksql.NewTable("users", "id")
|
||||
|
||||
var TeamMembersTable = ksql.NewTable("team_members", "user_id", "team_id")
|
||||
|
||||
func main() {
|
||||
ctx := context.Background()
|
||||
|
||||
db, err := kpgx.New(ctx, os.Getenv("PG_URL"), ksql.Config{})
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
db.Exec(ctx, `DROP TABLE team_members`)
|
||||
_, err = db.Exec(ctx, `CREATE TABLE IF NOT EXISTS team_members (
|
||||
user_id INTEGER,
|
||||
team_id INTEGER,
|
||||
PRIMARY KEY (user_id, team_id)
|
||||
)`)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
db.Exec(ctx, `DROP TABLE users`)
|
||||
_, err = db.Exec(ctx, `CREATE TABLE IF NOT EXISTS users (
|
||||
id serial PRIMARY KEY,
|
||||
name TEXT
|
||||
)`)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
u := User{
|
||||
Name: "ExampleUser1",
|
||||
}
|
||||
err = db.Insert(ctx, UsersTable, &u)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
err = db.Insert(ctx, TeamMembersTable, &TeamMember{
|
||||
UserID: u.ID,
|
||||
TeamID: 42,
|
||||
})
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
err = db.Insert(ctx, TeamMembersTable, &TeamMember{
|
||||
UserID: u.ID,
|
||||
TeamID: 43,
|
||||
})
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
err = db.Insert(ctx, TeamMembersTable, &TeamMember{
|
||||
UserID: u.ID,
|
||||
TeamID: 44,
|
||||
})
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
checkIfUserBelongsToTeams(ctx, db, u.ID, []int{1, 2, 42})
|
||||
}
|
||||
|
||||
func checkIfUserBelongsToTeams(ctx context.Context, db ksql.Provider, userID int, teamIDs []int) {
|
||||
// Check if user belongs to either of the input teams:
|
||||
var row struct {
|
||||
Count pgtype.Int8 `ksql:"c"`
|
||||
}
|
||||
err := db.QueryOne(ctx, &row,
|
||||
`SELECT count(*) as c
|
||||
FROM users AS u
|
||||
JOIN team_members AS tm
|
||||
ON u.id = tm.user_id
|
||||
WHERE u.id = $1
|
||||
AND tm.team_id = ANY($2)`,
|
||||
userID,
|
||||
[]int{1, 2, 42}, // Int slices are supported by PGX
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
|
||||
fmt.Printf("Count: %+v\n", row.Count.Int)
|
||||
}
|
9
go.mod
9
go.mod
@ -2,10 +2,9 @@ module github.com/vingarcia/ksql
|
||||
|
||||
go 1.14
|
||||
|
||||
require github.com/stretchr/testify v1.8.1
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/kr/pretty v0.2.1 // indirect
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/stretchr/testify v1.7.0
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
||||
github.com/kr/pretty v0.3.0 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||
)
|
||||
|
27
go.sum
27
go.sum
@ -1,20 +1,31 @@
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
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/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
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/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
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/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.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
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=
|
||||
|
14
go.work.example
Normal file
14
go.work.example
Normal file
@ -0,0 +1,14 @@
|
||||
go 1.23.1
|
||||
|
||||
use (
|
||||
.
|
||||
./adapters/kmysql
|
||||
./adapters/kpgx
|
||||
./adapters/kpgx5
|
||||
./adapters/kpostgres
|
||||
./adapters/ksqlite3
|
||||
./adapters/ksqlserver
|
||||
./adapters/modernc-ksqlite
|
||||
./benchmarks
|
||||
./examples
|
||||
)
|
29
internal/kbuilder/LICENSE
Normal file
29
internal/kbuilder/LICENSE
Normal file
@ -0,0 +1,29 @@
|
||||
Unlicense LICENSE
|
||||
|
||||
Vinícius Garcia (vingarcia00@gmail.com)
|
||||
|
||||
The software contained in the internal/kbuilder directory
|
||||
is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <https://unlicense.org>
|
@ -5,8 +5,8 @@ import (
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/vingarcia/ksql"
|
||||
"github.com/vingarcia/ksql/internal/structs"
|
||||
"github.com/vingarcia/ksql/sqldialect"
|
||||
)
|
||||
|
||||
// Insert is the struct template for building INSERT queries
|
||||
@ -22,16 +22,16 @@ type Insert struct {
|
||||
// Build is a utility function for finding the dialect based on the driver and
|
||||
// then calling BuildQuery(dialect)
|
||||
func (i Insert) Build(driver string) (sqlQuery string, params []interface{}, _ error) {
|
||||
dialect, err := ksql.GetDriverDialect(driver)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
dialect, ok := sqldialect.SupportedDialects[driver]
|
||||
if !ok {
|
||||
return "", nil, fmt.Errorf("unsupported driver `%s`", driver)
|
||||
}
|
||||
|
||||
return i.BuildQuery(dialect)
|
||||
}
|
||||
|
||||
// BuildQuery implements the queryBuilder interface
|
||||
func (i Insert) BuildQuery(dialect ksql.Dialect) (sqlQuery string, params []interface{}, _ error) {
|
||||
func (i Insert) BuildQuery(dialect sqldialect.Provider) (sqlQuery string, params []interface{}, _ error) {
|
||||
var b strings.Builder
|
||||
b.WriteString("INSERT INTO " + dialect.Escape(i.Into))
|
||||
|
||||
@ -81,7 +81,7 @@ func (i Insert) BuildQuery(dialect ksql.Dialect) (sqlQuery string, params []inte
|
||||
b.WriteString(" (")
|
||||
var escapedNames []string
|
||||
for i := 0; i < info.NumFields(); i++ {
|
||||
name := info.ByIndex(i).Name
|
||||
name := info.ByIndex(i).ColumnName
|
||||
escapedNames = append(escapedNames, dialect.Escape(name))
|
||||
}
|
||||
b.WriteString(strings.Join(escapedNames, ", "))
|
@ -3,8 +3,8 @@ package kbuilder_test
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/vingarcia/ksql/internal/kbuilder"
|
||||
tt "github.com/vingarcia/ksql/internal/testtools"
|
||||
"github.com/vingarcia/ksql/kbuilder"
|
||||
)
|
||||
|
||||
func TestInsertQuery(t *testing.T) {
|
@ -1,7 +1,9 @@
|
||||
package kbuilder
|
||||
|
||||
import (
|
||||
"github.com/vingarcia/ksql"
|
||||
"fmt"
|
||||
|
||||
"github.com/vingarcia/ksql/sqldialect"
|
||||
)
|
||||
|
||||
// Builder is the basic container for injecting
|
||||
@ -11,19 +13,23 @@ import (
|
||||
// directly without this builder, but we kept it
|
||||
// here for convenience.
|
||||
type Builder struct {
|
||||
dialect ksql.Dialect
|
||||
dialect sqldialect.Provider
|
||||
}
|
||||
|
||||
type queryBuilder interface {
|
||||
BuildQuery(dialect ksql.Dialect) (sqlQuery string, params []interface{}, _ error)
|
||||
BuildQuery(dialect sqldialect.Provider) (sqlQuery string, params []interface{}, _ error)
|
||||
}
|
||||
|
||||
// New creates a new Builder container.
|
||||
func New(driver string) (Builder, error) {
|
||||
dialect, err := ksql.GetDriverDialect(driver)
|
||||
dialect, ok := sqldialect.SupportedDialects[driver]
|
||||
if !ok {
|
||||
return Builder{}, fmt.Errorf("unsupported driver `%s`", driver)
|
||||
}
|
||||
|
||||
return Builder{
|
||||
dialect: dialect,
|
||||
}, err
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Build receives a query builder struct, injects it with the configurations
|
@ -7,9 +7,8 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/vingarcia/ksql"
|
||||
"github.com/vingarcia/ksql/internal/structs"
|
||||
"github.com/vingarcia/ksql/sqldialect"
|
||||
)
|
||||
|
||||
// Query is is the struct template for building SELECT queries.
|
||||
@ -34,16 +33,16 @@ type Query struct {
|
||||
// Build is a utility function for finding the dialect based on the driver and
|
||||
// then calling BuildQuery(dialect)
|
||||
func (q Query) Build(driver string) (sqlQuery string, params []interface{}, _ error) {
|
||||
dialect, err := ksql.GetDriverDialect(driver)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
dialect, ok := sqldialect.SupportedDialects[driver]
|
||||
if !ok {
|
||||
return "", nil, fmt.Errorf("unsupported driver `%s`", driver)
|
||||
}
|
||||
|
||||
return q.BuildQuery(dialect)
|
||||
}
|
||||
|
||||
// BuildQuery implements the queryBuilder interface
|
||||
func (q Query) BuildQuery(dialect ksql.Dialect) (sqlQuery string, params []interface{}, _ error) {
|
||||
func (q Query) BuildQuery(dialect sqldialect.Provider) (sqlQuery string, params []interface{}, _ error) {
|
||||
var b strings.Builder
|
||||
|
||||
switch v := q.Select.(type) {
|
||||
@ -52,7 +51,7 @@ func (q Query) BuildQuery(dialect ksql.Dialect) (sqlQuery string, params []inter
|
||||
default:
|
||||
selectQuery, err := buildSelectQuery(v, dialect)
|
||||
if err != nil {
|
||||
return "", nil, errors.Wrap(err, "error reading the Select field")
|
||||
return "", nil, fmt.Errorf("error reading the Select field: %w", err)
|
||||
}
|
||||
b.WriteString("SELECT " + selectQuery)
|
||||
}
|
||||
@ -107,7 +106,7 @@ type WhereQuery struct {
|
||||
// in a dynamic way.
|
||||
type WhereQueries []WhereQuery
|
||||
|
||||
func (w WhereQueries) build(dialect ksql.Dialect) (query string, params []interface{}) {
|
||||
func (w WhereQueries) build(dialect sqldialect.Provider) (query string, params []interface{}) {
|
||||
var conds []string
|
||||
for _, whereQuery := range w {
|
||||
var placeholders []interface{}
|
||||
@ -191,7 +190,7 @@ func OrderBy(fields string) OrderByQuery {
|
||||
var cachedSelectQueries = &sync.Map{}
|
||||
|
||||
// Builds the select query using cached info so that its efficient
|
||||
func buildSelectQuery(obj interface{}, dialect ksql.Dialect) (string, error) {
|
||||
func buildSelectQuery(obj interface{}, dialect sqldialect.Provider) (string, error) {
|
||||
t := reflect.TypeOf(obj)
|
||||
if t.Kind() == reflect.Ptr {
|
||||
t = t.Elem()
|
||||
@ -216,7 +215,7 @@ func buildSelectQuery(obj interface{}, dialect ksql.Dialect) (string, error) {
|
||||
|
||||
var escapedNames []string
|
||||
for i := 0; i < info.NumFields(); i++ {
|
||||
name := info.ByIndex(i).Name
|
||||
name := info.ByIndex(i).ColumnName
|
||||
escapedNames = append(escapedNames, dialect.Escape(name))
|
||||
}
|
||||
|
@ -5,8 +5,8 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/vingarcia/ksql/internal/kbuilder"
|
||||
tt "github.com/vingarcia/ksql/internal/testtools"
|
||||
"github.com/vingarcia/ksql/kbuilder"
|
||||
)
|
||||
|
||||
type User struct {
|
46
internal/modifiers/attr_wrapper.go
Normal file
46
internal/modifiers/attr_wrapper.go
Normal file
@ -0,0 +1,46 @@
|
||||
package modifiers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql/driver"
|
||||
|
||||
"github.com/vingarcia/ksql/ksqlmodifiers"
|
||||
)
|
||||
|
||||
// AttrScanWrapper is the wrapper that allow us to intercept the Scan process
|
||||
// so we can run the modifiers instead of allowing the database driver to use
|
||||
// its default behavior.
|
||||
//
|
||||
// For that this struct implements the `sql.Scanner` interface
|
||||
type AttrScanWrapper struct {
|
||||
Ctx context.Context
|
||||
|
||||
AttrPtr interface{}
|
||||
|
||||
ScanFn ksqlmodifiers.AttrScanner
|
||||
OpInfo ksqlmodifiers.OpInfo
|
||||
}
|
||||
|
||||
// Scan implements the sql.Scanner interface
|
||||
func (a AttrScanWrapper) Scan(dbValue interface{}) error {
|
||||
return a.ScanFn(a.Ctx, a.OpInfo, a.AttrPtr, dbValue)
|
||||
}
|
||||
|
||||
// AttrValueWrapper is the wrapper that allow us to intercept the "Valuing" process
|
||||
// so we can run the modifiers instead of allowing the database driver to use
|
||||
// its default behavior.
|
||||
//
|
||||
// For that this struct implements the `sql.Valuer` interface
|
||||
type AttrValueWrapper struct {
|
||||
Ctx context.Context
|
||||
|
||||
Attr interface{}
|
||||
|
||||
ValueFn ksqlmodifiers.AttrValuer
|
||||
OpInfo ksqlmodifiers.OpInfo
|
||||
}
|
||||
|
||||
// Value implements the sql.Valuer interface
|
||||
func (a AttrValueWrapper) Value() (driver.Value, error) {
|
||||
return a.ValueFn(a.Ctx, a.OpInfo, a.Attr)
|
||||
}
|
75
internal/modifiers/attr_wrapper_test.go
Normal file
75
internal/modifiers/attr_wrapper_test.go
Normal file
@ -0,0 +1,75 @@
|
||||
package modifiers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
tt "github.com/vingarcia/ksql/internal/testtools"
|
||||
"github.com/vingarcia/ksql/ksqlmodifiers"
|
||||
)
|
||||
|
||||
func TestAttrScanWrapper(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
var scanArgs map[string]interface{}
|
||||
wrapper := AttrScanWrapper{
|
||||
Ctx: ctx,
|
||||
AttrPtr: "fakeAttrPtr",
|
||||
ScanFn: func(ctx context.Context, opInfo ksqlmodifiers.OpInfo, attrPtr interface{}, dbValue interface{}) error {
|
||||
scanArgs = map[string]interface{}{
|
||||
"opInfo": opInfo,
|
||||
"attrPtr": attrPtr,
|
||||
"dbValue": dbValue,
|
||||
}
|
||||
return errors.New("fakeScanErrMsg")
|
||||
},
|
||||
OpInfo: ksqlmodifiers.OpInfo{
|
||||
Method: "fakeMethod",
|
||||
DriverName: "fakeDriverName",
|
||||
},
|
||||
}
|
||||
|
||||
err := wrapper.Scan("fakeDbValue")
|
||||
tt.AssertErrContains(t, err, "fakeScanErrMsg")
|
||||
tt.AssertEqual(t, scanArgs, map[string]interface{}{
|
||||
"opInfo": ksqlmodifiers.OpInfo{
|
||||
Method: "fakeMethod",
|
||||
DriverName: "fakeDriverName",
|
||||
},
|
||||
"attrPtr": "fakeAttrPtr",
|
||||
"dbValue": "fakeDbValue",
|
||||
})
|
||||
}
|
||||
|
||||
func TestAttrWrapper(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
var valueArgs map[string]interface{}
|
||||
wrapper := AttrValueWrapper{
|
||||
Ctx: ctx,
|
||||
Attr: "fakeAttr",
|
||||
ValueFn: func(ctx context.Context, opInfo ksqlmodifiers.OpInfo, inputValue interface{}) (outputValue interface{}, _ error) {
|
||||
valueArgs = map[string]interface{}{
|
||||
"opInfo": opInfo,
|
||||
"inputValue": inputValue,
|
||||
}
|
||||
return "fakeOutputValue", errors.New("fakeValueErrMsg")
|
||||
},
|
||||
OpInfo: ksqlmodifiers.OpInfo{
|
||||
Method: "fakeMethod",
|
||||
DriverName: "fakeDriverName",
|
||||
},
|
||||
}
|
||||
|
||||
value, err := wrapper.Value()
|
||||
tt.AssertErrContains(t, err, "fakeValueErrMsg")
|
||||
tt.AssertEqual(t, valueArgs, map[string]interface{}{
|
||||
"opInfo": ksqlmodifiers.OpInfo{
|
||||
Method: "fakeMethod",
|
||||
DriverName: "fakeDriverName",
|
||||
},
|
||||
"inputValue": "fakeAttr",
|
||||
})
|
||||
tt.AssertEqual(t, value, "fakeOutputValue")
|
||||
}
|
57
internal/modifiers/global_modifiers.go
Normal file
57
internal/modifiers/global_modifiers.go
Normal file
@ -0,0 +1,57 @@
|
||||
package modifiers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/vingarcia/ksql/ksqlmodifiers"
|
||||
)
|
||||
|
||||
// Here we keep all the registered modifiers
|
||||
var modifiers sync.Map
|
||||
|
||||
func init() {
|
||||
// Here we expose the registration function in a public package,
|
||||
// so users can use it:
|
||||
ksqlmodifiers.RegisterAttrModifier = RegisterAttrModifier
|
||||
|
||||
// These are the builtin modifiers:
|
||||
|
||||
// This one is useful for serializing/deserializing structs:
|
||||
modifiers.Store("json", jsonModifier)
|
||||
modifiers.Store("json/nullable", jsonNullableModifier)
|
||||
|
||||
// This next two are useful for the UpdatedAt and Created fields respectively:
|
||||
// They only work on time.Time attributes and will set the attribute to time.Now().
|
||||
modifiers.Store("timeNowUTC", timeNowUTCModifier)
|
||||
modifiers.Store("timeNowUTC/skipUpdates", timeNowUTCSkipUpdatesModifier)
|
||||
|
||||
// These are mostly example modifiers and they are also used
|
||||
// to test the feature of skipping updates, inserts and queries.
|
||||
modifiers.Store("skipUpdates", skipUpdatesModifier)
|
||||
modifiers.Store("skipInserts", skipInsertsModifier)
|
||||
modifiers.Store("nullable", nullableModifier)
|
||||
}
|
||||
|
||||
// RegisterAttrModifier allow users to add custom modifiers on startup
|
||||
// it is recommended to do this inside an init() function.
|
||||
func RegisterAttrModifier(key string, modifier ksqlmodifiers.AttrModifier) {
|
||||
_, found := modifiers.Load(key)
|
||||
if found {
|
||||
panic(fmt.Errorf("KSQL: cannot register modifier '%s' name is already in use", key))
|
||||
}
|
||||
|
||||
modifiers.Store(key, modifier)
|
||||
}
|
||||
|
||||
// LoadGlobalModifier is used internally by KSQL to load
|
||||
// modifiers during runtime.
|
||||
func LoadGlobalModifier(key string) (ksqlmodifiers.AttrModifier, error) {
|
||||
rawModifier, _ := modifiers.Load(key)
|
||||
modifier, ok := rawModifier.(ksqlmodifiers.AttrModifier)
|
||||
if !ok {
|
||||
return ksqlmodifiers.AttrModifier{}, fmt.Errorf("no modifier found with name '%s'", key)
|
||||
}
|
||||
|
||||
return modifier, nil
|
||||
}
|
54
internal/modifiers/global_modifiers_test.go
Normal file
54
internal/modifiers/global_modifiers_test.go
Normal file
@ -0,0 +1,54 @@
|
||||
package modifiers
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
tt "github.com/vingarcia/ksql/internal/testtools"
|
||||
"github.com/vingarcia/ksql/ksqlmodifiers"
|
||||
)
|
||||
|
||||
func TestRegisterAttrModifier(t *testing.T) {
|
||||
t.Run("should register new modifiers correctly", func(t *testing.T) {
|
||||
modifier1 := ksqlmodifiers.AttrModifier{
|
||||
SkipOnUpdate: true,
|
||||
}
|
||||
modifier2 := ksqlmodifiers.AttrModifier{
|
||||
SkipOnInsert: true,
|
||||
}
|
||||
|
||||
RegisterAttrModifier("fakeModifierName1", modifier1)
|
||||
RegisterAttrModifier("fakeModifierName2", modifier2)
|
||||
|
||||
mod, err := LoadGlobalModifier("fakeModifierName1")
|
||||
tt.AssertNoErr(t, err)
|
||||
tt.AssertEqual(t, mod, modifier1)
|
||||
|
||||
mod, err = LoadGlobalModifier("fakeModifierName2")
|
||||
tt.AssertNoErr(t, err)
|
||||
tt.AssertEqual(t, mod, modifier2)
|
||||
})
|
||||
|
||||
t.Run("should panic registering a modifier and the name already exists", func(t *testing.T) {
|
||||
modifier1 := ksqlmodifiers.AttrModifier{
|
||||
SkipOnUpdate: true,
|
||||
}
|
||||
modifier2 := ksqlmodifiers.AttrModifier{
|
||||
SkipOnInsert: true,
|
||||
}
|
||||
|
||||
RegisterAttrModifier("fakeModifierName", modifier1)
|
||||
panicPayload := tt.PanicHandler(func() {
|
||||
RegisterAttrModifier("fakeModifierName", modifier2)
|
||||
})
|
||||
|
||||
err, ok := panicPayload.(error)
|
||||
tt.AssertEqual(t, ok, true)
|
||||
tt.AssertErrContains(t, err, "KSQL", "fakeModifierName", "name is already in use")
|
||||
})
|
||||
|
||||
t.Run("should return an error when loading an inexistent modifier", func(t *testing.T) {
|
||||
mod, err := LoadGlobalModifier("nonExistentModifier")
|
||||
tt.AssertErrContains(t, err, "nonExistentModifier")
|
||||
tt.AssertEqual(t, mod, ksqlmodifiers.AttrModifier{})
|
||||
})
|
||||
}
|
48
internal/modifiers/json_modifier.go
Normal file
48
internal/modifiers/json_modifier.go
Normal file
@ -0,0 +1,48 @@
|
||||
package modifiers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/vingarcia/ksql/ksqlmodifiers"
|
||||
)
|
||||
|
||||
// This modifier serializes objects as JSON when
|
||||
// sending it to the database and decodes
|
||||
// them when receiving.
|
||||
var jsonModifier = ksqlmodifiers.AttrModifier{
|
||||
Scan: func(ctx context.Context, opInfo ksqlmodifiers.OpInfo, attrPtr interface{}, dbValue interface{}) error {
|
||||
if dbValue == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Required since sqlite3 returns strings not bytes
|
||||
if v, ok := dbValue.(string); ok {
|
||||
dbValue = []byte(v)
|
||||
}
|
||||
|
||||
rawJSON, ok := dbValue.([]byte)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type received to Scan: %T", dbValue)
|
||||
}
|
||||
return json.Unmarshal(rawJSON, attrPtr)
|
||||
},
|
||||
|
||||
Value: func(ctx context.Context, opInfo ksqlmodifiers.OpInfo, inputValue interface{}) (outputValue interface{}, _ error) {
|
||||
b, err := json.Marshal(inputValue)
|
||||
// SQL server uses the NVARCHAR type to store JSON and
|
||||
// it expects to receive strings not []byte, thus:
|
||||
if opInfo.DriverName == "sqlserver" {
|
||||
return string(b), err
|
||||
}
|
||||
return b, err
|
||||
},
|
||||
}
|
||||
|
||||
var jsonNullableModifier = ksqlmodifiers.AttrModifier{
|
||||
Nullable: true,
|
||||
|
||||
Scan: jsonModifier.Scan,
|
||||
Value: jsonModifier.Value,
|
||||
}
|
125
internal/modifiers/json_modifier_test.go
Normal file
125
internal/modifiers/json_modifier_test.go
Normal file
@ -0,0 +1,125 @@
|
||||
package modifiers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
tt "github.com/vingarcia/ksql/internal/testtools"
|
||||
"github.com/vingarcia/ksql/ksqlmodifiers"
|
||||
)
|
||||
|
||||
func TestAttrScan(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
type FakeAttr struct {
|
||||
Foo string `json:"foo"`
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
desc string
|
||||
dbInput interface{}
|
||||
expectedValue interface{}
|
||||
expectErrToContain []string
|
||||
}{
|
||||
{
|
||||
desc: "should not set struct to zero value if input is nil",
|
||||
dbInput: nil,
|
||||
expectedValue: FakeAttr{
|
||||
Foo: "notZeroValue",
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "should work when input is a byte slice",
|
||||
dbInput: []byte(`{"foo":"bar"}`),
|
||||
expectedValue: FakeAttr{
|
||||
Foo: "bar",
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "should work when input is a string",
|
||||
dbInput: `{"foo":"bar"}`,
|
||||
expectedValue: FakeAttr{
|
||||
Foo: "bar",
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "should report error if input type is unsupported",
|
||||
dbInput: 10,
|
||||
expectErrToContain: []string{"unexpected type", "int"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
fakeAttr := FakeAttr{
|
||||
Foo: "notZeroValue",
|
||||
}
|
||||
err := jsonModifier.Scan(ctx, ksqlmodifiers.OpInfo{}, &fakeAttr, test.dbInput)
|
||||
if test.expectErrToContain != nil {
|
||||
tt.AssertErrContains(t, err, test.expectErrToContain...)
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
tt.AssertNoErr(t, err)
|
||||
tt.AssertEqual(t, fakeAttr, test.expectedValue)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAttrValue(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
type FakeAttr struct {
|
||||
Foo string `json:"foo"`
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
desc string
|
||||
dbInput interface{}
|
||||
opInfoInput ksqlmodifiers.OpInfo
|
||||
attrValue interface{}
|
||||
|
||||
expectedOutput interface{}
|
||||
expectErrToContain []string
|
||||
}{
|
||||
{
|
||||
desc: "should return a byte array when the driver is not sqlserver",
|
||||
dbInput: []byte(`{"foo":"bar"}`),
|
||||
opInfoInput: ksqlmodifiers.OpInfo{
|
||||
DriverName: "notSQLServer",
|
||||
},
|
||||
attrValue: FakeAttr{
|
||||
Foo: "bar",
|
||||
},
|
||||
expectedOutput: tt.ToJSON(t, map[string]interface{}{
|
||||
"foo": "bar",
|
||||
}),
|
||||
},
|
||||
{
|
||||
desc: "should return a string when the driver is sqlserver",
|
||||
dbInput: []byte(`{"foo":"bar"}`),
|
||||
opInfoInput: ksqlmodifiers.OpInfo{
|
||||
DriverName: "sqlserver",
|
||||
},
|
||||
attrValue: FakeAttr{
|
||||
Foo: "bar",
|
||||
},
|
||||
expectedOutput: string(tt.ToJSON(t, map[string]interface{}{
|
||||
"foo": "bar",
|
||||
})),
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
output, err := jsonModifier.Value(ctx, test.opInfoInput, test.attrValue)
|
||||
if test.expectErrToContain != nil {
|
||||
tt.AssertErrContains(t, err, test.expectErrToContain...)
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
tt.AssertNoErr(t, err)
|
||||
tt.AssertEqual(t, output, test.expectedOutput)
|
||||
})
|
||||
}
|
||||
}
|
15
internal/modifiers/skip_and_keep_modifiers.go
Normal file
15
internal/modifiers/skip_and_keep_modifiers.go
Normal file
@ -0,0 +1,15 @@
|
||||
package modifiers
|
||||
|
||||
import "github.com/vingarcia/ksql/ksqlmodifiers"
|
||||
|
||||
var skipInsertsModifier = ksqlmodifiers.AttrModifier{
|
||||
SkipOnInsert: true,
|
||||
}
|
||||
|
||||
var skipUpdatesModifier = ksqlmodifiers.AttrModifier{
|
||||
SkipOnUpdate: true,
|
||||
}
|
||||
|
||||
var nullableModifier = ksqlmodifiers.AttrModifier{
|
||||
Nullable: true,
|
||||
}
|
24
internal/modifiers/time_modifiers.go
Normal file
24
internal/modifiers/time_modifiers.go
Normal file
@ -0,0 +1,24 @@
|
||||
package modifiers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/vingarcia/ksql/ksqlmodifiers"
|
||||
)
|
||||
|
||||
// This one is useful for updatedAt timestamps
|
||||
var timeNowUTCModifier = ksqlmodifiers.AttrModifier{
|
||||
Value: func(ctx context.Context, opInfo ksqlmodifiers.OpInfo, inputValue interface{}) (outputValue interface{}, _ error) {
|
||||
return time.Now().UTC(), nil
|
||||
},
|
||||
}
|
||||
|
||||
// This one is useful for createdAt timestamps
|
||||
var timeNowUTCSkipUpdatesModifier = ksqlmodifiers.AttrModifier{
|
||||
SkipOnUpdate: true,
|
||||
|
||||
Value: func(ctx context.Context, opInfo ksqlmodifiers.OpInfo, inputValue interface{}) (outputValue interface{}, _ error) {
|
||||
return time.Now().UTC(), nil
|
||||
},
|
||||
}
|
@ -5,6 +5,9 @@ import (
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/vingarcia/ksql/internal/modifiers"
|
||||
"github.com/vingarcia/ksql/ksqlmodifiers"
|
||||
)
|
||||
|
||||
// StructInfo stores metainformation of the struct
|
||||
@ -20,10 +23,24 @@ type StructInfo struct {
|
||||
// information regarding a specific field
|
||||
// of a struct.
|
||||
type FieldInfo struct {
|
||||
Name string
|
||||
Index int
|
||||
Valid bool
|
||||
SerializeAsJSON bool
|
||||
// AttrName is the name of struct attribute of the struct.
|
||||
AttrName string
|
||||
|
||||
// ColumnName is the name of the database column described by the ksql tag.
|
||||
ColumnName string
|
||||
|
||||
// Index indexes the position of this attribute on the struct.
|
||||
// This field is meant to be used together with the
|
||||
// `reflect.Value.Field()` and `reflect.Type.Field()` methods.
|
||||
Index int
|
||||
|
||||
// Valid will only be set to false if the instance
|
||||
// of this field was not initialized, i.e.
|
||||
// it denotes the zero value of a FieldInfo.
|
||||
Valid bool
|
||||
|
||||
// Modifier contains the AttrModifier associated with this field.
|
||||
Modifier ksqlmodifiers.AttrModifier
|
||||
}
|
||||
|
||||
// ByIndex returns either the *FieldInfo of a valid
|
||||
@ -49,12 +66,12 @@ func (s StructInfo) ByName(name string) *FieldInfo {
|
||||
func (s StructInfo) add(field FieldInfo) {
|
||||
field.Valid = true
|
||||
s.byIndex[field.Index] = &field
|
||||
s.byName[field.Name] = &field
|
||||
s.byName[field.ColumnName] = &field
|
||||
|
||||
// Make sure to save a lowercased version because
|
||||
// some databases will set these keys to lowercase.
|
||||
if _, found := s.byName[strings.ToLower(field.Name)]; !found {
|
||||
s.byName[strings.ToLower(field.Name)] = &field
|
||||
if _, found := s.byName[strings.ToLower(field.ColumnName)]; !found {
|
||||
s.byName[strings.ToLower(field.ColumnName)] = &field
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,11 +98,11 @@ func GetTagInfo(key reflect.Type) (StructInfo, error) {
|
||||
|
||||
func getCachedTagInfo(tagInfoCache *sync.Map, key reflect.Type) (StructInfo, error) {
|
||||
if data, found := tagInfoCache.Load(key); found {
|
||||
if info, ok := data.(StructInfo); !ok {
|
||||
info, ok := data.(StructInfo)
|
||||
if !ok {
|
||||
return StructInfo{}, fmt.Errorf("invalid cache entry, expected type StructInfo, found %T", data)
|
||||
} else {
|
||||
return info, nil
|
||||
}
|
||||
return info, nil
|
||||
}
|
||||
|
||||
info, err := getTagNames(key)
|
||||
@ -133,14 +150,16 @@ func StructToMap(obj interface{}) (map[string]interface{}, error) {
|
||||
field := v.Field(i)
|
||||
ft := field.Type()
|
||||
if ft.Kind() == reflect.Ptr {
|
||||
if field.IsNil() {
|
||||
continue
|
||||
if !field.IsNil() {
|
||||
field = field.Elem()
|
||||
} else {
|
||||
if !fieldInfo.Modifier.Nullable {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
field = field.Elem()
|
||||
}
|
||||
|
||||
m[fieldInfo.Name] = field.Interface()
|
||||
m[fieldInfo.ColumnName] = field.Interface()
|
||||
}
|
||||
|
||||
return m, nil
|
||||
@ -232,27 +251,32 @@ func (p PtrConverter) Convert(destType reflect.Type) (reflect.Value, error) {
|
||||
//
|
||||
// This should save several calls to `Field(i).Tag.Get("foo")`
|
||||
// which improves performance by a lot.
|
||||
func getTagNames(t reflect.Type) (StructInfo, error) {
|
||||
func getTagNames(t reflect.Type) (_ StructInfo, err error) {
|
||||
info := StructInfo{
|
||||
byIndex: map[int]*FieldInfo{},
|
||||
byName: map[string]*FieldInfo{},
|
||||
}
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
// If this field is private:
|
||||
if t.Field(i).PkgPath != "" {
|
||||
return StructInfo{}, fmt.Errorf("all fields using the ksql tags must be exported, but %v is unexported", t)
|
||||
}
|
||||
|
||||
attrName := t.Field(i).Name
|
||||
name := t.Field(i).Tag.Get("ksql")
|
||||
if name == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
// If this field is private:
|
||||
if t.Field(i).PkgPath != "" {
|
||||
return StructInfo{}, fmt.Errorf("all fields using the ksql tags must be exported, but %v is unexported", t)
|
||||
}
|
||||
|
||||
tags := strings.Split(name, ",")
|
||||
serializeAsJSON := false
|
||||
var modifier ksqlmodifiers.AttrModifier
|
||||
if len(tags) > 1 {
|
||||
name = tags[0]
|
||||
serializeAsJSON = tags[1] == "json"
|
||||
modifier, err = modifiers.LoadGlobalModifier(tags[1])
|
||||
if err != nil {
|
||||
return StructInfo{}, fmt.Errorf("attribute contains invalid modifier name: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if _, found := info.byName[name]; found {
|
||||
@ -263,9 +287,10 @@ func getTagNames(t reflect.Type) (StructInfo, error) {
|
||||
}
|
||||
|
||||
info.add(FieldInfo{
|
||||
Name: name,
|
||||
Index: i,
|
||||
SerializeAsJSON: serializeAsJSON,
|
||||
AttrName: attrName,
|
||||
ColumnName: name,
|
||||
Index: i,
|
||||
Modifier: modifier,
|
||||
})
|
||||
}
|
||||
|
||||
@ -283,8 +308,9 @@ func getTagNames(t reflect.Type) (StructInfo, error) {
|
||||
}
|
||||
|
||||
info.add(FieldInfo{
|
||||
Name: name,
|
||||
Index: i,
|
||||
AttrName: t.Field(i).Name,
|
||||
ColumnName: name,
|
||||
Index: i,
|
||||
})
|
||||
}
|
||||
|
||||
|
111
internal/structs/structs_test.go
Normal file
111
internal/structs/structs_test.go
Normal file
@ -0,0 +1,111 @@
|
||||
package structs
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
tt "github.com/vingarcia/ksql/internal/testtools"
|
||||
)
|
||||
|
||||
func TestGetTagInfo(t *testing.T) {
|
||||
tests := []struct {
|
||||
desc string
|
||||
obj interface{}
|
||||
expectedInfo StructInfo
|
||||
expecteErrToContain []string
|
||||
}{
|
||||
{
|
||||
desc: "should correctly parse all the fields tagged `ksql` on a struct",
|
||||
obj: struct {
|
||||
ShowStr string `ksql:"show_str"`
|
||||
HideStr string
|
||||
ShowInt int `ksql:"show_int"`
|
||||
HideInt int
|
||||
}{},
|
||||
expectedInfo: StructInfo{
|
||||
IsNestedStruct: false,
|
||||
byIndex: map[int]*FieldInfo{
|
||||
0: &FieldInfo{
|
||||
AttrName: "ShowStr",
|
||||
ColumnName: "show_str",
|
||||
Index: 0,
|
||||
Valid: true,
|
||||
},
|
||||
2: &FieldInfo{
|
||||
AttrName: "ShowInt",
|
||||
ColumnName: "show_int",
|
||||
Index: 2,
|
||||
Valid: true,
|
||||
},
|
||||
},
|
||||
byName: map[string]*FieldInfo{
|
||||
"show_str": &FieldInfo{
|
||||
AttrName: "ShowStr",
|
||||
ColumnName: "show_str",
|
||||
Index: 0,
|
||||
Valid: true,
|
||||
},
|
||||
"show_int": &FieldInfo{
|
||||
AttrName: "ShowInt",
|
||||
ColumnName: "show_int",
|
||||
Index: 2,
|
||||
Valid: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "should correctly ignore private fields if they are not tagged",
|
||||
obj: struct {
|
||||
ShowStr string `ksql:"show_str"`
|
||||
hideStr string
|
||||
ShowInt int `ksql:"show_int"`
|
||||
hideInt int
|
||||
}{},
|
||||
expectedInfo: StructInfo{
|
||||
IsNestedStruct: false,
|
||||
byIndex: map[int]*FieldInfo{
|
||||
0: &FieldInfo{
|
||||
AttrName: "ShowStr",
|
||||
ColumnName: "show_str",
|
||||
Index: 0,
|
||||
Valid: true,
|
||||
},
|
||||
2: &FieldInfo{
|
||||
AttrName: "ShowInt",
|
||||
ColumnName: "show_int",
|
||||
Index: 2,
|
||||
Valid: true,
|
||||
},
|
||||
},
|
||||
byName: map[string]*FieldInfo{
|
||||
"show_str": &FieldInfo{
|
||||
AttrName: "ShowStr",
|
||||
ColumnName: "show_str",
|
||||
Index: 0,
|
||||
Valid: true,
|
||||
},
|
||||
"show_int": &FieldInfo{
|
||||
AttrName: "ShowInt",
|
||||
ColumnName: "show_int",
|
||||
Index: 2,
|
||||
Valid: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
info, err := GetTagInfo(reflect.TypeOf(test.obj))
|
||||
if test.expecteErrToContain != nil {
|
||||
tt.AssertErrContains(t, err, test.expecteErrToContain...)
|
||||
t.Skip()
|
||||
}
|
||||
tt.AssertNoErr(t, err)
|
||||
|
||||
tt.AssertEqual(t, info, test.expectedInfo)
|
||||
})
|
||||
}
|
||||
}
|
@ -47,6 +47,19 @@ func AssertErrContains(t *testing.T, err error, substrs ...string) {
|
||||
}
|
||||
}
|
||||
|
||||
// AssertContains will check if the input text contains
|
||||
// all the substrs specified on the substrs argument or
|
||||
// fail with an appropriate error message.
|
||||
func AssertContains(t *testing.T, str string, substrs ...string) {
|
||||
for _, substr := range substrs {
|
||||
require.True(t,
|
||||
strings.Contains(str, substr),
|
||||
"missing substring '%s' in error message: '%s'",
|
||||
substr, str,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// AssertApproxDuration checks if the durations v1 and v2 are close up to the tolerance specified.
|
||||
// The format and args slice can be used for generating an appropriate error message if they are not.
|
||||
func AssertApproxDuration(t *testing.T, tolerance time.Duration, v1, v2 time.Duration, format string, args ...interface{}) {
|
||||
|
13
internal/testtools/json.go
Normal file
13
internal/testtools/json.go
Normal file
@ -0,0 +1,13 @@
|
||||
package tt
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func ToJSON(t *testing.T, obj interface{}) []byte {
|
||||
rawJSON, err := json.Marshal(obj)
|
||||
AssertNoErr(t, err)
|
||||
|
||||
return rawJSON
|
||||
}
|
12
internal/testtools/time.go
Normal file
12
internal/testtools/time.go
Normal file
@ -0,0 +1,12 @@
|
||||
package tt
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func ParseTime(t *testing.T, timestr string) time.Time {
|
||||
parsedTime, err := time.Parse(time.RFC3339, timestr)
|
||||
AssertNoErr(t, err)
|
||||
return parsedTime
|
||||
}
|
107
internal_mocks.go
Normal file
107
internal_mocks.go
Normal file
@ -0,0 +1,107 @@
|
||||
package ksql
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
// mockTxBeginner mocks the ksql.TxBeginner interface
|
||||
type mockTxBeginner struct {
|
||||
DBAdapter
|
||||
BeginTxFn func(ctx context.Context) (Tx, error)
|
||||
}
|
||||
|
||||
func (b mockTxBeginner) BeginTx(ctx context.Context) (Tx, error) {
|
||||
return b.BeginTxFn(ctx)
|
||||
}
|
||||
|
||||
// mockDBAdapter mocks the ksql.DBAdapter interface
|
||||
type mockDBAdapter struct {
|
||||
ExecContextFn func(ctx context.Context, query string, args ...interface{}) (Result, error)
|
||||
QueryContextFn func(ctx context.Context, query string, args ...interface{}) (Rows, error)
|
||||
}
|
||||
|
||||
func (m mockDBAdapter) ExecContext(ctx context.Context, query string, args ...interface{}) (Result, error) {
|
||||
return m.ExecContextFn(ctx, query, args...)
|
||||
}
|
||||
|
||||
func (m mockDBAdapter) QueryContext(ctx context.Context, query string, args ...interface{}) (Rows, error) {
|
||||
return m.QueryContextFn(ctx, query, args...)
|
||||
}
|
||||
|
||||
type mockRows struct {
|
||||
ScanFn func(...interface{}) error
|
||||
CloseFn func() error
|
||||
NextFn func() bool
|
||||
ErrFn func() error
|
||||
ColumnsFn func() ([]string, error)
|
||||
}
|
||||
|
||||
func (m mockRows) Scan(values ...interface{}) error {
|
||||
return m.ScanFn(values...)
|
||||
}
|
||||
|
||||
func (m mockRows) Close() error {
|
||||
if m.CloseFn == nil {
|
||||
return nil
|
||||
}
|
||||
return m.CloseFn()
|
||||
}
|
||||
|
||||
func (m mockRows) Next() bool {
|
||||
return m.NextFn()
|
||||
}
|
||||
|
||||
func (m mockRows) Err() error {
|
||||
if m.ErrFn == nil {
|
||||
return nil
|
||||
}
|
||||
return m.ErrFn()
|
||||
}
|
||||
|
||||
func (m mockRows) Columns() ([]string, error) {
|
||||
return m.ColumnsFn()
|
||||
}
|
||||
|
||||
// mockResult mocks the ksql.Result interface
|
||||
type mockResult struct {
|
||||
LastInsertIdFn func() (int64, error)
|
||||
RowsAffectedFn func() (int64, error)
|
||||
}
|
||||
|
||||
func (m mockResult) LastInsertId() (int64, error) {
|
||||
if m.LastInsertIdFn != nil {
|
||||
return m.LastInsertIdFn()
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (m mockResult) RowsAffected() (int64, error) {
|
||||
if m.RowsAffectedFn != nil {
|
||||
return m.RowsAffectedFn()
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
// mockTx mocks the ksql.Tx interface
|
||||
type mockTx struct {
|
||||
DBAdapter
|
||||
RollbackFn func(ctx context.Context) error
|
||||
CommitFn func(ctx context.Context) error
|
||||
}
|
||||
|
||||
func (m mockTx) Rollback(ctx context.Context) error {
|
||||
return m.RollbackFn(ctx)
|
||||
}
|
||||
|
||||
func (m mockTx) Commit(ctx context.Context) error {
|
||||
return m.CommitFn(ctx)
|
||||
}
|
||||
|
||||
// mockCloser mocks the io.Closer interface
|
||||
type mockCloser struct {
|
||||
CloseFn func() error
|
||||
}
|
||||
|
||||
func (m mockCloser) Close() error {
|
||||
return m.CloseFn()
|
||||
}
|
49
json.go
49
json.go
@ -1,49 +0,0 @@
|
||||
package ksql
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// This type was created to make it easier to adapt
|
||||
// input attributes to be convertible to and from JSON
|
||||
// before sending or receiving it from the database.
|
||||
type jsonSerializable struct {
|
||||
DriverName string
|
||||
Attr interface{}
|
||||
}
|
||||
|
||||
// Scan Implements the Scanner interface in order to load
|
||||
// this field from the JSON stored in the database
|
||||
func (j *jsonSerializable) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
v := reflect.ValueOf(j.Attr)
|
||||
// Set the struct to its 0 value just like json.Unmarshal
|
||||
// does for nil attributes:
|
||||
v.Elem().Set(reflect.Zero(reflect.TypeOf(j.Attr).Elem()))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Required since sqlite3 returns strings not bytes
|
||||
if v, ok := value.(string); ok {
|
||||
value = []byte(v)
|
||||
}
|
||||
|
||||
rawJSON, ok := value.([]byte)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type received to Scan: %T", value)
|
||||
}
|
||||
return json.Unmarshal(rawJSON, j.Attr)
|
||||
}
|
||||
|
||||
// Value Implements the Valuer interface in order to save
|
||||
// this field as JSON on the database.
|
||||
func (j jsonSerializable) Value() (driver.Value, error) {
|
||||
b, err := json.Marshal(j.Attr)
|
||||
if j.DriverName == "sqlserver" {
|
||||
return string(b), err
|
||||
}
|
||||
return b, err
|
||||
}
|
427
ksql.go
427
ksql.go
@ -10,16 +10,17 @@ import (
|
||||
"sync"
|
||||
"unicode"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/vingarcia/ksql/internal/modifiers"
|
||||
"github.com/vingarcia/ksql/internal/structs"
|
||||
"github.com/vingarcia/ksql/ksqltest"
|
||||
"github.com/vingarcia/ksql/ksqlmodifiers"
|
||||
"github.com/vingarcia/ksql/sqldialect"
|
||||
)
|
||||
|
||||
var selectQueryCache = initializeQueryCache()
|
||||
|
||||
func initializeQueryCache() map[string]*sync.Map {
|
||||
cache := map[string]*sync.Map{}
|
||||
for dname := range supportedDialects {
|
||||
for dname := range sqldialect.SupportedDialects {
|
||||
cache[dname] = &sync.Map{}
|
||||
}
|
||||
|
||||
@ -30,8 +31,7 @@ func initializeQueryCache() map[string]*sync.Map {
|
||||
// interfacing with the "database/sql" package implementing
|
||||
// the KSQL interface `ksql.Provider`.
|
||||
type DB struct {
|
||||
driver string
|
||||
dialect Dialect
|
||||
dialect sqldialect.Provider
|
||||
db DBAdapter
|
||||
}
|
||||
|
||||
@ -66,6 +66,34 @@ type Rows interface {
|
||||
Columns() ([]string, error)
|
||||
}
|
||||
|
||||
// ScanArgError is a type of error that is expected to be returned
|
||||
// from the Scan() method of the Rows interface.
|
||||
//
|
||||
// It should be returned when there is an error scanning one of the input
|
||||
// values.
|
||||
//
|
||||
// This is necessary in order to allow KSQL to produce a better and more
|
||||
// readable error message when this type of error occur.
|
||||
type ScanArgError struct {
|
||||
ColumnIndex int
|
||||
Err error
|
||||
}
|
||||
|
||||
// Error implements the error interface.
|
||||
func (s ScanArgError) Error() string {
|
||||
return fmt.Sprintf(
|
||||
"error scanning input attribute with index %d: %s",
|
||||
s.ColumnIndex, s.Err,
|
||||
)
|
||||
}
|
||||
|
||||
func (s ScanArgError) ErrorWithStructNames(structName string, colName string) error {
|
||||
return fmt.Errorf(
|
||||
"error scanning %s.%s: %w",
|
||||
structName, colName, s.Err,
|
||||
)
|
||||
}
|
||||
|
||||
// Tx represents a transaction and is expected to be returned by the DBAdapter.BeginTx function
|
||||
type Tx interface {
|
||||
DBAdapter
|
||||
@ -95,18 +123,16 @@ func (c *Config) SetDefaultValues() {
|
||||
// NewWithAdapter allows the user to insert a custom implementation
|
||||
// of the DBAdapter interface
|
||||
func NewWithAdapter(
|
||||
db DBAdapter,
|
||||
dialectName string,
|
||||
adapter DBAdapter,
|
||||
dialect sqldialect.Provider,
|
||||
) (DB, error) {
|
||||
dialect := supportedDialects[dialectName]
|
||||
if dialect == nil {
|
||||
return DB{}, fmt.Errorf("unsupported driver `%s`", dialectName)
|
||||
return DB{}, fmt.Errorf("expected a valid sqldialect.Provider as argument but got `nil`")
|
||||
}
|
||||
|
||||
return DB{
|
||||
dialect: dialect,
|
||||
driver: dialectName,
|
||||
db: db,
|
||||
db: adapter,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -122,11 +148,11 @@ func (c DB) Query(
|
||||
records interface{},
|
||||
query string,
|
||||
params ...interface{},
|
||||
) error {
|
||||
) (err error) {
|
||||
slicePtr := reflect.ValueOf(records)
|
||||
slicePtrType := slicePtr.Type()
|
||||
if slicePtrType.Kind() != reflect.Ptr {
|
||||
return fmt.Errorf("ksql: expected to receive a pointer to slice of structs, but got: %T", records)
|
||||
return fmt.Errorf("KSQL: expected to receive a pointer to slice of structs, but got: %T", records)
|
||||
}
|
||||
sliceType := slicePtrType.Elem()
|
||||
slice := slicePtr.Elem()
|
||||
@ -161,9 +187,11 @@ func (c DB) Query(
|
||||
query = selectPrefix + query
|
||||
}
|
||||
|
||||
defer ctxLog(ctx, query, params, &err)
|
||||
|
||||
rows, err := c.db.QueryContext(ctx, query, params...)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error running query: %s", err)
|
||||
return fmt.Errorf("error running query: %w", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
@ -185,18 +213,18 @@ func (c DB) Query(
|
||||
elemPtr = elemPtr.Elem()
|
||||
}
|
||||
|
||||
err = scanRows(c.dialect, rows, elemPtr.Interface())
|
||||
err = scanRows(ctx, c.dialect, rows, elemPtr.Interface())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if rows.Err() != nil {
|
||||
return rows.Err()
|
||||
return fmt.Errorf("KSQL: unexpected error when parsing query result: %w", rows.Err())
|
||||
}
|
||||
|
||||
if err := rows.Close(); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("KSQL: unexpected error when closing query result rows: %w", err)
|
||||
}
|
||||
|
||||
// Update the original slice passed by reference:
|
||||
@ -216,20 +244,20 @@ func (c DB) QueryOne(
|
||||
record interface{},
|
||||
query string,
|
||||
params ...interface{},
|
||||
) error {
|
||||
) (err error) {
|
||||
v := reflect.ValueOf(record)
|
||||
t := v.Type()
|
||||
if t.Kind() != reflect.Ptr {
|
||||
return fmt.Errorf("ksql: expected to receive a pointer to struct, but got: %T", record)
|
||||
return fmt.Errorf("KSQL: expected to receive a pointer to struct, but got: %T", record)
|
||||
}
|
||||
|
||||
if v.IsNil() {
|
||||
return fmt.Errorf("ksql: expected a valid pointer to struct as argument but received a nil pointer: %v", record)
|
||||
return fmt.Errorf("KSQL: expected a valid pointer to struct as argument but received a nil pointer: %v", record)
|
||||
}
|
||||
|
||||
tStruct := t.Elem()
|
||||
if tStruct.Kind() != reflect.Struct {
|
||||
return fmt.Errorf("ksql: expected to receive a pointer to struct, but got: %T", record)
|
||||
return fmt.Errorf("KSQL: expected to receive a pointer to struct, but got: %T", record)
|
||||
}
|
||||
|
||||
info, err := structs.GetTagInfo(tStruct)
|
||||
@ -251,20 +279,22 @@ func (c DB) QueryOne(
|
||||
query = selectPrefix + query
|
||||
}
|
||||
|
||||
defer ctxLog(ctx, query, params, &err)
|
||||
|
||||
rows, err := c.db.QueryContext(ctx, query, params...)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error running query: %s", err)
|
||||
return fmt.Errorf("error running query: %w", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
if !rows.Next() {
|
||||
if rows.Err() != nil {
|
||||
return rows.Err()
|
||||
if err := rows.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
return ErrRecordNotFound
|
||||
}
|
||||
|
||||
err = scanRowsFromType(c.dialect, rows, record, t, v)
|
||||
err = scanRowsFromType(ctx, c.dialect, rows, record, t, v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -291,7 +321,7 @@ func (c DB) QueryOne(
|
||||
func (c DB) QueryChunks(
|
||||
ctx context.Context,
|
||||
parser ChunkParser,
|
||||
) error {
|
||||
) (err error) {
|
||||
fnValue := reflect.ValueOf(parser.ForEachChunk)
|
||||
chunkType, err := structs.ParseInputFunc(parser.ForEachChunk)
|
||||
if err != nil {
|
||||
@ -324,6 +354,8 @@ func (c DB) QueryChunks(
|
||||
parser.Query = selectPrefix + parser.Query
|
||||
}
|
||||
|
||||
defer ctxLog(ctx, parser.Query, parser.Params, &err)
|
||||
|
||||
rows, err := c.db.QueryContext(ctx, parser.Query, parser.Params...)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -343,7 +375,7 @@ func (c DB) QueryChunks(
|
||||
chunk = reflect.Append(chunk, elemValue)
|
||||
}
|
||||
|
||||
err = scanRows(c.dialect, rows, chunk.Index(idx).Addr().Interface())
|
||||
err = scanRows(ctx, c.dialect, rows, chunk.Index(idx).Addr().Interface())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -397,22 +429,22 @@ func (c DB) Insert(
|
||||
ctx context.Context,
|
||||
table Table,
|
||||
record interface{},
|
||||
) error {
|
||||
) (err error) {
|
||||
v := reflect.ValueOf(record)
|
||||
t := v.Type()
|
||||
if err := assertStructPtr(t); err != nil {
|
||||
if err = assertStructPtr(t); err != nil {
|
||||
return fmt.Errorf(
|
||||
"ksql: expected record to be a pointer to struct, but got: %T",
|
||||
"KSQL: expected record to be a pointer to struct, but got: %T",
|
||||
record,
|
||||
)
|
||||
}
|
||||
|
||||
if v.IsNil() {
|
||||
return fmt.Errorf("ksql: expected a valid pointer to struct as argument but received a nil pointer: %v", record)
|
||||
return fmt.Errorf("KSQL: expected a valid pointer to struct as argument but received a nil pointer: %v", record)
|
||||
}
|
||||
|
||||
if err := table.validate(); err != nil {
|
||||
return fmt.Errorf("can't insert in ksql.Table: %s", err)
|
||||
return fmt.Errorf("can't insert in ksql.Table: %w", err)
|
||||
}
|
||||
|
||||
info, err := structs.GetTagInfo(t.Elem())
|
||||
@ -420,22 +452,24 @@ func (c DB) Insert(
|
||||
return err
|
||||
}
|
||||
|
||||
query, params, scanValues, err := buildInsertQuery(c.dialect, table, t, v, info, record)
|
||||
query, params, scanValues, err := buildInsertQuery(ctx, c.dialect, table, t, v, info, record)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer ctxLog(ctx, query, params, &err)
|
||||
|
||||
switch table.insertMethodFor(c.dialect) {
|
||||
case insertWithReturning, insertWithOutput:
|
||||
case sqldialect.InsertWithReturning, sqldialect.InsertWithOutput:
|
||||
err = c.insertReturningIDs(ctx, query, params, scanValues, table.idColumns)
|
||||
case insertWithLastInsertID:
|
||||
case sqldialect.InsertWithLastInsertID:
|
||||
err = c.insertWithLastInsertID(ctx, t, v, info, record, query, params, table.idColumns[0])
|
||||
case insertWithNoIDRetrieval:
|
||||
case sqldialect.InsertWithNoIDRetrieval:
|
||||
err = c.insertWithNoIDRetrieval(ctx, query, params)
|
||||
default:
|
||||
// Unsupported drivers should be detected on the New() function,
|
||||
// So we don't expect the code to ever get into this default case.
|
||||
err = fmt.Errorf("code error: unsupported driver `%s`", c.driver)
|
||||
err = fmt.Errorf("code error: unsupported driver `%s`", c.dialect.DriverName())
|
||||
}
|
||||
|
||||
return err
|
||||
@ -483,30 +517,52 @@ func (c DB) insertWithLastInsertID(
|
||||
) error {
|
||||
result, err := c.db.ExecContext(ctx, query, params...)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("error running insert query: %w", err)
|
||||
}
|
||||
|
||||
id, err := result.LastInsertId()
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("error fetching LastInsertId: %w", err)
|
||||
}
|
||||
|
||||
vID := reflect.ValueOf(id)
|
||||
tID := vID.Type()
|
||||
|
||||
fieldAddr := v.Elem().Field(info.ByName(idName).Index).Addr()
|
||||
fieldType := fieldAddr.Type().Elem()
|
||||
fieldValue := v.Elem().Field(info.ByName(idName).Index)
|
||||
fieldType := fieldValue.Type()
|
||||
|
||||
if !tID.ConvertibleTo(fieldType) {
|
||||
baseFieldKind := fieldType.Kind()
|
||||
leafFieldKind := baseFieldKind
|
||||
if baseFieldKind == reflect.Pointer {
|
||||
leafFieldKind = fieldType.Elem().Kind()
|
||||
}
|
||||
|
||||
switch leafFieldKind {
|
||||
case reflect.Int, reflect.Int64, reflect.Uint, reflect.Uint64:
|
||||
if baseFieldKind == reflect.Pointer {
|
||||
// If fieldValue is nil allocate memory for it:
|
||||
if fieldValue.IsNil() {
|
||||
fieldValue.Set(reflect.New(fieldType.Elem()))
|
||||
}
|
||||
|
||||
fieldValue.Elem().Set(vID.Convert(fieldType.Elem()))
|
||||
return nil
|
||||
}
|
||||
|
||||
fieldValue.Set(vID.Convert(fieldType))
|
||||
return nil
|
||||
|
||||
case reflect.String:
|
||||
// In case the record's ID is a string,
|
||||
// we cannot retrieve it, so we just return:
|
||||
return nil
|
||||
|
||||
default:
|
||||
return fmt.Errorf(
|
||||
"can't convert last insert id of type int64 into field `%s` of type %v",
|
||||
"error scanning field `%s` cannot assign last insert id of type int64 into field of type %v",
|
||||
idName,
|
||||
fieldType,
|
||||
)
|
||||
}
|
||||
|
||||
fieldAddr.Elem().Set(vID.Convert(fieldType))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c DB) insertWithNoIDRetrieval(
|
||||
@ -540,24 +596,23 @@ func assertStructPtr(t reflect.Type) error {
|
||||
//
|
||||
// The examples below should work for both types of tables:
|
||||
//
|
||||
// err := c.Delete(ctx, UsersTable, user)
|
||||
// err := c.Delete(ctx, UsersTable, user)
|
||||
//
|
||||
// err := c.Delete(ctx, UserPostsTable, map[string]interface{}{
|
||||
// "user_id": user.ID,
|
||||
// "post_id": post.ID,
|
||||
// })
|
||||
// err := c.Delete(ctx, UserPostsTable, map[string]interface{}{
|
||||
// "user_id": user.ID,
|
||||
// "post_id": post.ID,
|
||||
// })
|
||||
//
|
||||
// The example below is shorter but will only work for tables with a single primary key:
|
||||
//
|
||||
// err := c.Delete(ctx, UsersTable, user.ID)
|
||||
//
|
||||
// err := c.Delete(ctx, UsersTable, user.ID)
|
||||
func (c DB) Delete(
|
||||
ctx context.Context,
|
||||
table Table,
|
||||
idOrRecord interface{},
|
||||
) error {
|
||||
) (err error) {
|
||||
if err := table.validate(); err != nil {
|
||||
return fmt.Errorf("can't delete from ksql.Table: %s", err)
|
||||
return fmt.Errorf("can't delete from ksql.Table: %w", err)
|
||||
}
|
||||
|
||||
idMap, err := normalizeIDsAsMap(table.idColumns, idOrRecord)
|
||||
@ -569,6 +624,8 @@ func (c DB) Delete(
|
||||
var params []interface{}
|
||||
query, params = buildDeleteQuery(c.dialect, table, idMap)
|
||||
|
||||
defer ctxLog(ctx, query, params, &err)
|
||||
|
||||
result, err := c.db.ExecContext(ctx, query, params...)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -576,7 +633,7 @@ func (c DB) Delete(
|
||||
|
||||
n, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to check if the record was succesfully deleted: %s", err)
|
||||
return fmt.Errorf("unable to check if the record was succesfully deleted: %w", err)
|
||||
}
|
||||
|
||||
if n == 0 {
|
||||
@ -595,16 +652,16 @@ func normalizeIDsAsMap(idNames []string, idOrMap interface{}) (idMap map[string]
|
||||
if t.Kind() == reflect.Ptr {
|
||||
v := reflect.ValueOf(idOrMap)
|
||||
if v.IsNil() {
|
||||
return nil, fmt.Errorf("ksql: expected a valid pointer to struct as argument but received a nil pointer: %v", idOrMap)
|
||||
return nil, fmt.Errorf("KSQL: expected a valid pointer to struct as argument but received a nil pointer: %v", idOrMap)
|
||||
}
|
||||
t = t.Elem()
|
||||
}
|
||||
|
||||
switch t.Kind() {
|
||||
case reflect.Struct:
|
||||
idMap, err = ksqltest.StructToMap(idOrMap)
|
||||
idMap, err = structs.StructToMap(idOrMap)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not get ID(s) from input record")
|
||||
return nil, fmt.Errorf("could not get ID(s) from input record: %w", err)
|
||||
}
|
||||
case reflect.Map:
|
||||
var ok bool
|
||||
@ -621,19 +678,6 @@ func normalizeIDsAsMap(idNames []string, idOrMap interface{}) (idMap map[string]
|
||||
return idMap, validateIfAllIdsArePresent(idNames, idMap)
|
||||
}
|
||||
|
||||
// Update updates the given instances on the database by id.
|
||||
//
|
||||
// Partial updates are supported, i.e. it will ignore nil pointer attributes
|
||||
//
|
||||
// Deprecated: Use the Patch method instead
|
||||
func (c DB) Update(
|
||||
ctx context.Context,
|
||||
table Table,
|
||||
record interface{},
|
||||
) error {
|
||||
return c.Patch(ctx, table, record)
|
||||
}
|
||||
|
||||
// Patch applies a partial update (explained below) to the given instance on the database by id.
|
||||
//
|
||||
// Partial updates will ignore any nil pointer attributes from the struct, updating only
|
||||
@ -642,13 +686,13 @@ func (c DB) Patch(
|
||||
ctx context.Context,
|
||||
table Table,
|
||||
record interface{},
|
||||
) error {
|
||||
) (err error) {
|
||||
v := reflect.ValueOf(record)
|
||||
t := v.Type()
|
||||
tStruct := t
|
||||
if t.Kind() == reflect.Ptr {
|
||||
if v.IsNil() {
|
||||
return fmt.Errorf("ksql: expected a valid pointer to struct as argument but received a nil pointer: %v", record)
|
||||
return fmt.Errorf("KSQL: expected a valid pointer to struct as argument but received a nil pointer: %v", record)
|
||||
}
|
||||
tStruct = t.Elem()
|
||||
}
|
||||
@ -657,11 +701,18 @@ func (c DB) Patch(
|
||||
return err
|
||||
}
|
||||
|
||||
query, params, err := buildUpdateQuery(c.dialect, table.name, info, record, table.idColumns...)
|
||||
recordMap, err := structs.StructToMap(record)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
query, params, err := buildUpdateQuery(ctx, c.dialect, table.name, info, recordMap, table.idColumns...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer ctxLog(ctx, query, params, &err)
|
||||
|
||||
result, err := c.db.ExecContext(ctx, query, params...)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -670,7 +721,7 @@ func (c DB) Patch(
|
||||
n, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"unexpected error: unable to fetch how many rows were affected by the update: %s",
|
||||
"unexpected error: unable to fetch how many rows were affected by the update: %w",
|
||||
err,
|
||||
)
|
||||
}
|
||||
@ -682,14 +733,15 @@ func (c DB) Patch(
|
||||
}
|
||||
|
||||
func buildInsertQuery(
|
||||
dialect Dialect,
|
||||
ctx context.Context,
|
||||
dialect sqldialect.Provider,
|
||||
table Table,
|
||||
t reflect.Type,
|
||||
v reflect.Value,
|
||||
info structs.StructInfo,
|
||||
record interface{},
|
||||
) (query string, params []interface{}, scanValues []interface{}, err error) {
|
||||
recordMap, err := ksqltest.StructToMap(record)
|
||||
recordMap, err := structs.StructToMap(record)
|
||||
if err != nil {
|
||||
return "", nil, nil, err
|
||||
}
|
||||
@ -708,18 +760,29 @@ func buildInsertQuery(
|
||||
|
||||
columnNames := []string{}
|
||||
for col := range recordMap {
|
||||
if info.ByName(col).Modifier.SkipOnInsert {
|
||||
continue
|
||||
}
|
||||
|
||||
columnNames = append(columnNames, col)
|
||||
}
|
||||
|
||||
params = make([]interface{}, len(recordMap))
|
||||
valuesQuery := make([]string, len(recordMap))
|
||||
params = make([]interface{}, len(columnNames))
|
||||
valuesQuery := make([]string, len(columnNames))
|
||||
for i, col := range columnNames {
|
||||
recordValue := recordMap[col]
|
||||
params[i] = recordValue
|
||||
if info.ByName(col).SerializeAsJSON {
|
||||
params[i] = jsonSerializable{
|
||||
DriverName: dialect.DriverName(),
|
||||
Attr: recordValue,
|
||||
|
||||
valueFn := info.ByName(col).Modifier.Value
|
||||
if valueFn != nil {
|
||||
params[i] = modifiers.AttrValueWrapper{
|
||||
Ctx: ctx,
|
||||
Attr: recordValue,
|
||||
ValueFn: valueFn,
|
||||
OpInfo: ksqlmodifiers.OpInfo{
|
||||
DriverName: dialect.DriverName(),
|
||||
Method: "Insert",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -734,7 +797,7 @@ func buildInsertQuery(
|
||||
|
||||
var returningQuery, outputQuery string
|
||||
switch dialect.InsertMethod() {
|
||||
case insertWithReturning:
|
||||
case sqldialect.InsertWithReturning:
|
||||
escapedIDNames := []string{}
|
||||
for _, id := range table.idColumns {
|
||||
escapedIDNames = append(escapedIDNames, dialect.Escape(id))
|
||||
@ -747,7 +810,7 @@ func buildInsertQuery(
|
||||
v.Elem().Field(info.ByName(id).Index).Addr().Interface(),
|
||||
)
|
||||
}
|
||||
case insertWithOutput:
|
||||
case sqldialect.InsertWithOutput:
|
||||
escapedIDNames := []string{}
|
||||
for _, id := range table.idColumns {
|
||||
escapedIDNames = append(escapedIDNames, "INSERTED."+dialect.Escape(id))
|
||||
@ -762,11 +825,21 @@ func buildInsertQuery(
|
||||
}
|
||||
}
|
||||
|
||||
if len(columnNames) == 0 && dialect.DriverName() != "mysql" {
|
||||
query = fmt.Sprintf(
|
||||
"INSERT INTO %s%s DEFAULT VALUES%s",
|
||||
table.name,
|
||||
outputQuery,
|
||||
returningQuery,
|
||||
)
|
||||
return query, params, scanValues, nil
|
||||
}
|
||||
|
||||
// Note that the outputQuery and the returningQuery depend
|
||||
// on the selected driver, thus, they might be empty strings.
|
||||
query = fmt.Sprintf(
|
||||
"INSERT INTO %s (%s)%s VALUES (%s)%s",
|
||||
dialect.Escape(table.name),
|
||||
table.name,
|
||||
strings.Join(escapedColumnNames, ", "),
|
||||
outputQuery,
|
||||
strings.Join(valuesQuery, ", "),
|
||||
@ -777,26 +850,33 @@ func buildInsertQuery(
|
||||
}
|
||||
|
||||
func buildUpdateQuery(
|
||||
dialect Dialect,
|
||||
ctx context.Context,
|
||||
dialect sqldialect.Provider,
|
||||
tableName string,
|
||||
info structs.StructInfo,
|
||||
record interface{},
|
||||
recordMap map[string]interface{},
|
||||
idFieldNames ...string,
|
||||
) (query string, args []interface{}, err error) {
|
||||
recordMap, err := ksqltest.StructToMap(record)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
for key := range recordMap {
|
||||
if info.ByName(key).Modifier.SkipOnUpdate {
|
||||
delete(recordMap, key)
|
||||
}
|
||||
}
|
||||
|
||||
numAttrs := len(recordMap)
|
||||
args = make([]interface{}, numAttrs)
|
||||
numNonIDArgs := numAttrs - len(idFieldNames)
|
||||
whereArgs := args[numNonIDArgs:]
|
||||
|
||||
err = validateIfAllIdsArePresent(idFieldNames, recordMap)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
numNonIDArgs := numAttrs - len(idFieldNames)
|
||||
whereArgs := args[numNonIDArgs:]
|
||||
if numNonIDArgs == 0 {
|
||||
return "", nil, ErrNoValuesToUpdate
|
||||
}
|
||||
|
||||
whereQuery := make([]string, len(idFieldNames))
|
||||
for i, fieldName := range idFieldNames {
|
||||
whereArgs[i] = recordMap[fieldName]
|
||||
@ -817,10 +897,17 @@ func buildUpdateQuery(
|
||||
var setQuery []string
|
||||
for i, k := range keys {
|
||||
recordValue := recordMap[k]
|
||||
if info.ByName(k).SerializeAsJSON {
|
||||
recordValue = jsonSerializable{
|
||||
DriverName: dialect.DriverName(),
|
||||
Attr: recordValue,
|
||||
|
||||
valueFn := info.ByName(k).Modifier.Value
|
||||
if valueFn != nil {
|
||||
recordValue = modifiers.AttrValueWrapper{
|
||||
Ctx: ctx,
|
||||
Attr: recordValue,
|
||||
ValueFn: valueFn,
|
||||
OpInfo: ksqlmodifiers.OpInfo{
|
||||
DriverName: dialect.DriverName(),
|
||||
Method: "Update",
|
||||
},
|
||||
}
|
||||
}
|
||||
args[i] = recordValue
|
||||
@ -833,7 +920,7 @@ func buildUpdateQuery(
|
||||
|
||||
query = fmt.Sprintf(
|
||||
"UPDATE %s SET %s WHERE %s",
|
||||
dialect.Escape(tableName),
|
||||
tableName,
|
||||
strings.Join(setQuery, ", "),
|
||||
strings.Join(whereQuery, " AND "),
|
||||
)
|
||||
@ -845,11 +932,11 @@ func validateIfAllIdsArePresent(idNames []string, idMap map[string]interface{})
|
||||
for _, idName := range idNames {
|
||||
id, found := idMap[idName]
|
||||
if !found {
|
||||
return fmt.Errorf("missing required id field `%s` on input record", idName)
|
||||
return fmt.Errorf("missing required id field `%s` on input record: %w", idName, ErrRecordMissingIDs)
|
||||
}
|
||||
|
||||
if id == nil || reflect.ValueOf(id).IsZero() {
|
||||
return fmt.Errorf("invalid value '%v' received for id column: '%s'", id, idName)
|
||||
return fmt.Errorf("invalid value '%v' received for id column: '%s': %w", id, idName, ErrRecordMissingIDs)
|
||||
}
|
||||
}
|
||||
|
||||
@ -857,11 +944,21 @@ func validateIfAllIdsArePresent(idNames []string, idMap map[string]interface{})
|
||||
}
|
||||
|
||||
// Exec just runs an SQL command on the database returning no rows.
|
||||
func (c DB) Exec(ctx context.Context, query string, params ...interface{}) (Result, error) {
|
||||
func (c DB) Exec(ctx context.Context, query string, params ...interface{}) (_ Result, err error) {
|
||||
defer ctxLog(ctx, query, params, &err)
|
||||
|
||||
return c.db.ExecContext(ctx, query, params...)
|
||||
}
|
||||
|
||||
// Transaction just runs an SQL command on the database returning no rows.
|
||||
// Transaction encapsulates several queries into a single transaction.
|
||||
// All these queries should be made inside the input callback `fn`
|
||||
// and they should use the input ksql.Provider.
|
||||
//
|
||||
// If the callback returns any errors the transaction will be rolled back,
|
||||
// otherwise the transaction will me committed.
|
||||
//
|
||||
// If it happens that a second transaction is started inside a transaction
|
||||
// callback the same transaction will be reused with no errors.
|
||||
func (c DB) Transaction(ctx context.Context, fn func(Provider) error) error {
|
||||
switch txBeginner := c.db.(type) {
|
||||
case Tx:
|
||||
@ -869,14 +966,15 @@ func (c DB) Transaction(ctx context.Context, fn func(Provider) error) error {
|
||||
case TxBeginner:
|
||||
tx, err := txBeginner.BeginTx(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("KSQL: error starting transaction: %w", err)
|
||||
}
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
rollbackErr := tx.Rollback(ctx)
|
||||
if rollbackErr != nil {
|
||||
r = errors.Wrap(rollbackErr,
|
||||
fmt.Sprintf("unable to rollback after panic with value: %v", r),
|
||||
r = fmt.Errorf(
|
||||
"KSQL: unable to rollback after panic with value: %v, rollback error: %w",
|
||||
r, rollbackErr,
|
||||
)
|
||||
}
|
||||
panic(r)
|
||||
@ -890,8 +988,9 @@ func (c DB) Transaction(ctx context.Context, fn func(Provider) error) error {
|
||||
if err != nil {
|
||||
rollbackErr := tx.Rollback(ctx)
|
||||
if rollbackErr != nil {
|
||||
err = errors.Wrap(rollbackErr,
|
||||
fmt.Sprintf("unable to rollback after error: %s", err.Error()),
|
||||
err = fmt.Errorf(
|
||||
"KSQL: unable to rollback after error: %s, rollback error: %w",
|
||||
err, rollbackErr,
|
||||
)
|
||||
}
|
||||
return err
|
||||
@ -900,7 +999,7 @@ func (c DB) Transaction(ctx context.Context, fn func(Provider) error) error {
|
||||
return tx.Commit(ctx)
|
||||
|
||||
default:
|
||||
return fmt.Errorf("can't start transaction: The DBAdapter doesn't implement the TxBeginner interface")
|
||||
return fmt.Errorf("KSQL: can't start transaction: The DBAdapter doesn't implement the TxBeginner interface")
|
||||
}
|
||||
}
|
||||
|
||||
@ -921,28 +1020,29 @@ func (nopScanner) Scan(value interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func scanRows(dialect Dialect, rows Rows, record interface{}) error {
|
||||
func scanRows(ctx context.Context, dialect sqldialect.Provider, rows Rows, record interface{}) error {
|
||||
v := reflect.ValueOf(record)
|
||||
t := v.Type()
|
||||
return scanRowsFromType(dialect, rows, record, t, v)
|
||||
return scanRowsFromType(ctx, dialect, rows, record, t, v)
|
||||
}
|
||||
|
||||
func scanRowsFromType(
|
||||
dialect Dialect,
|
||||
ctx context.Context,
|
||||
dialect sqldialect.Provider,
|
||||
rows Rows,
|
||||
record interface{},
|
||||
t reflect.Type,
|
||||
v reflect.Value,
|
||||
) error {
|
||||
if t.Kind() != reflect.Ptr {
|
||||
return fmt.Errorf("ksql: expected record to be a pointer to struct, but got: %T", record)
|
||||
return fmt.Errorf("KSQL: expected record to be a pointer to struct, but got: %T", record)
|
||||
}
|
||||
|
||||
v = v.Elem()
|
||||
t = t.Elem()
|
||||
|
||||
if t.Kind() != reflect.Struct {
|
||||
return fmt.Errorf("ksql: expected record to be a pointer to struct, but got: %T", record)
|
||||
return fmt.Errorf("KSQL: expected record to be a pointer to struct, but got: %T", record)
|
||||
}
|
||||
|
||||
info, err := structs.GetTagInfo(t)
|
||||
@ -950,30 +1050,47 @@ func scanRowsFromType(
|
||||
return err
|
||||
}
|
||||
|
||||
var attrNames []string
|
||||
var scanArgs []interface{}
|
||||
if info.IsNestedStruct {
|
||||
// This version is positional meaning that it expect the arguments
|
||||
// to follow an specific order. It's ok because we don't allow the
|
||||
// user to type the "SELECT" part of the query for nested structs.
|
||||
scanArgs, err = getScanArgsForNestedStructs(dialect, rows, t, v, info)
|
||||
attrNames, scanArgs, err = getScanArgsForNestedStructs(ctx, dialect, rows, t, v, info)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
names, err := rows.Columns()
|
||||
colNames, err := rows.Columns()
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("KSQL: unable to read columns from returned rows: %w", err)
|
||||
}
|
||||
// Since this version uses the names of the columns it works
|
||||
// with any order of attributes/columns.
|
||||
scanArgs = getScanArgsFromNames(dialect, names, v, info)
|
||||
attrNames, scanArgs = getScanArgsFromNames(ctx, dialect, colNames, v, info)
|
||||
}
|
||||
|
||||
return rows.Scan(scanArgs...)
|
||||
err = rows.Scan(scanArgs...)
|
||||
if err != nil {
|
||||
if scanErr, ok := err.(ScanArgError); ok {
|
||||
return fmt.Errorf(
|
||||
"KSQL: scan error: %w",
|
||||
scanErr.ErrorWithStructNames(t.Name(), attrNames[scanErr.ColumnIndex]),
|
||||
)
|
||||
}
|
||||
return fmt.Errorf("KSQL: scan error: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getScanArgsForNestedStructs(dialect Dialect, rows Rows, t reflect.Type, v reflect.Value, info structs.StructInfo) ([]interface{}, error) {
|
||||
scanArgs := []interface{}{}
|
||||
func getScanArgsForNestedStructs(
|
||||
ctx context.Context,
|
||||
dialect sqldialect.Provider,
|
||||
rows Rows,
|
||||
t reflect.Type,
|
||||
v reflect.Value,
|
||||
info structs.StructInfo,
|
||||
) (attrNames []string, scanArgs []interface{}, _ error) {
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
if !info.ByIndex(i).Valid {
|
||||
continue
|
||||
@ -982,7 +1099,7 @@ func getScanArgsForNestedStructs(dialect Dialect, rows Rows, t reflect.Type, v r
|
||||
// TODO(vingarcia00): Handle case where type is pointer
|
||||
nestedStructInfo, err := structs.GetTagInfo(t.Field(i).Type)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
nestedStructValue := v.Field(i)
|
||||
@ -992,48 +1109,66 @@ func getScanArgsForNestedStructs(dialect Dialect, rows Rows, t reflect.Type, v r
|
||||
continue
|
||||
}
|
||||
|
||||
valueScanner := nopScannerValue
|
||||
if fieldInfo.Valid {
|
||||
valueScanner = nestedStructValue.Field(fieldInfo.Index).Addr().Interface()
|
||||
if fieldInfo.SerializeAsJSON {
|
||||
valueScanner = &jsonSerializable{
|
||||
valueScanner := nestedStructValue.Field(fieldInfo.Index).Addr().Interface()
|
||||
if fieldInfo.Modifier.Scan != nil {
|
||||
valueScanner = &modifiers.AttrScanWrapper{
|
||||
Ctx: ctx,
|
||||
AttrPtr: valueScanner,
|
||||
ScanFn: fieldInfo.Modifier.Scan,
|
||||
OpInfo: ksqlmodifiers.OpInfo{
|
||||
DriverName: dialect.DriverName(),
|
||||
Attr: valueScanner,
|
||||
}
|
||||
// We will not differentiate between Query, QueryOne and QueryChunks
|
||||
// if we did this could lead users to make very strange modifiers
|
||||
Method: "Query",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
scanArgs = append(scanArgs, valueScanner)
|
||||
attrNames = append(attrNames, info.ByIndex(i).AttrName+"."+fieldInfo.AttrName)
|
||||
}
|
||||
}
|
||||
|
||||
return scanArgs, nil
|
||||
return attrNames, scanArgs, nil
|
||||
}
|
||||
|
||||
func getScanArgsFromNames(dialect Dialect, names []string, v reflect.Value, info structs.StructInfo) []interface{} {
|
||||
scanArgs := []interface{}{}
|
||||
func getScanArgsFromNames(
|
||||
ctx context.Context,
|
||||
dialect sqldialect.Provider,
|
||||
names []string,
|
||||
v reflect.Value,
|
||||
info structs.StructInfo,
|
||||
) (attrNames []string, scanArgs []interface{}) {
|
||||
for _, name := range names {
|
||||
fieldInfo := info.ByName(name)
|
||||
|
||||
valueScanner := nopScannerValue
|
||||
if fieldInfo.Valid {
|
||||
valueScanner = v.Field(fieldInfo.Index).Addr().Interface()
|
||||
if fieldInfo.SerializeAsJSON {
|
||||
valueScanner = &jsonSerializable{
|
||||
DriverName: dialect.DriverName(),
|
||||
Attr: valueScanner,
|
||||
if fieldInfo.Modifier.Scan != nil {
|
||||
valueScanner = &modifiers.AttrScanWrapper{
|
||||
Ctx: ctx,
|
||||
AttrPtr: valueScanner,
|
||||
ScanFn: fieldInfo.Modifier.Scan,
|
||||
OpInfo: ksqlmodifiers.OpInfo{
|
||||
DriverName: dialect.DriverName(),
|
||||
// We will not differentiate between Query, QueryOne and QueryChunks
|
||||
// if we did this could lead users to make very strange modifiers
|
||||
Method: "Query",
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scanArgs = append(scanArgs, valueScanner)
|
||||
attrNames = append(attrNames, fieldInfo.AttrName)
|
||||
}
|
||||
|
||||
return scanArgs
|
||||
return attrNames, scanArgs
|
||||
}
|
||||
|
||||
func buildDeleteQuery(
|
||||
dialect Dialect,
|
||||
dialect sqldialect.Provider,
|
||||
table Table,
|
||||
idMap map[string]interface{},
|
||||
) (query string, params []interface{}) {
|
||||
@ -1047,7 +1182,7 @@ func buildDeleteQuery(
|
||||
|
||||
return fmt.Sprintf(
|
||||
"DELETE FROM %s WHERE %s",
|
||||
dialect.Escape(table.name),
|
||||
table.name,
|
||||
strings.Join(whereQuery, " AND "),
|
||||
), params
|
||||
}
|
||||
@ -1069,7 +1204,7 @@ func getFirstToken(s string) string {
|
||||
}
|
||||
|
||||
func buildSelectQuery(
|
||||
dialect Dialect,
|
||||
dialect sqldialect.Provider,
|
||||
structType reflect.Type,
|
||||
info structs.StructInfo,
|
||||
selectQueryCache *sync.Map,
|
||||
@ -1096,7 +1231,7 @@ func buildSelectQuery(
|
||||
}
|
||||
|
||||
func buildSelectQueryForPlainStructs(
|
||||
dialect Dialect,
|
||||
dialect sqldialect.Provider,
|
||||
structType reflect.Type,
|
||||
info structs.StructInfo,
|
||||
) string {
|
||||
@ -1107,14 +1242,14 @@ func buildSelectQueryForPlainStructs(
|
||||
continue
|
||||
}
|
||||
|
||||
fields = append(fields, dialect.Escape(fieldInfo.Name))
|
||||
fields = append(fields, dialect.Escape(fieldInfo.ColumnName))
|
||||
}
|
||||
|
||||
return "SELECT " + strings.Join(fields, ", ") + " "
|
||||
}
|
||||
|
||||
func buildSelectQueryForNestedStructs(
|
||||
dialect Dialect,
|
||||
dialect sqldialect.Provider,
|
||||
structType reflect.Type,
|
||||
info structs.StructInfo,
|
||||
) (string, error) {
|
||||
@ -1125,7 +1260,7 @@ func buildSelectQueryForNestedStructs(
|
||||
continue
|
||||
}
|
||||
|
||||
nestedStructName := nestedStructInfo.Name
|
||||
nestedStructName := nestedStructInfo.ColumnName
|
||||
nestedStructType := structType.Field(i).Type
|
||||
if nestedStructType.Kind() != reflect.Struct {
|
||||
return "", fmt.Errorf(
|
||||
@ -1147,7 +1282,7 @@ func buildSelectQueryForNestedStructs(
|
||||
|
||||
fields = append(
|
||||
fields,
|
||||
dialect.Escape(nestedStructName)+"."+dialect.Escape(fieldInfo.Name),
|
||||
dialect.Escape(nestedStructName)+"."+dialect.Escape(fieldInfo.ColumnName),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
378
ksql_test.go
378
ksql_test.go
@ -1,11 +1,25 @@
|
||||
package ksql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
tt "github.com/vingarcia/ksql/internal/testtools"
|
||||
"github.com/vingarcia/ksql/sqldialect"
|
||||
)
|
||||
|
||||
func TestScanArgError(t *testing.T) {
|
||||
err := ScanArgError{
|
||||
ColumnIndex: 12,
|
||||
Err: io.EOF,
|
||||
}
|
||||
|
||||
tt.AssertErrContains(t, err, "input attribute", "index 12", "EOF")
|
||||
}
|
||||
|
||||
func TestConfigSetDefaultValues(t *testing.T) {
|
||||
config := Config{}
|
||||
config.SetDefaultValues()
|
||||
@ -17,24 +31,374 @@ func TestConfigSetDefaultValues(t *testing.T) {
|
||||
|
||||
func TestNewAdapterWith(t *testing.T) {
|
||||
t.Run("should build new instances correctly", func(t *testing.T) {
|
||||
for dialectName := range supportedDialects {
|
||||
for _, dialect := range sqldialect.SupportedDialects {
|
||||
db, err := NewWithAdapter(
|
||||
DBAdapter(nil),
|
||||
dialectName,
|
||||
dialect,
|
||||
)
|
||||
|
||||
tt.AssertNoErr(t, err)
|
||||
tt.AssertEqual(t, db.dialect, supportedDialects[dialectName])
|
||||
tt.AssertEqual(t, db.driver, dialectName)
|
||||
tt.AssertEqual(t, db.dialect, dialect)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should report invalid dialectNames correctly", func(t *testing.T) {
|
||||
t.Run("should report invalid dialects correctly", func(t *testing.T) {
|
||||
_, err := NewWithAdapter(
|
||||
DBAdapter(nil),
|
||||
"fake-dialect-name",
|
||||
nil,
|
||||
)
|
||||
|
||||
tt.AssertNotEqual(t, err, nil)
|
||||
tt.AssertErrContains(t, err, "expected a valid", "Provider", "nil")
|
||||
})
|
||||
}
|
||||
|
||||
func TestClose(t *testing.T) {
|
||||
t.Run("should close the adapter if it implements the io.Closer interface", func(t *testing.T) {
|
||||
c := DB{
|
||||
db: struct {
|
||||
DBAdapter
|
||||
io.Closer
|
||||
}{
|
||||
DBAdapter: mockDBAdapter{},
|
||||
Closer: mockCloser{
|
||||
CloseFn: func() error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
err := c.Close()
|
||||
tt.AssertNoErr(t, err)
|
||||
})
|
||||
|
||||
t.Run("should exit normally if the adapter does not implement the io.Closer interface", func(t *testing.T) {
|
||||
c := DB{
|
||||
db: mockDBAdapter{},
|
||||
}
|
||||
|
||||
err := c.Close()
|
||||
tt.AssertNoErr(t, err)
|
||||
})
|
||||
|
||||
t.Run("should report an error if the adapter.Close() returns one", func(t *testing.T) {
|
||||
c := DB{
|
||||
db: struct {
|
||||
DBAdapter
|
||||
io.Closer
|
||||
}{
|
||||
DBAdapter: mockDBAdapter{},
|
||||
Closer: mockCloser{
|
||||
CloseFn: func() error {
|
||||
return fmt.Errorf("fakeCloseErrMsg")
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
err := c.Close()
|
||||
tt.AssertErrContains(t, err, "fakeCloseErrMsg")
|
||||
})
|
||||
}
|
||||
|
||||
func TestInjectLogger(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
tests := []struct {
|
||||
desc string
|
||||
methodCall func(ctx context.Context, db Provider) error
|
||||
queryErr error
|
||||
|
||||
expectLoggedQueryToContain []string
|
||||
expectLoggedParams map[interface{}]bool
|
||||
expectLoggedErrToContain []string
|
||||
}{
|
||||
{
|
||||
desc: "should work for the Query function",
|
||||
methodCall: func(ctx context.Context, db Provider) error {
|
||||
var row []struct {
|
||||
Count int `ksql:"count"`
|
||||
}
|
||||
return db.Query(ctx, &row, `FROM users WHERE type = $1 AND age < $2`, "fakeType", 42)
|
||||
},
|
||||
|
||||
expectLoggedQueryToContain: []string{"SELECT", "count", "type = $1"},
|
||||
expectLoggedParams: map[interface{}]bool{"fakeType": true, 42: true},
|
||||
},
|
||||
{
|
||||
desc: "should work for the Query function when an error is returned",
|
||||
methodCall: func(ctx context.Context, db Provider) error {
|
||||
var row []struct {
|
||||
Count int `ksql:"count"`
|
||||
}
|
||||
return db.Query(ctx, &row, `FROM users WHERE type = $1 AND age < $2`, "fakeType", 42)
|
||||
},
|
||||
queryErr: errors.New("fakeErrMsg"),
|
||||
|
||||
expectLoggedQueryToContain: []string{"SELECT", "count", "type = $1"},
|
||||
expectLoggedParams: map[interface{}]bool{"fakeType": true, 42: true},
|
||||
expectLoggedErrToContain: []string{"fakeErrMsg"},
|
||||
},
|
||||
{
|
||||
desc: "should work for the QueryOne function",
|
||||
methodCall: func(ctx context.Context, db Provider) error {
|
||||
var row struct {
|
||||
Count int `ksql:"count"`
|
||||
}
|
||||
return db.QueryOne(ctx, &row, `FROM users WHERE type = $1 AND age < $2`, "fakeType", 42)
|
||||
},
|
||||
|
||||
expectLoggedQueryToContain: []string{"SELECT", "count", "type = $1"},
|
||||
expectLoggedParams: map[interface{}]bool{"fakeType": true, 42: true},
|
||||
},
|
||||
{
|
||||
desc: "should work for the QueryOne function when an error is returned",
|
||||
methodCall: func(ctx context.Context, db Provider) error {
|
||||
var row struct {
|
||||
Count int `ksql:"count"`
|
||||
}
|
||||
return db.QueryOne(ctx, &row, `FROM users WHERE type = $1 AND age < $2`, "fakeType", 42)
|
||||
},
|
||||
queryErr: errors.New("fakeErrMsg"),
|
||||
|
||||
expectLoggedQueryToContain: []string{"SELECT", "count", "type = $1"},
|
||||
expectLoggedParams: map[interface{}]bool{"fakeType": true, 42: true},
|
||||
expectLoggedErrToContain: []string{"fakeErrMsg"},
|
||||
},
|
||||
{
|
||||
desc: "should work for the QueryChunks function",
|
||||
methodCall: func(ctx context.Context, db Provider) error {
|
||||
type Row struct {
|
||||
Count int `ksql:"count"`
|
||||
}
|
||||
return db.QueryChunks(ctx, ChunkParser{
|
||||
Query: `FROM users WHERE type = $1 AND age < $2`,
|
||||
Params: []interface{}{"fakeType", 42},
|
||||
ChunkSize: 100,
|
||||
ForEachChunk: func(row []Row) error {
|
||||
return nil
|
||||
},
|
||||
})
|
||||
},
|
||||
|
||||
expectLoggedQueryToContain: []string{"SELECT", "count", "type = $1"},
|
||||
expectLoggedParams: map[interface{}]bool{"fakeType": true, 42: true},
|
||||
},
|
||||
{
|
||||
desc: "should work for the QueryChunks function when an error is returned",
|
||||
methodCall: func(ctx context.Context, db Provider) error {
|
||||
type Row struct {
|
||||
Count int `ksql:"count"`
|
||||
}
|
||||
return db.QueryChunks(ctx, ChunkParser{
|
||||
Query: `FROM users WHERE type = $1 AND age < $2`,
|
||||
Params: []interface{}{"fakeType", 42},
|
||||
ChunkSize: 100,
|
||||
ForEachChunk: func(row []Row) error {
|
||||
return nil
|
||||
},
|
||||
})
|
||||
},
|
||||
queryErr: errors.New("fakeErrMsg"),
|
||||
|
||||
expectLoggedQueryToContain: []string{"SELECT", "count", "type = $1"},
|
||||
expectLoggedParams: map[interface{}]bool{"fakeType": true, 42: true},
|
||||
expectLoggedErrToContain: []string{"fakeErrMsg"},
|
||||
},
|
||||
{
|
||||
desc: "should work for the Insert function",
|
||||
methodCall: func(ctx context.Context, db Provider) error {
|
||||
fakeRecord := struct {
|
||||
ID int `ksql:"id"`
|
||||
Count int `ksql:"count"`
|
||||
}{
|
||||
ID: 42,
|
||||
Count: 43,
|
||||
}
|
||||
return db.Insert(ctx, NewTable("fakeTable"), &fakeRecord)
|
||||
},
|
||||
|
||||
expectLoggedQueryToContain: []string{"INSERT", "fakeTable", `"id"`},
|
||||
expectLoggedParams: map[interface{}]bool{42: true, 43: true},
|
||||
},
|
||||
{
|
||||
desc: "should work for the Insert function when an error is returned",
|
||||
methodCall: func(ctx context.Context, db Provider) error {
|
||||
fakeRecord := struct {
|
||||
ID int `ksql:"id"`
|
||||
Count int `ksql:"count"`
|
||||
}{
|
||||
ID: 42,
|
||||
Count: 43,
|
||||
}
|
||||
return db.Insert(ctx, NewTable("fakeTable"), &fakeRecord)
|
||||
},
|
||||
queryErr: errors.New("fakeErrMsg"),
|
||||
|
||||
expectLoggedQueryToContain: []string{"INSERT", "fakeTable", `"id"`},
|
||||
expectLoggedParams: map[interface{}]bool{42: true, 43: true},
|
||||
expectLoggedErrToContain: []string{"fakeErrMsg"},
|
||||
},
|
||||
{
|
||||
desc: "should work for the Patch function",
|
||||
methodCall: func(ctx context.Context, db Provider) error {
|
||||
fakeRecord := struct {
|
||||
ID int `ksql:"id"`
|
||||
Count int `ksql:"count"`
|
||||
}{
|
||||
ID: 42,
|
||||
Count: 43,
|
||||
}
|
||||
return db.Patch(ctx, NewTable("fakeTable"), &fakeRecord)
|
||||
},
|
||||
|
||||
expectLoggedQueryToContain: []string{"UPDATE", "fakeTable", `"id"`},
|
||||
expectLoggedParams: map[interface{}]bool{42: true, 43: true},
|
||||
},
|
||||
{
|
||||
desc: "should work for the Patch function when an error is returned",
|
||||
methodCall: func(ctx context.Context, db Provider) error {
|
||||
fakeRecord := struct {
|
||||
ID int `ksql:"id"`
|
||||
Count int `ksql:"count"`
|
||||
}{
|
||||
ID: 42,
|
||||
Count: 43,
|
||||
}
|
||||
return db.Patch(ctx, NewTable("fakeTable"), &fakeRecord)
|
||||
},
|
||||
queryErr: errors.New("fakeErrMsg"),
|
||||
|
||||
expectLoggedQueryToContain: []string{"UPDATE", "fakeTable", `"id"`},
|
||||
expectLoggedParams: map[interface{}]bool{42: true, 43: true},
|
||||
expectLoggedErrToContain: []string{"fakeErrMsg"},
|
||||
},
|
||||
{
|
||||
desc: "should work for the Delete function",
|
||||
methodCall: func(ctx context.Context, db Provider) error {
|
||||
fakeRecord := struct {
|
||||
ID int `ksql:"id"`
|
||||
Count int `ksql:"count"`
|
||||
}{
|
||||
ID: 42,
|
||||
Count: 43,
|
||||
}
|
||||
return db.Delete(ctx, NewTable("fakeTable"), &fakeRecord)
|
||||
},
|
||||
|
||||
expectLoggedQueryToContain: []string{"DELETE", "fakeTable", `"id"`},
|
||||
expectLoggedParams: map[interface{}]bool{42: true},
|
||||
},
|
||||
{
|
||||
desc: "should work for the Delete function when an error is returned",
|
||||
methodCall: func(ctx context.Context, db Provider) error {
|
||||
fakeRecord := struct {
|
||||
ID int `ksql:"id"`
|
||||
Count int `ksql:"count"`
|
||||
}{
|
||||
ID: 42,
|
||||
Count: 43,
|
||||
}
|
||||
return db.Delete(ctx, NewTable("fakeTable"), &fakeRecord)
|
||||
},
|
||||
queryErr: errors.New("fakeErrMsg"),
|
||||
|
||||
expectLoggedQueryToContain: []string{"DELETE", "fakeTable", `"id"`},
|
||||
expectLoggedParams: map[interface{}]bool{42: true},
|
||||
expectLoggedErrToContain: []string{"fakeErrMsg"},
|
||||
},
|
||||
{
|
||||
desc: "should work for the Exec function",
|
||||
methodCall: func(ctx context.Context, db Provider) error {
|
||||
_, err := db.Exec(ctx, `DELETE FROM fakeTable WHERE type = $1 OR age >= $2`, "fakeType", 142)
|
||||
return err
|
||||
},
|
||||
|
||||
expectLoggedQueryToContain: []string{"DELETE", "fakeTable", "type", "age"},
|
||||
expectLoggedParams: map[interface{}]bool{"fakeType": true, 142: true},
|
||||
},
|
||||
{
|
||||
desc: "should work for the Exec function when an error is returned",
|
||||
methodCall: func(ctx context.Context, db Provider) error {
|
||||
_, err := db.Exec(ctx, `DELETE FROM fakeTable WHERE type = $1 OR age >= $2`, "fakeType", 142)
|
||||
return err
|
||||
},
|
||||
queryErr: errors.New("fakeErrMsg"),
|
||||
|
||||
expectLoggedQueryToContain: []string{"DELETE", "fakeTable", "type", "age"},
|
||||
expectLoggedParams: map[interface{}]bool{"fakeType": true, 142: true},
|
||||
expectLoggedErrToContain: []string{"fakeErrMsg"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
var inputQuery string
|
||||
var inputParams []interface{}
|
||||
numRows := 1
|
||||
c := DB{
|
||||
dialect: sqldialect.SupportedDialects["postgres"],
|
||||
db: mockDBAdapter{
|
||||
QueryContextFn: func(ctx context.Context, query string, params ...interface{}) (Rows, error) {
|
||||
inputQuery = query
|
||||
inputParams = params
|
||||
|
||||
return mockRows{
|
||||
ScanFn: func(args ...interface{}) error {
|
||||
return nil
|
||||
},
|
||||
// Make sure this mock will return a single row
|
||||
// for the purposes of this test:
|
||||
NextFn: func() bool {
|
||||
numRows--
|
||||
return numRows >= 0
|
||||
},
|
||||
ColumnsFn: func() ([]string, error) { return []string{"count"}, nil },
|
||||
}, test.queryErr
|
||||
},
|
||||
ExecContextFn: func(ctx context.Context, query string, params ...interface{}) (Result, error) {
|
||||
inputQuery = query
|
||||
inputParams = params
|
||||
|
||||
return mockResult{
|
||||
// Make sure this mock will return a single row
|
||||
// for the purposes of this test:
|
||||
RowsAffectedFn: func() (int64, error) {
|
||||
return 1, nil
|
||||
},
|
||||
}, test.queryErr
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var loggedQuery string
|
||||
var loggedParams []interface{}
|
||||
var loggedErr error
|
||||
ctx := InjectLogger(ctx, func(ctx context.Context, values LogValues) {
|
||||
loggedQuery = values.Query
|
||||
loggedParams = values.Params
|
||||
loggedErr = values.Err
|
||||
})
|
||||
|
||||
err := test.methodCall(ctx, c)
|
||||
if test.expectLoggedErrToContain != nil {
|
||||
tt.AssertErrContains(t, err, test.expectLoggedErrToContain...)
|
||||
tt.AssertErrContains(t, loggedErr, test.expectLoggedErrToContain...)
|
||||
} else {
|
||||
tt.AssertNoErr(t, err)
|
||||
tt.AssertEqual(t, loggedErr, nil)
|
||||
}
|
||||
|
||||
tt.AssertEqual(t, loggedQuery, inputQuery)
|
||||
tt.AssertEqual(t, loggedParams, inputParams)
|
||||
|
||||
tt.AssertContains(t, loggedQuery, test.expectLoggedQueryToContain...)
|
||||
|
||||
paramsMap := map[interface{}]bool{}
|
||||
for _, param := range loggedParams {
|
||||
paramsMap[param] = true
|
||||
}
|
||||
tt.AssertEqual(t, paramsMap, test.expectLoggedParams)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user