* move examples
pull/749/head
Tony Chen 4 years ago committed by GitHub
parent 8722894939
commit 98b5903113
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      .github/workflows/go.yml
  2. 21
      examples/LICENSE
  3. 1
      examples/README.md
  4. 36
      examples/blog/.gitignore
  5. 21
      examples/blog/LICENSE
  6. 46
      examples/blog/Makefile
  7. 28
      examples/blog/README.md
  8. 865
      examples/blog/api/blog/v1/blog.pb.go
  9. 86
      examples/blog/api/blog/v1/blog.proto
  10. 245
      examples/blog/api/blog/v1/blog_grpc.pb.go
  11. 177
      examples/blog/api/blog/v1/blog_http.pb.go
  12. 142
      examples/blog/api/blog/v1/errors/article.pb.go
  13. 18
      examples/blog/api/blog/v1/errors/article.proto
  14. 24
      examples/blog/api/blog/v1/errors/article_errors.pb.go
  15. 101
      examples/blog/cmd/blog/main.go
  16. 21
      examples/blog/cmd/blog/wire.go
  17. 33
      examples/blog/cmd/blog/wire_gen.go
  18. 16
      examples/blog/configs/config.yaml
  19. 1
      examples/blog/internal/biz/README.md
  20. 73
      examples/blog/internal/biz/article.go
  21. 6
      examples/blog/internal/biz/biz.go
  22. 691
      examples/blog/internal/conf/conf.pb.go
  23. 44
      examples/blog/internal/conf/conf.proto
  24. 5
      examples/blog/internal/data/README.md
  25. 79
      examples/blog/internal/data/article.go
  26. 55
      examples/blog/internal/data/data.go
  27. 174
      examples/blog/internal/data/ent/article.go
  28. 74
      examples/blog/internal/data/ent/article/article.go
  29. 584
      examples/blog/internal/data/ent/article/where.go
  30. 350
      examples/blog/internal/data/ent/article_create.go
  31. 108
      examples/blog/internal/data/ent/article_delete.go
  32. 1068
      examples/blog/internal/data/ent/article_query.go
  33. 711
      examples/blog/internal/data/ent/article_update.go
  34. 465
      examples/blog/internal/data/ent/client.go
  35. 174
      examples/blog/internal/data/ent/comment.go
  36. 71
      examples/blog/internal/data/ent/comment/comment.go
  37. 556
      examples/blog/internal/data/ent/comment/where.go
  38. 319
      examples/blog/internal/data/ent/comment_create.go
  39. 108
      examples/blog/internal/data/ent/comment_delete.go
  40. 970
      examples/blog/internal/data/ent/comment_query.go
  41. 470
      examples/blog/internal/data/ent/comment_update.go
  42. 61
      examples/blog/internal/data/ent/config.go
  43. 33
      examples/blog/internal/data/ent/context.go
  44. 270
      examples/blog/internal/data/ent/ent.go
  45. 78
      examples/blog/internal/data/ent/enttest/enttest.go
  46. 230
      examples/blog/internal/data/ent/hook/hook.go
  47. 72
      examples/blog/internal/data/ent/migrate/migrate.go
  48. 105
      examples/blog/internal/data/ent/migrate/schema.go
  49. 1731
      examples/blog/internal/data/ent/mutation.go
  50. 16
      examples/blog/internal/data/ent/predicate/predicate.go
  51. 48
      examples/blog/internal/data/ent/runtime.go
  52. 10
      examples/blog/internal/data/ent/runtime/runtime.go
  53. 40
      examples/blog/internal/data/ent/schema/article.go
  54. 40
      examples/blog/internal/data/ent/schema/comment.go
  55. 38
      examples/blog/internal/data/ent/schema/tag.go
  56. 158
      examples/blog/internal/data/ent/tag.go
  57. 65
      examples/blog/internal/data/ent/tag/tag.go
  58. 556
      examples/blog/internal/data/ent/tag/where.go
  59. 315
      examples/blog/internal/data/ent/tag_create.go
  60. 108
      examples/blog/internal/data/ent/tag_delete.go
  61. 1002
      examples/blog/internal/data/ent/tag_query.go
  62. 530
      examples/blog/internal/data/ent/tag_update.go
  63. 216
      examples/blog/internal/data/ent/tx.go
  64. 25
      examples/blog/internal/data/redis.go
  65. 39
      examples/blog/internal/server/grpc.go
  66. 36
      examples/blog/internal/server/http.go
  67. 8
      examples/blog/internal/server/server.go
  68. 1
      examples/blog/internal/service/README.md
  69. 66
      examples/blog/internal/service/article.go
  70. 20
      examples/blog/internal/service/service.go
  71. 79
      examples/blog/pkg/middleware/trace.go
  72. 11
      examples/config/config.yaml
  73. 57
      examples/config/main.go
  74. 28
      examples/gin/main.go
  75. 33
      examples/go.mod
  76. 715
      examples/go.sum
  77. 77
      examples/helloworld/client/main.go
  78. 226
      examples/helloworld/helloworld/helloworld.pb.go
  79. 27
      examples/helloworld/helloworld/helloworld.proto
  80. 103
      examples/helloworld/helloworld/helloworld_grpc.pb.go
  81. 62
      examples/helloworld/helloworld/helloworld_http.pb.go
  82. 75
      examples/helloworld/server/main.go
  83. 30
      examples/mux/main.go

@ -46,3 +46,9 @@ jobs:
cd cmd/protoc-gen-go-errors
go build ./...
go test ./...
- name: Examples
run: |
cd examples
go build ./...
go test ./...

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 Kratos
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -0,0 +1 @@
# examples

@ -0,0 +1,36 @@
# Reference https://github.com/github/gitignore/blob/master/Go.gitignore
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, built with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Dependency directories (remove the comment below to include it)
vendor/
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# OS General
Thumbs.db
.DS_Store
# project
*.cert
*.key
*.log
bin/
# Develop tools
.vscode/
.idea/
*.swp

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 go-kratos
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -0,0 +1,46 @@
GOPATH:=$(shell go env GOPATH)
VERSION=$(shell git describe --tags --always)
PROTO_FILES=$(shell find . -name *.proto)
KRATOS_VERSION=$(shell go mod graph |grep go-kratos/kratos/v2 |head -n 1 |awk -F '@' '{print $$2}')
KRATOS=$(GOPATH)/pkg/mod/github.com/go-kratos/kratos/v2@$(KRATOS_VERSION)
.PHONY: init
init:
go get -u github.com/go-kratos/kratos/cmd/kratos/v2
go get -u github.com/go-kratos/kratos/cmd/protoc-gen-go-http/v2
go get -u github.com/go-kratos/kratos/cmd/protoc-gen-go-errors/v2
go get -u google.golang.org/protobuf/cmd/protoc-gen-go
go get -u google.golang.org/grpc/cmd/protoc-gen-go-grpc
.PHONY: proto
proto:
protoc --proto_path=. \
--proto_path=$(KRATOS)/api \
--proto_path=$(KRATOS)/third_party \
--proto_path=$(GOPATH)/src \
--go_out=paths=source_relative:. \
--go-grpc_out=paths=source_relative:. \
--go-http_out=paths=source_relative:. \
--go-errors_out=paths=source_relative:. $(PROTO_FILES)
.PHONY: run
run:
cd cmd/blog/ && go run .
.PHONY: ent
ent:
cd internal/data/ && ent generate ./ent/schema
.PHONY: build
build:
mkdir -p bin/ && go build -ldflags "-X main.Version=$(VERSION)" -o ./bin/ ./...
.PHONY: wire
wire:
cd cmd/blog/ && wire
.PHONY: test
test:
go test -v ./... -cover

@ -0,0 +1,28 @@
# Kratos Layout
## Install Kratos
```
go get github.com/go-kratos/kratos/cmd/kratos
go get github.com/go-kratos/kratos/cmd/protoc-gen-go-http
go get github.com/go-kratos/kratos/cmd/protoc-gen-go-errors
# from source
cd cmd/kratos && go install
cd cmd/protoc-gen-go-http && go install
cd cmd/protoc-gen-go-errors && go install
```
## Create a service
```
# create a template project
kratos new helloworld
cd helloworld
# Add a proto template
kratos proto add api/helloworld/helloworld.proto
# Generate the source code of service by proto file
kratos proto service api/helloworld/helloworld.proto -t internal/service
make proto
make build
make test
```

@ -0,0 +1,865 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.13.0
// source: api/blog/v1/blog.proto
package v1
import (
proto "github.com/golang/protobuf/proto"
_ "google.golang.org/genproto/googleapis/api/annotations"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4
type Article struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
Title string `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"`
Content string `protobuf:"bytes,3,opt,name=content,proto3" json:"content,omitempty"`
Like int64 `protobuf:"varint,4,opt,name=like,proto3" json:"like,omitempty"`
}
func (x *Article) Reset() {
*x = Article{}
if protoimpl.UnsafeEnabled {
mi := &file_api_blog_v1_blog_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Article) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Article) ProtoMessage() {}
func (x *Article) ProtoReflect() protoreflect.Message {
mi := &file_api_blog_v1_blog_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Article.ProtoReflect.Descriptor instead.
func (*Article) Descriptor() ([]byte, []int) {
return file_api_blog_v1_blog_proto_rawDescGZIP(), []int{0}
}
func (x *Article) GetId() int64 {
if x != nil {
return x.Id
}
return 0
}
func (x *Article) GetTitle() string {
if x != nil {
return x.Title
}
return ""
}
func (x *Article) GetContent() string {
if x != nil {
return x.Content
}
return ""
}
func (x *Article) GetLike() int64 {
if x != nil {
return x.Like
}
return 0
}
type CreateArticleRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"`
Content string `protobuf:"bytes,2,opt,name=content,proto3" json:"content,omitempty"`
}
func (x *CreateArticleRequest) Reset() {
*x = CreateArticleRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_blog_v1_blog_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CreateArticleRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CreateArticleRequest) ProtoMessage() {}
func (x *CreateArticleRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_blog_v1_blog_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CreateArticleRequest.ProtoReflect.Descriptor instead.
func (*CreateArticleRequest) Descriptor() ([]byte, []int) {
return file_api_blog_v1_blog_proto_rawDescGZIP(), []int{1}
}
func (x *CreateArticleRequest) GetTitle() string {
if x != nil {
return x.Title
}
return ""
}
func (x *CreateArticleRequest) GetContent() string {
if x != nil {
return x.Content
}
return ""
}
type CreateArticleReply struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Article *Article `protobuf:"bytes,1,opt,name=Article,proto3" json:"Article,omitempty"`
}
func (x *CreateArticleReply) Reset() {
*x = CreateArticleReply{}
if protoimpl.UnsafeEnabled {
mi := &file_api_blog_v1_blog_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CreateArticleReply) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CreateArticleReply) ProtoMessage() {}
func (x *CreateArticleReply) ProtoReflect() protoreflect.Message {
mi := &file_api_blog_v1_blog_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CreateArticleReply.ProtoReflect.Descriptor instead.
func (*CreateArticleReply) Descriptor() ([]byte, []int) {
return file_api_blog_v1_blog_proto_rawDescGZIP(), []int{2}
}
func (x *CreateArticleReply) GetArticle() *Article {
if x != nil {
return x.Article
}
return nil
}
type UpdateArticleRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
Title string `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"`
Content string `protobuf:"bytes,3,opt,name=content,proto3" json:"content,omitempty"`
}
func (x *UpdateArticleRequest) Reset() {
*x = UpdateArticleRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_blog_v1_blog_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *UpdateArticleRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UpdateArticleRequest) ProtoMessage() {}
func (x *UpdateArticleRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_blog_v1_blog_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use UpdateArticleRequest.ProtoReflect.Descriptor instead.
func (*UpdateArticleRequest) Descriptor() ([]byte, []int) {
return file_api_blog_v1_blog_proto_rawDescGZIP(), []int{3}
}
func (x *UpdateArticleRequest) GetId() int64 {
if x != nil {
return x.Id
}
return 0
}
func (x *UpdateArticleRequest) GetTitle() string {
if x != nil {
return x.Title
}
return ""
}
func (x *UpdateArticleRequest) GetContent() string {
if x != nil {
return x.Content
}
return ""
}
type UpdateArticleReply struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Article *Article `protobuf:"bytes,1,opt,name=Article,proto3" json:"Article,omitempty"`
}
func (x *UpdateArticleReply) Reset() {
*x = UpdateArticleReply{}
if protoimpl.UnsafeEnabled {
mi := &file_api_blog_v1_blog_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *UpdateArticleReply) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UpdateArticleReply) ProtoMessage() {}
func (x *UpdateArticleReply) ProtoReflect() protoreflect.Message {
mi := &file_api_blog_v1_blog_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use UpdateArticleReply.ProtoReflect.Descriptor instead.
func (*UpdateArticleReply) Descriptor() ([]byte, []int) {
return file_api_blog_v1_blog_proto_rawDescGZIP(), []int{4}
}
func (x *UpdateArticleReply) GetArticle() *Article {
if x != nil {
return x.Article
}
return nil
}
type DeleteArticleRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
}
func (x *DeleteArticleRequest) Reset() {
*x = DeleteArticleRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_blog_v1_blog_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *DeleteArticleRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*DeleteArticleRequest) ProtoMessage() {}
func (x *DeleteArticleRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_blog_v1_blog_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use DeleteArticleRequest.ProtoReflect.Descriptor instead.
func (*DeleteArticleRequest) Descriptor() ([]byte, []int) {
return file_api_blog_v1_blog_proto_rawDescGZIP(), []int{5}
}
func (x *DeleteArticleRequest) GetId() int64 {
if x != nil {
return x.Id
}
return 0
}
type DeleteArticleReply struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *DeleteArticleReply) Reset() {
*x = DeleteArticleReply{}
if protoimpl.UnsafeEnabled {
mi := &file_api_blog_v1_blog_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *DeleteArticleReply) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*DeleteArticleReply) ProtoMessage() {}
func (x *DeleteArticleReply) ProtoReflect() protoreflect.Message {
mi := &file_api_blog_v1_blog_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use DeleteArticleReply.ProtoReflect.Descriptor instead.
func (*DeleteArticleReply) Descriptor() ([]byte, []int) {
return file_api_blog_v1_blog_proto_rawDescGZIP(), []int{6}
}
type GetArticleRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
}
func (x *GetArticleRequest) Reset() {
*x = GetArticleRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_blog_v1_blog_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *GetArticleRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetArticleRequest) ProtoMessage() {}
func (x *GetArticleRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_blog_v1_blog_proto_msgTypes[7]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetArticleRequest.ProtoReflect.Descriptor instead.
func (*GetArticleRequest) Descriptor() ([]byte, []int) {
return file_api_blog_v1_blog_proto_rawDescGZIP(), []int{7}
}
func (x *GetArticleRequest) GetId() int64 {
if x != nil {
return x.Id
}
return 0
}
type GetArticleReply struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Article *Article `protobuf:"bytes,1,opt,name=Article,proto3" json:"Article,omitempty"`
}
func (x *GetArticleReply) Reset() {
*x = GetArticleReply{}
if protoimpl.UnsafeEnabled {
mi := &file_api_blog_v1_blog_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *GetArticleReply) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetArticleReply) ProtoMessage() {}
func (x *GetArticleReply) ProtoReflect() protoreflect.Message {
mi := &file_api_blog_v1_blog_proto_msgTypes[8]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetArticleReply.ProtoReflect.Descriptor instead.
func (*GetArticleReply) Descriptor() ([]byte, []int) {
return file_api_blog_v1_blog_proto_rawDescGZIP(), []int{8}
}
func (x *GetArticleReply) GetArticle() *Article {
if x != nil {
return x.Article
}
return nil
}
type ListArticleRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *ListArticleRequest) Reset() {
*x = ListArticleRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_blog_v1_blog_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ListArticleRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListArticleRequest) ProtoMessage() {}
func (x *ListArticleRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_blog_v1_blog_proto_msgTypes[9]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ListArticleRequest.ProtoReflect.Descriptor instead.
func (*ListArticleRequest) Descriptor() ([]byte, []int) {
return file_api_blog_v1_blog_proto_rawDescGZIP(), []int{9}
}
type ListArticleReply struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Results []*Article `protobuf:"bytes,1,rep,name=results,proto3" json:"results,omitempty"`
}
func (x *ListArticleReply) Reset() {
*x = ListArticleReply{}
if protoimpl.UnsafeEnabled {
mi := &file_api_blog_v1_blog_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ListArticleReply) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListArticleReply) ProtoMessage() {}
func (x *ListArticleReply) ProtoReflect() protoreflect.Message {
mi := &file_api_blog_v1_blog_proto_msgTypes[10]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ListArticleReply.ProtoReflect.Descriptor instead.
func (*ListArticleReply) Descriptor() ([]byte, []int) {
return file_api_blog_v1_blog_proto_rawDescGZIP(), []int{10}
}
func (x *ListArticleReply) GetResults() []*Article {
if x != nil {
return x.Results
}
return nil
}
var File_api_blog_v1_blog_proto protoreflect.FileDescriptor
var file_api_blog_v1_blog_proto_rawDesc = []byte{
0x0a, 0x16, 0x61, 0x70, 0x69, 0x2f, 0x62, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x6c,
0x6f, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31,
0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e,
0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x5d,
0x0a, 0x07, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74,
0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12,
0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6b,
0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x6c, 0x69, 0x6b, 0x65, 0x22, 0x46, 0x0a,
0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63,
0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f,
0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x3f, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41,
0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x29, 0x0a, 0x07, 0x41,
0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x07, 0x41,
0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x22, 0x56, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e,
0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14,
0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74,
0x69, 0x74, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18,
0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x3f,
0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52,
0x65, 0x70, 0x6c, 0x79, 0x12, 0x29, 0x0a, 0x07, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x18,
0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x41,
0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x07, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x22,
0x26, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20,
0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x22, 0x14, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74,
0x65, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x23, 0x0a,
0x11, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02,
0x69, 0x64, 0x22, 0x3c, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65,
0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x29, 0x0a, 0x07, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e,
0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x07, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65,
0x22, 0x14, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3d, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72,
0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x29, 0x0a, 0x07, 0x72, 0x65,
0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x61, 0x70,
0x69, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x07, 0x72, 0x65,
0x73, 0x75, 0x6c, 0x74, 0x73, 0x32, 0xf5, 0x03, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x67, 0x53, 0x65,
0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x62, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41,
0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x12, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e,
0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72,
0x65, 0x61, 0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79,
0x22, 0x17, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x11, 0x22, 0x0c, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x72,
0x74, 0x69, 0x63, 0x6c, 0x65, 0x2f, 0x3a, 0x01, 0x2a, 0x12, 0x66, 0x0a, 0x0d, 0x55, 0x70, 0x64,
0x61, 0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x12, 0x1c, 0x2e, 0x61, 0x70, 0x69,
0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c,
0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76,
0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52,
0x65, 0x70, 0x6c, 0x79, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x1a, 0x10, 0x2f, 0x76,
0x31, 0x2f, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a, 0x01,
0x2a, 0x12, 0x63, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x63,
0x6c, 0x65, 0x12, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65,
0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x18, 0x82, 0xd3,
0xe4, 0x93, 0x02, 0x12, 0x2a, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c,
0x65, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x5a, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74,
0x69, 0x63, 0x6c, 0x65, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65,
0x74, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69,
0x63, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12,
0x12, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x2f, 0x7b, 0x69,
0x64, 0x7d, 0x12, 0x59, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c,
0x65, 0x12, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41,
0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e,
0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x63,
0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x14, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0e, 0x12,
0x0c, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x2f, 0x42, 0x38, 0x0a,
0x06, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x50, 0x01, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75,
0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f,
0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x62, 0x6c, 0x6f, 0x67, 0x2f, 0x61, 0x70,
0x69, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_api_blog_v1_blog_proto_rawDescOnce sync.Once
file_api_blog_v1_blog_proto_rawDescData = file_api_blog_v1_blog_proto_rawDesc
)
func file_api_blog_v1_blog_proto_rawDescGZIP() []byte {
file_api_blog_v1_blog_proto_rawDescOnce.Do(func() {
file_api_blog_v1_blog_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_blog_v1_blog_proto_rawDescData)
})
return file_api_blog_v1_blog_proto_rawDescData
}
var file_api_blog_v1_blog_proto_msgTypes = make([]protoimpl.MessageInfo, 11)
var file_api_blog_v1_blog_proto_goTypes = []interface{}{
(*Article)(nil), // 0: api.v1.Article
(*CreateArticleRequest)(nil), // 1: api.v1.CreateArticleRequest
(*CreateArticleReply)(nil), // 2: api.v1.CreateArticleReply
(*UpdateArticleRequest)(nil), // 3: api.v1.UpdateArticleRequest
(*UpdateArticleReply)(nil), // 4: api.v1.UpdateArticleReply
(*DeleteArticleRequest)(nil), // 5: api.v1.DeleteArticleRequest
(*DeleteArticleReply)(nil), // 6: api.v1.DeleteArticleReply
(*GetArticleRequest)(nil), // 7: api.v1.GetArticleRequest
(*GetArticleReply)(nil), // 8: api.v1.GetArticleReply
(*ListArticleRequest)(nil), // 9: api.v1.ListArticleRequest
(*ListArticleReply)(nil), // 10: api.v1.ListArticleReply
}
var file_api_blog_v1_blog_proto_depIdxs = []int32{
0, // 0: api.v1.CreateArticleReply.Article:type_name -> api.v1.Article
0, // 1: api.v1.UpdateArticleReply.Article:type_name -> api.v1.Article
0, // 2: api.v1.GetArticleReply.Article:type_name -> api.v1.Article
0, // 3: api.v1.ListArticleReply.results:type_name -> api.v1.Article
1, // 4: api.v1.BlogService.CreateArticle:input_type -> api.v1.CreateArticleRequest
3, // 5: api.v1.BlogService.UpdateArticle:input_type -> api.v1.UpdateArticleRequest
5, // 6: api.v1.BlogService.DeleteArticle:input_type -> api.v1.DeleteArticleRequest
7, // 7: api.v1.BlogService.GetArticle:input_type -> api.v1.GetArticleRequest
9, // 8: api.v1.BlogService.ListArticle:input_type -> api.v1.ListArticleRequest
2, // 9: api.v1.BlogService.CreateArticle:output_type -> api.v1.CreateArticleReply
4, // 10: api.v1.BlogService.UpdateArticle:output_type -> api.v1.UpdateArticleReply
6, // 11: api.v1.BlogService.DeleteArticle:output_type -> api.v1.DeleteArticleReply
8, // 12: api.v1.BlogService.GetArticle:output_type -> api.v1.GetArticleReply
10, // 13: api.v1.BlogService.ListArticle:output_type -> api.v1.ListArticleReply
9, // [9:14] is the sub-list for method output_type
4, // [4:9] is the sub-list for method input_type
4, // [4:4] is the sub-list for extension type_name
4, // [4:4] is the sub-list for extension extendee
0, // [0:4] is the sub-list for field type_name
}
func init() { file_api_blog_v1_blog_proto_init() }
func file_api_blog_v1_blog_proto_init() {
if File_api_blog_v1_blog_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_api_blog_v1_blog_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Article); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_blog_v1_blog_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CreateArticleRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_blog_v1_blog_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CreateArticleReply); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_blog_v1_blog_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*UpdateArticleRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_blog_v1_blog_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*UpdateArticleReply); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_blog_v1_blog_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DeleteArticleRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_blog_v1_blog_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DeleteArticleReply); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_blog_v1_blog_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetArticleRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_blog_v1_blog_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetArticleReply); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_blog_v1_blog_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ListArticleRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_blog_v1_blog_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ListArticleReply); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_api_blog_v1_blog_proto_rawDesc,
NumEnums: 0,
NumMessages: 11,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_api_blog_v1_blog_proto_goTypes,
DependencyIndexes: file_api_blog_v1_blog_proto_depIdxs,
MessageInfos: file_api_blog_v1_blog_proto_msgTypes,
}.Build()
File_api_blog_v1_blog_proto = out.File
file_api_blog_v1_blog_proto_rawDesc = nil
file_api_blog_v1_blog_proto_goTypes = nil
file_api_blog_v1_blog_proto_depIdxs = nil
}

@ -0,0 +1,86 @@
syntax = "proto3";
package api.v1;
option go_package = "github.com/go-kratos/examples/blog/api/v1;v1";
option java_multiple_files = true;
option java_package = "api.v1";
import "google/api/annotations.proto";
service BlogService {
rpc CreateArticle (CreateArticleRequest) returns (CreateArticleReply) {
option (google.api.http) = {
post: "/v1/article/"
body: "*"
};
}
rpc UpdateArticle (UpdateArticleRequest) returns (UpdateArticleReply) {
option (google.api.http) = {
put: "/v1/article/{id}"
body: "*"
};
}
rpc DeleteArticle (DeleteArticleRequest) returns (DeleteArticleReply) {
option (google.api.http) = {
delete: "/v1/article/{id}"
};
}
rpc GetArticle (GetArticleRequest) returns (GetArticleReply) {
option (google.api.http) = {
get: "/v1/article/{id}"
};
}
rpc ListArticle (ListArticleRequest) returns (ListArticleReply) {
option (google.api.http) = {
get: "/v1/article/"
};
}
}
message Article {
int64 id = 1;
string title = 2;
string content = 3;
int64 like = 4;
}
message CreateArticleRequest {
string title = 1;
string content = 2;
}
message CreateArticleReply {
Article Article = 1;
}
message UpdateArticleRequest {
int64 id = 1;
string title = 2;
string content = 3;
}
message UpdateArticleReply {
Article Article = 1;
}
message DeleteArticleRequest {
int64 id = 1;
}
message DeleteArticleReply {
}
message GetArticleRequest {
int64 id = 1;
}
message GetArticleReply {
Article Article = 1;
}
message ListArticleRequest {
}
message ListArticleReply {
repeated Article results = 1;
}

