mirror of
https://github.com/zeromicro/go-zero.git
synced 2026-05-11 16:59:59 +08:00
Compare commits
42 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9ccb997ed8 | ||
|
|
01c92a6bc5 | ||
|
|
c9a2a60e28 | ||
|
|
b0739d63c0 | ||
|
|
c22f84cb5f | ||
|
|
60450bab02 | ||
|
|
3e8cec5c78 | ||
|
|
74ee163761 | ||
|
|
ea4f680052 | ||
|
|
58cdba2c5d | ||
|
|
a2fbc14c70 | ||
|
|
158df8c270 | ||
|
|
30ec236a87 | ||
|
|
ac3653b3f9 | ||
|
|
8520db4fd9 | ||
|
|
14141fed62 | ||
|
|
5d86cc2f20 | ||
|
|
8a6e4b7580 | ||
|
|
453f949638 | ||
|
|
75a330184d | ||
|
|
546fcd8bab | ||
|
|
3022f93b6d | ||
|
|
8ffc392c66 | ||
|
|
ae7d85dadf | ||
|
|
e89268ac37 | ||
|
|
aaa3623404 | ||
|
|
8998f16054 | ||
|
|
94417be018 | ||
|
|
f300408fc0 | ||
|
|
aaa39e17a3 | ||
|
|
73906f996d | ||
|
|
73417f54db | ||
|
|
491213afb8 | ||
|
|
edf743cd72 | ||
|
|
78a88be787 | ||
|
|
9f6a574f97 | ||
|
|
ea01cc78f0 | ||
|
|
a87978568a | ||
|
|
14cecb9b31 | ||
|
|
0ce54100a4 | ||
|
|
d28ac35ff7 | ||
|
|
a5962f677f |
102
CONTRIBUTING.md
Normal file
102
CONTRIBUTING.md
Normal file
@@ -0,0 +1,102 @@
|
||||
# Contributing
|
||||
|
||||
Welcome to go-zero!
|
||||
|
||||
- [Before you get started](#before-you-get-started)
|
||||
- [Code of Conduct](#code-of-conduct)
|
||||
- [Community Expectations](#community-expectations)
|
||||
- [Getting started](#getting-started)
|
||||
- [Your First Contribution](#your-first-contribution)
|
||||
- [Find something to work on](#find-something-to-work-on)
|
||||
- [Find a good first topic](#find-a-good-first-topic)
|
||||
- [Work on an Issue](#work-on-an-issue)
|
||||
- [File an Issue](#file-an-issue)
|
||||
- [Contributor Workflow](#contributor-workflow)
|
||||
- [Creating Pull Requests](#creating-pull-requests)
|
||||
- [Code Review](#code-review)
|
||||
- [Testing](#testing)
|
||||
|
||||
# Before you get started
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
Please make sure to read and observe our [Code of Conduct](/code-of-conduct.md).
|
||||
|
||||
## Community Expectations
|
||||
|
||||
go-zero is a community project driven by its community which strives to promote a healthy, friendly and productive environment.
|
||||
go-zero is a web and rpc framework written in Go. It's born to ensure the stability of the busy sites with resilient design. Builtin goctl greatly improves the development productivity.
|
||||
|
||||
# Getting started
|
||||
|
||||
- Fork the repository on GitHub.
|
||||
- Make your changes on your fork repository.
|
||||
- Submit a PR.
|
||||
|
||||
|
||||
# Your First Contribution
|
||||
|
||||
We will help you to contribute in different areas like filing issues, developing features, fixing critical bugs and
|
||||
getting your work reviewed and merged.
|
||||
|
||||
If you have questions about the development process,
|
||||
feel free to [file an issue](https://github.com/tal-tech/go-zero/issues/new/choose).
|
||||
|
||||
## Find something to work on
|
||||
|
||||
We are always in need of help, be it fixing documentation, reporting bugs or writing some code.
|
||||
Look at places where you feel best coding practices aren't followed, code refactoring is needed or tests are missing.
|
||||
Here is how you get started.
|
||||
|
||||
### Find a good first topic
|
||||
|
||||
[go-zero](https://github.com/tal-tech/go-zero) has beginner-friendly issues that provide a good first issue.
|
||||
For example, [go-zero](https://github.com/tal-tech/go-zero) has
|
||||
[help wanted](https://github.com/tal-tech/go-zero/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) and
|
||||
[good first issue](https://github.com/tal-tech/go-zero/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)
|
||||
labels for issues that should not need deep knowledge of the system.
|
||||
We can help new contributors who wish to work on such issues.
|
||||
|
||||
Another good way to contribute is to find a documentation improvement, such as a missing/broken link.
|
||||
Please see [Contributing](#contributing) below for the workflow.
|
||||
|
||||
#### Work on an issue
|
||||
|
||||
When you are willing to take on an issue, just reply on the issue. The maintainer will assign it to you.
|
||||
|
||||
### File an Issue
|
||||
|
||||
While we encourage everyone to contribute code, it is also appreciated when someone reports an issue.
|
||||
|
||||
Please follow the prompted submission guidelines while opening an issue.
|
||||
|
||||
# Contributor Workflow
|
||||
|
||||
Please do not ever hesitate to ask a question or send a pull request.
|
||||
|
||||
This is a rough outline of what a contributor's workflow looks like:
|
||||
|
||||
- Create a topic branch from where to base the contribution. This is usually master.
|
||||
- Make commits of logical units.
|
||||
- Push changes in a topic branch to a personal fork of the repository.
|
||||
- Submit a pull request to [go-zero](https://github.com/tal-tech/go-zero).
|
||||
|
||||
## Creating Pull Requests
|
||||
|
||||
Pull requests are often called simply "PR".
|
||||
go-zero generally follows the standard [github pull request](https://help.github.com/articles/about-pull-requests/) process.
|
||||
To submit a proposed change, please develop the code/fix and add new test cases.
|
||||
After that, run these local verifications before submitting pull request to predict the pass or
|
||||
fail of continuous integration.
|
||||
|
||||
* Format the code with `gofmt`
|
||||
* Run the test with data race enabled `go test -race ./…`
|
||||
|
||||
## Code Review
|
||||
|
||||
To make it easier for your PR to receive reviews, consider the reviewers will need you to:
|
||||
|
||||
* follow [good coding guidelines](https://github.com/golang/go/wiki/CodeReviewComments).
|
||||
* write [good commit messages](https://chris.beams.io/posts/git-commit/).
|
||||
* break large changes into a logical series of smaller patches which individually make easily understandable changes, and in aggregate solve a broader issue.
|
||||
|
||||
21
ROADMAP.md
Normal file
21
ROADMAP.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# go-zero Roadmap
|
||||
|
||||
This document defines a high level roadmap for go-zero development and upcoming releases.
|
||||
Community and contributor involvement is vital for successfully implementing all desired items for each release.
|
||||
We hope that the items listed below will inspire further engagement from the community to keep go-zero progressing and shipping exciting and valuable features.
|
||||
|
||||
## 2021 Q2
|
||||
- Support TLS in redis connections
|
||||
- Support service discovery through K8S watch api
|
||||
- Log full sql statements for easier sql problem solving
|
||||
|
||||
## 2021 Q3
|
||||
- Support `goctl mock` command to start a mocking server with given `.api` file
|
||||
- Adapt builtin tracing mechanism to opentracing solutions
|
||||
- Support `goctl model pg` to support PostgreSQL code generation
|
||||
|
||||
## 2021 Q4
|
||||
- Support `goctl doctor` command to report potential issues for given service
|
||||
- Support `context` in redis related methods for timeout and tracing
|
||||
- Support `context` in sql related methods for timeout and tracing
|
||||
- Support `context` in mongodb related methods for timeout and tracing
|
||||
76
code-of-conduct.md
Normal file
76
code-of-conduct.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to make participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||
level of experience, education, socio-economic status, nationality, personal
|
||||
appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all project spaces, and it also applies when
|
||||
an individual is representing the project or its community in public spaces.
|
||||
Examples of representing a project or community include using an official
|
||||
project e-mail address, posting via an official social media account, or acting
|
||||
as an appointed representative at an online or offline event. Representation of
|
||||
a project may be further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at [INSERT EMAIL ADDRESS]. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see
|
||||
https://www.contributor-covenant.org/faq
|
||||
@@ -94,7 +94,7 @@ func (b *googleBreaker) markFailure() {
|
||||
b.stat.Add(0)
|
||||
}
|
||||
|
||||
func (b *googleBreaker) history() (accepts int64, total int64) {
|
||||
func (b *googleBreaker) history() (accepts, total int64) {
|
||||
b.stat.Reduce(func(b *collection.Bucket) {
|
||||
accepts += int64(b.Sum)
|
||||
total += b.Count
|
||||
|
||||
@@ -151,7 +151,7 @@ func (tw *TimingWheel) drainAll(fn func(key, value interface{})) {
|
||||
}
|
||||
}
|
||||
|
||||
func (tw *TimingWheel) getPositionAndCircle(d time.Duration) (pos int, circle int) {
|
||||
func (tw *TimingWheel) getPositionAndCircle(d time.Duration) (pos, circle int) {
|
||||
steps := int(d / tw.interval)
|
||||
pos = (tw.tickedPos + steps) % tw.numSlots
|
||||
circle = (steps - 1) / tw.numSlots
|
||||
|
||||
@@ -5,7 +5,7 @@ package internal
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go.etcd.io/etcd/clientv3"
|
||||
clientv3 "go.etcd.io/etcd/client/v3"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
|
||||
@@ -6,10 +6,11 @@ package internal
|
||||
|
||||
import (
|
||||
context "context"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
clientv3 "go.etcd.io/etcd/clientv3"
|
||||
grpc "google.golang.org/grpc"
|
||||
reflect "reflect"
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
clientv3 "go.etcd.io/etcd/client/v3"
|
||||
grpc "google.golang.org/grpc"
|
||||
)
|
||||
|
||||
// MockEtcdClient is a mock of EtcdClient interface
|
||||
|
||||
@@ -2,5 +2,5 @@ package internal
|
||||
|
||||
// Listener interface wraps the OnUpdate method.
|
||||
type Listener interface {
|
||||
OnUpdate(keys []string, values []string, newKey string)
|
||||
OnUpdate(keys, values []string, newKey string)
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"github.com/tal-tech/go-zero/core/logx"
|
||||
"github.com/tal-tech/go-zero/core/syncx"
|
||||
"github.com/tal-tech/go-zero/core/threading"
|
||||
"go.etcd.io/etcd/clientv3"
|
||||
clientv3 "go.etcd.io/etcd/client/v3"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -260,26 +260,34 @@ func (c *cluster) reload(cli EtcdClient) {
|
||||
}
|
||||
|
||||
func (c *cluster) watch(cli EtcdClient, key string) {
|
||||
for {
|
||||
if c.watchStream(cli, key) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *cluster) watchStream(cli EtcdClient, key string) bool {
|
||||
rch := cli.Watch(clientv3.WithRequireLeader(c.context(cli)), makeKeyPrefix(key), clientv3.WithPrefix())
|
||||
for {
|
||||
select {
|
||||
case wresp, ok := <-rch:
|
||||
if !ok {
|
||||
logx.Error("etcd monitor chan has been closed")
|
||||
return
|
||||
return false
|
||||
}
|
||||
if wresp.Canceled {
|
||||
logx.Error("etcd monitor chan has been canceled")
|
||||
return
|
||||
logx.Errorf("etcd monitor chan has been canceled, error: %v", wresp.Err())
|
||||
return false
|
||||
}
|
||||
if wresp.Err() != nil {
|
||||
logx.Error(fmt.Sprintf("etcd monitor chan error: %v", wresp.Err()))
|
||||
return
|
||||
return false
|
||||
}
|
||||
|
||||
c.handleWatchEvents(key, wresp.Events)
|
||||
case <-c.done:
|
||||
return
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,10 +8,11 @@ import (
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/tal-tech/go-zero/core/contextx"
|
||||
"github.com/tal-tech/go-zero/core/lang"
|
||||
"github.com/tal-tech/go-zero/core/logx"
|
||||
"github.com/tal-tech/go-zero/core/stringx"
|
||||
"go.etcd.io/etcd/clientv3"
|
||||
"go.etcd.io/etcd/mvcc/mvccpb"
|
||||
"go.etcd.io/etcd/api/v3/mvccpb"
|
||||
clientv3 "go.etcd.io/etcd/client/v3"
|
||||
)
|
||||
|
||||
var mockLock sync.Mutex
|
||||
@@ -202,11 +203,13 @@ func TestClusterWatch_RespFailures(t *testing.T) {
|
||||
restore := setMockClient(cli)
|
||||
defer restore()
|
||||
ch := make(chan clientv3.WatchResponse)
|
||||
cli.EXPECT().Watch(gomock.Any(), "any/", gomock.Any()).Return(ch)
|
||||
cli.EXPECT().Watch(gomock.Any(), "any/", gomock.Any()).Return(ch).AnyTimes()
|
||||
cli.EXPECT().Ctx().Return(context.Background()).AnyTimes()
|
||||
c := new(cluster)
|
||||
c.done = make(chan lang.PlaceholderType)
|
||||
go func() {
|
||||
ch <- resp
|
||||
close(c.done)
|
||||
}()
|
||||
c.watch(cli, "any")
|
||||
})
|
||||
@@ -220,11 +223,13 @@ func TestClusterWatch_CloseChan(t *testing.T) {
|
||||
restore := setMockClient(cli)
|
||||
defer restore()
|
||||
ch := make(chan clientv3.WatchResponse)
|
||||
cli.EXPECT().Watch(gomock.Any(), "any/", gomock.Any()).Return(ch)
|
||||
cli.EXPECT().Watch(gomock.Any(), "any/", gomock.Any()).Return(ch).AnyTimes()
|
||||
cli.EXPECT().Ctx().Return(context.Background()).AnyTimes()
|
||||
c := new(cluster)
|
||||
c.done = make(chan lang.PlaceholderType)
|
||||
go func() {
|
||||
close(ch)
|
||||
close(c.done)
|
||||
}()
|
||||
c.watch(cli, "any")
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"github.com/tal-tech/go-zero/core/proc"
|
||||
"github.com/tal-tech/go-zero/core/syncx"
|
||||
"github.com/tal-tech/go-zero/core/threading"
|
||||
"go.etcd.io/etcd/clientv3"
|
||||
clientv3 "go.etcd.io/etcd/client/v3"
|
||||
)
|
||||
|
||||
type (
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"github.com/tal-tech/go-zero/core/discov/internal"
|
||||
"github.com/tal-tech/go-zero/core/lang"
|
||||
"github.com/tal-tech/go-zero/core/logx"
|
||||
"go.etcd.io/etcd/clientv3"
|
||||
clientv3 "go.etcd.io/etcd/client/v3"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -49,6 +49,11 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
// Concat returns a concatenated Stream.
|
||||
func Concat(s Stream, others ...Stream) Stream {
|
||||
return s.Concat(others...)
|
||||
}
|
||||
|
||||
// From constructs a Stream from the given GenerateFunc.
|
||||
func From(generate GenerateFunc) Stream {
|
||||
source := make(chan interface{})
|
||||
@@ -79,16 +84,42 @@ func Range(source <-chan interface{}) Stream {
|
||||
}
|
||||
}
|
||||
|
||||
// AllMach returns whether all elements of this stream match the provided predicate.
|
||||
// May not evaluate the predicate on all elements if not necessary for determining the result.
|
||||
// If the stream is empty then true is returned and the predicate is not evaluated.
|
||||
func (s Stream) AllMach(predicate func(item interface{}) bool) bool {
|
||||
for item := range s.source {
|
||||
if !predicate(item) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// AnyMach returns whether any elements of this stream match the provided predicate.
|
||||
// May not evaluate the predicate on all elements if not necessary for determining the result.
|
||||
// If the stream is empty then false is returned and the predicate is not evaluated.
|
||||
func (s Stream) AnyMach(predicate func(item interface{}) bool) bool {
|
||||
for item := range s.source {
|
||||
if predicate(item) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// Buffer buffers the items into a queue with size n.
|
||||
// It can balance the producer and the consumer if their processing throughput don't match.
|
||||
func (p Stream) Buffer(n int) Stream {
|
||||
func (s Stream) Buffer(n int) Stream {
|
||||
if n < 0 {
|
||||
n = 0
|
||||
}
|
||||
|
||||
source := make(chan interface{}, n)
|
||||
go func() {
|
||||
for item := range p.source {
|
||||
for item := range s.source {
|
||||
source <- item
|
||||
}
|
||||
close(source)
|
||||
@@ -97,23 +128,51 @@ func (p Stream) Buffer(n int) Stream {
|
||||
return Range(source)
|
||||
}
|
||||
|
||||
// Concat returns a Stream that concatenated other streams
|
||||
func (s Stream) Concat(others ...Stream) Stream {
|
||||
source := make(chan interface{})
|
||||
|
||||
go func() {
|
||||
group := threading.NewRoutineGroup()
|
||||
group.Run(func() {
|
||||
for item := range s.source {
|
||||
source <- item
|
||||
}
|
||||
})
|
||||
|
||||
for _, each := range others {
|
||||
each := each
|
||||
group.Run(func() {
|
||||
for item := range each.source {
|
||||
source <- item
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
group.Wait()
|
||||
close(source)
|
||||
}()
|
||||
|
||||
return Range(source)
|
||||
}
|
||||
|
||||
// Count counts the number of elements in the result.
|
||||
func (p Stream) Count() (count int) {
|
||||
for range p.source {
|
||||
func (s Stream) Count() (count int) {
|
||||
for range s.source {
|
||||
count++
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Distinct removes the duplicated items base on the given KeyFunc.
|
||||
func (p Stream) Distinct(fn KeyFunc) Stream {
|
||||
func (s Stream) Distinct(fn KeyFunc) Stream {
|
||||
source := make(chan interface{})
|
||||
|
||||
threading.GoSafe(func() {
|
||||
defer close(source)
|
||||
|
||||
keys := make(map[interface{}]lang.PlaceholderType)
|
||||
for item := range p.source {
|
||||
for item := range s.source {
|
||||
key := fn(item)
|
||||
if _, ok := keys[key]; !ok {
|
||||
source <- item
|
||||
@@ -126,14 +185,14 @@ func (p Stream) Distinct(fn KeyFunc) Stream {
|
||||
}
|
||||
|
||||
// Done waits all upstreaming operations to be done.
|
||||
func (p Stream) Done() {
|
||||
for range p.source {
|
||||
func (s Stream) Done() {
|
||||
for range s.source {
|
||||
}
|
||||
}
|
||||
|
||||
// Filter filters the items by the given FilterFunc.
|
||||
func (p Stream) Filter(fn FilterFunc, opts ...Option) Stream {
|
||||
return p.Walk(func(item interface{}, pipe chan<- interface{}) {
|
||||
func (s Stream) Filter(fn FilterFunc, opts ...Option) Stream {
|
||||
return s.Walk(func(item interface{}, pipe chan<- interface{}) {
|
||||
if fn(item) {
|
||||
pipe <- item
|
||||
}
|
||||
@@ -141,21 +200,21 @@ func (p Stream) Filter(fn FilterFunc, opts ...Option) Stream {
|
||||
}
|
||||
|
||||
// ForAll handles the streaming elements from the source and no later streams.
|
||||
func (p Stream) ForAll(fn ForAllFunc) {
|
||||
fn(p.source)
|
||||
func (s Stream) ForAll(fn ForAllFunc) {
|
||||
fn(s.source)
|
||||
}
|
||||
|
||||
// ForEach seals the Stream with the ForEachFunc on each item, no successive operations.
|
||||
func (p Stream) ForEach(fn ForEachFunc) {
|
||||
for item := range p.source {
|
||||
func (s Stream) ForEach(fn ForEachFunc) {
|
||||
for item := range s.source {
|
||||
fn(item)
|
||||
}
|
||||
}
|
||||
|
||||
// Group groups the elements into different groups based on their keys.
|
||||
func (p Stream) Group(fn KeyFunc) Stream {
|
||||
func (s Stream) Group(fn KeyFunc) Stream {
|
||||
groups := make(map[interface{}][]interface{})
|
||||
for item := range p.source {
|
||||
for item := range s.source {
|
||||
key := fn(item)
|
||||
groups[key] = append(groups[key], item)
|
||||
}
|
||||
@@ -172,7 +231,7 @@ func (p Stream) Group(fn KeyFunc) Stream {
|
||||
}
|
||||
|
||||
// Head returns the first n elements in p.
|
||||
func (p Stream) Head(n int64) Stream {
|
||||
func (s Stream) Head(n int64) Stream {
|
||||
if n < 1 {
|
||||
panic("n must be greater than 0")
|
||||
}
|
||||
@@ -180,7 +239,7 @@ func (p Stream) Head(n int64) Stream {
|
||||
source := make(chan interface{})
|
||||
|
||||
go func() {
|
||||
for item := range p.source {
|
||||
for item := range s.source {
|
||||
n--
|
||||
if n >= 0 {
|
||||
source <- item
|
||||
@@ -201,16 +260,16 @@ func (p Stream) Head(n int64) Stream {
|
||||
}
|
||||
|
||||
// Map converts each item to another corresponding item, which means it's a 1:1 model.
|
||||
func (p Stream) Map(fn MapFunc, opts ...Option) Stream {
|
||||
return p.Walk(func(item interface{}, pipe chan<- interface{}) {
|
||||
func (s Stream) Map(fn MapFunc, opts ...Option) Stream {
|
||||
return s.Walk(func(item interface{}, pipe chan<- interface{}) {
|
||||
pipe <- fn(item)
|
||||
}, opts...)
|
||||
}
|
||||
|
||||
// Merge merges all the items into a slice and generates a new stream.
|
||||
func (p Stream) Merge() Stream {
|
||||
func (s Stream) Merge() Stream {
|
||||
var items []interface{}
|
||||
for item := range p.source {
|
||||
for item := range s.source {
|
||||
items = append(items, item)
|
||||
}
|
||||
|
||||
@@ -222,21 +281,21 @@ func (p Stream) Merge() Stream {
|
||||
}
|
||||
|
||||
// Parallel applies the given ParallelFunc to each item concurrently with given number of workers.
|
||||
func (p Stream) Parallel(fn ParallelFunc, opts ...Option) {
|
||||
p.Walk(func(item interface{}, pipe chan<- interface{}) {
|
||||
func (s Stream) Parallel(fn ParallelFunc, opts ...Option) {
|
||||
s.Walk(func(item interface{}, pipe chan<- interface{}) {
|
||||
fn(item)
|
||||
}, opts...).Done()
|
||||
}
|
||||
|
||||
// Reduce is a utility method to let the caller deal with the underlying channel.
|
||||
func (p Stream) Reduce(fn ReduceFunc) (interface{}, error) {
|
||||
return fn(p.source)
|
||||
func (s Stream) Reduce(fn ReduceFunc) (interface{}, error) {
|
||||
return fn(s.source)
|
||||
}
|
||||
|
||||
// Reverse reverses the elements in the stream.
|
||||
func (p Stream) Reverse() Stream {
|
||||
func (s Stream) Reverse() Stream {
|
||||
var items []interface{}
|
||||
for item := range p.source {
|
||||
for item := range s.source {
|
||||
items = append(items, item)
|
||||
}
|
||||
// reverse, official method
|
||||
@@ -248,10 +307,36 @@ func (p Stream) Reverse() Stream {
|
||||
return Just(items...)
|
||||
}
|
||||
|
||||
// Skip returns a Stream that skips size elements.
|
||||
func (s Stream) Skip(n int64) Stream {
|
||||
if n < 0 {
|
||||
panic("n must not be negative")
|
||||
}
|
||||
if n == 0 {
|
||||
return s
|
||||
}
|
||||
|
||||
source := make(chan interface{})
|
||||
|
||||
go func() {
|
||||
for item := range s.source {
|
||||
n--
|
||||
if n >= 0 {
|
||||
continue
|
||||
} else {
|
||||
source <- item
|
||||
}
|
||||
}
|
||||
close(source)
|
||||
}()
|
||||
|
||||
return Range(source)
|
||||
}
|
||||
|
||||
// Sort sorts the items from the underlying source.
|
||||
func (p Stream) Sort(less LessFunc) Stream {
|
||||
func (s Stream) Sort(less LessFunc) Stream {
|
||||
var items []interface{}
|
||||
for item := range p.source {
|
||||
for item := range s.source {
|
||||
items = append(items, item)
|
||||
}
|
||||
sort.Slice(items, func(i, j int) bool {
|
||||
@@ -263,7 +348,7 @@ func (p Stream) Sort(less LessFunc) Stream {
|
||||
|
||||
// Split splits the elements into chunk with size up to n,
|
||||
// might be less than n on tailing elements.
|
||||
func (p Stream) Split(n int) Stream {
|
||||
func (s Stream) Split(n int) Stream {
|
||||
if n < 1 {
|
||||
panic("n should be greater than 0")
|
||||
}
|
||||
@@ -271,7 +356,7 @@ func (p Stream) Split(n int) Stream {
|
||||
source := make(chan interface{})
|
||||
go func() {
|
||||
var chunk []interface{}
|
||||
for item := range p.source {
|
||||
for item := range s.source {
|
||||
chunk = append(chunk, item)
|
||||
if len(chunk) == n {
|
||||
source <- chunk
|
||||
@@ -288,7 +373,7 @@ func (p Stream) Split(n int) Stream {
|
||||
}
|
||||
|
||||
// Tail returns the last n elements in p.
|
||||
func (p Stream) Tail(n int64) Stream {
|
||||
func (s Stream) Tail(n int64) Stream {
|
||||
if n < 1 {
|
||||
panic("n should be greater than 0")
|
||||
}
|
||||
@@ -297,7 +382,7 @@ func (p Stream) Tail(n int64) Stream {
|
||||
|
||||
go func() {
|
||||
ring := collection.NewRing(int(n))
|
||||
for item := range p.source {
|
||||
for item := range s.source {
|
||||
ring.Add(item)
|
||||
}
|
||||
for _, item := range ring.Take() {
|
||||
@@ -310,16 +395,16 @@ func (p Stream) Tail(n int64) Stream {
|
||||
}
|
||||
|
||||
// Walk lets the callers handle each item, the caller may write zero, one or more items base on the given item.
|
||||
func (p Stream) Walk(fn WalkFunc, opts ...Option) Stream {
|
||||
func (s Stream) Walk(fn WalkFunc, opts ...Option) Stream {
|
||||
option := buildOptions(opts...)
|
||||
if option.unlimitedWorkers {
|
||||
return p.walkUnlimited(fn, option)
|
||||
return s.walkUnlimited(fn, option)
|
||||
}
|
||||
|
||||
return p.walkLimited(fn, option)
|
||||
return s.walkLimited(fn, option)
|
||||
}
|
||||
|
||||
func (p Stream) walkLimited(fn WalkFunc, option *rxOptions) Stream {
|
||||
func (s Stream) walkLimited(fn WalkFunc, option *rxOptions) Stream {
|
||||
pipe := make(chan interface{}, option.workers)
|
||||
|
||||
go func() {
|
||||
@@ -328,7 +413,7 @@ func (p Stream) walkLimited(fn WalkFunc, option *rxOptions) Stream {
|
||||
|
||||
for {
|
||||
pool <- lang.Placeholder
|
||||
item, ok := <-p.source
|
||||
item, ok := <-s.source
|
||||
if !ok {
|
||||
<-pool
|
||||
break
|
||||
@@ -353,14 +438,14 @@ func (p Stream) walkLimited(fn WalkFunc, option *rxOptions) Stream {
|
||||
return Range(pipe)
|
||||
}
|
||||
|
||||
func (p Stream) walkUnlimited(fn WalkFunc, option *rxOptions) Stream {
|
||||
func (s Stream) walkUnlimited(fn WalkFunc, option *rxOptions) Stream {
|
||||
pipe := make(chan interface{}, defaultWorkers)
|
||||
|
||||
go func() {
|
||||
var wg sync.WaitGroup
|
||||
|
||||
for {
|
||||
item, ok := <-p.source
|
||||
item, ok := <-s.source
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
|
||||
@@ -3,7 +3,10 @@ package fx
|
||||
import (
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math/rand"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"sort"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
@@ -330,6 +333,29 @@ func TestWalk(t *testing.T) {
|
||||
assert.Equal(t, 9, result)
|
||||
}
|
||||
|
||||
func BenchmarkParallelMapReduce(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
|
||||
mapper := func(v interface{}) interface{} {
|
||||
return v.(int64) * v.(int64)
|
||||
}
|
||||
reducer := func(input <-chan interface{}) (interface{}, error) {
|
||||
var result int64
|
||||
for v := range input {
|
||||
result += v.(int64)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
b.ResetTimer()
|
||||
From(func(input chan<- interface{}) {
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
input <- int64(rand.Int())
|
||||
}
|
||||
})
|
||||
}).Map(mapper).Reduce(reducer)
|
||||
}
|
||||
|
||||
func BenchmarkMapReduce(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
|
||||
@@ -343,12 +369,103 @@ func BenchmarkMapReduce(b *testing.B) {
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
b.ResetTimer()
|
||||
From(func(input chan<- interface{}) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
input <- int64(rand.Int())
|
||||
}
|
||||
}).Map(mapper).Reduce(reducer)
|
||||
}
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
From(func(input chan<- interface{}) {
|
||||
for j := 0; j < 2; j++ {
|
||||
input <- int64(j)
|
||||
}
|
||||
}).Map(mapper).Reduce(reducer)
|
||||
func equal(t *testing.T, stream Stream, data []interface{}) {
|
||||
items := make([]interface{}, 0)
|
||||
for item := range stream.source {
|
||||
items = append(items, item)
|
||||
}
|
||||
if !reflect.DeepEqual(items, data) {
|
||||
t.Errorf(" %v, want %v", items, data)
|
||||
}
|
||||
}
|
||||
|
||||
func assetEqual(t *testing.T, except, data interface{}) {
|
||||
if !reflect.DeepEqual(except, data) {
|
||||
t.Errorf(" %v, want %v", data, except)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStream_AnyMach(t *testing.T) {
|
||||
assetEqual(t, false, Just(1, 2, 3).AnyMach(func(item interface{}) bool {
|
||||
return 4 == item.(int)
|
||||
}))
|
||||
assetEqual(t, false, Just(1, 2, 3).AnyMach(func(item interface{}) bool {
|
||||
return 0 == item.(int)
|
||||
}))
|
||||
assetEqual(t, true, Just(1, 2, 3).AnyMach(func(item interface{}) bool {
|
||||
return 2 == item.(int)
|
||||
}))
|
||||
assetEqual(t, true, Just(1, 2, 3).AnyMach(func(item interface{}) bool {
|
||||
return 2 == item.(int)
|
||||
}))
|
||||
}
|
||||
|
||||
func TestStream_AllMach(t *testing.T) {
|
||||
assetEqual(
|
||||
t, true, Just(1, 2, 3).AllMach(func(item interface{}) bool {
|
||||
return true
|
||||
}),
|
||||
)
|
||||
assetEqual(
|
||||
t, false, Just(1, 2, 3).AllMach(func(item interface{}) bool {
|
||||
return false
|
||||
}),
|
||||
)
|
||||
assetEqual(
|
||||
t, false, Just(1, 2, 3).AllMach(func(item interface{}) bool {
|
||||
return item.(int) == 1
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
func TestConcat(t *testing.T) {
|
||||
a1 := []interface{}{1, 2, 3}
|
||||
a2 := []interface{}{4, 5, 6}
|
||||
s1 := Just(a1...)
|
||||
s2 := Just(a2...)
|
||||
stream := Concat(s1, s2)
|
||||
var items []interface{}
|
||||
for item := range stream.source {
|
||||
items = append(items, item)
|
||||
}
|
||||
sort.Slice(items, func(i, j int) bool {
|
||||
return items[i].(int) < items[j].(int)
|
||||
})
|
||||
ints := make([]interface{}, 0)
|
||||
ints = append(ints, a1...)
|
||||
ints = append(ints, a2...)
|
||||
assetEqual(t, ints, items)
|
||||
}
|
||||
|
||||
func TestStream_Skip(t *testing.T) {
|
||||
assetEqual(t, 3, Just(1, 2, 3, 4).Skip(1).Count())
|
||||
assetEqual(t, 1, Just(1, 2, 3, 4).Skip(3).Count())
|
||||
assetEqual(t, 4, Just(1, 2, 3, 4).Skip(0).Count())
|
||||
equal(t, Just(1, 2, 3, 4).Skip(3), []interface{}{4})
|
||||
assert.Panics(t, func() {
|
||||
Just(1, 2, 3, 4).Skip(-1)
|
||||
})
|
||||
}
|
||||
|
||||
func TestStream_Concat(t *testing.T) {
|
||||
stream := Just(1).Concat(Just(2), Just(3))
|
||||
var items []interface{}
|
||||
for item := range stream.source {
|
||||
items = append(items, item)
|
||||
}
|
||||
sort.Slice(items, func(i, j int) bool {
|
||||
return items[i].(int) < items[j].(int)
|
||||
})
|
||||
assetEqual(t, []interface{}{1, 2, 3}, items)
|
||||
|
||||
just := Just(1)
|
||||
equal(t, just.Concat(just), []interface{}{1})
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ func (h *ConsistentHash) AddWithReplicas(node interface{}, replicas int) {
|
||||
h.ring[hash] = append(h.ring[hash], node)
|
||||
}
|
||||
|
||||
sort.Slice(h.keys, func(i int, j int) bool {
|
||||
sort.Slice(h.keys, func(i, j int) bool {
|
||||
return h.keys[i] < h.keys[j]
|
||||
})
|
||||
}
|
||||
|
||||
@@ -112,5 +112,5 @@ func (t mockTrace) Follow(ctx context.Context, serviceName, operationName string
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (t mockTrace) Visit(fn func(key string, val string) bool) {
|
||||
func (t mockTrace) Visit(fn func(key, val string) bool) {
|
||||
}
|
||||
|
||||
@@ -457,6 +457,10 @@ func (u *Unmarshaler) fillSlice(fieldType reflect.Type, value reflect.Value, map
|
||||
} else {
|
||||
conv.Index(i).Set(target.Elem())
|
||||
}
|
||||
case reflect.Slice:
|
||||
if err := u.fillSlice(dereffedBaseType, conv.Index(i), ithValue); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
if err := u.fillSliceValue(conv, i, dereffedBaseKind, ithValue); err != nil {
|
||||
return err
|
||||
@@ -492,18 +496,31 @@ func (u *Unmarshaler) fillSliceFromString(fieldType reflect.Type, value reflect.
|
||||
}
|
||||
|
||||
func (u *Unmarshaler) fillSliceValue(slice reflect.Value, index int, baseKind reflect.Kind, value interface{}) error {
|
||||
ithVal := slice.Index(index)
|
||||
switch v := value.(type) {
|
||||
case json.Number:
|
||||
return setValue(baseKind, slice.Index(index), v.String())
|
||||
return setValue(baseKind, ithVal, v.String())
|
||||
default:
|
||||
// don't need to consider the difference between int, int8, int16, int32, int64,
|
||||
// uint, uint8, uint16, uint32, uint64, because they're handled as json.Number.
|
||||
if slice.Index(index).Kind() != reflect.TypeOf(value).Kind() {
|
||||
return errTypeMismatch
|
||||
}
|
||||
if ithVal.Kind() == reflect.Ptr {
|
||||
baseType := Deref(ithVal.Type())
|
||||
if baseType.Kind() != reflect.TypeOf(value).Kind() {
|
||||
return errTypeMismatch
|
||||
}
|
||||
|
||||
slice.Index(index).Set(reflect.ValueOf(value))
|
||||
return nil
|
||||
target := reflect.New(baseType).Elem()
|
||||
target.Set(reflect.ValueOf(value))
|
||||
ithVal.Set(target.Addr())
|
||||
return nil
|
||||
} else {
|
||||
if ithVal.Kind() != reflect.TypeOf(value).Kind() {
|
||||
return errTypeMismatch
|
||||
}
|
||||
|
||||
ithVal.Set(reflect.ValueOf(value))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package mapping
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -2480,3 +2481,40 @@ func BenchmarkUnmarshal(b *testing.B) {
|
||||
UnmarshalKey(data, &an)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnmarshalJsonReaderMultiArray(t *testing.T) {
|
||||
payload := `{"a": "133", "b": [["add", "cccd"], ["eeee"]]}`
|
||||
var res struct {
|
||||
A string `json:"a"`
|
||||
B [][]string `json:"b"`
|
||||
}
|
||||
reader := strings.NewReader(payload)
|
||||
err := UnmarshalJsonReader(reader, &res)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, len(res.B))
|
||||
}
|
||||
|
||||
func TestUnmarshalJsonReaderPtrMultiArray(t *testing.T) {
|
||||
payload := `{"a": "133", "b": [["add", "cccd"], ["eeee"]]}`
|
||||
var res struct {
|
||||
A string `json:"a"`
|
||||
B [][]*string `json:"b"`
|
||||
}
|
||||
reader := strings.NewReader(payload)
|
||||
err := UnmarshalJsonReader(reader, &res)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, len(res.B))
|
||||
assert.Equal(t, 2, len(res.B[0]))
|
||||
}
|
||||
|
||||
func TestUnmarshalJsonReaderPtrArray(t *testing.T) {
|
||||
payload := `{"a": "133", "b": ["add", "cccd", "eeee"]}`
|
||||
var res struct {
|
||||
A string `json:"a"`
|
||||
B []*string `json:"b"`
|
||||
}
|
||||
reader := strings.NewReader(payload)
|
||||
err := UnmarshalJsonReader(reader, &res)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 3, len(res.B))
|
||||
}
|
||||
|
||||
@@ -286,7 +286,7 @@ func parseNumberRange(str string) (*numberRange, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func parseOption(fieldOpts *fieldOptions, fieldName string, option string) error {
|
||||
func parseOption(fieldOpts *fieldOptions, fieldName, option string) error {
|
||||
switch {
|
||||
case option == stringOption:
|
||||
fieldOpts.FromString = true
|
||||
|
||||
@@ -136,14 +136,16 @@ func MapReduceWithSource(source <-chan interface{}, mapper MapperFunc, reducer R
|
||||
|
||||
go func() {
|
||||
defer func() {
|
||||
drain(collector)
|
||||
|
||||
if r := recover(); r != nil {
|
||||
cancel(fmt.Errorf("%v", r))
|
||||
} else {
|
||||
finish()
|
||||
}
|
||||
}()
|
||||
|
||||
reducer(collector, writer, cancel)
|
||||
drain(collector)
|
||||
}()
|
||||
|
||||
go executeMappers(func(item interface{}, w Writer) {
|
||||
@@ -165,7 +167,6 @@ func MapReduceWithSource(source <-chan interface{}, mapper MapperFunc, reducer R
|
||||
func MapReduceVoid(generate GenerateFunc, mapper MapperFunc, reducer VoidReducerFunc, opts ...Option) error {
|
||||
_, err := MapReduce(generate, mapper, func(input <-chan interface{}, writer Writer, cancel func(error)) {
|
||||
reducer(input, cancel)
|
||||
drain(input)
|
||||
// We need to write a placeholder to let MapReduce to continue on reducer done,
|
||||
// otherwise, all goroutines are waiting. The placeholder will be discarded by MapReduce.
|
||||
writer.Write(lang.Placeholder)
|
||||
|
||||
@@ -71,7 +71,7 @@ func NewQueue(producerFactory ProducerFactory, consumerFactory ConsumerFactory)
|
||||
return q
|
||||
}
|
||||
|
||||
// AddListener adds a litener to q.
|
||||
// AddListener adds a listener to q.
|
||||
func (q *Queue) AddListener(listener Listener) {
|
||||
q.listeners = append(q.listeners, listener)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package search
|
||||
|
||||
import "errors"
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
const (
|
||||
colon = ':'
|
||||
@@ -8,16 +11,16 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrDupItem means adding duplicated item.
|
||||
ErrDupItem = errors.New("duplicated item")
|
||||
// ErrDupSlash means item is started with more than one slash.
|
||||
ErrDupSlash = errors.New("duplicated slash")
|
||||
// ErrEmptyItem means adding empty item.
|
||||
ErrEmptyItem = errors.New("empty item")
|
||||
// ErrInvalidState means search tree is in an invalid state.
|
||||
ErrInvalidState = errors.New("search tree is in an invalid state")
|
||||
// ErrNotFromRoot means path is not starting with slash.
|
||||
ErrNotFromRoot = errors.New("path should start with /")
|
||||
// errDupItem means adding duplicated item.
|
||||
errDupItem = errors.New("duplicated item")
|
||||
// errDupSlash means item is started with more than one slash.
|
||||
errDupSlash = errors.New("duplicated slash")
|
||||
// errEmptyItem means adding empty item.
|
||||
errEmptyItem = errors.New("empty item")
|
||||
// errInvalidState means search tree is in an invalid state.
|
||||
errInvalidState = errors.New("search tree is in an invalid state")
|
||||
// errNotFromRoot means path is not starting with slash.
|
||||
errNotFromRoot = errors.New("path should start with /")
|
||||
|
||||
// NotFound is used to hold the not found result.
|
||||
NotFound Result
|
||||
@@ -58,14 +61,22 @@ func NewTree() *Tree {
|
||||
// Add adds item to associate with route.
|
||||
func (t *Tree) Add(route string, item interface{}) error {
|
||||
if len(route) == 0 || route[0] != slash {
|
||||
return ErrNotFromRoot
|
||||
return errNotFromRoot
|
||||
}
|
||||
|
||||
if item == nil {
|
||||
return ErrEmptyItem
|
||||
return errEmptyItem
|
||||
}
|
||||
|
||||
return add(t.root, route[1:], item)
|
||||
err := add(t.root, route[1:], item)
|
||||
switch err {
|
||||
case errDupItem:
|
||||
return duplicatedItem(route)
|
||||
case errDupSlash:
|
||||
return duplicatedSlash(route)
|
||||
default:
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Search searches item that associates with given route.
|
||||
@@ -86,22 +97,22 @@ func (t *Tree) next(n *node, route string, result *Result) bool {
|
||||
}
|
||||
|
||||
for i := range route {
|
||||
if route[i] == slash {
|
||||
token := route[:i]
|
||||
return n.forEach(func(k string, v *node) bool {
|
||||
if r := match(k, token); r.found {
|
||||
if t.next(v, route[i+1:], result) {
|
||||
if r.named {
|
||||
addParam(result, r.key, r.value)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
})
|
||||
if route[i] != slash {
|
||||
continue
|
||||
}
|
||||
|
||||
token := route[:i]
|
||||
return n.forEach(func(k string, v *node) bool {
|
||||
r := match(k, token)
|
||||
if !r.found || !t.next(v, route[i+1:], result) {
|
||||
return false
|
||||
}
|
||||
if r.named {
|
||||
addParam(result, r.key, r.value)
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
return n.forEach(func(k string, v *node) bool {
|
||||
@@ -141,7 +152,7 @@ func (nd *node) getChildren(route string) map[string]*node {
|
||||
func add(nd *node, route string, item interface{}) error {
|
||||
if len(route) == 0 {
|
||||
if nd.item != nil {
|
||||
return ErrDupItem
|
||||
return errDupItem
|
||||
}
|
||||
|
||||
nd.item = item
|
||||
@@ -149,31 +160,33 @@ func add(nd *node, route string, item interface{}) error {
|
||||
}
|
||||
|
||||
if route[0] == slash {
|
||||
return ErrDupSlash
|
||||
return errDupSlash
|
||||
}
|
||||
|
||||
for i := range route {
|
||||
if route[i] == slash {
|
||||
token := route[:i]
|
||||
children := nd.getChildren(token)
|
||||
if child, ok := children[token]; ok {
|
||||
if child != nil {
|
||||
return add(child, route[i+1:], item)
|
||||
}
|
||||
if route[i] != slash {
|
||||
continue
|
||||
}
|
||||
|
||||
return ErrInvalidState
|
||||
token := route[:i]
|
||||
children := nd.getChildren(token)
|
||||
if child, ok := children[token]; ok {
|
||||
if child != nil {
|
||||
return add(child, route[i+1:], item)
|
||||
}
|
||||
|
||||
child := newNode(nil)
|
||||
children[token] = child
|
||||
return add(child, route[i+1:], item)
|
||||
return errInvalidState
|
||||
}
|
||||
|
||||
child := newNode(nil)
|
||||
children[token] = child
|
||||
return add(child, route[i+1:], item)
|
||||
}
|
||||
|
||||
children := nd.getChildren(route)
|
||||
if child, ok := children[route]; ok {
|
||||
if child.item != nil {
|
||||
return ErrDupItem
|
||||
return errDupItem
|
||||
}
|
||||
|
||||
child.item = item
|
||||
@@ -192,6 +205,14 @@ func addParam(result *Result, k, v string) {
|
||||
result.Params[k] = v
|
||||
}
|
||||
|
||||
func duplicatedItem(item string) error {
|
||||
return fmt.Errorf("duplicated item for %s", item)
|
||||
}
|
||||
|
||||
func duplicatedSlash(item string) error {
|
||||
return fmt.Errorf("duplicated slash for %s", item)
|
||||
}
|
||||
|
||||
func match(pat, token string) innerResult {
|
||||
if pat[0] == colon {
|
||||
return innerResult{
|
||||
|
||||
@@ -151,9 +151,9 @@ func TestAddDuplicate(t *testing.T) {
|
||||
err := tree.Add("/a/b", 1)
|
||||
assert.Nil(t, err)
|
||||
err = tree.Add("/a/b", 2)
|
||||
assert.Equal(t, ErrDupItem, err)
|
||||
assert.Error(t, errDupItem, err)
|
||||
err = tree.Add("/a/b/", 2)
|
||||
assert.Equal(t, ErrDupItem, err)
|
||||
assert.Error(t, errDupItem, err)
|
||||
}
|
||||
|
||||
func TestPlain(t *testing.T) {
|
||||
@@ -169,19 +169,19 @@ func TestPlain(t *testing.T) {
|
||||
func TestSearchWithDoubleSlashes(t *testing.T) {
|
||||
tree := NewTree()
|
||||
err := tree.Add("//a", 1)
|
||||
assert.Error(t, ErrDupSlash, err)
|
||||
assert.Error(t, errDupSlash, err)
|
||||
}
|
||||
|
||||
func TestSearchInvalidRoute(t *testing.T) {
|
||||
tree := NewTree()
|
||||
err := tree.Add("", 1)
|
||||
assert.Equal(t, ErrNotFromRoot, err)
|
||||
assert.Equal(t, errNotFromRoot, err)
|
||||
err = tree.Add("bad", 1)
|
||||
assert.Equal(t, ErrNotFromRoot, err)
|
||||
assert.Equal(t, errNotFromRoot, err)
|
||||
}
|
||||
|
||||
func TestSearchInvalidItem(t *testing.T) {
|
||||
tree := NewTree()
|
||||
err := tree.Add("/", nil)
|
||||
assert.Equal(t, ErrEmptyItem, err)
|
||||
assert.Equal(t, errEmptyItem, err)
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ var (
|
||||
cores uint64
|
||||
)
|
||||
|
||||
// if /proc not present, ignore the cpu calcuation, like wsl linux
|
||||
// if /proc not present, ignore the cpu calculation, like wsl linux
|
||||
func init() {
|
||||
cpus, err := perCpuUsage()
|
||||
if err != nil {
|
||||
|
||||
2
core/stores/cache/cachenode.go
vendored
2
core/stores/cache/cachenode.go
vendored
@@ -205,7 +205,7 @@ func (c cacheNode) doTake(v interface{}, key string, query func(v interface{}) e
|
||||
return jsonx.Unmarshal(val.([]byte), v)
|
||||
}
|
||||
|
||||
func (c cacheNode) processCache(key string, data string, v interface{}) error {
|
||||
func (c cacheNode) processCache(key, data string, v interface{}) error {
|
||||
err := jsonx.Unmarshal([]byte(data), v)
|
||||
if err == nil {
|
||||
return nil
|
||||
|
||||
@@ -17,7 +17,7 @@ type (
|
||||
// Store interface represents a KV store.
|
||||
Store interface {
|
||||
Del(keys ...string) (int, error)
|
||||
Eval(script string, key string, args ...interface{}) (interface{}, error)
|
||||
Eval(script, key string, args ...interface{}) (interface{}, error)
|
||||
Exists(key string) (bool, error)
|
||||
Expire(key string, seconds int) error
|
||||
Expireat(key string, expireTime int64) error
|
||||
@@ -39,7 +39,7 @@ type (
|
||||
Llen(key string) (int, error)
|
||||
Lpop(key string) (string, error)
|
||||
Lpush(key string, values ...interface{}) (int, error)
|
||||
Lrange(key string, start int, stop int) ([]string, error)
|
||||
Lrange(key string, start, stop int) ([]string, error)
|
||||
Lrem(key string, count int, value string) (int, error)
|
||||
Persist(key string) (bool, error)
|
||||
Pfadd(key string, values ...interface{}) (bool, error)
|
||||
@@ -47,7 +47,7 @@ type (
|
||||
Rpush(key string, values ...interface{}) (int, error)
|
||||
Sadd(key string, values ...interface{}) (int, error)
|
||||
Scard(key string) (int64, error)
|
||||
Set(key string, value string) error
|
||||
Set(key, value string) error
|
||||
Setex(key, value string, seconds int) error
|
||||
Setnx(key, value string) (bool, error)
|
||||
SetnxEx(key, value string, seconds int) (bool, error)
|
||||
@@ -74,7 +74,7 @@ type (
|
||||
Zrevrange(key string, start, stop int64) ([]string, error)
|
||||
ZrevrangebyscoreWithScores(key string, start, stop int64) ([]redis.Pair, error)
|
||||
ZrevrangebyscoreWithScoresAndLimit(key string, start, stop int64, page, size int) ([]redis.Pair, error)
|
||||
Zscore(key string, value string) (int64, error)
|
||||
Zscore(key, value string) (int64, error)
|
||||
Zrevrank(key, field string) (int64, error)
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ func (cs clusterStore) Del(keys ...string) (int, error) {
|
||||
return val, be.Err()
|
||||
}
|
||||
|
||||
func (cs clusterStore) Eval(script string, key string, args ...interface{}) (interface{}, error) {
|
||||
func (cs clusterStore) Eval(script, key string, args ...interface{}) (interface{}, error) {
|
||||
node, err := cs.getRedis(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -321,7 +321,7 @@ func (cs clusterStore) Lpush(key string, values ...interface{}) (int, error) {
|
||||
return node.Lpush(key, values...)
|
||||
}
|
||||
|
||||
func (cs clusterStore) Lrange(key string, start int, stop int) ([]string, error) {
|
||||
func (cs clusterStore) Lrange(key string, start, stop int) ([]string, error) {
|
||||
node, err := cs.getRedis(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -393,7 +393,7 @@ func (cs clusterStore) Scard(key string) (int64, error) {
|
||||
return node.Scard(key)
|
||||
}
|
||||
|
||||
func (cs clusterStore) Set(key string, value string) error {
|
||||
func (cs clusterStore) Set(key, value string) error {
|
||||
node, err := cs.getRedis(key)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -648,7 +648,7 @@ func (cs clusterStore) Zrevrank(key, field string) (int64, error) {
|
||||
return node.Zrevrank(key, field)
|
||||
}
|
||||
|
||||
func (cs clusterStore) Zscore(key string, value string) (int64, error) {
|
||||
func (cs clusterStore) Zscore(key, value string) (int64, error) {
|
||||
node, err := cs.getRedis(key)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
|
||||
@@ -24,11 +24,11 @@ type (
|
||||
CachedCollection interface {
|
||||
Count(query interface{}) (int, error)
|
||||
DelCache(keys ...string) error
|
||||
FindAllNoCache(v interface{}, query interface{}, opts ...QueryOption) error
|
||||
FindAllNoCache(v, query interface{}, opts ...QueryOption) error
|
||||
FindOne(v interface{}, key string, query interface{}) error
|
||||
FindOneNoCache(v interface{}, query interface{}) error
|
||||
FindOneNoCache(v, query interface{}) error
|
||||
FindOneId(v interface{}, key string, id interface{}) error
|
||||
FindOneIdNoCache(v interface{}, id interface{}) error
|
||||
FindOneIdNoCache(v, id interface{}) error
|
||||
GetCache(key string, v interface{}) error
|
||||
Insert(docs ...interface{}) error
|
||||
Pipe(pipeline interface{}) mongo.Pipe
|
||||
@@ -68,7 +68,7 @@ func (c *cachedCollection) DelCache(keys ...string) error {
|
||||
return c.cache.Del(keys...)
|
||||
}
|
||||
|
||||
func (c *cachedCollection) FindAllNoCache(v interface{}, query interface{}, opts ...QueryOption) error {
|
||||
func (c *cachedCollection) FindAllNoCache(v, query interface{}, opts ...QueryOption) error {
|
||||
q := c.collection.Find(query)
|
||||
for _, opt := range opts {
|
||||
q = opt(q)
|
||||
@@ -83,7 +83,7 @@ func (c *cachedCollection) FindOne(v interface{}, key string, query interface{})
|
||||
})
|
||||
}
|
||||
|
||||
func (c *cachedCollection) FindOneNoCache(v interface{}, query interface{}) error {
|
||||
func (c *cachedCollection) FindOneNoCache(v, query interface{}) error {
|
||||
q := c.collection.Find(query)
|
||||
return q.One(v)
|
||||
}
|
||||
@@ -95,7 +95,7 @@ func (c *cachedCollection) FindOneId(v interface{}, key string, id interface{})
|
||||
})
|
||||
}
|
||||
|
||||
func (c *cachedCollection) FindOneIdNoCache(v interface{}, id interface{}) error {
|
||||
func (c *cachedCollection) FindOneIdNoCache(v, id interface{}) error {
|
||||
q := c.collection.FindId(id)
|
||||
return q.One(v)
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ func (mm *Model) GetCollection(session *mgo.Session) CachedCollection {
|
||||
}
|
||||
|
||||
// FindAllNoCache finds all records without cache.
|
||||
func (mm *Model) FindAllNoCache(v interface{}, query interface{}, opts ...QueryOption) error {
|
||||
func (mm *Model) FindAllNoCache(v, query interface{}, opts ...QueryOption) error {
|
||||
return mm.execute(func(c CachedCollection) error {
|
||||
return c.FindAllNoCache(v, query, opts...)
|
||||
})
|
||||
@@ -89,7 +89,7 @@ func (mm *Model) FindOne(v interface{}, key string, query interface{}) error {
|
||||
}
|
||||
|
||||
// FindOneNoCache unmarshals a record into v with query, without cache.
|
||||
func (mm *Model) FindOneNoCache(v interface{}, query interface{}) error {
|
||||
func (mm *Model) FindOneNoCache(v, query interface{}) error {
|
||||
return mm.execute(func(c CachedCollection) error {
|
||||
return c.FindOneNoCache(v, query)
|
||||
})
|
||||
@@ -103,7 +103,7 @@ func (mm *Model) FindOneId(v interface{}, key string, id interface{}) error {
|
||||
}
|
||||
|
||||
// FindOneIdNoCache unmarshals a record into v with query, without cache.
|
||||
func (mm *Model) FindOneIdNoCache(v interface{}, id interface{}) error {
|
||||
func (mm *Model) FindOneIdNoCache(v, id interface{}) error {
|
||||
return mm.execute(func(c CachedCollection) error {
|
||||
return c.FindOneIdNoCache(v, id)
|
||||
})
|
||||
|
||||
@@ -180,7 +180,7 @@ func (s *Redis) BitOpXor(destKey string, keys ...string) (val int64, err error)
|
||||
}
|
||||
|
||||
// BitPos is redis bitpos command implementation.
|
||||
func (s *Redis) BitPos(key string, bit int64, start, end int64) (val int64, err error) {
|
||||
func (s *Redis) BitPos(key string, bit, start, end int64) (val int64, err error) {
|
||||
err = s.brk.DoWithAcceptable(func() error {
|
||||
conn, err := getRedis(s)
|
||||
if err != nil {
|
||||
@@ -346,7 +346,7 @@ func (s *Redis) GeoAdd(key string, geoLocation ...*GeoLocation) (val int64, err
|
||||
}
|
||||
|
||||
// GeoDist is the implementation of redis geodist command.
|
||||
func (s *Redis) GeoDist(key string, member1, member2, unit string) (val float64, err error) {
|
||||
func (s *Redis) GeoDist(key, member1, member2, unit string) (val float64, err error) {
|
||||
err = s.brk.DoWithAcceptable(func() error {
|
||||
conn, err := getRedis(s)
|
||||
if err != nil {
|
||||
@@ -795,7 +795,7 @@ func (s *Redis) Lpush(key string, values ...interface{}) (val int, err error) {
|
||||
}
|
||||
|
||||
// Lrange is the implementation of redis lrange command.
|
||||
func (s *Redis) Lrange(key string, start int, stop int) (val []string, err error) {
|
||||
func (s *Redis) Lrange(key string, start, stop int) (val []string, err error) {
|
||||
err = s.brk.DoWithAcceptable(func() error {
|
||||
conn, err := getRedis(s)
|
||||
if err != nil {
|
||||
@@ -1074,7 +1074,7 @@ func (s *Redis) ScriptLoad(script string) (string, error) {
|
||||
}
|
||||
|
||||
// Set is the implementation of redis set command.
|
||||
func (s *Redis) Set(key string, value string) error {
|
||||
func (s *Redis) Set(key, value string) error {
|
||||
return s.brk.DoWithAcceptable(func() error {
|
||||
conn, err := getRedis(s)
|
||||
if err != nil {
|
||||
@@ -1282,6 +1282,41 @@ func (s *Redis) Sdiffstore(destination string, keys ...string) (val int, err err
|
||||
return
|
||||
}
|
||||
|
||||
// Sinter is the implementation of redis sinter command.
|
||||
func (s *Redis) Sinter(keys ...string) (val []string, err error) {
|
||||
err = s.brk.DoWithAcceptable(func() error {
|
||||
conn, err := getRedis(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
val, err = conn.SInter(keys...).Result()
|
||||
return err
|
||||
}, acceptable)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Sinterstore is the implementation of redis sinterstore command.
|
||||
func (s *Redis) Sinterstore(destination string, keys ...string) (val int, err error) {
|
||||
err = s.brk.DoWithAcceptable(func() error {
|
||||
conn, err := getRedis(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
v, err := conn.SInterStore(destination, keys...).Result()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
val = int(v)
|
||||
return nil
|
||||
}, acceptable)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Ttl is the implementation of redis ttl command.
|
||||
func (s *Redis) Ttl(key string) (val int, err error) {
|
||||
err = s.brk.DoWithAcceptable(func() error {
|
||||
@@ -1412,7 +1447,7 @@ func (s *Redis) Zincrby(key string, increment int64, field string) (val int64, e
|
||||
}
|
||||
|
||||
// Zscore is the implementation of redis zscore command.
|
||||
func (s *Redis) Zscore(key string, value string) (val int64, err error) {
|
||||
func (s *Redis) Zscore(key, value string) (val int64, err error) {
|
||||
err = s.brk.DoWithAcceptable(func() error {
|
||||
conn, err := getRedis(s)
|
||||
if err != nil {
|
||||
@@ -1684,7 +1719,7 @@ func (s *Redis) ZrevrangebyscoreWithScoresAndLimit(key string, start, stop int64
|
||||
}
|
||||
|
||||
// Zrevrank is the implementation of redis zrevrank command.
|
||||
func (s *Redis) Zrevrank(key string, field string) (val int64, err error) {
|
||||
func (s *Redis) Zrevrank(key, field string) (val int64, err error) {
|
||||
err = s.brk.DoWithAcceptable(func() error {
|
||||
conn, err := getRedis(s)
|
||||
if err != nil {
|
||||
|
||||
@@ -638,6 +638,16 @@ func TestRedis_Set(t *testing.T) {
|
||||
num, err = client.Sdiffstore("key4", "key1", "key2")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 1, num)
|
||||
_, err = New(client.Addr, badType()).Sinter("key1", "key2")
|
||||
assert.NotNil(t, err)
|
||||
vals, err = client.Sinter("key1", "key2")
|
||||
assert.Nil(t, err)
|
||||
assert.ElementsMatch(t, []string{"2", "3", "4"}, vals)
|
||||
_, err = New(client.Addr, badType()).Sinterstore("key4", "key1", "key2")
|
||||
assert.NotNil(t, err)
|
||||
num, err = client.Sinterstore("key4", "key1", "key2")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 3, num)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,8 @@ type (
|
||||
}
|
||||
|
||||
statement struct {
|
||||
stmt *sql.Stmt
|
||||
query string
|
||||
stmt *sql.Stmt
|
||||
}
|
||||
|
||||
stmtConn interface {
|
||||
@@ -111,7 +112,8 @@ func (db *commonSqlConn) Prepare(query string) (stmt StmtSession, err error) {
|
||||
}
|
||||
|
||||
stmt = statement{
|
||||
stmt: st,
|
||||
query: query,
|
||||
stmt: st,
|
||||
}
|
||||
return nil
|
||||
}, db.acceptable)
|
||||
@@ -181,29 +183,29 @@ func (s statement) Close() error {
|
||||
}
|
||||
|
||||
func (s statement) Exec(args ...interface{}) (sql.Result, error) {
|
||||
return execStmt(s.stmt, args...)
|
||||
return execStmt(s.stmt, s.query, args...)
|
||||
}
|
||||
|
||||
func (s statement) QueryRow(v interface{}, args ...interface{}) error {
|
||||
return queryStmt(s.stmt, func(rows *sql.Rows) error {
|
||||
return unmarshalRow(v, rows, true)
|
||||
}, args...)
|
||||
}, s.query, args...)
|
||||
}
|
||||
|
||||
func (s statement) QueryRowPartial(v interface{}, args ...interface{}) error {
|
||||
return queryStmt(s.stmt, func(rows *sql.Rows) error {
|
||||
return unmarshalRow(v, rows, false)
|
||||
}, args...)
|
||||
}, s.query, args...)
|
||||
}
|
||||
|
||||
func (s statement) QueryRows(v interface{}, args ...interface{}) error {
|
||||
return queryStmt(s.stmt, func(rows *sql.Rows) error {
|
||||
return unmarshalRows(v, rows, true)
|
||||
}, args...)
|
||||
}, s.query, args...)
|
||||
}
|
||||
|
||||
func (s statement) QueryRowsPartial(v interface{}, args ...interface{}) error {
|
||||
return queryStmt(s.stmt, func(rows *sql.Rows) error {
|
||||
return unmarshalRows(v, rows, false)
|
||||
}, args...)
|
||||
}, s.query, args...)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package sqlx
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/tal-tech/go-zero/core/logx"
|
||||
@@ -12,10 +11,14 @@ import (
|
||||
const slowThreshold = time.Millisecond * 500
|
||||
|
||||
func exec(conn sessionConn, q string, args ...interface{}) (sql.Result, error) {
|
||||
stmt, err := format(q, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
startTime := timex.Now()
|
||||
result, err := conn.Exec(q, args...)
|
||||
duration := timex.Since(startTime)
|
||||
stmt := formatForPrint(q, args)
|
||||
if duration > slowThreshold {
|
||||
logx.WithDuration(duration).Slowf("[SQL] exec: slowcall - %s", stmt)
|
||||
} else {
|
||||
@@ -28,11 +31,15 @@ func exec(conn sessionConn, q string, args ...interface{}) (sql.Result, error) {
|
||||
return result, err
|
||||
}
|
||||
|
||||
func execStmt(conn stmtConn, args ...interface{}) (sql.Result, error) {
|
||||
func execStmt(conn stmtConn, q string, args ...interface{}) (sql.Result, error) {
|
||||
stmt, err := format(q, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
startTime := timex.Now()
|
||||
result, err := conn.Exec(args...)
|
||||
duration := timex.Since(startTime)
|
||||
stmt := fmt.Sprint(args...)
|
||||
if duration > slowThreshold {
|
||||
logx.WithDuration(duration).Slowf("[SQL] execStmt: slowcall - %s", stmt)
|
||||
} else {
|
||||
@@ -46,10 +53,14 @@ func execStmt(conn stmtConn, args ...interface{}) (sql.Result, error) {
|
||||
}
|
||||
|
||||
func query(conn sessionConn, scanner func(*sql.Rows) error, q string, args ...interface{}) error {
|
||||
stmt, err := format(q, args...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
startTime := timex.Now()
|
||||
rows, err := conn.Query(q, args...)
|
||||
duration := timex.Since(startTime)
|
||||
stmt := fmt.Sprint(args...)
|
||||
if duration > slowThreshold {
|
||||
logx.WithDuration(duration).Slowf("[SQL] query: slowcall - %s", stmt)
|
||||
} else {
|
||||
@@ -64,8 +75,12 @@ func query(conn sessionConn, scanner func(*sql.Rows) error, q string, args ...in
|
||||
return scanner(rows)
|
||||
}
|
||||
|
||||
func queryStmt(conn stmtConn, scanner func(*sql.Rows) error, args ...interface{}) error {
|
||||
stmt := fmt.Sprint(args...)
|
||||
func queryStmt(conn stmtConn, scanner func(*sql.Rows) error, q string, args ...interface{}) error {
|
||||
stmt, err := format(q, args...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
startTime := timex.Now()
|
||||
rows, err := conn.Query(args...)
|
||||
duration := timex.Since(startTime)
|
||||
|
||||
@@ -14,6 +14,7 @@ var errMockedPlaceholder = errors.New("placeholder")
|
||||
func TestStmt_exec(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
query string
|
||||
args []interface{}
|
||||
delay bool
|
||||
hasError bool
|
||||
@@ -23,18 +24,28 @@ func TestStmt_exec(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "normal",
|
||||
query: "select user from users where id=?",
|
||||
args: []interface{}{1},
|
||||
lastInsertId: 1,
|
||||
rowsAffected: 2,
|
||||
},
|
||||
{
|
||||
name: "exec error",
|
||||
query: "select user from users where id=?",
|
||||
args: []interface{}{1},
|
||||
hasError: true,
|
||||
err: errors.New("exec"),
|
||||
},
|
||||
{
|
||||
name: "exec more args error",
|
||||
query: "select user from users where id=? and name=?",
|
||||
args: []interface{}{1},
|
||||
hasError: true,
|
||||
err: errors.New("exec"),
|
||||
},
|
||||
{
|
||||
name: "slowcall",
|
||||
query: "select user from users where id=?",
|
||||
args: []interface{}{1},
|
||||
delay: true,
|
||||
lastInsertId: 1,
|
||||
@@ -51,7 +62,7 @@ func TestStmt_exec(t *testing.T) {
|
||||
rowsAffected: test.rowsAffected,
|
||||
err: test.err,
|
||||
delay: test.delay,
|
||||
}, "select user from users where id=?", args...)
|
||||
}, test.query, args...)
|
||||
},
|
||||
func(args ...interface{}) (sql.Result, error) {
|
||||
return execStmt(&mockedStmtConn{
|
||||
@@ -59,7 +70,7 @@ func TestStmt_exec(t *testing.T) {
|
||||
rowsAffected: test.rowsAffected,
|
||||
err: test.err,
|
||||
delay: test.delay,
|
||||
}, args...)
|
||||
}, test.query, args...)
|
||||
},
|
||||
}
|
||||
|
||||
@@ -89,23 +100,34 @@ func TestStmt_exec(t *testing.T) {
|
||||
func TestStmt_query(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
query string
|
||||
args []interface{}
|
||||
delay bool
|
||||
hasError bool
|
||||
err error
|
||||
}{
|
||||
{
|
||||
name: "normal",
|
||||
args: []interface{}{1},
|
||||
name: "normal",
|
||||
query: "select user from users where id=?",
|
||||
args: []interface{}{1},
|
||||
},
|
||||
{
|
||||
name: "query error",
|
||||
query: "select user from users where id=?",
|
||||
args: []interface{}{1},
|
||||
hasError: true,
|
||||
err: errors.New("exec"),
|
||||
},
|
||||
{
|
||||
name: "query more args error",
|
||||
query: "select user from users where id=? and name=?",
|
||||
args: []interface{}{1},
|
||||
hasError: true,
|
||||
err: errors.New("exec"),
|
||||
},
|
||||
{
|
||||
name: "slowcall",
|
||||
query: "select user from users where id=?",
|
||||
args: []interface{}{1},
|
||||
delay: true,
|
||||
},
|
||||
@@ -120,7 +142,7 @@ func TestStmt_query(t *testing.T) {
|
||||
delay: test.delay,
|
||||
}, func(rows *sql.Rows) error {
|
||||
return nil
|
||||
}, "select user from users where id=?", args...)
|
||||
}, test.query, args...)
|
||||
},
|
||||
func(args ...interface{}) error {
|
||||
return queryStmt(&mockedStmtConn{
|
||||
@@ -128,7 +150,7 @@ func TestStmt_query(t *testing.T) {
|
||||
delay: test.delay,
|
||||
}, func(rows *sql.Rows) error {
|
||||
return nil
|
||||
}, args...)
|
||||
}, test.query, args...)
|
||||
},
|
||||
}
|
||||
|
||||
@@ -143,7 +165,7 @@ func TestStmt_query(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
assert.Equal(t, errMockedPlaceholder, err)
|
||||
assert.NotNil(t, err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package sqlx
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/tal-tech/go-zero/core/logx"
|
||||
@@ -45,24 +46,6 @@ func escape(input string) string {
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func formatForPrint(query string, args ...interface{}) string {
|
||||
if len(args) == 0 {
|
||||
return query
|
||||
}
|
||||
|
||||
var vals []string
|
||||
for _, arg := range args {
|
||||
vals = append(vals, fmt.Sprintf("%q", mapping.Repr(arg)))
|
||||
}
|
||||
|
||||
var b strings.Builder
|
||||
b.WriteByte('[')
|
||||
b.WriteString(strings.Join(vals, ", "))
|
||||
b.WriteByte(']')
|
||||
|
||||
return strings.Join([]string{query, b.String()}, " ")
|
||||
}
|
||||
|
||||
func format(query string, args ...interface{}) (string, error) {
|
||||
numArgs := len(args)
|
||||
if numArgs == 0 {
|
||||
@@ -70,38 +53,52 @@ func format(query string, args ...interface{}) (string, error) {
|
||||
}
|
||||
|
||||
var b strings.Builder
|
||||
argIndex := 0
|
||||
var argIndex int
|
||||
bytes := len(query)
|
||||
|
||||
for _, ch := range query {
|
||||
if ch == '?' {
|
||||
for i := 0; i < bytes; i++ {
|
||||
ch := query[i]
|
||||
switch ch {
|
||||
case '?':
|
||||
if argIndex >= numArgs {
|
||||
return "", fmt.Errorf("error: %d ? in sql, but less arguments provided", argIndex)
|
||||
}
|
||||
|
||||
arg := args[argIndex]
|
||||
writeValue(&b, args[argIndex])
|
||||
argIndex++
|
||||
|
||||
switch v := arg.(type) {
|
||||
case bool:
|
||||
if v {
|
||||
b.WriteByte('1')
|
||||
} else {
|
||||
b.WriteByte('0')
|
||||
case '$':
|
||||
var j int
|
||||
for j = i + 1; j < bytes; j++ {
|
||||
char := query[j]
|
||||
if char < '0' || '9' < char {
|
||||
break
|
||||
}
|
||||
case string:
|
||||
b.WriteByte('\'')
|
||||
b.WriteString(escape(v))
|
||||
b.WriteByte('\'')
|
||||
default:
|
||||
b.WriteString(mapping.Repr(v))
|
||||
}
|
||||
} else {
|
||||
b.WriteRune(ch)
|
||||
if j > i+1 {
|
||||
index, err := strconv.Atoi(query[i+1 : j])
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// index starts from 1 for pg
|
||||
if index > argIndex {
|
||||
argIndex = index
|
||||
}
|
||||
index--
|
||||
if index < 0 || numArgs <= index {
|
||||
return "", fmt.Errorf("error: wrong index %d in sql", index)
|
||||
}
|
||||
|
||||
writeValue(&b, args[index])
|
||||
i = j - 1
|
||||
}
|
||||
default:
|
||||
b.WriteByte(ch)
|
||||
}
|
||||
}
|
||||
|
||||
if argIndex < numArgs {
|
||||
return "", fmt.Errorf("error: %d ? in sql, but more arguments provided", argIndex)
|
||||
return "", fmt.Errorf("error: %d arguments provided, not matching sql", argIndex)
|
||||
}
|
||||
|
||||
return b.String(), nil
|
||||
@@ -117,3 +114,20 @@ func logSqlError(stmt string, err error) {
|
||||
logx.Errorf("stmt: %s, error: %s", stmt, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func writeValue(buf *strings.Builder, arg interface{}) {
|
||||
switch v := arg.(type) {
|
||||
case bool:
|
||||
if v {
|
||||
buf.WriteByte('1')
|
||||
} else {
|
||||
buf.WriteByte('0')
|
||||
}
|
||||
case string:
|
||||
buf.WriteByte('\'')
|
||||
buf.WriteString(escape(v))
|
||||
buf.WriteByte('\'')
|
||||
default:
|
||||
buf.WriteString(mapping.Repr(v))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,30 +29,63 @@ func TestDesensitize_WithoutAccount(t *testing.T) {
|
||||
assert.True(t, strings.Contains(datasource, "tcp(111.222.333.44:3306)"))
|
||||
}
|
||||
|
||||
func TestFormatForPrint(t *testing.T) {
|
||||
func TestFormat(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
query string
|
||||
args []interface{}
|
||||
expect string
|
||||
hasErr bool
|
||||
}{
|
||||
{
|
||||
name: "no args",
|
||||
query: "select user, name from table where id=?",
|
||||
expect: `select user, name from table where id=?`,
|
||||
name: "mysql normal",
|
||||
query: "select name, age from users where bool=? and phone=?",
|
||||
args: []interface{}{true, "133"},
|
||||
expect: "select name, age from users where bool=1 and phone='133'",
|
||||
},
|
||||
{
|
||||
name: "one arg",
|
||||
query: "select user, name from table where id=?",
|
||||
args: []interface{}{"kevin"},
|
||||
expect: `select user, name from table where id=? ["kevin"]`,
|
||||
name: "mysql normal",
|
||||
query: "select name, age from users where bool=? and phone=?",
|
||||
args: []interface{}{false, "133"},
|
||||
expect: "select name, age from users where bool=0 and phone='133'",
|
||||
},
|
||||
{
|
||||
name: "pg normal",
|
||||
query: "select name, age from users where bool=$1 and phone=$2",
|
||||
args: []interface{}{true, "133"},
|
||||
expect: "select name, age from users where bool=1 and phone='133'",
|
||||
},
|
||||
{
|
||||
name: "pg normal reverse",
|
||||
query: "select name, age from users where bool=$2 and phone=$1",
|
||||
args: []interface{}{"133", false},
|
||||
expect: "select name, age from users where bool=0 and phone='133'",
|
||||
},
|
||||
{
|
||||
name: "pg error not number",
|
||||
query: "select name, age from users where bool=$a and phone=$1",
|
||||
args: []interface{}{"133", false},
|
||||
hasErr: true,
|
||||
},
|
||||
{
|
||||
name: "pg error more args",
|
||||
query: "select name, age from users where bool=$2 and phone=$1 and nickname=$3",
|
||||
args: []interface{}{"133", false},
|
||||
hasErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
test := test
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
actual := formatForPrint(test.query, test.args...)
|
||||
assert.Equal(t, test.expect, actual)
|
||||
t.Parallel()
|
||||
|
||||
actual, err := format(test.query, test.args...)
|
||||
if test.hasErr {
|
||||
assert.NotNil(t, err)
|
||||
} else {
|
||||
assert.Equal(t, test.expect, actual)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ func Reverse(s string) string {
|
||||
}
|
||||
|
||||
// Substr returns runes between start and stop [start, stop) regardless of the chars are ascii or utf8.
|
||||
func Substr(str string, start int, stop int) (string, error) {
|
||||
func Substr(str string, start, stop int) (string, error) {
|
||||
rs := []rune(str)
|
||||
length := len(rs)
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ func NewManagedResource(generate func() interface{}, equals func(a, b interface{
|
||||
}
|
||||
}
|
||||
|
||||
// MarkBroken marks the resouce broken.
|
||||
// MarkBroken marks the resource broken.
|
||||
func (mr *ManagedResource) MarkBroken(resource interface{}) {
|
||||
mr.lock.Lock()
|
||||
defer mr.lock.Unlock()
|
||||
|
||||
@@ -2,7 +2,7 @@ package syncx
|
||||
|
||||
import "sync"
|
||||
|
||||
// Once returns a func that guanartees fn can only called once.
|
||||
// Once returns a func that guarantees fn can only called once.
|
||||
func Once(fn func()) func() {
|
||||
once := new(sync.Once)
|
||||
return func() {
|
||||
|
||||
@@ -2,7 +2,7 @@ package syncx
|
||||
|
||||
import "sync/atomic"
|
||||
|
||||
// A OnceGuard is used to make sure a resouce can be taken once.
|
||||
// A OnceGuard is used to make sure a resource can be taken once.
|
||||
type OnceGuard struct {
|
||||
done uint32
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ type (
|
||||
|
||||
// A Pool is used to pool resources.
|
||||
// The difference between sync.Pool is that:
|
||||
// 1. the limit of the resouces
|
||||
// 1. the limit of the resources
|
||||
// 2. max age of the resources can be set
|
||||
// 3. the method to destroy resources can be customized
|
||||
Pool struct {
|
||||
@@ -56,7 +56,7 @@ func NewPool(n int, create func() interface{}, destroy func(interface{}), opts .
|
||||
return pool
|
||||
}
|
||||
|
||||
// Get gets a resouce.
|
||||
// Get gets a resource.
|
||||
func (p *Pool) Get() interface{} {
|
||||
p.lock.Lock()
|
||||
defer p.lock.Unlock()
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
// ErrUseOfCleaned is an error that indicates using a cleaned resource.
|
||||
var ErrUseOfCleaned = errors.New("using a cleaned resource")
|
||||
|
||||
// A RefResource is used to reference counting a resouce.
|
||||
// A RefResource is used to reference counting a resource.
|
||||
type RefResource struct {
|
||||
lock sync.Mutex
|
||||
ref int32
|
||||
|
||||
40
go.mod
40
go.mod
@@ -16,48 +16,36 @@ require (
|
||||
github.com/go-redis/redis v6.15.7+incompatible
|
||||
github.com/go-sql-driver/mysql v1.5.0
|
||||
github.com/go-xorm/builder v0.3.4
|
||||
github.com/gogo/protobuf v1.3.1 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
|
||||
github.com/golang/mock v1.4.3
|
||||
github.com/golang/protobuf v1.4.2
|
||||
github.com/google/uuid v1.1.1
|
||||
github.com/gorilla/websocket v1.4.2 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.14.3 // indirect
|
||||
github.com/golang/protobuf v1.5.2
|
||||
github.com/google/uuid v1.1.2
|
||||
github.com/iancoleman/strcase v0.1.2
|
||||
github.com/justinas/alice v1.2.0
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
|
||||
github.com/kr/pretty v0.2.0 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/lib/pq v1.3.0
|
||||
github.com/logrusorgru/aurora v2.0.3+incompatible
|
||||
github.com/mattn/go-colorable v0.1.6 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.9 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.4
|
||||
github.com/olekukonko/tablewriter v0.0.5
|
||||
github.com/onsi/ginkgo v1.7.0 // indirect
|
||||
github.com/onsi/gomega v1.5.0 // indirect
|
||||
github.com/pierrec/lz4 v2.5.1+incompatible // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/prometheus/client_golang v1.5.1
|
||||
github.com/prometheus/client_golang v1.11.0
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/spaolacci/murmur3 v1.1.0
|
||||
github.com/stretchr/testify v1.5.1
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6 // indirect
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/urfave/cli v1.22.5
|
||||
github.com/xwb1989/sqlparser v0.0.0-20180606152119-120387863bf2
|
||||
github.com/zeromicro/antlr v0.0.1 // indirect
|
||||
go.etcd.io/etcd v0.0.0-20200402134248-51bdeb39e698
|
||||
github.com/zeromicro/antlr v0.0.1
|
||||
go.etcd.io/etcd/api/v3 v3.5.0
|
||||
go.etcd.io/etcd/client/v3 v3.5.0
|
||||
go.uber.org/automaxprocs v1.3.0
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381
|
||||
golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1 // indirect
|
||||
golang.org/x/text v0.3.3 // indirect
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0
|
||||
golang.org/x/tools v0.0.0-20200410132612-ae9902aceb98 // indirect
|
||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f // indirect
|
||||
google.golang.org/grpc v1.29.1
|
||||
google.golang.org/protobuf v1.25.0 // indirect
|
||||
golang.org/x/net v0.0.0-20210614182718-04defd469f4e
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 // indirect
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba
|
||||
google.golang.org/genproto v0.0.0-20210617175327-b9e0b3197ced // indirect
|
||||
google.golang.org/grpc v1.38.0
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.28
|
||||
gopkg.in/h2non/gock.v1 v1.0.15
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
honnef.co/go/tools v0.0.1-2020.1.4 // indirect
|
||||
sigs.k8s.io/yaml v1.2.0 // indirect
|
||||
)
|
||||
|
||||
284
go.sum
284
go.sum
@@ -1,30 +1,26 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/ClickHouse/clickhouse-go v1.4.3 h1:iAFMa2UrQdR5bHJ2/yaSLffZkxpcOYQMCUuKeNXGdqc=
|
||||
github.com/ClickHouse/clickhouse-go v1.4.3/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI=
|
||||
github.com/DATA-DOG/go-sqlmock v1.4.1 h1:ThlnYciV1iM/V0OSF/dtkqWb6xo5qITT1TJBG1MRDJM=
|
||||
github.com/DATA-DOG/go-sqlmock v1.4.1/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZpUGpz5+4FfNmIU+FmZg2P3Xaj2v2bfNWmk=
|
||||
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
|
||||
github.com/alicebob/miniredis/v2 v2.14.1 h1:GjlbSeoJ24bzdLRs13HoMEeaRZx9kg5nHoRW7QV/nCs=
|
||||
github.com/alicebob/miniredis/v2 v2.14.1/go.mod h1:uS970Sw5Gs9/iK3yBg0l9Uj9s25wXxSpQUE9EaJ/Blg=
|
||||
github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q=
|
||||
github.com/antlr/antlr4 v0.0.0-20210105212045-464bcbc32de2 h1:rL2miklL5rhxUaZO7hntBcy/VHaiyuPQ4EJoy/NMwaM=
|
||||
github.com/antlr/antlr4 v0.0.0-20210105212045-464bcbc32de2/go.mod h1:T7PbCXFs94rrTttyxjbyT5+/1V8T2TYDejxUfHJjw1Y=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
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/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/bkaradzic/go-lz4 v1.0.0 h1:RXc4wYsyz985CkXXeX04y4VnZFGG8Rd43pRaHsOXAKk=
|
||||
github.com/bkaradzic/go-lz4 v1.0.0/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwjwegp5jy4=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
@@ -35,31 +31,28 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
|
||||
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 h1:F1EaeKL/ta07PY/k9Os/UFtwERei2/XzGemhpGnBKNg=
|
||||
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa h1:OaNxuTZr7kxeODyLWsRMC+OD03aFUH+mW6r2d+MWa5Y=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||
github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd/v22 v22.0.0 h1:XJIw/+VlJ+87J+doOxznsAWIdmWuViOVhkQamW5YV28=
|
||||
github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
|
||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI=
|
||||
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/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
|
||||
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/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 h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4 h1:qk/FSDDxo05wdJH28W+p5yivv7LuLYLRXPPD8KQCtZs=
|
||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/emicklei/proto v1.9.0 h1:l0QiNT6Qs7Yj0Mb4X6dnWBQer4ebei2BFcgQLbGqUDc=
|
||||
github.com/emicklei/proto v1.9.0/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
|
||||
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
|
||||
github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4=
|
||||
@@ -73,137 +66,111 @@ github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8 h1:DujepqpGd1hyOd7a
|
||||
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.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-redis/redis v6.15.7+incompatible h1:3skhDh95XQMpnqeqNftPkQD9jL9e5e36z/1SUm6dy1U=
|
||||
github.com/go-redis/redis v6.15.7+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-xorm/builder v0.3.4 h1:FxkeGB4Cggdw3tPwutLCpfjng2jugfkg6LDMrd/KsoY=
|
||||
github.com/go-xorm/builder v0.3.4/go.mod h1:KxkQkNN1DpPKTedxXyTQcmH+rXfvk4LZ9SOOBoZBAxw=
|
||||
github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:9wScpmSP5A3Bk8V3XHWUcJmYTh+ZnlHVyc+A4oZYS3Y=
|
||||
github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM=
|
||||
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godbus/dbus/v5 v5.0.4/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.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
|
||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.4.3 h1:GV+pQPG/EUUbkh47niozDcADz6go/dUwhVzdUQHIVRw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
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.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
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.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
|
||||
github.com/google/go-cmp v0.5.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/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4 h1:z53tR0945TRRQO/fLEVPI6SMv7ZflF0TEaTAoU7tOzg=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
|
||||
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.14.3 h1:OCJlWkOUoTnl0neNGlf4fUm3TmbEtguw7vR+nGtnDjY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.14.3/go.mod h1:6CwZWGDSPRJidgKAtJVvND6soZe6fT7iteq8wDPdhb0=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
|
||||
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/iancoleman/strcase v0.1.2 h1:gnomlvw9tnV3ITTAxzKSgTF+8kFWcU/f+TgttpXGz1U=
|
||||
github.com/iancoleman/strcase v0.1.2/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
|
||||
github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||
github.com/justinas/alice v1.2.0 h1:+MHSA/vccVCF4Uq37S42jwlkvI2Xzl7zTPCN5BnZNVo=
|
||||
github.com/justinas/alice v1.2.0/go.mod h1:fN5HRH/reO/zrUflLfTN43t3vXvKzvZIENsNEe7i7qA=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
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 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/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 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
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 v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU=
|
||||
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8=
|
||||
github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
|
||||
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54=
|
||||
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4=
|
||||
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
|
||||
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||
github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8=
|
||||
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
@@ -213,7 +180,6 @@ github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi
|
||||
github.com/pierrec/lz4 v2.5.1+incompatible h1:Yq0up0149Hh5Ekhm/91lgkZuD1ZDnXNM26bycpTzYBM=
|
||||
github.com/pierrec/lz4 v2.5.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
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=
|
||||
@@ -221,125 +187,114 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
|
||||
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 v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.5.1 h1:bdHYieyGlH+6OLEk2YQha8THib30KP0/yD0YH9m6xcA=
|
||||
github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ=
|
||||
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||
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/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U=
|
||||
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ=
|
||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8=
|
||||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
|
||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||
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.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
||||
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/pflag v1.0.1 h1:aCvUg6QPl3ibpQUxyLkrEkCHtPqYJL4x9AuhqVqFis4=
|
||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
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/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 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6 h1:lYIiVDtZnyTWlNwiAxLj0bbpTcx1BWCFhXjfsvmPdNc=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU=
|
||||
github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xwb1989/sqlparser v0.0.0-20180606152119-120387863bf2 h1:zzrxE1FKn5ryBNl9eKOeqQ58Y/Qpo3Q9QNxKHX5uzzQ=
|
||||
github.com/xwb1989/sqlparser v0.0.0-20180606152119-120387863bf2/go.mod h1:hzfGeIUDq/j97IG+FhNqkowIyEcD88LrW6fyU3K3WqY=
|
||||
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/gopher-lua v0.0.0-20191220021717-ab39c6098bdb h1:ZkM6LRnq40pR1Ox0hTHlnpkcOTuFIDQpZ1IN8rKKhX0=
|
||||
github.com/yuin/gopher-lua v0.0.0-20191220021717-ab39c6098bdb/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ=
|
||||
github.com/zeromicro/antlr v0.0.0-20210508120604-8d7a7786f5c4 h1:wt86gT5lsN+xWmij6lFCrDIqoxeOnqM2MxiO7cNm+Lo=
|
||||
github.com/zeromicro/antlr v0.0.0-20210508120604-8d7a7786f5c4/go.mod h1:nfpjEwFR6Q4xGDJMcZnCL9tEfQRgszMwu3rDz2Z+p5M=
|
||||
github.com/zeromicro/antlr v0.0.1 h1:CQpIn/dc0pUjgGQ81y98s/NGOm2Hfru2NNio2I9mQgk=
|
||||
github.com/zeromicro/antlr v0.0.1/go.mod h1:nfpjEwFR6Q4xGDJMcZnCL9tEfQRgszMwu3rDz2Z+p5M=
|
||||
go.etcd.io/bbolt v1.3.4 h1:hi1bXHMVrlQh6WwxAy+qZCV/SYIlqo+Ushwdpa4tAKg=
|
||||
go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||
go.etcd.io/etcd v0.0.0-20200402134248-51bdeb39e698 h1:jWtjCJX1qxhHISBMLRztWwR+EXkI7MJAF2HjHAE/x/I=
|
||||
go.etcd.io/etcd v0.0.0-20200402134248-51bdeb39e698/go.mod h1:YoUyTScD3Vcv2RBm3eGVOq7i1ULiz3OuXoQFWOirmAM=
|
||||
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
|
||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.etcd.io/etcd/api/v3 v3.5.0 h1:GsV3S+OfZEOCNXdtNkBSR7kgLobAa/SO6tCxRa0GAYw=
|
||||
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.0 h1:2aQv6F436YnN7I4VbI8PPYrBhu+SmrTaADcf8Mi/6PU=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
|
||||
go.etcd.io/etcd/client/v3 v3.5.0 h1:62Eh0XOro+rDwkrypAGDfgmNh5Joq+z+W9HZdlXMzek=
|
||||
go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0=
|
||||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/automaxprocs v1.3.0 h1:II28aZoGdaglS5vVNnspf28lnZpXScxtIozx1lAjdb0=
|
||||
go.uber.org/automaxprocs v1.3.0/go.mod h1:9CWT6lKIep8U41DDaPiH6eFscnTyjfTANNQNx6LrIcA=
|
||||
go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=
|
||||
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||
go.uber.org/zap v1.14.1 h1:nYDKopTbvAPq/NrUVZwT15y2lpROBiLLyoRTbXOYWOo=
|
||||
go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
|
||||
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/zap v1.17.0 h1:MTjgFu6ZLKvY6Pvaqk97GlxNBuMpV4Hy/3P6tRGlI2U=
|
||||
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
|
||||
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-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
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 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
|
||||
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/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/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/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
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-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
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-20191002035440-2ec189313ef0/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-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q=
|
||||
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
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 h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
|
||||
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/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-20180909124046-d0be0721c37e/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-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -347,80 +302,84 @@ golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1 h1:sIky/MyNRSHTrdxfsiUSS4WIAMvInbeXljJz+jDjeYE=
|
||||
golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/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=
|
||||
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 h1:RqytpXGR1iVNX7psjB3ff8y7sNFinVFvkx1c8SjBkio=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||
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/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/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.5/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-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE=
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/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-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/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-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-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200410132612-ae9902aceb98 h1:ibc1eDGW5ajwA4qzFTj0WHlD9eofMe1gAre+A0a3Vhs=
|
||||
golang.org/x/tools v0.0.0-20200410132612-ae9902aceb98/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
|
||||
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.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
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 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
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/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f h1:ohwtWcCwB/fZUxh/vjazHorYmBnua3NmY3CAjwC7mEA=
|
||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
|
||||
google.golang.org/genproto v0.0.0-20210617175327-b9e0b3197ced h1:c5geK1iMU3cDKtFrCVQIcjR3W+JOZMuhIyICMCTbtus=
|
||||
google.golang.org/genproto v0.0.0-20210617175327-b9e0b3197ced/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
||||
google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0=
|
||||
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0 h1:qdOKuR/EIArgaWNjetjgTzgVTAZ+S/WXVrq9HW9zimw=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
|
||||
google.golang.org/protobuf v1.26.0/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/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.28 h1:n1tBJnnK2r7g9OW2btFH91V92STTUevLXYFb8gy9EMk=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
@@ -428,30 +387,23 @@ gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/h2non/gock.v1 v1.0.15 h1:SzLqcIlb/fDfg7UvukMpNcWsu7sI5tWwL+KCATZqks0=
|
||||
gopkg.in/h2non/gock.v1 v1.0.15/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
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.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
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.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
rsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
|
||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||
|
||||
26
readme-cn.md
26
readme-cn.md
@@ -26,7 +26,7 @@ go-zero 包含极简的 API 定义和生成工具 goctl,可以根据定义的
|
||||
* 自动校验客户端请求参数合法性
|
||||
* 大量微服务治理和并发工具包
|
||||
|
||||
<img src="https://gitee.com/kevwan/static/raw/master/doc/images/architecture.png" alt="架构图" width="1500" />
|
||||

|
||||
|
||||
## 1. go-zero 框架背景
|
||||
|
||||
@@ -78,7 +78,7 @@ go-zero 是一个集成了各种工程实践的包含 web 和 rpc 框架,有
|
||||
|
||||
如下图,我们从多个层面保障了整体服务的高可用:
|
||||
|
||||

|
||||

|
||||
|
||||
觉得不错的话,别忘 **star** 👏
|
||||
|
||||
@@ -151,7 +151,7 @@ GO111MODULE=on GOPROXY=https://goproxy.cn/,direct go get -u github.com/tal-tech/
|
||||
|
||||
## 6. Benchmark
|
||||
|
||||

|
||||

|
||||
|
||||
[测试代码见这里](https://github.com/smallnest/go-web-framework-benchmark)
|
||||
|
||||
@@ -159,7 +159,7 @@ GO111MODULE=on GOPROXY=https://goproxy.cn/,direct go get -u github.com/tal-tech/
|
||||
|
||||
* API 文档
|
||||
|
||||
[https://go-zero.dev/zh-hans/](https://zeromicro.github.io/go-zero)
|
||||
[https://go-zero.dev/cn/](https://go-zero.dev/cn/)
|
||||
|
||||
* 常见问题
|
||||
|
||||
@@ -208,6 +208,22 @@ go-zero 已被许多公司用于生产部署,接入场景如在线教育、电
|
||||
>17. 三七游戏
|
||||
>18. 成都创道夫科技有限公司
|
||||
>19. 联想Lenovo
|
||||
>20. 云犀
|
||||
>21. 高盈国际
|
||||
>22. 北京中科生活服务有限公司
|
||||
>23. Indochat 印尼艾希英
|
||||
>24. 数赞
|
||||
>25. 量冠科技
|
||||
>26. 杭州又拍云科技有限公司
|
||||
>27. 深圳市点购电子商务控股股份有限公司
|
||||
>28. 深圳市宁克沃德科技有限公司
|
||||
>29. 桂林优利特医疗电子有限公司
|
||||
>30. 成都智橙互动科技有限公司
|
||||
>31. 深圳市班班科技有限公司
|
||||
>32. 飞视(苏州)数字技术有限公司
|
||||
>33. 上海鲸思智能科技有限公司
|
||||
>34. 南宁宸升计算机科技有限公司
|
||||
>35. 秦皇岛2084team
|
||||
|
||||
如果贵公司也已使用 go-zero,欢迎在 [登记地址](https://github.com/tal-tech/go-zero/issues/602) 登记,仅仅为了推广,不做其它用途。
|
||||
|
||||
@@ -215,7 +231,7 @@ go-zero 已被许多公司用于生产部署,接入场景如在线教育、电
|
||||
|
||||
`go-zero` 相关文章和视频都会在 `微服务实践` 公众号整理呈现,欢迎扫码关注 👏
|
||||
|
||||
<img src="https://gitee.com/kevwan/static/raw/master/images/wechat-micro.jpg" alt="wechat" width="300" />
|
||||
<img src="https://raw.githubusercontent.com/tal-tech/zero-doc/main/doc/images/wechat-micro.jpg" alt="wechat" width="300" />
|
||||
|
||||
## 10. 微信交流群
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ go get -u github.com/tal-tech/go-zero
|
||||
|
||||
[Rapid development of microservice systems](https://github.com/tal-tech/zero-doc/blob/main/doc/shorturl-en.md)
|
||||
|
||||
[Rapid development of microservice systems - multiple RPCs](https://github.com/tal-tech/zero-doc/blob/main/doc/bookstore-en.md)
|
||||
[Rapid development of microservice systems - multiple RPCs](https://github.com/tal-tech/zero-doc/blob/main/docs/zero/bookstore-en.md)
|
||||
|
||||
1. install goctl
|
||||
|
||||
@@ -200,14 +200,13 @@ go get -u github.com/tal-tech/go-zero
|
||||
|
||||
## 7. Benchmark
|
||||
|
||||
Document: [https://go-zero.dev/en/](https://go-zero.dev/en/)
|
||||
|
||||

|
||||
|
||||
[Checkout the test code](https://github.com/smallnest/go-web-framework-benchmark)
|
||||
|
||||
## 8. Documents (adding)
|
||||
|
||||
* [Documents](https://go-zero.dev/en/)
|
||||
* [Rapid development of microservice systems](https://github.com/tal-tech/zero-doc/blob/main/doc/shorturl-en.md)
|
||||
* [Rapid development of microservice systems - multiple RPCs](https://github.com/tal-tech/zero-doc/blob/main/docs/zero/bookstore-en.md)
|
||||
* [Examples](https://github.com/zeromicro/zero-examples)
|
||||
@@ -224,7 +223,7 @@ Document: [https://go-zero.dev/en/](https://go-zero.dev/en/)
|
||||
|
||||
## 10. Chat group
|
||||
|
||||
Join the chat via https://join.slack.com/t/go-zeroworkspace/shared_invite/zt-m39xssxc-kgIqERa7aVsujKNj~XuPKg
|
||||
Join the chat via https://join.slack.com/t/go-zero/shared_invite/zt-qxlclrv9-MWrCNkB2DpSgtEK2tVXJcw
|
||||
|
||||
## Give a Star! ⭐
|
||||
|
||||
|
||||
@@ -159,7 +159,7 @@ type mockedRouter struct{}
|
||||
func (m mockedRouter) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
|
||||
}
|
||||
|
||||
func (m mockedRouter) Handle(method string, path string, handler http.Handler) error {
|
||||
func (m mockedRouter) Handle(method, path string, handler http.Handler) error {
|
||||
return errors.New("foo")
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import "net/http"
|
||||
// Router interface represents a http router that handles http requests.
|
||||
type Router interface {
|
||||
http.Handler
|
||||
Handle(method string, path string, handler http.Handler) error
|
||||
Handle(method, path string, handler http.Handler) error
|
||||
SetNotFoundHandler(handler http.Handler)
|
||||
SetNotAllowedHandler(handler http.Handler)
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ const (
|
||||
`
|
||||
)
|
||||
|
||||
func genDoc(api *spec.ApiSpec, dir string, filename string) error {
|
||||
func genDoc(api *spec.ApiSpec, dir, filename string) error {
|
||||
fp, _, err := util.MaybeCreateFile(dir, "", filename)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -86,12 +86,17 @@ func ApiFormatByPath(apiFilePath string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
result, err := apiFormat(string(data))
|
||||
abs, err := filepath.Abs(apiFilePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = parser.ParseContent(result)
|
||||
result, err := apiFormat(string(data), abs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = parser.ParseContent(result, abs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -99,8 +104,8 @@ func ApiFormatByPath(apiFilePath string) error {
|
||||
return ioutil.WriteFile(apiFilePath, []byte(result), os.ModePerm)
|
||||
}
|
||||
|
||||
func apiFormat(data string) (string, error) {
|
||||
_, err := parser.ParseContent(data)
|
||||
func apiFormat(data string, filename ...string) (string, error) {
|
||||
_, err := parser.ParseContent(data, filename...)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
@@ -54,14 +54,19 @@ func DoGenProject(apiFile, dir, style string) error {
|
||||
}
|
||||
|
||||
logx.Must(util.MkdirIfNotExist(dir))
|
||||
rootPkg, err := getParentPackage(dir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logx.Must(genEtc(dir, cfg, api))
|
||||
logx.Must(genConfig(dir, cfg, api))
|
||||
logx.Must(genMain(dir, cfg, api))
|
||||
logx.Must(genServiceContext(dir, cfg, api))
|
||||
logx.Must(genMain(dir, rootPkg, cfg, api))
|
||||
logx.Must(genServiceContext(dir, rootPkg, cfg, api))
|
||||
logx.Must(genTypes(dir, cfg, api))
|
||||
logx.Must(genRoutes(dir, cfg, api))
|
||||
logx.Must(genHandlers(dir, cfg, api))
|
||||
logx.Must(genLogic(dir, cfg, api))
|
||||
logx.Must(genRoutes(dir, rootPkg, cfg, api))
|
||||
logx.Must(genHandlers(dir, rootPkg, cfg, api))
|
||||
logx.Must(genLogic(dir, rootPkg, cfg, api))
|
||||
logx.Must(genMiddleware(dir, cfg, api))
|
||||
|
||||
if err := backupAndSweep(apiFile); err != nil {
|
||||
|
||||
@@ -49,18 +49,14 @@ type handlerInfo struct {
|
||||
HasRequest bool
|
||||
}
|
||||
|
||||
func genHandler(dir string, cfg *config.Config, group spec.Group, route spec.Route) error {
|
||||
func genHandler(dir, rootPkg string, cfg *config.Config, group spec.Group, route spec.Route) error {
|
||||
handler := getHandlerName(route)
|
||||
if getHandlerFolderPath(group, route) != handlerDir {
|
||||
handler = strings.Title(handler)
|
||||
}
|
||||
parentPkg, err := getParentPackage(dir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return doGenToFile(dir, handler, cfg, group, route, handlerInfo{
|
||||
ImportPackages: genHandlerImports(group, route, parentPkg),
|
||||
ImportPackages: genHandlerImports(group, route, rootPkg),
|
||||
HandlerName: handler,
|
||||
RequestType: util.Title(route.RequestTypeName()),
|
||||
LogicType: strings.Title(getLogicName(route)),
|
||||
@@ -89,10 +85,10 @@ func doGenToFile(dir, handler string, cfg *config.Config, group spec.Group,
|
||||
})
|
||||
}
|
||||
|
||||
func genHandlers(dir string, cfg *config.Config, api *spec.ApiSpec) error {
|
||||
func genHandlers(dir, rootPkg string, cfg *config.Config, api *spec.ApiSpec) error {
|
||||
for _, group := range api.Service.Groups {
|
||||
for _, route := range group.Routes {
|
||||
if err := genHandler(dir, cfg, group, route); err != nil {
|
||||
if err := genHandler(dir, rootPkg, cfg, group, route); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,10 +39,10 @@ func (l *{{.logic}}) {{.function}}({{.request}}) {{.responseType}} {
|
||||
}
|
||||
`
|
||||
|
||||
func genLogic(dir string, cfg *config.Config, api *spec.ApiSpec) error {
|
||||
func genLogic(dir, rootPkg string, cfg *config.Config, api *spec.ApiSpec) error {
|
||||
for _, g := range api.Service.Groups {
|
||||
for _, r := range g.Routes {
|
||||
err := genLogicByRoute(dir, cfg, g, r)
|
||||
err := genLogicByRoute(dir, rootPkg, cfg, g, r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -51,19 +51,14 @@ func genLogic(dir string, cfg *config.Config, api *spec.ApiSpec) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func genLogicByRoute(dir string, cfg *config.Config, group spec.Group, route spec.Route) error {
|
||||
func genLogicByRoute(dir, rootPkg string, cfg *config.Config, group spec.Group, route spec.Route) error {
|
||||
logic := getLogicName(route)
|
||||
goFile, err := format.FileNamingFormat(cfg.NamingFormat, logic)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
parentPkg, err := getParentPackage(dir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
imports := genLogicImports(route, parentPkg)
|
||||
imports := genLogicImports(route, rootPkg)
|
||||
var responseString string
|
||||
var returnString string
|
||||
var requestString string
|
||||
|
||||
@@ -39,7 +39,7 @@ func main() {
|
||||
}
|
||||
`
|
||||
|
||||
func genMain(dir string, cfg *config.Config, api *spec.ApiSpec) error {
|
||||
func genMain(dir, rootPkg string, cfg *config.Config, api *spec.ApiSpec) error {
|
||||
name := strings.ToLower(api.Service.Name)
|
||||
if strings.HasSuffix(name, "-api") {
|
||||
name = strings.ReplaceAll(name, "-api", "")
|
||||
@@ -49,11 +49,6 @@ func genMain(dir string, cfg *config.Config, api *spec.ApiSpec) error {
|
||||
return err
|
||||
}
|
||||
|
||||
parentPkg, err := getParentPackage(dir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return genFile(fileGenConfig{
|
||||
dir: dir,
|
||||
subdir: "",
|
||||
@@ -63,7 +58,7 @@ func genMain(dir string, cfg *config.Config, api *spec.ApiSpec) error {
|
||||
templateFile: mainTemplateFile,
|
||||
builtinTemplate: mainTemplate,
|
||||
data: map[string]string{
|
||||
"importPackages": genMainImports(parentPkg),
|
||||
"importPackages": genMainImports(rootPkg),
|
||||
"serviceName": api.Service.Name,
|
||||
},
|
||||
})
|
||||
|
||||
@@ -62,7 +62,7 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
func genRoutes(dir string, cfg *config.Config, api *spec.ApiSpec) error {
|
||||
func genRoutes(dir, rootPkg string, cfg *config.Config, api *spec.ApiSpec) error {
|
||||
var builder strings.Builder
|
||||
groups, err := getRoutes(api)
|
||||
if err != nil {
|
||||
@@ -116,11 +116,6 @@ func genRoutes(dir string, cfg *config.Config, api *spec.ApiSpec) error {
|
||||
}
|
||||
}
|
||||
|
||||
parentPkg, err := getParentPackage(dir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
routeFilename, err := format.FileNamingFormat(cfg.NamingFormat, routesFilename)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -139,7 +134,7 @@ func genRoutes(dir string, cfg *config.Config, api *spec.ApiSpec) error {
|
||||
templateFile: "",
|
||||
builtinTemplate: routesTemplate,
|
||||
data: map[string]string{
|
||||
"importPackages": genRouteImports(parentPkg, api),
|
||||
"importPackages": genRouteImports(rootPkg, api),
|
||||
"routesAdditions": strings.TrimSpace(builder.String()),
|
||||
},
|
||||
})
|
||||
|
||||
@@ -33,7 +33,7 @@ func NewServiceContext(c {{.config}}) *ServiceContext {
|
||||
`
|
||||
)
|
||||
|
||||
func genServiceContext(dir string, cfg *config.Config, api *spec.ApiSpec) error {
|
||||
func genServiceContext(dir, rootPkg string, cfg *config.Config, api *spec.ApiSpec) error {
|
||||
filename, err := format.FileNamingFormat(cfg.NamingFormat, contextFilename)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -45,11 +45,6 @@ func genServiceContext(dir string, cfg *config.Config, api *spec.ApiSpec) error
|
||||
auths = append(auths, fmt.Sprintf("%s config.AuthConfig", item))
|
||||
}
|
||||
|
||||
parentPkg, err := getParentPackage(dir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var middlewareStr string
|
||||
var middlewareAssignment string
|
||||
middlewares := getMiddleware(api)
|
||||
@@ -61,9 +56,9 @@ func genServiceContext(dir string, cfg *config.Config, api *spec.ApiSpec) error
|
||||
fmt.Sprintf("middleware.New%s().%s", strings.Title(name), "Handle"))
|
||||
}
|
||||
|
||||
configImport := "\"" + ctlutil.JoinPackages(parentPkg, configDir) + "\""
|
||||
configImport := "\"" + ctlutil.JoinPackages(rootPkg, configDir) + "\""
|
||||
if len(middlewareStr) > 0 {
|
||||
configImport += "\n\t\"" + ctlutil.JoinPackages(parentPkg, middlewareDir) + "\""
|
||||
configImport += "\n\t\"" + ctlutil.JoinPackages(rootPkg, middlewareDir) + "\""
|
||||
configImport += fmt.Sprintf("\n\t\"%s/rest\"", vars.ProjectOpenSourceURL)
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ func (v *ApiVisitor) VisitApi(ctx *api.ApiContext) interface{} {
|
||||
return &final
|
||||
}
|
||||
|
||||
func (v *ApiVisitor) acceptService(root *Api, final *Api) {
|
||||
func (v *ApiVisitor) acceptService(root, final *Api) {
|
||||
for _, service := range root.Service {
|
||||
if _, ok := final.serviceM[service.ServiceApi.Name.Text()]; !ok && len(final.serviceM) > 0 {
|
||||
v.panic(service.ServiceApi.Name, fmt.Sprintf("mutiple service declaration"))
|
||||
@@ -104,7 +104,7 @@ func (v *ApiVisitor) duplicateServerItemCheck(service *Service) {
|
||||
}
|
||||
}
|
||||
|
||||
func (v *ApiVisitor) acceptType(root *Api, final *Api) {
|
||||
func (v *ApiVisitor) acceptType(root, final *Api) {
|
||||
for _, tp := range root.Type {
|
||||
if _, ok := final.typeM[tp.NameExpr().Text()]; ok {
|
||||
v.panic(tp.NameExpr(), fmt.Sprintf("duplicate type '%s'", tp.NameExpr().Text()))
|
||||
@@ -115,7 +115,7 @@ func (v *ApiVisitor) acceptType(root *Api, final *Api) {
|
||||
}
|
||||
}
|
||||
|
||||
func (v *ApiVisitor) acceptInfo(root *Api, final *Api) {
|
||||
func (v *ApiVisitor) acceptInfo(root, final *Api) {
|
||||
if root.Info != nil {
|
||||
infoM := map[string]PlaceHolder{}
|
||||
if final.Info != nil {
|
||||
@@ -133,7 +133,7 @@ func (v *ApiVisitor) acceptInfo(root *Api, final *Api) {
|
||||
}
|
||||
}
|
||||
|
||||
func (v *ApiVisitor) acceptImport(root *Api, final *Api) {
|
||||
func (v *ApiVisitor) acceptImport(root, final *Api) {
|
||||
for _, imp := range root.Import {
|
||||
if _, ok := final.importM[imp.Value.Text()]; ok {
|
||||
v.panic(imp.Import, fmt.Sprintf("duplicate import '%s'", imp.Value.Text()))
|
||||
@@ -144,7 +144,7 @@ func (v *ApiVisitor) acceptImport(root *Api, final *Api) {
|
||||
}
|
||||
}
|
||||
|
||||
func (v *ApiVisitor) acceptSyntax(root *Api, final *Api) {
|
||||
func (v *ApiVisitor) acceptSyntax(root, final *Api) {
|
||||
if root.Syntax != nil {
|
||||
if final.Syntax != nil {
|
||||
v.panic(root.Syntax.Syntax, fmt.Sprintf("mutiple syntax declaration"))
|
||||
|
||||
@@ -18,6 +18,7 @@ type (
|
||||
debug bool
|
||||
log console.Console
|
||||
antlr.DefaultErrorListener
|
||||
src string
|
||||
}
|
||||
|
||||
// ParserOption defines an function with argument Parser
|
||||
@@ -70,6 +71,12 @@ func (p *Parser) Accept(fn func(p *api.ApiParserParser, visitor *ApiVisitor) int
|
||||
|
||||
// Parse is used to parse the api from the specified file name
|
||||
func (p *Parser) Parse(filename string) (*Api, error) {
|
||||
abs, err := filepath.Abs(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p.src = abs
|
||||
data, err := p.readContent(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -79,8 +86,19 @@ func (p *Parser) Parse(filename string) (*Api, error) {
|
||||
}
|
||||
|
||||
// ParseContent is used to parse the api from the specified content
|
||||
func (p *Parser) ParseContent(content string) (*Api, error) {
|
||||
return p.parse("", content)
|
||||
func (p *Parser) ParseContent(content string, filename ...string) (*Api, error) {
|
||||
var f string
|
||||
if len(filename) > 0 {
|
||||
f = filename[0]
|
||||
abs, err := filepath.Abs(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p.src = abs
|
||||
}
|
||||
|
||||
return p.parse(f, content)
|
||||
}
|
||||
|
||||
// parse is used to parse api from the content
|
||||
@@ -94,7 +112,8 @@ func (p *Parser) parse(filename, content string) (*Api, error) {
|
||||
var apiAstList []*Api
|
||||
apiAstList = append(apiAstList, root)
|
||||
for _, imp := range root.Import {
|
||||
path := imp.Value.Text()
|
||||
dir := filepath.Dir(p.src)
|
||||
path := filepath.Join(dir, imp.Value.Text())
|
||||
data, err := p.readContent(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -158,7 +177,7 @@ func (p *Parser) invoke(linePrefix, content string) (v *Api, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (p *Parser) valid(mainApi *Api, nestedApi *Api) error {
|
||||
func (p *Parser) valid(mainApi, nestedApi *Api) error {
|
||||
err := p.nestedApiCheck(mainApi, nestedApi)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -218,7 +237,7 @@ func (p *Parser) valid(mainApi *Api, nestedApi *Api) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Parser) duplicateRouteCheck(nestedApi *Api, mainHandlerMap map[string]PlaceHolder, mainRouteMap map[string]PlaceHolder) error {
|
||||
func (p *Parser) duplicateRouteCheck(nestedApi *Api, mainHandlerMap, mainRouteMap map[string]PlaceHolder) error {
|
||||
for _, each := range nestedApi.Service {
|
||||
for _, r := range each.ServiceApi.ServiceRoute {
|
||||
handler := r.GetHandler()
|
||||
@@ -241,7 +260,7 @@ func (p *Parser) duplicateRouteCheck(nestedApi *Api, mainHandlerMap map[string]P
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Parser) nestedApiCheck(mainApi *Api, nestedApi *Api) error {
|
||||
func (p *Parser) nestedApiCheck(mainApi, nestedApi *Api) error {
|
||||
if len(nestedApi.Import) > 0 {
|
||||
importToken := nestedApi.Import[0].Import
|
||||
return fmt.Errorf("%s line %d:%d the nested api does not support import",
|
||||
@@ -415,12 +434,7 @@ func (p *Parser) checkType(linePrefix string, types map[string]TypeExpr, expr Da
|
||||
|
||||
func (p *Parser) readContent(filename string) (string, error) {
|
||||
filename = strings.ReplaceAll(filename, `"`, "")
|
||||
abs, err := filepath.Abs(filename)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadFile(abs)
|
||||
data, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
@@ -114,8 +114,10 @@ func (v *ApiVisitor) VisitTypeLit(ctx *api.TypeLitContext) interface{} {
|
||||
return alias
|
||||
}
|
||||
|
||||
doc := v.getDoc(ctx)
|
||||
st, ok := typeLit.(*TypeStruct)
|
||||
if ok {
|
||||
st.DocExpr = doc
|
||||
return st
|
||||
}
|
||||
|
||||
|
||||
@@ -34,9 +34,9 @@ func Parse(filename string) (*spec.ApiSpec, error) {
|
||||
}
|
||||
|
||||
// ParseContent parses the api content
|
||||
func ParseContent(content string) (*spec.ApiSpec, error) {
|
||||
func ParseContent(content string, filename ...string) (*spec.ApiSpec, error) {
|
||||
astParser := ast.NewParser()
|
||||
ast, err := astParser.ParseContent(content)
|
||||
ast, err := astParser.ParseContent(content, filename...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -76,14 +76,22 @@ func (p parser) fillInfo() {
|
||||
|
||||
func (p parser) fillSyntax() {
|
||||
if p.ast.Syntax != nil {
|
||||
p.spec.Syntax = spec.ApiSyntax{Version: p.ast.Syntax.Version.Text()}
|
||||
p.spec.Syntax = spec.ApiSyntax{
|
||||
Version: p.ast.Syntax.Version.Text(),
|
||||
Doc: p.stringExprs(p.ast.Syntax.DocExpr),
|
||||
Comment: p.stringExprs([]ast.Expr{p.ast.Syntax.CommentExpr}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p parser) fillImport() {
|
||||
if len(p.ast.Import) > 0 {
|
||||
for _, item := range p.ast.Import {
|
||||
p.spec.Imports = append(p.spec.Imports, spec.Import{Value: item.Value.Text()})
|
||||
p.spec.Imports = append(p.spec.Imports, spec.Import{
|
||||
Value: item.Value.Text(),
|
||||
Doc: p.stringExprs(item.DocExpr),
|
||||
Comment: p.stringExprs([]ast.Expr{item.CommentExpr}),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -173,10 +181,14 @@ func (p parser) astTypeToSpec(in ast.DataType) spec.Type {
|
||||
case *ast.Literal:
|
||||
raw := v.Literal.Text()
|
||||
if api.IsBasicType(raw) {
|
||||
return spec.PrimitiveType{RawName: raw}
|
||||
return spec.PrimitiveType{
|
||||
RawName: raw,
|
||||
}
|
||||
}
|
||||
|
||||
return spec.DefineStruct{RawName: raw}
|
||||
return spec.DefineStruct{
|
||||
RawName: raw,
|
||||
}
|
||||
case *ast.Interface:
|
||||
return spec.InterfaceType{RawName: v.Literal.Text()}
|
||||
case *ast.Map:
|
||||
@@ -198,6 +210,9 @@ func (p parser) astTypeToSpec(in ast.DataType) spec.Type {
|
||||
func (p parser) stringExprs(docs []ast.Expr) []string {
|
||||
var result []string
|
||||
for _, item := range docs {
|
||||
if item == nil {
|
||||
continue
|
||||
}
|
||||
result = append(result, item.Text())
|
||||
}
|
||||
return result
|
||||
@@ -222,9 +237,13 @@ func (p parser) fillService() error {
|
||||
AtServerAnnotation: spec.Annotation{},
|
||||
Method: astRoute.Route.Method.Text(),
|
||||
Path: astRoute.Route.Path.Text(),
|
||||
Doc: p.stringExprs(astRoute.Route.DocExpr),
|
||||
Comment: p.stringExprs([]ast.Expr{astRoute.Route.CommentExpr}),
|
||||
}
|
||||
if astRoute.AtHandler != nil {
|
||||
route.Handler = astRoute.AtHandler.Name.Text()
|
||||
route.HandlerDoc = append(route.HandlerDoc, p.stringExprs(astRoute.AtHandler.DocExpr)...)
|
||||
route.HandlerComment = append(route.HandlerComment, p.stringExprs([]ast.Expr{astRoute.AtHandler.CommentExpr})...)
|
||||
}
|
||||
|
||||
err := p.fillRouteAtServer(astRoute, &route)
|
||||
|
||||
28
tools/goctl/api/parser/parser_test.go
Normal file
28
tools/goctl/api/parser/parser_test.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/api/spec"
|
||||
)
|
||||
|
||||
var testApi = "// syntax doc\nsyntax = \"v1\" // syntax comment\n\n// type doc\ntype Request {\n\tName string `path:\"name,options=you|me\"`\n}\n\ntype Response {\n\tMessage string `json:\"message\"`\n}\n\n// service doc\nservice greet-api {\n\t// handler doc\n\t@handler GreetHandler // handler comment\n\tget /from/:name(Request) returns (Response);\n}"
|
||||
|
||||
func TestParseContent(t *testing.T) {
|
||||
sp, err := ParseContent(testApi)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, spec.Doc{`// syntax doc`}, sp.Syntax.Doc)
|
||||
assert.Equal(t, spec.Doc{`// syntax comment`}, sp.Syntax.Comment)
|
||||
for _, tp := range sp.Types {
|
||||
if tp.Name() == "Request" {
|
||||
assert.Equal(t, []string{`// type doc`}, tp.Documents())
|
||||
}
|
||||
}
|
||||
for _, e := range sp.Service.Routes() {
|
||||
if e.Handler == "GreetHandler" {
|
||||
assert.Equal(t, spec.Doc{"// handler doc"}, e.HandlerDoc)
|
||||
assert.Equal(t, spec.Doc{"// handler comment"}, e.HandlerComment)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,27 +5,87 @@ func (t PrimitiveType) Name() string {
|
||||
return t.RawName
|
||||
}
|
||||
|
||||
// Comments returns the comments of struct
|
||||
func (t PrimitiveType) Comments() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Documents returns the documents of struct
|
||||
func (t PrimitiveType) Documents() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Name returns a structure string, such as User
|
||||
func (t DefineStruct) Name() string {
|
||||
return t.RawName
|
||||
}
|
||||
|
||||
// Comments returns the comments of struct
|
||||
func (t DefineStruct) Comments() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Documents returns the documents of struct
|
||||
func (t DefineStruct) Documents() []string {
|
||||
return t.Docs
|
||||
}
|
||||
|
||||
// Name returns a map string, such as map[string]int
|
||||
func (t MapType) Name() string {
|
||||
return t.RawName
|
||||
}
|
||||
|
||||
// Comments returns the comments of struct
|
||||
func (t MapType) Comments() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Documents returns the documents of struct
|
||||
func (t MapType) Documents() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Name returns a slice string, such as []int
|
||||
func (t ArrayType) Name() string {
|
||||
return t.RawName
|
||||
}
|
||||
|
||||
// Comments returns the comments of struct
|
||||
func (t ArrayType) Comments() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Documents returns the documents of struct
|
||||
func (t ArrayType) Documents() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Name returns a pointer string, such as *User
|
||||
func (t PointerType) Name() string {
|
||||
return t.RawName
|
||||
}
|
||||
|
||||
// Comments returns the comments of struct
|
||||
func (t PointerType) Comments() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Documents returns the documents of struct
|
||||
func (t PointerType) Documents() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Name returns a interface string, Its fixed value is interface{}
|
||||
func (t InterfaceType) Name() string {
|
||||
return t.RawName
|
||||
}
|
||||
|
||||
// Comments returns the comments of struct
|
||||
func (t InterfaceType) Comments() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Documents returns the documents of struct
|
||||
func (t InterfaceType) Documents() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ type (
|
||||
// ApiSyntax describes the syntax grammar
|
||||
ApiSyntax struct {
|
||||
Version string
|
||||
Doc Doc
|
||||
Comment Doc
|
||||
}
|
||||
|
||||
// ApiSpec describes a api file
|
||||
@@ -25,7 +27,9 @@ type (
|
||||
|
||||
// Import describes api import
|
||||
Import struct {
|
||||
Value string
|
||||
Value string
|
||||
Doc Doc
|
||||
Comment Doc
|
||||
}
|
||||
|
||||
// Group defines a set of routing information
|
||||
@@ -71,6 +75,10 @@ type (
|
||||
Docs Doc
|
||||
Handler string
|
||||
AtDoc AtDoc
|
||||
HandlerDoc Doc
|
||||
HandlerComment Doc
|
||||
Doc Doc
|
||||
Comment Doc
|
||||
}
|
||||
|
||||
// Service describes api service
|
||||
@@ -82,6 +90,8 @@ type (
|
||||
// Type defines api type
|
||||
Type interface {
|
||||
Name() string
|
||||
Comments() []string
|
||||
Documents() []string
|
||||
}
|
||||
|
||||
// DefineStruct describes api structure
|
||||
|
||||
@@ -5,7 +5,9 @@ import (
|
||||
"os"
|
||||
"runtime"
|
||||
|
||||
"github.com/tal-tech/go-zero/core/load"
|
||||
"github.com/tal-tech/go-zero/core/logx"
|
||||
"github.com/tal-tech/go-zero/core/stat"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/api/apigen"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/api/dartgen"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/api/docgen"
|
||||
@@ -29,7 +31,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
buildVersion = "1.1.6"
|
||||
buildVersion = "1.1.8"
|
||||
commands = []cli.Command{
|
||||
{
|
||||
Name: "upgrade",
|
||||
@@ -531,6 +533,8 @@ var (
|
||||
|
||||
func main() {
|
||||
logx.Disable()
|
||||
load.Disable()
|
||||
stat.DisableLog()
|
||||
|
||||
app := cli.NewApp()
|
||||
app.Usage = "a cli tool to generate code"
|
||||
|
||||
@@ -54,8 +54,8 @@ type (
|
||||
|
||||
createRequest struct {
|
||||
innerType
|
||||
name string `form:"name"` // niha
|
||||
age int `form:"age,optional"` // nihaod
|
||||
name string `form:"name"`
|
||||
age int `form:"age,optional"`
|
||||
address []address `json:"address,optional"`
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"github.com/tal-tech/go-zero/core/stores/mongoc"
|
||||
)
|
||||
|
||||
{{if .Cache}}var prefix{{.Type}}CacheKey = "cache#{{.Type}}#"{{end}}
|
||||
{{if .Cache}}var prefix{{.Type}}CacheKey = "cache:{{.Type}}:"{{end}}
|
||||
|
||||
type {{.Type}}Model interface{
|
||||
Insert(ctx context.Context,data *{{.Type}}) error
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
-- 用户表 --
|
||||
CREATE TABLE `user` (
|
||||
`id` bigint(10) NOT NULL AUTO_INCREMENT,
|
||||
`user` varchar(50) NOT NULL DEFAULT '' COMMENT '用户',
|
||||
`name` varchar(255) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '用户名称',
|
||||
`password` varchar(255) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '用户密码',
|
||||
`mobile` varchar(255) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '手机号',
|
||||
`gender` char(5) COLLATE utf8mb4_general_ci NOT NULL COMMENT '男|女|未公开',
|
||||
`nickname` varchar(255) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '用户昵称',
|
||||
`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `name_index` (`name`),
|
||||
UNIQUE KEY `name_index2` (`name`),
|
||||
UNIQUE KEY `user_index` (`user`),
|
||||
UNIQUE KEY `mobile_index` (`mobile`)
|
||||
CREATE TABLE `user`
|
||||
(
|
||||
`id` bigint(10) NOT NULL AUTO_INCREMENT,
|
||||
`user` varchar(50) NOT NULL DEFAULT '' COMMENT '用户',
|
||||
`name` varchar(255) COLLATE utf8mb4_general_ci NULL COMMENT '用户\t名称',
|
||||
`password` varchar(255) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '用户\n密码',
|
||||
`mobile` varchar(255) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '手机号',
|
||||
`gender` char(5) COLLATE utf8mb4_general_ci NOT NULL COMMENT '男|女|未公\r开',
|
||||
`nickname` varchar(255) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '用户昵称',
|
||||
`create_time` timestamp NULL,
|
||||
`update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `name_index` (`name`),
|
||||
UNIQUE KEY `name_index2` (`name`),
|
||||
UNIQUE KEY `user_index` (`user`),
|
||||
UNIQUE KEY `mobile_index` (`mobile`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
CREATE TABLE `student` (
|
||||
|
||||
@@ -13,9 +13,9 @@ import (
|
||||
type Key struct {
|
||||
// VarLeft describes the variable of cache key expression which likes cacheUserIdPrefix
|
||||
VarLeft string
|
||||
// VarRight describes the value of cache key expression which likes "cache#user#id#"
|
||||
// VarRight describes the value of cache key expression which likes "cache:user:id:"
|
||||
VarRight string
|
||||
// VarExpression describes the cache key expression which likes cacheUserIdPrefix = "cache#user#id#"
|
||||
// VarExpression describes the cache key expression which likes cacheUserIdPrefix = "cache:user:id:"
|
||||
VarExpression string
|
||||
// KeyLeft describes the variable of key definition expression which likes userKey
|
||||
KeyLeft string
|
||||
@@ -76,12 +76,12 @@ func genCacheKey(table stringx.String, in []*parser.Field) Key {
|
||||
keyLeftJoin = append(keyLeftJoin, "key")
|
||||
|
||||
varLeft = varLeftJoin.Camel().With("").Untitle()
|
||||
varRight = fmt.Sprintf(`"%s"`, varRightJon.Camel().Untitle().With("#").Source()+"#")
|
||||
varRight = fmt.Sprintf(`"%s"`, varRightJon.Camel().Untitle().With(":").Source()+":")
|
||||
varExpression = fmt.Sprintf(`%s = %s`, varLeft, varRight)
|
||||
|
||||
keyLeft = keyLeftJoin.Camel().With("").Untitle()
|
||||
keyRight = fmt.Sprintf(`fmt.Sprintf("%s%s", %s, %s)`, "%s", keyRightArgJoin.With("").Source(), varLeft, keyRightJoin.With(", ").Source())
|
||||
dataKeyRight = fmt.Sprintf(`fmt.Sprintf("%s%s", %s, %s)`, "%s", keyRightArgJoin.With("").Source(), varLeft, dataRightJoin.With(", ").Source())
|
||||
keyRight = fmt.Sprintf(`fmt.Sprintf("%s%s", %s, %s)`, "%s", keyRightArgJoin.With(":").Source(), varLeft, keyRightJoin.With(", ").Source())
|
||||
dataKeyRight = fmt.Sprintf(`fmt.Sprintf("%s%s", %s, %s)`, "%s", keyRightArgJoin.With(":").Source(), varLeft, dataRightJoin.With(", ").Source())
|
||||
keyExpression = fmt.Sprintf("%s := %s", keyLeft, keyRight)
|
||||
dataKeyExpression = fmt.Sprintf("%s := %s", keyLeft, dataKeyRight)
|
||||
|
||||
|
||||
@@ -78,8 +78,8 @@ func TestGenCacheKeys(t *testing.T) {
|
||||
assert.Equal(t, true, func() bool {
|
||||
return cacheKeyEqual(primariCacheKey, Key{
|
||||
VarLeft: "cacheUserIdPrefix",
|
||||
VarRight: `"cache#user#id#"`,
|
||||
VarExpression: `cacheUserIdPrefix = "cache#user#id#"`,
|
||||
VarRight: `"cache:user:id:"`,
|
||||
VarExpression: `cacheUserIdPrefix = "cache:user:id:"`,
|
||||
KeyLeft: "userIdKey",
|
||||
KeyRight: `fmt.Sprintf("%s%v", cacheUserIdPrefix, id)`,
|
||||
DataKeyRight: `fmt.Sprintf("%s%v", cacheUserIdPrefix, data.Id)`,
|
||||
@@ -95,19 +95,19 @@ func TestGenCacheKeys(t *testing.T) {
|
||||
expected := []Key{
|
||||
{
|
||||
VarLeft: "cacheUserClassNamePrefix",
|
||||
VarRight: `"cache#user#class#name#"`,
|
||||
VarExpression: `cacheUserClassNamePrefix = "cache#user#class#name#"`,
|
||||
VarRight: `"cache:user:class:name:"`,
|
||||
VarExpression: `cacheUserClassNamePrefix = "cache:user:class:name:"`,
|
||||
KeyLeft: "userClassNameKey",
|
||||
KeyRight: `fmt.Sprintf("%s%v%v", cacheUserClassNamePrefix, class, name)`,
|
||||
DataKeyRight: `fmt.Sprintf("%s%v%v", cacheUserClassNamePrefix, data.Class, data.Name)`,
|
||||
KeyExpression: `userClassNameKey := fmt.Sprintf("%s%v%v", cacheUserClassNamePrefix, class, name)`,
|
||||
DataKeyExpression: `userClassNameKey := fmt.Sprintf("%s%v%v", cacheUserClassNamePrefix, data.Class, data.Name)`,
|
||||
KeyRight: `fmt.Sprintf("%s%v:%v", cacheUserClassNamePrefix, class, name)`,
|
||||
DataKeyRight: `fmt.Sprintf("%s%v:%v", cacheUserClassNamePrefix, data.Class, data.Name)`,
|
||||
KeyExpression: `userClassNameKey := fmt.Sprintf("%s%v:%v", cacheUserClassNamePrefix, class, name)`,
|
||||
DataKeyExpression: `userClassNameKey := fmt.Sprintf("%s%v:%v", cacheUserClassNamePrefix, data.Class, data.Name)`,
|
||||
FieldNameJoin: []string{"class", "name"},
|
||||
},
|
||||
{
|
||||
VarLeft: "cacheUserMobilePrefix",
|
||||
VarRight: `"cache#user#mobile#"`,
|
||||
VarExpression: `cacheUserMobilePrefix = "cache#user#mobile#"`,
|
||||
VarRight: `"cache:user:mobile:"`,
|
||||
VarExpression: `cacheUserMobilePrefix = "cache:user:mobile:"`,
|
||||
KeyLeft: "userMobileKey",
|
||||
KeyRight: `fmt.Sprintf("%s%v", cacheUserMobilePrefix, mobile)`,
|
||||
DataKeyRight: `fmt.Sprintf("%s%v", cacheUserMobilePrefix, data.Mobile)`,
|
||||
@@ -136,7 +136,7 @@ func TestGenCacheKeys(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func cacheKeyEqual(k1 Key, k2 Key) bool {
|
||||
func cacheKeyEqual(k1, k2 Key) bool {
|
||||
k1Join := k1.FieldNameJoin
|
||||
k2Join := k2.FieldNameJoin
|
||||
sort.Strings(k1Join)
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"sort"
|
||||
|
||||
"github.com/tal-tech/go-zero/core/stores/sqlx"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/model/sql/util"
|
||||
)
|
||||
|
||||
const indexPri = "PRIMARY"
|
||||
@@ -151,6 +152,7 @@ func (c *ColumnData) Convert() (*Table, error) {
|
||||
|
||||
m := make(map[string][]*Column)
|
||||
for _, each := range c.Columns {
|
||||
each.Comment = util.TrimNewLine(each.Comment)
|
||||
if each.Index != nil {
|
||||
m[each.Index.IndexName] = append(m[each.Index.IndexName], each)
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/tal-tech/go-zero/core/collection"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/model/sql/converter"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/model/sql/model"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/model/sql/util"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/util/console"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/util/stringx"
|
||||
"github.com/xwb1989/sqlparser"
|
||||
@@ -169,9 +170,7 @@ func convertColumns(columns []*sqlparser.ColumnDefinition, primaryColumn string)
|
||||
if column.Type.NotNull {
|
||||
isDefaultNull = false
|
||||
} else {
|
||||
if column.Type.Default == nil {
|
||||
isDefaultNull = false
|
||||
} else if string(column.Type.Default.Val) != "null" {
|
||||
if column.Type.Default != nil {
|
||||
isDefaultNull = false
|
||||
}
|
||||
}
|
||||
@@ -185,7 +184,7 @@ func convertColumns(columns []*sqlparser.ColumnDefinition, primaryColumn string)
|
||||
field.Name = stringx.From(column.Name.String())
|
||||
field.DataBaseType = column.Type.Type
|
||||
field.DataType = dataType
|
||||
field.Comment = comment
|
||||
field.Comment = util.TrimNewLine(comment)
|
||||
|
||||
if field.Name.Source() == primaryColumn {
|
||||
primaryKey = Primary{
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/model/sql/model"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/model/sql/util"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/util/stringx"
|
||||
)
|
||||
|
||||
@@ -20,7 +21,7 @@ func TestParseSelect(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestParseCreateTable(t *testing.T) {
|
||||
table, err := Parse("CREATE TABLE `test_user` (\n `id` bigint NOT NULL AUTO_INCREMENT,\n `mobile` varchar(255) COLLATE utf8mb4_bin NOT NULL,\n `class` bigint NOT NULL,\n `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,\n `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,\n `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,\n PRIMARY KEY (`id`),\n UNIQUE KEY `mobile_unique` (`mobile`),\n UNIQUE KEY `class_name_unique` (`class`,`name`),\n KEY `create_index` (`create_time`),\n KEY `name_index` (`name`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;")
|
||||
table, err := Parse("CREATE TABLE `test_user` (\n `id` bigint NOT NULL AUTO_INCREMENT,\n `mobile` varchar(255) COLLATE utf8mb4_bin NOT NULL comment '手\\t机 号',\n `class` bigint NOT NULL comment '班级',\n `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL comment '姓\n 名',\n `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP comment '创建\\r时间',\n `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,\n PRIMARY KEY (`id`),\n UNIQUE KEY `mobile_unique` (`mobile`),\n UNIQUE KEY `class_name_unique` (`class`,`name`),\n KEY `create_index` (`create_time`),\n KEY `name_index` (`name`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "test_user", table.Name.Source())
|
||||
assert.Equal(t, "id", table.PrimaryKey.Name.Source())
|
||||
@@ -82,6 +83,15 @@ func TestParseCreateTable(t *testing.T) {
|
||||
},
|
||||
})
|
||||
}())
|
||||
assert.True(t, func() bool {
|
||||
for _, e := range table.Fields {
|
||||
if e.Comment != util.TrimNewLine(e.Comment) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}())
|
||||
}
|
||||
|
||||
func TestConvertColumn(t *testing.T) {
|
||||
|
||||
@@ -28,7 +28,7 @@ type (
|
||||
StudentModel interface {
|
||||
Insert(data Student) (sql.Result, error)
|
||||
FindOne(id int64) (*Student, error)
|
||||
FindOneByClassName(class string, name string) (*Student, error)
|
||||
FindOneByClassName(class, name string) (*Student, error)
|
||||
Update(data Student) error
|
||||
// only for test
|
||||
Delete(id int64, className, studentName string) error
|
||||
@@ -85,7 +85,7 @@ func (m *defaultStudentModel) FindOne(id int64) (*Student, error) {
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultStudentModel) FindOneByClassName(class string, name string) (*Student, error) {
|
||||
func (m *defaultStudentModel) FindOneByClassName(class, name string) (*Student, error) {
|
||||
studentClassNameKey := fmt.Sprintf("%s%v%v", cacheStudentClassNamePrefix, class, name)
|
||||
var resp Student
|
||||
err := m.QueryRowIndex(&resp, studentClassNameKey, m.formatPrimary, func(conn sqlx.SqlConn, v interface{}) (i interface{}, e error) {
|
||||
|
||||
8
tools/goctl/model/sql/util/newline.go
Normal file
8
tools/goctl/model/sql/util/newline.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package util
|
||||
|
||||
import "strings"
|
||||
|
||||
// TrimNewLine trims \r and \n chars.
|
||||
func TrimNewLine(s string) string {
|
||||
return strings.NewReplacer("\r", "", "\n", "").Replace(s)
|
||||
}
|
||||
@@ -136,7 +136,7 @@ func getCommand(arg string) (string, bool, error) {
|
||||
return arg, false, nil
|
||||
}
|
||||
|
||||
func downloadFile(filepath string, url string) error {
|
||||
func downloadFile(filepath, url string) error {
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
// Run provides the execution of shell scripts in golang,
|
||||
// which can support macOS, Windows, and Linux operating systems.
|
||||
// Other operating systems are currently not supported
|
||||
func Run(arg string, dir string, in ...*bytes.Buffer) (string, error) {
|
||||
func Run(arg, dir string, in ...*bytes.Buffer) (string, error) {
|
||||
goos := runtime.GOOS
|
||||
var cmd *exec.Cmd
|
||||
switch goos {
|
||||
|
||||
@@ -64,8 +64,13 @@ func (g *DefaultGenerator) GenMain(ctx DirContext, proto parser.Proto, cfg *conf
|
||||
return err
|
||||
}
|
||||
|
||||
etcFileName, err := format.FileNamingFormat(cfg.NamingFormat, ctx.GetServiceName().Source())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return util.With("main").GoFmt(true).Parse(text).SaveTo(map[string]interface{}{
|
||||
"serviceName": strings.ToLower(ctx.GetServiceName().ToCamel()),
|
||||
"serviceName": etcFileName,
|
||||
"imports": strings.Join(imports, util.NL),
|
||||
"pkg": proto.PbPackage,
|
||||
"serviceNew": stringx.From(proto.Service.Name).ToCamel(),
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package p2c
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/rand"
|
||||
@@ -32,25 +31,24 @@ const (
|
||||
logInterval = time.Minute
|
||||
)
|
||||
|
||||
var emptyPickResult balancer.PickResult
|
||||
|
||||
func init() {
|
||||
balancer.Register(newBuilder())
|
||||
}
|
||||
|
||||
type p2cPickerBuilder struct{}
|
||||
|
||||
func newBuilder() balancer.Builder {
|
||||
return base.NewBalancerBuilder(Name, new(p2cPickerBuilder))
|
||||
}
|
||||
|
||||
func (b *p2cPickerBuilder) Build(readySCs map[resolver.Address]balancer.SubConn) balancer.Picker {
|
||||
func (b *p2cPickerBuilder) Build(info base.PickerBuildInfo) balancer.Picker {
|
||||
readySCs := info.ReadySCs
|
||||
if len(readySCs) == 0 {
|
||||
return base.NewErrPicker(balancer.ErrNoSubConnAvailable)
|
||||
}
|
||||
|
||||
var conns []*subConn
|
||||
for addr, conn := range readySCs {
|
||||
for conn, connInfo := range readySCs {
|
||||
conns = append(conns, &subConn{
|
||||
addr: addr,
|
||||
addr: connInfo.Address,
|
||||
conn: conn,
|
||||
success: initSuccess,
|
||||
})
|
||||
@@ -63,6 +61,10 @@ func (b *p2cPickerBuilder) Build(readySCs map[resolver.Address]balancer.SubConn)
|
||||
}
|
||||
}
|
||||
|
||||
func newBuilder() balancer.Builder {
|
||||
return base.NewBalancerBuilder(Name, new(p2cPickerBuilder), base.Config{HealthCheck: true})
|
||||
}
|
||||
|
||||
type p2cPicker struct {
|
||||
conns []*subConn
|
||||
r *rand.Rand
|
||||
@@ -70,15 +72,14 @@ type p2cPicker struct {
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
func (p *p2cPicker) Pick(ctx context.Context, info balancer.PickInfo) (
|
||||
conn balancer.SubConn, done func(balancer.DoneInfo), err error) {
|
||||
func (p *p2cPicker) Pick(info balancer.PickInfo) (balancer.PickResult, error) {
|
||||
p.lock.Lock()
|
||||
defer p.lock.Unlock()
|
||||
|
||||
var chosen *subConn
|
||||
switch len(p.conns) {
|
||||
case 0:
|
||||
return nil, nil, balancer.ErrNoSubConnAvailable
|
||||
return emptyPickResult, balancer.ErrNoSubConnAvailable
|
||||
case 1:
|
||||
chosen = p.choose(p.conns[0], nil)
|
||||
case 2:
|
||||
@@ -103,7 +104,11 @@ func (p *p2cPicker) Pick(ctx context.Context, info balancer.PickInfo) (
|
||||
|
||||
atomic.AddInt64(&chosen.inflight, 1)
|
||||
atomic.AddInt64(&chosen.requests, 1)
|
||||
return chosen.conn, p.buildDoneFunc(chosen), nil
|
||||
|
||||
return balancer.PickResult{
|
||||
SubConn: chosen.conn,
|
||||
Done: p.buildDoneFunc(chosen),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *p2cPicker) buildDoneFunc(c *subConn) func(info balancer.DoneInfo) {
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/tal-tech/go-zero/core/logx"
|
||||
"github.com/tal-tech/go-zero/core/mathx"
|
||||
"google.golang.org/grpc/balancer"
|
||||
"google.golang.org/grpc/balancer/base"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/resolver"
|
||||
"google.golang.org/grpc/status"
|
||||
@@ -23,8 +24,8 @@ func init() {
|
||||
|
||||
func TestP2cPicker_PickNil(t *testing.T) {
|
||||
builder := new(p2cPickerBuilder)
|
||||
picker := builder.Build(nil)
|
||||
_, _, err := picker.Pick(context.Background(), balancer.PickInfo{
|
||||
picker := builder.Build(base.PickerBuildInfo{})
|
||||
_, err := picker.Pick(balancer.PickInfo{
|
||||
FullMethodName: "/",
|
||||
Ctx: context.Background(),
|
||||
})
|
||||
@@ -61,18 +62,22 @@ func TestP2cPicker_Pick(t *testing.T) {
|
||||
|
||||
const total = 10000
|
||||
builder := new(p2cPickerBuilder)
|
||||
ready := make(map[resolver.Address]balancer.SubConn)
|
||||
ready := make(map[balancer.SubConn]base.SubConnInfo)
|
||||
for i := 0; i < test.candidates; i++ {
|
||||
ready[resolver.Address{
|
||||
Addr: strconv.Itoa(i),
|
||||
}] = new(mockClientConn)
|
||||
ready[new(mockClientConn)] = base.SubConnInfo{
|
||||
Address: resolver.Address{
|
||||
Addr: strconv.Itoa(i),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
picker := builder.Build(ready)
|
||||
picker := builder.Build(base.PickerBuildInfo{
|
||||
ReadySCs: ready,
|
||||
})
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(total)
|
||||
for i := 0; i < total; i++ {
|
||||
_, done, err := picker.Pick(context.Background(), balancer.PickInfo{
|
||||
result, err := picker.Pick(balancer.PickInfo{
|
||||
FullMethodName: "/",
|
||||
Ctx: context.Background(),
|
||||
})
|
||||
@@ -82,7 +87,7 @@ func TestP2cPicker_Pick(t *testing.T) {
|
||||
}
|
||||
go func() {
|
||||
runtime.Gosched()
|
||||
done(balancer.DoneInfo{
|
||||
result.Done(balancer.DoneInfo{
|
||||
Err: err,
|
||||
})
|
||||
wg.Done()
|
||||
|
||||
@@ -92,7 +92,7 @@ func (c *client) dial(server string, opts ...ClientOption) error {
|
||||
service = server[pos+1:]
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("rpc dial: %s, error: %s, make sure rpc service %q is alread started",
|
||||
return fmt.Errorf("rpc dial: %s, error: %s, make sure rpc service %q is already started",
|
||||
server, err.Error(), service)
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,9 @@ type mockedClientConn struct {
|
||||
state resolver.State
|
||||
}
|
||||
|
||||
func (m *mockedClientConn) UpdateState(state resolver.State) {
|
||||
func (m *mockedClientConn) UpdateState(state resolver.State) error {
|
||||
m.state = state
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockedClientConn) ReportError(err error) {
|
||||
|
||||
Reference in New Issue
Block a user