mirror of
https://github.com/3ybactuk/marketplace-go-service-project.git
synced 2025-10-30 05:53:45 +03:00
Merge branch 'hw-4' into 'master'
[hw-4] add postgres db See merge request nvshubin1/homework!4
This commit is contained in:
3
Makefile
3
Makefile
@@ -2,6 +2,7 @@ include make/lint.mk
|
||||
include make/build.mk
|
||||
include make/coverage.mk
|
||||
include make/generate.mk
|
||||
include make/bin-deps.mk
|
||||
|
||||
PKGS = $(shell go list ./... | grep -vE 'mock|config|generated|header|document|internal/pb')
|
||||
INTEGRATION_TAG = integration
|
||||
@@ -24,7 +25,7 @@ run-all:
|
||||
.PHONY: .integration-test
|
||||
integration-test:
|
||||
ALLURE_OUTPUT_PATH=$(shell pwd)/allure-results ALLURE_OUTPUT_FOLDER=cart go test -v -tags=$(INTEGRATION_TAG) ./cart/tests/integration
|
||||
ALLURE_OUTPUT_PATH=$(shell pwd)/allure-results ALLURE_OUTPUT_FOLDER=loms go test -v -tags=$(INTEGRATION_TAG) ./loms/tests/integration
|
||||
CGO_ENABLED=0 ALLURE_OUTPUT_PATH=$(shell pwd)/allure-results ALLURE_OUTPUT_FOLDER=loms go test -v -tags=$(INTEGRATION_TAG) ./loms/tests/integration
|
||||
|
||||
bench:
|
||||
go test -bench=BenchmarkInMemoryRepository -benchmem ./cart/internal/domain/cart/repository -benchtime 3s
|
||||
|
||||
@@ -8,6 +8,7 @@ bindir:
|
||||
|
||||
build: bindir
|
||||
echo "build cart"
|
||||
go build -o ${BINDIR}/cart cmd/server/main.go
|
||||
|
||||
coverage:
|
||||
@go test -race -coverprofile=coverage.txt -covermode=atomic $(PKGS)
|
||||
|
||||
49
cart/go.mod
49
cart/go.mod
@@ -10,58 +10,17 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
dario.cat/mergo v1.0.1 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
|
||||
github.com/containerd/log v0.1.0 // indirect
|
||||
github.com/containerd/platforms v0.2.1 // indirect
|
||||
github.com/cpuguy83/dockercfg v0.3.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/distribution/reference v0.6.0 // indirect
|
||||
github.com/docker/docker v28.0.1+incompatible // indirect
|
||||
github.com/docker/go-connections v0.5.0 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/ebitengine/purego v0.8.2 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/klauspost/compress v1.17.4 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/kr/pretty v0.3.1 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
||||
github.com/magiconair/properties v1.8.10 // indirect
|
||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||
github.com/moby/patternmatcher v0.6.0 // indirect
|
||||
github.com/moby/sys/sequential v0.5.0 // indirect
|
||||
github.com/moby/sys/user v0.1.0 // indirect
|
||||
github.com/moby/sys/userns v0.1.0 // indirect
|
||||
github.com/moby/term v0.5.0 // indirect
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.1 // indirect
|
||||
github.com/ozontech/allure-go/pkg/allure v0.6.14 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
github.com/shirou/gopsutil/v4 v4.25.1 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
||||
github.com/tklauser/numcpus v0.6.1 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
|
||||
github.com/rogpeppe/go-internal v1.13.1 // indirect
|
||||
go.opentelemetry.io/otel v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.36.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.6.0 // indirect
|
||||
golang.org/x/crypto v0.37.0 // indirect
|
||||
golang.org/x/net v0.39.0 // indirect
|
||||
golang.org/x/text v0.24.0 // indirect
|
||||
@@ -74,7 +33,5 @@ require (
|
||||
github.com/gojuno/minimock/v3 v3.4.5
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/ozontech/allure-go/pkg/framework v0.6.34
|
||||
github.com/testcontainers/testcontainers-go v0.37.0
|
||||
golang.org/x/sys v0.33.0 // indirect
|
||||
)
|
||||
|
||||
141
cart/go.sum
141
cart/go.sum
@@ -1,46 +1,13 @@
|
||||
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
|
||||
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
|
||||
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
|
||||
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
|
||||
github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A=
|
||||
github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/cpuguy83/dockercfg v0.3.2 h1:DlJTyZGBDlXqUZ2Dk2Q3xHs/FtnooJJVaad2S9GKorA=
|
||||
github.com/cpuguy83/dockercfg v0.3.2/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc=
|
||||
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
||||
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
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/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
|
||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/docker/docker v28.0.1+incompatible h1:FCHjSRdXhNRFjlHMTv4jUNlIBbTeRjrWfeFuJp7jpo0=
|
||||
github.com/docker/docker v28.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
|
||||
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
|
||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/ebitengine/purego v0.8.2 h1:jPPGWs2sZ1UgOSgD2bClL0MJIqu58nOmIcBuXr62z1I=
|
||||
github.com/ebitengine/purego v0.8.2/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
|
||||
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
@@ -50,101 +17,41 @@ github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91
|
||||
github.com/go-playground/validator/v10 v10.26.0 h1:SP05Nqhjcvz81uJaRfEV0YBSSSGMc/iMaVtFbr3Sw2k=
|
||||
github.com/go-playground/validator/v10 v10.26.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/gojuno/minimock/v3 v3.4.5 h1:Jcb0tEYZvVlQNtAAYpg3jCOoSwss2c1/rNugYTzj304=
|
||||
github.com/gojuno/minimock/v3 v3.4.5/go.mod h1:o9F8i2IT8v3yirA7mmdpNGzh1WNesm6iQakMtQV6KiE=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4=
|
||||
github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
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.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||
github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE=
|
||||
github.com/magiconair/properties v1.8.10/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
|
||||
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
|
||||
github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk=
|
||||
github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
|
||||
github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc=
|
||||
github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo=
|
||||
github.com/moby/sys/user v0.1.0 h1:WmZ93f5Ux6het5iituh9x2zAG7NFY9Aqi49jjE1PaQg=
|
||||
github.com/moby/sys/user v0.1.0/go.mod h1:fKJhFOnsCN6xZ5gSfbM6zaHGgDJMrqt9/reuj4T7MmU=
|
||||
github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g=
|
||||
github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28=
|
||||
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
|
||||
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
|
||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
|
||||
github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
|
||||
github.com/ozontech/allure-go/pkg/allure v0.6.14 h1:lDamtSF+WtHQLg2+qQYijtC4Fk3KLGb6txNxxTZwUGc=
|
||||
github.com/ozontech/allure-go/pkg/allure v0.6.14/go.mod h1:4oEG2yq+DGOzJS/ZjPc87C/mx3tAnlYpYonk77Ru/vQ=
|
||||
github.com/ozontech/allure-go/pkg/framework v0.6.34 h1:IjM65Y3JP7ale7Ug3aBnFV4+c1NYYBCrgl/VrtEd/FY=
|
||||
github.com/ozontech/allure-go/pkg/framework v0.6.34/go.mod h1:oISDLE6Tfww35TBQz+1nrtbLtyBqR6ELxOtJ+MVjHOw=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
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/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
|
||||
github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY=
|
||||
github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ=
|
||||
github.com/shirou/gopsutil/v4 v4.25.1 h1:QSWkTc+fu9LTAWfkZwZ6j8MSUk4A2LV7rbH0ZqmLjXs=
|
||||
github.com/shirou/gopsutil/v4 v4.25.1/go.mod h1:RoUCUpndaJFtT+2zsZzzmhvbfGoDCJ7nFXKJf8GqJbI=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/testcontainers/testcontainers-go v0.37.0 h1:L2Qc0vkTw2EHWQ08djon0D2uw7Z/PtHS/QzZZ5Ra/hg=
|
||||
github.com/testcontainers/testcontainers-go v0.37.0/go.mod h1:QPzbxZhQ6Bclip9igjLFj6z0hs01bU8lrl2dHQmgFGM=
|
||||
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
|
||||
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
|
||||
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
|
||||
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
||||
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=
|
||||
go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=
|
||||
go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0 h1:dNzwXjZKpMpE2JhmO+9HsPl42NIXFIFSUSSs0fiqra0=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0/go.mod h1:90PoxvaEB5n6AOdZvi+yWJQoE95U8Dhhw2bSyRqnTD0=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU=
|
||||
go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=
|
||||
go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=
|
||||
go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs=
|
||||
@@ -153,56 +60,17 @@ go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce
|
||||
go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
|
||||
go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=
|
||||
go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=
|
||||
go.opentelemetry.io/proto/otlp v1.6.0 h1:jQjP+AQyTf+Fe7OKj/MfkDrmK4MNVtw2NpXsf9fefDI=
|
||||
go.opentelemetry.io/proto/otlp v1.6.0/go.mod h1:cicgGehlFuNdgZkcALOCh3VE6K/u2tAjzlRhDwmVpZc=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
|
||||
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
|
||||
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/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
|
||||
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o=
|
||||
golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
|
||||
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
|
||||
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44=
|
||||
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250428153025-10db94c68c34 h1:0PeQib/pH3nB/5pEmFeVQJotzGohV0dq4Vcp09H5yhE=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250428153025-10db94c68c34/go.mod h1:0awUlEkap+Pb1UMeJwJQQAdJQrt3moU7J2moTy69irI=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a h1:v2PbRU4K3llS09c7zodFpNePeamkAwG3mPrAery9VeE=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
|
||||
google.golang.org/grpc v1.72.0 h1:S7UkcVa60b5AAQTaO6ZKamFp1zMZSU0fGDK2WZLbBnM=
|
||||
@@ -212,8 +80,5 @@ google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
|
||||
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// Code generated by http://github.com/gojuno/minimock (v3.4.5). DO NOT EDIT.
|
||||
// Code generated by http://github.com/gojuno/minimock (v3.4.0). DO NOT EDIT.
|
||||
|
||||
package mock
|
||||
|
||||
//go:generate minimock -i route256/cart/internal/domain/cart/service.Repository -o repository_mock.go -n RepositoryMock -p mock
|
||||
//go:generate minimock -i route256/cart/internal/domain/service.Repository -o repository_mock.go -n RepositoryMock -p mock
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
@@ -19,9 +19,9 @@ import (
|
||||
"github.com/testcontainers/testcontainers-go/wait"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
lomsService "route256/cart/internal/adapter/client/loms"
|
||||
productsService "route256/cart/internal/adapter/client/products"
|
||||
"route256/cart/internal/app"
|
||||
lomsService "route256/cart/internal/clients/loms"
|
||||
productsService "route256/cart/internal/clients/products"
|
||||
"route256/cart/internal/domain/entity"
|
||||
"route256/cart/internal/domain/model"
|
||||
"route256/cart/internal/domain/repository"
|
||||
|
||||
@@ -17,7 +17,43 @@ services:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: loms/Dockerfile
|
||||
depends_on:
|
||||
- postgres-master
|
||||
ports:
|
||||
- "8083:8083"
|
||||
- "8084:8084"
|
||||
- "8085:8085"
|
||||
|
||||
postgres-master:
|
||||
image: gitlab-registry.ozon.dev/go/classroom-18/students/base/postgres:16
|
||||
container_name: postgres-master
|
||||
environment:
|
||||
- POSTGRESQL_USERNAME=user
|
||||
- POSTGRESQL_PASSWORD=password
|
||||
- POSTGRESQL_DATABASE=route256
|
||||
- POSTGRESQL_REPLICATION_MODE=master
|
||||
- POSTGRESQL_REPLICATION_USER=repl_user
|
||||
- POSTGRESQL_REPLICATION_PASSWORD=repl_password
|
||||
- POSTGRESQL_SYNCHRONOUS_COMMIT_MODE=on
|
||||
- POSTGRESQL_NUM_SYNCHRONOUS_REPLICAS=1
|
||||
ports:
|
||||
- "5433:5432"
|
||||
|
||||
postgres-replica:
|
||||
image: gitlab-registry.ozon.dev/go/classroom-18/students/base/postgres:16
|
||||
container_name: postgres-replica
|
||||
depends_on:
|
||||
- postgres-master
|
||||
environment:
|
||||
- POSTGRESQL_DATABASE=route256
|
||||
- POSTGRESQL_USERNAME=user
|
||||
- POSTGRESQL_PASSWORD=password
|
||||
- POSTGRESQL_REPLICATION_MODE=slave
|
||||
- POSTGRESQL_REPLICATION_USER=repl_user
|
||||
- POSTGRESQL_REPLICATION_PASSWORD=repl_password
|
||||
- POSTGRESQL_MASTER_HOST=postgres-master
|
||||
- POSTGRESQL_MASTER_PORT_NUMBER=5432
|
||||
- POSTGRESQL_SYNCHRONOUS_COMMIT_MODE=on
|
||||
- POSTGRESQL_NUM_SYNCHRONOUS_REPLICAS=1
|
||||
ports:
|
||||
- "5434:5432"
|
||||
|
||||
@@ -17,3 +17,4 @@
|
||||
1. [Основы Go](./homework-1)
|
||||
2. [Тестирование в Go](./homework-2)
|
||||
3. [Межсервисное взаимодействие и основы эксплуатации](./homework-3)
|
||||
4. [Базы данных](./homework-4)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
### create normal order
|
||||
POST http://localhost:8084/order/create
|
||||
POST http://192.168.64.4:8084/order/create
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
@@ -19,14 +19,14 @@ Content-Type: application/json
|
||||
|
||||
|
||||
### get info, assert status="awaiting payment"
|
||||
GET http://localhost:8084/order/info?orderId=1
|
||||
GET http://192.168.64.4:8084/order/info?orderId=1
|
||||
Content-Type: application/json
|
||||
|
||||
### expected: 200 (OK) {"status":"awaiting payment","user":31337,"Items":[{"sku":1076963,"count":3},{"sku":135717466,"count":2}]}
|
||||
|
||||
|
||||
### pay order
|
||||
POST http://localhost:8084/order/pay
|
||||
POST http://192.168.64.4:8084/order/pay
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
@@ -36,14 +36,14 @@ Content-Type: application/json
|
||||
|
||||
|
||||
### check actual status is "payed"
|
||||
GET http://localhost:8084/order/info?orderId=1
|
||||
GET http://192.168.64.4:8084/order/info?orderId=1
|
||||
Content-Type: application/json
|
||||
|
||||
### expected: 200 (OK) {"status":"payed","user":31337,"Items":[{"sku":1076963,"count":3},{"sku":135717466,"count":2}]}
|
||||
|
||||
|
||||
### unable to cancel payed order
|
||||
POST http://localhost:8084/order/cancel
|
||||
POST http://192.168.64.4:8084/order/cancel
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
@@ -53,14 +53,14 @@ Content-Type: application/json
|
||||
|
||||
|
||||
### get unknown order
|
||||
GET http://localhost:8084/order/info?orderId=404
|
||||
GET http://192.168.64.4:8084/order/info?orderId=404
|
||||
Content-Type: application/json
|
||||
|
||||
### expected: 404 (Not Found) {"code": 5, ... }
|
||||
|
||||
|
||||
### cancel order not exists
|
||||
POST http://localhost:8084/order/cancel
|
||||
POST http://192.168.64.4:8084/order/cancel
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
@@ -70,7 +70,7 @@ Content-Type: application/json
|
||||
|
||||
|
||||
### create order with item that has no stocks info
|
||||
POST http://localhost:8084/order/create
|
||||
POST http://192.168.64.4:8084/order/create
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
@@ -86,13 +86,13 @@ Content-Type: application/json
|
||||
|
||||
|
||||
### check order status is failed (not necessary, because no orderId after creation if any fails)
|
||||
GET http://localhost:8084/order/info?orderId=2
|
||||
GET http://192.168.64.4:8084/order/info?orderId=2
|
||||
Content-Type: application/json
|
||||
|
||||
### expected: 200 (OK) {"status":"failed","userId":31337,"Items":[{"sku":404,"count":3}]}
|
||||
|
||||
### cancel failed order
|
||||
POST http://localhost:8084/order/cancel
|
||||
POST http://192.168.64.4:8084/order/cancel
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
@@ -102,21 +102,21 @@ Content-Type: application/json
|
||||
|
||||
|
||||
### stock info for unknown sku
|
||||
GET http://localhost:8084/stock/info?sku=404
|
||||
GET http://192.168.64.4:8084/stock/info?sku=404
|
||||
Content-Type: application/json
|
||||
|
||||
### expected: 404 Not Found {"code":5, ... }
|
||||
|
||||
|
||||
### stock info for normal sku
|
||||
GET http://localhost:8084/stock/info?sku=135717466
|
||||
GET http://192.168.64.4:8084/stock/info?sku=135717466
|
||||
Content-Type: application/json
|
||||
|
||||
### expected: 200 (OK) {"count":78}
|
||||
|
||||
|
||||
### create order with count for sku more than stock
|
||||
POST http://localhost:8084/order/create
|
||||
POST http://192.168.64.4:8084/order/create
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
@@ -131,13 +131,13 @@ Content-Type: application/json
|
||||
### expected: 400 (Bad Request) {"code":9, ... }
|
||||
|
||||
### no change in stock info after failed order creation
|
||||
GET http://localhost:8084/stock/info?sku=135717466
|
||||
GET http://192.168.64.4:8084/stock/info?sku=135717466
|
||||
Content-Type: application/json
|
||||
|
||||
### expected: 200 (OK) {"count":78}
|
||||
|
||||
### create normal order for cancellation
|
||||
POST http://localhost:8084/order/create
|
||||
POST http://192.168.64.4:8084/order/create
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
@@ -153,7 +153,7 @@ Content-Type: application/json
|
||||
|
||||
|
||||
### cancel order
|
||||
POST http://localhost:8084/order/cancel
|
||||
POST http://192.168.64.4:8084/order/cancel
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
@@ -163,14 +163,14 @@ Content-Type: application/json
|
||||
|
||||
|
||||
### check canceled order status
|
||||
GET http://localhost:8084/order/info?orderId=4
|
||||
GET http://192.168.64.4:8084/order/info?orderId=4
|
||||
Content-Type: application/json
|
||||
|
||||
### expected: {"status":"cancelled","user":31337,"Items":[{"sku":1076963,"count":2}]}
|
||||
|
||||
|
||||
### check stocks returns
|
||||
GET http://localhost:8084/stock/info?sku=135717466
|
||||
GET http://192.168.64.4:8084/stock/info?sku=135717466
|
||||
Content-Type: application/json
|
||||
|
||||
### expected: {"count":78}; 200 OK
|
||||
|
||||
33
docs/homework-4/README.md
Normal file
33
docs/homework-4/README.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# Домашнее задание по модулю "Базы данных"
|
||||
|
||||
Необходимо развернуть БД PostgreSQL для сервиса loms. Реализовать слой `Repository`, в котором будут походы в БД
|
||||
|
||||
## Основное задание
|
||||
|
||||
1. Для сервиса loms реализовать в слое `Repository` поход в БД
|
||||
2. Развернуть экземпляр БД PostgreSQL в отдельном контейнере
|
||||
3. Корректно использовать транзакции в операции создания заказа
|
||||
4. Реализовать автоматические миграции, накатывающие схему БД и/или тестовые данные
|
||||
5. SQL-код должен быть написан в виде raw. Без использования ORM или билдеров (можно sqlc)
|
||||
|
||||
## Дополнительное задание
|
||||
|
||||
1. Для БД поднять синхронную реплику. Балансировать read/write запросы между ними (write только в master, read в любую из реплик)
|
||||
2. Написать по одному интеграционному тесту на каждый SQL-запрос в репозитории сервиса loms. Не забыть накатывать тестовые данные в миграции, после прогона тестов - удалить данные из БД
|
||||
3. Реализовать SQL-запросы с помощью sqlc
|
||||
|
||||
## Автоматические проверки
|
||||
|
||||
Ваше решение должно проходить автоматические проверки:
|
||||
|
||||
- Компиляция
|
||||
- Линтер
|
||||
- Unit-тесты
|
||||
- Code coverage >40%
|
||||
- Автотесты
|
||||
|
||||
Прохождение автоматических проверок влияет на итоговую оценку за домашнюю работу.
|
||||
|
||||
### Дедлайны сдачи и проверки задания:
|
||||
|
||||
- 21 июня 23:59 (сдача) / 24 июня, 23:59 (проверка)
|
||||
36
go.work.sum
36
go.work.sum
@@ -1,32 +1,61 @@
|
||||
cel.dev/expr v0.23.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw=
|
||||
cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg=
|
||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
github.com/ClickHouse/ch-go v0.65.1/go.mod h1:bsodgURwmrkvkBe5jw1qnGDgyITsYErfONKAHn05nv4=
|
||||
github.com/ClickHouse/clickhouse-go/v2 v2.34.0/go.mod h1:yioSINoRLVZkLyDzdMXPLRIqhDvel8iLBlwh6Iefso8=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0/go.mod h1:yAZHSGnqScoU556rBOVkwLze6WP5N+U11RHuWaGVxwY=
|
||||
github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/coder/websocket v1.8.13/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs=
|
||||
github.com/ebitengine/purego v0.8.4 h1:CF7LEKg5FFOsASUj0+QwaXf8Ht6TlFxg09+S9wz0omw=
|
||||
github.com/ebitengine/purego v0.8.4/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
||||
github.com/elastic/go-sysinfo v1.15.3/go.mod h1:K/cNrqYTDrSoMh2oDkYEMS2+a72GRxMvNP+GC+vRIlo=
|
||||
github.com/elastic/go-windows v1.0.2/go.mod h1:bGcDpBzXgYSqM0Gx3DM4+UxFj300SZLixie9u9ixLM8=
|
||||
github.com/envoyproxy/go-control-plane v0.13.4/go.mod h1:kDfuBlDVsSj2MjrLEtRWtHlsWIFcGyB2RMO44Dc5GZA=
|
||||
github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw=
|
||||
github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4=
|
||||
github.com/go-faster/city v1.0.1/go.mod h1:jKcUJId49qdW3L1qKHH/3wPeUstCVpVSXTM6vO3VcTw=
|
||||
github.com/go-faster/errors v0.7.1/go.mod h1:5ySTjWFiphBs07IKuiL69nxdfd5+fzh1u7FPGZP2quo=
|
||||
github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA=
|
||||
github.com/go-sql-driver/mysql v1.9.2/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
|
||||
github.com/gofrs/uuid/v5 v5.3.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
|
||||
github.com/golang/glog v1.2.4/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/hexdigest/gowrap v1.4.2/go.mod h1:s+1hE6qakgdaaLqgdwPAj5qKYVBCSbPJhEbx+I1ef/Q=
|
||||
github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60=
|
||||
github.com/lyft/protoc-gen-star/v2 v2.0.4-0.20230330145011-496ad1ac90a4/go.mod h1:amey7yeodaJhXSbf/TlLvWiqQfLOSpEk//mLlc+axEk=
|
||||
github.com/mfridman/xflag v0.1.0/go.mod h1:/483ywM5ZO5SuMVjrIGquYNE5CzLrj5Ux/LxWWnjRaE=
|
||||
github.com/microsoft/go-mssqldb v1.8.0/go.mod h1:6znkekS3T2vp0waiMhen4GPU1BiAsrP+iXHcE7a7rFo=
|
||||
github.com/paulmach/orb v0.11.1/go.mod h1:5mULz1xQfs3bmQm63QEJA6lNGujuRafwA5S/EnuLaLU=
|
||||
github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
|
||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY=
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY=
|
||||
github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
|
||||
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
|
||||
github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
|
||||
github.com/spiffe/go-spiffe/v2 v2.5.0/go.mod h1:P+NxobPc6wXhVtINNtFjNWGBTreew1GBUCwT2wPmb7g=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/tursodatabase/libsql-client-go v0.0.0-20240902231107-85af5b9d094d/go.mod h1:l8xTsYB90uaVdMHXMCxKKLSgw5wLYBwBKKefNIUnm9s=
|
||||
github.com/vertica/vertica-sql-go v1.3.3/go.mod h1:jnn2GFuv+O2Jcjktb7zyc4Utlbu9YVqpHH/lx63+1M4=
|
||||
github.com/ydb-platform/ydb-go-genproto v0.0.0-20241112172322-ea1f63298f77/go.mod h1:Er+FePu1dNUieD+XTMDduGpQuCPssK5Q4BjF+IIXJ3I=
|
||||
github.com/ydb-platform/ydb-go-sdk/v3 v3.108.1/go.mod h1:l5sSv153E18VvYcsmr51hok9Sjc16tEC8AXGbwrk+ho=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/zeebo/errs v1.4.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4=
|
||||
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.35.0/go.mod h1:qGWP8/+ILwMRIUf9uIVLloR1uo5ZYAslM4O6OqUi1DA=
|
||||
go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
@@ -40,9 +69,7 @@ golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||
golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0=
|
||||
golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
|
||||
@@ -50,9 +77,12 @@ golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463/go.mod h1:U90ffi8eUL9MwPcrJylN5+Mk2v3vuPDptd5yyNUiRR8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a/go.mod h1:a77HrdMjoeKbnd2jmgcWdaS++ZLZAEq3orIOAEIKiVw=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
|
||||
google.golang.org/grpc v1.64.1/go.mod h1:hiQF4LFZelK2WKaP6W0L92zGHtiQdZxk8CrSdvyjeP0=
|
||||
google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
|
||||
google.golang.org/grpc v1.72.2/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=
|
||||
google.golang.org/grpc/examples v0.0.0-20230224211313-3775f633ce20/go.mod h1:Nr5H8+MlGWr5+xX/STzdoEqJrO+YteqFbMyCsrb6mH0=
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
howett.net/plist v1.0.1/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g=
|
||||
|
||||
@@ -1,11 +1,40 @@
|
||||
BINDIR=${CURDIR}/bin
|
||||
BINDIR=${CURDIR}/../bin
|
||||
PACKAGE=route256/loms
|
||||
MIGRATIONS_FOLDER := ./db/migrations/
|
||||
LOCAL_DB_NAME := route256
|
||||
LOCAL_DB_DSN := postgresql://user:password@192.168.64.4:5433/route256?sslmode=disable
|
||||
|
||||
PROD_USER := loms-user
|
||||
PROD_PASS := loms-password
|
||||
PROD_DB := postgres-master
|
||||
|
||||
PROD_MIGRATIONS := ./loms/db/migrations/
|
||||
|
||||
bindir:
|
||||
mkdir -p ${BINDIR}
|
||||
|
||||
build: bindir
|
||||
echo "build loms"
|
||||
go build -o ${BINDIR}/loms cmd/server/main.go
|
||||
|
||||
# Used for CI
|
||||
run-migrations:
|
||||
echo "run migrations"
|
||||
$(GOOSE) -dir $(PROD_MIGRATIONS) postgres "postgresql://$(PROD_USER):$(PROD_PASS)@$(PROD_DB):5432/loms_db?sslmode=disable" up
|
||||
|
||||
db-create-migration:
|
||||
$(BINDIR)/goose -dir $(MIGRATIONS_FOLDER) create -s $(n) sql
|
||||
|
||||
db-migrate:
|
||||
$(BINDIR)/goose -dir $(MIGRATIONS_FOLDER) postgres "$(LOCAL_DB_DSN)" up
|
||||
|
||||
db-migrate-down:
|
||||
$(BINDIR)/goose -dir $(MIGRATIONS_FOLDER) postgres "$(LOCAL_DB_DSN)" down
|
||||
|
||||
db-reset-local:
|
||||
psql -c "drop database if exists \"$(LOCAL_DB_NAME)\""
|
||||
psql -c "create database \"$(LOCAL_DB_NAME)\""
|
||||
make db-migrate
|
||||
|
||||
.PHONY: generate-sqlc
|
||||
generate-sqlc:
|
||||
$(BINDIR)/sqlc generate
|
||||
|
||||
@@ -9,18 +9,18 @@ jaeger:
|
||||
port: 6831
|
||||
|
||||
db_master:
|
||||
host: localhost
|
||||
host: postgres-master
|
||||
port: 5432
|
||||
user: loms-user
|
||||
password: loms-password
|
||||
db_name: loms_db
|
||||
user: user
|
||||
password: password
|
||||
db_name: route256
|
||||
|
||||
db_replica:
|
||||
host: localhost
|
||||
port: 5433
|
||||
user: loms-user
|
||||
password: loms-password
|
||||
db_name: loms_db
|
||||
host: postgres-replica
|
||||
port: 5432
|
||||
user: user
|
||||
password: password
|
||||
db_name: route256
|
||||
|
||||
kafka:
|
||||
host: localhost
|
||||
|
||||
20
loms/db/migrations/00001_create_orders.sql
Normal file
20
loms/db/migrations/00001_create_orders.sql
Normal file
@@ -0,0 +1,20 @@
|
||||
-- +goose Up
|
||||
CREATE TABLE
|
||||
orders (
|
||||
id bigserial PRIMARY KEY,
|
||||
status_name TEXT NOT NULL DEFAULT '',
|
||||
user_id BIGINT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE
|
||||
order_items (
|
||||
id bigserial PRIMARY KEY,
|
||||
order_id BIGINT NOT NULL REFERENCES orders (id) ON DELETE CASCADE,
|
||||
sku BIGINT NOT NULL,
|
||||
COUNT BIGINT NOT NULL CHECK (COUNT > 0)
|
||||
);
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE order_items;
|
||||
|
||||
DROP TABLE orders;
|
||||
10
loms/db/migrations/00002_create_stocks.sql
Normal file
10
loms/db/migrations/00002_create_stocks.sql
Normal file
@@ -0,0 +1,10 @@
|
||||
-- +goose Up
|
||||
CREATE TABLE
|
||||
stocks (
|
||||
sku BIGINT PRIMARY KEY,
|
||||
total_count BIGINT NOT NULL,
|
||||
reserved BIGINT NOT NULL DEFAULT 0
|
||||
);
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE stocks;
|
||||
24
loms/db/migrations/00003_add_stocks.sql
Normal file
24
loms/db/migrations/00003_add_stocks.sql
Normal file
@@ -0,0 +1,24 @@
|
||||
-- +goose Up
|
||||
INSERT INTO
|
||||
stocks (sku, total_count, reserved)
|
||||
VALUES
|
||||
(139275865, 65534, 0),
|
||||
(2956315, 100, 30),
|
||||
(1076963, 100, 35),
|
||||
(135717466, 100, 20),
|
||||
(135937324, 100, 30),
|
||||
(1625903, 10000, 0),
|
||||
(1148162, 100, 0);
|
||||
|
||||
-- +goose Down
|
||||
DELETE FROM stocks
|
||||
WHERE
|
||||
sku IN (
|
||||
139275865,
|
||||
2956315,
|
||||
1076963,
|
||||
135717466,
|
||||
135937324,
|
||||
1625903,
|
||||
1148162
|
||||
);
|
||||
74
loms/go.mod
74
loms/go.mod
@@ -1,27 +1,87 @@
|
||||
module route256/loms
|
||||
|
||||
go 1.23.1
|
||||
go 1.23.9
|
||||
|
||||
require (
|
||||
github.com/gojuno/minimock/v3 v3.4.5
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3
|
||||
github.com/jackc/pgx/v5 v5.7.5
|
||||
github.com/opentracing/opentracing-go v1.2.0
|
||||
github.com/ozontech/allure-go/pkg/framework v0.6.34
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/rs/zerolog v1.34.0
|
||||
github.com/stretchr/testify v1.8.4
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/testcontainers/testcontainers-go v0.37.0
|
||||
google.golang.org/grpc v1.73.0
|
||||
google.golang.org/protobuf v1.36.6
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
require (
|
||||
dario.cat/mergo v1.0.1 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
|
||||
github.com/containerd/log v0.1.0 // indirect
|
||||
github.com/containerd/platforms v0.2.1 // indirect
|
||||
github.com/cpuguy83/dockercfg v0.3.2 // indirect
|
||||
github.com/distribution/reference v0.6.0 // indirect
|
||||
github.com/docker/docker v28.0.1+incompatible // indirect
|
||||
github.com/docker/go-connections v0.5.0 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/ebitengine/purego v0.8.4 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/klauspost/compress v1.18.0 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
||||
github.com/magiconair/properties v1.8.10 // indirect
|
||||
github.com/mfridman/interpolate v0.0.2 // indirect
|
||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||
github.com/moby/patternmatcher v0.6.0 // indirect
|
||||
github.com/moby/sys/sequential v0.5.0 // indirect
|
||||
github.com/moby/sys/user v0.1.0 // indirect
|
||||
github.com/moby/sys/userns v0.1.0 // indirect
|
||||
github.com/moby/term v0.5.0 // indirect
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.1 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
github.com/sethvargo/go-retry v0.3.0 // indirect
|
||||
github.com/shirou/gopsutil/v4 v4.25.1 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
||||
github.com/tklauser/numcpus v0.6.1 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
|
||||
go.opentelemetry.io/otel v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.36.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.7.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/ozontech/allure-go/pkg/allure v0.6.14 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/rogpeppe/go-internal v1.14.1 // indirect
|
||||
golang.org/x/net v0.38.0 // indirect
|
||||
golang.org/x/sys v0.31.0 // indirect
|
||||
golang.org/x/text v0.23.0 // indirect
|
||||
github.com/pressly/goose/v3 v3.24.3
|
||||
golang.org/x/crypto v0.38.0 // indirect
|
||||
golang.org/x/net v0.40.0 // indirect
|
||||
golang.org/x/sync v0.14.0 // indirect
|
||||
golang.org/x/sys v0.33.0 // indirect
|
||||
golang.org/x/text v0.25.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a // indirect
|
||||
)
|
||||
|
||||
207
loms/go.sum
207
loms/go.sum
@@ -1,62 +1,224 @@
|
||||
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
|
||||
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
|
||||
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
|
||||
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
|
||||
github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A=
|
||||
github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/cpuguy83/dockercfg v0.3.2 h1:DlJTyZGBDlXqUZ2Dk2Q3xHs/FtnooJJVaad2S9GKorA=
|
||||
github.com/cpuguy83/dockercfg v0.3.2/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc=
|
||||
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
||||
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
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/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
|
||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/docker/docker v28.0.1+incompatible h1:FCHjSRdXhNRFjlHMTv4jUNlIBbTeRjrWfeFuJp7jpo0=
|
||||
github.com/docker/docker v28.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
|
||||
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
|
||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/ebitengine/purego v0.8.4 h1:CF7LEKg5FFOsASUj0+QwaXf8Ht6TlFxg09+S9wz0omw=
|
||||
github.com/ebitengine/purego v0.8.4/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/gojuno/minimock/v3 v3.4.5 h1:Jcb0tEYZvVlQNtAAYpg3jCOoSwss2c1/rNugYTzj304=
|
||||
github.com/gojuno/minimock/v3 v3.4.5/go.mod h1:o9F8i2IT8v3yirA7mmdpNGzh1WNesm6iQakMtQV6KiE=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI=
|
||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgx/v5 v5.7.5 h1:JHGfMnQY+IEtGM63d+NGMjoRpysB2JBwDr5fsngwmJs=
|
||||
github.com/jackc/pgx/v5 v5.7.5/go.mod h1:aruU7o91Tc2q2cFp5h4uP3f6ztExVpyVv88Xl/8Vl8M=
|
||||
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
||||
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||
github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE=
|
||||
github.com/magiconair/properties v1.8.10/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mfridman/interpolate v0.0.2 h1:pnuTK7MQIxxFz1Gr+rjSIx9u7qVjf5VOoM/u6BbAxPY=
|
||||
github.com/mfridman/interpolate v0.0.2/go.mod h1:p+7uk6oE07mpE/Ik1b8EckO0O4ZXiGAfshKBWLUM9Xg=
|
||||
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
|
||||
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
|
||||
github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk=
|
||||
github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
|
||||
github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc=
|
||||
github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo=
|
||||
github.com/moby/sys/user v0.1.0 h1:WmZ93f5Ux6het5iituh9x2zAG7NFY9Aqi49jjE1PaQg=
|
||||
github.com/moby/sys/user v0.1.0/go.mod h1:fKJhFOnsCN6xZ5gSfbM6zaHGgDJMrqt9/reuj4T7MmU=
|
||||
github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g=
|
||||
github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28=
|
||||
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
|
||||
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
|
||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
|
||||
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
|
||||
github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
|
||||
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/ozontech/allure-go/pkg/allure v0.6.14 h1:lDamtSF+WtHQLg2+qQYijtC4Fk3KLGb6txNxxTZwUGc=
|
||||
github.com/ozontech/allure-go/pkg/allure v0.6.14/go.mod h1:4oEG2yq+DGOzJS/ZjPc87C/mx3tAnlYpYonk77Ru/vQ=
|
||||
github.com/ozontech/allure-go/pkg/framework v0.6.34 h1:IjM65Y3JP7ale7Ug3aBnFV4+c1NYYBCrgl/VrtEd/FY=
|
||||
github.com/ozontech/allure-go/pkg/framework v0.6.34/go.mod h1:oISDLE6Tfww35TBQz+1nrtbLtyBqR6ELxOtJ+MVjHOw=
|
||||
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/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/pressly/goose/v3 v3.24.3 h1:DSWWNwwggVUsYZ0X2VitiAa9sKuqtBfe+Jr9zFGwWlM=
|
||||
github.com/pressly/goose/v3 v3.24.3/go.mod h1:v9zYL4xdViLHCUUJh/mhjnm6JrK7Eul8AS93IxiZM4E=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
|
||||
github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY=
|
||||
github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/sethvargo/go-retry v0.3.0 h1:EEt31A35QhrcRZtrYFDTBg91cqZVnFL2navjDrah2SE=
|
||||
github.com/sethvargo/go-retry v0.3.0/go.mod h1:mNX17F0C/HguQMyMyJxcnU471gOZGxCLyYaFyAZraas=
|
||||
github.com/shirou/gopsutil/v4 v4.25.1 h1:QSWkTc+fu9LTAWfkZwZ6j8MSUk4A2LV7rbH0ZqmLjXs=
|
||||
github.com/shirou/gopsutil/v4 v4.25.1/go.mod h1:RoUCUpndaJFtT+2zsZzzmhvbfGoDCJ7nFXKJf8GqJbI=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/testcontainers/testcontainers-go v0.37.0 h1:L2Qc0vkTw2EHWQ08djon0D2uw7Z/PtHS/QzZZ5Ra/hg=
|
||||
github.com/testcontainers/testcontainers-go v0.37.0/go.mod h1:QPzbxZhQ6Bclip9igjLFj6z0hs01bU8lrl2dHQmgFGM=
|
||||
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
|
||||
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
|
||||
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
|
||||
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
||||
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=
|
||||
go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y=
|
||||
go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M=
|
||||
go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=
|
||||
go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=
|
||||
go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0 h1:dNzwXjZKpMpE2JhmO+9HsPl42NIXFIFSUSSs0fiqra0=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0/go.mod h1:90PoxvaEB5n6AOdZvi+yWJQoE95U8Dhhw2bSyRqnTD0=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU=
|
||||
go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=
|
||||
go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=
|
||||
go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs=
|
||||
go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
|
||||
go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs=
|
||||
go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
|
||||
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
|
||||
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=
|
||||
go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=
|
||||
go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os=
|
||||
go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8=
|
||||
golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
|
||||
golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 h1:y5zboxd6LQAqYIhHnB48p0ByQ/GnQx2BE33L8BOHQkI=
|
||||
golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6/go.mod h1:U6Lno4MTRCDY+Ba7aCcauB9T60gsv5s4ralQzP72ZoQ=
|
||||
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/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
|
||||
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
|
||||
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
||||
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
|
||||
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
|
||||
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=
|
||||
golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
|
||||
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
|
||||
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44=
|
||||
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a h1:v2PbRU4K3llS09c7zodFpNePeamkAwG3mPrAery9VeE=
|
||||
@@ -68,5 +230,16 @@ google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
|
||||
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
|
||||
modernc.org/libc v1.65.0 h1:e183gLDnAp9VJh6gWKdTy0CThL9Pt7MfcR/0bgb7Y1Y=
|
||||
modernc.org/libc v1.65.0/go.mod h1:7m9VzGq7APssBTydds2zBcxGREwvIGpuUBaKTXdm2Qs=
|
||||
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
|
||||
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
|
||||
modernc.org/memory v1.10.0 h1:fzumd51yQ1DxcOxSO+S6X7+QTuVU+n8/Aj7swYjFfC4=
|
||||
modernc.org/memory v1.10.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw=
|
||||
modernc.org/sqlite v1.37.0 h1:s1TMe7T3Q3ovQiK2Ouz4Jwh7dw4ZDqbebSDTlSJdfjI=
|
||||
modernc.org/sqlite v1.37.0/go.mod h1:5YiWv+YviqGMuGw4V+PNplcyaJ5v+vQd7TQOgkACoJM=
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
"google.golang.org/grpc"
|
||||
@@ -16,11 +17,12 @@ import (
|
||||
"google.golang.org/grpc/reflection"
|
||||
|
||||
"route256/loms/internal/app/server"
|
||||
ordersRepository "route256/loms/internal/domain/repository/orders"
|
||||
stocksRepository "route256/loms/internal/domain/repository/stocks"
|
||||
ordersRepository "route256/loms/internal/domain/repository/orders/sqlc"
|
||||
stocksRepository "route256/loms/internal/domain/repository/stocks/sqlc"
|
||||
"route256/loms/internal/domain/service"
|
||||
"route256/loms/internal/infra/config"
|
||||
mw "route256/loms/internal/infra/grpc/middleware"
|
||||
"route256/loms/internal/infra/postgres"
|
||||
|
||||
pb "route256/pkg/api/loms/v1"
|
||||
)
|
||||
@@ -50,13 +52,16 @@ func NewApp(configPath string) (*App, error) {
|
||||
|
||||
log.WithLevel(zerolog.GlobalLevel()).Msgf("using logging level=`%s`", zerolog.GlobalLevel().String())
|
||||
|
||||
stockRepo, err := stocksRepository.NewInMemoryRepository(100)
|
||||
masterPool, replicaPool, err := getPostgresPools(c)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("stocksRepository.NewInMemoryRepository: %w", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
orderRepo := ordersRepository.NewInMemoryRepository(100)
|
||||
service := service.NewLomsService(orderRepo, stockRepo)
|
||||
stockRepo := stocksRepository.NewStockRepository(masterPool, replicaPool)
|
||||
orderRepo := ordersRepository.NewOrderRepository(masterPool)
|
||||
txManager := postgres.NewTxManager(masterPool, replicaPool)
|
||||
|
||||
service := service.NewLomsService(orderRepo, stockRepo, txManager)
|
||||
controller := server.NewServer(service)
|
||||
|
||||
app := &App{
|
||||
@@ -117,3 +122,34 @@ func (app *App) ListenAndServe() error {
|
||||
|
||||
return gwServer.ListenAndServe()
|
||||
}
|
||||
|
||||
func getPostgresPools(c *config.Config) (masterPool, replicaPool *pgxpool.Pool, err error) {
|
||||
masterConn := fmt.Sprintf(
|
||||
"postgresql://%s:%s@%s:%s/%s?sslmode=disable",
|
||||
c.DatabaseMaster.User,
|
||||
c.DatabaseMaster.Password,
|
||||
c.DatabaseMaster.Host,
|
||||
c.DatabaseMaster.Port,
|
||||
c.DatabaseMaster.DBName,
|
||||
)
|
||||
|
||||
replicaConn := fmt.Sprintf(
|
||||
"postgresql://%s:%s@%s:%s/%s?sslmode=disable",
|
||||
c.DatabaseReplica.User,
|
||||
c.DatabaseReplica.Password,
|
||||
c.DatabaseReplica.Host,
|
||||
c.DatabaseReplica.Port,
|
||||
c.DatabaseReplica.DBName,
|
||||
)
|
||||
|
||||
pools, err := postgres.NewPools(context.Background(), masterConn, replicaConn)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if len(pools) != 2 {
|
||||
return nil, nil, fmt.Errorf("got wrong number of pools when establishing postgres connection")
|
||||
}
|
||||
|
||||
return pools[0], pools[1], nil
|
||||
}
|
||||
|
||||
32
loms/internal/domain/repository/orders/sqlc/db.go
Normal file
32
loms/internal/domain/repository/orders/sqlc/db.go
Normal file
@@ -0,0 +1,32 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.29.0
|
||||
|
||||
package sqlc
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgconn"
|
||||
)
|
||||
|
||||
type DBTX interface {
|
||||
Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error)
|
||||
Query(context.Context, string, ...interface{}) (pgx.Rows, error)
|
||||
QueryRow(context.Context, string, ...interface{}) pgx.Row
|
||||
}
|
||||
|
||||
func New(db DBTX) *Queries {
|
||||
return &Queries{db: db}
|
||||
}
|
||||
|
||||
type Queries struct {
|
||||
db DBTX
|
||||
}
|
||||
|
||||
func (q *Queries) WithTx(tx pgx.Tx) *Queries {
|
||||
return &Queries{
|
||||
db: tx,
|
||||
}
|
||||
}
|
||||
5
loms/internal/domain/repository/orders/sqlc/models.go
Normal file
5
loms/internal/domain/repository/orders/sqlc/models.go
Normal file
@@ -0,0 +1,5 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.29.0
|
||||
|
||||
package sqlc
|
||||
18
loms/internal/domain/repository/orders/sqlc/querier.go
Normal file
18
loms/internal/domain/repository/orders/sqlc/querier.go
Normal file
@@ -0,0 +1,18 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.29.0
|
||||
|
||||
package sqlc
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
type Querier interface {
|
||||
OrderAddItem(ctx context.Context, arg *OrderAddItemParams) error
|
||||
OrderCreate(ctx context.Context, arg *OrderCreateParams) (int64, error)
|
||||
OrderGetByID(ctx context.Context, id int64) ([]*OrderGetByIDRow, error)
|
||||
OrderSetStatus(ctx context.Context, arg *OrderSetStatusParams) (int64, error)
|
||||
}
|
||||
|
||||
var _ Querier = (*Queries)(nil)
|
||||
25
loms/internal/domain/repository/orders/sqlc/query.sql
Normal file
25
loms/internal/domain/repository/orders/sqlc/query.sql
Normal file
@@ -0,0 +1,25 @@
|
||||
-- name: OrderCreate :one
|
||||
insert into orders (status_name, user_id)
|
||||
values ($1, $2)
|
||||
returning id;
|
||||
|
||||
-- name: OrderAddItem :exec
|
||||
insert into order_items (order_id, sku, count)
|
||||
select $1, $2, $3;
|
||||
|
||||
-- name: OrderSetStatus :execrows
|
||||
update orders
|
||||
set status_name = $2
|
||||
where id = $1;
|
||||
|
||||
-- name: OrderGetByID :many
|
||||
select
|
||||
o.id as order_id,
|
||||
o.status_name as status,
|
||||
o.user_id,
|
||||
oi.sku,
|
||||
oi.count
|
||||
from orders o
|
||||
left join order_items oi on oi.order_id = o.id
|
||||
where o.id = $1
|
||||
order by oi.id;
|
||||
110
loms/internal/domain/repository/orders/sqlc/query.sql.go
Normal file
110
loms/internal/domain/repository/orders/sqlc/query.sql.go
Normal file
@@ -0,0 +1,110 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.29.0
|
||||
// source: query.sql
|
||||
|
||||
package sqlc
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
const orderAddItem = `-- name: OrderAddItem :exec
|
||||
insert into order_items (order_id, sku, count)
|
||||
select $1, $2, $3
|
||||
`
|
||||
|
||||
type OrderAddItemParams struct {
|
||||
OrderID int64
|
||||
Sku int64
|
||||
Count int64
|
||||
}
|
||||
|
||||
func (q *Queries) OrderAddItem(ctx context.Context, arg *OrderAddItemParams) error {
|
||||
_, err := q.db.Exec(ctx, orderAddItem, arg.OrderID, arg.Sku, arg.Count)
|
||||
return err
|
||||
}
|
||||
|
||||
const orderCreate = `-- name: OrderCreate :one
|
||||
insert into orders (status_name, user_id)
|
||||
values ($1, $2)
|
||||
returning id
|
||||
`
|
||||
|
||||
type OrderCreateParams struct {
|
||||
StatusName string
|
||||
UserID int64
|
||||
}
|
||||
|
||||
func (q *Queries) OrderCreate(ctx context.Context, arg *OrderCreateParams) (int64, error) {
|
||||
row := q.db.QueryRow(ctx, orderCreate, arg.StatusName, arg.UserID)
|
||||
var id int64
|
||||
err := row.Scan(&id)
|
||||
return id, err
|
||||
}
|
||||
|
||||
const orderGetByID = `-- name: OrderGetByID :many
|
||||
select
|
||||
o.id as order_id,
|
||||
o.status_name as status,
|
||||
o.user_id,
|
||||
oi.sku,
|
||||
oi.count
|
||||
from orders o
|
||||
left join order_items oi on oi.order_id = o.id
|
||||
where o.id = $1
|
||||
order by oi.id
|
||||
`
|
||||
|
||||
type OrderGetByIDRow struct {
|
||||
OrderID int64
|
||||
Status string
|
||||
UserID int64
|
||||
Sku *int64
|
||||
Count *int64
|
||||
}
|
||||
|
||||
func (q *Queries) OrderGetByID(ctx context.Context, id int64) ([]*OrderGetByIDRow, error) {
|
||||
rows, err := q.db.Query(ctx, orderGetByID, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []*OrderGetByIDRow
|
||||
for rows.Next() {
|
||||
var i OrderGetByIDRow
|
||||
if err := rows.Scan(
|
||||
&i.OrderID,
|
||||
&i.Status,
|
||||
&i.UserID,
|
||||
&i.Sku,
|
||||
&i.Count,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, &i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const orderSetStatus = `-- name: OrderSetStatus :execrows
|
||||
update orders
|
||||
set status_name = $2
|
||||
where id = $1
|
||||
`
|
||||
|
||||
type OrderSetStatusParams struct {
|
||||
ID int64
|
||||
StatusName string
|
||||
}
|
||||
|
||||
func (q *Queries) OrderSetStatus(ctx context.Context, arg *OrderSetStatusParams) (int64, error) {
|
||||
result, err := q.db.Exec(ctx, orderSetStatus, arg.ID, arg.StatusName)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return result.RowsAffected(), nil
|
||||
}
|
||||
105
loms/internal/domain/repository/orders/sqlc/repository.go
Normal file
105
loms/internal/domain/repository/orders/sqlc/repository.go
Normal file
@@ -0,0 +1,105 @@
|
||||
package sqlc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
|
||||
"route256/loms/internal/domain/entity"
|
||||
"route256/loms/internal/domain/model"
|
||||
"route256/loms/internal/domain/service"
|
||||
"route256/loms/internal/infra/postgres"
|
||||
)
|
||||
|
||||
type orderRepo struct {
|
||||
pool *pgxpool.Pool
|
||||
}
|
||||
|
||||
func NewOrderRepository(pool *pgxpool.Pool) service.OrderRepository {
|
||||
return &orderRepo{
|
||||
pool: pool,
|
||||
}
|
||||
}
|
||||
|
||||
func (o *orderRepo) GetQuerier(ctx context.Context) *Queries {
|
||||
tx, ok := postgres.TxFromCtx(ctx)
|
||||
if ok {
|
||||
return New(tx)
|
||||
}
|
||||
|
||||
return New(o.pool)
|
||||
}
|
||||
|
||||
func (o *orderRepo) OrderCreate(ctx context.Context, order *entity.Order) (entity.ID, error) {
|
||||
querier := o.GetQuerier(ctx)
|
||||
|
||||
id, err := querier.OrderCreate(ctx, &OrderCreateParams{
|
||||
StatusName: order.Status,
|
||||
UserID: int64(order.UserID),
|
||||
})
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("querier.OrderCreate: %w", err)
|
||||
}
|
||||
|
||||
for _, item := range order.Items {
|
||||
if err := querier.OrderAddItem(ctx, &OrderAddItemParams{
|
||||
OrderID: id,
|
||||
Sku: int64(item.ID),
|
||||
Count: int64(item.Count),
|
||||
}); err != nil {
|
||||
return 0, fmt.Errorf("querier.OrderAddItem: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return entity.ID(id), nil
|
||||
}
|
||||
|
||||
func (o *orderRepo) OrderGetByID(ctx context.Context, orderID entity.ID) (*entity.Order, error) {
|
||||
querier := o.GetQuerier(ctx)
|
||||
|
||||
rows, err := querier.OrderGetByID(ctx, int64(orderID))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("querier.OrderGetByID: %w", err)
|
||||
}
|
||||
|
||||
if len(rows) == 0 {
|
||||
return nil, model.ErrOrderNotFound
|
||||
}
|
||||
|
||||
items := make([]entity.OrderItem, len(rows))
|
||||
for i, row := range rows {
|
||||
items[i] = entity.OrderItem{
|
||||
ID: entity.Sku(*row.Sku),
|
||||
//nolint:gosec // will not overflow, uint32 is stored as int64
|
||||
Count: uint32(*row.Count),
|
||||
}
|
||||
}
|
||||
|
||||
order := &entity.Order{
|
||||
OrderID: orderID,
|
||||
Status: rows[0].Status,
|
||||
UserID: entity.ID(rows[0].UserID),
|
||||
Items: items,
|
||||
}
|
||||
|
||||
return order, nil
|
||||
}
|
||||
|
||||
func (o *orderRepo) OrderSetStatus(ctx context.Context, orderID entity.ID, newStatus string) error {
|
||||
querier := o.GetQuerier(ctx)
|
||||
|
||||
rows, err := querier.OrderSetStatus(ctx, &OrderSetStatusParams{
|
||||
ID: int64(orderID),
|
||||
StatusName: newStatus,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("querier.OrderSetStatus: %w", err)
|
||||
}
|
||||
|
||||
if rows == 0 {
|
||||
return model.ErrOrderNotFound
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
32
loms/internal/domain/repository/stocks/sqlc/db.go
Normal file
32
loms/internal/domain/repository/stocks/sqlc/db.go
Normal file
@@ -0,0 +1,32 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.29.0
|
||||
|
||||
package sqlc
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgconn"
|
||||
)
|
||||
|
||||
type DBTX interface {
|
||||
Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error)
|
||||
Query(context.Context, string, ...interface{}) (pgx.Rows, error)
|
||||
QueryRow(context.Context, string, ...interface{}) pgx.Row
|
||||
}
|
||||
|
||||
func New(db DBTX) *Queries {
|
||||
return &Queries{db: db}
|
||||
}
|
||||
|
||||
type Queries struct {
|
||||
db DBTX
|
||||
}
|
||||
|
||||
func (q *Queries) WithTx(tx pgx.Tx) *Queries {
|
||||
return &Queries{
|
||||
db: tx,
|
||||
}
|
||||
}
|
||||
11
loms/internal/domain/repository/stocks/sqlc/models.go
Normal file
11
loms/internal/domain/repository/stocks/sqlc/models.go
Normal file
@@ -0,0 +1,11 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.29.0
|
||||
|
||||
package sqlc
|
||||
|
||||
type Stock struct {
|
||||
Sku int64
|
||||
TotalCount int64
|
||||
Reserved int64
|
||||
}
|
||||
18
loms/internal/domain/repository/stocks/sqlc/querier.go
Normal file
18
loms/internal/domain/repository/stocks/sqlc/querier.go
Normal file
@@ -0,0 +1,18 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.29.0
|
||||
|
||||
package sqlc
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
type Querier interface {
|
||||
StockCancel(ctx context.Context, arg *StockCancelParams) (int64, error)
|
||||
StockGetByID(ctx context.Context, sku int64) (*Stock, error)
|
||||
StockReserve(ctx context.Context, arg *StockReserveParams) (int64, error)
|
||||
StockReserveRemove(ctx context.Context, arg *StockReserveRemoveParams) (int64, error)
|
||||
}
|
||||
|
||||
var _ Querier = (*Queries)(nil)
|
||||
24
loms/internal/domain/repository/stocks/sqlc/query.sql
Normal file
24
loms/internal/domain/repository/stocks/sqlc/query.sql
Normal file
@@ -0,0 +1,24 @@
|
||||
-- name: StockGetByID :one
|
||||
select sku, total_count, reserved
|
||||
from stocks
|
||||
where sku = $1
|
||||
limit 1;
|
||||
|
||||
-- name: StockReserve :execrows
|
||||
update stocks
|
||||
set reserved = reserved + $2
|
||||
where sku = $1
|
||||
and total_count >= reserved + $2;
|
||||
|
||||
-- name: StockReserveRemove :execrows
|
||||
update stocks
|
||||
set reserved = reserved - $2,
|
||||
total_count = total_count - $2
|
||||
where sku = $1
|
||||
and reserved >= $2 and total_count >= $2;
|
||||
|
||||
-- name: StockCancel :execrows
|
||||
update stocks
|
||||
set reserved = reserved - $2
|
||||
where sku = $1
|
||||
and reserved >= $2;
|
||||
85
loms/internal/domain/repository/stocks/sqlc/query.sql.go
Normal file
85
loms/internal/domain/repository/stocks/sqlc/query.sql.go
Normal file
@@ -0,0 +1,85 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.29.0
|
||||
// source: query.sql
|
||||
|
||||
package sqlc
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
const stockCancel = `-- name: StockCancel :execrows
|
||||
update stocks
|
||||
set reserved = reserved - $2
|
||||
where sku = $1
|
||||
and reserved >= $2
|
||||
`
|
||||
|
||||
type StockCancelParams struct {
|
||||
Sku int64
|
||||
Reserved int64
|
||||
}
|
||||
|
||||
func (q *Queries) StockCancel(ctx context.Context, arg *StockCancelParams) (int64, error) {
|
||||
result, err := q.db.Exec(ctx, stockCancel, arg.Sku, arg.Reserved)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return result.RowsAffected(), nil
|
||||
}
|
||||
|
||||
const stockGetByID = `-- name: StockGetByID :one
|
||||
select sku, total_count, reserved
|
||||
from stocks
|
||||
where sku = $1
|
||||
limit 1
|
||||
`
|
||||
|
||||
func (q *Queries) StockGetByID(ctx context.Context, sku int64) (*Stock, error) {
|
||||
row := q.db.QueryRow(ctx, stockGetByID, sku)
|
||||
var i Stock
|
||||
err := row.Scan(&i.Sku, &i.TotalCount, &i.Reserved)
|
||||
return &i, err
|
||||
}
|
||||
|
||||
const stockReserve = `-- name: StockReserve :execrows
|
||||
update stocks
|
||||
set reserved = reserved + $2
|
||||
where sku = $1
|
||||
and total_count >= reserved + $2
|
||||
`
|
||||
|
||||
type StockReserveParams struct {
|
||||
Sku int64
|
||||
Reserved int64
|
||||
}
|
||||
|
||||
func (q *Queries) StockReserve(ctx context.Context, arg *StockReserveParams) (int64, error) {
|
||||
result, err := q.db.Exec(ctx, stockReserve, arg.Sku, arg.Reserved)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return result.RowsAffected(), nil
|
||||
}
|
||||
|
||||
const stockReserveRemove = `-- name: StockReserveRemove :execrows
|
||||
update stocks
|
||||
set reserved = reserved - $2,
|
||||
total_count = total_count - $2
|
||||
where sku = $1
|
||||
and reserved >= $2 and total_count >= $2
|
||||
`
|
||||
|
||||
type StockReserveRemoveParams struct {
|
||||
Sku int64
|
||||
Reserved int64
|
||||
}
|
||||
|
||||
func (q *Queries) StockReserveRemove(ctx context.Context, arg *StockReserveRemoveParams) (int64, error) {
|
||||
result, err := q.db.Exec(ctx, stockReserveRemove, arg.Sku, arg.Reserved)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return result.RowsAffected(), nil
|
||||
}
|
||||
137
loms/internal/domain/repository/stocks/sqlc/repository.go
Normal file
137
loms/internal/domain/repository/stocks/sqlc/repository.go
Normal file
@@ -0,0 +1,137 @@
|
||||
package sqlc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
|
||||
"route256/loms/internal/domain/entity"
|
||||
"route256/loms/internal/domain/model"
|
||||
"route256/loms/internal/domain/service"
|
||||
"route256/loms/internal/infra/postgres"
|
||||
"route256/loms/internal/infra/tools"
|
||||
)
|
||||
|
||||
type stockRepo struct {
|
||||
read *pgxpool.Pool
|
||||
write *pgxpool.Pool
|
||||
}
|
||||
|
||||
func NewStockRepository(write, read *pgxpool.Pool) service.StockRepository {
|
||||
return &stockRepo{
|
||||
read: read,
|
||||
write: write,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *stockRepo) GetQuerier(ctx context.Context) *Queries {
|
||||
tx, ok := postgres.TxFromCtx(ctx)
|
||||
if ok {
|
||||
return New(tx)
|
||||
}
|
||||
|
||||
return New(s.write)
|
||||
}
|
||||
|
||||
func (s *stockRepo) StockReserve(ctx context.Context, stock *entity.Stock) error {
|
||||
querier := s.GetQuerier(ctx)
|
||||
|
||||
rows, err := querier.StockReserve(ctx, &StockReserveParams{
|
||||
Sku: int64(stock.Item.ID),
|
||||
Reserved: int64(stock.Reserved),
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("querier.StockReserve: %w", err)
|
||||
}
|
||||
|
||||
if rows == 0 {
|
||||
return model.ErrNotEnoughStocks
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *stockRepo) StockReserveRemove(ctx context.Context, stock *entity.Stock) error {
|
||||
querier := s.GetQuerier(ctx)
|
||||
|
||||
rows, err := querier.StockReserveRemove(ctx, &StockReserveRemoveParams{
|
||||
Sku: int64(stock.Item.ID),
|
||||
Reserved: int64(stock.Reserved),
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("querier.StockReserveRemove: %w", err)
|
||||
}
|
||||
|
||||
if rows > 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
_, err = querier.StockGetByID(ctx, int64(stock.Item.ID))
|
||||
switch {
|
||||
case errors.Is(err, pgx.ErrNoRows):
|
||||
return model.ErrUnknownStock
|
||||
case err != nil:
|
||||
return fmt.Errorf("querier.StockGetByID: %w", err)
|
||||
default:
|
||||
return model.ErrNotEnoughStocks
|
||||
}
|
||||
}
|
||||
|
||||
func (s *stockRepo) StockCancel(ctx context.Context, stock *entity.Stock) error {
|
||||
querier := s.GetQuerier(ctx)
|
||||
|
||||
rows, err := querier.StockCancel(ctx, &StockCancelParams{
|
||||
Sku: int64(stock.Item.ID),
|
||||
Reserved: int64(stock.Reserved),
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("querier.StockCancel: %w", err)
|
||||
}
|
||||
|
||||
if rows > 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
_, err = querier.StockGetByID(ctx, int64(stock.Item.ID))
|
||||
switch {
|
||||
case errors.Is(err, pgx.ErrNoRows):
|
||||
return model.ErrUnknownStock
|
||||
case err != nil:
|
||||
return fmt.Errorf("querier.StockGetByID: %w", err)
|
||||
default:
|
||||
return model.ErrNotEnoughStocks
|
||||
}
|
||||
}
|
||||
|
||||
func (s *stockRepo) StockGetByID(ctx context.Context, sku entity.Sku) (*entity.Stock, error) {
|
||||
querier := s.GetQuerier(ctx)
|
||||
|
||||
stock, err := querier.StockGetByID(ctx, int64(sku))
|
||||
switch {
|
||||
case errors.Is(err, pgx.ErrNoRows):
|
||||
return nil, model.ErrUnknownStock
|
||||
case err != nil:
|
||||
return nil, fmt.Errorf("querier.StockGetByID: %w", err)
|
||||
default:
|
||||
count, castErr := tools.SafeCastInt64ToUInt32(stock.TotalCount)
|
||||
if castErr != nil {
|
||||
return nil, castErr
|
||||
}
|
||||
|
||||
reserved, castErr := tools.SafeCastInt64ToUInt32(stock.Reserved)
|
||||
if castErr != nil {
|
||||
return nil, castErr
|
||||
}
|
||||
|
||||
return &entity.Stock{
|
||||
Item: entity.OrderItem{
|
||||
ID: entity.Sku(stock.Sku),
|
||||
Count: count,
|
||||
},
|
||||
Reserved: reserved,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
// Code generated by http://github.com/gojuno/minimock (v3.4.5). DO NOT EDIT.
|
||||
// Code generated by http://github.com/gojuno/minimock (v3.4.0). DO NOT EDIT.
|
||||
|
||||
package mock
|
||||
|
||||
//go:generate minimock -i route256/loms/internal/domain/loms/service.OrderRepository -o order_repository_mock.go -n OrderRepositoryMock -p mock
|
||||
//go:generate minimock -i route256/loms/internal/domain/service.OrderRepository -o order_repository_mock.go -n OrderRepositoryMock -p mock
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// Code generated by http://github.com/gojuno/minimock (v3.4.5). DO NOT EDIT.
|
||||
// Code generated by http://github.com/gojuno/minimock (v3.4.0). DO NOT EDIT.
|
||||
|
||||
package mock
|
||||
|
||||
//go:generate minimock -i route256/loms/internal/domain/loms/service.StockRepository -o stock_repository_mock.go -n StockRepositoryMock -p mock
|
||||
//go:generate minimock -i route256/loms/internal/domain/service.StockRepository -o stock_repository_mock.go -n StockRepositoryMock -p mock
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
@@ -28,15 +28,24 @@ type StockRepository interface {
|
||||
StockGetByID(ctx context.Context, sku entity.Sku) (*entity.Stock, error)
|
||||
}
|
||||
|
||||
type txManager interface {
|
||||
WriteWithTransaction(ctx context.Context, fn func(ctx context.Context) error) (err error)
|
||||
ReadWithTransaction(ctx context.Context, fn func(ctx context.Context) error) (err error)
|
||||
WriteWithRepeatableRead(ctx context.Context, fn func(ctx context.Context) error) (err error)
|
||||
ReadWithRepeatableRead(ctx context.Context, fn func(ctx context.Context) error) (err error)
|
||||
}
|
||||
|
||||
type LomsService struct {
|
||||
orders OrderRepository
|
||||
stocks StockRepository
|
||||
txManager txManager
|
||||
}
|
||||
|
||||
func NewLomsService(orderRepo OrderRepository, stockRepo StockRepository) *LomsService {
|
||||
func NewLomsService(orderRepo OrderRepository, stockRepo StockRepository, txManager txManager) *LomsService {
|
||||
return &LomsService{
|
||||
orders: orderRepo,
|
||||
stocks: stockRepo,
|
||||
txManager: txManager,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,40 +86,44 @@ func (s *LomsService) OrderCreate(ctx context.Context, orderReq *pb.OrderCreateR
|
||||
return int(a.ID - b.ID)
|
||||
})
|
||||
|
||||
id, err := s.orders.OrderCreate(ctx, order)
|
||||
var (
|
||||
orderID entity.ID
|
||||
resErr error
|
||||
)
|
||||
|
||||
err := s.txManager.WriteWithTransaction(ctx, func(txCtx context.Context) error {
|
||||
id, err := s.orders.OrderCreate(txCtx, order)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("orders.OrderCreate: %w", err)
|
||||
return err
|
||||
}
|
||||
|
||||
order.OrderID = id
|
||||
orderID = id
|
||||
|
||||
commitedStocks := make([]*entity.Stock, 0, len(order.Items))
|
||||
for _, item := range order.Items {
|
||||
stock := &entity.Stock{
|
||||
Item: item,
|
||||
Reserved: item.Count,
|
||||
committed := make([]*entity.Stock, 0, len(order.Items))
|
||||
for _, it := range order.Items {
|
||||
st := &entity.Stock{Item: it, Reserved: it.Count}
|
||||
if err := s.stocks.StockReserve(txCtx, st); err != nil {
|
||||
s.rollbackStocks(txCtx, committed)
|
||||
|
||||
_ = s.orders.OrderSetStatus(txCtx, id,
|
||||
pb.OrderStatus_ORDER_STATUS_FAILED.String())
|
||||
|
||||
resErr = fmt.Errorf("stocks.StockReserve: %w", err)
|
||||
return nil
|
||||
}
|
||||
committed = append(committed, st)
|
||||
}
|
||||
|
||||
if err := s.stocks.StockReserve(ctx, stock); err != nil {
|
||||
s.rollbackStocks(ctx, commitedStocks)
|
||||
|
||||
if statusErr := s.orders.OrderSetStatus(ctx, order.OrderID, pb.OrderStatus_ORDER_STATUS_FAILED.String()); statusErr != nil {
|
||||
log.Error().Err(statusErr).Msg("failed to update status on stock reserve fail")
|
||||
}
|
||||
|
||||
return 0, fmt.Errorf("stocks.StockReserve: %w", err)
|
||||
}
|
||||
|
||||
commitedStocks = append(commitedStocks, stock)
|
||||
}
|
||||
|
||||
if err := s.orders.OrderSetStatus(ctx, order.OrderID, pb.OrderStatus_ORDER_STATUS_AWAITING_PAYMENT.String()); err != nil {
|
||||
s.rollbackStocks(ctx, commitedStocks)
|
||||
|
||||
return s.orders.OrderSetStatus(txCtx, id,
|
||||
pb.OrderStatus_ORDER_STATUS_AWAITING_PAYMENT.String())
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return order.OrderID, nil
|
||||
if resErr != nil {
|
||||
return 0, resErr
|
||||
}
|
||||
return orderID, nil
|
||||
}
|
||||
|
||||
func (s *LomsService) OrderInfo(ctx context.Context, orderID entity.ID) (*entity.Order, error) {
|
||||
@@ -122,7 +135,12 @@ func (s *LomsService) OrderInfo(ctx context.Context, orderID entity.ID) (*entity
|
||||
}
|
||||
|
||||
func (s *LomsService) OrderPay(ctx context.Context, orderID entity.ID) error {
|
||||
order, err := s.OrderInfo(ctx, orderID)
|
||||
if orderID <= 0 {
|
||||
return model.ErrInvalidInput
|
||||
}
|
||||
|
||||
return s.txManager.WriteWithTransaction(ctx, func(txCtx context.Context) error {
|
||||
order, err := s.orders.OrderGetByID(txCtx, orderID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -131,23 +149,29 @@ func (s *LomsService) OrderPay(ctx context.Context, orderID entity.ID) error {
|
||||
case pb.OrderStatus_ORDER_STATUS_PAYED.String():
|
||||
return nil
|
||||
case pb.OrderStatus_ORDER_STATUS_AWAITING_PAYMENT.String():
|
||||
for _, item := range order.Items {
|
||||
if err := s.stocks.StockReserveRemove(ctx, &entity.Stock{
|
||||
Item: item,
|
||||
Reserved: item.Count,
|
||||
for _, it := range order.Items {
|
||||
if err := s.stocks.StockReserveRemove(txCtx, &entity.Stock{
|
||||
Item: it,
|
||||
Reserved: it.Count,
|
||||
}); err != nil {
|
||||
log.Error().Err(err).Msg("failed to free stock reservation")
|
||||
}
|
||||
}
|
||||
|
||||
return s.orders.OrderSetStatus(ctx, orderID, pb.OrderStatus_ORDER_STATUS_PAYED.String())
|
||||
return s.orders.OrderSetStatus(txCtx, orderID,
|
||||
pb.OrderStatus_ORDER_STATUS_PAYED.String())
|
||||
default:
|
||||
return model.ErrOrderInvalidStatus
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func (s *LomsService) OrderCancel(ctx context.Context, orderID entity.ID) error {
|
||||
order, err := s.OrderInfo(ctx, orderID)
|
||||
if orderID <= 0 {
|
||||
return model.ErrInvalidInput
|
||||
}
|
||||
|
||||
return s.txManager.WriteWithTransaction(ctx, func(txCtx context.Context) error {
|
||||
order, err := s.orders.OrderGetByID(txCtx, orderID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -155,21 +179,22 @@ func (s *LomsService) OrderCancel(ctx context.Context, orderID entity.ID) error
|
||||
switch order.Status {
|
||||
case pb.OrderStatus_ORDER_STATUS_CANCELLED.String():
|
||||
return nil
|
||||
case pb.OrderStatus_ORDER_STATUS_FAILED.String(), pb.OrderStatus_ORDER_STATUS_PAYED.String():
|
||||
case pb.OrderStatus_ORDER_STATUS_FAILED.String(),
|
||||
pb.OrderStatus_ORDER_STATUS_PAYED.String():
|
||||
return model.ErrOrderInvalidStatus
|
||||
}
|
||||
|
||||
stocks := make([]*entity.Stock, len(order.Items))
|
||||
for i, item := range order.Items {
|
||||
stocks[i] = &entity.Stock{
|
||||
Item: item,
|
||||
Reserved: item.Count,
|
||||
for _, it := range order.Items {
|
||||
if err := s.stocks.StockCancel(txCtx, &entity.Stock{
|
||||
Item: it,
|
||||
Reserved: it.Count,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
s.rollbackStocks(ctx, stocks)
|
||||
|
||||
return s.orders.OrderSetStatus(ctx, orderID, pb.OrderStatus_ORDER_STATUS_CANCELLED.String())
|
||||
return s.orders.OrderSetStatus(txCtx, orderID,
|
||||
pb.OrderStatus_ORDER_STATUS_CANCELLED.String())
|
||||
})
|
||||
}
|
||||
|
||||
func (s *LomsService) StocksInfo(ctx context.Context, sku entity.Sku) (uint32, error) {
|
||||
@@ -182,5 +207,5 @@ func (s *LomsService) StocksInfo(ctx context.Context, sku entity.Sku) (uint32, e
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return stock.Item.Count, nil
|
||||
return stock.Item.Count - stock.Reserved, nil
|
||||
}
|
||||
|
||||
@@ -21,6 +21,24 @@ const (
|
||||
testSku = entity.Sku(199)
|
||||
)
|
||||
|
||||
type mockTxManager struct{}
|
||||
|
||||
func (t *mockTxManager) WriteWithTransaction(ctx context.Context, fn func(ctx context.Context) error) (err error) {
|
||||
return fn(ctx)
|
||||
}
|
||||
|
||||
func (t *mockTxManager) ReadWithTransaction(ctx context.Context, fn func(ctx context.Context) error) (err error) {
|
||||
return fn(ctx)
|
||||
}
|
||||
|
||||
func (t *mockTxManager) WriteWithRepeatableRead(ctx context.Context, fn func(ctx context.Context) error) (err error) {
|
||||
return fn(ctx)
|
||||
}
|
||||
|
||||
func (t *mockTxManager) ReadWithRepeatableRead(ctx context.Context, fn func(ctx context.Context) error) (err error) {
|
||||
return fn(ctx)
|
||||
}
|
||||
|
||||
func TestLomsService_OrderCreate(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -130,8 +148,7 @@ func TestLomsService_OrderCreate(t *testing.T) {
|
||||
OrderCreateMock.Return(1, nil).
|
||||
OrderSetStatusMock.Return(errors.New("unexpected error")),
|
||||
stocks: mock.NewStockRepositoryMock(mc).
|
||||
StockReserveMock.Return(nil).
|
||||
StockCancelMock.Return(nil),
|
||||
StockReserveMock.Return(nil),
|
||||
},
|
||||
args: args{
|
||||
req: goodReq,
|
||||
@@ -145,7 +162,7 @@ func TestLomsService_OrderCreate(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
svc := NewLomsService(tt.fields.orders, tt.fields.stocks)
|
||||
svc := NewLomsService(tt.fields.orders, tt.fields.stocks, &mockTxManager{})
|
||||
_, err := svc.OrderCreate(ctx, tt.args.req)
|
||||
tt.wantErr(t, err)
|
||||
})
|
||||
@@ -256,24 +273,46 @@ func TestLomsService_OrderPay(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
svc := NewLomsService(tt.fields.orders, tt.fields.stocks)
|
||||
svc := NewLomsService(tt.fields.orders, tt.fields.stocks, &mockTxManager{})
|
||||
err := svc.OrderPay(ctx, tt.args.id)
|
||||
tt.wantErr(t, err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLomsService_OrderInfo(t *testing.T) {
|
||||
func TestLomsService_OrderInfoBadInput(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
svc := NewLomsService(
|
||||
nil,
|
||||
nil,
|
||||
&mockTxManager{},
|
||||
)
|
||||
|
||||
_, err := svc.OrderInfo(context.Background(), 0)
|
||||
require.ErrorIs(t, err, model.ErrInvalidInput)
|
||||
}
|
||||
|
||||
func TestLomsService_OrderInfoSuccess(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
order := &entity.Order{
|
||||
OrderID: 123,
|
||||
Status: "payed",
|
||||
UserID: 1337,
|
||||
Items: []entity.OrderItem{},
|
||||
}
|
||||
|
||||
mc := minimock.NewController(t)
|
||||
svc := NewLomsService(
|
||||
mock.NewOrderRepositoryMock(mc),
|
||||
mock.NewStockRepositoryMock(mc),
|
||||
mock.NewOrderRepositoryMock(mc).OrderGetByIDMock.Return(order, nil),
|
||||
nil,
|
||||
&mockTxManager{},
|
||||
)
|
||||
|
||||
err := svc.OrderPay(context.Background(), 0)
|
||||
require.ErrorIs(t, err, model.ErrInvalidInput)
|
||||
gotOrder, err := svc.OrderInfo(context.Background(), 123)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, order, gotOrder)
|
||||
}
|
||||
|
||||
func TestLomsService_OrderCancel(t *testing.T) {
|
||||
@@ -370,7 +409,7 @@ func TestLomsService_OrderCancel(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
svc := NewLomsService(tt.fields.orders, tt.fields.stocks)
|
||||
svc := NewLomsService(tt.fields.orders, tt.fields.stocks, &mockTxManager{})
|
||||
err := svc.OrderCancel(ctx, tt.args.id)
|
||||
tt.wantErr(t, err)
|
||||
})
|
||||
@@ -437,7 +476,7 @@ func TestLomsService_StocksInfo(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
svc := NewLomsService(nil, tt.fields.stocks)
|
||||
svc := NewLomsService(nil, tt.fields.stocks, &mockTxManager{})
|
||||
got, err := svc.StocksInfo(ctx, tt.args.sku)
|
||||
tt.wantErr(t, err)
|
||||
if err == nil {
|
||||
|
||||
56
loms/internal/infra/postgres/postgres.go
Normal file
56
loms/internal/infra/postgres/postgres.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// From https://gitlab.ozon.dev/go/classroom-18/students/week-4-workshop/-/blob/master/internal/infra/postgres/postgres.go
|
||||
|
||||
func NewPool(ctx context.Context, dsn string) (*pgxpool.Pool, error) {
|
||||
config, err := pgxpool.ParseConfig(dsn)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "pgxpool.ParseConfig")
|
||||
}
|
||||
|
||||
pool, err := pgxpool.NewWithConfig(ctx, config)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "pgxpool.NewWithConfig")
|
||||
}
|
||||
|
||||
return pool, nil
|
||||
}
|
||||
|
||||
func NewPools(ctx context.Context, DSNs ...string) ([]*pgxpool.Pool, error) {
|
||||
pools := make([]*pgxpool.Pool, len(DSNs))
|
||||
|
||||
for i, dsn := range DSNs {
|
||||
cfg, err := pgxpool.ParseConfig(dsn)
|
||||
if err != nil {
|
||||
closeOpened(pools[:i])
|
||||
|
||||
return nil, errors.Wrap(err, "pgxpool.ParseConfig")
|
||||
}
|
||||
|
||||
pool, err := pgxpool.NewWithConfig(ctx, cfg)
|
||||
if err != nil {
|
||||
closeOpened(pools[:i])
|
||||
|
||||
return nil, errors.Wrap(err, "pgxpool.NewWithConfig")
|
||||
}
|
||||
|
||||
pools[i] = pool
|
||||
}
|
||||
|
||||
return pools, nil
|
||||
}
|
||||
|
||||
func closeOpened(pools []*pgxpool.Pool) {
|
||||
for _, p := range pools {
|
||||
if p != nil {
|
||||
p.Close()
|
||||
}
|
||||
}
|
||||
}
|
||||
87
loms/internal/infra/postgres/tx.go
Normal file
87
loms/internal/infra/postgres/tx.go
Normal file
@@ -0,0 +1,87 @@
|
||||
package postgres
|
||||
|
||||
// From https://gitlab.ozon.dev/go/classroom-18/students/week-4-workshop/-/blob/master/internal/infra/postgres/tx.go
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
"github.com/opentracing/opentracing-go"
|
||||
)
|
||||
|
||||
// Tx транзакция.
|
||||
type Tx pgx.Tx
|
||||
|
||||
type txKey struct{}
|
||||
|
||||
func ctxWithTx(ctx context.Context, tx pgx.Tx) context.Context {
|
||||
return context.WithValue(ctx, txKey{}, tx)
|
||||
}
|
||||
|
||||
func TxFromCtx(ctx context.Context) (pgx.Tx, bool) {
|
||||
tx, ok := ctx.Value(txKey{}).(pgx.Tx)
|
||||
|
||||
return tx, ok
|
||||
}
|
||||
|
||||
type TxManager struct {
|
||||
write *pgxpool.Pool
|
||||
read *pgxpool.Pool
|
||||
}
|
||||
|
||||
func NewTxManager(write, read *pgxpool.Pool) *TxManager {
|
||||
return &TxManager{
|
||||
write: write,
|
||||
read: read,
|
||||
}
|
||||
}
|
||||
|
||||
// WithTransaction выполняет fn в транзакции с дефолтным уровнем изоляции.
|
||||
func (m *TxManager) WriteWithTransaction(ctx context.Context, fn func(ctx context.Context) error) (err error) {
|
||||
return m.withTx(ctx, m.write, pgx.TxOptions{}, fn)
|
||||
}
|
||||
|
||||
func (m *TxManager) ReadWithTransaction(ctx context.Context, fn func(ctx context.Context) error) (err error) {
|
||||
return m.withTx(ctx, m.read, pgx.TxOptions{}, fn)
|
||||
}
|
||||
|
||||
// WithTransaction выполняет fn в транзакции с уровнем изоляции RepeatableRead.
|
||||
func (m *TxManager) WriteWithRepeatableRead(ctx context.Context, fn func(ctx context.Context) error) (err error) {
|
||||
return m.withTx(ctx, m.write, pgx.TxOptions{IsoLevel: pgx.RepeatableRead}, fn)
|
||||
}
|
||||
|
||||
func (m *TxManager) ReadWithRepeatableRead(ctx context.Context, fn func(ctx context.Context) error) (err error) {
|
||||
return m.withTx(ctx, m.read, pgx.TxOptions{IsoLevel: pgx.RepeatableRead}, fn)
|
||||
}
|
||||
|
||||
// WithTx выполняет fn в транзакции.
|
||||
func (m *TxManager) withTx(ctx context.Context, pool *pgxpool.Pool, options pgx.TxOptions, fn func(ctx context.Context) error) (err error) {
|
||||
var span opentracing.Span
|
||||
span, ctx = opentracing.StartSpanFromContext(ctx, "Transaction")
|
||||
defer span.Finish()
|
||||
|
||||
tx, err := pool.BeginTx(ctx, options)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
ctx = ctxWithTx(ctx, tx)
|
||||
|
||||
defer func() {
|
||||
if p := recover(); p != nil {
|
||||
// a panic occurred, rollback and repanic
|
||||
_ = tx.Rollback(ctx)
|
||||
panic(p)
|
||||
} else if err != nil {
|
||||
// something went wrong, rollback
|
||||
_ = tx.Rollback(ctx)
|
||||
} else {
|
||||
// all good, commit
|
||||
err = tx.Commit(ctx)
|
||||
}
|
||||
}()
|
||||
|
||||
err = fn(ctx)
|
||||
|
||||
return
|
||||
}
|
||||
19
loms/internal/infra/tools/safecast.go
Normal file
19
loms/internal/infra/tools/safecast.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package tools
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
||||
func SafeCastInt64ToUInt32(num int64) (uint32, error) {
|
||||
if num < 0 {
|
||||
return 0, fmt.Errorf("tried casting signed negative number to unsigned number")
|
||||
}
|
||||
|
||||
if num > math.MaxUint32 {
|
||||
return 0, fmt.Errorf("tried casting larger number than uint32 can store")
|
||||
}
|
||||
|
||||
// the bounds are checked, and cast should be safe.
|
||||
return uint32(num), nil // #nosec G115
|
||||
}
|
||||
28
loms/sqlc.yaml
Normal file
28
loms/sqlc.yaml
Normal file
@@ -0,0 +1,28 @@
|
||||
version: "2"
|
||||
sql:
|
||||
- engine: "postgresql"
|
||||
queries: "internal/domain/repository/orders/sqlc/query.sql"
|
||||
schema: "db/migrations"
|
||||
gen:
|
||||
go:
|
||||
package: "sqlc"
|
||||
out: "internal/domain/repository/orders/sqlc"
|
||||
sql_package: "pgx/v5"
|
||||
emit_interface: true
|
||||
emit_pointers_for_null_types: true
|
||||
emit_result_struct_pointers: true
|
||||
emit_params_struct_pointers: true
|
||||
omit_unused_structs: true
|
||||
- engine: "postgresql"
|
||||
queries: "internal/domain/repository/stocks/sqlc/query.sql"
|
||||
schema: "db/migrations"
|
||||
gen:
|
||||
go:
|
||||
package: "sqlc"
|
||||
out: "internal/domain/repository/stocks/sqlc"
|
||||
sql_package: "pgx/v5"
|
||||
emit_interface: true
|
||||
emit_pointers_for_null_types: true
|
||||
emit_result_struct_pointers: true
|
||||
emit_params_struct_pointers: true
|
||||
omit_unused_structs: true
|
||||
@@ -5,20 +5,27 @@ package integration
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"net"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
"github.com/ozontech/allure-go/pkg/framework/provider"
|
||||
"github.com/ozontech/allure-go/pkg/framework/suite"
|
||||
"github.com/pressly/goose/v3"
|
||||
"github.com/testcontainers/testcontainers-go"
|
||||
"github.com/testcontainers/testcontainers-go/wait"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
|
||||
"route256/loms/internal/app/server"
|
||||
"route256/loms/internal/domain/entity"
|
||||
ordersRepository "route256/loms/internal/domain/repository/orders"
|
||||
stocksRepository "route256/loms/internal/domain/repository/stocks"
|
||||
ordersRepository "route256/loms/internal/domain/repository/orders/sqlc"
|
||||
stocksRepository "route256/loms/internal/domain/repository/stocks/sqlc"
|
||||
lomsService "route256/loms/internal/domain/service"
|
||||
"route256/loms/internal/infra/postgres"
|
||||
|
||||
pb "route256/pkg/api/loms/v1"
|
||||
)
|
||||
@@ -30,14 +37,75 @@ const (
|
||||
|
||||
testUID = entity.ID(1337)
|
||||
testCount = uint32(2)
|
||||
migrationsDir = "../../db/migrations"
|
||||
)
|
||||
|
||||
func startPostgres(ctx context.Context, migrationsDir string) (*pgxpool.Pool, func(), error) {
|
||||
req := testcontainers.ContainerRequest{
|
||||
Image: "gitlab-registry.ozon.dev/go/classroom-18/students/base/postgres:16",
|
||||
Env: map[string]string{
|
||||
"POSTGRESQL_USERNAME": "user",
|
||||
"POSTGRESQL_PASSWORD": "postgres",
|
||||
"POSTGRESQL_DATABASE": "loms_test",
|
||||
"POSTGRESQL_PORT": "5437",
|
||||
},
|
||||
ExposedPorts: []string{"5437/tcp"},
|
||||
WaitingFor: wait.ForListeningPort("5437/tcp").WithStartupTimeout(30 * time.Second),
|
||||
}
|
||||
container, err := testcontainers.GenericContainer(ctx,
|
||||
testcontainers.GenericContainerRequest{ContainerRequest: req, Started: true})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
endpoint, err := container.Endpoint(ctx, "")
|
||||
if err != nil {
|
||||
container.Terminate(ctx)
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
dsn := fmt.Sprintf("postgresql://user:postgres@%s/loms_test?sslmode=disable", endpoint)
|
||||
|
||||
var pool *pgxpool.Pool
|
||||
for i := 0; i < 30; i++ {
|
||||
pool, err = pgxpool.New(ctx, dsn)
|
||||
if err == nil && pool.Ping(ctx) == nil {
|
||||
break
|
||||
}
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
if err != nil {
|
||||
container.Terminate(ctx)
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
std, err := sql.Open("pgx", dsn)
|
||||
if err != nil {
|
||||
container.Terminate(ctx)
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := goose.Up(std, migrationsDir); err != nil {
|
||||
container.Terminate(ctx)
|
||||
return nil, nil, err
|
||||
}
|
||||
std.Close()
|
||||
|
||||
cleanup := func() {
|
||||
pool.Close()
|
||||
_ = container.Terminate(context.Background())
|
||||
}
|
||||
return pool, cleanup, nil
|
||||
}
|
||||
|
||||
type LomsIntegrationSuite struct {
|
||||
suite.Suite
|
||||
|
||||
grpcSrv *grpc.Server
|
||||
grpcConn *grpc.ClientConn
|
||||
|
||||
lomsClient pb.LOMSClient
|
||||
|
||||
cleanup func()
|
||||
}
|
||||
|
||||
func TestLomsIntegrationSuite(t *testing.T) {
|
||||
@@ -45,12 +113,17 @@ func TestLomsIntegrationSuite(t *testing.T) {
|
||||
}
|
||||
|
||||
func (s *LomsIntegrationSuite) BeforeAll(t provider.T) {
|
||||
ctx := context.Background()
|
||||
t.WithNewStep("init cart-service", func(sCtx provider.StepCtx) {
|
||||
orderRepo := ordersRepository.NewInMemoryRepository(100)
|
||||
stockRepo, err := stocksRepository.NewInMemoryRepository(100)
|
||||
sCtx.Require().NoError(err)
|
||||
pool, cleanup, err := startPostgres(ctx, migrationsDir)
|
||||
s.cleanup = cleanup
|
||||
|
||||
svc := lomsService.NewLomsService(orderRepo, stockRepo)
|
||||
orderRepo := ordersRepository.NewOrderRepository(pool)
|
||||
stockRepo := stocksRepository.NewStockRepository(pool, pool)
|
||||
|
||||
txManager := postgres.NewTxManager(pool, pool)
|
||||
|
||||
svc := lomsService.NewLomsService(orderRepo, stockRepo, txManager)
|
||||
lomsServer := server.NewServer(svc)
|
||||
|
||||
lis, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
@@ -74,6 +147,7 @@ func (s *LomsIntegrationSuite) BeforeAll(t provider.T) {
|
||||
func (s *LomsIntegrationSuite) AfterAll(t provider.T) {
|
||||
s.grpcSrv.Stop()
|
||||
_ = s.grpcConn.Close()
|
||||
s.cleanup()
|
||||
}
|
||||
|
||||
func (s *LomsIntegrationSuite) TestOrderProcessPositive(t provider.T) {
|
||||
|
||||
31
make/bin-deps.mk
Normal file
31
make/bin-deps.mk
Normal file
@@ -0,0 +1,31 @@
|
||||
CURDIR=$(shell pwd)
|
||||
BINDIR=${CURDIR}/bin
|
||||
GOVER=$(shell go version | perl -nle '/(go\d\S+)/; print $$1;')
|
||||
|
||||
LINTVER=v1.60.3
|
||||
LINTBIN=bin/golangci-lint
|
||||
|
||||
bindir:
|
||||
mkdir -p ${BINDIR}
|
||||
|
||||
.PHONY: .bin-deps
|
||||
.bin-deps: bindir
|
||||
$(info Installing binary dependencies...)
|
||||
GOBIN=$(BINDIR) go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28.1 && \
|
||||
GOBIN=$(BINDIR) go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2.0 && \
|
||||
GOBIN=$(BINDIR) go install github.com/envoyproxy/protoc-gen-validate@v1.0.4 && \
|
||||
GOBIN=$(BINDIR) go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway@v2.19.1 && \
|
||||
GOBIN=$(BINDIR) go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2@v2.19.1 && \
|
||||
GOBIN=$(BINDIR) go install github.com/go-swagger/go-swagger/cmd/swagger@v0.30.5 && \
|
||||
GOBIN=$(BINDIR) go install github.com/gojuno/minimock/v3/cmd/minimock@v3.4.0
|
||||
|
||||
$(info Installing golangci-lint...)
|
||||
test -f ${LINTBIN} || \
|
||||
(GOBIN=${BINDIR} go install github.com/golangci/golangci-lint/cmd/golangci-lint@${LINTVER} && \
|
||||
mv ${BINDIR}/golangci-lint ${LINTBIN})
|
||||
|
||||
$(info Installing goose binary...)
|
||||
GOBIN=$(BINDIR) go install github.com/pressly/goose/v3/cmd/goose@v3.24.1
|
||||
|
||||
$(info Installing sqlc binary...)
|
||||
GOBIN=$(BINDIR) CGO_ENABLED=0 go install github.com/sqlc-dev/sqlc/cmd/sqlc@v1.29.0
|
||||
@@ -1,17 +1,6 @@
|
||||
CURDIR=$(shell pwd)
|
||||
BINDIR=${CURDIR}/bin
|
||||
|
||||
.PHONY: .bin-deps
|
||||
.bin-deps:
|
||||
$(info Installing binary dependencies...)
|
||||
|
||||
GOBIN=$(BINDIR) go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28.1 && \
|
||||
GOBIN=$(BINDIR) go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2.0 && \
|
||||
GOBIN=$(BINDIR) go install github.com/envoyproxy/protoc-gen-validate@v1.0.4 && \
|
||||
GOBIN=$(BINDIR) go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway@v2.19.1 && \
|
||||
GOBIN=$(BINDIR) go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2@v2.19.1 && \
|
||||
GOBIN=$(BINDIR) go install github.com/go-swagger/go-swagger/cmd/swagger@v0.30.5
|
||||
|
||||
# Устанавливаем proto описания google/protobuf
|
||||
vendor-proto/google/protobuf:
|
||||
git clone -b main --single-branch -n --depth=1 \
|
||||
@@ -69,7 +58,7 @@ define generate
|
||||
echo "no internal package in $(1)"; \
|
||||
exit 0; \
|
||||
fi; \
|
||||
go generate ./$(1)/internal/...; \
|
||||
PATH=$(PATH):$(BINDIR) go generate ./$(1)/internal/...; \
|
||||
fi
|
||||
endef
|
||||
|
||||
|
||||
13
make/lint.mk
13
make/lint.mk
@@ -1,19 +1,6 @@
|
||||
CURDIR=$(shell pwd)
|
||||
BINDIR=${CURDIR}/bin
|
||||
GOVER=$(shell go version | perl -nle '/(go\d\S+)/; print $$1;')
|
||||
LINTVER=v1.60.3
|
||||
LINTBIN=bin/golangci-lint
|
||||
|
||||
|
||||
bindir:
|
||||
mkdir -p ${BINDIR}
|
||||
|
||||
|
||||
install-lint: bindir
|
||||
test -f ${LINTBIN} || \
|
||||
(GOBIN=${BINDIR} go install github.com/golangci/golangci-lint/cmd/golangci-lint@${LINTVER} && \
|
||||
mv ${BINDIR}/golangci-lint ${LINTBIN})
|
||||
|
||||
define lint
|
||||
@if [ -f "$(1)/go.mod" ]; then \
|
||||
output=$$(${LINTBIN} --config=.golangci.yaml run $(1)/... 2>&1); \
|
||||
|
||||
Reference in New Issue
Block a user