@ -0,0 +1,245 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
package v1
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
// BlogServiceClient is the client API for BlogService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type BlogServiceClient interface {
CreateArticle(ctx context.Context, in *CreateArticleRequest, opts ...grpc.CallOption) (*CreateArticleReply, error)
UpdateArticle(ctx context.Context, in *UpdateArticleRequest, opts ...grpc.CallOption) (*UpdateArticleReply, error)
DeleteArticle(ctx context.Context, in *DeleteArticleRequest, opts ...grpc.CallOption) (*DeleteArticleReply, error)
GetArticle(ctx context.Context, in *GetArticleRequest, opts ...grpc.CallOption) (*GetArticleReply, error)
ListArticle(ctx context.Context, in *ListArticleRequest, opts ...grpc.CallOption) (*ListArticleReply, error)
}
type blogServiceClient struct {
cc grpc.ClientConnInterface
}
func NewBlogServiceClient(cc grpc.ClientConnInterface) BlogServiceClient {
return &blogServiceClient{cc}
}
func (c *blogServiceClient) CreateArticle(ctx context.Context, in *CreateArticleRequest, opts ...grpc.CallOption) (*CreateArticleReply, error) {
out := new(CreateArticleReply)
err := c.cc.Invoke(ctx, "/api.v1.BlogService/CreateArticle", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *blogServiceClient) UpdateArticle(ctx context.Context, in *UpdateArticleRequest, opts ...grpc.CallOption) (*UpdateArticleReply, error) {
out := new(UpdateArticleReply)
err := c.cc.Invoke(ctx, "/api.v1.BlogService/UpdateArticle", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *blogServiceClient) DeleteArticle(ctx context.Context, in *DeleteArticleRequest, opts ...grpc.CallOption) (*DeleteArticleReply, error) {
out := new(DeleteArticleReply)
err := c.cc.Invoke(ctx, "/api.v1.BlogService/DeleteArticle", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *blogServiceClient) GetArticle(ctx context.Context, in *GetArticleRequest, opts ...grpc.CallOption) (*GetArticleReply, error) {
out := new(GetArticleReply)
err := c.cc.Invoke(ctx, "/api.v1.BlogService/GetArticle", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *blogServiceClient) ListArticle(ctx context.Context, in *ListArticleRequest, opts ...grpc.CallOption) (*ListArticleReply, error) {
out := new(ListArticleReply)
err := c.cc.Invoke(ctx, "/api.v1.BlogService/ListArticle", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// BlogServiceServer is the server API for BlogService service.
// All implementations must embed UnimplementedBlogServiceServer
// for forward compatibility
type BlogServiceServer interface {
CreateArticle(context.Context, *CreateArticleRequest) (*CreateArticleReply, error)
UpdateArticle(context.Context, *UpdateArticleRequest) (*UpdateArticleReply, error)
DeleteArticle(context.Context, *DeleteArticleRequest) (*DeleteArticleReply, error)
GetArticle(context.Context, *GetArticleRequest) (*GetArticleReply, error)
ListArticle(context.Context, *ListArticleRequest) (*ListArticleReply, error)
mustEmbedUnimplementedBlogServiceServer()
}
// UnimplementedBlogServiceServer must be embedded to have forward compatible implementations.
type UnimplementedBlogServiceServer struct {
}
func (UnimplementedBlogServiceServer) CreateArticle(context.Context, *CreateArticleRequest) (*CreateArticleReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method CreateArticle not implemented")
}
func (UnimplementedBlogServiceServer) UpdateArticle(context.Context, *UpdateArticleRequest) (*UpdateArticleReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method UpdateArticle not implemented")
}
func (UnimplementedBlogServiceServer) DeleteArticle(context.Context, *DeleteArticleRequest) (*DeleteArticleReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method DeleteArticle not implemented")
}
func (UnimplementedBlogServiceServer) GetArticle(context.Context, *GetArticleRequest) (*GetArticleReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetArticle not implemented")
}
func (UnimplementedBlogServiceServer) ListArticle(context.Context, *ListArticleRequest) (*ListArticleReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method ListArticle not implemented")
}
func (UnimplementedBlogServiceServer) mustEmbedUnimplementedBlogServiceServer() {}
// UnsafeBlogServiceServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to BlogServiceServer will
// result in compilation errors.
type UnsafeBlogServiceServer interface {
mustEmbedUnimplementedBlogServiceServer()
}
func RegisterBlogServiceServer(s grpc.ServiceRegistrar, srv BlogServiceServer) {
s.RegisterService(&BlogService_ServiceDesc, srv)
}
func _BlogService_CreateArticle_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CreateArticleRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(BlogServiceServer).CreateArticle(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/api.v1.BlogService/CreateArticle",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(BlogServiceServer).CreateArticle(ctx, req.(*CreateArticleRequest))
}
return interceptor(ctx, in, info, handler)
}
func _BlogService_UpdateArticle_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(UpdateArticleRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(BlogServiceServer).UpdateArticle(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/api.v1.BlogService/UpdateArticle",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(BlogServiceServer).UpdateArticle(ctx, req.(*UpdateArticleRequest))
}
return interceptor(ctx, in, info, handler)
}
func _BlogService_DeleteArticle_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(DeleteArticleRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(BlogServiceServer).DeleteArticle(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/api.v1.BlogService/DeleteArticle",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(BlogServiceServer).DeleteArticle(ctx, req.(*DeleteArticleRequest))
}
return interceptor(ctx, in, info, handler)
}
func _BlogService_GetArticle_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetArticleRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(BlogServiceServer).GetArticle(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/api.v1.BlogService/GetArticle",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(BlogServiceServer).GetArticle(ctx, req.(*GetArticleRequest))
}
return interceptor(ctx, in, info, handler)
}
func _BlogService_ListArticle_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ListArticleRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(BlogServiceServer).ListArticle(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/api.v1.BlogService/ListArticle",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(BlogServiceServer).ListArticle(ctx, req.(*ListArticleRequest))
}
return interceptor(ctx, in, info, handler)
}
// BlogService_ServiceDesc is the grpc.ServiceDesc for BlogService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var BlogService_ServiceDesc = grpc.ServiceDesc{
ServiceName: "api.v1.BlogService",
HandlerType: (*BlogServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "CreateArticle",
Handler: _BlogService_CreateArticle_Handler,
},
{
MethodName: "UpdateArticle",
Handler: _BlogService_UpdateArticle_Handler,
},
{
MethodName: "DeleteArticle",
Handler: _BlogService_DeleteArticle_Handler,
},
{
MethodName: "GetArticle",
Handler: _BlogService_GetArticle_Handler,
},
{
MethodName: "ListArticle",
Handler: _BlogService_ListArticle_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "api/blog/v1/blog.proto",
}

@ -0,0 +1,177 @@
// Code generated by protoc-gen-go-http. DO NOT EDIT.
package v1
import (
context "context"
http1 "github.com/go-kratos/kratos/v2/transport/http"
binding "github.com/go-kratos/kratos/v2/transport/http/binding"
mux "github.com/gorilla/mux"
http "net/http"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the kratos package it is being compiled against.
var _ = new(http.Request)
var _ = new(context.Context)
var _ = binding.MapProto
var _ = mux.NewRouter
const _ = http1.SupportPackageIsVersion1
type BlogServiceHandler interface {
CreateArticle(context.Context, *CreateArticleRequest) (*CreateArticleReply, error)
DeleteArticle(context.Context, *DeleteArticleRequest) (*DeleteArticleReply, error)
GetArticle(context.Context, *GetArticleRequest) (*GetArticleReply, error)
ListArticle(context.Context, *ListArticleRequest) (*ListArticleReply, error)
UpdateArticle(context.Context, *UpdateArticleRequest) (*UpdateArticleReply, error)
}
func NewBlogServiceHandler(srv BlogServiceHandler, opts ...http1.HandleOption) http.Handler {
h := http1.DefaultHandleOptions()
for _, o := range opts {
o(&h)
}
r := mux.NewRouter()
r.HandleFunc("/v1/article/", func(w http.ResponseWriter, r *http.Request) {
var in CreateArticleRequest
if err := h.Decode(r, &in); err != nil {
h.Error(w, r, err)
return
}
next := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.CreateArticle(ctx, req.(*CreateArticleRequest))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
out, err := next(r.Context(), &in)
if err != nil {
h.Error(w, r, err)
return
}
reply := out.(*CreateArticleReply)
if err := h.Encode(w, r, reply); err != nil {
h.Error(w, r, err)
}
}).Methods("POST")
r.HandleFunc("/v1/article/{id}", func(w http.ResponseWriter, r *http.Request) {
var in UpdateArticleRequest
if err := h.Decode(r, &in); err != nil {
h.Error(w, r, err)
return
}
if err := binding.MapProto(&in, mux.Vars(r)); err != nil {
h.Error(w, r, err)
return
}
next := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.UpdateArticle(ctx, req.(*UpdateArticleRequest))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
out, err := next(r.Context(), &in)
if err != nil {
h.Error(w, r, err)
return
}
reply := out.(*UpdateArticleReply)
if err := h.Encode(w, r, reply); err != nil {
h.Error(w, r, err)
}
}).Methods("PUT")
r.HandleFunc("/v1/article/{id}", func(w http.ResponseWriter, r *http.Request) {
var in DeleteArticleRequest
if err := h.Decode(r, &in); err != nil {
h.Error(w, r, err)
return
}
if err := binding.MapProto(&in, mux.Vars(r)); err != nil {
h.Error(w, r, err)
return
}
next := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.DeleteArticle(ctx, req.(*DeleteArticleRequest))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
out, err := next(r.Context(), &in)
if err != nil {
h.Error(w, r, err)
return
}
reply := out.(*DeleteArticleReply)
if err := h.Encode(w, r, reply); err != nil {
h.Error(w, r, err)
}
}).Methods("DELETE")
r.HandleFunc("/v1/article/{id}", func(w http.ResponseWriter, r *http.Request) {
var in GetArticleRequest
if err := h.Decode(r, &in); err != nil {
h.Error(w, r, err)
return
}
if err := binding.MapProto(&in, mux.Vars(r)); err != nil {
h.Error(w, r, err)
return
}
next := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.GetArticle(ctx, req.(*GetArticleRequest))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
out, err := next(r.Context(), &in)
if err != nil {
h.Error(w, r, err)
return
}
reply := out.(*GetArticleReply)
if err := h.Encode(w, r, reply); err != nil {
h.Error(w, r, err)
}
}).Methods("GET")
r.HandleFunc("/v1/article/", func(w http.ResponseWriter, r *http.Request) {
var in ListArticleRequest
if err := h.Decode(r, &in); err != nil {
h.Error(w, r, err)
return
}
next := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.ListArticle(ctx, req.(*ListArticleRequest))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
out, err := next(r.Context(), &in)
if err != nil {
h.Error(w, r, err)
return
}
reply := out.(*ListArticleReply)
if err := h.Encode(w, r, reply); err != nil {
h.Error(w, r, err)
}
}).Methods("GET")
return r
}

@ -0,0 +1,142 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.13.0
// source: api/blog/v1/errors/article.proto
package errors
import (
_ "github.com/go-kratos/kratos/v2/api/kratos/api"
proto "github.com/golang/protobuf/proto"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4
type Article int32
const (
Article_TitleMissing Article = 0
Article_ContentMissing Article = 1
)
// Enum value maps for Article.
var (
Article_name = map[int32]string{
0: "TitleMissing",
1: "ContentMissing",
}
Article_value = map[string]int32{
"TitleMissing": 0,
"ContentMissing": 1,
}
)
func (x Article) Enum() *Article {
p := new(Article)
*p = x
return p
}
func (x Article) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (Article) Descriptor() protoreflect.EnumDescriptor {
return file_api_blog_v1_errors_article_proto_enumTypes[0].Descriptor()
}
func (Article) Type() protoreflect.EnumType {
return &file_api_blog_v1_errors_article_proto_enumTypes[0]
}
func (x Article) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Use Article.Descriptor instead.
func (Article) EnumDescriptor() ([]byte, []int) {
return file_api_blog_v1_errors_article_proto_rawDescGZIP(), []int{0}
}
var File_api_blog_v1_errors_article_proto protoreflect.FileDescriptor
var file_api_blog_v1_errors_article_proto_rawDesc = []byte{
0x0a, 0x20, 0x61, 0x70, 0x69, 0x2f, 0x62, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x72,
0x72, 0x6f, 0x72, 0x73, 0x2f, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x12, 0x12, 0x61, 0x70, 0x69, 0x2e, 0x62, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x2e,
0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x1a, 0x1c, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x61,
0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x2a, 0x34, 0x0a, 0x07, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x12,
0x10, 0x0a, 0x0c, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x10,
0x00, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x4d, 0x69, 0x73, 0x73,
0x69, 0x6e, 0x67, 0x10, 0x01, 0x1a, 0x03, 0xc0, 0x3e, 0x01, 0x42, 0x5b, 0x0a, 0x0e, 0x62, 0x6c,
0x6f, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x50, 0x01, 0x5a, 0x37,
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, 0x6b, 0x72,
0x61, 0x74, 0x6f, 0x73, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x62, 0x6c,
0x6f, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73,
0x3b, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0xa2, 0x02, 0x0d, 0x41, 0x50, 0x49, 0x42, 0x6c, 0x6f,
0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_api_blog_v1_errors_article_proto_rawDescOnce sync.Once
file_api_blog_v1_errors_article_proto_rawDescData = file_api_blog_v1_errors_article_proto_rawDesc
)
func file_api_blog_v1_errors_article_proto_rawDescGZIP() []byte {
file_api_blog_v1_errors_article_proto_rawDescOnce.Do(func() {
file_api_blog_v1_errors_article_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_blog_v1_errors_article_proto_rawDescData)
})
return file_api_blog_v1_errors_article_proto_rawDescData
}
var file_api_blog_v1_errors_article_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_api_blog_v1_errors_article_proto_goTypes = []interface{}{
(Article)(0), // 0: api.blog.v1.errors.Article
}
var file_api_blog_v1_errors_article_proto_depIdxs = []int32{
0, // [0:0] is the sub-list for method output_type
0, // [0:0] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_api_blog_v1_errors_article_proto_init() }
func file_api_blog_v1_errors_article_proto_init() {
if File_api_blog_v1_errors_article_proto != nil {
return
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_api_blog_v1_errors_article_proto_rawDesc,
NumEnums: 1,
NumMessages: 0,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_api_blog_v1_errors_article_proto_goTypes,
DependencyIndexes: file_api_blog_v1_errors_article_proto_depIdxs,
EnumInfos: file_api_blog_v1_errors_article_proto_enumTypes,
}.Build()
File_api_blog_v1_errors_article_proto = out.File
file_api_blog_v1_errors_article_proto_rawDesc = nil
file_api_blog_v1_errors_article_proto_goTypes = nil
file_api_blog_v1_errors_article_proto_depIdxs = nil
}

@ -0,0 +1,18 @@
syntax = "proto3";
package api.blog.v1.errors;
import "kratos/api/annotations.proto";
//
option go_package = "github.com/go-kratos/examples/blog/api/v1/errors;errors";
option java_multiple_files = true;
option java_package = "blog.v1.errors";
option objc_class_prefix = "APIBlogErrors";
enum Article {
option (kratos.api.errors) = true;
TitleMissing = 0;
ContentMissing = 1;
}

@ -0,0 +1,24 @@
// Code generated by protoc-gen-go-errors. DO NOT EDIT.
package errors
import (
errors "github.com/go-kratos/kratos/v2/errors"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the kratos package it is being compiled against.
const _ = errors.SupportPackageIsVersion1
const (
Errors_TitleMissing = "Article_TitleMissing"
Errors_ContentMissing = "Article_ContentMissing"
)
func IsTitleMissing(err error) bool {
return errors.Reason(err) == Errors_TitleMissing
}
func IsContentMissing(err error) bool {
return errors.Reason(err) == Errors_ContentMissing
}

@ -0,0 +1,101 @@
package main
import (
"flag"
"os"
"go.opentelemetry.io/otel/exporters/trace/jaeger"
"github.com/go-kratos/examples/blog/internal/conf"
"github.com/go-kratos/kratos/v2"
"github.com/go-kratos/kratos/v2/config"
"github.com/go-kratos/kratos/v2/config/file"
"github.com/go-kratos/kratos/v2/log"
"github.com/go-kratos/kratos/v2/transport/grpc"
"github.com/go-kratos/kratos/v2/transport/http"
"go.opentelemetry.io/otel/label"
"go.opentelemetry.io/otel/sdk/trace"
"gopkg.in/yaml.v2"
)
// go build -ldflags "-X main.Version=x.y.z"
var (
// Name is the name of the compiled software.
Name string
// Version is the version of the compiled software.
Version string
// flagconf is the config flag.
flagconf string
)
func init() {
flag.StringVar(&flagconf, "conf", "../../configs", "config path, eg: -conf config.yaml")
}
func newApp(logger log.Logger, hs *http.Server, gs *grpc.Server) *kratos.App {
return kratos.New(
kratos.Name(Name),
kratos.Version(Version),
kratos.Metadata(map[string]string{}),
kratos.Logger(logger),
kratos.Server(
hs,
gs,
),
)
}
// todo: move to wire DI
func newTracer() func() {
// Create and install Jaeger export pipeline.
flush, err := jaeger.InstallNewPipeline(
jaeger.WithCollectorEndpoint("http://localhost:14268/api/traces"),
jaeger.WithProcess(jaeger.Process{
ServiceName: "trace-demo",
Tags: []label.KeyValue{
label.String("exporter", "jaeger"),
label.Float64("float", 312.23),
},
}),
jaeger.WithSDK(&trace.Config{DefaultSampler: trace.AlwaysSample()}),
)
if err != nil {
panic(err)
}
return flush
}
func main() {
flag.Parse()
logger := log.NewStdLogger(os.Stdout)
config := config.New(
config.WithSource(
file.NewSource(flagconf),
),
config.WithDecoder(func(kv *config.KeyValue, v map[string]interface{}) error {
return yaml.Unmarshal(kv.Value, v)
}),
)
if err := config.Load(); err != nil {
panic(err)
}
var bc conf.Bootstrap
if err := config.Scan(&bc); err != nil {
panic(err)
}
flush := newTracer()
defer flush()
app, err := initApp(bc.Server, bc.Data, logger)
if err != nil {
panic(err)
}
// start and wait for stop signal
if err := app.Run(); err != nil {
panic(err)
}
}

@ -0,0 +1,21 @@
// +build wireinject
// The build tag makes sure the stub is not built in the final build.
package main
import (
"github.com/go-kratos/examples/blog/internal/biz"
"github.com/go-kratos/examples/blog/internal/conf"
"github.com/go-kratos/examples/blog/internal/data"
"github.com/go-kratos/examples/blog/internal/server"
"github.com/go-kratos/examples/blog/internal/service"
"github.com/go-kratos/kratos/v2"
"github.com/go-kratos/kratos/v2/log"
"github.com/google/wire"
)
// initApp init kratos application.
func initApp(*conf.Server, *conf.Data, log.Logger) (*kratos.App, error) {
panic(wire.Build(server.ProviderSet, data.ProviderSet, biz.ProviderSet, service.ProviderSet, newApp))
}

@ -0,0 +1,33 @@
// Code generated by Wire. DO NOT EDIT.
//go:generate go run github.com/google/wire/cmd/wire
//+build !wireinject
package main
import (
"github.com/go-kratos/examples/blog/internal/biz"
"github.com/go-kratos/examples/blog/internal/conf"
"github.com/go-kratos/examples/blog/internal/data"
"github.com/go-kratos/examples/blog/internal/server"
"github.com/go-kratos/examples/blog/internal/service"
"github.com/go-kratos/kratos/v2"
"github.com/go-kratos/kratos/v2/log"
)
// Injectors from wire.go:
// initApp init kratos application.
func initApp(confServer *conf.Server, confData *conf.Data, logger log.Logger) (*kratos.App, error) {
dataData, err := data.NewData(confData, logger)
if err != nil {
return nil, err
}
articleRepo := data.NewArticleRepo(dataData, logger)
articleUsecase := biz.NewArticleUsecase(articleRepo, logger)
blogService := service.NewBlogService(articleUsecase, logger)
httpServer := server.NewHTTPServer(confServer, blogService)
grpcServer := server.NewGRPCServer(confServer, blogService)
app := newApp(logger, httpServer, grpcServer)
return app, nil
}

@ -0,0 +1,16 @@
server:
http:
addr: 0.0.0.0:8000
timeout: 1s
grpc:
addr: 0.0.0.0:9000
timeout: 1s
data:
database:
driver: mysql
source: root:password@tcp(127.0.0.1:3306)/testdb?parseTime=True
redis:
addr: 127.0.0.1:6379
dial_timeout: 1s
read_timeout: 0.4s
write_timeout: 0.6s

@ -0,0 +1,73 @@
package biz
import (
"context"
"github.com/go-kratos/kratos/v2/log"
"time"
)
type Article struct {
Id int64
Title string
Content string
CreatedAt time.Time
UpdatedAt time.Time
Like int64
}
type ArticleRepo interface {
// db
ListArticle(ctx context.Context) ([]*Article, error)
GetArticle(ctx context.Context, id int64) (*Article, error)
CreateArticle(ctx context.Context, article *Article) error
UpdateArticle(ctx context.Context, id int64, article *Article) error
DeleteArticle(ctx context.Context, id int64) error
// redis
GetArticleLike(ctx context.Context, id int64) (rv int64, err error)
IncArticleLike(ctx context.Context, id int64) error
}
type ArticleUsecase struct {
repo ArticleRepo
}
func NewArticleUsecase(repo ArticleRepo, logger log.Logger) *ArticleUsecase {
return &ArticleUsecase{repo: repo}
}
func (uc *ArticleUsecase) List(ctx context.Context) (ps []*Article, err error) {
ps, err = uc.repo.ListArticle(ctx)
if err != nil {
return
}
return
}
func (uc *ArticleUsecase) Get(ctx context.Context, id int64) (p *Article, err error) {
p, err = uc.repo.GetArticle(ctx, id)
if err != nil {
return
}
err = uc.repo.IncArticleLike(ctx, id)
if err != nil {
return
}
p.Like, err = uc.repo.GetArticleLike(ctx, id)
if err != nil {
return
}
return
}
func (uc *ArticleUsecase) Create(ctx context.Context, article *Article) error {
return uc.repo.CreateArticle(ctx, article)
}
func (uc *ArticleUsecase) Update(ctx context.Context, id int64, article *Article) error {
return uc.repo.UpdateArticle(ctx, id, article)
}
func (uc *ArticleUsecase) Delete(ctx context.Context, id int64) error {
return uc.repo.DeleteArticle(ctx, id)
}

@ -0,0 +1,6 @@
package biz
import "github.com/google/wire"
// ProviderSet is biz providers.
var ProviderSet = wire.NewSet(NewArticleUsecase)

@ -0,0 +1,691 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.13.0
// source: internal/conf/conf.proto
package conf
import (
proto "github.com/golang/protobuf/proto"
duration "github.com/golang/protobuf/ptypes/duration"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4
type Bootstrap struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Server *Server `protobuf:"bytes,1,opt,name=server,proto3" json:"server,omitempty"`
Data *Data `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"`
}
func (x *Bootstrap) Reset() {
*x = Bootstrap{}
if protoimpl.UnsafeEnabled {
mi := &file_internal_conf_conf_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Bootstrap) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Bootstrap) ProtoMessage() {}
func (x *Bootstrap) ProtoReflect() protoreflect.Message {
mi := &file_internal_conf_conf_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Bootstrap.ProtoReflect.Descriptor instead.
func (*Bootstrap) Descriptor() ([]byte, []int) {
return file_internal_conf_conf_proto_rawDescGZIP(), []int{0}
}
func (x *Bootstrap) GetServer() *Server {
if x != nil {
return x.Server
}
return nil
}
func (x *Bootstrap) GetData() *Data {
if x != nil {
return x.Data
}
return nil
}
type Server struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Http *Server_HTTP `protobuf:"bytes,1,opt,name=http,proto3" json:"http,omitempty"`
Grpc *Server_GRPC `protobuf:"bytes,2,opt,name=grpc,proto3" json:"grpc,omitempty"`
}
func (x *Server) Reset() {
*x = Server{}
if protoimpl.UnsafeEnabled {
mi := &file_internal_conf_conf_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Server) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Server) ProtoMessage() {}
func (x *Server) ProtoReflect() protoreflect.Message {
mi := &file_internal_conf_conf_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Server.ProtoReflect.Descriptor instead.
func (*Server) Descriptor() ([]byte, []int) {
return file_internal_conf_conf_proto_rawDescGZIP(), []int{1}
}
func (x *Server) GetHttp() *Server_HTTP {
if x != nil {
return x.Http
}
return nil
}
func (x *Server) GetGrpc() *Server_GRPC {
if x != nil {
return x.Grpc
}
return nil
}
type Data struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Database *Data_Database `protobuf:"bytes,1,opt,name=database,proto3" json:"database,omitempty"`
Redis *Data_Redis `protobuf:"bytes,2,opt,name=redis,proto3" json:"redis,omitempty"`
}
func (x *Data) Reset() {
*x = Data{}
if protoimpl.UnsafeEnabled {
mi := &file_internal_conf_conf_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Data) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Data) ProtoMessage() {}
func (x *Data) ProtoReflect() protoreflect.Message {
mi := &file_internal_conf_conf_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Data.ProtoReflect.Descriptor instead.
func (*Data) Descriptor() ([]byte, []int) {
return file_internal_conf_conf_proto_rawDescGZIP(), []int{2}
}
func (x *Data) GetDatabase() *Data_Database {
if x != nil {
return x.Database
}
return nil
}
func (x *Data) GetRedis() *Data_Redis {
if x != nil {
return x.Redis
}
return nil
}
type Server_HTTP struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Network string `protobuf:"bytes,1,opt,name=network,proto3" json:"network,omitempty"`
Addr string `protobuf:"bytes,2,opt,name=addr,proto3" json:"addr,omitempty"`
Timeout *duration.Duration `protobuf:"bytes,3,opt,name=timeout,proto3" json:"timeout,omitempty"`
}
func (x *Server_HTTP) Reset() {
*x = Server_HTTP{}
if protoimpl.UnsafeEnabled {
mi := &file_internal_conf_conf_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Server_HTTP) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Server_HTTP) ProtoMessage() {}
func (x *Server_HTTP) ProtoReflect() protoreflect.Message {
mi := &file_internal_conf_conf_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Server_HTTP.ProtoReflect.Descriptor instead.
func (*Server_HTTP) Descriptor() ([]byte, []int) {
return file_internal_conf_conf_proto_rawDescGZIP(), []int{1, 0}
}
func (x *Server_HTTP) GetNetwork() string {
if x != nil {
return x.Network
}
return ""
}
func (x *Server_HTTP) GetAddr() string {
if x != nil {
return x.Addr
}
return ""
}
func (x *Server_HTTP) GetTimeout() *duration.Duration {
if x != nil {
return x.Timeout
}
return nil
}
type Server_GRPC struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Network string `protobuf:"bytes,1,opt,name=network,proto3" json:"network,omitempty"`
Addr string `protobuf:"bytes,2,opt,name=addr,proto3" json:"addr,omitempty"`
Timeout *duration.Duration `protobuf:"bytes,3,opt,name=timeout,proto3" json:"timeout,omitempty"`
}
func (x *Server_GRPC) Reset() {
*x = Server_GRPC{}
if protoimpl.UnsafeEnabled {
mi := &file_internal_conf_conf_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Server_GRPC) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Server_GRPC) ProtoMessage() {}
func (x *Server_GRPC) ProtoReflect() protoreflect.Message {
mi := &file_internal_conf_conf_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Server_GRPC.ProtoReflect.Descriptor instead.
func (*Server_GRPC) Descriptor() ([]byte, []int) {
return file_internal_conf_conf_proto_rawDescGZIP(), []int{1, 1}
}
func (x *Server_GRPC) GetNetwork() string {
if x != nil {
return x.Network
}
return ""
}
func (x *Server_GRPC) GetAddr() string {
if x != nil {
return x.Addr
}
return ""
}
func (x *Server_GRPC) GetTimeout() *duration.Duration {
if x != nil {
return x.Timeout
}
return nil
}
type Data_Database struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Driver string `protobuf:"bytes,1,opt,name=driver,proto3" json:"driver,omitempty"`
Source string `protobuf:"bytes,2,opt,name=source,proto3" json:"source,omitempty"`
}
func (x *Data_Database) Reset() {
*x = Data_Database{}
if protoimpl.UnsafeEnabled {
mi := &file_internal_conf_conf_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Data_Database) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Data_Database) ProtoMessage() {}
func (x *Data_Database) ProtoReflect() protoreflect.Message {
mi := &file_internal_conf_conf_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Data_Database.ProtoReflect.Descriptor instead.
func (*Data_Database) Descriptor() ([]byte, []int) {
return file_internal_conf_conf_proto_rawDescGZIP(), []int{2, 0}
}
func (x *Data_Database) GetDriver() string {
if x != nil {
return x.Driver
}
return ""
}
func (x *Data_Database) GetSource() string {
if x != nil {
return x.Source
}
return ""
}
type Data_Redis struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Network string `protobuf:"bytes,1,opt,name=network,proto3" json:"network,omitempty"`
Addr string `protobuf:"bytes,2,opt,name=addr,proto3" json:"addr,omitempty"`
Password string `protobuf:"bytes,3,opt,name=password,proto3" json:"password,omitempty"`
Db int32 `protobuf:"varint,4,opt,name=db,proto3" json:"db,omitempty"`
DialTimeout *duration.Duration `protobuf:"bytes,5,opt,name=dial_timeout,json=dialTimeout,proto3" json:"dial_timeout,omitempty"`
ReadTimeout *duration.Duration `protobuf:"bytes,6,opt,name=read_timeout,json=readTimeout,proto3" json:"read_timeout,omitempty"`
WriteTimeout *duration.Duration `protobuf:"bytes,7,opt,name=write_timeout,json=writeTimeout,proto3" json:"write_timeout,omitempty"`
}
func (x *Data_Redis) Reset() {
*x = Data_Redis{}
if protoimpl.UnsafeEnabled {
mi := &file_internal_conf_conf_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Data_Redis) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Data_Redis) ProtoMessage() {}
func (x *Data_Redis) ProtoReflect() protoreflect.Message {
mi := &file_internal_conf_conf_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Data_Redis.ProtoReflect.Descriptor instead.
func (*Data_Redis) Descriptor() ([]byte, []int) {
return file_internal_conf_conf_proto_rawDescGZIP(), []int{2, 1}
}
func (x *Data_Redis) GetNetwork() string {
if x != nil {
return x.Network
}
return ""
}
func (x *Data_Redis) GetAddr() string {
if x != nil {
return x.Addr
}
return ""
}
func (x *Data_Redis) GetPassword() string {
if x != nil {
return x.Password
}
return ""
}
func (x *Data_Redis) GetDb() int32 {
if x != nil {
return x.Db
}
return 0
}
func (x *Data_Redis) GetDialTimeout() *duration.Duration {
if x != nil {
return x.DialTimeout
}
return nil
}
func (x *Data_Redis) GetReadTimeout() *duration.Duration {
if x != nil {
return x.ReadTimeout
}
return nil
}
func (x *Data_Redis) GetWriteTimeout() *duration.Duration {
if x != nil {
return x.WriteTimeout
}
return nil
}
var File_internal_conf_conf_proto protoreflect.FileDescriptor
var file_internal_conf_conf_proto_rawDesc = []byte{
0x0a, 0x18, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x2f,
0x63, 0x6f, 0x6e, 0x66, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x14, 0x6b, 0x72, 0x61, 0x74,
0x6f, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66,
0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x22, 0x71, 0x0a, 0x09, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x12, 0x34, 0x0a,
0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e,
0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e,
0x63, 0x6f, 0x6e, 0x66, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x06, 0x73, 0x65, 0x72,
0x76, 0x65, 0x72, 0x12, 0x2e, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x1a, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72,
0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x64,
0x61, 0x74, 0x61, 0x22, 0xcc, 0x02, 0x0a, 0x06, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x35,
0x0a, 0x04, 0x68, 0x74, 0x74, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6b,
0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63,
0x6f, 0x6e, 0x66, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x52,
0x04, 0x68, 0x74, 0x74, 0x70, 0x12, 0x35, 0x0a, 0x04, 0x67, 0x72, 0x70, 0x63, 0x18, 0x02, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x69, 0x6e, 0x74,
0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65,
0x72, 0x2e, 0x47, 0x52, 0x50, 0x43, 0x52, 0x04, 0x67, 0x72, 0x70, 0x63, 0x1a, 0x69, 0x0a, 0x04,
0x48, 0x54, 0x54, 0x50, 0x12, 0x18, 0x0a, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, 0x12,
0x0a, 0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x64,
0x64, 0x72, 0x12, 0x33, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x03, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07,
0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x1a, 0x69, 0x0a, 0x04, 0x47, 0x52, 0x50, 0x43, 0x12,
0x18, 0x0a, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x64, 0x64,
0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x33, 0x0a,
0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19,
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f,
0x75, 0x74, 0x22, 0xdb, 0x03, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x3f, 0x0a, 0x08, 0x64,
0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e,
0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e,
0x63, 0x6f, 0x6e, 0x66, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61,
0x73, 0x65, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x05,
0x72, 0x65, 0x64, 0x69, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6b, 0x72,
0x61, 0x74, 0x6f, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f,
0x6e, 0x66, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x64, 0x69, 0x73, 0x52, 0x05, 0x72,
0x65, 0x64, 0x69, 0x73, 0x1a, 0x3a, 0x0a, 0x08, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65,
0x12, 0x16, 0x0a, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72,
0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
0x1a, 0x9d, 0x02, 0x0a, 0x05, 0x52, 0x65, 0x64, 0x69, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6e, 0x65,
0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, 0x74,
0x77, 0x6f, 0x72, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01,
0x28, 0x09, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73,
0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73,
0x77, 0x6f, 0x72, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x64, 0x62, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05,
0x52, 0x02, 0x64, 0x62, 0x12, 0x3c, 0x0a, 0x0c, 0x64, 0x69, 0x61, 0x6c, 0x5f, 0x74, 0x69, 0x6d,
0x65, 0x6f, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f,
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x6f,
0x75, 0x74, 0x12, 0x3c, 0x0a, 0x0c, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f,
0x75, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x72, 0x65, 0x61, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74,
0x12, 0x3e, 0x0a, 0x0d, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75,
0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x52, 0x0c, 0x77, 0x72, 0x69, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74,
0x42, 0x08, 0x5a, 0x06, 0x2e, 0x3b, 0x63, 0x6f, 0x6e, 0x66, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x33,
}
var (
file_internal_conf_conf_proto_rawDescOnce sync.Once
file_internal_conf_conf_proto_rawDescData = file_internal_conf_conf_proto_rawDesc
)
func file_internal_conf_conf_proto_rawDescGZIP() []byte {
file_internal_conf_conf_proto_rawDescOnce.Do(func() {
file_internal_conf_conf_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_conf_conf_proto_rawDescData)
})
return file_internal_conf_conf_proto_rawDescData
}
var file_internal_conf_conf_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
var file_internal_conf_conf_proto_goTypes = []interface{}{
(*Bootstrap)(nil), // 0: kratos.internal.conf.Bootstrap
(*Server)(nil), // 1: kratos.internal.conf.Server
(*Data)(nil), // 2: kratos.internal.conf.Data
(*Server_HTTP)(nil), // 3: kratos.internal.conf.Server.HTTP
(*Server_GRPC)(nil), // 4: kratos.internal.conf.Server.GRPC
(*Data_Database)(nil), // 5: kratos.internal.conf.Data.Database
(*Data_Redis)(nil), // 6: kratos.internal.conf.Data.Redis
(*duration.Duration)(nil), // 7: google.protobuf.Duration
}
var file_internal_conf_conf_proto_depIdxs = []int32{
1, // 0: kratos.internal.conf.Bootstrap.server:type_name -> kratos.internal.conf.Server
2, // 1: kratos.internal.conf.Bootstrap.data:type_name -> kratos.internal.conf.Data
3, // 2: kratos.internal.conf.Server.http:type_name -> kratos.internal.conf.Server.HTTP
4, // 3: kratos.internal.conf.Server.grpc:type_name -> kratos.internal.conf.Server.GRPC
5, // 4: kratos.internal.conf.Data.database:type_name -> kratos.internal.conf.Data.Database
6, // 5: kratos.internal.conf.Data.redis:type_name -> kratos.internal.conf.Data.Redis
7, // 6: kratos.internal.conf.Server.HTTP.timeout:type_name -> google.protobuf.Duration
7, // 7: kratos.internal.conf.Server.GRPC.timeout:type_name -> google.protobuf.Duration
7, // 8: kratos.internal.conf.Data.Redis.dial_timeout:type_name -> google.protobuf.Duration
7, // 9: kratos.internal.conf.Data.Redis.read_timeout:type_name -> google.protobuf.Duration
7, // 10: kratos.internal.conf.Data.Redis.write_timeout:type_name -> google.protobuf.Duration
11, // [11:11] is the sub-list for method output_type
11, // [11:11] is the sub-list for method input_type
11, // [11:11] is the sub-list for extension type_name
11, // [11:11] is the sub-list for extension extendee
0, // [0:11] is the sub-list for field type_name
}
func init() { file_internal_conf_conf_proto_init() }
func file_internal_conf_conf_proto_init() {
if File_internal_conf_conf_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_internal_conf_conf_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Bootstrap); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_internal_conf_conf_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Server); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_internal_conf_conf_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Data); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_internal_conf_conf_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Server_HTTP); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_internal_conf_conf_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Server_GRPC); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_internal_conf_conf_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Data_Database); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_internal_conf_conf_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Data_Redis); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_internal_conf_conf_proto_rawDesc,
NumEnums: 0,
NumMessages: 7,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_internal_conf_conf_proto_goTypes,
DependencyIndexes: file_internal_conf_conf_proto_depIdxs,
MessageInfos: file_internal_conf_conf_proto_msgTypes,
}.Build()
File_internal_conf_conf_proto = out.File
file_internal_conf_conf_proto_rawDesc = nil
file_internal_conf_conf_proto_goTypes = nil
file_internal_conf_conf_proto_depIdxs = nil
}

@ -0,0 +1,44 @@
syntax = "proto3";
package kratos.internal.conf;
option go_package = ".;conf";
import "google/protobuf/duration.proto";
message Bootstrap {
Server server = 1;
Data data = 2;
}
message Server {
message HTTP {
string network = 1;
string addr = 2;
google.protobuf.Duration timeout = 3;
}
message GRPC {
string network = 1;
string addr = 2;
google.protobuf.Duration timeout = 3;
}
HTTP http = 1;
GRPC grpc = 2;
}
message Data {
message Database {
string driver = 1;
string source = 2;
}
message Redis {
string network = 1;
string addr = 2;
string password = 3;
int32 db = 4;
google.protobuf.Duration dial_timeout = 5;
google.protobuf.Duration read_timeout = 6;
google.protobuf.Duration write_timeout = 7;
}
Database database = 1;
Redis redis = 2;
}

@ -0,0 +1,5 @@
# Data
```
go generate ./ent
```

@ -0,0 +1,79 @@
package data
import (
"context"
"github.com/go-kratos/examples/blog/internal/biz"
"github.com/go-kratos/kratos/v2/log"
"time"
)
type articleRepo struct {
data *Data
log *log.Helper
}
// NewArticleRepo .
func NewArticleRepo(data *Data, logger log.Logger) biz.ArticleRepo {
return &articleRepo{
data: data,
log: log.NewHelper("article_repo", logger),
}
}
func (ar *articleRepo) ListArticle(ctx context.Context) ([]*biz.Article, error) {
ps, err := ar.data.db.Article.Query().All(ctx)
if err != nil {
return nil, err
}
rv := make([]*biz.Article, 0)
for _, p := range ps {
rv = append(rv, &biz.Article{
Id: p.ID,
Title: p.Title,
Content: p.Content,
CreatedAt: p.CreatedAt,
UpdatedAt: p.UpdatedAt,
})
}
return rv, nil
}
func (ar *articleRepo) GetArticle(ctx context.Context, id int64) (*biz.Article, error) {
p, err := ar.data.db.Article.Get(ctx, id)
if err != nil {
return nil, err
}
return &biz.Article{
Id: p.ID,
Title: p.Title,
Content: p.Content,
CreatedAt: p.CreatedAt,
UpdatedAt: p.UpdatedAt,
}, nil
}
func (ar *articleRepo) CreateArticle(ctx context.Context, article *biz.Article) error {
_, err := ar.data.db.Article.
Create().
SetTitle(article.Title).
SetContent(article.Content).
Save(ctx)
return err
}
func (ar *articleRepo) UpdateArticle(ctx context.Context, id int64, article *biz.Article) error {
p, err := ar.data.db.Article.Get(ctx, id)
if err != nil {
return err
}
_, err = p.Update().
SetTitle(article.Title).
SetContent(article.Content).
SetUpdatedAt(time.Now()).
Save(ctx)
return err
}
func (ar *articleRepo) DeleteArticle(ctx context.Context, id int64) error {
return ar.data.db.Article.DeleteOneID(id).Exec(ctx)
}

@ -0,0 +1,55 @@
package data
import (
"context"
"github.com/go-kratos/examples/blog/internal/conf"
"github.com/go-kratos/examples/blog/internal/data/ent"
"github.com/go-kratos/kratos/v2/log"
"github.com/go-redis/redis/extra/redisotel"
"github.com/go-redis/redis/v8"
"github.com/google/wire"
// init mysql driver
_ "github.com/go-sql-driver/mysql"
)
// ProviderSet is data providers.
var ProviderSet = wire.NewSet(NewData, NewArticleRepo)
// Data .
type Data struct {
db *ent.Client
rdb *redis.Client
}
// NewData .
func NewData(conf *conf.Data, logger log.Logger) (*Data, error) {
log := log.NewHelper("data", logger)
client, err := ent.Open(
conf.Database.Driver,
conf.Database.Source,
)
if err != nil {
log.Errorf("failed opening connection to sqlite: %v", err)
return nil, err
}
// Run the auto migration tool.
if err := client.Schema.Create(context.Background()); err != nil {
log.Errorf("failed creating schema resources: %v", err)
return nil, err
}
rdb := redis.NewClient(&redis.Options{
Addr: conf.Redis.Addr,
Password: conf.Redis.Password,
DB: int(conf.Redis.Db),
DialTimeout: conf.Redis.DialTimeout.AsDuration(),
WriteTimeout: conf.Redis.WriteTimeout.AsDuration(),
ReadTimeout: conf.Redis.ReadTimeout.AsDuration(),
})
rdb.AddHook(redisotel.TracingHook{})
return &Data{
db: client,
rdb: rdb,
}, nil
}

@ -0,0 +1,174 @@
// Code generated by entc, DO NOT EDIT.
package ent
import (
"fmt"
"strings"
"time"
"entgo.io/ent/dialect/sql"
"github.com/go-kratos/examples/blog/internal/data/ent/article"
)
// Article is the model entity for the Article schema.
type Article struct {
config `json:"-"`
// ID of the ent.
ID int64 `json:"id,omitempty"`
// Title holds the value of the "title" field.
Title string `json:"title,omitempty"`
// Content holds the value of the "content" field.
Content string `json:"content,omitempty"`
// CreatedAt holds the value of the "created_at" field.
CreatedAt time.Time `json:"created_at,omitempty"`
// UpdatedAt holds the value of the "updated_at" field.
UpdatedAt time.Time `json:"updated_at,omitempty"`
// Edges holds the relations/edges for other nodes in the graph.
// The values are being populated by the ArticleQuery when eager-loading is set.
Edges ArticleEdges `json:"edges"`
}
// ArticleEdges holds the relations/edges for other nodes in the graph.
type ArticleEdges struct {
// Comments holds the value of the comments edge.
Comments []*Comment `json:"comments,omitempty"`
// Tags holds the value of the tags edge.
Tags []*Tag `json:"tags,omitempty"`
// loadedTypes holds the information for reporting if a
// type was loaded (or requested) in eager-loading or not.
loadedTypes [2]bool
}
// CommentsOrErr returns the Comments value or an error if the edge
// was not loaded in eager-loading.
func (e ArticleEdges) CommentsOrErr() ([]*Comment, error) {
if e.loadedTypes[0] {
return e.Comments, nil
}
return nil, &NotLoadedError{edge: "comments"}
}
// TagsOrErr returns the Tags value or an error if the edge
// was not loaded in eager-loading.
func (e ArticleEdges) TagsOrErr() ([]*Tag, error) {
if e.loadedTypes[1] {
return e.Tags, nil
}
return nil, &NotLoadedError{edge: "tags"}
}
// scanValues returns the types for scanning values from sql.Rows.
func (*Article) scanValues(columns []string) ([]interface{}, error) {
values := make([]interface{}, len(columns))
for i := range columns {
switch columns[i] {
case article.FieldID:
values[i] = &sql.NullInt64{}
case article.FieldTitle, article.FieldContent:
values[i] = &sql.NullString{}
case article.FieldCreatedAt, article.FieldUpdatedAt:
values[i] = &sql.NullTime{}
default:
return nil, fmt.Errorf("unexpected column %q for type Article", columns[i])
}
}
return values, nil
}
// assignValues assigns the values that were returned from sql.Rows (after scanning)
// to the Article fields.
func (a *Article) assignValues(columns []string, values []interface{}) error {
if m, n := len(values), len(columns); m < n {
return fmt.Errorf("mismatch number of scan values: %d != %d", m, n)
}
for i := range columns {
switch columns[i] {
case article.FieldID:
value, ok := values[i].(*sql.NullInt64)
if !ok {
return fmt.Errorf("unexpected type %T for field id", value)
}
a.ID = int64(value.Int64)
case article.FieldTitle:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field title", values[i])
} else if value.Valid {
a.Title = value.String
}
case article.FieldContent:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field content", values[i])
} else if value.Valid {
a.Content = value.String
}
case article.FieldCreatedAt:
if value, ok := values[i].(*sql.NullTime); !ok {
return fmt.Errorf("unexpected type %T for field created_at", values[i])
} else if value.Valid {
a.CreatedAt = value.Time
}
case article.FieldUpdatedAt:
if value, ok := values[i].(*sql.NullTime); !ok {
return fmt.Errorf("unexpected type %T for field updated_at", values[i])
} else if value.Valid {
a.UpdatedAt = value.Time
}
}
}
return nil
}
// QueryComments queries the "comments" edge of the Article entity.
func (a *Article) QueryComments() *CommentQuery {
return (&ArticleClient{config: a.config}).QueryComments(a)
}
// QueryTags queries the "tags" edge of the Article entity.
func (a *Article) QueryTags() *TagQuery {
return (&ArticleClient{config: a.config}).QueryTags(a)
}
// Update returns a builder for updating this Article.
// Note that you need to call Article.Unwrap() before calling this method if this Article
// was returned from a transaction, and the transaction was committed or rolled back.
func (a *Article) Update() *ArticleUpdateOne {
return (&ArticleClient{config: a.config}).UpdateOne(a)
}
// Unwrap unwraps the Article entity that was returned from a transaction after it was closed,
// so that all future queries will be executed through the driver which created the transaction.
func (a *Article) Unwrap() *Article {
tx, ok := a.config.driver.(*txDriver)
if !ok {
panic("ent: Article is not a transactional entity")
}
a.config.driver = tx.drv
return a
}
// String implements the fmt.Stringer.
func (a *Article) String() string {
var builder strings.Builder
builder.WriteString("Article(")
builder.WriteString(fmt.Sprintf("id=%v", a.ID))
builder.WriteString(", title=")
builder.WriteString(a.Title)
builder.WriteString(", content=")
builder.WriteString(a.Content)
builder.WriteString(", created_at=")
builder.WriteString(a.CreatedAt.Format(time.ANSIC))
builder.WriteString(", updated_at=")
builder.WriteString(a.UpdatedAt.Format(time.ANSIC))
builder.WriteByte(')')
return builder.String()
}
// Articles is a parsable slice of Article.
type Articles []*Article
func (a Articles) config(cfg config) {
for _i := range a {
a[_i].config = cfg
}
}

@ -0,0 +1,74 @@
// Code generated by entc, DO NOT EDIT.
package article
import (
"time"
)
const (
// Label holds the string label denoting the article type in the database.
Label = "article"
// FieldID holds the string denoting the id field in the database.
FieldID = "id"
// FieldTitle holds the string denoting the title field in the database.
FieldTitle = "title"
// FieldContent holds the string denoting the content field in the database.
FieldContent = "content"
// FieldCreatedAt holds the string denoting the created_at field in the database.
FieldCreatedAt = "created_at"
// FieldUpdatedAt holds the string denoting the updated_at field in the database.
FieldUpdatedAt = "updated_at"
// EdgeComments holds the string denoting the comments edge name in mutations.
EdgeComments = "comments"
// EdgeTags holds the string denoting the tags edge name in mutations.
EdgeTags = "tags"
// Table holds the table name of the article in the database.
Table = "articles"
// CommentsTable is the table the holds the comments relation/edge.
CommentsTable = "comments"
// CommentsInverseTable is the table name for the Comment entity.
// It exists in this package in order to avoid circular dependency with the "comment" package.
CommentsInverseTable = "comments"
// CommentsColumn is the table column denoting the comments relation/edge.
CommentsColumn = "article_comments"
// TagsTable is the table the holds the tags relation/edge. The primary key declared below.
TagsTable = "tag_posts"
// TagsInverseTable is the table name for the Tag entity.
// It exists in this package in order to avoid circular dependency with the "tag" package.
TagsInverseTable = "tags"
)
// Columns holds all SQL columns for article fields.
var Columns = []string{
FieldID,
FieldTitle,
FieldContent,
FieldCreatedAt,
FieldUpdatedAt,
}
var (
// TagsPrimaryKey and TagsColumn2 are the table columns denoting the
// primary key for the tags relation (M2M).
TagsPrimaryKey = []string{"tag_id", "article_id"}
)
// ValidColumn reports if the column name is valid (part of the table columns).
func ValidColumn(column string) bool {
for i := range Columns {
if column == Columns[i] {
return true
}
}
return false
}
var (
// DefaultCreatedAt holds the default value on creation for the "created_at" field.
DefaultCreatedAt func() time.Time
// DefaultUpdatedAt holds the default value on creation for the "updated_at" field.
DefaultUpdatedAt func() time.Time
)

