init
This commit is contained in:
commit
3bffcfa0d3
|
@ -0,0 +1,4 @@
|
|||
.env.development
|
||||
.env.production
|
||||
.env
|
||||
.netrc
|
|
@ -0,0 +1,19 @@
|
|||
FROM golang:alpine
|
||||
RUN apk add git
|
||||
|
||||
ENV MODE=production
|
||||
ENV GIN_MODE=release
|
||||
ENV GOPRIVATE=github.com/tribalwarshelp
|
||||
|
||||
COPY ./.netrc /root/.netrc
|
||||
RUN chmod 600 /root/.netrc
|
||||
|
||||
WORKDIR /go/src/app
|
||||
COPY . .
|
||||
|
||||
RUN go build -o main .
|
||||
|
||||
ADD https://github.com/ufoscout/docker-compose-wait/releases/download/2.2.1/wait ./wait
|
||||
RUN chmod +x ./wait
|
||||
|
||||
CMD ./wait && ./main
|
|
@ -0,0 +1,20 @@
|
|||
module github.com/tribalwarshelp/api
|
||||
|
||||
go 1.14
|
||||
|
||||
require (
|
||||
github.com/99designs/gqlgen v0.11.3
|
||||
github.com/gin-gonic/gin v1.6.3
|
||||
github.com/go-pg/pg/v10 v10.0.0-beta.1
|
||||
github.com/go-playground/validator/v10 v10.3.0 // indirect
|
||||
github.com/joho/godotenv v1.3.0
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.1 // indirect
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/segmentio/encoding v0.1.13 // indirect
|
||||
github.com/tribalwarshelp/shared v0.0.0-20200602122915-bb9a531672b6
|
||||
github.com/vektah/gqlparser/v2 v2.0.1
|
||||
golang.org/x/net v0.0.0-20200602114024-627f9648deb9 // indirect
|
||||
golang.org/x/sys v0.0.0-20200602100848-8d3cce7afc34 // indirect
|
||||
gopkg.in/yaml.v2 v2.3.0 // indirect
|
||||
)
|
|
@ -0,0 +1,299 @@
|
|||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/99designs/gqlgen v0.11.3 h1:oFSxl1DFS9X///uHV3y6CEfpcXWrDUxVblR4Xib2bs4=
|
||||
github.com/99designs/gqlgen v0.11.3/go.mod h1:RgX5GRRdDWNkh4pBrdzNpNPFVsdoUFY2+adM6nb1N+4=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/DataDog/sketches-go v0.0.0-20190923095040-43f19ad77ff7 h1:qELHH0AWCvf98Yf+CNIJx9vOZOfHFDDzgDRYsnNk/vs=
|
||||
github.com/DataDog/sketches-go v0.0.0-20190923095040-43f19ad77ff7/go.mod h1:Q5DbzQ+3AkgGwymQO7aZFNP7ns2lZKGtvRBzRXfdi60=
|
||||
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
|
||||
github.com/agnivade/levenshtein v1.0.3 h1:M5ZnqLOoZR8ygVq0FfkXsNOKzMCk0xRiow0R5+5VkQ0=
|
||||
github.com/agnivade/levenshtein v1.0.3/go.mod h1:4SFRZbbXWLF4MU1T9Qg0pGgH3Pjs+t6ie5efyrwRJXs=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
|
||||
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=
|
||||
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
|
||||
github.com/benbjohnson/clock v1.0.0 h1:78Jk/r6m4wCi6sndMpty7A//t4dw/RW5fV4ZgDVfX1w=
|
||||
github.com/benbjohnson/clock v1.0.0/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
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/codemodus/kace v0.5.1 h1:4OCsBlE2c/rSJo375ggfnucv9eRzge/U5LrrOZd47HA=
|
||||
github.com/codemodus/kace v0.5.1/go.mod h1:coddaHoX1ku1YFSe4Ip0mL9kQjJvKkzb9CfIdG1YR04=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
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/dgryski/trifles v0.0.0-20190318185328-a8d75aae118c h1:TUuUh0Xgj97tLMNtWtNvI9mIV6isjEb9lBMNv+77IGM=
|
||||
github.com/dgryski/trifles v0.0.0-20190318185328-a8d75aae118c/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
|
||||
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/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
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-chi/chi v3.3.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
|
||||
github.com/go-pg/pg/v10 v10.0.0-beta.1 h1:GD65aZVx9yR6fxxXdglBlook89oxxg2FYE11TDd9Now=
|
||||
github.com/go-pg/pg/v10 v10.0.0-beta.1/go.mod h1:JYxBTzIz9dpSAa+bphD1U7A/PBCwiuw1o8pYNDSsQ+4=
|
||||
github.com/go-pg/pg/v9 v9.0.0-beta.14/go.mod h1:T2Sr6bpTCOr2lUqOUMiXLMJqZHSUBKk1LdgSqjwhZfA=
|
||||
github.com/go-pg/pg/v9 v9.0.3/go.mod h1:Tm/Q3Vt6gdQOH6TTN1H/xLlIXc+Qrka7TZ6uREtu/eA=
|
||||
github.com/go-pg/pg/v9 v9.1.6 h1:IqBayenvp9EWjHncRE7//SRmQuktq60oeO1/MkEx3dY=
|
||||
github.com/go-pg/pg/v9 v9.1.6/go.mod h1:QM13HBLkdml4zcKOfUfGLymM6hb72aKTJLrmaH8rsFg=
|
||||
github.com/go-pg/urlstruct v0.1.0/go.mod h1:2Nag+BIny6G/KYCkdt++ZnqU/VinzimGapKfs4kwlN0=
|
||||
github.com/go-pg/urlstruct v0.2.6/go.mod h1:dxENwVISWSOX+k87hDt0ueEJadD+gZWv3tHzwfmZPu8=
|
||||
github.com/go-pg/urlstruct v0.3.0/go.mod h1:/XKyiUOUUS3onjF+LJxbfmSywYAdl6qMfVbX33Q8rgg=
|
||||
github.com/go-pg/urlstruct v0.4.0 h1:3lmbUGYQclB3UOx9akDs2T251zwkKQuPkvPTmCm07+A=
|
||||
github.com/go-pg/urlstruct v0.4.0/go.mod h1:/XKyiUOUUS3onjF+LJxbfmSywYAdl6qMfVbX33Q8rgg=
|
||||
github.com/go-pg/zerochecker v0.1.1 h1:av77Qe7Gs+1oYGGh51k0sbZ0bUaxJEdeP0r8YE64Dco=
|
||||
github.com/go-pg/zerochecker v0.1.1/go.mod h1:NJZ4wKL0NmTtz0GKCoJ8kym6Xn/EQzXRl2OnAe7MmDo=
|
||||
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-playground/validator/v10 v10.3.0 h1:nZU+7q+yJoFmwvNgv/LnPUkwPal62+b2xXj0AU1Es7o=
|
||||
github.com/go-playground/validator/v10 v10.3.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
|
||||
github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
|
||||
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.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 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
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 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/mux v1.6.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/websocket v1.2.0 h1:VJtLvh6VQym50czpZzx07z/kw9EgAxI3x1ZB8taTMQQ=
|
||||
github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
|
||||
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
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 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
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/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
|
||||
github.com/matryer/moq v0.0.0-20200106131100-75d0ddfc0007/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mitchellh/mapstructure v0.0.0-20180203102830-a4e142e9c047 h1:zCoDWFD5nrJJVjbXiDZcVhOBSzKn3o9LgRLLMRNuru8=
|
||||
github.com/mitchellh/mapstructure v0.0.0-20180203102830-a4e142e9c047/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||
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 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
|
||||
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/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=
|
||||
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
|
||||
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/opentracing/opentracing-go v1.1.1-0.20190913142402-a7454ce5950e/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/segmentio/encoding v0.1.10/go.mod h1:RWhr02uzMB9gQC1x+MfYxedtmBibb9cZ6Vv9VxRSSbw=
|
||||
github.com/segmentio/encoding v0.1.12 h1:SwIDXReTDnlYqOcLachzJEczAEihST7Mx7nGlAWCJ3Q=
|
||||
github.com/segmentio/encoding v0.1.12/go.mod h1:RWhr02uzMB9gQC1x+MfYxedtmBibb9cZ6Vv9VxRSSbw=
|
||||
github.com/segmentio/encoding v0.1.13 h1:izH8HknGvMZvlqplu+kmCmbsW5VEvz4yBsZpdUUKUDM=
|
||||
github.com/segmentio/encoding v0.1.13/go.mod h1:RWhr02uzMB9gQC1x+MfYxedtmBibb9cZ6Vv9VxRSSbw=
|
||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo=
|
||||
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs=
|
||||
github.com/tribalwarshelp/shared v0.0.0-20200602122915-bb9a531672b6 h1:vrqEpEwkKg63/hV5cIGgmDvdcAdDm4pR0N14nC3eCjQ=
|
||||
github.com/tribalwarshelp/shared v0.0.0-20200602122915-bb9a531672b6/go.mod h1:tf+2yTHasV6jAF3V2deZ9slNoCyBzC0fMdTjI7clf6Y=
|
||||
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/urfave/cli/v2 v2.1.1 h1:Qt8FeAtxE/vfdrLmR3rxR6JRE0RoVmbXu8+6kZtYU4k=
|
||||
github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
|
||||
github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e/go.mod h1:/HUdMve7rvxZma+2ZELQeNh88+003LL7Pf/CZ089j8U=
|
||||
github.com/vektah/gqlparser/v2 v2.0.1 h1:xgl5abVnsd4hkN9rk65OJID9bfcLSMuTaTcZj777q1o=
|
||||
github.com/vektah/gqlparser/v2 v2.0.1/go.mod h1:SyUiHgLATUR8BiYURfTirrTcGpcE+4XkV2se04Px1Ms=
|
||||
github.com/vmihailenco/bufpool v0.1.5/go.mod h1:fL9i/PRTuS7AELqAHwSU1Zf1c70xhkhGe/cD5ud9pJk=
|
||||
github.com/vmihailenco/bufpool v0.1.11 h1:gOq2WmBrq0i2yW5QJ16ykccQ4wH9UyEsgLm6czKAd94=
|
||||
github.com/vmihailenco/bufpool v0.1.11/go.mod h1:AFf/MOy3l2CFTKbxwt0mp2MwnqjNEs5H/UxrkA5jxTQ=
|
||||
github.com/vmihailenco/msgpack/v4 v4.3.5/go.mod h1:DuaveEe48abshDmz5UBKyZ+yDugvaeFk5ayfrewUOaw=
|
||||
github.com/vmihailenco/msgpack/v4 v4.3.7/go.mod h1:Ii+PksJlvFT5ZRcB/4YLAInMIp6a0WOCm0L3BU0aNG4=
|
||||
github.com/vmihailenco/msgpack/v4 v4.3.11 h1:Q47CePddpNGNhk4GCnAx9DDtASi2rasatE0cd26cZoE=
|
||||
github.com/vmihailenco/msgpack/v4 v4.3.11/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4=
|
||||
github.com/vmihailenco/msgpack/v5 v5.0.0-alpha.2 h1:0jVpYJSRJzGY7m21n9V5uIkl7Zre64W8DR1dxEKX2g4=
|
||||
github.com/vmihailenco/msgpack/v5 v5.0.0-alpha.2/go.mod h1:LDfrk4wJpSFwkzNOJxrCWiSm8c7Iqw/hXNPT2fzQfE8=
|
||||
github.com/vmihailenco/tagparser v0.1.0/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
|
||||
github.com/vmihailenco/tagparser v0.1.1 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37wVyIuWY=
|
||||
github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
|
||||
go.opentelemetry.io/otel v0.6.0 h1:+vkHm/XwJ7ekpISV2Ixew93gCrxTbuwTF5rSewnLLgw=
|
||||
go.opentelemetry.io/otel v0.6.0/go.mod h1:jzBIgIzK43Iu1BpDAXwqOd6UPsSAk+ewVZ5ofSXw4Ek=
|
||||
golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b/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-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20191128160524-b544559bb6d1/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw=
|
||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
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-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-20190420063019-afa5a82059c6/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-20190923162816-aa69164e4478/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-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200222033325-078779b8f2d8/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-20200520182314-0ba52f642ac2 h1:eDrdRpKgkcCqKZQwyZRyeFZgfqt37SL7Kv3tok06cKE=
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYcn15TUbkhwuCO3foqqM=
|
||||
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200602100848-8d3cce7afc34 h1:u6CI7A++8r4SItZHYe2cWeAEndN4p1p+3Oum/Ft2EzM=
|
||||
golang.org/x/sys v0.0.0-20200602100848-8d3cce7afc34/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/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-20190515012406-7d7faa4812bd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20200114235610-7ae403b6b589 h1:rjUrONFu4kLchcZTfp3/96bR8bW8dIa8uz3cR5n0cgM=
|
||||
golang.org/x/tools v0.0.0-20200114235610-7ae403b6b589/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
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.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
|
||||
google.golang.org/appengine v1.6.6/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-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20191009194640-548a555dbc03/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
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.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
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 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
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.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.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
mellium.im/sasl v0.2.1 h1:nspKSRg7/SyO0cRGY71OkfHab8tf9kCts6a6oTDut0w=
|
||||
mellium.im/sasl v0.2.1/go.mod h1:ROaEDLQNuf9vjKqE1SrAfnsobm2YKXT1gnN1uDp1PjQ=
|
||||
sourcegraph.com/sourcegraph/appdash v0.0.0-20180110180208-2cc67fd64755/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
|
||||
sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67/go.mod h1:L5q+DGLGOQFpo1snNEkLOJT2d1YTW66rWNzatr3He1k=
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/sh
|
||||
|
||||
cd ./graphql
|
||||
go run github.com/99designs/gqlgen
|
||||
cd ..
|
|
@ -0,0 +1,76 @@
|
|||
package dataloaders
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/tribalwarshelp/api/player"
|
||||
"github.com/tribalwarshelp/api/tribe"
|
||||
"github.com/tribalwarshelp/shared/models"
|
||||
)
|
||||
|
||||
type DataLoaders struct {
|
||||
PlayerByID PlayerLoader
|
||||
TribeByID TribeLoader
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
PlayerRepo player.Repository
|
||||
TribeRepo tribe.Repository
|
||||
}
|
||||
|
||||
func New(server string, cfg Config) *DataLoaders {
|
||||
return &DataLoaders{
|
||||
PlayerByID: PlayerLoader{
|
||||
wait: 2 * time.Millisecond,
|
||||
maxBatch: 0,
|
||||
fetch: func(ids []int) ([]*models.Player, []error) {
|
||||
log.Println("playerbyid", ids)
|
||||
players, _, err := cfg.PlayerRepo.Fetch(context.Background(), server, &models.PlayerFilter{
|
||||
ID: ids,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, []error{err}
|
||||
}
|
||||
|
||||
playerByID := make(map[int]*models.Player)
|
||||
for _, player := range players {
|
||||
playerByID[player.ID] = player
|
||||
}
|
||||
|
||||
sorted := make([]*models.Player, len(ids))
|
||||
for i, id := range ids {
|
||||
sorted[i] = playerByID[id]
|
||||
}
|
||||
|
||||
return sorted, nil
|
||||
},
|
||||
},
|
||||
TribeByID: TribeLoader{
|
||||
wait: 2 * time.Millisecond,
|
||||
maxBatch: 0,
|
||||
fetch: func(ids []int) ([]*models.Tribe, []error) {
|
||||
log.Println("tribebyid", ids)
|
||||
tribes, _, err := cfg.TribeRepo.Fetch(context.Background(), server, &models.TribeFilter{
|
||||
ID: ids,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, []error{err}
|
||||
}
|
||||
|
||||
tribeByID := make(map[int]*models.Tribe)
|
||||
for _, tribe := range tribes {
|
||||
tribeByID[tribe.ID] = tribe
|
||||
}
|
||||
|
||||
sorted := make([]*models.Tribe, len(ids))
|
||||
for i, id := range ids {
|
||||
sorted[i] = tribeByID[id]
|
||||
}
|
||||
|
||||
return sorted, nil
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
|
@ -0,0 +1,224 @@
|
|||
// Code generated by github.com/vektah/dataloaden, DO NOT EDIT.
|
||||
|
||||
package dataloaders
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/tribalwarshelp/shared/models"
|
||||
)
|
||||
|
||||
// PlayerLoaderConfig captures the config to create a new PlayerLoader
|
||||
type PlayerLoaderConfig struct {
|
||||
// Fetch is a method that provides the data for the loader
|
||||
Fetch func(keys []int) ([]*models.Player, []error)
|
||||
|
||||
// Wait is how long wait before sending a batch
|
||||
Wait time.Duration
|
||||
|
||||
// MaxBatch will limit the maximum number of keys to send in one batch, 0 = not limit
|
||||
MaxBatch int
|
||||
}
|
||||
|
||||
// NewPlayerLoader creates a new PlayerLoader given a fetch, wait, and maxBatch
|
||||
func NewPlayerLoader(config PlayerLoaderConfig) *PlayerLoader {
|
||||
return &PlayerLoader{
|
||||
fetch: config.Fetch,
|
||||
wait: config.Wait,
|
||||
maxBatch: config.MaxBatch,
|
||||
}
|
||||
}
|
||||
|
||||
// PlayerLoader batches and caches requests
|
||||
type PlayerLoader struct {
|
||||
// this method provides the data for the loader
|
||||
fetch func(keys []int) ([]*models.Player, []error)
|
||||
|
||||
// how long to done before sending a batch
|
||||
wait time.Duration
|
||||
|
||||
// this will limit the maximum number of keys to send in one batch, 0 = no limit
|
||||
maxBatch int
|
||||
|
||||
// INTERNAL
|
||||
|
||||
// lazily created cache
|
||||
cache map[int]*models.Player
|
||||
|
||||
// the current batch. keys will continue to be collected until timeout is hit,
|
||||
// then everything will be sent to the fetch method and out to the listeners
|
||||
batch *playerLoaderBatch
|
||||
|
||||
// mutex to prevent races
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
type playerLoaderBatch struct {
|
||||
keys []int
|
||||
data []*models.Player
|
||||
error []error
|
||||
closing bool
|
||||
done chan struct{}
|
||||
}
|
||||
|
||||
// Load a Player by key, batching and caching will be applied automatically
|
||||
func (l *PlayerLoader) Load(key int) (*models.Player, error) {
|
||||
return l.LoadThunk(key)()
|
||||
}
|
||||
|
||||
// LoadThunk returns a function that when called will block waiting for a Player.
|
||||
// This method should be used if you want one goroutine to make requests to many
|
||||
// different data loaders without blocking until the thunk is called.
|
||||
func (l *PlayerLoader) LoadThunk(key int) func() (*models.Player, error) {
|
||||
l.mu.Lock()
|
||||
if it, ok := l.cache[key]; ok {
|
||||
l.mu.Unlock()
|
||||
return func() (*models.Player, error) {
|
||||
return it, nil
|
||||
}
|
||||
}
|
||||
if l.batch == nil {
|
||||
l.batch = &playerLoaderBatch{done: make(chan struct{})}
|
||||
}
|
||||
batch := l.batch
|
||||
pos := batch.keyIndex(l, key)
|
||||
l.mu.Unlock()
|
||||
|
||||
return func() (*models.Player, error) {
|
||||
<-batch.done
|
||||
|
||||
var data *models.Player
|
||||
if pos < len(batch.data) {
|
||||
data = batch.data[pos]
|
||||
}
|
||||
|
||||
var err error
|
||||
// its convenient to be able to return a single error for everything
|
||||
if len(batch.error) == 1 {
|
||||
err = batch.error[0]
|
||||
} else if batch.error != nil {
|
||||
err = batch.error[pos]
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
l.mu.Lock()
|
||||
l.unsafeSet(key, data)
|
||||
l.mu.Unlock()
|
||||
}
|
||||
|
||||
return data, err
|
||||
}
|
||||
}
|
||||
|
||||
// LoadAll fetches many keys at once. It will be broken into appropriate sized
|
||||
// sub batches depending on how the loader is configured
|
||||
func (l *PlayerLoader) LoadAll(keys []int) ([]*models.Player, []error) {
|
||||
results := make([]func() (*models.Player, error), len(keys))
|
||||
|
||||
for i, key := range keys {
|
||||
results[i] = l.LoadThunk(key)
|
||||
}
|
||||
|
||||
players := make([]*models.Player, len(keys))
|
||||
errors := make([]error, len(keys))
|
||||
for i, thunk := range results {
|
||||
players[i], errors[i] = thunk()
|
||||
}
|
||||
return players, errors
|
||||
}
|
||||
|
||||
// LoadAllThunk returns a function that when called will block waiting for a Players.
|
||||
// This method should be used if you want one goroutine to make requests to many
|
||||
// different data loaders without blocking until the thunk is called.
|
||||
func (l *PlayerLoader) LoadAllThunk(keys []int) func() ([]*models.Player, []error) {
|
||||
results := make([]func() (*models.Player, error), len(keys))
|
||||
for i, key := range keys {
|
||||
results[i] = l.LoadThunk(key)
|
||||
}
|
||||
return func() ([]*models.Player, []error) {
|
||||
players := make([]*models.Player, len(keys))
|
||||
errors := make([]error, len(keys))
|
||||
for i, thunk := range results {
|
||||
players[i], errors[i] = thunk()
|
||||
}
|
||||
return players, errors
|
||||
}
|
||||
}
|
||||
|
||||
// Prime the cache with the provided key and value. If the key already exists, no change is made
|
||||
// and false is returned.
|
||||
// (To forcefully prime the cache, clear the key first with loader.clear(key).prime(key, value).)
|
||||
func (l *PlayerLoader) Prime(key int, value *models.Player) bool {
|
||||
l.mu.Lock()
|
||||
var found bool
|
||||
if _, found = l.cache[key]; !found {
|
||||
// make a copy when writing to the cache, its easy to pass a pointer in from a loop var
|
||||
// and end up with the whole cache pointing to the same value.
|
||||
cpy := *value
|
||||
l.unsafeSet(key, &cpy)
|
||||
}
|
||||
l.mu.Unlock()
|
||||
return !found
|
||||
}
|
||||
|
||||
// Clear the value at key from the cache, if it exists
|
||||
func (l *PlayerLoader) Clear(key int) {
|
||||
l.mu.Lock()
|
||||
delete(l.cache, key)
|
||||
l.mu.Unlock()
|
||||
}
|
||||
|
||||
func (l *PlayerLoader) unsafeSet(key int, value *models.Player) {
|
||||
if l.cache == nil {
|
||||
l.cache = map[int]*models.Player{}
|
||||
}
|
||||
l.cache[key] = value
|
||||
}
|
||||
|
||||
// keyIndex will return the location of the key in the batch, if its not found
|
||||
// it will add the key to the batch
|
||||
func (b *playerLoaderBatch) keyIndex(l *PlayerLoader, key int) int {
|
||||
for i, existingKey := range b.keys {
|
||||
if key == existingKey {
|
||||
return i
|
||||
}
|
||||
}
|
||||
|
||||
pos := len(b.keys)
|
||||
b.keys = append(b.keys, key)
|
||||
if pos == 0 {
|
||||
go b.startTimer(l)
|
||||
}
|
||||
|
||||
if l.maxBatch != 0 && pos >= l.maxBatch-1 {
|
||||
if !b.closing {
|
||||
b.closing = true
|
||||
l.batch = nil
|
||||
go b.end(l)
|
||||
}
|
||||
}
|
||||
|
||||
return pos
|
||||
}
|
||||
|
||||
func (b *playerLoaderBatch) startTimer(l *PlayerLoader) {
|
||||
time.Sleep(l.wait)
|
||||
l.mu.Lock()
|
||||
|
||||
// we must have hit a batch limit and are already finalizing this batch
|
||||
if b.closing {
|
||||
l.mu.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
l.batch = nil
|
||||
l.mu.Unlock()
|
||||
|
||||
b.end(l)
|
||||
}
|
||||
|
||||
func (b *playerLoaderBatch) end(l *PlayerLoader) {
|
||||
b.data, b.error = l.fetch(b.keys)
|
||||
close(b.done)
|
||||
}
|
|
@ -0,0 +1,224 @@
|
|||
// Code generated by github.com/vektah/dataloaden, DO NOT EDIT.
|
||||
|
||||
package dataloaders
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/tribalwarshelp/shared/models"
|
||||
)
|
||||
|
||||
// TribeLoaderConfig captures the config to create a new TribeLoader
|
||||
type TribeLoaderConfig struct {
|
||||
// Fetch is a method that provides the data for the loader
|
||||
Fetch func(keys []int) ([]*models.Tribe, []error)
|
||||
|
||||
// Wait is how long wait before sending a batch
|
||||
Wait time.Duration
|
||||
|
||||
// MaxBatch will limit the maximum number of keys to send in one batch, 0 = not limit
|
||||
MaxBatch int
|
||||
}
|
||||
|
||||
// NewTribeLoader creates a new TribeLoader given a fetch, wait, and maxBatch
|
||||
func NewTribeLoader(config TribeLoaderConfig) *TribeLoader {
|
||||
return &TribeLoader{
|
||||
fetch: config.Fetch,
|
||||
wait: config.Wait,
|
||||
maxBatch: config.MaxBatch,
|
||||
}
|
||||
}
|
||||
|
||||
// TribeLoader batches and caches requests
|
||||
type TribeLoader struct {
|
||||
// this method provides the data for the loader
|
||||
fetch func(keys []int) ([]*models.Tribe, []error)
|
||||
|
||||
// how long to done before sending a batch
|
||||
wait time.Duration
|
||||
|
||||
// this will limit the maximum number of keys to send in one batch, 0 = no limit
|
||||
maxBatch int
|
||||
|
||||
// INTERNAL
|
||||
|
||||
// lazily created cache
|
||||
cache map[int]*models.Tribe
|
||||
|
||||
// the current batch. keys will continue to be collected until timeout is hit,
|
||||
// then everything will be sent to the fetch method and out to the listeners
|
||||
batch *tribeLoaderBatch
|
||||
|
||||
// mutex to prevent races
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
type tribeLoaderBatch struct {
|
||||
keys []int
|
||||
data []*models.Tribe
|
||||
error []error
|
||||
closing bool
|
||||
done chan struct{}
|
||||
}
|
||||
|
||||
// Load a Tribe by key, batching and caching will be applied automatically
|
||||
func (l *TribeLoader) Load(key int) (*models.Tribe, error) {
|
||||
return l.LoadThunk(key)()
|
||||
}
|
||||
|
||||
// LoadThunk returns a function that when called will block waiting for a Tribe.
|
||||
// This method should be used if you want one goroutine to make requests to many
|
||||
// different data loaders without blocking until the thunk is called.
|
||||
func (l *TribeLoader) LoadThunk(key int) func() (*models.Tribe, error) {
|
||||
l.mu.Lock()
|
||||
if it, ok := l.cache[key]; ok {
|
||||
l.mu.Unlock()
|
||||
return func() (*models.Tribe, error) {
|
||||
return it, nil
|
||||
}
|
||||
}
|
||||
if l.batch == nil {
|
||||
l.batch = &tribeLoaderBatch{done: make(chan struct{})}
|
||||
}
|
||||
batch := l.batch
|
||||
pos := batch.keyIndex(l, key)
|
||||
l.mu.Unlock()
|
||||
|
||||
return func() (*models.Tribe, error) {
|
||||
<-batch.done
|
||||
|
||||
var data *models.Tribe
|
||||
if pos < len(batch.data) {
|
||||
data = batch.data[pos]
|
||||
}
|
||||
|
||||
var err error
|
||||
// its convenient to be able to return a single error for everything
|
||||
if len(batch.error) == 1 {
|
||||
err = batch.error[0]
|
||||
} else if batch.error != nil {
|
||||
err = batch.error[pos]
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
l.mu.Lock()
|
||||
l.unsafeSet(key, data)
|
||||
l.mu.Unlock()
|
||||
}
|
||||
|
||||
return data, err
|
||||
}
|
||||
}
|
||||
|
||||
// LoadAll fetches many keys at once. It will be broken into appropriate sized
|
||||
// sub batches depending on how the loader is configured
|
||||
func (l *TribeLoader) LoadAll(keys []int) ([]*models.Tribe, []error) {
|
||||
results := make([]func() (*models.Tribe, error), len(keys))
|
||||
|
||||
for i, key := range keys {
|
||||
results[i] = l.LoadThunk(key)
|
||||
}
|
||||
|
||||
tribes := make([]*models.Tribe, len(keys))
|
||||
errors := make([]error, len(keys))
|
||||
for i, thunk := range results {
|
||||
tribes[i], errors[i] = thunk()
|
||||
}
|
||||
return tribes, errors
|
||||
}
|
||||
|
||||
// LoadAllThunk returns a function that when called will block waiting for a Tribes.
|
||||
// This method should be used if you want one goroutine to make requests to many
|
||||
// different data loaders without blocking until the thunk is called.
|
||||
func (l *TribeLoader) LoadAllThunk(keys []int) func() ([]*models.Tribe, []error) {
|
||||
results := make([]func() (*models.Tribe, error), len(keys))
|
||||
for i, key := range keys {
|
||||
results[i] = l.LoadThunk(key)
|
||||
}
|
||||
return func() ([]*models.Tribe, []error) {
|
||||
tribes := make([]*models.Tribe, len(keys))
|
||||
errors := make([]error, len(keys))
|
||||
for i, thunk := range results {
|
||||
tribes[i], errors[i] = thunk()
|
||||
}
|
||||
return tribes, errors
|
||||
}
|
||||
}
|
||||
|
||||
// Prime the cache with the provided key and value. If the key already exists, no change is made
|
||||
// and false is returned.
|
||||
// (To forcefully prime the cache, clear the key first with loader.clear(key).prime(key, value).)
|
||||
func (l *TribeLoader) Prime(key int, value *models.Tribe) bool {
|
||||
l.mu.Lock()
|
||||
var found bool
|
||||
if _, found = l.cache[key]; !found {
|
||||
// make a copy when writing to the cache, its easy to pass a pointer in from a loop var
|
||||
// and end up with the whole cache pointing to the same value.
|
||||
cpy := *value
|
||||
l.unsafeSet(key, &cpy)
|
||||
}
|
||||
l.mu.Unlock()
|
||||
return !found
|
||||
}
|
||||
|
||||
// Clear the value at key from the cache, if it exists
|
||||
func (l *TribeLoader) Clear(key int) {
|
||||
l.mu.Lock()
|
||||
delete(l.cache, key)
|
||||
l.mu.Unlock()
|
||||
}
|
||||
|
||||
func (l *TribeLoader) unsafeSet(key int, value *models.Tribe) {
|
||||
if l.cache == nil {
|
||||
l.cache = map[int]*models.Tribe{}
|
||||
}
|
||||
l.cache[key] = value
|
||||
}
|
||||
|
||||
// keyIndex will return the location of the key in the batch, if its not found
|
||||
// it will add the key to the batch
|
||||
func (b *tribeLoaderBatch) keyIndex(l *TribeLoader, key int) int {
|
||||
for i, existingKey := range b.keys {
|
||||
if key == existingKey {
|
||||
return i
|
||||
}
|
||||
}
|
||||
|
||||
pos := len(b.keys)
|
||||
b.keys = append(b.keys, key)
|
||||
if pos == 0 {
|
||||
go b.startTimer(l)
|
||||
}
|
||||
|
||||
if l.maxBatch != 0 && pos >= l.maxBatch-1 {
|
||||
if !b.closing {
|
||||
b.closing = true
|
||||
l.batch = nil
|
||||
go b.end(l)
|
||||
}
|
||||
}
|
||||
|
||||
return pos
|
||||
}
|
||||
|
||||
func (b *tribeLoaderBatch) startTimer(l *TribeLoader) {
|
||||
time.Sleep(l.wait)
|
||||
l.mu.Lock()
|
||||
|
||||
// we must have hit a batch limit and are already finalizing this batch
|
||||
if b.closing {
|
||||
l.mu.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
l.batch = nil
|
||||
l.mu.Unlock()
|
||||
|
||||
b.end(l)
|
||||
}
|
||||
|
||||
func (b *tribeLoaderBatch) end(l *TribeLoader) {
|
||||
b.data, b.error = l.fetch(b.keys)
|
||||
close(b.done)
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package httpdelivery
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/99designs/gqlgen/graphql/handler"
|
||||
"github.com/99designs/gqlgen/graphql/playground"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/tribalwarshelp/api/graphql/generated"
|
||||
"github.com/tribalwarshelp/api/graphql/resolvers"
|
||||
)
|
||||
|
||||
func Attach(g *gin.RouterGroup, r *resolvers.Resolver) error {
|
||||
if r == nil {
|
||||
return fmt.Errorf("Graphql resolver cannot be nil")
|
||||
}
|
||||
g.POST("/graphql", graphqlHandler(r))
|
||||
g.GET("/", playgroundHandler())
|
||||
return nil
|
||||
}
|
||||
|
||||
// Defining the Graphql handler
|
||||
func graphqlHandler(r *resolvers.Resolver) gin.HandlerFunc {
|
||||
// NewExecutableSchema and Config are in the generated.go file
|
||||
// Resolver is in the resolver.go file
|
||||
cfg := generated.Config{Resolvers: r}
|
||||
h := handler.NewDefaultServer(generated.NewExecutableSchema(cfg))
|
||||
|
||||
return func(c *gin.Context) {
|
||||
c.Header("Cache-Control", "no-store, must-revalidate")
|
||||
h.ServeHTTP(c.Writer, c.Request)
|
||||
}
|
||||
}
|
||||
|
||||
// Defining the Playground handler
|
||||
func playgroundHandler() gin.HandlerFunc {
|
||||
h := playground.Handler("Playground", "/graphql")
|
||||
|
||||
return func(c *gin.Context) {
|
||||
h.ServeHTTP(c.Writer, c.Request)
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,32 @@
|
|||
// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
|
||||
|
||||
package generated
|
||||
|
||||
import (
|
||||
"github.com/tribalwarshelp/shared/models"
|
||||
)
|
||||
|
||||
type LangVersionList struct {
|
||||
Items []*models.LangVersion `json:"items"`
|
||||
Total int `json:"total"`
|
||||
}
|
||||
|
||||
type PlayerList struct {
|
||||
Items []*models.Player `json:"items"`
|
||||
Total int `json:"total"`
|
||||
}
|
||||
|
||||
type ServerList struct {
|
||||
Items []*models.Server `json:"items"`
|
||||
Total int `json:"total"`
|
||||
}
|
||||
|
||||
type TribeList struct {
|
||||
Items []*models.Tribe `json:"items"`
|
||||
Total int `json:"total"`
|
||||
}
|
||||
|
||||
type VillageList struct {
|
||||
Items []*models.Village `json:"items"`
|
||||
Total int `json:"total"`
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
schema:
|
||||
- 'schema/*.graphql'
|
||||
exec:
|
||||
filename: generated/generated.go
|
||||
package: generated
|
||||
model:
|
||||
filename: generated/models.go
|
||||
package: generated
|
||||
resolver:
|
||||
filename: resolvers/resolver.go
|
||||
package: resolvers
|
||||
type: Resolver
|
||||
struct_tag: gqlgen
|
||||
models:
|
||||
LanguageTag:
|
||||
model: github.com/tribalwarshelp/shared/models.LanguageTag
|
||||
ServerStatus:
|
||||
model: github.com/tribalwarshelp/shared/models.ServerStatus
|
||||
LangVersion:
|
||||
model: github.com/tribalwarshelp/shared/models.LangVersion
|
||||
LangVersionFilter:
|
||||
model: github.com/tribalwarshelp/shared/models.LangVersionFilter
|
||||
Server:
|
||||
model: github.com/tribalwarshelp/shared/models.Server
|
||||
ServerFilter:
|
||||
model: github.com/tribalwarshelp/shared/models.ServerFilter
|
||||
Player:
|
||||
model: github.com/tribalwarshelp/shared/models.Player
|
||||
PlayerFilter:
|
||||
model: github.com/tribalwarshelp/shared/models.PlayerFilter
|
||||
Tribe:
|
||||
model: github.com/tribalwarshelp/shared/models.Tribe
|
||||
TribeFilter:
|
||||
model: github.com/tribalwarshelp/shared/models.TribeFilter
|
||||
Village:
|
||||
model: github.com/tribalwarshelp/shared/models.Village
|
||||
VillageFilter:
|
||||
model: github.com/tribalwarshelp/shared/models.VillageFilter
|
|
@ -0,0 +1,19 @@
|
|||
package resolvers
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/tribalwarshelp/api/graphql/generated"
|
||||
"github.com/tribalwarshelp/shared/models"
|
||||
)
|
||||
|
||||
func (r *queryResolver) LangVersions(ctx context.Context, filter *models.LangVersionFilter) (*generated.LangVersionList, error) {
|
||||
var err error
|
||||
list := &generated.LangVersionList{}
|
||||
list.Items, list.Total, err = r.LangVersionUcase.Fetch(ctx, filter)
|
||||
return list, err
|
||||
}
|
||||
|
||||
func (r *queryResolver) LangVersion(ctx context.Context, tag models.LanguageTag) (*models.LangVersion, error) {
|
||||
return r.LangVersionUcase.GetByTag(ctx, tag)
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package resolvers
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/99designs/gqlgen/graphql"
|
||||
"github.com/tribalwarshelp/api/graphql/generated"
|
||||
"github.com/tribalwarshelp/api/middleware"
|
||||
"github.com/tribalwarshelp/shared/models"
|
||||
)
|
||||
|
||||
func (r *playerResolver) Tribe(ctx context.Context, obj *models.Player) (*models.Tribe, error) {
|
||||
if obj.Tribe != nil {
|
||||
return obj.Tribe, nil
|
||||
}
|
||||
|
||||
rctx := graphql.GetFieldContext(ctx)
|
||||
server, ok := rctx.Parent.Parent.Parent.Args["server"].(string)
|
||||
if ok {
|
||||
dataloaders := middleware.DataLoadersFromContext(ctx)
|
||||
if dataloaders != nil {
|
||||
if dataloader, ok := dataloaders[server]; ok {
|
||||
tribe, _ := dataloader.TribeByID.Load(obj.TribeID)
|
||||
if tribe != nil {
|
||||
return tribe, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (r *queryResolver) Players(ctx context.Context, server string, filter *models.PlayerFilter) (*generated.PlayerList, error) {
|
||||
var err error
|
||||
list := &generated.PlayerList{}
|
||||
list.Items, list.Total, err = r.PlayerUcase.Fetch(ctx, server, filter)
|
||||
return list, err
|
||||
}
|
||||
|
||||
func (r *queryResolver) Player(ctx context.Context, server string, id int) (*models.Player, error) {
|
||||
return r.PlayerUcase.GetByID(ctx, server, id)
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package resolvers
|
||||
|
||||
import (
|
||||
"github.com/tribalwarshelp/api/graphql/generated"
|
||||
"github.com/tribalwarshelp/api/langversion"
|
||||
"github.com/tribalwarshelp/api/player"
|
||||
"github.com/tribalwarshelp/api/server"
|
||||
"github.com/tribalwarshelp/api/tribe"
|
||||
"github.com/tribalwarshelp/api/village"
|
||||
)
|
||||
|
||||
type Resolver struct {
|
||||
LangVersionUcase langversion.Usecase
|
||||
ServerUcase server.Usecase
|
||||
PlayerUcase player.Usecase
|
||||
TribeUcase tribe.Usecase
|
||||
VillageUcase village.Usecase
|
||||
}
|
||||
|
||||
// Query returns generated.QueryResolver implementation.
|
||||
func (r *Resolver) Query() generated.QueryResolver { return &queryResolver{r} }
|
||||
func (r *Resolver) Player() generated.PlayerResolver { return &playerResolver{r} }
|
||||
func (r *Resolver) Village() generated.VillageResolver { return &villageResolver{r} }
|
||||
|
||||
type queryResolver struct{ *Resolver }
|
||||
type playerResolver struct{ *Resolver }
|
||||
type villageResolver struct{ *Resolver }
|
|
@ -0,0 +1,19 @@
|
|||
package resolvers
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/tribalwarshelp/api/graphql/generated"
|
||||
"github.com/tribalwarshelp/shared/models"
|
||||
)
|
||||
|
||||
func (r *queryResolver) Servers(ctx context.Context, filter *models.ServerFilter) (*generated.ServerList, error) {
|
||||
var err error
|
||||
list := &generated.ServerList{}
|
||||
list.Items, list.Total, err = r.ServerUcase.Fetch(ctx, filter)
|
||||
return list, err
|
||||
}
|
||||
|
||||
func (r *queryResolver) Server(ctx context.Context, key string) (*models.Server, error) {
|
||||
return r.ServerUcase.GetByKey(ctx, key)
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package resolvers
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/tribalwarshelp/api/graphql/generated"
|
||||
"github.com/tribalwarshelp/shared/models"
|
||||
)
|
||||
|
||||
func (r *queryResolver) Tribes(ctx context.Context, server string, filter *models.TribeFilter) (*generated.TribeList, error) {
|
||||
var err error
|
||||
list := &generated.TribeList{}
|
||||
list.Items, list.Total, err = r.TribeUcase.Fetch(ctx, server, filter)
|
||||
return list, err
|
||||
}
|
||||
|
||||
func (r *queryResolver) Tribe(ctx context.Context, server string, id int) (*models.Tribe, error) {
|
||||
return r.TribeUcase.GetByID(ctx, server, id)
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package resolvers
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/99designs/gqlgen/graphql"
|
||||
"github.com/tribalwarshelp/api/graphql/generated"
|
||||
"github.com/tribalwarshelp/api/middleware"
|
||||
"github.com/tribalwarshelp/shared/models"
|
||||
)
|
||||
|
||||
func (r *villageResolver) Player(ctx context.Context, obj *models.Village) (*models.Player, error) {
|
||||
if obj.Player != nil {
|
||||
return obj.Player, nil
|
||||
}
|
||||
|
||||
rctx := graphql.GetFieldContext(ctx)
|
||||
server, ok := rctx.Parent.Parent.Parent.Args["server"].(string)
|
||||
if ok {
|
||||
dataloaders := middleware.DataLoadersFromContext(ctx)
|
||||
if dataloaders != nil {
|
||||
if dataloader, ok := dataloaders[server]; ok {
|
||||
tribe, _ := dataloader.PlayerByID.Load(obj.PlayerID)
|
||||
if tribe != nil {
|
||||
return tribe, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (r *queryResolver) Villages(ctx context.Context, server string, filter *models.VillageFilter) (*generated.VillageList, error) {
|
||||
var err error
|
||||
list := &generated.VillageList{}
|
||||
list.Items, list.Total, err = r.VillageUcase.Fetch(ctx, server, filter)
|
||||
return list, err
|
||||
}
|
||||
|
||||
func (r *queryResolver) Village(ctx context.Context, server string, id int) (*models.Village, error) {
|
||||
return r.VillageUcase.GetByID(ctx, server, id)
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
directive @goField(
|
||||
forceResolver: Boolean
|
||||
name: String
|
||||
) on INPUT_FIELD_DEFINITION | FIELD_DEFINITION
|
|
@ -0,0 +1,36 @@
|
|||
enum LanguageTag {
|
||||
PL
|
||||
EN
|
||||
DE
|
||||
}
|
||||
|
||||
type LangVersion {
|
||||
tag: LanguageTag!
|
||||
name: String!
|
||||
host: String!
|
||||
timezone: String!
|
||||
}
|
||||
|
||||
input LangVersionFilter {
|
||||
tag: [LanguageTag!]
|
||||
tagNEQ: [LanguageTag!]
|
||||
|
||||
host: [String!]
|
||||
hostNEQ: [String!]
|
||||
hostMATCH: String
|
||||
hostIEQ: String
|
||||
|
||||
offset: Int
|
||||
limit: Int
|
||||
sort: String
|
||||
}
|
||||
|
||||
type LangVersionList {
|
||||
items: [LangVersion!]
|
||||
total: Int!
|
||||
}
|
||||
|
||||
extend type Query {
|
||||
langVersions(filter: LangVersionFilter): LangVersionList!
|
||||
langVersion(tag: LanguageTag!): LangVersion
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
type Player {
|
||||
id: Int!
|
||||
name: String!
|
||||
totalVillages: Int!
|
||||
points: Int!
|
||||
rank: Int!
|
||||
exist: Boolean!
|
||||
rankAtt: Int!
|
||||
scoreAtt: Int!
|
||||
rankDef: Int!
|
||||
scoreDef: Int!
|
||||
rankSup: Int!
|
||||
scoreSup: Int!
|
||||
rankTotal: Int!
|
||||
scoreTotal: Int!
|
||||
tribe: Tribe @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
type PlayerList {
|
||||
items: [Player!]
|
||||
total: Int!
|
||||
}
|
||||
|
||||
input PlayerFilter {
|
||||
id: [Int!]
|
||||
idNEQ: [Int!]
|
||||
|
||||
exist: Boolean
|
||||
|
||||
name: [String!]
|
||||
nameNEQ: [String!]
|
||||
nameMATCH: String
|
||||
nameIEQ: String
|
||||
|
||||
totalVillages: Int
|
||||
totalVillagesGT: Int
|
||||
totalVillagesGTE: Int
|
||||
totalVillagesLT: Int
|
||||
totalVillagesLTE: Int
|
||||
|
||||
points: Int
|
||||
pointsGT: Int
|
||||
pointsGTE: Int
|
||||
pointsLT: Int
|
||||
pointsLTE: Int
|
||||
|
||||
rank: Int
|
||||
rankGT: Int
|
||||
rankGTE: Int
|
||||
rankLT: Int
|
||||
rankLTE: Int
|
||||
|
||||
rankAtt: Int
|
||||
rankAttGT: Int
|
||||
rankAttGTE: Int
|
||||
rankAttLT: Int
|
||||
rankAttLTE: Int
|
||||
|
||||
scoreAtt: Int
|
||||
scoreAttGT: Int
|
||||
scoreAttGTE: Int
|
||||
scoreAttLT: Int
|
||||
scoreAttLTE: Int
|
||||
|
||||
rankDef: Int
|
||||
rankDefGT: Int
|
||||
rankDefGTE: Int
|
||||
rankDefLT: Int
|
||||
rankDefLTE: Int
|
||||
|
||||
scoreDef: Int
|
||||
scoreDefGT: Int
|
||||
scoreDefGTE: Int
|
||||
scoreDefLT: Int
|
||||
scoreDefLTE: Int
|
||||
|
||||
rankSup: Int
|
||||
rankSupGT: Int
|
||||
rankSupGTE: Int
|
||||
rankSupLT: Int
|
||||
rankSupLTE: Int
|
||||
|
||||
scoreSup: Int
|
||||
scoreSupGT: Int
|
||||
scoreSupGTE: Int
|
||||
scoreSupLT: Int
|
||||
scoreSupLTE: Int
|
||||
|
||||
rankTotal: Int
|
||||
rankTotalGT: Int
|
||||
rankTotalGTE: Int
|
||||
rankTotalLT: Int
|
||||
rankTotalLTE: Int
|
||||
|
||||
scoreTotal: Int
|
||||
scoreTotalGT: Int
|
||||
scoreTotalGTE: Int
|
||||
scoreTotalLT: Int
|
||||
scoreTotalLTE: Int
|
||||
|
||||
tribeID: [Int!]
|
||||
|
||||
offset: Int
|
||||
limit: Int
|
||||
sort: String
|
||||
}
|
||||
|
||||
extend type Query {
|
||||
players(server: String!, filter: PlayerFilter): PlayerList!
|
||||
player(server: String!, id: Int!): Player
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
enum ServerStatus {
|
||||
OPEN
|
||||
CLOSED
|
||||
}
|
||||
|
||||
type Server {
|
||||
id: Int!
|
||||
key: String!
|
||||
status: ServerStatus!
|
||||
langVersionTag: LanguageTag!
|
||||
}
|
||||
|
||||
type ServerList {
|
||||
items: [Server!]
|
||||
total: Int!
|
||||
}
|
||||
|
||||
input ServerFilter {
|
||||
id: [Int!]
|
||||
idNEQ: [Int!]
|
||||
|
||||
key: [String!]
|
||||
keyNEQ: [String!]
|
||||
keyMATCH: String
|
||||
keyIEQ: String
|
||||
|
||||
status: [ServerStatus!]
|
||||
statusNEQ: [ServerStatus!]
|
||||
|
||||
langVersionTag: [LanguageTag!]
|
||||
langVersionTagNEQ: [LanguageTag!]
|
||||
|
||||
offset: Int
|
||||
limit: Int
|
||||
sort: String
|
||||
}
|
||||
|
||||
extend type Query {
|
||||
servers(filter: ServerFilter): ServerList!
|
||||
server(key: String!): Server
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
type Tribe {
|
||||
id: Int!
|
||||
name: String!
|
||||
tag: String!
|
||||
totalMembers: Int!
|
||||
totalVillages: Int!
|
||||
points: Int!
|
||||
allPoints: Int!
|
||||
rank: Int!
|
||||
exist: Boolean!
|
||||
rankAtt: Int!
|
||||
scoreAtt: Int!
|
||||
rankDef: Int!
|
||||
scoreDef: Int!
|
||||
rankTotal: Int!
|
||||
scoreTotal: Int!
|
||||
}
|
||||
|
||||
type TribeList {
|
||||
items: [Tribe!]
|
||||
total: Int!
|
||||
}
|
||||
|
||||
input TribeFilter {
|
||||
id: [Int!]
|
||||
idNEQ: [Int!]
|
||||
|
||||
exist: Boolean
|
||||
|
||||
tag: [String!]
|
||||
tagNEQ: [String!]
|
||||
tagMATCH: String
|
||||
tagIEQ: String
|
||||
|
||||
name: [String!]
|
||||
nameNEQ: [String!]
|
||||
nameMATCH: String
|
||||
nameIEQ: String
|
||||
|
||||
totalMembers: Int
|
||||
totalMembersGT: Int
|
||||
totalMembersGTE: Int
|
||||
totalMembersLT: Int
|
||||
totalMembersLTE: Int
|
||||
|
||||
totalVillages: Int
|
||||
totalVillagesGT: Int
|
||||
totalVillagesGTE: Int
|
||||
totalVillagesLT: Int
|
||||
totalVillagesLTE: Int
|
||||
|
||||
points: Int
|
||||
pointsGT: Int
|
||||
pointsGTE: Int
|
||||
pointsLT: Int
|
||||
pointsLTE: Int
|
||||
|
||||
allPoints: Int
|
||||
allPointsGT: Int
|
||||
allPointsGTE: Int
|
||||
allPointsLT: Int
|
||||
allPointsLTE: Int
|
||||
|
||||
rank: Int
|
||||
rankGT: Int
|
||||
rankGTE: Int
|
||||
rankLT: Int
|
||||
rankLTE: Int
|
||||
|
||||
rankAtt: Int
|
||||
rankAttGT: Int
|
||||
rankAttGTE: Int
|
||||
rankAttLT: Int
|
||||
rankAttLTE: Int
|
||||
|
||||
scoreAtt: Int
|
||||
scoreAttGT: Int
|
||||
scoreAttGTE: Int
|
||||
scoreAttLT: Int
|
||||
scoreAttLTE: Int
|
||||
|
||||
rankDef: Int
|
||||
rankDefGT: Int
|
||||
rankDefGTE: Int
|
||||
rankDefLT: Int
|
||||
rankDefLTE: Int
|
||||
|
||||
scoreDef: Int
|
||||
scoreDefGT: Int
|
||||
scoreDefGTE: Int
|
||||
scoreDefLT: Int
|
||||
scoreDefLTE: Int
|
||||
|
||||
rankTotal: Int
|
||||
rankTotalGT: Int
|
||||
rankTotalGTE: Int
|
||||
rankTotalLT: Int
|
||||
rankTotalLTE: Int
|
||||
|
||||
scoreTotal: Int
|
||||
scoreTotalGT: Int
|
||||
scoreTotalGTE: Int
|
||||
scoreTotalLT: Int
|
||||
scoreTotalLTE: Int
|
||||
|
||||
offset: Int
|
||||
limit: Int
|
||||
sort: String
|
||||
}
|
||||
|
||||
extend type Query {
|
||||
tribes(server: String!, filter: TribeFilter): TribeList!
|
||||
tribe(server: String!, id: Int!): Tribe
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
type Village {
|
||||
id: Int!
|
||||
name: String!
|
||||
points: Int!
|
||||
x: Int!
|
||||
y: Int!
|
||||
bonus: Int!
|
||||
player: Player @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
type VillageList {
|
||||
items: [Village!]
|
||||
total: Int!
|
||||
}
|
||||
|
||||
input VillageFilter {
|
||||
id: [Int!]
|
||||
idNEQ: [Int!]
|
||||
|
||||
name: [String!]
|
||||
nameNEQ: [String!]
|
||||
nameMATCH: String
|
||||
nameIEQ: String
|
||||
|
||||
points: Int
|
||||
pointsGT: Int
|
||||
pointsGTE: Int
|
||||
pointsLT: Int
|
||||
pointsLTE: Int
|
||||
|
||||
bonus: Int
|
||||
bonusGT: Int
|
||||
bonusGTE: Int
|
||||
bonusLT: Int
|
||||
bonusLTE: Int
|
||||
|
||||
playerID: [Int!]
|
||||
|
||||
offset: Int
|
||||
limit: Int
|
||||
sort: String
|
||||
}
|
||||
|
||||
extend type Query {
|
||||
villages(server: String!, filter: VillageFilter): VillageList!
|
||||
village(server: String!, id: Int!): Village
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package langversion
|
||||
|
||||
const (
|
||||
PaginationLimit = 100
|
||||
)
|
|
@ -0,0 +1,11 @@
|
|||
package langversion
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/tribalwarshelp/shared/models"
|
||||
)
|
||||
|
||||
type Repository interface {
|
||||
Fetch(ctx context.Context, filter *models.LangVersionFilter) ([]*models.LangVersion, int, error)
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/go-pg/pg/v10"
|
||||
"github.com/go-pg/pg/v10/orm"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/tribalwarshelp/api/langversion"
|
||||
"github.com/tribalwarshelp/shared/models"
|
||||
)
|
||||
|
||||
type pgRepository struct {
|
||||
*pg.DB
|
||||
}
|
||||
|
||||
func NewPGRepository(db *pg.DB) (langversion.Repository, error) {
|
||||
if err := db.CreateTable((*models.LangVersion)(nil), &orm.CreateTableOptions{
|
||||
IfNotExists: true,
|
||||
}); err != nil {
|
||||
return nil, errors.Wrap(err, "Cannot create 'lang_versions' table")
|
||||
}
|
||||
return &pgRepository{db}, nil
|
||||
}
|
||||
|
||||
func (repo *pgRepository) Fetch(ctx context.Context, f *models.LangVersionFilter) ([]*models.LangVersion, int, error) {
|
||||
var err error
|
||||
data := []*models.LangVersion{}
|
||||
query := repo.Model(&data).Context(ctx)
|
||||
|
||||
if f != nil {
|
||||
query = query.
|
||||
WhereStruct(f).
|
||||
Limit(f.Limit).
|
||||
Offset(f.Offset)
|
||||
|
||||
if f.Sort != "" {
|
||||
query = query.Order(f.Sort)
|
||||
}
|
||||
}
|
||||
|
||||
total, err := query.SelectAndCount()
|
||||
if err != nil && err != pg.ErrNoRows {
|
||||
return nil, 0, errors.Wrap(err, "Internal server error")
|
||||
}
|
||||
|
||||
return data, total, nil
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package langversion
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/tribalwarshelp/shared/models"
|
||||
)
|
||||
|
||||
type Usecase interface {
|
||||
Fetch(ctx context.Context, filter *models.LangVersionFilter) ([]*models.LangVersion, int, error)
|
||||
GetByTag(ctx context.Context, tag models.LanguageTag) (*models.LangVersion, error)
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package usecase
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/tribalwarshelp/api/langversion"
|
||||
"github.com/tribalwarshelp/shared/models"
|
||||
)
|
||||
|
||||
type usecase struct {
|
||||
repo langversion.Repository
|
||||
}
|
||||
|
||||
func New(repo langversion.Repository) langversion.Usecase {
|
||||
return &usecase{
|
||||
repo,
|
||||
}
|
||||
}
|
||||
|
||||
func (ucase *usecase) Fetch(ctx context.Context, filter *models.LangVersionFilter) ([]*models.LangVersion, int, error) {
|
||||
if filter == nil {
|
||||
filter = &models.LangVersionFilter{}
|
||||
}
|
||||
if filter.Limit > langversion.PaginationLimit || filter.Limit <= 0 {
|
||||
filter.Limit = langversion.PaginationLimit
|
||||
}
|
||||
return ucase.repo.Fetch(ctx, filter)
|
||||
}
|
||||
|
||||
func (ucase *usecase) GetByTag(ctx context.Context, tag models.LanguageTag) (*models.LangVersion, error) {
|
||||
langversions, total, err := ucase.repo.Fetch(ctx, &models.LangVersionFilter{
|
||||
Tag: []models.LanguageTag{tag},
|
||||
Limit: 1,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if total == 0 {
|
||||
return nil, fmt.Errorf("There is no lang version with tag: %s.", tag)
|
||||
}
|
||||
return langversions[0], nil
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"time"
|
||||
|
||||
"github.com/tribalwarshelp/shared/mode"
|
||||
|
||||
httpdelivery "github.com/tribalwarshelp/api/graphql/delivery/http"
|
||||
"github.com/tribalwarshelp/api/graphql/resolvers"
|
||||
|
||||
"github.com/tribalwarshelp/api/graphql/dataloaders"
|
||||
|
||||
langversionrepo "github.com/tribalwarshelp/api/langversion/repository"
|
||||
langversionucase "github.com/tribalwarshelp/api/langversion/usecase"
|
||||
"github.com/tribalwarshelp/api/middleware"
|
||||
playerrepo "github.com/tribalwarshelp/api/player/repository"
|
||||
playerucase "github.com/tribalwarshelp/api/player/usecase"
|
||||
serverrepo "github.com/tribalwarshelp/api/server/repository"
|
||||
serverucase "github.com/tribalwarshelp/api/server/usecase"
|
||||
triberepo "github.com/tribalwarshelp/api/tribe/repository"
|
||||
tribeucase "github.com/tribalwarshelp/api/tribe/usecase"
|
||||
villagerepo "github.com/tribalwarshelp/api/village/repository"
|
||||
villageucase "github.com/tribalwarshelp/api/village/usecase"
|
||||
|
||||
"github.com/go-pg/pg/v10"
|
||||
"github.com/joho/godotenv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func init() {
|
||||
os.Setenv("TZ", "UTC")
|
||||
|
||||
if mode.Get() == mode.DevelopmentMode {
|
||||
godotenv.Load(".env.development")
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
db := pg.Connect(&pg.Options{
|
||||
User: os.Getenv("DB_USER"),
|
||||
Password: os.Getenv("DB_PASSWORD"),
|
||||
Database: os.Getenv("DB_NAME"),
|
||||
Addr: os.Getenv("DB_HOST") + ":" + os.Getenv("DB_PORT"),
|
||||
})
|
||||
defer func() {
|
||||
if err := db.Close(); err != nil {
|
||||
log.Fatal("Database disconnecting:", err)
|
||||
}
|
||||
}()
|
||||
|
||||
langversionRepo, err := langversionrepo.NewPGRepository(db)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
serverRepo, err := serverrepo.NewPGRepository(db)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
tribeRepo := triberepo.NewPGRepository(db)
|
||||
playerRepo := playerrepo.NewPGRepository(db)
|
||||
villageRepo := villagerepo.NewPGRepository(db)
|
||||
|
||||
router := gin.Default()
|
||||
v1 := router.Group("")
|
||||
v1.Use(middleware.DataLoadersToContext(serverRepo, dataloaders.Config{
|
||||
PlayerRepo: playerRepo,
|
||||
TribeRepo: tribeRepo,
|
||||
}))
|
||||
httpdelivery.Attach(v1, &resolvers.Resolver{
|
||||
LangVersionUcase: langversionucase.New(langversionRepo),
|
||||
ServerUcase: serverucase.New(serverRepo),
|
||||
TribeUcase: tribeucase.New(tribeRepo),
|
||||
PlayerUcase: playerucase.New(playerRepo),
|
||||
VillageUcase: villageucase.New(villageRepo),
|
||||
})
|
||||
|
||||
srv := &http.Server{
|
||||
Addr: ":8080",
|
||||
Handler: router,
|
||||
}
|
||||
|
||||
go func() {
|
||||
// service connections
|
||||
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||
log.Fatalf("listen: %s\n", err)
|
||||
}
|
||||
}()
|
||||
|
||||
quit := make(chan os.Signal)
|
||||
signal.Notify(quit, os.Interrupt)
|
||||
<-quit
|
||||
log.Println("Shutdown Server ...")
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
if err := srv.Shutdown(ctx); err != nil {
|
||||
log.Fatal("Server Shutdown:", err)
|
||||
}
|
||||
log.Println("Server exiting")
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
package middleware
|
||||
|
||||
type ContextKey string
|
|
@ -0,0 +1,48 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/vektah/gqlparser/v2/gqlerror"
|
||||
|
||||
"github.com/tribalwarshelp/api/graphql/dataloaders"
|
||||
"github.com/tribalwarshelp/api/server"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
var DataloadersContextKey ContextKey = "dataloaders"
|
||||
|
||||
func DataLoadersToContext(serverRepo server.Repository, cfg dataloaders.Config) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
ctx := c.Request.Context()
|
||||
loaders := make(map[string]*dataloaders.DataLoaders)
|
||||
servers, _, err := serverRepo.Fetch(c.Request.Context(), nil)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusOK, &gqlerror.Error{
|
||||
Message: err.Error(),
|
||||
})
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
for _, server := range servers {
|
||||
loaders[server.Key] = dataloaders.New(server.Key, cfg)
|
||||
}
|
||||
c.Request = c.Request.WithContext(StoreDataLoadersInContext(ctx, loaders))
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
func StoreDataLoadersInContext(ctx context.Context, loaders map[string]*dataloaders.DataLoaders) context.Context {
|
||||
return context.WithValue(ctx, DataloadersContextKey, loaders)
|
||||
}
|
||||
|
||||
func DataLoadersFromContext(ctx context.Context) map[string]*dataloaders.DataLoaders {
|
||||
dl := ctx.Value(DataloadersContextKey)
|
||||
if dl == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return dl.(map[string]*dataloaders.DataLoaders)
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package player
|
||||
|
||||
const (
|
||||
PaginationLimit = 100
|
||||
)
|
|
@ -0,0 +1,11 @@
|
|||
package player
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/tribalwarshelp/shared/models"
|
||||
)
|
||||
|
||||
type Repository interface {
|
||||
Fetch(ctx context.Context, server string, filter *models.PlayerFilter) ([]*models.Player, int, error)
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/go-pg/pg/v10"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/tribalwarshelp/api/player"
|
||||
"github.com/tribalwarshelp/shared/models"
|
||||
)
|
||||
|
||||
type pgRepository struct {
|
||||
*pg.DB
|
||||
}
|
||||
|
||||
func NewPGRepository(db *pg.DB) player.Repository {
|
||||
return &pgRepository{db}
|
||||
}
|
||||
|
||||
func (repo *pgRepository) Fetch(ctx context.Context, server string, f *models.PlayerFilter) ([]*models.Player, int, error) {
|
||||
var err error
|
||||
data := []*models.Player{}
|
||||
query := repo.WithParam("SERVER", pg.Safe(server)).Model(&data).Context(ctx)
|
||||
|
||||
if f != nil {
|
||||
query = query.
|
||||
WhereStruct(f).
|
||||
Limit(f.Limit).
|
||||
Offset(f.Offset)
|
||||
|
||||
if f.Sort != "" {
|
||||
query = query.Order(f.Sort)
|
||||
}
|
||||
}
|
||||
|
||||
total, err := query.SelectAndCount()
|
||||
if err != nil && err != pg.ErrNoRows {
|
||||
if strings.Contains(err.Error(), `relation "`+server) {
|
||||
return nil, 0, fmt.Errorf("Server not found")
|
||||
}
|
||||
return nil, 0, errors.Wrap(err, "Internal server error")
|
||||
}
|
||||
|
||||
return data, total, nil
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package player
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/tribalwarshelp/shared/models"
|
||||
)
|
||||
|
||||
type Usecase interface {
|
||||
Fetch(ctx context.Context, server string, filter *models.PlayerFilter) ([]*models.Player, int, error)
|
||||
GetByID(ctx context.Context, server string, id int) (*models.Player, error)
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package usecase
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/tribalwarshelp/api/player"
|
||||
"github.com/tribalwarshelp/shared/models"
|
||||
)
|
||||
|
||||
type usecase struct {
|
||||
repo player.Repository
|
||||
}
|
||||
|
||||
func New(repo player.Repository) player.Usecase {
|
||||
return &usecase{repo}
|
||||
}
|
||||
|
||||
func (ucase *usecase) Fetch(ctx context.Context, server string, filter *models.PlayerFilter) ([]*models.Player, int, error) {
|
||||
if filter == nil {
|
||||
filter = &models.PlayerFilter{}
|
||||
}
|
||||
if filter.Limit > player.PaginationLimit || filter.Limit <= 0 {
|
||||
filter.Limit = player.PaginationLimit
|
||||
}
|
||||
return ucase.repo.Fetch(ctx, server, filter)
|
||||
}
|
||||
|
||||
func (ucase *usecase) GetByID(ctx context.Context, server string, id int) (*models.Player, error) {
|
||||
players, total, err := ucase.repo.Fetch(ctx, server, &models.PlayerFilter{
|
||||
ID: []int{id},
|
||||
Limit: 1,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if total == 0 {
|
||||
return nil, fmt.Errorf("Player with id: %d not found.", id)
|
||||
}
|
||||
return players[0], nil
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package server
|
||||
|
||||
const (
|
||||
PaginationLimit = 100
|
||||
)
|
|
@ -0,0 +1,11 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/tribalwarshelp/shared/models"
|
||||
)
|
||||
|
||||
type Repository interface {
|
||||
Fetch(ctx context.Context, filter *models.ServerFilter) ([]*models.Server, int, error)
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/go-pg/pg/v10"
|
||||
"github.com/go-pg/pg/v10/orm"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/tribalwarshelp/api/server"
|
||||
"github.com/tribalwarshelp/shared/models"
|
||||
)
|
||||
|
||||
type pgRepository struct {
|
||||
*pg.DB
|
||||
}
|
||||
|
||||
func NewPGRepository(db *pg.DB) (server.Repository, error) {
|
||||
if err := db.CreateTable((*models.Server)(nil), &orm.CreateTableOptions{
|
||||
IfNotExists: true,
|
||||
}); err != nil {
|
||||
return nil, errors.Wrap(err, "Cannot create 'servers' table")
|
||||
}
|
||||
return &pgRepository{db}, nil
|
||||
}
|
||||
|
||||
func (repo *pgRepository) Fetch(ctx context.Context, f *models.ServerFilter) ([]*models.Server, int, error) {
|
||||
var err error
|
||||
data := []*models.Server{}
|
||||
query := repo.Model(&data).Context(ctx)
|
||||
|
||||
if f != nil {
|
||||
query = query.
|
||||
WhereStruct(f).
|
||||
Limit(f.Limit).
|
||||
Offset(f.Offset)
|
||||
|
||||
if f.Sort != "" {
|
||||
query = query.Order(f.Sort)
|
||||
}
|
||||
}
|
||||
|
||||
total, err := query.SelectAndCount()
|
||||
if err != nil && err != pg.ErrNoRows {
|
||||
return nil, 0, errors.Wrap(err, "Internal server error")
|
||||
}
|
||||
|
||||
return data, total, nil
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/tribalwarshelp/shared/models"
|
||||
)
|
||||
|
||||
type Usecase interface {
|
||||
Fetch(ctx context.Context, filter *models.ServerFilter) ([]*models.Server, int, error)
|
||||
GetByKey(ctx context.Context, key string) (*models.Server, error)
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package usecase
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/tribalwarshelp/api/server"
|
||||
"github.com/tribalwarshelp/shared/models"
|
||||
)
|
||||
|
||||
type usecase struct {
|
||||
repo server.Repository
|
||||
}
|
||||
|
||||
func New(repo server.Repository) server.Usecase {
|
||||
return &usecase{repo}
|
||||
}
|
||||
|
||||
func (ucase *usecase) Fetch(ctx context.Context, filter *models.ServerFilter) ([]*models.Server, int, error) {
|
||||
if filter == nil {
|
||||
filter = &models.ServerFilter{}
|
||||
}
|
||||
if filter.Limit > server.PaginationLimit || filter.Limit <= 0 {
|
||||
filter.Limit = server.PaginationLimit
|
||||
}
|
||||
return ucase.repo.Fetch(ctx, filter)
|
||||
}
|
||||
|
||||
func (ucase *usecase) GetByKey(ctx context.Context, key string) (*models.Server, error) {
|
||||
servers, total, err := ucase.repo.Fetch(ctx, &models.ServerFilter{
|
||||
Key: []string{key},
|
||||
Limit: 1,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if total == 0 {
|
||||
return nil, fmt.Errorf("Server with key: %s not found.", key)
|
||||
}
|
||||
return servers[0], nil
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package tribe
|
||||
|
||||
const (
|
||||
PaginationLimit = 100
|
||||
)
|
|
@ -0,0 +1,11 @@
|
|||
package tribe
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/tribalwarshelp/shared/models"
|
||||
)
|
||||
|
||||
type Repository interface {
|
||||
Fetch(ctx context.Context, server string, filter *models.TribeFilter) ([]*models.Tribe, int, error)
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/go-pg/pg/v10"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/tribalwarshelp/api/tribe"
|
||||
"github.com/tribalwarshelp/shared/models"
|
||||
)
|
||||
|
||||
type pgRepository struct {
|
||||
*pg.DB
|
||||
}
|
||||
|
||||
func NewPGRepository(db *pg.DB) tribe.Repository {
|
||||
return &pgRepository{db}
|
||||
}
|
||||
|
||||
func (repo *pgRepository) Fetch(ctx context.Context, server string, f *models.TribeFilter) ([]*models.Tribe, int, error) {
|
||||
var err error
|
||||
data := []*models.Tribe{}
|
||||
query := repo.WithParam("SERVER", pg.Safe(server)).Model(&data).Context(ctx)
|
||||
|
||||
if f != nil {
|
||||
query = query.
|
||||
WhereStruct(f).
|
||||
Limit(f.Limit).
|
||||
Offset(f.Offset)
|
||||
|
||||
if f.Sort != "" {
|
||||
query = query.Order(f.Sort)
|
||||
}
|
||||
}
|
||||
|
||||
total, err := query.SelectAndCount()
|
||||
if err != nil && err != pg.ErrNoRows {
|
||||
if strings.Contains(err.Error(), `relation "`+server) {
|
||||
return nil, 0, fmt.Errorf("Server not found")
|
||||
}
|
||||
return nil, 0, errors.Wrap(err, "Internal server error")
|
||||
}
|
||||
|
||||
return data, total, nil
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package tribe
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/tribalwarshelp/shared/models"
|
||||
)
|
||||
|
||||
type Usecase interface {
|
||||
Fetch(ctx context.Context, server string, filter *models.TribeFilter) ([]*models.Tribe, int, error)
|
||||
GetByID(ctx context.Context, server string, id int) (*models.Tribe, error)
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package usecase
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/tribalwarshelp/api/tribe"
|
||||
"github.com/tribalwarshelp/shared/models"
|
||||
)
|
||||
|
||||
type usecase struct {
|
||||
repo tribe.Repository
|
||||
}
|
||||
|
||||
func New(repo tribe.Repository) tribe.Usecase {
|
||||
return &usecase{repo}
|
||||
}
|
||||
|
||||
func (ucase *usecase) Fetch(ctx context.Context, server string, filter *models.TribeFilter) ([]*models.Tribe, int, error) {
|
||||
if filter == nil {
|
||||
filter = &models.TribeFilter{}
|
||||
}
|
||||
if filter.Limit > tribe.PaginationLimit || filter.Limit <= 0 {
|
||||
filter.Limit = tribe.PaginationLimit
|
||||
}
|
||||
return ucase.repo.Fetch(ctx, server, filter)
|
||||
}
|
||||
|
||||
func (ucase *usecase) GetByID(ctx context.Context, server string, id int) (*models.Tribe, error) {
|
||||
tribes, total, err := ucase.repo.Fetch(ctx, server, &models.TribeFilter{
|
||||
ID: []int{id},
|
||||
Limit: 1,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if total == 0 {
|
||||
return nil, fmt.Errorf("Tribe with id: %d not found.", id)
|
||||
}
|
||||
return tribes[0], nil
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package village
|
||||
|
||||
const (
|
||||
PaginationLimit = 100
|
||||
)
|
|
@ -0,0 +1,11 @@
|
|||
package village
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/tribalwarshelp/shared/models"
|
||||
)
|
||||
|
||||
type Repository interface {
|
||||
Fetch(ctx context.Context, server string, filter *models.VillageFilter) ([]*models.Village, int, error)
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/go-pg/pg/v10"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/tribalwarshelp/api/village"
|
||||
"github.com/tribalwarshelp/shared/models"
|
||||
)
|
||||
|
||||
type pgRepository struct {
|
||||
*pg.DB
|
||||
}
|
||||
|
||||
func NewPGRepository(db *pg.DB) village.Repository {
|
||||
return &pgRepository{db}
|
||||
}
|
||||
|
||||
func (repo *pgRepository) Fetch(ctx context.Context, server string, f *models.VillageFilter) ([]*models.Village, int, error) {
|
||||
var err error
|
||||
data := []*models.Village{}
|
||||
query := repo.WithParam("SERVER", pg.Safe(server)).Model(&data).Context(ctx)
|
||||
|
||||
if f != nil {
|
||||
query = query.
|
||||
WhereStruct(f).
|
||||
Limit(f.Limit).
|
||||
Offset(f.Offset)
|
||||
|
||||
if f.Sort != "" {
|
||||
query = query.Order(f.Sort)
|
||||
}
|
||||
}
|
||||
|
||||
total, err := query.SelectAndCount()
|
||||
if err != nil && err != pg.ErrNoRows {
|
||||
if strings.Contains(err.Error(), `relation "`+server) {
|
||||
return nil, 0, fmt.Errorf("Server not found")
|
||||
}
|
||||
return nil, 0, errors.Wrap(err, "Internal server error")
|
||||
}
|
||||
|
||||
return data, total, nil
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package village
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/tribalwarshelp/shared/models"
|
||||
)
|
||||
|
||||
type Usecase interface {
|
||||
Fetch(ctx context.Context, server string, filter *models.VillageFilter) ([]*models.Village, int, error)
|
||||
GetByID(ctx context.Context, server string, id int) (*models.Village, error)
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package usecase
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/tribalwarshelp/api/village"
|
||||
"github.com/tribalwarshelp/shared/models"
|
||||
)
|
||||
|
||||
type usecase struct {
|
||||
repo village.Repository
|
||||
}
|
||||
|
||||
func New(repo village.Repository) village.Usecase {
|
||||
return &usecase{repo}
|
||||
}
|
||||
|
||||
func (ucase *usecase) Fetch(ctx context.Context, server string, filter *models.VillageFilter) ([]*models.Village, int, error) {
|
||||
if filter == nil {
|
||||
filter = &models.VillageFilter{}
|
||||
}
|
||||
if filter.Limit > village.PaginationLimit || filter.Limit <= 0 {
|
||||
filter.Limit = village.PaginationLimit
|
||||
}
|
||||
return ucase.repo.Fetch(ctx, server, filter)
|
||||
}
|
||||
|
||||
func (ucase *usecase) GetByID(ctx context.Context, server string, id int) (*models.Village, error) {
|
||||
villages, total, err := ucase.repo.Fetch(ctx, server, &models.VillageFilter{
|
||||
ID: []int{id},
|
||||
Limit: 1,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if total == 0 {
|
||||
return nil, fmt.Errorf("Village with id: %d not found.", id)
|
||||
}
|
||||
return villages[0], nil
|
||||
}
|
Reference in New Issue