add catalog listing in catalog
parent
e6c8e56e76
commit
914842291f
11
go.mod
11
go.mod
|
@ -9,6 +9,7 @@ require (
|
||||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
|
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
|
||||||
github.com/chenzhuoyu/iasm v0.9.1 // indirect
|
github.com/chenzhuoyu/iasm v0.9.1 // indirect
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||||
|
github.com/fatih/color v1.16.0 // indirect
|
||||||
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
||||||
github.com/gin-contrib/cache v1.2.0 // indirect
|
github.com/gin-contrib/cache v1.2.0 // indirect
|
||||||
github.com/gin-contrib/cors v1.5.0 // indirect
|
github.com/gin-contrib/cors v1.5.0 // indirect
|
||||||
|
@ -21,24 +22,34 @@ require (
|
||||||
github.com/goccy/go-json v0.10.2 // indirect
|
github.com/goccy/go-json v0.10.2 // indirect
|
||||||
github.com/gomodule/redigo v1.8.9 // indirect
|
github.com/gomodule/redigo v1.8.9 // indirect
|
||||||
github.com/google/uuid v1.6.0 // indirect
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
|
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||||
github.com/jmoiron/sqlx v1.3.5 // indirect
|
github.com/jmoiron/sqlx v1.3.5 // indirect
|
||||||
github.com/joho/godotenv v1.5.1 // indirect
|
github.com/joho/godotenv v1.5.1 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||||
github.com/leodido/go-urn v1.4.0 // indirect
|
github.com/leodido/go-urn v1.4.0 // indirect
|
||||||
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
github.com/memcachier/mc/v3 v3.0.3 // indirect
|
github.com/memcachier/mc/v3 v3.0.3 // indirect
|
||||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
|
github.com/orcaman/concurrent-map/v2 v2.0.1 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.1.1 // indirect
|
github.com/pelletier/go-toml/v2 v2.1.1 // indirect
|
||||||
github.com/redis/go-redis/v9 v9.5.1 // indirect
|
github.com/redis/go-redis/v9 v9.5.1 // indirect
|
||||||
github.com/robfig/go-cache v0.0.0-20130306151617-9fc39e0dbf62 // indirect
|
github.com/robfig/go-cache v0.0.0-20130306151617-9fc39e0dbf62 // indirect
|
||||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||||
|
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||||
github.com/ugorji/go/codec v1.2.12 // indirect
|
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||||
|
github.com/uptrace/bun v1.1.17 // indirect
|
||||||
|
github.com/uptrace/bun/dialect/mysqldialect v1.1.17 // indirect
|
||||||
|
github.com/uptrace/bun/extra/bundebug v1.1.17 // indirect
|
||||||
|
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
|
||||||
|
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||||
golang.org/x/arch v0.7.0 // indirect
|
golang.org/x/arch v0.7.0 // indirect
|
||||||
golang.org/x/crypto v0.20.0 // indirect
|
golang.org/x/crypto v0.20.0 // indirect
|
||||||
|
golang.org/x/mod v0.14.0 // indirect
|
||||||
golang.org/x/net v0.21.0 // indirect
|
golang.org/x/net v0.21.0 // indirect
|
||||||
golang.org/x/sys v0.17.0 // indirect
|
golang.org/x/sys v0.17.0 // indirect
|
||||||
golang.org/x/text v0.14.0 // indirect
|
golang.org/x/text v0.14.0 // indirect
|
||||||
|
|
24
go.sum
24
go.sum
|
@ -17,6 +17,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||||
|
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
||||||
|
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
|
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
|
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
|
||||||
github.com/gin-contrib/cache v1.2.0 h1:WA+AJR4kmHDTaLLShCHo/IeWVmmGRZ3Lsr3JQ46tFlE=
|
github.com/gin-contrib/cache v1.2.0 h1:WA+AJR4kmHDTaLLShCHo/IeWVmmGRZ3Lsr3JQ46tFlE=
|
||||||
|
@ -47,6 +49,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
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/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||||
|
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||||
github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g=
|
github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g=
|
||||||
github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ=
|
github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ=
|
||||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||||
|
@ -60,6 +64,9 @@ github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgSh
|
||||||
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
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/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
|
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.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
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/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||||
|
@ -72,6 +79,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
|
github.com/orcaman/concurrent-map/v2 v2.0.1 h1:jOJ5Pg2w1oeB6PeDurIYf6k9PQ+aTITr/6lP/L/zp6c=
|
||||||
|
github.com/orcaman/concurrent-map/v2 v2.0.1/go.mod h1:9Eq3TG2oBe5FirmYWQfYO5iH1q0Jv47PLaNK++uCdOM=
|
||||||
github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI=
|
github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI=
|
||||||
github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
@ -92,18 +101,33 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
|
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo=
|
||||||
|
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs=
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||||
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
|
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
|
||||||
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||||
|
github.com/uptrace/bun v1.1.17 h1:qxBaEIo0hC/8O3O6GrMDKxqyT+mw5/s0Pn/n6xjyGIk=
|
||||||
|
github.com/uptrace/bun v1.1.17/go.mod h1:hATAzivtTIRsSJR4B8AXR+uABqnQxr3myKDKEf5iQ9U=
|
||||||
|
github.com/uptrace/bun/dialect/mysqldialect v1.1.17 h1:CsaZu+C3hW6jH5XnbQWPeZbHOoeURRpX9wd9wNy9fYU=
|
||||||
|
github.com/uptrace/bun/dialect/mysqldialect v1.1.17/go.mod h1:PDT12yHB0yLidZWFoPjhXfEKvsu7tLyjY67+OSMQsVw=
|
||||||
|
github.com/uptrace/bun/extra/bundebug v1.1.17 h1:LcZ8DzyyGdXAmbUqmnCpBq7TPFegMp59FGy+uzEE21c=
|
||||||
|
github.com/uptrace/bun/extra/bundebug v1.1.17/go.mod h1:FOwNaBEGGChv3qBVh3pz3TPlUuikZ93qKjd/LJdl91o=
|
||||||
|
github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=
|
||||||
|
github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
|
||||||
|
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
|
||||||
|
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
|
||||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||||
golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc=
|
golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc=
|
||||||
golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||||
golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg=
|
golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg=
|
||||||
golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ=
|
golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ=
|
||||||
|
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
|
||||||
|
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||||
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
||||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/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.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
|
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
|
||||||
|
|
|
@ -1,41 +1,78 @@
|
||||||
package endpoints
|
package endpoints
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gin-gonic/gin"
|
cmap "github.com/orcaman/concurrent-map/v2"
|
||||||
"relynolli-server/models"
|
"relynolli-server/models"
|
||||||
"relynolli-server/services"
|
"relynolli-server/status"
|
||||||
"strconv"
|
"relynolli-server/storage"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
// "relynolli-server/models"
|
||||||
|
// "relynolli-server/services"
|
||||||
|
// "strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (h *handlers) GetCatalogItems(c *gin.Context) {
|
type GetCatalogItemsRequest struct {
|
||||||
|
Limit int `form:"limit" `
|
||||||
|
Page int `form:"page"`
|
||||||
|
}
|
||||||
|
|
||||||
limit, _ := strconv.Atoi(c.DefaultQuery("limit", "10"))
|
func (h *handlers) GetCatalogItems(c *gin.Context) {
|
||||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
queries := cmap.New[[]string]()
|
||||||
offset := (page - 1) * limit
|
for key, val := range c.Request.URL.Query() {
|
||||||
if c.DefaultQuery("isFilter", "0") == "0" {
|
queries.Set(key, val)
|
||||||
c.JSON(200, services.GetCatalogItems(limit, offset))
|
}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
meta := models.Meta{
|
||||||
|
RequestStarted: time.Now().Unix(),
|
||||||
|
}
|
||||||
|
|
||||||
|
LPQuery := new(GetCatalogItemsRequest)
|
||||||
|
LPError := c.ShouldBindQuery(LPQuery)
|
||||||
|
if LPError != nil {
|
||||||
|
meta.RequestFinished = time.Now().Unix()
|
||||||
|
c.JSON(400, models.Response{
|
||||||
|
Status: status.STATUS_BAD_REQUEST,
|
||||||
|
Info: "Limit and page query params should be integer numbers",
|
||||||
|
Meta: &meta,
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.JSON(200, services.FilterCatalogItems(c.Request.URL.Query(), limit, offset))
|
if LPQuery.Page == 0 {
|
||||||
|
LPQuery.Page = 1
|
||||||
|
}
|
||||||
|
if LPQuery.Limit == 0 {
|
||||||
|
LPQuery.Limit = 10
|
||||||
|
}
|
||||||
|
|
||||||
|
s := storage.NewStorageCatalog()
|
||||||
|
count, items, err := s.GetCatalogItems(ctx, queries, LPQuery.Limit, (LPQuery.Page-1)*LPQuery.Limit)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
meta.RequestFinished = time.Now().Unix()
|
||||||
|
c.JSON(500,
|
||||||
|
models.Response{
|
||||||
|
Status: status.STATUS_SERVER_ERROR,
|
||||||
|
Info: fmt.Sprintf("Cannot resolve request. Details: %s", err.Error()),
|
||||||
|
Meta: &meta})
|
||||||
|
}
|
||||||
|
|
||||||
|
meta.Limit = LPQuery.Limit
|
||||||
|
meta.Page = LPQuery.Page
|
||||||
|
meta.RequestFinished = time.Now().Unix()
|
||||||
|
meta.Count = count
|
||||||
|
|
||||||
|
c.JSON(200, models.Response{
|
||||||
|
Status: status.STATUS_OK,
|
||||||
|
Data: items,
|
||||||
|
Meta: &meta,
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *handlers) GetCatalogItem(c *gin.Context) {
|
func (h *handlers) GetCatalogItem(c *gin.Context) {
|
||||||
code := c.Param("code")
|
|
||||||
if code == "" {
|
|
||||||
c.JSON(400, models.Response{Status: 400, Info: "product \"Code\" should be provided"})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := services.GetCatalogItem(code)
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(404, models.Response{Status: 404, Info: err.Error()})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
c.JSON(200, resp)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *handlers) Count(c *gin.Context) {
|
|
||||||
c.JSON(200, models.Response{Status: 200, Info: fmt.Sprintf("%d", services.GetCatalogItemsCount())})
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,6 @@ type handlers struct{}
|
||||||
type Handlers interface {
|
type Handlers interface {
|
||||||
GetFilters(c *gin.Context)
|
GetFilters(c *gin.Context)
|
||||||
GetCatalogItems(c *gin.Context)
|
GetCatalogItems(c *gin.Context)
|
||||||
GetCatalogItem(c *gin.Context)
|
|
||||||
Count(c *gin.Context)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetHandlers() Handlers {
|
func GetHandlers() Handlers {
|
||||||
|
|
|
@ -1,38 +1,41 @@
|
||||||
package endpoints
|
package endpoints
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"context"
|
||||||
|
"fmt"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"relynolli-server/internal"
|
"relynolli-server/models"
|
||||||
|
"relynolli-server/status"
|
||||||
|
"relynolli-server/storage"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type filterValues struct {
|
|
||||||
Id int `json:"id"`
|
|
||||||
Value string `json:"value"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type filterStruct struct {
|
|
||||||
Id int `json:"id"`
|
|
||||||
Code string `json:"code"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Values []filterValues `json:"values"`
|
|
||||||
valuesString []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *handlers) GetFilters(c *gin.Context) {
|
func (h *handlers) GetFilters(c *gin.Context) {
|
||||||
stmt := "select * from api_filter;"
|
|
||||||
var responseData []filterStruct
|
|
||||||
|
|
||||||
db := internal.InitDatabase()
|
meta := models.Meta{
|
||||||
rows := db.Query(stmt)
|
RequestStarted: time.Now().Unix(),
|
||||||
for rows.Next() {
|
|
||||||
filter := filterStruct{}
|
|
||||||
// grab data from db
|
|
||||||
rows.Scan(&filter.Id, &filter.Code, &filter.Name, &filter.valuesString)
|
|
||||||
json.Unmarshal(filter.valuesString, &filter.Values)
|
|
||||||
// parse data as json
|
|
||||||
responseData = append(responseData, filter)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(200, responseData)
|
s := storage.NewStorageCatalog()
|
||||||
|
ctx := context.Background()
|
||||||
|
count, items, err := s.GetFilters(ctx)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
meta.RequestFinished = time.Now().Unix()
|
||||||
|
c.JSON(500, models.Response{
|
||||||
|
Status: status.STATUS_SERVER_ERROR,
|
||||||
|
Info: fmt.Sprintf("Internal Server Error: %s", err.Error()),
|
||||||
|
Meta: &meta,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
meta.RequestFinished = time.Now().Unix()
|
||||||
|
meta.Count = count
|
||||||
|
|
||||||
|
c.JSON(200, models.Response{
|
||||||
|
Status: status.STATUS_OK,
|
||||||
|
Data: &items,
|
||||||
|
Meta: &meta,
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
package catalog
|
package catalog
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/gin-contrib/cache"
|
||||||
|
"os"
|
||||||
"relynolli-server/handlers/catalog/endpoints"
|
"relynolli-server/handlers/catalog/endpoints"
|
||||||
"relynolli-server/internal"
|
"relynolli-server/internal"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gin-contrib/cache"
|
// "relynolli-server/internal"
|
||||||
|
// "time"
|
||||||
|
|
||||||
|
// "github.com/gin-contrib/cache"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -13,8 +18,15 @@ func HandleRoutes(parent *gin.RouterGroup) {
|
||||||
h := endpoints.GetHandlers()
|
h := endpoints.GetHandlers()
|
||||||
cacheStore := internal.InitCacheStore()
|
cacheStore := internal.InitCacheStore()
|
||||||
catalog := parent.Group("/catalog")
|
catalog := parent.Group("/catalog")
|
||||||
catalog.GET("/filters", cache.CachePage(cacheStore, 15, h.GetFilters))
|
if os.Getenv("IS_PROD") == "1" {
|
||||||
catalog.GET("/count", cache.CachePage(cacheStore, 15 * time.Minute, h.Count))
|
// Caching for production usage
|
||||||
catalog.GET("", cache.CachePage(cacheStore, 15 * time.Minute, h.GetCatalogItems))
|
catalog.GET("", cache.CachePage(cacheStore, 15*time.Minute, h.GetCatalogItems))
|
||||||
catalog.GET("/:code", cache.CachePage(cacheStore, 15 * time.Minute, h.GetCatalogItem))
|
}
|
||||||
|
|
||||||
|
catalog.GET("", h.GetCatalogItems)
|
||||||
|
catalog.GET("/filters", h.GetFilters)
|
||||||
|
|
||||||
|
// catalog.GET("/filters", cache.CachePage(cacheStore, 15, h.GetFilters))
|
||||||
|
// catalog.GET("/count", cache.CachePage(cacheStore, 15 * time.Minute, h.Count))
|
||||||
|
// catalog.GET("/:code", cache.CachePage(cacheStore, 15 * time.Minute, h.GetCatalogItem))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package order
|
package order
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"relynolli-server/handlers/order/endpoints"
|
"relynolli-server/handlers/order/endpoints"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
func HandleRoutes(parent *gin.RouterGroup) {
|
func HandleRoutes(parent *gin.RouterGroup) {
|
||||||
|
|
|
@ -2,16 +2,16 @@ package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"relynolli-server/handlers/cart"
|
// "relynolli-server/handlers/cart"
|
||||||
"relynolli-server/handlers/catalog"
|
"relynolli-server/handlers/catalog"
|
||||||
"relynolli-server/handlers/order"
|
// "relynolli-server/handlers/order"
|
||||||
"relynolli-server/handlers/validate"
|
// "relynolli-server/handlers/validate"
|
||||||
)
|
)
|
||||||
|
|
||||||
func InitializeRouter(router *gin.Engine) {
|
func InitializeRouter(router *gin.Engine) {
|
||||||
APIV1Router := router.Group("/api/v1")
|
APIV1Router := router.Group("/api/v1")
|
||||||
catalog.HandleRoutes(APIV1Router)
|
catalog.HandleRoutes(APIV1Router)
|
||||||
cart.HandleRoutes(APIV1Router)
|
// cart.HandleRoutes(APIV1Router)
|
||||||
order.HandleRoutes(APIV1Router)
|
// order.HandleRoutes(APIV1Router)
|
||||||
validate.HandleRoutes(APIV1Router)
|
// validate.HandleRoutes(APIV1Router)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,25 +3,22 @@ package internal
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/uptrace/bun/extra/bundebug"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
|
||||||
|
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/uptrace/bun"
|
||||||
|
"github.com/uptrace/bun/dialect/mysqldialect"
|
||||||
)
|
)
|
||||||
|
|
||||||
type database struct {
|
type database struct {
|
||||||
instance *sqlx.DB
|
instance *bun.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
type Database interface {
|
type Database interface {
|
||||||
GetInstance() *sqlx.DB
|
GetInstance() *bun.DB
|
||||||
Close()
|
|
||||||
Query(stmt string) *sqlx.Rows
|
|
||||||
Execute(stmt string) sql.Result
|
|
||||||
FetchRows(stmt string, dest interface{})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -30,27 +27,31 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func initialize() {
|
func initialize() {
|
||||||
db, err := sqlx.Open("mysql", fmt.Sprintf(
|
db, err := sql.Open("mysql", fmt.Sprintf(
|
||||||
"%s:%s@tcp(%s)/%s",
|
"%s:%s@tcp(%s)/%s",
|
||||||
os.Getenv("MYSQL_USER"),
|
os.Getenv("MYSQL_USER"),
|
||||||
os.Getenv("MYSQL_PASSWORD"),
|
os.Getenv("MYSQL_PASSWORD"),
|
||||||
os.Getenv("MYSQL_HOST"),
|
os.Getenv("MYSQL_HOST"),
|
||||||
os.Getenv("MYSQL_DATABASE")))
|
os.Getenv("MYSQL_DATABASE")))
|
||||||
|
|
||||||
db.SetConnMaxLifetime(time.Minute * 3)
|
|
||||||
db.SetMaxOpenConns(3)
|
|
||||||
db.SetMaxIdleConns(3)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
conErr := db.Ping()
|
|
||||||
|
// Resolve instances of bun
|
||||||
|
|
||||||
|
ormDb := bun.NewDB(db, mysqldialect.New())
|
||||||
|
ormDb.AddQueryHook(bundebug.NewQueryHook())
|
||||||
|
|
||||||
|
// Check Connection
|
||||||
|
conErr := ormDb.Ping()
|
||||||
|
|
||||||
if conErr != nil {
|
if conErr != nil {
|
||||||
panic(conErr)
|
panic(conErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println("Connection to db succeded")
|
log.Println("Connection to db succeded")
|
||||||
instance = &database{instance: db}
|
instance = &database{instance: ormDb}
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitDatabase() Database {
|
func InitDatabase() Database {
|
||||||
|
@ -60,39 +61,6 @@ func InitDatabase() Database {
|
||||||
return instance
|
return instance
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *database) GetInstance() *sqlx.DB {
|
func (d *database) GetInstance() *bun.DB {
|
||||||
return db.instance
|
return d.instance
|
||||||
}
|
|
||||||
|
|
||||||
func (db *database) Close() {
|
|
||||||
defer log.Println("Connection to database was closed")
|
|
||||||
err := db.instance.Close()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (db *database) Query(stmt string) *sqlx.Rows {
|
|
||||||
rows, err := db.instance.Queryx(stmt)
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return rows
|
|
||||||
}
|
|
||||||
|
|
||||||
func (db *database) Execute(stmt string) sql.Result {
|
|
||||||
result, err := db.instance.Exec(stmt)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
type FetchRowStruct []interface{}
|
|
||||||
|
|
||||||
func (db *database) FetchRows(stmt string, dest interface{}) {
|
|
||||||
err := db.instance.Select(dest, stmt)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
2
main.go
2
main.go
|
@ -28,7 +28,7 @@ func main() {
|
||||||
rdb := internal.InitRedis()
|
rdb := internal.InitRedis()
|
||||||
|
|
||||||
handlers.InitializeRouter(server)
|
handlers.InitializeRouter(server)
|
||||||
defer db.Close()
|
defer db.GetInstance().Close()
|
||||||
defer rdb.Close()
|
defer rdb.Close()
|
||||||
|
|
||||||
gracefullyShutDown := make(chan os.Signal, 1)
|
gracefullyShutDown := make(chan os.Signal, 1)
|
||||||
|
|
|
@ -1,47 +1,47 @@
|
||||||
package models
|
package models
|
||||||
|
|
||||||
type CatalogStruct struct {
|
// type CatalogStruct struct {
|
||||||
Id int
|
// Id int
|
||||||
Code string
|
// Code string
|
||||||
Name string
|
// Name string
|
||||||
IsActive int `json:"is_active" db:"is_active"`
|
// IsActive int `json:"is_active" db:"is_active"`
|
||||||
Properties []byte
|
// Properties []byte
|
||||||
DetailText string `json:"detailText" db:"detailText"`
|
// DetailText string `json:"detailText" db:"detailText"`
|
||||||
Price []byte
|
// Price []byte
|
||||||
AvailableQuantity int `json:"availableQuantity,omitempty" db:"available_quantity"`
|
// AvailableQuantity int `json:"availableQuantity,omitempty" db:"available_quantity"`
|
||||||
}
|
// }
|
||||||
|
|
||||||
type CatalogStructWeb struct {
|
// type CatalogStructWeb struct {
|
||||||
Id int `json:"id"`
|
// Id int `json:"id"`
|
||||||
Code string `json:"code"`
|
// Code string `json:"code"`
|
||||||
Name string `json:"name"`
|
// Name string `json:"name"`
|
||||||
IsActive int `json:"is_active" db:"is_active"`
|
// IsActive int `json:"is_active" db:"is_active"`
|
||||||
Properties map[string]interface{} `json:"properties"`
|
// Properties map[string]interface{} `json:"properties"`
|
||||||
DetailText string `json:"detailText" db:"detailText"`
|
// DetailText string `json:"detailText" db:"detailText"`
|
||||||
Price map[string]interface{} `json:"price"`
|
// Price map[string]interface{} `json:"price"`
|
||||||
AvailableQuantity int `json:"availableQuantity,omitempty" db:"available_quantity"`
|
// AvailableQuantity int `json:"availableQuantity,omitempty" db:"available_quantity"`
|
||||||
}
|
// }
|
||||||
|
|
||||||
type CatalogWithQuantityWeb struct {
|
// type CatalogWithQuantityWeb struct {
|
||||||
Id int `json:"id"`
|
// Id int `json:"id"`
|
||||||
Code string `json:"code"`
|
// Code string `json:"code"`
|
||||||
Name string `json:"name"`
|
// Name string `json:"name"`
|
||||||
IsActive int `json:"is_active"`
|
// IsActive int `json:"is_active"`
|
||||||
Properties map[string]interface{} `json:"properties"`
|
// Properties map[string]interface{} `json:"properties"`
|
||||||
DetailText string `json:"detailText"`
|
// DetailText string `json:"detailText"`
|
||||||
Price map[string]interface{} `json:"price"`
|
// Price map[string]interface{} `json:"price"`
|
||||||
Quantity int `json:"quantity"`
|
// Quantity int `json:"quantity"`
|
||||||
AvailableQuantity int `json:"available_quantity" db:"available_quantity"`
|
// AvailableQuantity int `json:"available_quantity" db:"available_quantity"`
|
||||||
}
|
// }
|
||||||
|
|
||||||
type CatalogWithQuantity struct {
|
// type CatalogWithQuantity struct {
|
||||||
Id int
|
// Id int
|
||||||
Code string
|
// Code string
|
||||||
Name string
|
// Name string
|
||||||
IsActive int `json:"is_active" db:"is_active"`
|
// IsActive int `json:"is_active" db:"is_active"`
|
||||||
Properties []byte
|
// Properties []byte
|
||||||
DetailText string `json:"detailText" db:"detailText"`
|
// DetailText string `json:"detailText" db:"detailText"`
|
||||||
Price []byte
|
// Price []byte
|
||||||
Quantity int `json:"quantity"`
|
// Quantity int `json:"quantity"`
|
||||||
AvailableQuantity int `json:"available_quantity" db:"available_quantity"`
|
// AvailableQuantity int `json:"available_quantity" db:"available_quantity"`
|
||||||
}
|
// }
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
package catalog
|
||||||
|
|
||||||
|
import "github.com/uptrace/bun"
|
||||||
|
|
||||||
|
type DBCatalog struct {
|
||||||
|
bun.BaseModel `bun:"select:api_catalog"`
|
||||||
|
Id int64 `bun:"id" json:"id"`
|
||||||
|
Code string `bun:"code" json:"code"`
|
||||||
|
Name string `bun:"name" json:"name"`
|
||||||
|
IsActive bool `bun:"is_active,type:integer" json:"isActive"`
|
||||||
|
Properties *DBCatalogProperties `bun:"properties" json:"properties"`
|
||||||
|
DetailText string `bun:"detailText" json:"detailText"`
|
||||||
|
Price *DBCatalogPrice `bun:"price" json:"price"`
|
||||||
|
AvailableQuantity int64 `bun:"available_quantity" json:"availableQuantity"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DBCatalogProperties struct {
|
||||||
|
Acea string `json:"acea,omitempty"`
|
||||||
|
Width string `json:"width,omitempty"`
|
||||||
|
Height string `json:"height,omitempty"`
|
||||||
|
Length string `json:"length,omitempty"`
|
||||||
|
Volume string `json:"volume,omitempty"`
|
||||||
|
Weight string `json:"weight,omitempty"`
|
||||||
|
Mileage string `json:"mileage,omitempty"`
|
||||||
|
BoxType string `json:"box_type,omitempty"`
|
||||||
|
Category string `json:"category,omitempty"`
|
||||||
|
OilType string `json:"oil_type,omitempty"`
|
||||||
|
Documents []string `json:"documents,omitempty"`
|
||||||
|
UseAreas string `json:"use_areas,omitempty"`
|
||||||
|
Viscosity string `json:"viscosity,omitempty"`
|
||||||
|
AcidIndex string `json:"acid_index,omitempty"`
|
||||||
|
MainImage []string `json:"main_image,omitempty"`
|
||||||
|
PourPoint string `json:"pour_point,omitempty"`
|
||||||
|
FlashPoint string `json:"flash_point,omitempty"`
|
||||||
|
Subcategory string `json:"subcategory,omitempty"`
|
||||||
|
VendorCode string `json:"vendor_code,omitempty"`
|
||||||
|
ApiStandart string `json:"api_standart,omitempty"`
|
||||||
|
Requirements string `json:"requirements,omitempty"`
|
||||||
|
ViscosityIndex string `json:"viscosity_index,omitempty"`
|
||||||
|
ViscosityKinematic string `json:"viscosity_kinematic,omitempty"`
|
||||||
|
TribologicalProperties string `json:"tribological_properties,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DBCatalogPrice struct {
|
||||||
|
BASE float64 `json:"BASE"`
|
||||||
|
OPTMAX float64 `json:"OPTMAX,omitempty"`
|
||||||
|
OPTMIN float64 `json:"OPTMIN,omitempty"`
|
||||||
|
MOC float64 `json:"Мелко-Оптовая Цена (МОЦ),omitempty"`
|
||||||
|
KOC float64 `json:"Крупно-Оптовая Цена (КОЦ),omitempty"`
|
||||||
|
MCP float64 `json:"Минимальная Цена Продаж (МЦП),omitempty"`
|
||||||
|
RRC float64 `json:"Рекомендуемая Розничная цена (РРЦ),omitempty"`
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package catalog
|
||||||
|
|
||||||
|
type DomainCatalog struct {
|
||||||
|
// bun.BaseModel `bun:"select:api_catalog"`
|
||||||
|
Id int64
|
||||||
|
Code string
|
||||||
|
Name string
|
||||||
|
IsActive bool `bun:"is_active,type:integer"`
|
||||||
|
Properties string `bun:"properties"`
|
||||||
|
DetailText string `bun:"detailText"`
|
||||||
|
Price string `bun:"price"`
|
||||||
|
AvailableQunatity int64 `bun:"available_quantity"`
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
package catalog
|
|
@ -0,0 +1,16 @@
|
||||||
|
package filters
|
||||||
|
|
||||||
|
import "github.com/uptrace/bun"
|
||||||
|
|
||||||
|
type DBFilter struct {
|
||||||
|
bun.BaseModel `bun:"select:api_filter"`
|
||||||
|
Id int64 `bun:"id" json:"id"`
|
||||||
|
Code string `bun:"code" json:"code"`
|
||||||
|
Name string `bun:"name" json:"name"`
|
||||||
|
Values *[]DBFilterValues `bun:"values" json:"values"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DBFilterValues struct {
|
||||||
|
Id int64 `json:"id"`
|
||||||
|
Value string `json:"value"`
|
||||||
|
}
|
|
@ -1,7 +1,19 @@
|
||||||
package models
|
package models
|
||||||
|
|
||||||
|
import "relynolli-server/status"
|
||||||
|
|
||||||
type Response struct {
|
type Response struct {
|
||||||
Status int `json:"status"`
|
Status status.Status `json:"status"`
|
||||||
Info string `json:"info,omitempty"`
|
Info string `json:"info,omitempty"`
|
||||||
Data interface{} `json:"data,omitempty"`
|
Data interface{} `json:"data,omitempty"`
|
||||||
|
|
||||||
|
Meta *Meta `json:"meta"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Meta struct {
|
||||||
|
RequestStarted int64 `json:"requestStarted"`
|
||||||
|
RequestFinished int64 `json:"requestFinished"`
|
||||||
|
Page int `json:"page,omitempty"`
|
||||||
|
Limit int `json:"limit,omitempty"`
|
||||||
|
Count int `json:"count,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
package status
|
||||||
|
|
||||||
|
type Status string
|
||||||
|
|
||||||
|
const (
|
||||||
|
STATUS_OK Status = "OK"
|
||||||
|
STATUS_NOT_FOUND Status = "not_found"
|
||||||
|
STATUS_BAD_REQUEST Status = "bad_request"
|
||||||
|
STATUS_SERVER_ERROR Status = "internal_server_error"
|
||||||
|
)
|
|
@ -0,0 +1,15 @@
|
||||||
|
package storage
|
||||||
|
|
||||||
|
import "context"
|
||||||
|
|
||||||
|
type StorageCart interface {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *storage) GetCartItem(ctx context.Context) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *storage) GetCartItems(ctx context.Context) {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,83 @@
|
||||||
|
package storage
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
cmap "github.com/orcaman/concurrent-map/v2"
|
||||||
|
"github.com/uptrace/bun"
|
||||||
|
"relynolli-server/internal"
|
||||||
|
"relynolli-server/models/catalog"
|
||||||
|
filters2 "relynolli-server/models/filters"
|
||||||
|
"slices"
|
||||||
|
)
|
||||||
|
|
||||||
|
type StorageCatalog interface {
|
||||||
|
GetCatalogItem(ctx context.Context, id *int64) (*catalog.DBCatalog, error)
|
||||||
|
GetCatalogItems(ctx context.Context, filters cmap.ConcurrentMap[string, []string], limit int, offset int) (int, *[]catalog.DBCatalog, error)
|
||||||
|
GetFilters(ctx context.Context) (int, *[]filters2.DBFilter, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStorageCatalog() StorageCatalog {
|
||||||
|
if instance == nil {
|
||||||
|
instance = &storage{
|
||||||
|
db: internal.InitDatabase().GetInstance(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return instance
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *storage) GetCatalogItem(ctx context.Context, id *int64) (*catalog.DBCatalog, error) {
|
||||||
|
db := internal.InitDatabase().GetInstance()
|
||||||
|
model := new(catalog.DBCatalog)
|
||||||
|
|
||||||
|
err := db.NewSelect().Model(model).Where("id = ?", id).Where("available_quantity > 0").Where("is_available = 1").Scan(ctx)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return model, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildFilterGroup(ctx context.Context, q *bun.SelectQuery, filters *cmap.ConcurrentMap[string, []string]) *bun.SelectQuery {
|
||||||
|
db := internal.InitDatabase().GetInstance()
|
||||||
|
availableFilters := new([]filters2.DBFilter)
|
||||||
|
|
||||||
|
//Get filters
|
||||||
|
db.NewSelect().Model(availableFilters).Where("code in (?)", bun.In(filters.Keys())).Scan(ctx)
|
||||||
|
|
||||||
|
for _, filter := range filters.Keys() {
|
||||||
|
if !slices.ContainsFunc(*availableFilters, func(elem filters2.DBFilter) bool {
|
||||||
|
return elem.Code == filter
|
||||||
|
}) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
q = q.WhereGroup(" AND ", func(query *bun.SelectQuery) *bun.SelectQuery {
|
||||||
|
values, _ := filters.Get(filter)
|
||||||
|
for _, val := range values {
|
||||||
|
query = q.WhereOr(fmt.Sprintf("properties->>'$.%s' = ?", filter), val)
|
||||||
|
}
|
||||||
|
return query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return q
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *storage) GetCatalogItems(ctx context.Context, filters cmap.ConcurrentMap[string, []string], limit int, offset int) (int, *[]catalog.DBCatalog, error) {
|
||||||
|
db := internal.InitDatabase().GetInstance()
|
||||||
|
model := new([]catalog.DBCatalog)
|
||||||
|
filterQuery := db.NewSelect().Model(model).Where("is_active = 1").Where("available_quantity > 0")
|
||||||
|
count, _ := buildFilterGroup(ctx, filterQuery, &filters).Limit(limit).Offset(offset).ScanAndCount(ctx)
|
||||||
|
|
||||||
|
return count, model, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *storage) GetFilters(ctx context.Context) (int, *[]filters2.DBFilter, error) {
|
||||||
|
models := new([]filters2.DBFilter)
|
||||||
|
db := internal.InitDatabase().GetInstance()
|
||||||
|
count, err := db.NewSelect().Model(models).ScanAndCount(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return 0, nil, err
|
||||||
|
}
|
||||||
|
return count, models, nil
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package storage
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/uptrace/bun"
|
||||||
|
)
|
||||||
|
|
||||||
|
type storage struct {
|
||||||
|
db *bun.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
var instance *storage = nil
|
Loading…
Reference in New Issue