@ -0,0 +1,584 @@
// Code generated by entc, DO NOT EDIT.
package article
import (
"time"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"github.com/go-kratos/examples/blog/internal/data/ent/predicate"
)
// ID filters vertices based on their ID field.
func ID(id int64) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldID), id))
})
}
// IDEQ applies the EQ predicate on the ID field.
func IDEQ(id int64) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldID), id))
})
}
// IDNEQ applies the NEQ predicate on the ID field.
func IDNEQ(id int64) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.NEQ(s.C(FieldID), id))
})
}
// IDIn applies the In predicate on the ID field.
func IDIn(ids ...int64) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
// if not arguments were provided, append the FALSE constants,
// since we can't apply "IN ()". This will make this predicate falsy.
if len(ids) == 0 {
s.Where(sql.False())
return
}
v := make([]interface{}, len(ids))
for i := range v {
v[i] = ids[i]
}
s.Where(sql.In(s.C(FieldID), v...))
})
}
// IDNotIn applies the NotIn predicate on the ID field.
func IDNotIn(ids ...int64) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
// if not arguments were provided, append the FALSE constants,
// since we can't apply "IN ()". This will make this predicate falsy.
if len(ids) == 0 {
s.Where(sql.False())
return
}
v := make([]interface{}, len(ids))
for i := range v {
v[i] = ids[i]
}
s.Where(sql.NotIn(s.C(FieldID), v...))
})
}
// IDGT applies the GT predicate on the ID field.
func IDGT(id int64) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.GT(s.C(FieldID), id))
})
}
// IDGTE applies the GTE predicate on the ID field.
func IDGTE(id int64) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.GTE(s.C(FieldID), id))
})
}
// IDLT applies the LT predicate on the ID field.
func IDLT(id int64) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.LT(s.C(FieldID), id))
})
}
// IDLTE applies the LTE predicate on the ID field.
func IDLTE(id int64) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.LTE(s.C(FieldID), id))
})
}
// Title applies equality check predicate on the "title" field. It's identical to TitleEQ.
func Title(v string) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldTitle), v))
})
}
// Content applies equality check predicate on the "content" field. It's identical to ContentEQ.
func Content(v string) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldContent), v))
})
}
// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ.
func CreatedAt(v time.Time) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldCreatedAt), v))
})
}
// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ.
func UpdatedAt(v time.Time) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldUpdatedAt), v))
})
}
// TitleEQ applies the EQ predicate on the "title" field.
func TitleEQ(v string) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldTitle), v))
})
}
// TitleNEQ applies the NEQ predicate on the "title" field.
func TitleNEQ(v string) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.NEQ(s.C(FieldTitle), v))
})
}
// TitleIn applies the In predicate on the "title" field.
func TitleIn(vs ...string) predicate.Article {
v := make([]interface{}, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.Article(func(s *sql.Selector) {
// if not arguments were provided, append the FALSE constants,
// since we can't apply "IN ()". This will make this predicate falsy.
if len(v) == 0 {
s.Where(sql.False())
return
}
s.Where(sql.In(s.C(FieldTitle), v...))
})
}
// TitleNotIn applies the NotIn predicate on the "title" field.
func TitleNotIn(vs ...string) predicate.Article {
v := make([]interface{}, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.Article(func(s *sql.Selector) {
// if not arguments were provided, append the FALSE constants,
// since we can't apply "IN ()". This will make this predicate falsy.
if len(v) == 0 {
s.Where(sql.False())
return
}
s.Where(sql.NotIn(s.C(FieldTitle), v...))
})
}
// TitleGT applies the GT predicate on the "title" field.
func TitleGT(v string) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.GT(s.C(FieldTitle), v))
})
}
// TitleGTE applies the GTE predicate on the "title" field.
func TitleGTE(v string) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.GTE(s.C(FieldTitle), v))
})
}
// TitleLT applies the LT predicate on the "title" field.
func TitleLT(v string) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.LT(s.C(FieldTitle), v))
})
}
// TitleLTE applies the LTE predicate on the "title" field.
func TitleLTE(v string) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.LTE(s.C(FieldTitle), v))
})
}
// TitleContains applies the Contains predicate on the "title" field.
func TitleContains(v string) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.Contains(s.C(FieldTitle), v))
})
}
// TitleHasPrefix applies the HasPrefix predicate on the "title" field.
func TitleHasPrefix(v string) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.HasPrefix(s.C(FieldTitle), v))
})
}
// TitleHasSuffix applies the HasSuffix predicate on the "title" field.
func TitleHasSuffix(v string) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.HasSuffix(s.C(FieldTitle), v))
})
}
// TitleEqualFold applies the EqualFold predicate on the "title" field.
func TitleEqualFold(v string) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.EqualFold(s.C(FieldTitle), v))
})
}
// TitleContainsFold applies the ContainsFold predicate on the "title" field.
func TitleContainsFold(v string) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.ContainsFold(s.C(FieldTitle), v))
})
}
// ContentEQ applies the EQ predicate on the "content" field.
func ContentEQ(v string) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldContent), v))
})
}
// ContentNEQ applies the NEQ predicate on the "content" field.
func ContentNEQ(v string) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.NEQ(s.C(FieldContent), v))
})
}
// ContentIn applies the In predicate on the "content" field.
func ContentIn(vs ...string) predicate.Article {
v := make([]interface{}, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.Article(func(s *sql.Selector) {
// if not arguments were provided, append the FALSE constants,
// since we can't apply "IN ()". This will make this predicate falsy.
if len(v) == 0 {
s.Where(sql.False())
return
}
s.Where(sql.In(s.C(FieldContent), v...))
})
}
// ContentNotIn applies the NotIn predicate on the "content" field.
func ContentNotIn(vs ...string) predicate.Article {
v := make([]interface{}, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.Article(func(s *sql.Selector) {
// if not arguments were provided, append the FALSE constants,
// since we can't apply "IN ()". This will make this predicate falsy.
if len(v) == 0 {
s.Where(sql.False())
return
}
s.Where(sql.NotIn(s.C(FieldContent), v...))
})
}
// ContentGT applies the GT predicate on the "content" field.
func ContentGT(v string) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.GT(s.C(FieldContent), v))
})
}
// ContentGTE applies the GTE predicate on the "content" field.
func ContentGTE(v string) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.GTE(s.C(FieldContent), v))
})
}
// ContentLT applies the LT predicate on the "content" field.
func ContentLT(v string) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.LT(s.C(FieldContent), v))
})
}
// ContentLTE applies the LTE predicate on the "content" field.
func ContentLTE(v string) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.LTE(s.C(FieldContent), v))
})
}
// ContentContains applies the Contains predicate on the "content" field.
func ContentContains(v string) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.Contains(s.C(FieldContent), v))
})
}
// ContentHasPrefix applies the HasPrefix predicate on the "content" field.
func ContentHasPrefix(v string) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.HasPrefix(s.C(FieldContent), v))
})
}
// ContentHasSuffix applies the HasSuffix predicate on the "content" field.
func ContentHasSuffix(v string) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.HasSuffix(s.C(FieldContent), v))
})
}
// ContentEqualFold applies the EqualFold predicate on the "content" field.
func ContentEqualFold(v string) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.EqualFold(s.C(FieldContent), v))
})
}
// ContentContainsFold applies the ContainsFold predicate on the "content" field.
func ContentContainsFold(v string) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.ContainsFold(s.C(FieldContent), v))
})
}
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
func CreatedAtEQ(v time.Time) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldCreatedAt), v))
})
}
// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
func CreatedAtNEQ(v time.Time) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.NEQ(s.C(FieldCreatedAt), v))
})
}
// CreatedAtIn applies the In predicate on the "created_at" field.
func CreatedAtIn(vs ...time.Time) predicate.Article {
v := make([]interface{}, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.Article(func(s *sql.Selector) {
// if not arguments were provided, append the FALSE constants,
// since we can't apply "IN ()". This will make this predicate falsy.
if len(v) == 0 {
s.Where(sql.False())
return
}
s.Where(sql.In(s.C(FieldCreatedAt), v...))
})
}
// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
func CreatedAtNotIn(vs ...time.Time) predicate.Article {
v := make([]interface{}, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.Article(func(s *sql.Selector) {
// if not arguments were provided, append the FALSE constants,
// since we can't apply "IN ()". This will make this predicate falsy.
if len(v) == 0 {
s.Where(sql.False())
return
}
s.Where(sql.NotIn(s.C(FieldCreatedAt), v...))
})
}
// CreatedAtGT applies the GT predicate on the "created_at" field.
func CreatedAtGT(v time.Time) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.GT(s.C(FieldCreatedAt), v))
})
}
// CreatedAtGTE applies the GTE predicate on the "created_at" field.
func CreatedAtGTE(v time.Time) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.GTE(s.C(FieldCreatedAt), v))
})
}
// CreatedAtLT applies the LT predicate on the "created_at" field.
func CreatedAtLT(v time.Time) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.LT(s.C(FieldCreatedAt), v))
})
}
// CreatedAtLTE applies the LTE predicate on the "created_at" field.
func CreatedAtLTE(v time.Time) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.LTE(s.C(FieldCreatedAt), v))
})
}
// UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
func UpdatedAtEQ(v time.Time) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldUpdatedAt), v))
})
}
// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field.
func UpdatedAtNEQ(v time.Time) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.NEQ(s.C(FieldUpdatedAt), v))
})
}
// UpdatedAtIn applies the In predicate on the "updated_at" field.
func UpdatedAtIn(vs ...time.Time) predicate.Article {
v := make([]interface{}, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.Article(func(s *sql.Selector) {
// if not arguments were provided, append the FALSE constants,
// since we can't apply "IN ()". This will make this predicate falsy.
if len(v) == 0 {
s.Where(sql.False())
return
}
s.Where(sql.In(s.C(FieldUpdatedAt), v...))
})
}
// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field.
func UpdatedAtNotIn(vs ...time.Time) predicate.Article {
v := make([]interface{}, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.Article(func(s *sql.Selector) {
// if not arguments were provided, append the FALSE constants,
// since we can't apply "IN ()". This will make this predicate falsy.
if len(v) == 0 {
s.Where(sql.False())
return
}
s.Where(sql.NotIn(s.C(FieldUpdatedAt), v...))
})
}
// UpdatedAtGT applies the GT predicate on the "updated_at" field.
func UpdatedAtGT(v time.Time) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.GT(s.C(FieldUpdatedAt), v))
})
}
// UpdatedAtGTE applies the GTE predicate on the "updated_at" field.
func UpdatedAtGTE(v time.Time) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.GTE(s.C(FieldUpdatedAt), v))
})
}
// UpdatedAtLT applies the LT predicate on the "updated_at" field.
func UpdatedAtLT(v time.Time) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.LT(s.C(FieldUpdatedAt), v))
})
}
// UpdatedAtLTE applies the LTE predicate on the "updated_at" field.
func UpdatedAtLTE(v time.Time) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s.Where(sql.LTE(s.C(FieldUpdatedAt), v))
})
}
// HasComments applies the HasEdge predicate on the "comments" edge.
func HasComments() predicate.Article {
return predicate.Article(func(s *sql.Selector) {
step := sqlgraph.NewStep(
sqlgraph.From(Table, FieldID),
sqlgraph.To(CommentsTable, FieldID),
sqlgraph.Edge(sqlgraph.O2M, false, CommentsTable, CommentsColumn),
)
sqlgraph.HasNeighbors(s, step)
})
}
// HasCommentsWith applies the HasEdge predicate on the "comments" edge with a given conditions (other predicates).
func HasCommentsWith(preds ...predicate.Comment) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
step := sqlgraph.NewStep(
sqlgraph.From(Table, FieldID),
sqlgraph.To(CommentsInverseTable, FieldID),
sqlgraph.Edge(sqlgraph.O2M, false, CommentsTable, CommentsColumn),
)
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
for _, p := range preds {
p(s)
}
})
})
}
// HasTags applies the HasEdge predicate on the "tags" edge.
func HasTags() predicate.Article {
return predicate.Article(func(s *sql.Selector) {
step := sqlgraph.NewStep(
sqlgraph.From(Table, FieldID),
sqlgraph.To(TagsTable, FieldID),
sqlgraph.Edge(sqlgraph.M2M, true, TagsTable, TagsPrimaryKey...),
)
sqlgraph.HasNeighbors(s, step)
})
}
// HasTagsWith applies the HasEdge predicate on the "tags" edge with a given conditions (other predicates).
func HasTagsWith(preds ...predicate.Tag) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
step := sqlgraph.NewStep(
sqlgraph.From(Table, FieldID),
sqlgraph.To(TagsInverseTable, FieldID),
sqlgraph.Edge(sqlgraph.M2M, true, TagsTable, TagsPrimaryKey...),
)
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
for _, p := range preds {
p(s)
}
})
})
}
// And groups predicates with the AND operator between them.
func And(predicates ...predicate.Article) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s1 := s.Clone().SetP(nil)
for _, p := range predicates {
p(s1)
}
s.Where(s1.P())
})
}
// Or groups predicates with the OR operator between them.
func Or(predicates ...predicate.Article) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
s1 := s.Clone().SetP(nil)
for i, p := range predicates {
if i > 0 {
s1.Or()
}
p(s1)
}
s.Where(s1.P())
})
}
// Not applies the not operator on the given predicate.
func Not(p predicate.Article) predicate.Article {
return predicate.Article(func(s *sql.Selector) {
p(s.Not())
})
}

@ -0,0 +1,350 @@
// Code generated by entc, DO NOT EDIT.
package ent
import (
"context"
"errors"
"fmt"
"time"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
"github.com/go-kratos/examples/blog/internal/data/ent/article"
"github.com/go-kratos/examples/blog/internal/data/ent/comment"
"github.com/go-kratos/examples/blog/internal/data/ent/tag"
)
// ArticleCreate is the builder for creating a Article entity.
type ArticleCreate struct {
config
mutation *ArticleMutation
hooks []Hook
}
// SetTitle sets the "title" field.
func (ac *ArticleCreate) SetTitle(s string) *ArticleCreate {
ac.mutation.SetTitle(s)
return ac
}
// SetContent sets the "content" field.
func (ac *ArticleCreate) SetContent(s string) *ArticleCreate {
ac.mutation.SetContent(s)
return ac
}
// SetCreatedAt sets the "created_at" field.
func (ac *ArticleCreate) SetCreatedAt(t time.Time) *ArticleCreate {
ac.mutation.SetCreatedAt(t)
return ac
}
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
func (ac *ArticleCreate) SetNillableCreatedAt(t *time.Time) *ArticleCreate {
if t != nil {
ac.SetCreatedAt(*t)
}
return ac
}
// SetUpdatedAt sets the "updated_at" field.
func (ac *ArticleCreate) SetUpdatedAt(t time.Time) *ArticleCreate {
ac.mutation.SetUpdatedAt(t)
return ac
}
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
func (ac *ArticleCreate) SetNillableUpdatedAt(t *time.Time) *ArticleCreate {
if t != nil {
ac.SetUpdatedAt(*t)
}
return ac
}
// SetID sets the "id" field.
func (ac *ArticleCreate) SetID(i int64) *ArticleCreate {
ac.mutation.SetID(i)
return ac
}
// AddCommentIDs adds the "comments" edge to the Comment entity by IDs.
func (ac *ArticleCreate) AddCommentIDs(ids ...int64) *ArticleCreate {
ac.mutation.AddCommentIDs(ids...)
return ac
}
// AddComments adds the "comments" edges to the Comment entity.
func (ac *ArticleCreate) AddComments(c ...*Comment) *ArticleCreate {
ids := make([]int64, len(c))
for i := range c {
ids[i] = c[i].ID
}
return ac.AddCommentIDs(ids...)
}
// AddTagIDs adds the "tags" edge to the Tag entity by IDs.
func (ac *ArticleCreate) AddTagIDs(ids ...int64) *ArticleCreate {
ac.mutation.AddTagIDs(ids...)
return ac
}
// AddTags adds the "tags" edges to the Tag entity.
func (ac *ArticleCreate) AddTags(t ...*Tag) *ArticleCreate {
ids := make([]int64, len(t))
for i := range t {
ids[i] = t[i].ID
}
return ac.AddTagIDs(ids...)
}
// Mutation returns the ArticleMutation object of the builder.
func (ac *ArticleCreate) Mutation() *ArticleMutation {
return ac.mutation
}
// Save creates the Article in the database.
func (ac *ArticleCreate) Save(ctx context.Context) (*Article, error) {
var (
err error
node *Article
)
ac.defaults()
if len(ac.hooks) == 0 {
if err = ac.check(); err != nil {
return nil, err
}
node, err = ac.sqlSave(ctx)
} else {
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
mutation, ok := m.(*ArticleMutation)
if !ok {
return nil, fmt.Errorf("unexpected mutation type %T", m)
}
if err = ac.check(); err != nil {
return nil, err
}
ac.mutation = mutation
node, err = ac.sqlSave(ctx)
mutation.done = true
return node, err
})
for i := len(ac.hooks) - 1; i >= 0; i-- {
mut = ac.hooks[i](mut)
}
if _, err := mut.Mutate(ctx, ac.mutation); err != nil {
return nil, err
}
}
return node, err
}
// SaveX calls Save and panics if Save returns an error.
func (ac *ArticleCreate) SaveX(ctx context.Context) *Article {
v, err := ac.Save(ctx)
if err != nil {
panic(err)
}
return v
}
// defaults sets the default values of the builder before save.
func (ac *ArticleCreate) defaults() {
if _, ok := ac.mutation.CreatedAt(); !ok {
v := article.DefaultCreatedAt()
ac.mutation.SetCreatedAt(v)
}
if _, ok := ac.mutation.UpdatedAt(); !ok {
v := article.DefaultUpdatedAt()
ac.mutation.SetUpdatedAt(v)
}
}
// check runs all checks and user-defined validators on the builder.
func (ac *ArticleCreate) check() error {
if _, ok := ac.mutation.Title(); !ok {
return &ValidationError{Name: "title", err: errors.New("ent: missing required field \"title\"")}
}
if _, ok := ac.mutation.Content(); !ok {
return &ValidationError{Name: "content", err: errors.New("ent: missing required field \"content\"")}
}
if _, ok := ac.mutation.CreatedAt(); !ok {
return &ValidationError{Name: "created_at", err: errors.New("ent: missing required field \"created_at\"")}
}
if _, ok := ac.mutation.UpdatedAt(); !ok {
return &ValidationError{Name: "updated_at", err: errors.New("ent: missing required field \"updated_at\"")}
}
return nil
}
func (ac *ArticleCreate) sqlSave(ctx context.Context) (*Article, error) {
_node, _spec := ac.createSpec()
if err := sqlgraph.CreateNode(ctx, ac.driver, _spec); err != nil {
if cerr, ok := isSQLConstraintError(err); ok {
err = cerr
}
return nil, err
}
if _node.ID == 0 {
id := _spec.ID.Value.(int64)
_node.ID = int64(id)
}
return _node, nil
}
func (ac *ArticleCreate) createSpec() (*Article, *sqlgraph.CreateSpec) {
var (
_node = &Article{config: ac.config}
_spec = &sqlgraph.CreateSpec{
Table: article.Table,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: article.FieldID,
},
}
)
if id, ok := ac.mutation.ID(); ok {
_node.ID = id
_spec.ID.Value = id
}
if value, ok := ac.mutation.Title(); ok {
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: value,
Column: article.FieldTitle,
})
_node.Title = value
}
if value, ok := ac.mutation.Content(); ok {
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: value,
Column: article.FieldContent,
})
_node.Content = value
}
if value, ok := ac.mutation.CreatedAt(); ok {
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeTime,
Value: value,
Column: article.FieldCreatedAt,
})
_node.CreatedAt = value
}
if value, ok := ac.mutation.UpdatedAt(); ok {
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeTime,
Value: value,
Column: article.FieldUpdatedAt,
})
_node.UpdatedAt = value
}
if nodes := ac.mutation.CommentsIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2M,
Inverse: false,
Table: article.CommentsTable,
Columns: []string{article.CommentsColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: comment.FieldID,
},
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges = append(_spec.Edges, edge)
}
if nodes := ac.mutation.TagsIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2M,
Inverse: true,
Table: article.TagsTable,
Columns: article.TagsPrimaryKey,
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: tag.FieldID,
},
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges = append(_spec.Edges, edge)
}
return _node, _spec
}
// ArticleCreateBulk is the builder for creating many Article entities in bulk.
type ArticleCreateBulk struct {
config
builders []*ArticleCreate
}
// Save creates the Article entities in the database.
func (acb *ArticleCreateBulk) Save(ctx context.Context) ([]*Article, error) {
specs := make([]*sqlgraph.CreateSpec, len(acb.builders))
nodes := make([]*Article, len(acb.builders))
mutators := make([]Mutator, len(acb.builders))
for i := range acb.builders {
func(i int, root context.Context) {
builder := acb.builders[i]
builder.defaults()
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
mutation, ok := m.(*ArticleMutation)
if !ok {
return nil, fmt.Errorf("unexpected mutation type %T", m)
}
if err := builder.check(); err != nil {
return nil, err
}
builder.mutation = mutation
nodes[i], specs[i] = builder.createSpec()
var err error
if i < len(mutators)-1 {
_, err = mutators[i+1].Mutate(root, acb.builders[i+1].mutation)
} else {
// Invoke the actual operation on the latest mutation in the chain.
if err = sqlgraph.BatchCreate(ctx, acb.driver, &sqlgraph.BatchCreateSpec{Nodes: specs}); err != nil {
if cerr, ok := isSQLConstraintError(err); ok {
err = cerr
}
}
}
mutation.done = true
if err != nil {
return nil, err
}
if nodes[i].ID == 0 {
id := specs[i].ID.Value.(int64)
nodes[i].ID = int64(id)
}
return nodes[i], nil
})
for i := len(builder.hooks) - 1; i >= 0; i-- {
mut = builder.hooks[i](mut)
}
mutators[i] = mut
}(i, ctx)
}
if len(mutators) > 0 {
if _, err := mutators[0].Mutate(ctx, acb.builders[0].mutation); err != nil {
return nil, err
}
}
return nodes, nil
}
// SaveX is like Save, but panics if an error occurs.
func (acb *ArticleCreateBulk) SaveX(ctx context.Context) []*Article {
v, err := acb.Save(ctx)
if err != nil {
panic(err)
}
return v
}

@ -0,0 +1,108 @@
// Code generated by entc, DO NOT EDIT.
package ent
import (
"context"
"fmt"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
"github.com/go-kratos/examples/blog/internal/data/ent/article"
"github.com/go-kratos/examples/blog/internal/data/ent/predicate"
)
// ArticleDelete is the builder for deleting a Article entity.
type ArticleDelete struct {
config
hooks []Hook
mutation *ArticleMutation
}
// Where adds a new predicate to the ArticleDelete builder.
func (ad *ArticleDelete) Where(ps ...predicate.Article) *ArticleDelete {
ad.mutation.predicates = append(ad.mutation.predicates, ps...)
return ad
}
// Exec executes the deletion query and returns how many vertices were deleted.
func (ad *ArticleDelete) Exec(ctx context.Context) (int, error) {
var (
err error
affected int
)
if len(ad.hooks) == 0 {
affected, err = ad.sqlExec(ctx)
} else {
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
mutation, ok := m.(*ArticleMutation)
if !ok {
return nil, fmt.Errorf("unexpected mutation type %T", m)
}
ad.mutation = mutation
affected, err = ad.sqlExec(ctx)
mutation.done = true
return affected, err
})
for i := len(ad.hooks) - 1; i >= 0; i-- {
mut = ad.hooks[i](mut)
}
if _, err := mut.Mutate(ctx, ad.mutation); err != nil {
return 0, err
}
}
return affected, err
}
// ExecX is like Exec, but panics if an error occurs.
func (ad *ArticleDelete) ExecX(ctx context.Context) int {
n, err := ad.Exec(ctx)
if err != nil {
panic(err)
}
return n
}
func (ad *ArticleDelete) sqlExec(ctx context.Context) (int, error) {
_spec := &sqlgraph.DeleteSpec{
Node: &sqlgraph.NodeSpec{
Table: article.Table,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: article.FieldID,
},
},
}
if ps := ad.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
return sqlgraph.DeleteNodes(ctx, ad.driver, _spec)
}
// ArticleDeleteOne is the builder for deleting a single Article entity.
type ArticleDeleteOne struct {
ad *ArticleDelete
}
// Exec executes the deletion query.
func (ado *ArticleDeleteOne) Exec(ctx context.Context) error {
n, err := ado.ad.Exec(ctx)
switch {
case err != nil:
return err
case n == 0:
return &NotFoundError{article.Label}
default:
return nil
}
}
// ExecX is like Exec, but panics if an error occurs.
func (ado *ArticleDeleteOne) ExecX(ctx context.Context) {
ado.ad.ExecX(ctx)
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,711 @@
// Code generated by entc, DO NOT EDIT.
package ent
import (
"context"
"fmt"
"time"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
"github.com/go-kratos/examples/blog/internal/data/ent/article"
"github.com/go-kratos/examples/blog/internal/data/ent/comment"
"github.com/go-kratos/examples/blog/internal/data/ent/predicate"
"github.com/go-kratos/examples/blog/internal/data/ent/tag"
)
// ArticleUpdate is the builder for updating Article entities.
type ArticleUpdate struct {
config
hooks []Hook
mutation *ArticleMutation
}
// Where adds a new predicate for the ArticleUpdate builder.
func (au *ArticleUpdate) Where(ps ...predicate.Article) *ArticleUpdate {
au.mutation.predicates = append(au.mutation.predicates, ps...)
return au
}
// SetTitle sets the "title" field.
func (au *ArticleUpdate) SetTitle(s string) *ArticleUpdate {
au.mutation.SetTitle(s)
return au
}
// SetContent sets the "content" field.
func (au *ArticleUpdate) SetContent(s string) *ArticleUpdate {
au.mutation.SetContent(s)
return au
}
// SetCreatedAt sets the "created_at" field.
func (au *ArticleUpdate) SetCreatedAt(t time.Time) *ArticleUpdate {
au.mutation.SetCreatedAt(t)
return au
}
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
func (au *ArticleUpdate) SetNillableCreatedAt(t *time.Time) *ArticleUpdate {
if t != nil {
au.SetCreatedAt(*t)
}
return au
}
// SetUpdatedAt sets the "updated_at" field.
func (au *ArticleUpdate) SetUpdatedAt(t time.Time) *ArticleUpdate {
au.mutation.SetUpdatedAt(t)
return au
}
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
func (au *ArticleUpdate) SetNillableUpdatedAt(t *time.Time) *ArticleUpdate {
if t != nil {
au.SetUpdatedAt(*t)
}
return au
}
// AddCommentIDs adds the "comments" edge to the Comment entity by IDs.
func (au *ArticleUpdate) AddCommentIDs(ids ...int64) *ArticleUpdate {
au.mutation.AddCommentIDs(ids...)
return au
}
// AddComments adds the "comments" edges to the Comment entity.
func (au *ArticleUpdate) AddComments(c ...*Comment) *ArticleUpdate {
ids := make([]int64, len(c))
for i := range c {
ids[i] = c[i].ID
}
return au.AddCommentIDs(ids...)
}
// AddTagIDs adds the "tags" edge to the Tag entity by IDs.
func (au *ArticleUpdate) AddTagIDs(ids ...int64) *ArticleUpdate {
au.mutation.AddTagIDs(ids...)
return au
}
// AddTags adds the "tags" edges to the Tag entity.
func (au *ArticleUpdate) AddTags(t ...*Tag) *ArticleUpdate {
ids := make([]int64, len(t))
for i := range t {
ids[i] = t[i].ID
}
return au.AddTagIDs(ids...)
}
// Mutation returns the ArticleMutation object of the builder.
func (au *ArticleUpdate) Mutation() *ArticleMutation {
return au.mutation
}
// ClearComments clears all "comments" edges to the Comment entity.
func (au *ArticleUpdate) ClearComments() *ArticleUpdate {
au.mutation.ClearComments()
return au
}
// RemoveCommentIDs removes the "comments" edge to Comment entities by IDs.
func (au *ArticleUpdate) RemoveCommentIDs(ids ...int64) *ArticleUpdate {
au.mutation.RemoveCommentIDs(ids...)
return au
}
// RemoveComments removes "comments" edges to Comment entities.
func (au *ArticleUpdate) RemoveComments(c ...*Comment) *ArticleUpdate {
ids := make([]int64, len(c))
for i := range c {
ids[i] = c[i].ID
}
return au.RemoveCommentIDs(ids...)
}
// ClearTags clears all "tags" edges to the Tag entity.
func (au *ArticleUpdate) ClearTags() *ArticleUpdate {
au.mutation.ClearTags()
return au
}
// RemoveTagIDs removes the "tags" edge to Tag entities by IDs.
func (au *ArticleUpdate) RemoveTagIDs(ids ...int64) *ArticleUpdate {
au.mutation.RemoveTagIDs(ids...)
return au
}
// RemoveTags removes "tags" edges to Tag entities.
func (au *ArticleUpdate) RemoveTags(t ...*Tag) *ArticleUpdate {
ids := make([]int64, len(t))
for i := range t {
ids[i] = t[i].ID
}
return au.RemoveTagIDs(ids...)
}
// Save executes the query and returns the number of nodes affected by the update operation.
func (au *ArticleUpdate) Save(ctx context.Context) (int, error) {
var (
err error
affected int
)
if len(au.hooks) == 0 {
affected, err = au.sqlSave(ctx)
} else {
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
mutation, ok := m.(*ArticleMutation)
if !ok {
return nil, fmt.Errorf("unexpected mutation type %T", m)
}
au.mutation = mutation
affected, err = au.sqlSave(ctx)
mutation.done = true
return affected, err
})
for i := len(au.hooks) - 1; i >= 0; i-- {
mut = au.hooks[i](mut)
}
if _, err := mut.Mutate(ctx, au.mutation); err != nil {
return 0, err
}
}
return affected, err
}
// SaveX is like Save, but panics if an error occurs.
func (au *ArticleUpdate) SaveX(ctx context.Context) int {
affected, err := au.Save(ctx)
if err != nil {
panic(err)
}
return affected
}
// Exec executes the query.
func (au *ArticleUpdate) Exec(ctx context.Context) error {
_, err := au.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (au *ArticleUpdate) ExecX(ctx context.Context) {
if err := au.Exec(ctx); err != nil {
panic(err)
}
}
func (au *ArticleUpdate) sqlSave(ctx context.Context) (n int, err error) {
_spec := &sqlgraph.UpdateSpec{
Node: &sqlgraph.NodeSpec{
Table: article.Table,
Columns: article.Columns,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: article.FieldID,
},
},
}
if ps := au.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
if value, ok := au.mutation.Title(); ok {
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: value,
Column: article.FieldTitle,
})
}
if value, ok := au.mutation.Content(); ok {
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: value,
Column: article.FieldContent,
})
}
if value, ok := au.mutation.CreatedAt(); ok {
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
Type: field.TypeTime,
Value: value,
Column: article.FieldCreatedAt,
})
}
if value, ok := au.mutation.UpdatedAt(); ok {
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
Type: field.TypeTime,
Value: value,
Column: article.FieldUpdatedAt,
})
}
if au.mutation.CommentsCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2M,
Inverse: false,
Table: article.CommentsTable,
Columns: []string{article.CommentsColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: comment.FieldID,
},
},
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := au.mutation.RemovedCommentsIDs(); len(nodes) > 0 && !au.mutation.CommentsCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2M,
Inverse: false,
Table: article.CommentsTable,
Columns: []string{article.CommentsColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: comment.FieldID,
},
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := au.mutation.CommentsIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2M,
Inverse: false,
Table: article.CommentsTable,
Columns: []string{article.CommentsColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: comment.FieldID,
},
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Add = append(_spec.Edges.Add, edge)
}
if au.mutation.TagsCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2M,
Inverse: true,
Table: article.TagsTable,
Columns: article.TagsPrimaryKey,
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: tag.FieldID,
},
},
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := au.mutation.RemovedTagsIDs(); len(nodes) > 0 && !au.mutation.TagsCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2M,
Inverse: true,
Table: article.TagsTable,
Columns: article.TagsPrimaryKey,
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: tag.FieldID,
},
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := au.mutation.TagsIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2M,
Inverse: true,
Table: article.TagsTable,
Columns: article.TagsPrimaryKey,
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: tag.FieldID,
},
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Add = append(_spec.Edges.Add, edge)
}
if n, err = sqlgraph.UpdateNodes(ctx, au.driver, _spec); err != nil {
if _, ok := err.(*sqlgraph.NotFoundError); ok {
err = &NotFoundError{article.Label}
} else if cerr, ok := isSQLConstraintError(err); ok {
err = cerr
}
return 0, err
}
return n, nil
}
// ArticleUpdateOne is the builder for updating a single Article entity.
type ArticleUpdateOne struct {
config
hooks []Hook
mutation *ArticleMutation
}
// SetTitle sets the "title" field.
func (auo *ArticleUpdateOne) SetTitle(s string) *ArticleUpdateOne {
auo.mutation.SetTitle(s)
return auo
}
// SetContent sets the "content" field.
func (auo *ArticleUpdateOne) SetContent(s string) *ArticleUpdateOne {
auo.mutation.SetContent(s)
return auo
}
// SetCreatedAt sets the "created_at" field.
func (auo *ArticleUpdateOne) SetCreatedAt(t time.Time) *ArticleUpdateOne {
auo.mutation.SetCreatedAt(t)
return auo
}
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
func (auo *ArticleUpdateOne) SetNillableCreatedAt(t *time.Time) *ArticleUpdateOne {
if t != nil {
auo.SetCreatedAt(*t)
}
return auo
}
// SetUpdatedAt sets the "updated_at" field.
func (auo *ArticleUpdateOne) SetUpdatedAt(t time.Time) *ArticleUpdateOne {
auo.mutation.SetUpdatedAt(t)
return auo
}
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
func (auo *ArticleUpdateOne) SetNillableUpdatedAt(t *time.Time) *ArticleUpdateOne {
if t != nil {
auo.SetUpdatedAt(*t)
}
return auo
}
// AddCommentIDs adds the "comments" edge to the Comment entity by IDs.
func (auo *ArticleUpdateOne) AddCommentIDs(ids ...int64) *ArticleUpdateOne {
auo.mutation.AddCommentIDs(ids...)
return auo
}
// AddComments adds the "comments" edges to the Comment entity.
func (auo *ArticleUpdateOne) AddComments(c ...*Comment) *ArticleUpdateOne {
ids := make([]int64, len(c))
for i := range c {
ids[i] = c[i].ID
}
return auo.AddCommentIDs(ids...)
}
// AddTagIDs adds the "tags" edge to the Tag entity by IDs.
func (auo *ArticleUpdateOne) AddTagIDs(ids ...int64) *ArticleUpdateOne {
auo.mutation.AddTagIDs(ids...)
return auo
}
// AddTags adds the "tags" edges to the Tag entity.
func (auo *ArticleUpdateOne) AddTags(t ...*Tag) *ArticleUpdateOne {
ids := make([]int64, len(t))
for i := range t {
ids[i] = t[i].ID
}
return auo.AddTagIDs(ids...)
}
// Mutation returns the ArticleMutation object of the builder.
func (auo *ArticleUpdateOne) Mutation() *ArticleMutation {
return auo.mutation
}
// ClearComments clears all "comments" edges to the Comment entity.
func (auo *ArticleUpdateOne) ClearComments() *ArticleUpdateOne {
auo.mutation.ClearComments()
return auo
}
// RemoveCommentIDs removes the "comments" edge to Comment entities by IDs.
func (auo *ArticleUpdateOne) RemoveCommentIDs(ids ...int64) *ArticleUpdateOne {
auo.mutation.RemoveCommentIDs(ids...)
return auo
}
// RemoveComments removes "comments" edges to Comment entities.
func (auo *ArticleUpdateOne) RemoveComments(c ...*Comment) *ArticleUpdateOne {
ids := make([]int64, len(c))
for i := range c {
ids[i] = c[i].ID
}
return auo.RemoveCommentIDs(ids...)
}
// ClearTags clears all "tags" edges to the Tag entity.
func (auo *ArticleUpdateOne) ClearTags() *ArticleUpdateOne {
auo.mutation.ClearTags()
return auo
}
// RemoveTagIDs removes the "tags" edge to Tag entities by IDs.
func (auo *ArticleUpdateOne) RemoveTagIDs(ids ...int64) *ArticleUpdateOne {
auo.mutation.RemoveTagIDs(ids...)
return auo
}
// RemoveTags removes "tags" edges to Tag entities.
func (auo *ArticleUpdateOne) RemoveTags(t ...*Tag) *ArticleUpdateOne {
ids := make([]int64, len(t))
for i := range t {
ids[i] = t[i].ID
}
return auo.RemoveTagIDs(ids...)
}
// Save executes the query and returns the updated Article entity.
func (auo *ArticleUpdateOne) Save(ctx context.Context) (*Article, error) {
var (
err error
node *Article
)
if len(auo.hooks) == 0 {
node, err = auo.sqlSave(ctx)
} else {
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
mutation, ok := m.(*ArticleMutation)
if !ok {
return nil, fmt.Errorf("unexpected mutation type %T", m)
}
auo.mutation = mutation
node, err = auo.sqlSave(ctx)
mutation.done = true
return node, err
})
for i := len(auo.hooks) - 1; i >= 0; i-- {
mut = auo.hooks[i](mut)
}
if _, err := mut.Mutate(ctx, auo.mutation); err != nil {
return nil, err
}
}
return node, err
}
// SaveX is like Save, but panics if an error occurs.
func (auo *ArticleUpdateOne) SaveX(ctx context.Context) *Article {
node, err := auo.Save(ctx)
if err != nil {
panic(err)
}
return node
}
// Exec executes the query on the entity.
func (auo *ArticleUpdateOne) Exec(ctx context.Context) error {
_, err := auo.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (auo *ArticleUpdateOne) ExecX(ctx context.Context) {
if err := auo.Exec(ctx); err != nil {
panic(err)
}
}
func (auo *ArticleUpdateOne) sqlSave(ctx context.Context) (_node *Article, err error) {
_spec := &sqlgraph.UpdateSpec{
Node: &sqlgraph.NodeSpec{
Table: article.Table,
Columns: article.Columns,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: article.FieldID,
},
},
}
id, ok := auo.mutation.ID()
if !ok {
return nil, &ValidationError{Name: "ID", err: fmt.Errorf("missing Article.ID for update")}
}
_spec.Node.ID.Value = id
if ps := auo.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
if value, ok := auo.mutation.Title(); ok {
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: value,
Column: article.FieldTitle,
})
}
if value, ok := auo.mutation.Content(); ok {
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: value,
Column: article.FieldContent,
})
}
if value, ok := auo.mutation.CreatedAt(); ok {
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
Type: field.TypeTime,
Value: value,
Column: article.FieldCreatedAt,
})
}
if value, ok := auo.mutation.UpdatedAt(); ok {
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
Type: field.TypeTime,
Value: value,
Column: article.FieldUpdatedAt,
})
}
if auo.mutation.CommentsCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2M,
Inverse: false,
Table: article.CommentsTable,
Columns: []string{article.CommentsColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: comment.FieldID,
},
},
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := auo.mutation.RemovedCommentsIDs(); len(nodes) > 0 && !auo.mutation.CommentsCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2M,
Inverse: false,
Table: article.CommentsTable,
Columns: []string{article.CommentsColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: comment.FieldID,
},
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := auo.mutation.CommentsIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2M,
Inverse: false,
Table: article.CommentsTable,
Columns: []string{article.CommentsColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: comment.FieldID,
},
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Add = append(_spec.Edges.Add, edge)
}
if auo.mutation.TagsCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2M,
Inverse: true,
Table: article.TagsTable,
Columns: article.TagsPrimaryKey,
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: tag.FieldID,
},
},
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := auo.mutation.RemovedTagsIDs(); len(nodes) > 0 && !auo.mutation.TagsCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2M,
Inverse: true,
Table: article.TagsTable,
Columns: article.TagsPrimaryKey,
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: tag.FieldID,
},
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := auo.mutation.TagsIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2M,
Inverse: true,
Table: article.TagsTable,
Columns: article.TagsPrimaryKey,
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: tag.FieldID,
},
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Add = append(_spec.Edges.Add, edge)
}
_node = &Article{config: auo.config}
_spec.Assign = _node.assignValues
_spec.ScanValues = _node.scanValues
if err = sqlgraph.UpdateNode(ctx, auo.driver, _spec); err != nil {
if _, ok := err.(*sqlgraph.NotFoundError); ok {
err = &NotFoundError{article.Label}
} else if cerr, ok := isSQLConstraintError(err); ok {
err = cerr
}
return nil, err
}
return _node, nil
}

@ -0,0 +1,465 @@
// Code generated by entc, DO NOT EDIT.
package ent
import (
"context"
"fmt"
"log"
"github.com/go-kratos/examples/blog/internal/data/ent/migrate"
"github.com/go-kratos/examples/blog/internal/data/ent/article"
"github.com/go-kratos/examples/blog/internal/data/ent/comment"
"github.com/go-kratos/examples/blog/internal/data/ent/tag"
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
)
// Client is the client that holds all ent builders.
type Client struct {
config
// Schema is the client for creating, migrating and dropping schema.
Schema *migrate.Schema
// Article is the client for interacting with the Article builders.
Article *ArticleClient
// Comment is the client for interacting with the Comment builders.
Comment *CommentClient
// Tag is the client for interacting with the Tag builders.
Tag *TagClient
}
// NewClient creates a new client configured with the given options.
func NewClient(opts ...Option) *Client {
cfg := config{log: log.Println, hooks: &hooks{}}
cfg.options(opts...)
client := &Client{config: cfg}
client.init()
return client
}
func (c *Client) init() {
c.Schema = migrate.NewSchema(c.driver)
c.Article = NewArticleClient(c.config)
c.Comment = NewCommentClient(c.config)
c.Tag = NewTagClient(c.config)
}
// Open opens a database/sql.DB specified by the driver name and
// the data source name, and returns a new client attached to it.
// Optional parameters can be added for configuring the client.
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite:
drv, err := sql.Open(driverName, dataSourceName)
if err != nil {
return nil, err
}
return NewClient(append(options, Driver(drv))...), nil
default:
return nil, fmt.Errorf("unsupported driver: %q", driverName)
}
}
// Tx returns a new transactional client. The provided context
// is used until the transaction is committed or rolled back.
func (c *Client) Tx(ctx context.Context) (*Tx, error) {
if _, ok := c.driver.(*txDriver); ok {
return nil, fmt.Errorf("ent: cannot start a transaction within a transaction")
}
tx, err := newTx(ctx, c.driver)
if err != nil {
return nil, fmt.Errorf("ent: starting a transaction: %v", err)
}
cfg := c.config
cfg.driver = tx
return &Tx{
ctx: ctx,
config: cfg,
Article: NewArticleClient(cfg),
Comment: NewCommentClient(cfg),
Tag: NewTagClient(cfg),
}, nil
}
// BeginTx returns a transactional client with specified options.
func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error) {
if _, ok := c.driver.(*txDriver); ok {
return nil, fmt.Errorf("ent: cannot start a transaction within a transaction")
}
tx, err := c.driver.(interface {
BeginTx(context.Context, *sql.TxOptions) (dialect.Tx, error)
}).BeginTx(ctx, opts)
if err != nil {
return nil, fmt.Errorf("ent: starting a transaction: %v", err)
}
cfg := c.config
cfg.driver = &txDriver{tx: tx, drv: c.driver}
return &Tx{
config: cfg,
Article: NewArticleClient(cfg),
Comment: NewCommentClient(cfg),
Tag: NewTagClient(cfg),
}, nil
}
// Debug returns a new debug-client. It's used to get verbose logging on specific operations.
//
// client.Debug().
// Article.
// Query().
// Count(ctx)
//
func (c *Client) Debug() *Client {
if c.debug {
return c
}
cfg := c.config
cfg.driver = dialect.Debug(c.driver, c.log)
client := &Client{config: cfg}
client.init()
return client
}
// Close closes the database connection and prevents new queries from starting.
func (c *Client) Close() error {
return c.driver.Close()
}
// Use adds the mutation hooks to all the entity clients.
// In order to add hooks to a specific client, call: `client.Node.Use(...)`.
func (c *Client) Use(hooks ...Hook) {
c.Article.Use(hooks...)
c.Comment.Use(hooks...)
c.Tag.Use(hooks...)
}
// ArticleClient is a client for the Article schema.
type ArticleClient struct {
config
}
// NewArticleClient returns a client for the Article from the given config.
func NewArticleClient(c config) *ArticleClient {
return &ArticleClient{config: c}
}
// Use adds a list of mutation hooks to the hooks stack.
// A call to `Use(f, g, h)` equals to `article.Hooks(f(g(h())))`.
func (c *ArticleClient) Use(hooks ...Hook) {
c.hooks.Article = append(c.hooks.Article, hooks...)
}
// Create returns a create builder for Article.
func (c *ArticleClient) Create() *ArticleCreate {
mutation := newArticleMutation(c.config, OpCreate)
return &ArticleCreate{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// CreateBulk returns a builder for creating a bulk of Article entities.
func (c *ArticleClient) CreateBulk(builders ...*ArticleCreate) *ArticleCreateBulk {
return &ArticleCreateBulk{config: c.config, builders: builders}
}
// Update returns an update builder for Article.
func (c *ArticleClient) Update() *ArticleUpdate {
mutation := newArticleMutation(c.config, OpUpdate)
return &ArticleUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// UpdateOne returns an update builder for the given entity.
func (c *ArticleClient) UpdateOne(a *Article) *ArticleUpdateOne {
mutation := newArticleMutation(c.config, OpUpdateOne, withArticle(a))
return &ArticleUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// UpdateOneID returns an update builder for the given id.
func (c *ArticleClient) UpdateOneID(id int64) *ArticleUpdateOne {
mutation := newArticleMutation(c.config, OpUpdateOne, withArticleID(id))
return &ArticleUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// Delete returns a delete builder for Article.
func (c *ArticleClient) Delete() *ArticleDelete {
mutation := newArticleMutation(c.config, OpDelete)
return &ArticleDelete{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// DeleteOne returns a delete builder for the given entity.
func (c *ArticleClient) DeleteOne(a *Article) *ArticleDeleteOne {
return c.DeleteOneID(a.ID)
}
// DeleteOneID returns a delete builder for the given id.
func (c *ArticleClient) DeleteOneID(id int64) *ArticleDeleteOne {
builder := c.Delete().Where(article.ID(id))
builder.mutation.id = &id
builder.mutation.op = OpDeleteOne
return &ArticleDeleteOne{builder}
}
// Query returns a query builder for Article.
func (c *ArticleClient) Query() *ArticleQuery {
return &ArticleQuery{config: c.config}
}
// Get returns a Article entity by its id.
func (c *ArticleClient) Get(ctx context.Context, id int64) (*Article, error) {
return c.Query().Where(article.ID(id)).Only(ctx)
}
// GetX is like Get, but panics if an error occurs.
func (c *ArticleClient) GetX(ctx context.Context, id int64) *Article {
obj, err := c.Get(ctx, id)
if err != nil {
panic(err)
}
return obj
}
// QueryComments queries the comments edge of a Article.
func (c *ArticleClient) QueryComments(a *Article) *CommentQuery {
query := &CommentQuery{config: c.config}
query.path = func(ctx context.Context) (fromV *sql.Selector, _ error) {
id := a.ID
step := sqlgraph.NewStep(
sqlgraph.From(article.Table, article.FieldID, id),
sqlgraph.To(comment.Table, comment.FieldID),
sqlgraph.Edge(sqlgraph.O2M, false, article.CommentsTable, article.CommentsColumn),
)
fromV = sqlgraph.Neighbors(a.driver.Dialect(), step)
return fromV, nil
}
return query
}
// QueryTags queries the tags edge of a Article.
func (c *ArticleClient) QueryTags(a *Article) *TagQuery {
query := &TagQuery{config: c.config}
query.path = func(ctx context.Context) (fromV *sql.Selector, _ error) {
id := a.ID
step := sqlgraph.NewStep(
sqlgraph.From(article.Table, article.FieldID, id),
sqlgraph.To(tag.Table, tag.FieldID),
sqlgraph.Edge(sqlgraph.M2M, true, article.TagsTable, article.TagsPrimaryKey...),
)
fromV = sqlgraph.Neighbors(a.driver.Dialect(), step)
return fromV, nil
}
return query
}
// Hooks returns the client hooks.
func (c *ArticleClient) Hooks() []Hook {
return c.hooks.Article
}
// CommentClient is a client for the Comment schema.
type CommentClient struct {
config
}
// NewCommentClient returns a client for the Comment from the given config.
func NewCommentClient(c config) *CommentClient {
return &CommentClient{config: c}
}
// Use adds a list of mutation hooks to the hooks stack.
// A call to `Use(f, g, h)` equals to `comment.Hooks(f(g(h())))`.
func (c *CommentClient) Use(hooks ...Hook) {
c.hooks.Comment = append(c.hooks.Comment, hooks...)
}
// Create returns a create builder for Comment.
func (c *CommentClient) Create() *CommentCreate {
mutation := newCommentMutation(c.config, OpCreate)
return &CommentCreate{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// CreateBulk returns a builder for creating a bulk of Comment entities.
func (c *CommentClient) CreateBulk(builders ...*CommentCreate) *CommentCreateBulk {
return &CommentCreateBulk{config: c.config, builders: builders}
}
// Update returns an update builder for Comment.
func (c *CommentClient) Update() *CommentUpdate {
mutation := newCommentMutation(c.config, OpUpdate)
return &CommentUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// UpdateOne returns an update builder for the given entity.
func (c *CommentClient) UpdateOne(co *Comment) *CommentUpdateOne {
mutation := newCommentMutation(c.config, OpUpdateOne, withComment(co))
return &CommentUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// UpdateOneID returns an update builder for the given id.
func (c *CommentClient) UpdateOneID(id int64) *CommentUpdateOne {
mutation := newCommentMutation(c.config, OpUpdateOne, withCommentID(id))
return &CommentUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// Delete returns a delete builder for Comment.
func (c *CommentClient) Delete() *CommentDelete {
mutation := newCommentMutation(c.config, OpDelete)
return &CommentDelete{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// DeleteOne returns a delete builder for the given entity.
func (c *CommentClient) DeleteOne(co *Comment) *CommentDeleteOne {
return c.DeleteOneID(co.ID)
}
// DeleteOneID returns a delete builder for the given id.
func (c *CommentClient) DeleteOneID(id int64) *CommentDeleteOne {
builder := c.Delete().Where(comment.ID(id))
builder.mutation.id = &id
builder.mutation.op = OpDeleteOne
return &CommentDeleteOne{builder}
}
// Query returns a query builder for Comment.
func (c *CommentClient) Query() *CommentQuery {
return &CommentQuery{config: c.config}
}
// Get returns a Comment entity by its id.
func (c *CommentClient) Get(ctx context.Context, id int64) (*Comment, error) {
return c.Query().Where(comment.ID(id)).Only(ctx)
}
// GetX is like Get, but panics if an error occurs.
func (c *CommentClient) GetX(ctx context.Context, id int64) *Comment {
obj, err := c.Get(ctx, id)
if err != nil {
panic(err)
}
return obj
}
// QueryPost queries the post edge of a Comment.
func (c *CommentClient) QueryPost(co *Comment) *ArticleQuery {
query := &ArticleQuery{config: c.config}
query.path = func(ctx context.Context) (fromV *sql.Selector, _ error) {
id := co.ID
step := sqlgraph.NewStep(
sqlgraph.From(comment.Table, comment.FieldID, id),
sqlgraph.To(article.Table, article.FieldID),
sqlgraph.Edge(sqlgraph.M2O, true, comment.PostTable, comment.PostColumn),
)
fromV = sqlgraph.Neighbors(co.driver.Dialect(), step)
return fromV, nil
}
return query
}
// Hooks returns the client hooks.
func (c *CommentClient) Hooks() []Hook {
return c.hooks.Comment
}
// TagClient is a client for the Tag schema.
type TagClient struct {
config
}
// NewTagClient returns a client for the Tag from the given config.
func NewTagClient(c config) *TagClient {
return &TagClient{config: c}
}
// Use adds a list of mutation hooks to the hooks stack.
// A call to `Use(f, g, h)` equals to `tag.Hooks(f(g(h())))`.
func (c *TagClient) Use(hooks ...Hook) {
c.hooks.Tag = append(c.hooks.Tag, hooks...)
}
// Create returns a create builder for Tag.
func (c *TagClient) Create() *TagCreate {
mutation := newTagMutation(c.config, OpCreate)
return &TagCreate{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// CreateBulk returns a builder for creating a bulk of Tag entities.
func (c *TagClient) CreateBulk(builders ...*TagCreate) *TagCreateBulk {
return &TagCreateBulk{config: c.config, builders: builders}
}
// Update returns an update builder for Tag.
func (c *TagClient) Update() *TagUpdate {
mutation := newTagMutation(c.config, OpUpdate)
return &TagUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// UpdateOne returns an update builder for the given entity.
func (c *TagClient) UpdateOne(t *Tag) *TagUpdateOne {
mutation := newTagMutation(c.config, OpUpdateOne, withTag(t))
return &TagUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// UpdateOneID returns an update builder for the given id.
func (c *TagClient) UpdateOneID(id int64) *TagUpdateOne {
mutation := newTagMutation(c.config, OpUpdateOne, withTagID(id))
return &TagUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// Delete returns a delete builder for Tag.
func (c *TagClient) Delete() *TagDelete {
mutation := newTagMutation(c.config, OpDelete)
return &TagDelete{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// DeleteOne returns a delete builder for the given entity.
func (c *TagClient) DeleteOne(t *Tag) *TagDeleteOne {
return c.DeleteOneID(t.ID)
}
// DeleteOneID returns a delete builder for the given id.
func (c *TagClient) DeleteOneID(id int64) *TagDeleteOne {
builder := c.Delete().Where(tag.ID(id))
builder.mutation.id = &id
builder.mutation.op = OpDeleteOne
return &TagDeleteOne{builder}
}
// Query returns a query builder for Tag.
func (c *TagClient) Query() *TagQuery {
return &TagQuery{config: c.config}
}
// Get returns a Tag entity by its id.
func (c *TagClient) Get(ctx context.Context, id int64) (*Tag, error) {
return c.Query().Where(tag.ID(id)).Only(ctx)
}
// GetX is like Get, but panics if an error occurs.
func (c *TagClient) GetX(ctx context.Context, id int64) *Tag {
obj, err := c.Get(ctx, id)
if err != nil {
panic(err)
}
return obj
}
// QueryPosts queries the posts edge of a Tag.
func (c *TagClient) QueryPosts(t *Tag) *ArticleQuery {
query := &ArticleQuery{config: c.config}
query.path = func(ctx context.Context) (fromV *sql.Selector, _ error) {
id := t.ID
step := sqlgraph.NewStep(
sqlgraph.From(tag.Table, tag.FieldID, id),
sqlgraph.To(article.Table, article.FieldID),
sqlgraph.Edge(sqlgraph.M2M, false, tag.PostsTable, tag.PostsPrimaryKey...),
)
fromV = sqlgraph.Neighbors(t.driver.Dialect(), step)
return fromV, nil
}
return query
}
// Hooks returns the client hooks.
func (c *TagClient) Hooks() []Hook {
return c.hooks.Tag
}

@ -0,0 +1,174 @@
// Code generated by entc, DO NOT EDIT.
package ent
import (
"fmt"
"strings"
"time"
"entgo.io/ent/dialect/sql"
"github.com/go-kratos/examples/blog/internal/data/ent/article"
"github.com/go-kratos/examples/blog/internal/data/ent/comment"
)
// Comment is the model entity for the Comment schema.
type Comment struct {
config `json:"-"`
// ID of the ent.
ID int64 `json:"id,omitempty"`
// Name holds the value of the "name" field.
Name string `json:"name,omitempty"`
// Content holds the value of the "content" field.
Content string `json:"content,omitempty"`
// CreatedAt holds the value of the "created_at" field.
CreatedAt time.Time `json:"created_at,omitempty"`
// UpdatedAt holds the value of the "updated_at" field.
UpdatedAt time.Time `json:"updated_at,omitempty"`
// Edges holds the relations/edges for other nodes in the graph.
// The values are being populated by the CommentQuery when eager-loading is set.
Edges CommentEdges `json:"edges"`
article_comments *int64
}
// CommentEdges holds the relations/edges for other nodes in the graph.
type CommentEdges struct {
// Post holds the value of the post edge.
Post *Article `json:"post,omitempty"`
// loadedTypes holds the information for reporting if a
// type was loaded (or requested) in eager-loading or not.
loadedTypes [1]bool
}
// PostOrErr returns the Post value or an error if the edge
// was not loaded in eager-loading, or loaded but was not found.
func (e CommentEdges) PostOrErr() (*Article, error) {
if e.loadedTypes[0] {
if e.Post == nil {
// The edge post was loaded in eager-loading,
// but was not found.
return nil, &NotFoundError{label: article.Label}
}
return e.Post, nil
}
return nil, &NotLoadedError{edge: "post"}
}
// scanValues returns the types for scanning values from sql.Rows.
func (*Comment) scanValues(columns []string) ([]interface{}, error) {
values := make([]interface{}, len(columns))
for i := range columns {
switch columns[i] {
case comment.FieldID:
values[i] = &sql.NullInt64{}
case comment.FieldName, comment.FieldContent:
values[i] = &sql.NullString{}
case comment.FieldCreatedAt, comment.FieldUpdatedAt:
values[i] = &sql.NullTime{}
case comment.ForeignKeys[0]: // article_comments
values[i] = &sql.NullInt64{}
default:
return nil, fmt.Errorf("unexpected column %q for type Comment", columns[i])
}
}
return values, nil
}
// assignValues assigns the values that were returned from sql.Rows (after scanning)
// to the Comment fields.
func (c *Comment) assignValues(columns []string, values []interface{}) error {
if m, n := len(values), len(columns); m < n {
return fmt.Errorf("mismatch number of scan values: %d != %d", m, n)
}
for i := range columns {
switch columns[i] {
case comment.FieldID:
value, ok := values[i].(*sql.NullInt64)
if !ok {
return fmt.Errorf("unexpected type %T for field id", value)
}
c.ID = int64(value.Int64)
case comment.FieldName:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field name", values[i])
} else if value.Valid {
c.Name = value.String
}
case comment.FieldContent:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field content", values[i])
} else if value.Valid {
c.Content = value.String
}
case comment.FieldCreatedAt:
if value, ok := values[i].(*sql.NullTime); !ok {
return fmt.Errorf("unexpected type %T for field created_at", values[i])
} else if value.Valid {
c.CreatedAt = value.Time
}
case comment.FieldUpdatedAt:
if value, ok := values[i].(*sql.NullTime); !ok {
return fmt.Errorf("unexpected type %T for field updated_at", values[i])
} else if value.Valid {
c.UpdatedAt = value.Time
}
case comment.ForeignKeys[0]:
if value, ok := values[i].(*sql.NullInt64); !ok {
return fmt.Errorf("unexpected type %T for edge-field article_comments", value)
} else if value.Valid {
c.article_comments = new(int64)
*c.article_comments = int64(value.Int64)
}
}
}
return nil
}
// QueryPost queries the "post" edge of the Comment entity.
func (c *Comment) QueryPost() *ArticleQuery {
return (&CommentClient{config: c.config}).QueryPost(c)
}
// Update returns a builder for updating this Comment.
// Note that you need to call Comment.Unwrap() before calling this method if this Comment
// was returned from a transaction, and the transaction was committed or rolled back.
func (c *Comment) Update() *CommentUpdateOne {
return (&CommentClient{config: c.config}).UpdateOne(c)
}
// Unwrap unwraps the Comment entity that was returned from a transaction after it was closed,
// so that all future queries will be executed through the driver which created the transaction.
func (c *Comment) Unwrap() *Comment {
tx, ok := c.config.driver.(*txDriver)
if !ok {
panic("ent: Comment is not a transactional entity")
}
c.config.driver = tx.drv
return c
}
// String implements the fmt.Stringer.
func (c *Comment) String() string {
var builder strings.Builder
builder.WriteString("Comment(")
builder.WriteString(fmt.Sprintf("id=%v", c.ID))
builder.WriteString(", name=")
builder.WriteString(c.Name)
builder.WriteString(", content=")
builder.WriteString(c.Content)
builder.WriteString(", created_at=")
builder.WriteString(c.CreatedAt.Format(time.ANSIC))
builder.WriteString(", updated_at=")
builder.WriteString(c.UpdatedAt.Format(time.ANSIC))
builder.WriteByte(')')
return builder.String()
}
// Comments is a parsable slice of Comment.
type Comments []*Comment
func (c Comments) config(cfg config) {
for _i := range c {
c[_i].config = cfg
}
}

@ -0,0 +1,71 @@
// Code generated by entc, DO NOT EDIT.
package comment
import (
"time"
)
const (
// Label holds the string label denoting the comment type in the database.
Label = "comment"
// FieldID holds the string denoting the id field in the database.
FieldID = "id"
// FieldName holds the string denoting the name field in the database.
FieldName = "name"
// FieldContent holds the string denoting the content field in the database.
FieldContent = "content"
// FieldCreatedAt holds the string denoting the created_at field in the database.
FieldCreatedAt = "created_at"
// FieldUpdatedAt holds the string denoting the updated_at field in the database.
FieldUpdatedAt = "updated_at"
// EdgePost holds the string denoting the post edge name in mutations.
EdgePost = "post"
// Table holds the table name of the comment in the database.
Table = "comments"
// PostTable is the table the holds the post relation/edge.
PostTable = "comments"
// PostInverseTable is the table name for the Article entity.
// It exists in this package in order to avoid circular dependency with the "article" package.
PostInverseTable = "articles"
// PostColumn is the table column denoting the post relation/edge.
PostColumn = "article_comments"
)
// Columns holds all SQL columns for comment fields.
var Columns = []string{
FieldID,
FieldName,
FieldContent,
FieldCreatedAt,
FieldUpdatedAt,
}
// ForeignKeys holds the SQL foreign-keys that are owned by the Comment type.
var ForeignKeys = []string{
"article_comments",
}
// ValidColumn reports if the column name is valid (part of the table columns).
func ValidColumn(column string) bool {
for i := range Columns {
if column == Columns[i] {
return true
}
}
for i := range ForeignKeys {
if column == ForeignKeys[i] {
return true
}
}
return false
}
var (
// DefaultCreatedAt holds the default value on creation for the "created_at" field.
DefaultCreatedAt func() time.Time
// DefaultUpdatedAt holds the default value on creation for the "updated_at" field.
DefaultUpdatedAt func() time.Time
)

@ -0,0 +1,556 @@
// Code generated by entc, DO NOT EDIT.
package comment
import (
"time"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"github.com/go-kratos/examples/blog/internal/data/ent/predicate"
)
// ID filters vertices based on their ID field.
func ID(id int64) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldID), id))
})
}
// IDEQ applies the EQ predicate on the ID field.
func IDEQ(id int64) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldID), id))
})
}
// IDNEQ applies the NEQ predicate on the ID field.
func IDNEQ(id int64) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.NEQ(s.C(FieldID), id))
})
}
// IDIn applies the In predicate on the ID field.
func IDIn(ids ...int64) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
// if not arguments were provided, append the FALSE constants,
// since we can't apply "IN ()". This will make this predicate falsy.
if len(ids) == 0 {
s.Where(sql.False())
return
}
v := make([]interface{}, len(ids))
for i := range v {
v[i] = ids[i]
}
s.Where(sql.In(s.C(FieldID), v...))
})
}
// IDNotIn applies the NotIn predicate on the ID field.
func IDNotIn(ids ...int64) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
// if not arguments were provided, append the FALSE constants,
// since we can't apply "IN ()". This will make this predicate falsy.
if len(ids) == 0 {
s.Where(sql.False())
return
}
v := make([]interface{}, len(ids))
for i := range v {
v[i] = ids[i]
}
s.Where(sql.NotIn(s.C(FieldID), v...))
})
}
// IDGT applies the GT predicate on the ID field.
func IDGT(id int64) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.GT(s.C(FieldID), id))
})
}
// IDGTE applies the GTE predicate on the ID field.
func IDGTE(id int64) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.GTE(s.C(FieldID), id))
})
}
// IDLT applies the LT predicate on the ID field.
func IDLT(id int64) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.LT(s.C(FieldID), id))
})
}
// IDLTE applies the LTE predicate on the ID field.
func IDLTE(id int64) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.LTE(s.C(FieldID), id))
})
}
// Name applies equality check predicate on the "name" field. It's identical to NameEQ.
func Name(v string) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldName), v))
})
}
// Content applies equality check predicate on the "content" field. It's identical to ContentEQ.
func Content(v string) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldContent), v))
})
}
// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ.
func CreatedAt(v time.Time) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldCreatedAt), v))
})
}
// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ.
func UpdatedAt(v time.Time) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldUpdatedAt), v))
})
}
// NameEQ applies the EQ predicate on the "name" field.
func NameEQ(v string) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldName), v))
})
}
// NameNEQ applies the NEQ predicate on the "name" field.
func NameNEQ(v string) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.NEQ(s.C(FieldName), v))
})
}
// NameIn applies the In predicate on the "name" field.
func NameIn(vs ...string) predicate.Comment {
v := make([]interface{}, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.Comment(func(s *sql.Selector) {
// if not arguments were provided, append the FALSE constants,
// since we can't apply "IN ()". This will make this predicate falsy.
if len(v) == 0 {
s.Where(sql.False())
return
}
s.Where(sql.In(s.C(FieldName), v...))
})
}
// NameNotIn applies the NotIn predicate on the "name" field.
func NameNotIn(vs ...string) predicate.Comment {
v := make([]interface{}, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.Comment(func(s *sql.Selector) {
// if not arguments were provided, append the FALSE constants,
// since we can't apply "IN ()". This will make this predicate falsy.
if len(v) == 0 {
s.Where(sql.False())
return
}
s.Where(sql.NotIn(s.C(FieldName), v...))
})
}
// NameGT applies the GT predicate on the "name" field.
func NameGT(v string) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.GT(s.C(FieldName), v))
})
}
// NameGTE applies the GTE predicate on the "name" field.
func NameGTE(v string) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.GTE(s.C(FieldName), v))
})
}
// NameLT applies the LT predicate on the "name" field.
func NameLT(v string) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.LT(s.C(FieldName), v))
})
}
// NameLTE applies the LTE predicate on the "name" field.
func NameLTE(v string) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.LTE(s.C(FieldName), v))
})
}
// NameContains applies the Contains predicate on the "name" field.
func NameContains(v string) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.Contains(s.C(FieldName), v))
})
}
// NameHasPrefix applies the HasPrefix predicate on the "name" field.
func NameHasPrefix(v string) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.HasPrefix(s.C(FieldName), v))
})
}
// NameHasSuffix applies the HasSuffix predicate on the "name" field.
func NameHasSuffix(v string) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.HasSuffix(s.C(FieldName), v))
})
}
// NameEqualFold applies the EqualFold predicate on the "name" field.
func NameEqualFold(v string) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.EqualFold(s.C(FieldName), v))
})
}
// NameContainsFold applies the ContainsFold predicate on the "name" field.
func NameContainsFold(v string) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.ContainsFold(s.C(FieldName), v))
})
}
// ContentEQ applies the EQ predicate on the "content" field.
func ContentEQ(v string) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldContent), v))
})
}
// ContentNEQ applies the NEQ predicate on the "content" field.
func ContentNEQ(v string) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.NEQ(s.C(FieldContent), v))
})
}
// ContentIn applies the In predicate on the "content" field.
func ContentIn(vs ...string) predicate.Comment {
v := make([]interface{}, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.Comment(func(s *sql.Selector) {
// if not arguments were provided, append the FALSE constants,
// since we can't apply "IN ()". This will make this predicate falsy.
if len(v) == 0 {
s.Where(sql.False())
return
}
s.Where(sql.In(s.C(FieldContent), v...))
})
}
// ContentNotIn applies the NotIn predicate on the "content" field.
func ContentNotIn(vs ...string) predicate.Comment {
v := make([]interface{}, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.Comment(func(s *sql.Selector) {
// if not arguments were provided, append the FALSE constants,
// since we can't apply "IN ()". This will make this predicate falsy.
if len(v) == 0 {
s.Where(sql.False())
return
}
s.Where(sql.NotIn(s.C(FieldContent), v...))
})
}
// ContentGT applies the GT predicate on the "content" field.
func ContentGT(v string) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.GT(s.C(FieldContent), v))
})
}
// ContentGTE applies the GTE predicate on the "content" field.
func ContentGTE(v string) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.GTE(s.C(FieldContent), v))
})
}
// ContentLT applies the LT predicate on the "content" field.
func ContentLT(v string) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.LT(s.C(FieldContent), v))
})
}
// ContentLTE applies the LTE predicate on the "content" field.
func ContentLTE(v string) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.LTE(s.C(FieldContent), v))
})
}
// ContentContains applies the Contains predicate on the "content" field.
func ContentContains(v string) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.Contains(s.C(FieldContent), v))
})
}
// ContentHasPrefix applies the HasPrefix predicate on the "content" field.
func ContentHasPrefix(v string) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.HasPrefix(s.C(FieldContent), v))
})
}
// ContentHasSuffix applies the HasSuffix predicate on the "content" field.
func ContentHasSuffix(v string) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.HasSuffix(s.C(FieldContent), v))
})
}
// ContentEqualFold applies the EqualFold predicate on the "content" field.
func ContentEqualFold(v string) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.EqualFold(s.C(FieldContent), v))
})
}
// ContentContainsFold applies the ContainsFold predicate on the "content" field.
func ContentContainsFold(v string) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.ContainsFold(s.C(FieldContent), v))
})
}
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
func CreatedAtEQ(v time.Time) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldCreatedAt), v))
})
}
// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
func CreatedAtNEQ(v time.Time) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.NEQ(s.C(FieldCreatedAt), v))
})
}
// CreatedAtIn applies the In predicate on the "created_at" field.
func CreatedAtIn(vs ...time.Time) predicate.Comment {
v := make([]interface{}, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.Comment(func(s *sql.Selector) {
// if not arguments were provided, append the FALSE constants,
// since we can't apply "IN ()". This will make this predicate falsy.
if len(v) == 0 {
s.Where(sql.False())
return
}
s.Where(sql.In(s.C(FieldCreatedAt), v...))
})
}
// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
func CreatedAtNotIn(vs ...time.Time) predicate.Comment {
v := make([]interface{}, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.Comment(func(s *sql.Selector) {
// if not arguments were provided, append the FALSE constants,
// since we can't apply "IN ()". This will make this predicate falsy.
if len(v) == 0 {
s.Where(sql.False())
return
}
s.Where(sql.NotIn(s.C(FieldCreatedAt), v...))
})
}
// CreatedAtGT applies the GT predicate on the "created_at" field.
func CreatedAtGT(v time.Time) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.GT(s.C(FieldCreatedAt), v))
})
}
// CreatedAtGTE applies the GTE predicate on the "created_at" field.
func CreatedAtGTE(v time.Time) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.GTE(s.C(FieldCreatedAt), v))
})
}
// CreatedAtLT applies the LT predicate on the "created_at" field.
func CreatedAtLT(v time.Time) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.LT(s.C(FieldCreatedAt), v))
})
}
// CreatedAtLTE applies the LTE predicate on the "created_at" field.
func CreatedAtLTE(v time.Time) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.LTE(s.C(FieldCreatedAt), v))
})
}
// UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
func UpdatedAtEQ(v time.Time) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldUpdatedAt), v))
})
}
// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field.
func UpdatedAtNEQ(v time.Time) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.NEQ(s.C(FieldUpdatedAt), v))
})
}
// UpdatedAtIn applies the In predicate on the "updated_at" field.
func UpdatedAtIn(vs ...time.Time) predicate.Comment {
v := make([]interface{}, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.Comment(func(s *sql.Selector) {
// if not arguments were provided, append the FALSE constants,
// since we can't apply "IN ()". This will make this predicate falsy.
if len(v) == 0 {
s.Where(sql.False())
return
}
s.Where(sql.In(s.C(FieldUpdatedAt), v...))
})
}
// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field.
func UpdatedAtNotIn(vs ...time.Time) predicate.Comment {
v := make([]interface{}, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.Comment(func(s *sql.Selector) {
// if not arguments were provided, append the FALSE constants,
// since we can't apply "IN ()". This will make this predicate falsy.
if len(v) == 0 {
s.Where(sql.False())
return
}
s.Where(sql.NotIn(s.C(FieldUpdatedAt), v...))
})
}
// UpdatedAtGT applies the GT predicate on the "updated_at" field.
func UpdatedAtGT(v time.Time) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.GT(s.C(FieldUpdatedAt), v))
})
}
// UpdatedAtGTE applies the GTE predicate on the "updated_at" field.
func UpdatedAtGTE(v time.Time) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.GTE(s.C(FieldUpdatedAt), v))
})
}
// UpdatedAtLT applies the LT predicate on the "updated_at" field.
func UpdatedAtLT(v time.Time) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.LT(s.C(FieldUpdatedAt), v))
})
}
// UpdatedAtLTE applies the LTE predicate on the "updated_at" field.
func UpdatedAtLTE(v time.Time) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s.Where(sql.LTE(s.C(FieldUpdatedAt), v))
})
}
// HasPost applies the HasEdge predicate on the "post" edge.
func HasPost() predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
step := sqlgraph.NewStep(
sqlgraph.From(Table, FieldID),
sqlgraph.To(PostTable, FieldID),
sqlgraph.Edge(sqlgraph.M2O, true, PostTable, PostColumn),
)
sqlgraph.HasNeighbors(s, step)
})
}
// HasPostWith applies the HasEdge predicate on the "post" edge with a given conditions (other predicates).
func HasPostWith(preds ...predicate.Article) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
step := sqlgraph.NewStep(
sqlgraph.From(Table, FieldID),
sqlgraph.To(PostInverseTable, FieldID),
sqlgraph.Edge(sqlgraph.M2O, true, PostTable, PostColumn),
)
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
for _, p := range preds {
p(s)
}
})
})
}
// And groups predicates with the AND operator between them.
func And(predicates ...predicate.Comment) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s1 := s.Clone().SetP(nil)
for _, p := range predicates {
p(s1)
}
s.Where(s1.P())
})
}
// Or groups predicates with the OR operator between them.
func Or(predicates ...predicate.Comment) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
s1 := s.Clone().SetP(nil)
for i, p := range predicates {
if i > 0 {
s1.Or()
}
p(s1)
}
s.Where(s1.P())
})
}
// Not applies the not operator on the given predicate.
func Not(p predicate.Comment) predicate.Comment {
return predicate.Comment(func(s *sql.Selector) {
p(s.Not())
})
}

@ -0,0 +1,319 @@
// Code generated by entc, DO NOT EDIT.
package ent
import (
"context"
"errors"
"fmt"
"time"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
"github.com/go-kratos/examples/blog/internal/data/ent/article"
"github.com/go-kratos/examples/blog/internal/data/ent/comment"
)
// CommentCreate is the builder for creating a Comment entity.
type CommentCreate struct {
config
mutation *CommentMutation
hooks []Hook
}
// SetName sets the "name" field.
func (cc *CommentCreate) SetName(s string) *CommentCreate {
cc.mutation.SetName(s)
return cc
}
// SetContent sets the "content" field.
func (cc *CommentCreate) SetContent(s string) *CommentCreate {
cc.mutation.SetContent(s)
return cc
}
// SetCreatedAt sets the "created_at" field.
func (cc *CommentCreate) SetCreatedAt(t time.Time) *CommentCreate {
cc.mutation.SetCreatedAt(t)
return cc
}
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
func (cc *CommentCreate) SetNillableCreatedAt(t *time.Time) *CommentCreate {
if t != nil {
cc.SetCreatedAt(*t)
}
return cc
}
// SetUpdatedAt sets the "updated_at" field.
func (cc *CommentCreate) SetUpdatedAt(t time.Time) *CommentCreate {
cc.mutation.SetUpdatedAt(t)
return cc
}
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
func (cc *CommentCreate) SetNillableUpdatedAt(t *time.Time) *CommentCreate {
if t != nil {
cc.SetUpdatedAt(*t)
}
return cc
}
// SetID sets the "id" field.
func (cc *CommentCreate) SetID(i int64) *CommentCreate {
cc.mutation.SetID(i)
return cc
}
// SetPostID sets the "post" edge to the Article entity by ID.
func (cc *CommentCreate) SetPostID(id int64) *CommentCreate {
cc.mutation.SetPostID(id)
return cc
}
// SetNillablePostID sets the "post" edge to the Article entity by ID if the given value is not nil.
func (cc *CommentCreate) SetNillablePostID(id *int64) *CommentCreate {
if id != nil {
cc = cc.SetPostID(*id)
}
return cc
}
// SetPost sets the "post" edge to the Article entity.
func (cc *CommentCreate) SetPost(a *Article) *CommentCreate {
return cc.SetPostID(a.ID)
}
// Mutation returns the CommentMutation object of the builder.
func (cc *CommentCreate) Mutation() *CommentMutation {
return cc.mutation
}
// Save creates the Comment in the database.
func (cc *CommentCreate) Save(ctx context.Context) (*Comment, error) {
var (
err error
node *Comment
)
cc.defaults()
if len(cc.hooks) == 0 {
if err = cc.check(); err != nil {
return nil, err
}
node, err = cc.sqlSave(ctx)
} else {
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
mutation, ok := m.(*CommentMutation)
if !ok {
return nil, fmt.Errorf("unexpected mutation type %T", m)
}
if err = cc.check(); err != nil {
return nil, err
}
cc.mutation = mutation
node, err = cc.sqlSave(ctx)
mutation.done = true
return node, err
})
for i := len(cc.hooks) - 1; i >= 0; i-- {
mut = cc.hooks[i](mut)
}
if _, err := mut.Mutate(ctx, cc.mutation); err != nil {
return nil, err
}
}
return node, err
}
// SaveX calls Save and panics if Save returns an error.
func (cc *CommentCreate) SaveX(ctx context.Context) *Comment {
v, err := cc.Save(ctx)
if err != nil {
panic(err)
}
return v
}
// defaults sets the default values of the builder before save.
func (cc *CommentCreate) defaults() {
if _, ok := cc.mutation.CreatedAt(); !ok {
v := comment.DefaultCreatedAt()
cc.mutation.SetCreatedAt(v)
}
if _, ok := cc.mutation.UpdatedAt(); !ok {
v := comment.DefaultUpdatedAt()
cc.mutation.SetUpdatedAt(v)
}
}
// check runs all checks and user-defined validators on the builder.
func (cc *CommentCreate) check() error {
if _, ok := cc.mutation.Name(); !ok {
return &ValidationError{Name: "name", err: errors.New("ent: missing required field \"name\"")}
}
if _, ok := cc.mutation.Content(); !ok {
return &ValidationError{Name: "content", err: errors.New("ent: missing required field \"content\"")}
}
if _, ok := cc.mutation.CreatedAt(); !ok {
return &ValidationError{Name: "created_at", err: errors.New("ent: missing required field \"created_at\"")}
}
if _, ok := cc.mutation.UpdatedAt(); !ok {
return &ValidationError{Name: "updated_at", err: errors.New("ent: missing required field \"updated_at\"")}
}
return nil
}
func (cc *CommentCreate) sqlSave(ctx context.Context) (*Comment, error) {
_node, _spec := cc.createSpec()
if err := sqlgraph.CreateNode(ctx, cc.driver, _spec); err != nil {
if cerr, ok := isSQLConstraintError(err); ok {
err = cerr
}
return nil, err
}
if _node.ID == 0 {
id := _spec.ID.Value.(int64)
_node.ID = int64(id)
}
return _node, nil
}
func (cc *CommentCreate) createSpec() (*Comment, *sqlgraph.CreateSpec) {
var (
_node = &Comment{config: cc.config}
_spec = &sqlgraph.CreateSpec{
Table: comment.Table,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: comment.FieldID,
},
}
)
if id, ok := cc.mutation.ID(); ok {
_node.ID = id
_spec.ID.Value = id
}
if value, ok := cc.mutation.Name(); ok {
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: value,
Column: comment.FieldName,
})
_node.Name = value
}
if value, ok := cc.mutation.Content(); ok {
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: value,
Column: comment.FieldContent,
})
_node.Content = value
}
if value, ok := cc.mutation.CreatedAt(); ok {
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeTime,
Value: value,
Column: comment.FieldCreatedAt,
})
_node.CreatedAt = value
}
if value, ok := cc.mutation.UpdatedAt(); ok {
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeTime,
Value: value,
Column: comment.FieldUpdatedAt,
})
_node.UpdatedAt = value
}
if nodes := cc.mutation.PostIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: true,
Table: comment.PostTable,
Columns: []string{comment.PostColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: article.FieldID,
},
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges = append(_spec.Edges, edge)
}
return _node, _spec
}
// CommentCreateBulk is the builder for creating many Comment entities in bulk.
type CommentCreateBulk struct {
config
builders []*CommentCreate
}
// Save creates the Comment entities in the database.
func (ccb *CommentCreateBulk) Save(ctx context.Context) ([]*Comment, error) {
specs := make([]*sqlgraph.CreateSpec, len(ccb.builders))
nodes := make([]*Comment, len(ccb.builders))
mutators := make([]Mutator, len(ccb.builders))
for i := range ccb.builders {
func(i int, root context.Context) {
builder := ccb.builders[i]
builder.defaults()
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
mutation, ok := m.(*CommentMutation)
if !ok {
return nil, fmt.Errorf("unexpected mutation type %T", m)
}
if err := builder.check(); err != nil {
return nil, err
}
builder.mutation = mutation
nodes[i], specs[i] = builder.createSpec()
var err error
if i < len(mutators)-1 {
_, err = mutators[i+1].Mutate(root, ccb.builders[i+1].mutation)
} else {
// Invoke the actual operation on the latest mutation in the chain.
if err = sqlgraph.BatchCreate(ctx, ccb.driver, &sqlgraph.BatchCreateSpec{Nodes: specs}); err != nil {
if cerr, ok := isSQLConstraintError(err); ok {
err = cerr
}
}
}
mutation.done = true
if err != nil {
return nil, err
}
if nodes[i].ID == 0 {
id := specs[i].ID.Value.(int64)
nodes[i].ID = int64(id)
}
return nodes[i], nil
})
for i := len(builder.hooks) - 1; i >= 0; i-- {
mut = builder.hooks[i](mut)
}
mutators[i] = mut
}(i, ctx)
}
if len(mutators) > 0 {
if _, err := mutators[0].Mutate(ctx, ccb.builders[0].mutation); err != nil {
return nil, err
}
}
return nodes, nil
}
// SaveX is like Save, but panics if an error occurs.
func (ccb *CommentCreateBulk) SaveX(ctx context.Context) []*Comment {
v, err := ccb.Save(ctx)
if err != nil {
panic(err)
}
return v
}

@ -0,0 +1,108 @@
// Code generated by entc, DO NOT EDIT.
package ent
import (
"context"
"fmt"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
"github.com/go-kratos/examples/blog/internal/data/ent/comment"
"github.com/go-kratos/examples/blog/internal/data/ent/predicate"
)
// CommentDelete is the builder for deleting a Comment entity.
type CommentDelete struct {
config
hooks []Hook
mutation *CommentMutation
}
// Where adds a new predicate to the CommentDelete builder.
func (cd *CommentDelete) Where(ps ...predicate.Comment) *CommentDelete {
cd.mutation.predicates = append(cd.mutation.predicates, ps...)
return cd
}
// Exec executes the deletion query and returns how many vertices were deleted.
func (cd *CommentDelete) Exec(ctx context.Context) (int, error) {
var (
err error
affected int
)
if len(cd.hooks) == 0 {
affected, err = cd.sqlExec(ctx)
} else {
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
mutation, ok := m.(*CommentMutation)
if !ok {
return nil, fmt.Errorf("unexpected mutation type %T", m)
}
cd.mutation = mutation
affected, err = cd.sqlExec(ctx)
mutation.done = true
return affected, err
})
for i := len(cd.hooks) - 1; i >= 0; i-- {
mut = cd.hooks[i](mut)
}
if _, err := mut.Mutate(ctx, cd.mutation); err != nil {
return 0, err
}
}
return affected, err
}
// ExecX is like Exec, but panics if an error occurs.
func (cd *CommentDelete) ExecX(ctx context.Context) int {
n, err := cd.Exec(ctx)
if err != nil {
panic(err)
}
return n
}
func (cd *CommentDelete) sqlExec(ctx context.Context) (int, error) {
_spec := &sqlgraph.DeleteSpec{
Node: &sqlgraph.NodeSpec{
Table: comment.Table,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: comment.FieldID,
},
},
}
if ps := cd.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
return sqlgraph.DeleteNodes(ctx, cd.driver, _spec)
}
// CommentDeleteOne is the builder for deleting a single Comment entity.
type CommentDeleteOne struct {
cd *CommentDelete
}
// Exec executes the deletion query.
func (cdo *CommentDeleteOne) Exec(ctx context.Context) error {
n, err := cdo.cd.Exec(ctx)
switch {
case err != nil:
return err
case n == 0:
return &NotFoundError{comment.Label}
default:
return nil
}
}
// ExecX is like Exec, but panics if an error occurs.
func (cdo *CommentDeleteOne) ExecX(ctx context.Context) {
cdo.cd.ExecX(ctx)
}

@ -0,0 +1,970 @@
// Code generated by entc, DO NOT EDIT.
package ent
import (
"context"
"errors"
"fmt"
"math"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
"github.com/go-kratos/examples/blog/internal/data/ent/article"
"github.com/go-kratos/examples/blog/internal/data/ent/comment"
"github.com/go-kratos/examples/blog/internal/data/ent/predicate"
)
// CommentQuery is the builder for querying Comment entities.
type CommentQuery struct {
config
limit *int
offset *int
order []OrderFunc
fields []string
predicates []predicate.Comment
// eager-loading edges.
withPost *ArticleQuery
withFKs bool
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
}
// Where adds a new predicate for the CommentQuery builder.
func (cq *CommentQuery) Where(ps ...predicate.Comment) *CommentQuery {
cq.predicates = append(cq.predicates, ps...)
return cq
}
// Limit adds a limit step to the query.
func (cq *CommentQuery) Limit(limit int) *CommentQuery {
cq.limit = &limit
return cq
}
// Offset adds an offset step to the query.
func (cq *CommentQuery) Offset(offset int) *CommentQuery {
cq.offset = &offset
return cq
}
// Order adds an order step to the query.
func (cq *CommentQuery) Order(o ...OrderFunc) *CommentQuery {
cq.order = append(cq.order, o...)
return cq
}
// QueryPost chains the current query on the "post" edge.
func (cq *CommentQuery) QueryPost() *ArticleQuery {
query := &ArticleQuery{config: cq.config}
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
if err := cq.prepareQuery(ctx); err != nil {
return nil, err
}
selector := cq.sqlQuery(ctx)
if err := selector.Err(); err != nil {
return nil, err
}
step := sqlgraph.NewStep(
sqlgraph.From(comment.Table, comment.FieldID, selector),
sqlgraph.To(article.Table, article.FieldID),
sqlgraph.Edge(sqlgraph.M2O, true, comment.PostTable, comment.PostColumn),
)
fromU = sqlgraph.SetNeighbors(cq.driver.Dialect(), step)
return fromU, nil
}
return query
}
// First returns the first Comment entity from the query.
// Returns a *NotFoundError when no Comment was found.
func (cq *CommentQuery) First(ctx context.Context) (*Comment, error) {
nodes, err := cq.Limit(1).All(ctx)
if err != nil {
return nil, err
}
if len(nodes) == 0 {
return nil, &NotFoundError{comment.Label}
}
return nodes[0], nil
}
// FirstX is like First, but panics if an error occurs.
func (cq *CommentQuery) FirstX(ctx context.Context) *Comment {
node, err := cq.First(ctx)
if err != nil && !IsNotFound(err) {
panic(err)
}
return node
}
// FirstID returns the first Comment ID from the query.
// Returns a *NotFoundError when no Comment ID was found.
func (cq *CommentQuery) FirstID(ctx context.Context) (id int64, err error) {
var ids []int64
if ids, err = cq.Limit(1).IDs(ctx); err != nil {
return
}
if len(ids) == 0 {
err = &NotFoundError{comment.Label}
return
}
return ids[0], nil
}
// FirstIDX is like FirstID, but panics if an error occurs.
func (cq *CommentQuery) FirstIDX(ctx context.Context) int64 {
id, err := cq.FirstID(ctx)
if err != nil && !IsNotFound(err) {
panic(err)
}
return id
}
// Only returns a single Comment entity found by the query, ensuring it only returns one.
// Returns a *NotSingularError when exactly one Comment entity is not found.
// Returns a *NotFoundError when no Comment entities are found.
func (cq *CommentQuery) Only(ctx context.Context) (*Comment, error) {
nodes, err := cq.Limit(2).All(ctx)
if err != nil {
return nil, err
}
switch len(nodes) {
case 1:
return nodes[0], nil
case 0:
return nil, &NotFoundError{comment.Label}
default:
return nil, &NotSingularError{comment.Label}
}
}
// OnlyX is like Only, but panics if an error occurs.
func (cq *CommentQuery) OnlyX(ctx context.Context) *Comment {
node, err := cq.Only(ctx)
if err != nil {
panic(err)
}
return node
}
// OnlyID is like Only, but returns the only Comment ID in the query.
// Returns a *NotSingularError when exactly one Comment ID is not found.
// Returns a *NotFoundError when no entities are found.
func (cq *CommentQuery) OnlyID(ctx context.Context) (id int64, err error) {
var ids []int64
if ids, err = cq.Limit(2).IDs(ctx); err != nil {
return
}
switch len(ids) {
case 1:
id = ids[0]
case 0:
err = &NotFoundError{comment.Label}
default:
err = &NotSingularError{comment.Label}
}
return
}
// OnlyIDX is like OnlyID, but panics if an error occurs.
func (cq *CommentQuery) OnlyIDX(ctx context.Context) int64 {
id, err := cq.OnlyID(ctx)
if err != nil {
panic(err)
}
return id
}
// All executes the query and returns a list of Comments.
func (cq *CommentQuery) All(ctx context.Context) ([]*Comment, error) {
if err := cq.prepareQuery(ctx); err != nil {
return nil, err
}
return cq.sqlAll(ctx)
}
// AllX is like All, but panics if an error occurs.
func (cq *CommentQuery) AllX(ctx context.Context) []*Comment {
nodes, err := cq.All(ctx)
if err != nil {
panic(err)
}
return nodes
}
// IDs executes the query and returns a list of Comment IDs.
func (cq *CommentQuery) IDs(ctx context.Context) ([]int64, error) {
var ids []int64
if err := cq.Select(comment.FieldID).Scan(ctx, &ids); err != nil {
return nil, err
}
return ids, nil
}
// IDsX is like IDs, but panics if an error occurs.
func (cq *CommentQuery) IDsX(ctx context.Context) []int64 {
ids, err := cq.IDs(ctx)
if err != nil {
panic(err)
}
return ids
}
// Count returns the count of the given query.
func (cq *CommentQuery) Count(ctx context.Context) (int, error) {
if err := cq.prepareQuery(ctx); err != nil {
return 0, err
}
return cq.sqlCount(ctx)
}
// CountX is like Count, but panics if an error occurs.
func (cq *CommentQuery) CountX(ctx context.Context) int {
count, err := cq.Count(ctx)
if err != nil {
panic(err)
}
return count
}
// Exist returns true if the query has elements in the graph.
func (cq *CommentQuery) Exist(ctx context.Context) (bool, error) {
if err := cq.prepareQuery(ctx); err != nil {
return false, err
}
return cq.sqlExist(ctx)
}
// ExistX is like Exist, but panics if an error occurs.
func (cq *CommentQuery) ExistX(ctx context.Context) bool {
exist, err := cq.Exist(ctx)
if err != nil {
panic(err)
}
return exist
}
// Clone returns a duplicate of the CommentQuery builder, including all associated steps. It can be
// used to prepare common query builders and use them differently after the clone is made.
func (cq *CommentQuery) Clone() *CommentQuery {
if cq == nil {
return nil
}
return &CommentQuery{
config: cq.config,
limit: cq.limit,
offset: cq.offset,
order: append([]OrderFunc{}, cq.order...),
predicates: append([]predicate.Comment{}, cq.predicates...),
withPost: cq.withPost.Clone(),
// clone intermediate query.
sql: cq.sql.Clone(),
path: cq.path,
}
}
// WithPost tells the query-builder to eager-load the nodes that are connected to
// the "post" edge. The optional arguments are used to configure the query builder of the edge.
func (cq *CommentQuery) WithPost(opts ...func(*ArticleQuery)) *CommentQuery {
query := &ArticleQuery{config: cq.config}
for _, opt := range opts {
opt(query)
}
cq.withPost = query
return cq
}
// GroupBy is used to group vertices by one or more fields/columns.
// It is often used with aggregate functions, like: count, max, mean, min, sum.
//
// Example:
//
// var v []struct {
// Name string `json:"name,omitempty"`
// Count int `json:"count,omitempty"`
// }
//
// client.Comment.Query().
// GroupBy(comment.FieldName).
// Aggregate(ent.Count()).
// Scan(ctx, &v)
//
func (cq *CommentQuery) GroupBy(field string, fields ...string) *CommentGroupBy {
group := &CommentGroupBy{config: cq.config}
group.fields = append([]string{field}, fields...)
group.path = func(ctx context.Context) (prev *sql.Selector, err error) {
if err := cq.prepareQuery(ctx); err != nil {
return nil, err
}
return cq.sqlQuery(ctx), nil
}
return group
}
// Select allows the selection one or more fields/columns for the given query,
// instead of selecting all fields in the entity.
//
// Example:
//
// var v []struct {
// Name string `json:"name,omitempty"`
// }
//
// client.Comment.Query().
// Select(comment.FieldName).
// Scan(ctx, &v)
//
func (cq *CommentQuery) Select(field string, fields ...string) *CommentSelect {
cq.fields = append([]string{field}, fields...)
return &CommentSelect{CommentQuery: cq}
}
func (cq *CommentQuery) prepareQuery(ctx context.Context) error {
for _, f := range cq.fields {
if !comment.ValidColumn(f) {
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
}
}
if cq.path != nil {
prev, err := cq.path(ctx)
if err != nil {
return err
}
cq.sql = prev
}
return nil
}
func (cq *CommentQuery) sqlAll(ctx context.Context) ([]*Comment, error) {
var (
nodes = []*Comment{}
withFKs = cq.withFKs
_spec = cq.querySpec()
loadedTypes = [1]bool{
cq.withPost != nil,
}
)
if cq.withPost != nil {
withFKs = true
}
if withFKs {
_spec.Node.Columns = append(_spec.Node.Columns, comment.ForeignKeys...)
}
_spec.ScanValues = func(columns []string) ([]interface{}, error) {
node := &Comment{config: cq.config}
nodes = append(nodes, node)
return node.scanValues(columns)
}
_spec.Assign = func(columns []string, values []interface{}) error {
if len(nodes) == 0 {
return fmt.Errorf("ent: Assign called without calling ScanValues")
}
node := nodes[len(nodes)-1]
node.Edges.loadedTypes = loadedTypes
return node.assignValues(columns, values)
}
if err := sqlgraph.QueryNodes(ctx, cq.driver, _spec); err != nil {
return nil, err
}
if len(nodes) == 0 {
return nodes, nil
}
if query := cq.withPost; query != nil {
ids := make([]int64, 0, len(nodes))
nodeids := make(map[int64][]*Comment)
for i := range nodes {
if fk := nodes[i].article_comments; fk != nil {
ids = append(ids, *fk)
nodeids[*fk] = append(nodeids[*fk], nodes[i])
}
}
query.Where(article.IDIn(ids...))
neighbors, err := query.All(ctx)
if err != nil {
return nil, err
}
for _, n := range neighbors {
nodes, ok := nodeids[n.ID]
if !ok {
return nil, fmt.Errorf(`unexpected foreign-key "article_comments" returned %v`, n.ID)
}
for i := range nodes {
nodes[i].Edges.Post = n
}
}
}
return nodes, nil
}
func (cq *CommentQuery) sqlCount(ctx context.Context) (int, error) {
_spec := cq.querySpec()
return sqlgraph.CountNodes(ctx, cq.driver, _spec)
}
func (cq *CommentQuery) sqlExist(ctx context.Context) (bool, error) {
n, err := cq.sqlCount(ctx)
if err != nil {
return false, fmt.Errorf("ent: check existence: %v", err)
}
return n > 0, nil
}
func (cq *CommentQuery) querySpec() *sqlgraph.QuerySpec {
_spec := &sqlgraph.QuerySpec{
Node: &sqlgraph.NodeSpec{
Table: comment.Table,
Columns: comment.Columns,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: comment.FieldID,
},
},
From: cq.sql,
Unique: true,
}
if fields := cq.fields; len(fields) > 0 {
_spec.Node.Columns = make([]string, 0, len(fields))
_spec.Node.Columns = append(_spec.Node.Columns, comment.FieldID)
for i := range fields {
if fields[i] != comment.FieldID {
_spec.Node.Columns = append(_spec.Node.Columns, fields[i])
}
}
}
if ps := cq.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
if limit := cq.limit; limit != nil {
_spec.Limit = *limit
}
if offset := cq.offset; offset != nil {
_spec.Offset = *offset
}
if ps := cq.order; len(ps) > 0 {
_spec.Order = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector, comment.ValidColumn)
}
}
}
return _spec
}
func (cq *CommentQuery) sqlQuery(ctx context.Context) *sql.Selector {
builder := sql.Dialect(cq.driver.Dialect())
t1 := builder.Table(comment.Table)
selector := builder.Select(t1.Columns(comment.Columns...)...).From(t1)
if cq.sql != nil {
selector = cq.sql
selector.Select(selector.Columns(comment.Columns...)...)
}
for _, p := range cq.predicates {
p(selector)
}
for _, p := range cq.order {
p(selector, comment.ValidColumn)
}
if offset := cq.offset; offset != nil {
// limit is mandatory for offset clause. We start
// with default value, and override it below if needed.
selector.Offset(*offset).Limit(math.MaxInt32)
}
if limit := cq.limit; limit != nil {
selector.Limit(*limit)
}
return selector
}
// CommentGroupBy is the group-by builder for Comment entities.
type CommentGroupBy struct {
config
fields []string
fns []AggregateFunc
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
}
// Aggregate adds the given aggregation functions to the group-by query.
func (cgb *CommentGroupBy) Aggregate(fns ...AggregateFunc) *CommentGroupBy {
cgb.fns = append(cgb.fns, fns...)
return cgb
}
// Scan applies the group-by query and scans the result into the given value.
func (cgb *CommentGroupBy) Scan(ctx context.Context, v interface{}) error {
query, err := cgb.path(ctx)
if err != nil {
return err
}
cgb.sql = query
return cgb.sqlScan(ctx, v)
}
// ScanX is like Scan, but panics if an error occurs.
func (cgb *CommentGroupBy) ScanX(ctx context.Context, v interface{}) {
if err := cgb.Scan(ctx, v); err != nil {
panic(err)
}
}
// Strings returns list of strings from group-by.
// It is only allowed when executing a group-by query with one field.
func (cgb *CommentGroupBy) Strings(ctx context.Context) ([]string, error) {
if len(cgb.fields) > 1 {
return nil, errors.New("ent: CommentGroupBy.Strings is not achievable when grouping more than 1 field")
}
var v []string
if err := cgb.Scan(ctx, &v); err != nil {
return nil, err
}
return v, nil
}
// StringsX is like Strings, but panics if an error occurs.
func (cgb *CommentGroupBy) StringsX(ctx context.Context) []string {
v, err := cgb.Strings(ctx)
if err != nil {
panic(err)
}
return v
}
// String returns a single string from a group-by query.
// It is only allowed when executing a group-by query with one field.
func (cgb *CommentGroupBy) String(ctx context.Context) (_ string, err error) {
var v []string
if v, err = cgb.Strings(ctx); err != nil {
return
}
switch len(v) {
case 1:
return v[0], nil
case 0:
err = &NotFoundError{comment.Label}
default:
err = fmt.Errorf("ent: CommentGroupBy.Strings returned %d results when one was expected", len(v))
}
return
}
// StringX is like String, but panics if an error occurs.
func (cgb *CommentGroupBy) StringX(ctx context.Context) string {
v, err := cgb.String(ctx)
if err != nil {
panic(err)
}
return v
}
// Ints returns list of ints from group-by.
// It is only allowed when executing a group-by query with one field.
func (cgb *CommentGroupBy) Ints(ctx context.Context) ([]int, error) {
if len(cgb.fields) > 1 {
return nil, errors.New("ent: CommentGroupBy.Ints is not achievable when grouping more than 1 field")
}
var v []int
if err := cgb.Scan(ctx, &v); err != nil {
return nil, err
}
return v, nil
}
// IntsX is like Ints, but panics if an error occurs.
func (cgb *CommentGroupBy) IntsX(ctx context.Context) []int {
v, err := cgb.Ints(ctx)
if err != nil {
panic(err)
}
return v
}
// Int returns a single int from a group-by query.
// It is only allowed when executing a group-by query with one field.
func (cgb *CommentGroupBy) Int(ctx context.Context) (_ int, err error) {
var v []int
if v, err = cgb.Ints(ctx); err != nil {
return
}
switch len(v) {
case 1:
return v[0], nil
case 0:
err = &NotFoundError{comment.Label}
default:
err = fmt.Errorf("ent: CommentGroupBy.Ints returned %d results when one was expected", len(v))
}
return
}
// IntX is like Int, but panics if an error occurs.
func (cgb *CommentGroupBy) IntX(ctx context.Context) int {
v, err := cgb.Int(ctx)
if err != nil {
panic(err)
}
return v
}
// Float64s returns list of float64s from group-by.
// It is only allowed when executing a group-by query with one field.
func (cgb *CommentGroupBy) Float64s(ctx context.Context) ([]float64, error) {
if len(cgb.fields) > 1 {
return nil, errors.New("ent: CommentGroupBy.Float64s is not achievable when grouping more than 1 field")
}
var v []float64
if err := cgb.Scan(ctx, &v); err != nil {
return nil, err
}
return v, nil
}
// Float64sX is like Float64s, but panics if an error occurs.
func (cgb *CommentGroupBy) Float64sX(ctx context.Context) []float64 {
v, err := cgb.Float64s(ctx)
if err != nil {
panic(err)
}
return v
}
// Float64 returns a single float64 from a group-by query.
// It is only allowed when executing a group-by query with one field.
func (cgb *CommentGroupBy) Float64(ctx context.Context) (_ float64, err error) {
var v []float64
if v, err = cgb.Float64s(ctx); err != nil {
return
}
switch len(v) {
case 1:
return v[0], nil
case 0:
err = &NotFoundError{comment.Label}
default:
err = fmt.Errorf("ent: CommentGroupBy.Float64s returned %d results when one was expected", len(v))
}
return
}
// Float64X is like Float64, but panics if an error occurs.
func (cgb *CommentGroupBy) Float64X(ctx context.Context) float64 {
v, err := cgb.Float64(ctx)
if err != nil {
panic(err)
}
return v
}
// Bools returns list of bools from group-by.
// It is only allowed when executing a group-by query with one field.
func (cgb *CommentGroupBy) Bools(ctx context.Context) ([]bool, error) {
if len(cgb.fields) > 1 {
return nil, errors.New("ent: CommentGroupBy.Bools is not achievable when grouping more than 1 field")
}
var v []bool
if err := cgb.Scan(ctx, &v); err != nil {
return nil, err
}
return v, nil
}
// BoolsX is like Bools, but panics if an error occurs.
func (cgb *CommentGroupBy) BoolsX(ctx context.Context) []bool {
v, err := cgb.Bools(ctx)
if err != nil {
panic(err)
}
return v
}
// Bool returns a single bool from a group-by query.
// It is only allowed when executing a group-by query with one field.
func (cgb *CommentGroupBy) Bool(ctx context.Context) (_ bool, err error) {
var v []bool
if v, err = cgb.Bools(ctx); err != nil {
return
}
switch len(v) {
case 1:
return v[0], nil
case 0:
err = &NotFoundError{comment.Label}
default:
err = fmt.Errorf("ent: CommentGroupBy.Bools returned %d results when one was expected", len(v))
}
return
}
// BoolX is like Bool, but panics if an error occurs.
func (cgb *CommentGroupBy) BoolX(ctx context.Context) bool {
v, err := cgb.Bool(ctx)
if err != nil {
panic(err)
}
return v
}
func (cgb *CommentGroupBy) sqlScan(ctx context.Context, v interface{}) error {
for _, f := range cgb.fields {
if !comment.ValidColumn(f) {
return &ValidationError{Name: f, err: fmt.Errorf("invalid field %q for group-by", f)}
}
}
selector := cgb.sqlQuery()
if err := selector.Err(); err != nil {
return err
}
rows := &sql.Rows{}
query, args := selector.Query()
if err := cgb.driver.Query(ctx, query, args, rows); err != nil {
return err
}
defer rows.Close()
return sql.ScanSlice(rows, v)
}
func (cgb *CommentGroupBy) sqlQuery() *sql.Selector {
selector := cgb.sql
columns := make([]string, 0, len(cgb.fields)+len(cgb.fns))
columns = append(columns, cgb.fields...)
for _, fn := range cgb.fns {
columns = append(columns, fn(selector, comment.ValidColumn))
}
return selector.Select(columns...).GroupBy(cgb.fields...)
}
// CommentSelect is the builder for selecting fields of Comment entities.
type CommentSelect struct {
*CommentQuery
// intermediate query (i.e. traversal path).
sql *sql.Selector
}
// Scan applies the selector query and scans the result into the given value.
func (cs *CommentSelect) Scan(ctx context.Context, v interface{}) error {
if err := cs.prepareQuery(ctx); err != nil {
return err
}
cs.sql = cs.CommentQuery.sqlQuery(ctx)
return cs.sqlScan(ctx, v)
}
// ScanX is like Scan, but panics if an error occurs.
func (cs *CommentSelect) ScanX(ctx context.Context, v interface{}) {
if err := cs.Scan(ctx, v); err != nil {
panic(err)
}
}
// Strings returns list of strings from a selector. It is only allowed when selecting one field.
func (cs *CommentSelect) Strings(ctx context.Context) ([]string, error) {
if len(cs.fields) > 1 {
return nil, errors.New("ent: CommentSelect.Strings is not achievable when selecting more than 1 field")
}
var v []string
if err := cs.Scan(ctx, &v); err != nil {
return nil, err
}
return v, nil
}
// StringsX is like Strings, but panics if an error occurs.
func (cs *CommentSelect) StringsX(ctx context.Context) []string {
v, err := cs.Strings(ctx)
if err != nil {
panic(err)
}
return v
}
// String returns a single string from a selector. It is only allowed when selecting one field.
func (cs *CommentSelect) String(ctx context.Context) (_ string, err error) {
var v []string
if v, err = cs.Strings(ctx); err != nil {
return
}
switch len(v) {
case 1:
return v[0], nil
case 0:
err = &NotFoundError{comment.Label}
default:
err = fmt.Errorf("ent: CommentSelect.Strings returned %d results when one was expected", len(v))
}
return
}
// StringX is like String, but panics if an error occurs.
func (cs *CommentSelect) StringX(ctx context.Context) string {
v, err := cs.String(ctx)
if err != nil {
panic(err)
}
return v
}
// Ints returns list of ints from a selector. It is only allowed when selecting one field.
func (cs *CommentSelect) Ints(ctx context.Context) ([]int, error) {
if len(cs.fields) > 1 {
return nil, errors.New("ent: CommentSelect.Ints is not achievable when selecting more than 1 field")
}
var v []int
if err := cs.Scan(ctx, &v); err != nil {
return nil, err
}
return v, nil
}
// IntsX is like Ints, but panics if an error occurs.
func (cs *CommentSelect) IntsX(ctx context.Context) []int {
v, err := cs.Ints(ctx)
if err != nil {
panic(err)
}
return v
}
// Int returns a single int from a selector. It is only allowed when selecting one field.
func (cs *CommentSelect) Int(ctx context.Context) (_ int, err error) {
var v []int
if v, err = cs.Ints(ctx); err != nil {
return
}
switch len(v) {
case 1:
return v[0], nil
case 0:
err = &NotFoundError{comment.Label}
default:
err = fmt.Errorf("ent: CommentSelect.Ints returned %d results when one was expected", len(v))
}
return
}
// IntX is like Int, but panics if an error occurs.
func (cs *CommentSelect) IntX(ctx context.Context) int {
v, err := cs.Int(ctx)
if err != nil {
panic(err)
}
return v
}
// Float64s returns list of float64s from a selector. It is only allowed when selecting one field.
func (cs *CommentSelect) Float64s(ctx context.Context) ([]float64, error) {
if len(cs.fields) > 1 {
return nil, errors.New("ent: CommentSelect.Float64s is not achievable when selecting more than 1 field")
}
var v []float64
if err := cs.Scan(ctx, &v); err != nil {
return nil, err
}
return v, nil
}
// Float64sX is like Float64s, but panics if an error occurs.
func (cs *CommentSelect) Float64sX(ctx context.Context) []float64 {
v, err := cs.Float64s(ctx)
if err != nil {
panic(err)
}
return v
}
// Float64 returns a single float64 from a selector. It is only allowed when selecting one field.
func (cs *CommentSelect) Float64(ctx context.Context) (_ float64, err error) {
var v []float64
if v, err = cs.Float64s(ctx); err != nil {
return
}
switch len(v) {
case 1:
return v[0], nil
case 0:
err = &NotFoundError{comment.Label}
default:
err = fmt.Errorf("ent: CommentSelect.Float64s returned %d results when one was expected", len(v))
}
return
}
// Float64X is like Float64, but panics if an error occurs.
func (cs *CommentSelect) Float64X(ctx context.Context) float64 {
v, err := cs.Float64(ctx)
if err != nil {
panic(err)
}
return v
}
// Bools returns list of bools from a selector. It is only allowed when selecting one field.
func (cs *CommentSelect) Bools(ctx context.Context) ([]bool, error) {
if len(cs.fields) > 1 {
return nil, errors.New("ent: CommentSelect.Bools is not achievable when selecting more than 1 field")
}
var v []bool
if err := cs.Scan(ctx, &v); err != nil {
return nil, err
}
return v, nil
}
// BoolsX is like Bools, but panics if an error occurs.
func (cs *CommentSelect) BoolsX(ctx context.Context) []bool {
v, err := cs.Bools(ctx)
if err != nil {
panic(err)
}
return v
}
// Bool returns a single bool from a selector. It is only allowed when selecting one field.
func (cs *CommentSelect) Bool(ctx context.Context) (_ bool, err error) {
var v []bool
if v, err = cs.Bools(ctx); err != nil {
return
}
switch len(v) {
case 1:
return v[0], nil
case 0:
err = &NotFoundError{comment.Label}
default:
err = fmt.Errorf("ent: CommentSelect.Bools returned %d results when one was expected", len(v))
}
return
}
// BoolX is like Bool, but panics if an error occurs.
func (cs *CommentSelect) BoolX(ctx context.Context) bool {
v, err := cs.Bool(ctx)
if err != nil {
panic(err)
}
return v
}
func (cs *CommentSelect) sqlScan(ctx context.Context, v interface{}) error {
rows := &sql.Rows{}
query, args := cs.sqlQuery().Query()
if err := cs.driver.Query(ctx, query, args, rows); err != nil {
return err
}
defer rows.Close()
return sql.ScanSlice(rows, v)
}
func (cs *CommentSelect) sqlQuery() sql.Querier {
selector := cs.sql
selector.Select(selector.Columns(cs.fields...)...)
return selector
}

@ -0,0 +1,470 @@
// Code generated by entc, DO NOT EDIT.
package ent
import (
"context"
"fmt"
"time"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
"github.com/go-kratos/examples/blog/internal/data/ent/article"
"github.com/go-kratos/examples/blog/internal/data/ent/comment"
"github.com/go-kratos/examples/blog/internal/data/ent/predicate"
)
// CommentUpdate is the builder for updating Comment entities.
type CommentUpdate struct {
config
hooks []Hook
mutation *CommentMutation
}
// Where adds a new predicate for the CommentUpdate builder.
func (cu *CommentUpdate) Where(ps ...predicate.Comment) *CommentUpdate {
cu.mutation.predicates = append(cu.mutation.predicates, ps...)
return cu
}
// SetName sets the "name" field.
func (cu *CommentUpdate) SetName(s string) *CommentUpdate {
cu.mutation.SetName(s)
return cu
}
// SetContent sets the "content" field.
func (cu *CommentUpdate) SetContent(s string) *CommentUpdate {
cu.mutation.SetContent(s)
return cu
}
// SetCreatedAt sets the "created_at" field.
func (cu *CommentUpdate) SetCreatedAt(t time.Time) *CommentUpdate {
cu.mutation.SetCreatedAt(t)
return cu
}
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
func (cu *CommentUpdate) SetNillableCreatedAt(t *time.Time) *CommentUpdate {
if t != nil {
cu.SetCreatedAt(*t)
}
return cu
}
// SetUpdatedAt sets the "updated_at" field.
func (cu *CommentUpdate) SetUpdatedAt(t time.Time) *CommentUpdate {
cu.mutation.SetUpdatedAt(t)
return cu
}
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
func (cu *CommentUpdate) SetNillableUpdatedAt(t *time.Time) *CommentUpdate {
if t != nil {
cu.SetUpdatedAt(*t)
}
return cu
}
// SetPostID sets the "post" edge to the Article entity by ID.
func (cu *CommentUpdate) SetPostID(id int64) *CommentUpdate {
cu.mutation.SetPostID(id)
return cu
}
// SetNillablePostID sets the "post" edge to the Article entity by ID if the given value is not nil.
func (cu *CommentUpdate) SetNillablePostID(id *int64) *CommentUpdate {
if id != nil {
cu = cu.SetPostID(*id)
}
return cu
}
// SetPost sets the "post" edge to the Article entity.
func (cu *CommentUpdate) SetPost(a *Article) *CommentUpdate {
return cu.SetPostID(a.ID)
}
// Mutation returns the CommentMutation object of the builder.
func (cu *CommentUpdate) Mutation() *CommentMutation {
return cu.mutation
}
// ClearPost clears the "post" edge to the Article entity.
func (cu *CommentUpdate) ClearPost() *CommentUpdate {
cu.mutation.ClearPost()
return cu
}
// Save executes the query and returns the number of nodes affected by the update operation.
func (cu *CommentUpdate) Save(ctx context.Context) (int, error) {
var (
err error
affected int
)
if len(cu.hooks) == 0 {
affected, err = cu.sqlSave(ctx)
} else {
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
mutation, ok := m.(*CommentMutation)
if !ok {
return nil, fmt.Errorf("unexpected mutation type %T", m)
}
cu.mutation = mutation
affected, err = cu.sqlSave(ctx)
mutation.done = true
return affected, err
})
for i := len(cu.hooks) - 1; i >= 0; i-- {
mut = cu.hooks[i](mut)
}
if _, err := mut.Mutate(ctx, cu.mutation); err != nil {
return 0, err
}
}
return affected, err
}
// SaveX is like Save, but panics if an error occurs.
func (cu *CommentUpdate) SaveX(ctx context.Context) int {
affected, err := cu.Save(ctx)
if err != nil {
panic(err)
}
return affected
}
// Exec executes the query.
func (cu *CommentUpdate) Exec(ctx context.Context) error {
_, err := cu.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (cu *CommentUpdate) ExecX(ctx context.Context) {
if err := cu.Exec(ctx); err != nil {
panic(err)
}
}
func (cu *CommentUpdate) sqlSave(ctx context.Context) (n int, err error) {
_spec := &sqlgraph.UpdateSpec{
Node: &sqlgraph.NodeSpec{
Table: comment.Table,
Columns: comment.Columns,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: comment.FieldID,
},
},
}
if ps := cu.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
if value, ok := cu.mutation.Name(); ok {
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: value,
Column: comment.FieldName,
})
}
if value, ok := cu.mutation.Content(); ok {
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: value,
Column: comment.FieldContent,
})
}
if value, ok := cu.mutation.CreatedAt(); ok {
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
Type: field.TypeTime,
Value: value,
Column: comment.FieldCreatedAt,
})
}
if value, ok := cu.mutation.UpdatedAt(); ok {
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
Type: field.TypeTime,
Value: value,
Column: comment.FieldUpdatedAt,
})
}
if cu.mutation.PostCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: true,
Table: comment.PostTable,
Columns: []string{comment.PostColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: article.FieldID,
},
},
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := cu.mutation.PostIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: true,
Table: comment.PostTable,
Columns: []string{comment.PostColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: article.FieldID,
},
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Add = append(_spec.Edges.Add, edge)
}
if n, err = sqlgraph.UpdateNodes(ctx, cu.driver, _spec); err != nil {
if _, ok := err.(*sqlgraph.NotFoundError); ok {
err = &NotFoundError{comment.Label}
} else if cerr, ok := isSQLConstraintError(err); ok {
err = cerr
}
return 0, err
}
return n, nil
}
// CommentUpdateOne is the builder for updating a single Comment entity.
type CommentUpdateOne struct {
config
hooks []Hook
mutation *CommentMutation
}
// SetName sets the "name" field.
func (cuo *CommentUpdateOne) SetName(s string) *CommentUpdateOne {
cuo.mutation.SetName(s)
return cuo
}
// SetContent sets the "content" field.
func (cuo *CommentUpdateOne) SetContent(s string) *CommentUpdateOne {
cuo.mutation.SetContent(s)
return cuo
}
// SetCreatedAt sets the "created_at" field.
func (cuo *CommentUpdateOne) SetCreatedAt(t time.Time) *CommentUpdateOne {
cuo.mutation.SetCreatedAt(t)
return cuo
}
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
func (cuo *CommentUpdateOne) SetNillableCreatedAt(t *time.Time) *CommentUpdateOne {
if t != nil {
cuo.SetCreatedAt(*t)
}
return cuo
}
// SetUpdatedAt sets the "updated_at" field.
func (cuo *CommentUpdateOne) SetUpdatedAt(t time.Time) *CommentUpdateOne {
cuo.mutation.SetUpdatedAt(t)
return cuo
}
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
func (cuo *CommentUpdateOne) SetNillableUpdatedAt(t *time.Time) *CommentUpdateOne {
if t != nil {
cuo.SetUpdatedAt(*t)
}
return cuo
}
// SetPostID sets the "post" edge to the Article entity by ID.
func (cuo *CommentUpdateOne) SetPostID(id int64) *CommentUpdateOne {
cuo.mutation.SetPostID(id)
return cuo
}
// SetNillablePostID sets the "post" edge to the Article entity by ID if the given value is not nil.
func (cuo *CommentUpdateOne) SetNillablePostID(id *int64) *CommentUpdateOne {
if id != nil {
cuo = cuo.SetPostID(*id)
}
return cuo
}
// SetPost sets the "post" edge to the Article entity.
func (cuo *CommentUpdateOne) SetPost(a *Article) *CommentUpdateOne {
return cuo.SetPostID(a.ID)
}
// Mutation returns the CommentMutation object of the builder.
func (cuo *CommentUpdateOne) Mutation() *CommentMutation {
return cuo.mutation
}
// ClearPost clears the "post" edge to the Article entity.
func (cuo *CommentUpdateOne) ClearPost() *CommentUpdateOne {
cuo.mutation.ClearPost()
return cuo
}
// Save executes the query and returns the updated Comment entity.
func (cuo *CommentUpdateOne) Save(ctx context.Context) (*Comment, error) {
var (
err error
node *Comment
)
if len(cuo.hooks) == 0 {
node, err = cuo.sqlSave(ctx)
} else {
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
mutation, ok := m.(*CommentMutation)
if !ok {
return nil, fmt.Errorf("unexpected mutation type %T", m)
}
cuo.mutation = mutation
node, err = cuo.sqlSave(ctx)
mutation.done = true
return node, err
})
for i := len(cuo.hooks) - 1; i >= 0; i-- {
mut = cuo.hooks[i](mut)
}
if _, err := mut.Mutate(ctx, cuo.mutation); err != nil {
return nil, err
}
}
return node, err
}
// SaveX is like Save, but panics if an error occurs.
func (cuo *CommentUpdateOne) SaveX(ctx context.Context) *Comment {
node, err := cuo.Save(ctx)
if err != nil {
panic(err)
}
return node
}
// Exec executes the query on the entity.
func (cuo *CommentUpdateOne) Exec(ctx context.Context) error {
_, err := cuo.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (cuo *CommentUpdateOne) ExecX(ctx context.Context) {
if err := cuo.Exec(ctx); err != nil {
panic(err)
}
}
func (cuo *CommentUpdateOne) sqlSave(ctx context.Context) (_node *Comment, err error) {
_spec := &sqlgraph.UpdateSpec{
Node: &sqlgraph.NodeSpec{
Table: comment.Table,
Columns: comment.Columns,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: comment.FieldID,
},
},
}
id, ok := cuo.mutation.ID()
if !ok {
return nil, &ValidationError{Name: "ID", err: fmt.Errorf("missing Comment.ID for update")}
}
_spec.Node.ID.Value = id
if ps := cuo.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
if value, ok := cuo.mutation.Name(); ok {
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: value,
Column: comment.FieldName,
})
}
if value, ok := cuo.mutation.Content(); ok {
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: value,
Column: comment.FieldContent,
})
}
if value, ok := cuo.mutation.CreatedAt(); ok {
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
Type: field.TypeTime,
Value: value,
Column: comment.FieldCreatedAt,
})
}
if value, ok := cuo.mutation.UpdatedAt(); ok {
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
Type: field.TypeTime,
Value: value,
Column: comment.FieldUpdatedAt,
})
}
if cuo.mutation.PostCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: true,
Table: comment.PostTable,
Columns: []string{comment.PostColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: article.FieldID,
},
},
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := cuo.mutation.PostIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: true,
Table: comment.PostTable,
Columns: []string{comment.PostColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: article.FieldID,
},
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Add = append(_spec.Edges.Add, edge)
}
_node = &Comment{config: cuo.config}
_spec.Assign = _node.assignValues
_spec.ScanValues = _node.scanValues
if err = sqlgraph.UpdateNode(ctx, cuo.driver, _spec); err != nil {
if _, ok := err.(*sqlgraph.NotFoundError); ok {
err = &NotFoundError{comment.Label}
} else if cerr, ok := isSQLConstraintError(err); ok {
err = cerr
}
return nil, err
}
return _node, nil
}

@ -0,0 +1,61 @@
// Code generated by entc, DO NOT EDIT.
package ent
import (
"entgo.io/ent"
"entgo.io/ent/dialect"
)
// Option function to configure the client.
type Option func(*config)
// Config is the configuration for the client and its builder.
type config struct {
// driver used for executing database requests.
driver dialect.Driver
// debug enable a debug logging.
debug bool
// log used for logging on debug mode.
log func(...interface{})
// hooks to execute on mutations.
hooks *hooks
}
// hooks per client, for fast access.
type hooks struct {
Article []ent.Hook
Comment []ent.Hook
Tag []ent.Hook
}
// Options applies the options on the config object.
func (c *config) options(opts ...Option) {
for _, opt := range opts {
opt(c)
}
if c.debug {
c.driver = dialect.Debug(c.driver, c.log)
}
}
// Debug enables debug logging on the ent.Driver.
func Debug() Option {
return func(c *config) {
c.debug = true
}
}
// Log sets the logging function for debug mode.
func Log(fn func(...interface{})) Option {
return func(c *config) {
c.log = fn
}
}
// Driver configures the client driver.
func Driver(driver dialect.Driver) Option {
return func(c *config) {
c.driver = driver
}
}

@ -0,0 +1,33 @@
// Code generated by entc, DO NOT EDIT.
package ent
import (
"context"
)
type clientCtxKey struct{}
// FromContext returns a Client stored inside a context, or nil if there isn't one.
func FromContext(ctx context.Context) *Client {
c, _ := ctx.Value(clientCtxKey{}).(*Client)
return c
}
// NewContext returns a new context with the given Client attached.
func NewContext(parent context.Context, c *Client) context.Context {
return context.WithValue(parent, clientCtxKey{}, c)
}
type txCtxKey struct{}
// TxFromContext returns a Tx stored inside a context, or nil if there isn't one.
func TxFromContext(ctx context.Context) *Tx {
tx, _ := ctx.Value(txCtxKey{}).(*Tx)
return tx
}
// NewTxContext returns a new context with the given Tx attached.
func NewTxContext(parent context.Context, tx *Tx) context.Context {
return context.WithValue(parent, txCtxKey{}, tx)
}

@ -0,0 +1,270 @@
// Code generated by entc, DO NOT EDIT.
package ent
import (
"errors"
"fmt"
"strings"
"entgo.io/ent"
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
)
// ent aliases to avoid import conflicts in user's code.
type (
Op = ent.Op
Hook = ent.Hook
Value = ent.Value
Query = ent.Query
Policy = ent.Policy
Mutator = ent.Mutator
Mutation = ent.Mutation
MutateFunc = ent.MutateFunc
)
// OrderFunc applies an ordering on the sql selector.
type OrderFunc func(*sql.Selector, func(string) bool)
// Asc applies the given fields in ASC order.
func Asc(fields ...string) OrderFunc {
return func(s *sql.Selector, check func(string) bool) {
for _, f := range fields {
if check(f) {
s.OrderBy(sql.Asc(f))
} else {
s.AddError(&ValidationError{Name: f, err: fmt.Errorf("invalid field %q for ordering", f)})
}
}
}
}
// Desc applies the given fields in DESC order.
func Desc(fields ...string) OrderFunc {
return func(s *sql.Selector, check func(string) bool) {
for _, f := range fields {
if check(f) {
s.OrderBy(sql.Desc(f))
} else {
s.AddError(&ValidationError{Name: f, err: fmt.Errorf("invalid field %q for ordering", f)})
}
}
}
}
// AggregateFunc applies an aggregation step on the group-by traversal/selector.
type AggregateFunc func(*sql.Selector, func(string) bool) string
// As is a pseudo aggregation function for renaming another other functions with custom names. For example:
//
// GroupBy(field1, field2).
// Aggregate(ent.As(ent.Sum(field1), "sum_field1"), (ent.As(ent.Sum(field2), "sum_field2")).
// Scan(ctx, &v)
//
func As(fn AggregateFunc, end string) AggregateFunc {
return func(s *sql.Selector, check func(string) bool) string {
return sql.As(fn(s, check), end)
}
}
// Count applies the "count" aggregation function on each group.
func Count() AggregateFunc {
return func(s *sql.Selector, _ func(string) bool) string {
return sql.Count("*")
}
}
// Max applies the "max" aggregation function on the given field of each group.
func Max(field string) AggregateFunc {
return func(s *sql.Selector, check func(string) bool) string {
if !check(field) {
s.AddError(&ValidationError{Name: field, err: fmt.Errorf("invalid field %q for grouping", field)})
return ""
}
return sql.Max(s.C(field))
}
}
// Mean applies the "mean" aggregation function on the given field of each group.
func Mean(field string) AggregateFunc {
return func(s *sql.Selector, check func(string) bool) string {
if !check(field) {
s.AddError(&ValidationError{Name: field, err: fmt.Errorf("invalid field %q for grouping", field)})
return ""
}
return sql.Avg(s.C(field))
}
}
// Min applies the "min" aggregation function on the given field of each group.
func Min(field string) AggregateFunc {
return func(s *sql.Selector, check func(string) bool) string {
if !check(field) {
s.AddError(&ValidationError{Name: field, err: fmt.Errorf("invalid field %q for grouping", field)})
return ""
}
return sql.Min(s.C(field))
}
}
// Sum applies the "sum" aggregation function on the given field of each group.
func Sum(field string) AggregateFunc {
return func(s *sql.Selector, check func(string) bool) string {
if !check(field) {
s.AddError(&ValidationError{Name: field, err: fmt.Errorf("invalid field %q for grouping", field)})
return ""
}
return sql.Sum(s.C(field))
}
}
// ValidationError returns when validating a field fails.
type ValidationError struct {
Name string // Field or edge name.
err error
}
// Error implements the error interface.
func (e *ValidationError) Error() string {
return e.err.Error()
}
// Unwrap implements the errors.Wrapper interface.
func (e *ValidationError) Unwrap() error {
return e.err
}
// IsValidationError returns a boolean indicating whether the error is a validaton error.
func IsValidationError(err error) bool {
if err == nil {
return false
}
var e *ValidationError
return errors.As(err, &e)
}
// NotFoundError returns when trying to fetch a specific entity and it was not found in the database.
type NotFoundError struct {
label string
}
// Error implements the error interface.
func (e *NotFoundError) Error() string {
return "ent: " + e.label + " not found"
}
// IsNotFound returns a boolean indicating whether the error is a not found error.
func IsNotFound(err error) bool {
if err == nil {
return false
}
var e *NotFoundError
return errors.As(err, &e)
}
// MaskNotFound masks not found error.
func MaskNotFound(err error) error {
if IsNotFound(err) {
return nil
}
return err
}
// NotSingularError returns when trying to fetch a singular entity and more then one was found in the database.
type NotSingularError struct {
label string
}
// Error implements the error interface.
func (e *NotSingularError) Error() string {
return "ent: " + e.label + " not singular"
}
// IsNotSingular returns a boolean indicating whether the error is a not singular error.
func IsNotSingular(err error) bool {
if err == nil {
return false
}
var e *NotSingularError
return errors.As(err, &e)
}
// NotLoadedError returns when trying to get a node that was not loaded by the query.
type NotLoadedError struct {
edge string
}
// Error implements the error interface.
func (e *NotLoadedError) Error() string {
return "ent: " + e.edge + " edge was not loaded"
}
// IsNotLoaded returns a boolean indicating whether the error is a not loaded error.
func IsNotLoaded(err error) bool {
if err == nil {
return false
}
var e *NotLoadedError
return errors.As(err, &e)
}
// ConstraintError returns when trying to create/update one or more entities and
// one or more of their constraints failed. For example, violation of edge or
// field uniqueness.
type ConstraintError struct {
msg string
wrap error
}
// Error implements the error interface.
func (e ConstraintError) Error() string {
return "ent: constraint failed: " + e.msg
}
// Unwrap implements the errors.Wrapper interface.
func (e *ConstraintError) Unwrap() error {
return e.wrap
}
// IsConstraintError returns a boolean indicating whether the error is a constraint failure.
func IsConstraintError(err error) bool {
if err == nil {
return false
}
var e *ConstraintError
return errors.As(err, &e)
}
func isSQLConstraintError(err error) (*ConstraintError, bool) {
var (
msg = err.Error()
// error format per dialect.
errors = [...]string{
"Error 1062", // MySQL 1062 error (ER_DUP_ENTRY).
"UNIQUE constraint failed", // SQLite.
"duplicate key value violates unique constraint", // PostgreSQL.
}
)
if _, ok := err.(*sqlgraph.ConstraintError); ok {
return &ConstraintError{msg, err}, true
}
for i := range errors {
if strings.Contains(msg, errors[i]) {
return &ConstraintError{msg, err}, true
}
}
return nil, false
}
// rollback calls tx.Rollback and wraps the given error with the rollback error if present.
func rollback(tx dialect.Tx, err error) error {
if rerr := tx.Rollback(); rerr != nil {
err = fmt.Errorf("%s: %v", err.Error(), rerr)
}
if err, ok := isSQLConstraintError(err); ok {
return err
}
return err
}

@ -0,0 +1,78 @@
// Code generated by entc, DO NOT EDIT.
package enttest
import (
"context"
"github.com/go-kratos/examples/blog/internal/data/ent"
// required by schema hooks.
_ "github.com/go-kratos/examples/blog/internal/data/ent/runtime"
"entgo.io/ent/dialect/sql/schema"
)
type (
// TestingT is the interface that is shared between
// testing.T and testing.B and used by enttest.
TestingT interface {
FailNow()
Error(...interface{})
}
// Option configures client creation.
Option func(*options)
options struct {
opts []ent.Option
migrateOpts []schema.MigrateOption
}
)
// WithOptions forwards options to client creation.
func WithOptions(opts ...ent.Option) Option {
return func(o *options) {
o.opts = append(o.opts, opts...)
}
}
// WithMigrateOptions forwards options to auto migration.
func WithMigrateOptions(opts ...schema.MigrateOption) Option {
return func(o *options) {
o.migrateOpts = append(o.migrateOpts, opts...)
}
}
func newOptions(opts []Option) *options {
o := &options{}
for _, opt := range opts {
opt(o)
}
return o
}
// Open calls ent.Open and auto-run migration.
func Open(t TestingT, driverName, dataSourceName string, opts ...Option) *ent.Client {
o := newOptions(opts)
c, err := ent.Open(driverName, dataSourceName, o.opts...)
if err != nil {
t.Error(err)
t.FailNow()
}
if err := c.Schema.Create(context.Background(), o.migrateOpts...); err != nil {
t.Error(err)
t.FailNow()
}
return c
}
// NewClient calls ent.NewClient and auto-run migration.
func NewClient(t TestingT, opts ...Option) *ent.Client {
o := newOptions(opts)
c := ent.NewClient(o.opts...)
if err := c.Schema.Create(context.Background(), o.migrateOpts...); err != nil {
t.Error(err)
t.FailNow()
}
return c
}

@ -0,0 +1,230 @@
// Code generated by entc, DO NOT EDIT.
package hook
import (
"context"
"fmt"
"github.com/go-kratos/examples/blog/internal/data/ent"
)
// The ArticleFunc type is an adapter to allow the use of ordinary
// function as Article mutator.
type ArticleFunc func(context.Context, *ent.ArticleMutation) (ent.Value, error)
// Mutate calls f(ctx, m).
func (f ArticleFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
mv, ok := m.(*ent.ArticleMutation)
if !ok {
return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.ArticleMutation", m)
}
return f(ctx, mv)
}
// The CommentFunc type is an adapter to allow the use of ordinary
// function as Comment mutator.
type CommentFunc func(context.Context, *ent.CommentMutation) (ent.Value, error)
// Mutate calls f(ctx, m).
func (f CommentFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
mv, ok := m.(*ent.CommentMutation)
if !ok {
return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.CommentMutation", m)
}
return f(ctx, mv)
}
// The TagFunc type is an adapter to allow the use of ordinary
// function as Tag mutator.
type TagFunc func(context.Context, *ent.TagMutation) (ent.Value, error)
// Mutate calls f(ctx, m).
func (f TagFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
mv, ok := m.(*ent.TagMutation)
if !ok {
return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.TagMutation", m)
}
return f(ctx, mv)
}
// Condition is a hook condition function.
type Condition func(context.Context, ent.Mutation) bool
// And groups conditions with the AND operator.
func And(first, second Condition, rest ...Condition) Condition {
return func(ctx context.Context, m ent.Mutation) bool {
if !first(ctx, m) || !second(ctx, m) {
return false
}
for _, cond := range rest {
if !cond(ctx, m) {
return false
}
}
return true
}
}
// Or groups conditions with the OR operator.
func Or(first, second Condition, rest ...Condition) Condition {
return func(ctx context.Context, m ent.Mutation) bool {
if first(ctx, m) || second(ctx, m) {
return true
}
for _, cond := range rest {
if cond(ctx, m) {
return true
}
}
return false
}
}
// Not negates a given condition.
func Not(cond Condition) Condition {
return func(ctx context.Context, m ent.Mutation) bool {
return !cond(ctx, m)
}
}
// HasOp is a condition testing mutation operation.
func HasOp(op ent.Op) Condition {
return func(_ context.Context, m ent.Mutation) bool {
return m.Op().Is(op)
}
}
// HasAddedFields is a condition validating `.AddedField` on fields.
func HasAddedFields(field string, fields ...string) Condition {
return func(_ context.Context, m ent.Mutation) bool {
if _, exists := m.AddedField(field); !exists {
return false
}
for _, field := range fields {
if _, exists := m.AddedField(field); !exists {
return false
}
}
return true
}
}
// HasClearedFields is a condition validating `.FieldCleared` on fields.
func HasClearedFields(field string, fields ...string) Condition {
return func(_ context.Context, m ent.Mutation) bool {
if exists := m.FieldCleared(field); !exists {
return false
}
for _, field := range fields {
if exists := m.FieldCleared(field); !exists {
return false
}
}
return true
}
}
// HasFields is a condition validating `.Field` on fields.
func HasFields(field string, fields ...string) Condition {
return func(_ context.Context, m ent.Mutation) bool {
if _, exists := m.Field(field); !exists {
return false
}
for _, field := range fields {
if _, exists := m.Field(field); !exists {
return false
}
}
return true
}
}
// If executes the given hook under condition.
//
// hook.If(ComputeAverage, And(HasFields(...), HasAddedFields(...)))
//
func If(hk ent.Hook, cond Condition) ent.Hook {
return func(next ent.Mutator) ent.Mutator {
return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) {
if cond(ctx, m) {
return hk(next).Mutate(ctx, m)
}
return next.Mutate(ctx, m)
})
}
}
// On executes the given hook only for the given operation.
//
// hook.On(Log, ent.Delete|ent.Create)
//
func On(hk ent.Hook, op ent.Op) ent.Hook {
return If(hk, HasOp(op))
}
// Unless skips the given hook only for the given operation.
//
// hook.Unless(Log, ent.Update|ent.UpdateOne)
//
func Unless(hk ent.Hook, op ent.Op) ent.Hook {
return If(hk, Not(HasOp(op)))
}
// FixedError is a hook returning a fixed error.
func FixedError(err error) ent.Hook {
return func(ent.Mutator) ent.Mutator {
return ent.MutateFunc(func(context.Context, ent.Mutation) (ent.Value, error) {
return nil, err
})
}
}
// Reject returns a hook that rejects all operations that match op.
//
// func (T) Hooks() []ent.Hook {
// return []ent.Hook{
// Reject(ent.Delete|ent.Update),
// }
// }
//
func Reject(op ent.Op) ent.Hook {
hk := FixedError(fmt.Errorf("%s operation is not allowed", op))
return On(hk, op)
}
// Chain acts as a list of hooks and is effectively immutable.
// Once created, it will always hold the same set of hooks in the same order.
type Chain struct {
hooks []ent.Hook
}
// NewChain creates a new chain of hooks.
func NewChain(hooks ...ent.Hook) Chain {
return Chain{append([]ent.Hook(nil), hooks...)}
}
// Hook chains the list of hooks and returns the final hook.
func (c Chain) Hook() ent.Hook {
return func(mutator ent.Mutator) ent.Mutator {
for i := len(c.hooks) - 1; i >= 0; i-- {
mutator = c.hooks[i](mutator)
}
return mutator
}
}
// Append extends a chain, adding the specified hook
// as the last ones in the mutation flow.
func (c Chain) Append(hooks ...ent.Hook) Chain {
newHooks := make([]ent.Hook, 0, len(c.hooks)+len(hooks))
newHooks = append(newHooks, c.hooks...)
newHooks = append(newHooks, hooks...)
return Chain{newHooks}
}
// Extend extends a chain, adding the specified chain
// as the last ones in the mutation flow.
func (c Chain) Extend(chain Chain) Chain {
return c.Append(chain.hooks...)
}

@ -0,0 +1,72 @@
// Code generated by entc, DO NOT EDIT.
package migrate
import (
"context"
"fmt"
"io"
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql/schema"
)
var (
// WithGlobalUniqueID sets the universal ids options to the migration.
// If this option is enabled, ent migration will allocate a 1<<32 range
// for the ids of each entity (table).
// Note that this option cannot be applied on tables that already exist.
WithGlobalUniqueID = schema.WithGlobalUniqueID
// WithDropColumn sets the drop column option to the migration.
// If this option is enabled, ent migration will drop old columns
// that were used for both fields and edges. This defaults to false.
WithDropColumn = schema.WithDropColumn
// WithDropIndex sets the drop index option to the migration.
// If this option is enabled, ent migration will drop old indexes
// that were defined in the schema. This defaults to false.
// Note that unique constraints are defined using `UNIQUE INDEX`,
// and therefore, it's recommended to enable this option to get more
// flexibility in the schema changes.
WithDropIndex = schema.WithDropIndex
// WithFixture sets the foreign-key renaming option to the migration when upgrading
// ent from v0.1.0 (issue-#285). Defaults to false.
WithFixture = schema.WithFixture
// WithForeignKeys enables creating foreign-key in schema DDL. This defaults to true.
WithForeignKeys = schema.WithForeignKeys
)
// Schema is the API for creating, migrating and dropping a schema.
type Schema struct {
drv dialect.Driver
universalID bool
}
// NewSchema creates a new schema client.
func NewSchema(drv dialect.Driver) *Schema { return &Schema{drv: drv} }
// Create creates all schema resources.
func (s *Schema) Create(ctx context.Context, opts ...schema.MigrateOption) error {
migrate, err := schema.NewMigrate(s.drv, opts...)
if err != nil {
return fmt.Errorf("ent/migrate: %v", err)
}
return migrate.Create(ctx, Tables...)
}
// WriteTo writes the schema changes to w instead of running them against the database.
//
// if err := client.Schema.WriteTo(context.Background(), os.Stdout); err != nil {
// log.Fatal(err)
// }
//
func (s *Schema) WriteTo(ctx context.Context, w io.Writer, opts ...schema.MigrateOption) error {
drv := &schema.WriteDriver{
Writer: w,
Driver: s.drv,
}
migrate, err := schema.NewMigrate(drv, opts...)
if err != nil {
return fmt.Errorf("ent/migrate: %v", err)
}
return migrate.Create(ctx, Tables...)
}

@ -0,0 +1,105 @@
// Code generated by entc, DO NOT EDIT.
package migrate
import (
"entgo.io/ent/dialect/sql/schema"
"entgo.io/ent/schema/field"
)
var (
// ArticlesColumns holds the columns for the "articles" table.
ArticlesColumns = []*schema.Column{
{Name: "id", Type: field.TypeInt64, Increment: true},
{Name: "title", Type: field.TypeString},
{Name: "content", Type: field.TypeString},
{Name: "created_at", Type: field.TypeTime, SchemaType: map[string]string{"mysql": "datetime"}},
{Name: "updated_at", Type: field.TypeTime, SchemaType: map[string]string{"mysql": "datetime"}},
}
// ArticlesTable holds the schema information for the "articles" table.
ArticlesTable = &schema.Table{
Name: "articles",
Columns: ArticlesColumns,
PrimaryKey: []*schema.Column{ArticlesColumns[0]},
ForeignKeys: []*schema.ForeignKey{},
}
// CommentsColumns holds the columns for the "comments" table.
CommentsColumns = []*schema.Column{
{Name: "id", Type: field.TypeInt64, Increment: true},
{Name: "name", Type: field.TypeString},
{Name: "content", Type: field.TypeString},
{Name: "created_at", Type: field.TypeTime, SchemaType: map[string]string{"mysql": "datetime"}},
{Name: "updated_at", Type: field.TypeTime, SchemaType: map[string]string{"mysql": "datetime"}},
{Name: "article_comments", Type: field.TypeInt64, Nullable: true},
}
// CommentsTable holds the schema information for the "comments" table.
CommentsTable = &schema.Table{
Name: "comments",
Columns: CommentsColumns,
PrimaryKey: []*schema.Column{CommentsColumns[0]},
ForeignKeys: []*schema.ForeignKey{
{
Symbol: "comments_articles_comments",
Columns: []*schema.Column{CommentsColumns[5]},
RefColumns: []*schema.Column{ArticlesColumns[0]},
OnDelete: schema.SetNull,
},
},
}
// TagsColumns holds the columns for the "tags" table.
TagsColumns = []*schema.Column{
{Name: "id", Type: field.TypeInt64, Increment: true},
{Name: "slug", Type: field.TypeString},
{Name: "name", Type: field.TypeString},
{Name: "created_at", Type: field.TypeTime, SchemaType: map[string]string{"mysql": "datetime"}},
{Name: "updated_at", Type: field.TypeTime, SchemaType: map[string]string{"mysql": "datetime"}},
}
// TagsTable holds the schema information for the "tags" table.
TagsTable = &schema.Table{
Name: "tags",
Columns: TagsColumns,
PrimaryKey: []*schema.Column{TagsColumns[0]},
ForeignKeys: []*schema.ForeignKey{},
}
// TagPostsColumns holds the columns for the "tag_posts" table.
TagPostsColumns = []*schema.Column{
{Name: "tag_id", Type: field.TypeInt64},
{Name: "article_id", Type: field.TypeInt64},
}
// TagPostsTable holds the schema information for the "tag_posts" table.
TagPostsTable = &schema.Table{
Name: "tag_posts",
Columns: TagPostsColumns,
PrimaryKey: []*schema.Column{TagPostsColumns[0], TagPostsColumns[1]},
ForeignKeys: []*schema.ForeignKey{
{
Symbol: "tag_posts_tag_id",
Columns: []*schema.Column{TagPostsColumns[0]},
RefColumns: []*schema.Column{TagsColumns[0]},
OnDelete: schema.Cascade,
},
{
Symbol: "tag_posts_article_id",
Columns: []*schema.Column{TagPostsColumns[1]},
RefColumns: []*schema.Column{ArticlesColumns[0]},
OnDelete: schema.Cascade,
},
},
}
// Tables holds all the tables in the schema.
Tables = []*schema.Table{
ArticlesTable,
CommentsTable,
TagsTable,
TagPostsTable,
}
)
func init() {
CommentsTable.ForeignKeys[0].RefTable = ArticlesTable
TagPostsTable.ForeignKeys[0].RefTable = TagsTable
TagPostsTable.ForeignKeys[1].RefTable = ArticlesTable
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,16 @@
// Code generated by entc, DO NOT EDIT.
package predicate
import (
"entgo.io/ent/dialect/sql"
)
// Article is the predicate function for article builders.
type Article func(*sql.Selector)
// Comment is the predicate function for comment builders.
type Comment func(*sql.Selector)
// Tag is the predicate function for tag builders.
type Tag func(*sql.Selector)

@ -0,0 +1,48 @@
// Code generated by entc, DO NOT EDIT.
package ent
import (
"time"
"github.com/go-kratos/examples/blog/internal/data/ent/article"
"github.com/go-kratos/examples/blog/internal/data/ent/comment"
"github.com/go-kratos/examples/blog/internal/data/ent/schema"
"github.com/go-kratos/examples/blog/internal/data/ent/tag"
)
// The init function reads all schema descriptors with runtime code
// (default values, validators, hooks and policies) and stitches it
// to their package variables.
func init() {
articleFields := schema.Article{}.Fields()
_ = articleFields
// articleDescCreatedAt is the schema descriptor for created_at field.
articleDescCreatedAt := articleFields[3].Descriptor()
// article.DefaultCreatedAt holds the default value on creation for the created_at field.
article.DefaultCreatedAt = articleDescCreatedAt.Default.(func() time.Time)
// articleDescUpdatedAt is the schema descriptor for updated_at field.
articleDescUpdatedAt := articleFields[4].Descriptor()
// article.DefaultUpdatedAt holds the default value on creation for the updated_at field.
article.DefaultUpdatedAt = articleDescUpdatedAt.Default.(func() time.Time)
commentFields := schema.Comment{}.Fields()
_ = commentFields
// commentDescCreatedAt is the schema descriptor for created_at field.
commentDescCreatedAt := commentFields[3].Descriptor()
// comment.DefaultCreatedAt holds the default value on creation for the created_at field.
comment.DefaultCreatedAt = commentDescCreatedAt.Default.(func() time.Time)
// commentDescUpdatedAt is the schema descriptor for updated_at field.
commentDescUpdatedAt := commentFields[4].Descriptor()
// comment.DefaultUpdatedAt holds the default value on creation for the updated_at field.
comment.DefaultUpdatedAt = commentDescUpdatedAt.Default.(func() time.Time)
tagFields := schema.Tag{}.Fields()
_ = tagFields
// tagDescCreatedAt is the schema descriptor for created_at field.
tagDescCreatedAt := tagFields[3].Descriptor()
// tag.DefaultCreatedAt holds the default value on creation for the created_at field.
tag.DefaultCreatedAt = tagDescCreatedAt.Default.(func() time.Time)
// tagDescUpdatedAt is the schema descriptor for updated_at field.
tagDescUpdatedAt := tagFields[4].Descriptor()
// tag.DefaultUpdatedAt holds the default value on creation for the updated_at field.
tag.DefaultUpdatedAt = tagDescUpdatedAt.Default.(func() time.Time)
}

@ -0,0 +1,10 @@
// Code generated by entc, DO NOT EDIT.
package runtime
// The schema-stitching logic is generated in github.com/go-kratos/examples/blog/internal/data/ent/runtime.go
const (
Version = "v0.6.0" // Version of ent codegen.
Sum = "h1:oo/a8sXPQKzHYFlVwmwOnyzBy+u8FWQsoLLqFCrOBt0=" // Sum of ent codegen.
)

@ -0,0 +1,40 @@
package schema
import (
"entgo.io/ent"
"entgo.io/ent/dialect"
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/field"
"time"
)
// Article holds the schema definition for the Article entity.
type Article struct {
ent.Schema
}
// Fields of the Post.
func (Article) Fields() []ent.Field {
return []ent.Field{
field.Int64("id"),
field.String("title"),
field.String("content"),
field.Time("created_at").
Default(time.Now).SchemaType(map[string]string{
dialect.MySQL: "datetime",
}),
field.Time("updated_at").
Default(time.Now).SchemaType(map[string]string{
dialect.MySQL: "datetime",
}),
}
}
// Edges of the Post.
func (Article) Edges() []ent.Edge {
return []ent.Edge{
edge.To("comments", Comment.Type),
edge.From("tags", Tag.Type).
Ref("posts"),
}
}

@ -0,0 +1,40 @@
package schema
import (
"entgo.io/ent"
"entgo.io/ent/dialect"
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/field"
"time"
)
// Comment holds the schema definition for the Comment entity.
type Comment struct {
ent.Schema
}
// Fields of the Comment.
func (Comment) Fields() []ent.Field {
return []ent.Field{
field.Int64("id"),
field.String("name"),
field.String("content"),
field.Time("created_at").
Default(time.Now).SchemaType(map[string]string{
dialect.MySQL: "datetime",
}),
field.Time("updated_at").
Default(time.Now).SchemaType(map[string]string{
dialect.MySQL: "datetime",
}),
}
}
// Edges of the Comment.
func (Comment) Edges() []ent.Edge {
return []ent.Edge{
edge.From("post", Article.Type).
Ref("comments").
Unique(),
}
}

@ -0,0 +1,38 @@
package schema
import (
"entgo.io/ent"
"entgo.io/ent/dialect"
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/field"
"time"
)
// Tag holds the schema definition for the Tag entity.
type Tag struct {
ent.Schema
}
// Fields of the Tag.
func (Tag) Fields() []ent.Field {
return []ent.Field{
field.Int64("id"),
field.String("slug"),
field.String("name"),
field.Time("created_at").
Default(time.Now).SchemaType(map[string]string{
dialect.MySQL: "datetime",
}),
field.Time("updated_at").
Default(time.Now).SchemaType(map[string]string{
dialect.MySQL: "datetime",
}),
}
}
// Edges of the Tag.
func (Tag) Edges() []ent.Edge {
return []ent.Edge{
edge.To("posts", Article.Type),
}
}

@ -0,0 +1,158 @@
// Code generated by entc, DO NOT EDIT.
package ent
import (
"fmt"
"strings"
"time"
"entgo.io/ent/dialect/sql"
"github.com/go-kratos/examples/blog/internal/data/ent/tag"
)
// Tag is the model entity for the Tag schema.
type Tag struct {
config `json:"-"`
// ID of the ent.
ID int64 `json:"id,omitempty"`
// Slug holds the value of the "slug" field.
Slug string `json:"slug,omitempty"`
// Name holds the value of the "name" field.
Name string `json:"name,omitempty"`
// CreatedAt holds the value of the "created_at" field.
CreatedAt time.Time `json:"created_at,omitempty"`
// UpdatedAt holds the value of the "updated_at" field.
UpdatedAt time.Time `json:"updated_at,omitempty"`
// Edges holds the relations/edges for other nodes in the graph.
// The values are being populated by the TagQuery when eager-loading is set.
Edges TagEdges `json:"edges"`
}
// TagEdges holds the relations/edges for other nodes in the graph.
type TagEdges struct {
// Posts holds the value of the posts edge.
Posts []*Article `json:"posts,omitempty"`
// loadedTypes holds the information for reporting if a
// type was loaded (or requested) in eager-loading or not.
loadedTypes [1]bool
}
// PostsOrErr returns the Posts value or an error if the edge
// was not loaded in eager-loading.
func (e TagEdges) PostsOrErr() ([]*Article, error) {
if e.loadedTypes[0] {
return e.Posts, nil
}
return nil, &NotLoadedError{edge: "posts"}
}
// scanValues returns the types for scanning values from sql.Rows.
func (*Tag) scanValues(columns []string) ([]interface{}, error) {
values := make([]interface{}, len(columns))
for i := range columns {
switch columns[i] {
case tag.FieldID:
values[i] = &sql.NullInt64{}
case tag.FieldSlug, tag.FieldName:
values[i] = &sql.NullString{}
case tag.FieldCreatedAt, tag.FieldUpdatedAt:
values[i] = &sql.NullTime{}
default:
return nil, fmt.Errorf("unexpected column %q for type Tag", columns[i])
}
}
return values, nil
}
// assignValues assigns the values that were returned from sql.Rows (after scanning)
// to the Tag fields.
func (t *Tag) assignValues(columns []string, values []interface{}) error {
if m, n := len(values), len(columns); m < n {
return fmt.Errorf("mismatch number of scan values: %d != %d", m, n)
}
for i := range columns {
switch columns[i] {
case tag.FieldID:
value, ok := values[i].(*sql.NullInt64)
if !ok {
return fmt.Errorf("unexpected type %T for field id", value)
}
t.ID = int64(value.Int64)
case tag.FieldSlug:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field slug", values[i])
} else if value.Valid {
t.Slug = value.String
}
case tag.FieldName:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field name", values[i])
} else if value.Valid {
t.Name = value.String
}
case tag.FieldCreatedAt:
if value, ok := values[i].(*sql.NullTime); !ok {
return fmt.Errorf("unexpected type %T for field created_at", values[i])
} else if value.Valid {
t.CreatedAt = value.Time
}
case tag.FieldUpdatedAt:
if value, ok := values[i].(*sql.NullTime); !ok {
return fmt.Errorf("unexpected type %T for field updated_at", values[i])
} else if value.Valid {
t.UpdatedAt = value.Time
}
}
}
return nil
}
// QueryPosts queries the "posts" edge of the Tag entity.
func (t *Tag) QueryPosts() *ArticleQuery {
return (&TagClient{config: t.config}).QueryPosts(t)
}
// Update returns a builder for updating this Tag.
// Note that you need to call Tag.Unwrap() before calling this method if this Tag
// was returned from a transaction, and the transaction was committed or rolled back.
func (t *Tag) Update() *TagUpdateOne {
return (&TagClient{config: t.config}).UpdateOne(t)
}
// Unwrap unwraps the Tag entity that was returned from a transaction after it was closed,
// so that all future queries will be executed through the driver which created the transaction.
func (t *Tag) Unwrap() *Tag {
tx, ok := t.config.driver.(*txDriver)
if !ok {
panic("ent: Tag is not a transactional entity")
}
t.config.driver = tx.drv
return t
}
// String implements the fmt.Stringer.
func (t *Tag) String() string {
var builder strings.Builder
builder.WriteString("Tag(")
builder.WriteString(fmt.Sprintf("id=%v", t.ID))
builder.WriteString(", slug=")
builder.WriteString(t.Slug)
builder.WriteString(", name=")
builder.WriteString(t.Name)
builder.WriteString(", created_at=")
builder.WriteString(t.CreatedAt.Format(time.ANSIC))
builder.WriteString(", updated_at=")
builder.WriteString(t.UpdatedAt.Format(time.ANSIC))
builder.WriteByte(')')
return builder.String()
}
// Tags is a parsable slice of Tag.
type Tags []*Tag
func (t Tags) config(cfg config) {
for _i := range t {
t[_i].config = cfg
}
}

@ -0,0 +1,65 @@
// Code generated by entc, DO NOT EDIT.
package tag
import (
"time"
)
const (
// Label holds the string label denoting the tag type in the database.
Label = "tag"
// FieldID holds the string denoting the id field in the database.
FieldID = "id"
// FieldSlug holds the string denoting the slug field in the database.
FieldSlug = "slug"
// FieldName holds the string denoting the name field in the database.
FieldName = "name"
// FieldCreatedAt holds the string denoting the created_at field in the database.
FieldCreatedAt = "created_at"
// FieldUpdatedAt holds the string denoting the updated_at field in the database.
FieldUpdatedAt = "updated_at"
// EdgePosts holds the string denoting the posts edge name in mutations.
EdgePosts = "posts"
// Table holds the table name of the tag in the database.
Table = "tags"
// PostsTable is the table the holds the posts relation/edge. The primary key declared below.
PostsTable = "tag_posts"
// PostsInverseTable is the table name for the Article entity.
// It exists in this package in order to avoid circular dependency with the "article" package.
PostsInverseTable = "articles"
)
// Columns holds all SQL columns for tag fields.
var Columns = []string{
FieldID,
FieldSlug,
FieldName,
FieldCreatedAt,
FieldUpdatedAt,
}
var (
// PostsPrimaryKey and PostsColumn2 are the table columns denoting the
// primary key for the posts relation (M2M).
PostsPrimaryKey = []string{"tag_id", "article_id"}
)
// ValidColumn reports if the column name is valid (part of the table columns).
func ValidColumn(column string) bool {
for i := range Columns {
if column == Columns[i] {
return true
}
}
return false
}
var (
// DefaultCreatedAt holds the default value on creation for the "created_at" field.
DefaultCreatedAt func() time.Time
// DefaultUpdatedAt holds the default value on creation for the "updated_at" field.
DefaultUpdatedAt func() time.Time
)

@ -0,0 +1,556 @@
// Code generated by entc, DO NOT EDIT.
package tag
import (
"time"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"github.com/go-kratos/examples/blog/internal/data/ent/predicate"
)
// ID filters vertices based on their ID field.
func ID(id int64) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldID), id))
})
}
// IDEQ applies the EQ predicate on the ID field.
func IDEQ(id int64) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldID), id))
})
}
// IDNEQ applies the NEQ predicate on the ID field.
func IDNEQ(id int64) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.NEQ(s.C(FieldID), id))
})
}
// IDIn applies the In predicate on the ID field.
func IDIn(ids ...int64) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
// if not arguments were provided, append the FALSE constants,
// since we can't apply "IN ()". This will make this predicate falsy.
if len(ids) == 0 {
s.Where(sql.False())
return
}
v := make([]interface{}, len(ids))
for i := range v {
v[i] = ids[i]
}
s.Where(sql.In(s.C(FieldID), v...))
})
}
// IDNotIn applies the NotIn predicate on the ID field.
func IDNotIn(ids ...int64) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
// if not arguments were provided, append the FALSE constants,
// since we can't apply "IN ()". This will make this predicate falsy.
if len(ids) == 0 {
s.Where(sql.False())
return
}
v := make([]interface{}, len(ids))
for i := range v {
v[i] = ids[i]
}
s.Where(sql.NotIn(s.C(FieldID), v...))
})
}
// IDGT applies the GT predicate on the ID field.
func IDGT(id int64) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.GT(s.C(FieldID), id))
})
}
// IDGTE applies the GTE predicate on the ID field.
func IDGTE(id int64) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.GTE(s.C(FieldID), id))
})
}
// IDLT applies the LT predicate on the ID field.
func IDLT(id int64) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.LT(s.C(FieldID), id))
})
}
// IDLTE applies the LTE predicate on the ID field.
func IDLTE(id int64) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.LTE(s.C(FieldID), id))
})
}
// Slug applies equality check predicate on the "slug" field. It's identical to SlugEQ.
func Slug(v string) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldSlug), v))
})
}
// Name applies equality check predicate on the "name" field. It's identical to NameEQ.
func Name(v string) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldName), v))
})
}
// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ.
func CreatedAt(v time.Time) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldCreatedAt), v))
})
}
// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ.
func UpdatedAt(v time.Time) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldUpdatedAt), v))
})
}
// SlugEQ applies the EQ predicate on the "slug" field.
func SlugEQ(v string) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldSlug), v))
})
}
// SlugNEQ applies the NEQ predicate on the "slug" field.
func SlugNEQ(v string) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.NEQ(s.C(FieldSlug), v))
})
}
// SlugIn applies the In predicate on the "slug" field.
func SlugIn(vs ...string) predicate.Tag {
v := make([]interface{}, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.Tag(func(s *sql.Selector) {
// if not arguments were provided, append the FALSE constants,
// since we can't apply "IN ()". This will make this predicate falsy.
if len(v) == 0 {
s.Where(sql.False())
return
}
s.Where(sql.In(s.C(FieldSlug), v...))
})
}
// SlugNotIn applies the NotIn predicate on the "slug" field.
func SlugNotIn(vs ...string) predicate.Tag {
v := make([]interface{}, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.Tag(func(s *sql.Selector) {
// if not arguments were provided, append the FALSE constants,
// since we can't apply "IN ()". This will make this predicate falsy.
if len(v) == 0 {
s.Where(sql.False())
return
}
s.Where(sql.NotIn(s.C(FieldSlug), v...))
})
}
// SlugGT applies the GT predicate on the "slug" field.
func SlugGT(v string) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.GT(s.C(FieldSlug), v))
})
}
// SlugGTE applies the GTE predicate on the "slug" field.
func SlugGTE(v string) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.GTE(s.C(FieldSlug), v))
})
}
// SlugLT applies the LT predicate on the "slug" field.
func SlugLT(v string) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.LT(s.C(FieldSlug), v))
})
}
// SlugLTE applies the LTE predicate on the "slug" field.
func SlugLTE(v string) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.LTE(s.C(FieldSlug), v))
})
}
// SlugContains applies the Contains predicate on the "slug" field.
func SlugContains(v string) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.Contains(s.C(FieldSlug), v))
})
}
// SlugHasPrefix applies the HasPrefix predicate on the "slug" field.
func SlugHasPrefix(v string) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.HasPrefix(s.C(FieldSlug), v))
})
}
// SlugHasSuffix applies the HasSuffix predicate on the "slug" field.
func SlugHasSuffix(v string) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.HasSuffix(s.C(FieldSlug), v))
})
}
// SlugEqualFold applies the EqualFold predicate on the "slug" field.
func SlugEqualFold(v string) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.EqualFold(s.C(FieldSlug), v))
})
}
// SlugContainsFold applies the ContainsFold predicate on the "slug" field.
func SlugContainsFold(v string) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.ContainsFold(s.C(FieldSlug), v))
})
}
// NameEQ applies the EQ predicate on the "name" field.
func NameEQ(v string) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldName), v))
})
}
// NameNEQ applies the NEQ predicate on the "name" field.
func NameNEQ(v string) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.NEQ(s.C(FieldName), v))
})
}
// NameIn applies the In predicate on the "name" field.
func NameIn(vs ...string) predicate.Tag {
v := make([]interface{}, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.Tag(func(s *sql.Selector) {
// if not arguments were provided, append the FALSE constants,
// since we can't apply "IN ()". This will make this predicate falsy.
if len(v) == 0 {
s.Where(sql.False())
return
}
s.Where(sql.In(s.C(FieldName), v...))
})
}
// NameNotIn applies the NotIn predicate on the "name" field.
func NameNotIn(vs ...string) predicate.Tag {
v := make([]interface{}, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.Tag(func(s *sql.Selector) {
// if not arguments were provided, append the FALSE constants,
// since we can't apply "IN ()". This will make this predicate falsy.
if len(v) == 0 {
s.Where(sql.False())
return
}
s.Where(sql.NotIn(s.C(FieldName), v...))
})
}
// NameGT applies the GT predicate on the "name" field.
func NameGT(v string) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.GT(s.C(FieldName), v))
})
}
// NameGTE applies the GTE predicate on the "name" field.
func NameGTE(v string) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.GTE(s.C(FieldName), v))
})
}
// NameLT applies the LT predicate on the "name" field.
func NameLT(v string) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.LT(s.C(FieldName), v))
})
}
// NameLTE applies the LTE predicate on the "name" field.
func NameLTE(v string) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.LTE(s.C(FieldName), v))
})
}
// NameContains applies the Contains predicate on the "name" field.
func NameContains(v string) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.Contains(s.C(FieldName), v))
})
}
// NameHasPrefix applies the HasPrefix predicate on the "name" field.
func NameHasPrefix(v string) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.HasPrefix(s.C(FieldName), v))
})
}
// NameHasSuffix applies the HasSuffix predicate on the "name" field.
func NameHasSuffix(v string) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.HasSuffix(s.C(FieldName), v))
})
}
// NameEqualFold applies the EqualFold predicate on the "name" field.
func NameEqualFold(v string) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.EqualFold(s.C(FieldName), v))
})
}
// NameContainsFold applies the ContainsFold predicate on the "name" field.
func NameContainsFold(v string) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.ContainsFold(s.C(FieldName), v))
})
}
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
func CreatedAtEQ(v time.Time) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldCreatedAt), v))
})
}
// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
func CreatedAtNEQ(v time.Time) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.NEQ(s.C(FieldCreatedAt), v))
})
}
// CreatedAtIn applies the In predicate on the "created_at" field.
func CreatedAtIn(vs ...time.Time) predicate.Tag {
v := make([]interface{}, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.Tag(func(s *sql.Selector) {
// if not arguments were provided, append the FALSE constants,
// since we can't apply "IN ()". This will make this predicate falsy.
if len(v) == 0 {
s.Where(sql.False())
return
}
s.Where(sql.In(s.C(FieldCreatedAt), v...))
})
}
// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
func CreatedAtNotIn(vs ...time.Time) predicate.Tag {
v := make([]interface{}, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.Tag(func(s *sql.Selector) {
// if not arguments were provided, append the FALSE constants,
// since we can't apply "IN ()". This will make this predicate falsy.
if len(v) == 0 {
s.Where(sql.False())
return
}
s.Where(sql.NotIn(s.C(FieldCreatedAt), v...))
})
}
// CreatedAtGT applies the GT predicate on the "created_at" field.
func CreatedAtGT(v time.Time) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.GT(s.C(FieldCreatedAt), v))
})
}
// CreatedAtGTE applies the GTE predicate on the "created_at" field.
func CreatedAtGTE(v time.Time) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.GTE(s.C(FieldCreatedAt), v))
})
}
// CreatedAtLT applies the LT predicate on the "created_at" field.
func CreatedAtLT(v time.Time) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.LT(s.C(FieldCreatedAt), v))
})
}
// CreatedAtLTE applies the LTE predicate on the "created_at" field.
func CreatedAtLTE(v time.Time) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.LTE(s.C(FieldCreatedAt), v))
})
}
// UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
func UpdatedAtEQ(v time.Time) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldUpdatedAt), v))
})
}
// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field.
func UpdatedAtNEQ(v time.Time) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.NEQ(s.C(FieldUpdatedAt), v))
})
}
// UpdatedAtIn applies the In predicate on the "updated_at" field.
func UpdatedAtIn(vs ...time.Time) predicate.Tag {
v := make([]interface{}, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.Tag(func(s *sql.Selector) {
// if not arguments were provided, append the FALSE constants,
// since we can't apply "IN ()". This will make this predicate falsy.
if len(v) == 0 {
s.Where(sql.False())
return
}
s.Where(sql.In(s.C(FieldUpdatedAt), v...))
})
}
// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field.
func UpdatedAtNotIn(vs ...time.Time) predicate.Tag {
v := make([]interface{}, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.Tag(func(s *sql.Selector) {
// if not arguments were provided, append the FALSE constants,
// since we can't apply "IN ()". This will make this predicate falsy.
if len(v) == 0 {
s.Where(sql.False())
return
}
s.Where(sql.NotIn(s.C(FieldUpdatedAt), v...))
})
}
// UpdatedAtGT applies the GT predicate on the "updated_at" field.
func UpdatedAtGT(v time.Time) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.GT(s.C(FieldUpdatedAt), v))
})
}
// UpdatedAtGTE applies the GTE predicate on the "updated_at" field.
func UpdatedAtGTE(v time.Time) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.GTE(s.C(FieldUpdatedAt), v))
})
}
// UpdatedAtLT applies the LT predicate on the "updated_at" field.
func UpdatedAtLT(v time.Time) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.LT(s.C(FieldUpdatedAt), v))
})
}
// UpdatedAtLTE applies the LTE predicate on the "updated_at" field.
func UpdatedAtLTE(v time.Time) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s.Where(sql.LTE(s.C(FieldUpdatedAt), v))
})
}
// HasPosts applies the HasEdge predicate on the "posts" edge.
func HasPosts() predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
step := sqlgraph.NewStep(
sqlgraph.From(Table, FieldID),
sqlgraph.To(PostsTable, FieldID),
sqlgraph.Edge(sqlgraph.M2M, false, PostsTable, PostsPrimaryKey...),
)
sqlgraph.HasNeighbors(s, step)
})
}
// HasPostsWith applies the HasEdge predicate on the "posts" edge with a given conditions (other predicates).
func HasPostsWith(preds ...predicate.Article) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
step := sqlgraph.NewStep(
sqlgraph.From(Table, FieldID),
sqlgraph.To(PostsInverseTable, FieldID),
sqlgraph.Edge(sqlgraph.M2M, false, PostsTable, PostsPrimaryKey...),
)
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
for _, p := range preds {
p(s)
}
})
})
}
// And groups predicates with the AND operator between them.
func And(predicates ...predicate.Tag) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s1 := s.Clone().SetP(nil)
for _, p := range predicates {
p(s1)
}
s.Where(s1.P())
})
}
// Or groups predicates with the OR operator between them.
func Or(predicates ...predicate.Tag) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
s1 := s.Clone().SetP(nil)
for i, p := range predicates {
if i > 0 {
s1.Or()
}
p(s1)
}
s.Where(s1.P())
})
}
// Not applies the not operator on the given predicate.
func Not(p predicate.Tag) predicate.Tag {
return predicate.Tag(func(s *sql.Selector) {
p(s.Not())
})
}

@ -0,0 +1,315 @@
// Code generated by entc, DO NOT EDIT.
package ent
import (
"context"
"errors"
"fmt"
"time"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
"github.com/go-kratos/examples/blog/internal/data/ent/article"
"github.com/go-kratos/examples/blog/internal/data/ent/tag"
)
// TagCreate is the builder for creating a Tag entity.
type TagCreate struct {
config
mutation *TagMutation
hooks []Hook
}
// SetSlug sets the "slug" field.
func (tc *TagCreate) SetSlug(s string) *TagCreate {
tc.mutation.SetSlug(s)
return tc
}
// SetName sets the "name" field.
func (tc *TagCreate) SetName(s string) *TagCreate {
tc.mutation.SetName(s)
return tc
}
// SetCreatedAt sets the "created_at" field.
func (tc *TagCreate) SetCreatedAt(t time.Time) *TagCreate {
tc.mutation.SetCreatedAt(t)
return tc
}
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
func (tc *TagCreate) SetNillableCreatedAt(t *time.Time) *TagCreate {
if t != nil {
tc.SetCreatedAt(*t)
}
return tc
}
// SetUpdatedAt sets the "updated_at" field.
func (tc *TagCreate) SetUpdatedAt(t time.Time) *TagCreate {
tc.mutation.SetUpdatedAt(t)
return tc
}
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
func (tc *TagCreate) SetNillableUpdatedAt(t *time.Time) *TagCreate {
if t != nil {
tc.SetUpdatedAt(*t)
}
return tc
}
// SetID sets the "id" field.
func (tc *TagCreate) SetID(i int64) *TagCreate {
tc.mutation.SetID(i)
return tc
}
// AddPostIDs adds the "posts" edge to the Article entity by IDs.
func (tc *TagCreate) AddPostIDs(ids ...int64) *TagCreate {
tc.mutation.AddPostIDs(ids...)
return tc
}
// AddPosts adds the "posts" edges to the Article entity.
func (tc *TagCreate) AddPosts(a ...*Article) *TagCreate {
ids := make([]int64, len(a))
for i := range a {
ids[i] = a[i].ID
}
return tc.AddPostIDs(ids...)
}
// Mutation returns the TagMutation object of the builder.
func (tc *TagCreate) Mutation() *TagMutation {
return tc.mutation
}
// Save creates the Tag in the database.
func (tc *TagCreate) Save(ctx context.Context) (*Tag, error) {
var (
err error
node *Tag
)
tc.defaults()
if len(tc.hooks) == 0 {
if err = tc.check(); err != nil {
return nil, err
}
node, err = tc.sqlSave(ctx)
} else {
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
mutation, ok := m.(*TagMutation)
if !ok {
return nil, fmt.Errorf("unexpected mutation type %T", m)
}
if err = tc.check(); err != nil {
return nil, err
}
tc.mutation = mutation
node, err = tc.sqlSave(ctx)
mutation.done = true
return node, err
})
for i := len(tc.hooks) - 1; i >= 0; i-- {
mut = tc.hooks[i](mut)
}
if _, err := mut.Mutate(ctx, tc.mutation); err != nil {
return nil, err
}
}
return node, err
}
// SaveX calls Save and panics if Save returns an error.
func (tc *TagCreate) SaveX(ctx context.Context) *Tag {
v, err := tc.Save(ctx)
if err != nil {
panic(err)
}
return v
}
// defaults sets the default values of the builder before save.
func (tc *TagCreate) defaults() {
if _, ok := tc.mutation.CreatedAt(); !ok {
v := tag.DefaultCreatedAt()
tc.mutation.SetCreatedAt(v)
}
if _, ok := tc.mutation.UpdatedAt(); !ok {
v := tag.DefaultUpdatedAt()
tc.mutation.SetUpdatedAt(v)
}
}
// check runs all checks and user-defined validators on the builder.
func (tc *TagCreate) check() error {
if _, ok := tc.mutation.Slug(); !ok {
return &ValidationError{Name: "slug", err: errors.New("ent: missing required field \"slug\"")}
}
if _, ok := tc.mutation.Name(); !ok {
return &ValidationError{Name: "name", err: errors.New("ent: missing required field \"name\"")}
}
if _, ok := tc.mutation.CreatedAt(); !ok {
return &ValidationError{Name: "created_at", err: errors.New("ent: missing required field \"created_at\"")}
}
if _, ok := tc.mutation.UpdatedAt(); !ok {
return &ValidationError{Name: "updated_at", err: errors.New("ent: missing required field \"updated_at\"")}
}
return nil
}
func (tc *TagCreate) sqlSave(ctx context.Context) (*Tag, error) {
_node, _spec := tc.createSpec()
if err := sqlgraph.CreateNode(ctx, tc.driver, _spec); err != nil {
if cerr, ok := isSQLConstraintError(err); ok {
err = cerr
}
return nil, err
}
if _node.ID == 0 {
id := _spec.ID.Value.(int64)
_node.ID = int64(id)
}
return _node, nil
}
func (tc *TagCreate) createSpec() (*Tag, *sqlgraph.CreateSpec) {
var (
_node = &Tag{config: tc.config}
_spec = &sqlgraph.CreateSpec{
Table: tag.Table,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: tag.FieldID,
},
}
)
if id, ok := tc.mutation.ID(); ok {
_node.ID = id
_spec.ID.Value = id
}
if value, ok := tc.mutation.Slug(); ok {
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: value,
Column: tag.FieldSlug,
})
_node.Slug = value
}
if value, ok := tc.mutation.Name(); ok {
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: value,
Column: tag.FieldName,
})
_node.Name = value
}
if value, ok := tc.mutation.CreatedAt(); ok {
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeTime,
Value: value,
Column: tag.FieldCreatedAt,
})
_node.CreatedAt = value
}
if value, ok := tc.mutation.UpdatedAt(); ok {
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeTime,
Value: value,
Column: tag.FieldUpdatedAt,
})
_node.UpdatedAt = value
}
if nodes := tc.mutation.PostsIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2M,
Inverse: false,
Table: tag.PostsTable,
Columns: tag.PostsPrimaryKey,
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: article.FieldID,
},
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges = append(_spec.Edges, edge)
}
return _node, _spec
}
// TagCreateBulk is the builder for creating many Tag entities in bulk.
type TagCreateBulk struct {
config
builders []*TagCreate
}
// Save creates the Tag entities in the database.
func (tcb *TagCreateBulk) Save(ctx context.Context) ([]*Tag, error) {
specs := make([]*sqlgraph.CreateSpec, len(tcb.builders))
nodes := make([]*Tag, len(tcb.builders))
mutators := make([]Mutator, len(tcb.builders))
for i := range tcb.builders {
func(i int, root context.Context) {
builder := tcb.builders[i]
builder.defaults()
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
mutation, ok := m.(*TagMutation)
if !ok {
return nil, fmt.Errorf("unexpected mutation type %T", m)
}
if err := builder.check(); err != nil {
return nil, err
}
builder.mutation = mutation
nodes[i], specs[i] = builder.createSpec()
var err error
if i < len(mutators)-1 {
_, err = mutators[i+1].Mutate(root, tcb.builders[i+1].mutation)
} else {
// Invoke the actual operation on the latest mutation in the chain.
if err = sqlgraph.BatchCreate(ctx, tcb.driver, &sqlgraph.BatchCreateSpec{Nodes: specs}); err != nil {
if cerr, ok := isSQLConstraintError(err); ok {
err = cerr
}
}
}
mutation.done = true
if err != nil {
return nil, err
}
if nodes[i].ID == 0 {
id := specs[i].ID.Value.(int64)
nodes[i].ID = int64(id)
}
return nodes[i], nil
})
for i := len(builder.hooks) - 1; i >= 0; i-- {
mut = builder.hooks[i](mut)
}
mutators[i] = mut
}(i, ctx)
}
if len(mutators) > 0 {
if _, err := mutators[0].Mutate(ctx, tcb.builders[0].mutation); err != nil {
return nil, err
}
}
return nodes, nil
}
// SaveX is like Save, but panics if an error occurs.
func (tcb *TagCreateBulk) SaveX(ctx context.Context) []*Tag {
v, err := tcb.Save(ctx)
if err != nil {
panic(err)
}
return v
}

@ -0,0 +1,108 @@
// Code generated by entc, DO NOT EDIT.
package ent
import (
"context"
"fmt"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
"github.com/go-kratos/examples/blog/internal/data/ent/predicate"
"github.com/go-kratos/examples/blog/internal/data/ent/tag"
)
// TagDelete is the builder for deleting a Tag entity.
type TagDelete struct {
config
hooks []Hook
mutation *TagMutation
}
// Where adds a new predicate to the TagDelete builder.
func (td *TagDelete) Where(ps ...predicate.Tag) *TagDelete {
td.mutation.predicates = append(td.mutation.predicates, ps...)
return td
}
// Exec executes the deletion query and returns how many vertices were deleted.
func (td *TagDelete) Exec(ctx context.Context) (int, error) {
var (
err error
affected int
)
if len(td.hooks) == 0 {
affected, err = td.sqlExec(ctx)
} else {
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
mutation, ok := m.(*TagMutation)
if !ok {
return nil, fmt.Errorf("unexpected mutation type %T", m)
}
td.mutation = mutation
affected, err = td.sqlExec(ctx)
mutation.done = true
return affected, err
})
for i := len(td.hooks) - 1; i >= 0; i-- {
mut = td.hooks[i](mut)
}
if _, err := mut.Mutate(ctx, td.mutation); err != nil {
return 0, err
}
}
return affected, err
}
// ExecX is like Exec, but panics if an error occurs.
func (td *TagDelete) ExecX(ctx context.Context) int {
n, err := td.Exec(ctx)
if err != nil {
panic(err)
}
return n
}
func (td *TagDelete) sqlExec(ctx context.Context) (int, error) {
_spec := &sqlgraph.DeleteSpec{
Node: &sqlgraph.NodeSpec{
Table: tag.Table,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: tag.FieldID,
},
},
}
if ps := td.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
return sqlgraph.DeleteNodes(ctx, td.driver, _spec)
}
// TagDeleteOne is the builder for deleting a single Tag entity.
type TagDeleteOne struct {
td *TagDelete
}
// Exec executes the deletion query.
func (tdo *TagDeleteOne) Exec(ctx context.Context) error {
n, err := tdo.td.Exec(ctx)
switch {
case err != nil:
return err
case n == 0:
return &NotFoundError{tag.Label}
default:
return nil
}
}
// ExecX is like Exec, but panics if an error occurs.
func (tdo *TagDeleteOne) ExecX(ctx context.Context) {
tdo.td.ExecX(ctx)
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,530 @@
// Code generated by entc, DO NOT EDIT.
package ent
import (
"context"
"fmt"
"time"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
"github.com/go-kratos/examples/blog/internal/data/ent/article"
"github.com/go-kratos/examples/blog/internal/data/ent/predicate"
"github.com/go-kratos/examples/blog/internal/data/ent/tag"
)
// TagUpdate is the builder for updating Tag entities.
type TagUpdate struct {
config
hooks []Hook
mutation *TagMutation
}
// Where adds a new predicate for the TagUpdate builder.
func (tu *TagUpdate) Where(ps ...predicate.Tag) *TagUpdate {
tu.mutation.predicates = append(tu.mutation.predicates, ps...)
return tu
}
// SetSlug sets the "slug" field.
func (tu *TagUpdate) SetSlug(s string) *TagUpdate {
tu.mutation.SetSlug(s)
return tu
}
// SetName sets the "name" field.
func (tu *TagUpdate) SetName(s string) *TagUpdate {
tu.mutation.SetName(s)
return tu
}
// SetCreatedAt sets the "created_at" field.
func (tu *TagUpdate) SetCreatedAt(t time.Time) *TagUpdate {
tu.mutation.SetCreatedAt(t)
return tu
}
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
func (tu *TagUpdate) SetNillableCreatedAt(t *time.Time) *TagUpdate {
if t != nil {
tu.SetCreatedAt(*t)
}
return tu
}
// SetUpdatedAt sets the "updated_at" field.
func (tu *TagUpdate) SetUpdatedAt(t time.Time) *TagUpdate {
tu.mutation.SetUpdatedAt(t)
return tu
}
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
func (tu *TagUpdate) SetNillableUpdatedAt(t *time.Time) *TagUpdate {
if t != nil {
tu.SetUpdatedAt(*t)
}
return tu
}
// AddPostIDs adds the "posts" edge to the Article entity by IDs.
func (tu *TagUpdate) AddPostIDs(ids ...int64) *TagUpdate {
tu.mutation.AddPostIDs(ids...)
return tu
}
// AddPosts adds the "posts" edges to the Article entity.
func (tu *TagUpdate) AddPosts(a ...*Article) *TagUpdate {
ids := make([]int64, len(a))
for i := range a {
ids[i] = a[i].ID
}
return tu.AddPostIDs(ids...)
}
// Mutation returns the TagMutation object of the builder.
func (tu *TagUpdate) Mutation() *TagMutation {
return tu.mutation
}
// ClearPosts clears all "posts" edges to the Article entity.
func (tu *TagUpdate) ClearPosts() *TagUpdate {
tu.mutation.ClearPosts()
return tu
}
// RemovePostIDs removes the "posts" edge to Article entities by IDs.
func (tu *TagUpdate) RemovePostIDs(ids ...int64) *TagUpdate {
tu.mutation.RemovePostIDs(ids...)
return tu
}
// RemovePosts removes "posts" edges to Article entities.
func (tu *TagUpdate) RemovePosts(a ...*Article) *TagUpdate {
ids := make([]int64, len(a))
for i := range a {
ids[i] = a[i].ID
}
return tu.RemovePostIDs(ids...)
}
// Save executes the query and returns the number of nodes affected by the update operation.
func (tu *TagUpdate) Save(ctx context.Context) (int, error) {
var (
err error
affected int
)
if len(tu.hooks) == 0 {
affected, err = tu.sqlSave(ctx)
} else {
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
mutation, ok := m.(*TagMutation)
if !ok {
return nil, fmt.Errorf("unexpected mutation type %T", m)
}
tu.mutation = mutation
affected, err = tu.sqlSave(ctx)
mutation.done = true
return affected, err
})
for i := len(tu.hooks) - 1; i >= 0; i-- {
mut = tu.hooks[i](mut)
}
if _, err := mut.Mutate(ctx, tu.mutation); err != nil {
return 0, err
}
}
return affected, err
}
// SaveX is like Save, but panics if an error occurs.
func (tu *TagUpdate) SaveX(ctx context.Context) int {
affected, err := tu.Save(ctx)
if err != nil {
panic(err)
}
return affected
}
// Exec executes the query.
func (tu *TagUpdate) Exec(ctx context.Context) error {
_, err := tu.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (tu *TagUpdate) ExecX(ctx context.Context) {
if err := tu.Exec(ctx); err != nil {
panic(err)
}
}
func (tu *TagUpdate) sqlSave(ctx context.Context) (n int, err error) {
_spec := &sqlgraph.UpdateSpec{
Node: &sqlgraph.NodeSpec{
Table: tag.Table,
Columns: tag.Columns,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: tag.FieldID,
},
},
}
if ps := tu.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
if value, ok := tu.mutation.Slug(); ok {
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: value,
Column: tag.FieldSlug,
})
}
if value, ok := tu.mutation.Name(); ok {
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: value,
Column: tag.FieldName,
})
}
if value, ok := tu.mutation.CreatedAt(); ok {
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
Type: field.TypeTime,
Value: value,
Column: tag.FieldCreatedAt,
})
}
if value, ok := tu.mutation.UpdatedAt(); ok {
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
Type: field.TypeTime,
Value: value,
Column: tag.FieldUpdatedAt,
})
}
if tu.mutation.PostsCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2M,
Inverse: false,
Table: tag.PostsTable,
Columns: tag.PostsPrimaryKey,
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: article.FieldID,
},
},
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := tu.mutation.RemovedPostsIDs(); len(nodes) > 0 && !tu.mutation.PostsCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2M,
Inverse: false,
Table: tag.PostsTable,
Columns: tag.PostsPrimaryKey,
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: article.FieldID,
},
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := tu.mutation.PostsIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2M,
Inverse: false,
Table: tag.PostsTable,
Columns: tag.PostsPrimaryKey,
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: article.FieldID,
},
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Add = append(_spec.Edges.Add, edge)
}
if n, err = sqlgraph.UpdateNodes(ctx, tu.driver, _spec); err != nil {
if _, ok := err.(*sqlgraph.NotFoundError); ok {
err = &NotFoundError{tag.Label}
} else if cerr, ok := isSQLConstraintError(err); ok {
err = cerr
}
return 0, err
}
return n, nil
}
// TagUpdateOne is the builder for updating a single Tag entity.
type TagUpdateOne struct {
config
hooks []Hook
mutation *TagMutation
}
// SetSlug sets the "slug" field.
func (tuo *TagUpdateOne) SetSlug(s string) *TagUpdateOne {
tuo.mutation.SetSlug(s)
return tuo
}
// SetName sets the "name" field.
func (tuo *TagUpdateOne) SetName(s string) *TagUpdateOne {
tuo.mutation.SetName(s)
return tuo
}
// SetCreatedAt sets the "created_at" field.
func (tuo *TagUpdateOne) SetCreatedAt(t time.Time) *TagUpdateOne {
tuo.mutation.SetCreatedAt(t)
return tuo
}
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
func (tuo *TagUpdateOne) SetNillableCreatedAt(t *time.Time) *TagUpdateOne {
if t != nil {
tuo.SetCreatedAt(*t)
}
return tuo
}
// SetUpdatedAt sets the "updated_at" field.
func (tuo *TagUpdateOne) SetUpdatedAt(t time.Time) *TagUpdateOne {
tuo.mutation.SetUpdatedAt(t)
return tuo
}
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
func (tuo *TagUpdateOne) SetNillableUpdatedAt(t *time.Time) *TagUpdateOne {
if t != nil {
tuo.SetUpdatedAt(*t)
}
return tuo
}
// AddPostIDs adds the "posts" edge to the Article entity by IDs.
func (tuo *TagUpdateOne) AddPostIDs(ids ...int64) *TagUpdateOne {
tuo.mutation.AddPostIDs(ids...)
return tuo
}
// AddPosts adds the "posts" edges to the Article entity.
func (tuo *TagUpdateOne) AddPosts(a ...*Article) *TagUpdateOne {
ids := make([]int64, len(a))
for i := range a {
ids[i] = a[i].ID
}
return tuo.AddPostIDs(ids...)
}
// Mutation returns the TagMutation object of the builder.
func (tuo *TagUpdateOne) Mutation() *TagMutation {
return tuo.mutation
}
// ClearPosts clears all "posts" edges to the Article entity.
func (tuo *TagUpdateOne) ClearPosts() *TagUpdateOne {
tuo.mutation.ClearPosts()
return tuo
}
// RemovePostIDs removes the "posts" edge to Article entities by IDs.
func (tuo *TagUpdateOne) RemovePostIDs(ids ...int64) *TagUpdateOne {
tuo.mutation.RemovePostIDs(ids...)
return tuo
}
// RemovePosts removes "posts" edges to Article entities.
func (tuo *TagUpdateOne) RemovePosts(a ...*Article) *TagUpdateOne {
ids := make([]int64, len(a))
for i := range a {
ids[i] = a[i].ID
}
return tuo.RemovePostIDs(ids...)
}
// Save executes the query and returns the updated Tag entity.
func (tuo *TagUpdateOne) Save(ctx context.Context) (*Tag, error) {
var (
err error
node *Tag
)
if len(tuo.hooks) == 0 {
node, err = tuo.sqlSave(ctx)
} else {
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
mutation, ok := m.(*TagMutation)
if !ok {
return nil, fmt.Errorf("unexpected mutation type %T", m)
}
tuo.mutation = mutation
node, err = tuo.sqlSave(ctx)
mutation.done = true
return node, err
})
for i := len(tuo.hooks) - 1; i >= 0; i-- {
mut = tuo.hooks[i](mut)
}
if _, err := mut.Mutate(ctx, tuo.mutation); err != nil {
return nil, err
}
}
return node, err
}
// SaveX is like Save, but panics if an error occurs.
func (tuo *TagUpdateOne) SaveX(ctx context.Context) *Tag {
node, err := tuo.Save(ctx)
if err != nil {
panic(err)
}
return node
}
// Exec executes the query on the entity.
func (tuo *TagUpdateOne) Exec(ctx context.Context) error {
_, err := tuo.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (tuo *TagUpdateOne) ExecX(ctx context.Context) {
if err := tuo.Exec(ctx); err != nil {
panic(err)
}
}
func (tuo *TagUpdateOne) sqlSave(ctx context.Context) (_node *Tag, err error) {
_spec := &sqlgraph.UpdateSpec{
Node: &sqlgraph.NodeSpec{
Table: tag.Table,
Columns: tag.Columns,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: tag.FieldID,
},
},
}
id, ok := tuo.mutation.ID()
if !ok {
return nil, &ValidationError{Name: "ID", err: fmt.Errorf("missing Tag.ID for update")}
}
_spec.Node.ID.Value = id
if ps := tuo.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
if value, ok := tuo.mutation.Slug(); ok {
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: value,
Column: tag.FieldSlug,
})
}
if value, ok := tuo.mutation.Name(); ok {
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: value,
Column: tag.FieldName,
})
}
if value, ok := tuo.mutation.CreatedAt(); ok {
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
Type: field.TypeTime,
Value: value,
Column: tag.FieldCreatedAt,
})
}
if value, ok := tuo.mutation.UpdatedAt(); ok {
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
Type: field.TypeTime,
Value: value,
Column: tag.FieldUpdatedAt,
})
}
if tuo.mutation.PostsCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2M,
Inverse: false,
Table: tag.PostsTable,
Columns: tag.PostsPrimaryKey,
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: article.FieldID,
},
},
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := tuo.mutation.RemovedPostsIDs(); len(nodes) > 0 && !tuo.mutation.PostsCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2M,
Inverse: false,
Table: tag.PostsTable,
Columns: tag.PostsPrimaryKey,
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: article.FieldID,
},
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := tuo.mutation.PostsIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2M,
Inverse: false,
Table: tag.PostsTable,
Columns: tag.PostsPrimaryKey,
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt64,
Column: article.FieldID,
},
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Add = append(_spec.Edges.Add, edge)
}
_node = &Tag{config: tuo.config}
_spec.Assign = _node.assignValues
_spec.ScanValues = _node.scanValues
if err = sqlgraph.UpdateNode(ctx, tuo.driver, _spec); err != nil {
if _, ok := err.(*sqlgraph.NotFoundError); ok {
err = &NotFoundError{tag.Label}
} else if cerr, ok := isSQLConstraintError(err); ok {
err = cerr
}
return nil, err
}
return _node, nil
}

@ -0,0 +1,216 @@
// Code generated by entc, DO NOT EDIT.
package ent
import (
"context"
"sync"
"entgo.io/ent/dialect"
)
// Tx is a transactional client that is created by calling Client.Tx().
type Tx struct {
config
// Article is the client for interacting with the Article builders.
Article *ArticleClient
// Comment is the client for interacting with the Comment builders.
Comment *CommentClient
// Tag is the client for interacting with the Tag builders.
Tag *TagClient
// lazily loaded.
client *Client
clientOnce sync.Once
// completion callbacks.
mu sync.Mutex
onCommit []CommitHook
onRollback []RollbackHook
// ctx lives for the life of the transaction. It is
// the same context used by the underlying connection.
ctx context.Context
}
type (
// Committer is the interface that wraps the Committer method.
Committer interface {
Commit(context.Context, *Tx) error
}
// The CommitFunc type is an adapter to allow the use of ordinary
// function as a Committer. If f is a function with the appropriate
// signature, CommitFunc(f) is a Committer that calls f.
CommitFunc func(context.Context, *Tx) error
// CommitHook defines the "commit middleware". A function that gets a Committer
// and returns a Committer. For example:
//
// hook := func(next ent.Committer) ent.Committer {
// return ent.CommitFunc(func(context.Context, tx *ent.Tx) error {
// // Do some stuff before.
// if err := next.Commit(ctx, tx); err != nil {
// return err
// }
// // Do some stuff after.
// return nil
// })
// }
//
CommitHook func(Committer) Committer
)
// Commit calls f(ctx, m).
func (f CommitFunc) Commit(ctx context.Context, tx *Tx) error {
return f(ctx, tx)
}
// Commit commits the transaction.
func (tx *Tx) Commit() error {
txDriver := tx.config.driver.(*txDriver)
var fn Committer = CommitFunc(func(context.Context, *Tx) error {
return txDriver.tx.Commit()
})
tx.mu.Lock()
hooks := append([]CommitHook(nil), tx.onCommit...)
tx.mu.Unlock()
for i := len(hooks) - 1; i >= 0; i-- {
fn = hooks[i](fn)
}
return fn.Commit(tx.ctx, tx)
}
// OnCommit adds a hook to call on commit.
func (tx *Tx) OnCommit(f CommitHook) {
tx.mu.Lock()
defer tx.mu.Unlock()
tx.onCommit = append(tx.onCommit, f)
}
type (
// Rollbacker is the interface that wraps the Rollbacker method.
Rollbacker interface {
Rollback(context.Context, *Tx) error
}
// The RollbackFunc type is an adapter to allow the use of ordinary
// function as a Rollbacker. If f is a function with the appropriate
// signature, RollbackFunc(f) is a Rollbacker that calls f.
RollbackFunc func(context.Context, *Tx) error
// RollbackHook defines the "rollback middleware". A function that gets a Rollbacker
// and returns a Rollbacker. For example:
//
// hook := func(next ent.Rollbacker) ent.Rollbacker {
// return ent.RollbackFunc(func(context.Context, tx *ent.Tx) error {
// // Do some stuff before.
// if err := next.Rollback(ctx, tx); err != nil {
// return err
// }
// // Do some stuff after.
// return nil
// })
// }
//
RollbackHook func(Rollbacker) Rollbacker
)
// Rollback calls f(ctx, m).
func (f RollbackFunc) Rollback(ctx context.Context, tx *Tx) error {
return f(ctx, tx)
}
// Rollback rollbacks the transaction.
func (tx *Tx) Rollback() error {
txDriver := tx.config.driver.(*txDriver)
var fn Rollbacker = RollbackFunc(func(context.Context, *Tx) error {
return txDriver.tx.Rollback()
})
tx.mu.Lock()
hooks := append([]RollbackHook(nil), tx.onRollback...)
tx.mu.Unlock()
for i := len(hooks) - 1; i >= 0; i-- {
fn = hooks[i](fn)
}
return fn.Rollback(tx.ctx, tx)
}
// OnRollback adds a hook to call on rollback.
func (tx *Tx) OnRollback(f RollbackHook) {
tx.mu.Lock()
defer tx.mu.Unlock()
tx.onRollback = append(tx.onRollback, f)
}
// Client returns a Client that binds to current transaction.
func (tx *Tx) Client() *Client {
tx.clientOnce.Do(func() {
tx.client = &Client{config: tx.config}
tx.client.init()
})
return tx.client
}
func (tx *Tx) init() {
tx.Article = NewArticleClient(tx.config)
tx.Comment = NewCommentClient(tx.config)
tx.Tag = NewTagClient(tx.config)
}
// txDriver wraps the given dialect.Tx with a nop dialect.Driver implementation.
// The idea is to support transactions without adding any extra code to the builders.
// When a builder calls to driver.Tx(), it gets the same dialect.Tx instance.
// Commit and Rollback are nop for the internal builders and the user must call one
// of them in order to commit or rollback the transaction.
//
// If a closed transaction is embedded in one of the generated entities, and the entity
// applies a query, for example: Article.QueryXXX(), the query will be executed
// through the driver which created this transaction.
//
// Note that txDriver is not goroutine safe.
type txDriver struct {
// the driver we started the transaction from.
drv dialect.Driver
// tx is the underlying transaction.
tx dialect.Tx
}
// newTx creates a new transactional driver.
func newTx(ctx context.Context, drv dialect.Driver) (*txDriver, error) {
tx, err := drv.Tx(ctx)
if err != nil {
return nil, err
}
return &txDriver{tx: tx, drv: drv}, nil
}
// Tx returns the transaction wrapper (txDriver) to avoid Commit or Rollback calls
// from the internal builders. Should be called only by the internal builders.
func (tx *txDriver) Tx(context.Context) (dialect.Tx, error) { return tx, nil }
// Dialect returns the dialect of the driver we started the transaction from.
func (tx *txDriver) Dialect() string { return tx.drv.Dialect() }
// Close is a nop close.
func (*txDriver) Close() error { return nil }
// Commit is a nop commit for the internal builders.
// User must call `Tx.Commit` in order to commit the transaction.
func (*txDriver) Commit() error { return nil }
// Rollback is a nop rollback for the internal builders.
// User must call `Tx.Rollback` in order to rollback the transaction.
func (*txDriver) Rollback() error { return nil }
// Exec calls tx.Exec.
func (tx *txDriver) Exec(ctx context.Context, query string, args, v interface{}) error {
return tx.tx.Exec(ctx, query, args, v)
}
// Query calls tx.Query.
func (tx *txDriver) Query(ctx context.Context, query string, args, v interface{}) error {
return tx.tx.Query(ctx, query, args, v)
}
var _ dialect.Driver = (*txDriver)(nil)

@ -0,0 +1,25 @@
package data
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
func likeKey(id int64) string {
return fmt.Sprintf("like:%d", id)
}
func (ar *articleRepo) GetArticleLike(ctx context.Context, id int64) (rv int64, err error) {
get := ar.data.rdb.Get(ctx, likeKey(id))
rv, err = get.Int64()
if err == redis.Nil {
return 0, nil
}
return
}
func (ar *articleRepo) IncArticleLike(ctx context.Context, id int64) error {
_, err := ar.data.rdb.Incr(ctx, likeKey(id)).Result()
return err
}

@ -0,0 +1,39 @@
package server
import (
v1 "github.com/go-kratos/examples/blog/api/blog/v1"
"github.com/go-kratos/examples/blog/internal/conf"
"github.com/go-kratos/examples/blog/internal/service"
"github.com/go-kratos/kratos/v2/middleware"
"github.com/go-kratos/kratos/v2/middleware/logging"
"github.com/go-kratos/kratos/v2/middleware/recovery"
"github.com/go-kratos/kratos/v2/middleware/status"
"github.com/go-kratos/kratos/v2/middleware/tracing"
"github.com/go-kratos/kratos/v2/transport/grpc"
)
// NewGRPCServer new a gRPC server.
func NewGRPCServer(c *conf.Server, blog *service.BlogService) *grpc.Server {
var opts = []grpc.ServerOption{
grpc.Middleware(
middleware.Chain(
recovery.Recovery(),
status.Server(),
tracing.Server(),
logging.Server(),
),
),
}
if c.Grpc.Network != "" {
opts = append(opts, grpc.Network(c.Grpc.Network))
}
if c.Grpc.Addr != "" {
opts = append(opts, grpc.Address(c.Grpc.Addr))
}
if c.Grpc.Timeout != nil {
opts = append(opts, grpc.Timeout(c.Grpc.Timeout.AsDuration()))
}
srv := grpc.NewServer(opts...)
v1.RegisterBlogServiceServer(srv, blog)
return srv
}

@ -0,0 +1,36 @@
package server
import (
v1 "github.com/go-kratos/examples/blog/api/blog/v1"
"github.com/go-kratos/examples/blog/internal/conf"
"github.com/go-kratos/examples/blog/internal/service"
"github.com/go-kratos/kratos/v2/middleware"
"github.com/go-kratos/kratos/v2/middleware/logging"
"github.com/go-kratos/kratos/v2/middleware/recovery"
"github.com/go-kratos/kratos/v2/middleware/tracing"
"github.com/go-kratos/kratos/v2/transport/http"
)
// NewHTTPServer new a HTTP server.
func NewHTTPServer(c *conf.Server, blog *service.BlogService) *http.Server {
var opts = []http.ServerOption{}
if c.Http.Network != "" {
opts = append(opts, http.Network(c.Http.Network))
}
if c.Http.Addr != "" {
opts = append(opts, http.Address(c.Http.Addr))
}
if c.Http.Timeout != nil {
opts = append(opts, http.Timeout(c.Http.Timeout.AsDuration()))
}
m := http.Middleware(
middleware.Chain(
recovery.Recovery(),
tracing.Server(),
logging.Server(),
),
)
srv := http.NewServer(opts...)
srv.HandlePrefix("/", v1.NewBlogServiceHandler(blog, m))
return srv
}

@ -0,0 +1,8 @@
package server
import (
"github.com/google/wire"
)
// ProviderSet is server providers.
var ProviderSet = wire.NewSet(NewHTTPServer, NewGRPCServer)

@ -0,0 +1,66 @@
package service
import (
"context"
"go.opentelemetry.io/otel"
pb "github.com/go-kratos/examples/blog/api/blog/v1"
"github.com/go-kratos/examples/blog/internal/biz"
"github.com/go-kratos/kratos/v2/log"
)
func NewBlogService(article *biz.ArticleUsecase, logger log.Logger) *BlogService {
return &BlogService{
article: article,
log: log.NewHelper("article", logger),
}
}
func (s *BlogService) CreateArticle(ctx context.Context, req *pb.CreateArticleRequest) (*pb.CreateArticleReply, error) {
s.log.Infof("input data %v", req)
err := s.article.Create(ctx, &biz.Article{
Title: req.Title,
Content: req.Content,
})
return &pb.CreateArticleReply{}, err
}
func (s *BlogService) UpdateArticle(ctx context.Context, req *pb.UpdateArticleRequest) (*pb.UpdateArticleReply, error) {
s.log.Infof("input data %v", req)
err := s.article.Update(ctx, req.Id, &biz.Article{
Title: req.Title,
Content: req.Content,
})
return &pb.UpdateArticleReply{}, err
}
func (s *BlogService) DeleteArticle(ctx context.Context, req *pb.DeleteArticleRequest) (*pb.DeleteArticleReply, error) {
s.log.Infof("input data %v", req)
err := s.article.Delete(ctx, req.Id)
return &pb.DeleteArticleReply{}, err
}
func (s *BlogService) GetArticle(ctx context.Context, req *pb.GetArticleRequest) (*pb.GetArticleReply, error) {
tr := otel.Tracer("api")
_, span := tr.Start(ctx, "GetArticle")
defer span.End()
p, err := s.article.Get(ctx, req.Id)
if err != nil {
return nil, err
}
return &pb.GetArticleReply{Article: &pb.Article{Id: p.Id, Title: p.Title, Content: p.Content, Like: p.Like}}, nil
}
func (s *BlogService) ListArticle(ctx context.Context, req *pb.ListArticleRequest) (*pb.ListArticleReply, error) {
ps, err := s.article.List(ctx)
reply := &pb.ListArticleReply{}
for _, p := range ps {
reply.Results = append(reply.Results, &pb.Article{
Id: p.Id,
Title: p.Title,
Content: p.Content,
})
}
return reply, err
}

@ -0,0 +1,20 @@
package service
import (
pb "github.com/go-kratos/examples/blog/api/blog/v1"
"github.com/go-kratos/examples/blog/internal/biz"
"github.com/go-kratos/kratos/v2/log"
"github.com/google/wire"
)
// ProviderSet is service providers.
var ProviderSet = wire.NewSet(NewBlogService)
type BlogService struct {
pb.UnimplementedBlogServiceServer
log *log.Helper
article *biz.ArticleUsecase
}

@ -0,0 +1,79 @@
package tracing
import (
"context"
"github.com/go-kratos/kratos/v2/middleware"
"github.com/go-kratos/kratos/v2/transport/grpc"
"github.com/go-kratos/kratos/v2/transport/http"
"github.com/opentracing/opentracing-go"
"github.com/opentracing/opentracing-go/ext"
"github.com/opentracing/opentracing-go/log"
"google.golang.org/grpc/metadata"
)
// Option is tracing option.
type Option func(*options)
type options struct {
tracer opentracing.Tracer
}
// WithTracer sets a custom tracer to be used for this middleware, otherwise the opentracing.GlobalTracer is used.
func WithTracer(tracer opentracing.Tracer) Option {
return func(o *options) {
o.tracer = tracer
}
}
// Server returns a new server middleware for OpenTracing.
func Server(opts ...Option) middleware.Middleware {
options := options{
tracer: opentracing.GlobalTracer(),
}
for _, o := range opts {
o(&options)
}
return func(handler middleware.Handler) middleware.Handler {
return func(ctx context.Context, req interface{}) (reply interface{}, err error) {
var (
component string
operation string
spanContext opentracing.SpanContext
)
if info, ok := http.FromServerContext(ctx); ok {
// HTTP span
component = "HTTP"
operation = info.Request.RequestURI
spanContext, _ = options.tracer.Extract(
opentracing.HTTPHeaders,
opentracing.HTTPHeadersCarrier(info.Request.Header),
)
} else if info, ok := grpc.FromServerContext(ctx); ok {
// gRPC span
component = "gRPC"
operation = info.FullMethod
if md, ok := metadata.FromIncomingContext(ctx); ok {
spanContext, _ = options.tracer.Extract(
opentracing.HTTPHeaders,
opentracing.HTTPHeadersCarrier(md),
)
}
}
span := options.tracer.StartSpan(
operation,
ext.RPCServerOption(spanContext),
opentracing.Tag{Key: string(ext.Component), Value: component},
)
defer span.Finish()
if reply, err = handler(ctx, req); err != nil {
ext.Error.Set(span, true)
span.LogFields(
log.String("event", "error"),
log.String("message", err.Error()),
)
}
return
}
}
}

@ -0,0 +1,11 @@
service:
name: config
version: v1.0.0
http:
server:
address: 0.0.0.0:8000
timeout: 1s
grpc:
server:
address: 0.0.0.0:9000
timeout: 1s

@ -0,0 +1,57 @@
package main
import (
"flag"
"log"
"github.com/go-kratos/kratos/v2/config"
"github.com/go-kratos/kratos/v2/config/file"
"gopkg.in/yaml.v2"
)
var flagconf string
func init() {
flag.StringVar(&flagconf, "conf", "config.yaml", "config path, eg: -conf config.yaml")
}
func main() {
flag.Parse()
c := config.New(
config.WithSource(
file.NewSource(flagconf),
),
config.WithDecoder(func(kv *config.KeyValue, v map[string]interface{}) error {
return yaml.Unmarshal(kv.Value, v)
}),
)
if err := c.Load(); err != nil {
panic(err)
}
// struct
var v struct {
Serivce struct {
Name string `json:"name"`
Version string `json:"version"`
} `json:"service"`
}
if err := c.Scan(&v); err != nil {
panic(err)
}
log.Printf("config: %+v", v)
// key/value
name, err := c.Value("service.name").String()
if err != nil {
panic(err)
}
log.Printf("service: %s", name)
// watch key
if err := c.Watch("service.name", func(key string, value config.Value) {
log.Printf("config changed: %s = %v\n", key, value)
}); err != nil {
panic(err)
}
<-make(chan struct{})
}

@ -0,0 +1,28 @@
package main
import (
"log"
"github.com/gin-gonic/gin"
"github.com/go-kratos/kratos/v2"
transhttp "github.com/go-kratos/kratos/v2/transport/http"
)
func main() {
router := gin.Default()
router.GET("/home", func(ctx *gin.Context) {
ctx.String(200, "Hello Gin!")
})
httpSrv := transhttp.NewServer(transhttp.Address(":8000"))
httpSrv.HandlePrefix("/", router)
app := kratos.New(
kratos.Name("gin"),
kratos.Server(
httpSrv,
),
)
if err := app.Run(); err != nil {
log.Println(err)
}
}

@ -0,0 +1,33 @@
module github.com/go-kratos/examples
go 1.15
require (
entgo.io/ent v0.6.0
github.com/gin-gonic/gin v1.6.3
github.com/go-kratos/kratos/v2 v2.0.0-alpha4
github.com/go-redis/redis/extra/redisotel v0.2.0
github.com/go-redis/redis/v8 v8.6.0
github.com/go-sql-driver/mysql v1.5.1-0.20200311113236-681ffa848bae
github.com/golang/protobuf v1.4.3
github.com/google/wire v0.5.0
github.com/gorilla/mux v1.8.0
github.com/grpc-ecosystem/grpc-gateway v1.16.0
github.com/imdario/mergo v0.3.11 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/opentracing/opentracing-go v1.2.0
go.opentelemetry.io/otel v0.17.0
go.opentelemetry.io/otel/exporters/trace/jaeger v0.17.0
go.opentelemetry.io/otel/sdk v0.17.0
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46 // indirect
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705
google.golang.org/grpc v1.36.0
google.golang.org/protobuf v1.25.0
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
gopkg.in/yaml.v2 v2.4.0
)
replace github.com/go-kratos/kratos/v2 => ./..

@ -0,0 +1,715 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
entgo.io/ent v0.6.0 h1:oo/a8sXPQKzHYFlVwmwOnyzBy+u8FWQsoLLqFCrOBt0=
entgo.io/ent v0.6.0/go.mod h1:+Y513RSj+qleCpyeCmF8leXqAAhCYDJfpzGPIAFPBxc=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/apache/thrift v0.13.0 h1:5hryIiq9gtn+MiLVn0wP37kb/uTeRZgN08WoCsAhIhI=
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
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/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
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=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
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.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/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/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
github.com/go-bindata/go-bindata v1.0.1-0.20190711162640-ee3c2418e368/go.mod h1:7xCgX1lzlrXPHkfvn3EhumqHkmSlzt8at9q7v0ax19c=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4=
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY=
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
github.com/go-redis/redis/extra/rediscmd v0.2.0 h1:A3bhCsCKsedClEH9/jYlcKqOuBoeeV+H0yDie5t+a6w=
github.com/go-redis/redis/extra/rediscmd v0.2.0/go.mod h1:Z5bP1EHl9PvWhx/DupfCdZwB0JgOO3aVxWc/PFux+BE=
github.com/go-redis/redis/extra/redisotel v0.2.0 h1:BET5CrjdCZvLUVd9Hnm+q0ywqnbC2iRq6Pq2DKnCzfM=
github.com/go-redis/redis/extra/redisotel v0.2.0/go.mod h1:b5A+vQ2dnKk9BqsAgiOyoumTCl9SV4XOrbfzNIkJuC0=
github.com/go-redis/redis/v8 v8.3.2/go.mod h1:jszGxBCez8QA1HWSmQxJO9Y82kNibbUmeYhKWrBejTU=
github.com/go-redis/redis/v8 v8.4.0/go.mod h1:A1tbYoHSa1fXwN+//ljcCYYJeLmVrwL9hbQN45Jdy0M=
github.com/go-redis/redis/v8 v8.6.0 h1:swqbqOrxaPztsj2Hf1p94M3YAgl7hYEpcw21z299hh8=
github.com/go-redis/redis/v8 v8.6.0/go.mod h1:DQ9q4Rk2HtwkrwVrdgmphoOQDMfpvcd/nHEwRsicg8s=
github.com/go-sql-driver/mysql v1.5.1-0.20200311113236-681ffa848bae h1:L6V0ANsMIMdLgXly241UXhXNFWYgXbgjHupTAAURrV0=
github.com/go-sql-driver/mysql v1.5.1-0.20200311113236-681ffa848bae/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
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.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
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/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.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
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/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/subcommands v1.0.1 h1:/eqq+otEXm5vhfBrbREPCSVQbvofip6kIz+mX5TUH7k=
github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/wire v0.5.0 h1:I7ELFeVBr3yfPIcc8+MWvrjk+3VjbcSzoXm3JVa+jD8=
github.com/google/wire v0.5.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
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/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
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.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
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/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/ginkgo v1.15.0 h1:1V1NfVQR87RtWAgp1lv9JZJ5Jap+XFGKPi00andXGi4=
github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
github.com/onsi/gomega v1.10.5 h1:7n6FEkpFmfCoo2t+YYqXH0evK+a9ICQz0xcAy9dYcaQ=
github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48=
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/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/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
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/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.opencensus.io v0.22.6/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
go.opentelemetry.io/otel v0.13.0/go.mod h1:dlSNewoRYikTkotEnxdmuBHgzT+k/idJSfDv/FxEnOY=
go.opentelemetry.io/otel v0.14.0/go.mod h1:vH5xEuwy7Rts0GNtsCW3HYQoZDY+OmBJ6t1bFGGlxgw=
go.opentelemetry.io/otel v0.17.0 h1:6MKOu8WY4hmfpQ4oQn34u6rYhnf2sWf1LXYO/UFm71U=
go.opentelemetry.io/otel v0.17.0/go.mod h1:Oqtdxmf7UtEvL037ohlgnaYa1h7GtMh0NcSd9eqkC9s=
go.opentelemetry.io/otel/exporters/trace/jaeger v0.17.0 h1:9Nivnf6Oqkm6P8o7LGJfQNjqP45O2FgDAQgLncy1pPM=
go.opentelemetry.io/otel/exporters/trace/jaeger v0.17.0/go.mod h1:PCzsDDOeNfZNiKfWMgL8jK3qodD147xu6n/DYvFFNdw=
go.opentelemetry.io/otel/metric v0.17.0 h1:t+5EioN8YFXQ2EH+1j6FHCKMUj+57zIDSnSGr/mWuug=
go.opentelemetry.io/otel/metric v0.17.0/go.mod h1:hUz9lH1rNXyEwWAhIWCMFWKhYtpASgSnObJFnU26dJ0=
go.opentelemetry.io/otel/oteltest v0.17.0 h1:TyAihUowTDLqb4+m5ePAsR71xPJaTBJl4KDArIdi9k4=
go.opentelemetry.io/otel/oteltest v0.17.0/go.mod h1:JT/LGFxPwpN+nlsTiinSYjdIx3hZIGqHCpChcIZmdoE=
go.opentelemetry.io/otel/sdk v0.17.0 h1:eHXQwanmbtSHM/GcJYbJ8FyyH/sT9a0e+1Z9ZWkF7Ug=
go.opentelemetry.io/otel/sdk v0.17.0/go.mod h1:INs1PePjjF2hf842AXsxGTe5lH023QfLTZRFPiV/RUk=
go.opentelemetry.io/otel/trace v0.17.0 h1:SBOj64/GAOyWzs5F680yW1ITIfJkm6cJWL2YAvuL9xY=
go.opentelemetry.io/otel/trace v0.17.0/go.mod h1:bIujpqg6ZL6xUTubIUgziI1jSaUPthmabA/ygf/6Cfg=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/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-20190605123033-f99c8df09eb5/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/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
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-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
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-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0 h1:8pl+sMODzuvGJkmj2W4kZihvVb5mKm8pB/X44PIQHv8=
golang.org/x/mod v0.4.0/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-20181023162649-9b4f9f5ad519/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-20181201002055-351d144fa1fc/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-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/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-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
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-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/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 h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
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-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/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-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/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-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46 h1:V066+OYJ66oTjnhm4Yrn7SXIwSCiDQJxpBxmvqb1N1c=
golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
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.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
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/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-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/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-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210105164027-a548c3f4af2d h1:v9TQ4+tS+0r4R+9E6svkcl6ocSxeHONeVkK2y6YhzmA=
golang.org/x/tools v0.0.0-20210105164027-a548c3f4af2d/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
google.golang.org/api v0.39.0 h1:zHCTXf0NeDdKTgcSQpT+ZflWAqHsEp1GmdpxW09f3YM=
google.golang.org/api v0.39.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
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/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210114201628-6edceaf6022f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705 h1:PYBmACG+YEv8uQPW0r1kJj8tR+gkF0UWq7iFdUezwEw=
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
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.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.36.0 h1:o1bcQ6imQMIOpdrO3SWf2z5RV72WbDwdXuK0MDlc8As=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
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/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/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/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-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
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.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 h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/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-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/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/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=

@ -0,0 +1,77 @@
package main
import (
"context"
"log"
"net/http"
pb "github.com/go-kratos/examples/helloworld/helloworld"
"github.com/go-kratos/kratos/v2/errors"
"github.com/go-kratos/kratos/v2/middleware"
"github.com/go-kratos/kratos/v2/middleware/recovery"
"github.com/go-kratos/kratos/v2/middleware/status"
transgrpc "github.com/go-kratos/kratos/v2/transport/grpc"
transhttp "github.com/go-kratos/kratos/v2/transport/http"
)
func main() {
callHTTP()
callGRPC()
}
func callHTTP() {
client, err := transhttp.NewClient(context.Background())
if err != nil {
log.Fatal(err)
}
req, err := http.NewRequest("GET", "http://127.0.0.1:8000/helloworld/kratos", nil)
if err != nil {
log.Fatal(err)
}
reply := new(pb.HelloReply)
if err := transhttp.Do(client, req, reply); err != nil {
log.Fatal(err)
}
log.Printf("[http] SayHello %s\n", reply.Message)
// returns error
req, err = http.NewRequest("GET", "http://127.0.0.1:8000/helloworld/error", nil)
if err != nil {
log.Fatal(err)
}
if err := transhttp.Do(client, req, reply); err != nil {
log.Printf("[http] SayHello error is invalid argument: %v\n", err)
}
}
func callGRPC() {
conn, err := transgrpc.DialInsecure(
context.Background(),
transgrpc.WithEndpoint("127.0.0.1:9000"),
transgrpc.WithMiddleware(
middleware.Chain(
status.Client(),
recovery.Recovery(),
),
),
)
if err != nil {
log.Fatal(err)
}
client := pb.NewGreeterClient(conn)
reply, err := client.SayHello(context.Background(), &pb.HelloRequest{Name: "kratos"})
if err != nil {
log.Fatal(err)
}
log.Printf("[grpc] SayHello %+v\n", reply)
// returns error
_, err = client.SayHello(context.Background(), &pb.HelloRequest{Name: "error"})
if err != nil {
log.Printf("[grpc] SayHello error: %v\n", err)
}
if errors.IsInvalidArgument(err) {
log.Printf("[grpc] SayHello error is invalid argument: %v\n", err)
}
}

@ -0,0 +1,226 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.13.0
// source: helloworld.proto
package helloworld
import (
proto "github.com/golang/protobuf/proto"
_ "google.golang.org/genproto/googleapis/api/annotations"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4
// The request message containing the user's name.
type HelloRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
}
func (x *HelloRequest) Reset() {
*x = HelloRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_helloworld_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *HelloRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*HelloRequest) ProtoMessage() {}
func (x *HelloRequest) ProtoReflect() protoreflect.Message {
mi := &file_helloworld_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use HelloRequest.ProtoReflect.Descriptor instead.
func (*HelloRequest) Descriptor() ([]byte, []int) {
return file_helloworld_proto_rawDescGZIP(), []int{0}
}
func (x *HelloRequest) GetName() string {
if x != nil {
return x.Name
}
return ""
}
// The response message containing the greetings
type HelloReply struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
}
func (x *HelloReply) Reset() {
*x = HelloReply{}
if protoimpl.UnsafeEnabled {
mi := &file_helloworld_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *HelloReply) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*HelloReply) ProtoMessage() {}
func (x *HelloReply) ProtoReflect() protoreflect.Message {
mi := &file_helloworld_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use HelloReply.ProtoReflect.Descriptor instead.
func (*HelloReply) Descriptor() ([]byte, []int) {
return file_helloworld_proto_rawDescGZIP(), []int{1}
}
func (x *HelloReply) GetMessage() string {
if x != nil {
return x.Message
}
return ""
}
var File_helloworld_proto protoreflect.FileDescriptor
var file_helloworld_proto_rawDesc = []byte{
0x0a, 0x10, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x12, 0x0a, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x1a, 0x1c,
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x22, 0x0a, 0x0c,
0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04,
0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
0x22, 0x26, 0x0a, 0x0a, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x18,
0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0x63, 0x0a, 0x07, 0x47, 0x72, 0x65, 0x65,
0x74, 0x65, 0x72, 0x12, 0x58, 0x0a, 0x08, 0x53, 0x61, 0x79, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x12,
0x18, 0x2e, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x48, 0x65, 0x6c,
0x6c, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x68, 0x65, 0x6c, 0x6c,
0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c,
0x79, 0x22, 0x1a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x12, 0x12, 0x2f, 0x68, 0x65, 0x6c, 0x6c,
0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x42, 0x3c, 0x5a,
0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, 0x6b,
0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x65, 0x78, 0x61,
0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64,
0x2f, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x33,
}
var (
file_helloworld_proto_rawDescOnce sync.Once
file_helloworld_proto_rawDescData = file_helloworld_proto_rawDesc
)
func file_helloworld_proto_rawDescGZIP() []byte {
file_helloworld_proto_rawDescOnce.Do(func() {
file_helloworld_proto_rawDescData = protoimpl.X.CompressGZIP(file_helloworld_proto_rawDescData)
})
return file_helloworld_proto_rawDescData
}
var file_helloworld_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_helloworld_proto_goTypes = []interface{}{
(*HelloRequest)(nil), // 0: helloworld.HelloRequest
(*HelloReply)(nil), // 1: helloworld.HelloReply
}
var file_helloworld_proto_depIdxs = []int32{
0, // 0: helloworld.Greeter.SayHello:input_type -> helloworld.HelloRequest
1, // 1: helloworld.Greeter.SayHello:output_type -> helloworld.HelloReply
1, // [1:2] is the sub-list for method output_type
0, // [0:1] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_helloworld_proto_init() }
func file_helloworld_proto_init() {
if File_helloworld_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_helloworld_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*HelloRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_helloworld_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*HelloReply); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_helloworld_proto_rawDesc,
NumEnums: 0,
NumMessages: 2,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_helloworld_proto_goTypes,
DependencyIndexes: file_helloworld_proto_depIdxs,
MessageInfos: file_helloworld_proto_msgTypes,
}.Build()
File_helloworld_proto = out.File
file_helloworld_proto_rawDesc = nil
file_helloworld_proto_goTypes = nil
file_helloworld_proto_depIdxs = nil
}

@ -0,0 +1,27 @@
syntax = "proto3";
package helloworld;
import "google/api/annotations.proto";
option go_package = "github.com/go-kratos/kratos/examples/helloworld/helloworld";
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {
option (google.api.http) = {
get: "/helloworld/{name}",
};
}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}

@ -0,0 +1,103 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
package helloworld
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
// GreeterClient is the client API for Greeter service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type GreeterClient interface {
// Sends a greeting
SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error)
}
type greeterClient struct {
cc grpc.ClientConnInterface
}
func NewGreeterClient(cc grpc.ClientConnInterface) GreeterClient {
return &greeterClient{cc}
}
func (c *greeterClient) SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) {
out := new(HelloReply)
err := c.cc.Invoke(ctx, "/helloworld.Greeter/SayHello", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// GreeterServer is the server API for Greeter service.
// All implementations must embed UnimplementedGreeterServer
// for forward compatibility
type GreeterServer interface {
// Sends a greeting
SayHello(context.Context, *HelloRequest) (*HelloReply, error)
mustEmbedUnimplementedGreeterServer()
}
// UnimplementedGreeterServer must be embedded to have forward compatible implementations.
type UnimplementedGreeterServer struct {
}
func (UnimplementedGreeterServer) SayHello(context.Context, *HelloRequest) (*HelloReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method SayHello not implemented")
}
func (UnimplementedGreeterServer) mustEmbedUnimplementedGreeterServer() {}
// UnsafeGreeterServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to GreeterServer will
// result in compilation errors.
type UnsafeGreeterServer interface {
mustEmbedUnimplementedGreeterServer()
}
func RegisterGreeterServer(s grpc.ServiceRegistrar, srv GreeterServer) {
s.RegisterService(&Greeter_ServiceDesc, srv)
}
func _Greeter_SayHello_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(HelloRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(GreeterServer).SayHello(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/helloworld.Greeter/SayHello",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(GreeterServer).SayHello(ctx, req.(*HelloRequest))
}
return interceptor(ctx, in, info, handler)
}
// Greeter_ServiceDesc is the grpc.ServiceDesc for Greeter service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var Greeter_ServiceDesc = grpc.ServiceDesc{
ServiceName: "helloworld.Greeter",
HandlerType: (*GreeterServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "SayHello",
Handler: _Greeter_SayHello_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "helloworld.proto",
}

@ -0,0 +1,62 @@
// Code generated by protoc-gen-go-http. DO NOT EDIT.
package helloworld
import (
context "context"
http1 "github.com/go-kratos/kratos/v2/transport/http"
binding "github.com/go-kratos/kratos/v2/transport/http/binding"
mux "github.com/gorilla/mux"
http "net/http"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the kratos package it is being compiled against.
var _ = new(http.Request)
var _ = new(context.Context)
var _ = binding.MapProto
var _ = mux.NewRouter
const _ = http1.SupportPackageIsVersion1
type GreeterHandler interface {
SayHello(context.Context, *HelloRequest) (*HelloReply, error)
}
func NewGreeterHandler(srv GreeterHandler, opts ...http1.HandleOption) http.Handler {
h := http1.DefaultHandleOptions()
for _, o := range opts {
o(&h)
}
r := mux.NewRouter()
r.HandleFunc("/helloworld/{name}", func(w http.ResponseWriter, r *http.Request) {
var in HelloRequest
if err := binding.MapProto(&in, mux.Vars(r)); err != nil {
h.Error(w, r, err)
return
}
if err := h.Decode(r, &in); err != nil {
h.Error(w, r, err)
return
}
next := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.SayHello(ctx, req.(*HelloRequest))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
out, err := next(r.Context(), &in)
if err != nil {
h.Error(w, r, err)
return
}
if err := h.Encode(w, r, out); err != nil {
h.Error(w, r, err)
}
}).Methods("GET")
return r
}

@ -0,0 +1,75 @@
package main
import (
"context"
"fmt"
"os"
pb "github.com/go-kratos/examples/helloworld/helloworld"
"github.com/go-kratos/kratos/v2"
"github.com/go-kratos/kratos/v2/errors"
"github.com/go-kratos/kratos/v2/log"
"github.com/go-kratos/kratos/v2/middleware"
"github.com/go-kratos/kratos/v2/middleware/logging"
"github.com/go-kratos/kratos/v2/middleware/recovery"
"github.com/go-kratos/kratos/v2/middleware/status"
"github.com/go-kratos/kratos/v2/transport/grpc"
"github.com/go-kratos/kratos/v2/transport/http"
)
// server is used to implement helloworld.GreeterServer.
type server struct {
pb.UnimplementedGreeterServer
}
// SayHello implements helloworld.GreeterServer
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
if in.Name == "error" {
return nil, errors.InvalidArgument("BadRequest", "invalid argument %s", in.Name)
}
if in.Name == "panic" {
panic("grpc panic")
}
return &pb.HelloReply{Message: fmt.Sprintf("Hello %+v", in.Name)}, nil
}
func main() {
logger := log.NewStdLogger(os.Stdout)
log := log.NewHelper("main", logger)
grpcSrv := grpc.NewServer(
grpc.Address(":9000"),
grpc.Middleware(
middleware.Chain(
logging.Server(logging.WithLogger(logger)),
status.Server(),
recovery.Recovery(),
),
))
s := &server{}
pb.RegisterGreeterServer(grpcSrv, s)
httpSrv := http.NewServer(http.Address(":8000"))
httpSrv.HandlePrefix("/", pb.NewGreeterHandler(s,
http.Middleware(
middleware.Chain(
logging.Server(logging.WithLogger(logger)),
recovery.Recovery(),
),
)),
)
app := kratos.New(
kratos.Name("helloworld"),
kratos.Server(
httpSrv,
grpcSrv,
),
)
if err := app.Run(); err != nil {
log.Error(err)
}
}

@ -0,0 +1,30 @@
package main
import (
"fmt"
"log"
"net/http"
"github.com/go-kratos/kratos/v2"
transhttp "github.com/go-kratos/kratos/v2/transport/http"
"github.com/gorilla/mux"
)
func main() {
router := mux.NewRouter()
router.HandleFunc("/home", func(w http.ResponseWriter, req *http.Request) {
fmt.Fprint(w, "Hello Gorilla Mux!")
}).Methods("GET")
httpSrv := transhttp.NewServer(transhttp.Address(":8000"))
httpSrv.HandlePrefix("/", router)
app := kratos.New(
kratos.Name("gin"),
kratos.Server(
httpSrv,
),
)
if err := app.Run(); err != nil {
log.Println(err)
}
}
Loading…
Cancel
Save