get tasks + insert result
This commit is contained in:
parent
47700dfd14
commit
718101ee67
6 changed files with 268 additions and 8 deletions
|
|
@ -21,7 +21,7 @@ func New(deps Deps) *Handler {
|
|||
r := newRepo(deps.DB)
|
||||
s := newService(r, deps.Utils, deps.UserProvider)
|
||||
c := newController(s, deps.Utils)
|
||||
p := newProvider()
|
||||
p := newProvider(s, deps.Utils)
|
||||
|
||||
return &Handler{
|
||||
controller: c,
|
||||
|
|
|
|||
|
|
@ -44,3 +44,9 @@ type ExtraData struct {
|
|||
OriginId int64
|
||||
URL string
|
||||
}
|
||||
|
||||
type taskData struct {
|
||||
MerchUuid string
|
||||
OriginName string
|
||||
Url string
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,18 +3,93 @@ package merch
|
|||
import (
|
||||
"context"
|
||||
"merch-api/internal/common"
|
||||
"merch-api/pkg/utils"
|
||||
)
|
||||
|
||||
type provider struct{}
|
||||
const providerLogHeader string = "[provider]"
|
||||
|
||||
func newProvider() *provider {
|
||||
return &provider{}
|
||||
type provider struct {
|
||||
service *service
|
||||
utils utils.Utils
|
||||
}
|
||||
|
||||
func newProvider(s *service, u utils.Utils) *provider {
|
||||
return &provider{
|
||||
service: s,
|
||||
utils: u,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *provider) GetTasks(ctx context.Context) ([]common.Task, error) {
|
||||
return nil, nil
|
||||
rawTasks, err := p.service.repo.getTaskData(ctx)
|
||||
if err != nil {
|
||||
logErr(providerLogHeader, err)
|
||||
return nil, err
|
||||
}
|
||||
return p.convertTasks(rawTasks), nil
|
||||
}
|
||||
|
||||
func (p *provider) InsertRecords(ctx context.Context) error {
|
||||
func (p *provider) InsertPrices(ctx context.Context, rawPrices []common.Result) error {
|
||||
if rawPrices == nil || len(rawPrices) == 0 {
|
||||
logDebug(providerLogHeader, "no prices given")
|
||||
return nil
|
||||
}
|
||||
|
||||
var uuids []string
|
||||
for _, rawPrice := range rawPrices {
|
||||
uuids = append(uuids, rawPrice.MerchUuid)
|
||||
}
|
||||
|
||||
uuidMap, err := p.service.getMerchUuidMap(ctx, uuids)
|
||||
if err != nil {
|
||||
logErr(serviceLogHeader, err)
|
||||
return err
|
||||
}
|
||||
|
||||
originIds, _, err := p.service.getOriginsMaps(ctx)
|
||||
if err != nil {
|
||||
logErr(serviceLogHeader, err)
|
||||
return err
|
||||
}
|
||||
|
||||
now := p.utils.TimeNowUTC()
|
||||
var insertPrices []Price
|
||||
for _, rawPrice := range rawPrices {
|
||||
insertPrices = append(insertPrices, Price{
|
||||
CreatedAt: now,
|
||||
UpdatedAt: p.utils.NullTimeFromNow(now),
|
||||
MerchId: uuidMap[rawPrice.MerchUuid],
|
||||
OriginId: originIds[rawPrice.OriginName],
|
||||
Price: int(rawPrice.Price),
|
||||
})
|
||||
}
|
||||
|
||||
if err = p.service.repo.insertPrices(ctx, insertPrices); err != nil {
|
||||
logErr(serviceLogHeader, err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *provider) convertTasks(rawTasks []taskData) []common.Task {
|
||||
convert := make(map[string]*common.Task, len(rawTasks))
|
||||
for _, item := range rawTasks {
|
||||
task, ok := convert[item.MerchUuid]
|
||||
if !ok {
|
||||
task = &common.Task{
|
||||
MerchUuid: item.MerchUuid,
|
||||
Origins: make(map[string]string),
|
||||
}
|
||||
convert[item.MerchUuid] = task
|
||||
}
|
||||
task.Origins[item.OriginName] = item.Url
|
||||
}
|
||||
|
||||
result := make([]common.Task, 0, len(convert))
|
||||
for _, task := range convert {
|
||||
result = append(result, *task)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
|
|
|||
75
internal/merch/provider_test.go
Normal file
75
internal/merch/provider_test.go
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
package merch
|
||||
|
||||
import (
|
||||
"merch-api/internal/common"
|
||||
"merch-api/pkg/utils"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_provider_convertTasks(t *testing.T) {
|
||||
type fields struct {
|
||||
service *service
|
||||
utils utils.Utils
|
||||
}
|
||||
type args struct {
|
||||
rawTasks []taskData
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
want []common.Task
|
||||
}{
|
||||
{
|
||||
name: "Success convert tasks",
|
||||
fields: fields{
|
||||
service: nil,
|
||||
utils: nil,
|
||||
},
|
||||
args: args{[]taskData{
|
||||
{"1", "surugaya", "url"},
|
||||
{"1", "mandarake", "url"},
|
||||
{"1", "amiami", "url"},
|
||||
{"2", "surugaya", "url"},
|
||||
{"2", "mandarake", "url"},
|
||||
{"2", "amiami", "url"},
|
||||
{"3", "surugaya", "url"},
|
||||
{"3", "amiami", "url"},
|
||||
{"4", "amiami", "url"},
|
||||
}},
|
||||
want: []common.Task{
|
||||
{"1", map[string]string{"surugaya": "url", "mandarake": "url", "amiami": "url"}},
|
||||
{"2", map[string]string{"surugaya": "url", "mandarake": "url", "amiami": "url"}},
|
||||
{"3", map[string]string{"surugaya": "url", "amiami": "url"}},
|
||||
{"4", map[string]string{"amiami": "url"}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Success convert tasks",
|
||||
fields: fields{
|
||||
service: nil,
|
||||
utils: nil,
|
||||
},
|
||||
args: args{[]taskData{
|
||||
{"1", "surugaya", "url"},
|
||||
{"1", "mandarake", "url"},
|
||||
{"1", "amiami", "url"},
|
||||
}},
|
||||
want: []common.Task{
|
||||
{"1", map[string]string{"surugaya": "url", "mandarake": "url", "amiami": "url"}},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
p := &provider{
|
||||
service: tt.fields.service,
|
||||
utils: tt.fields.utils,
|
||||
}
|
||||
if got := p.convertTasks(tt.args.rawTasks); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("convertTasks() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -18,6 +18,7 @@ type Repository interface {
|
|||
getMany(ctx context.Context, userId int64) ([]merchDTO, error)
|
||||
|
||||
getMerchIdByUuid(ctx context.Context, userId int64, uuid string) (int64, error)
|
||||
getMerchUuidMap(ctx context.Context, merchUuids []string) (map[string]int64, error)
|
||||
|
||||
updateMerch(ctx context.Context, userId int64, merch *updateMerchDTO) (*merchDTO, error)
|
||||
updateExtraData(ctx context.Context, merchId int64, insertData []ExtraData) ([]ExtraData, error)
|
||||
|
|
@ -26,6 +27,8 @@ type Repository interface {
|
|||
deleteOneMerchRecord(ctx context.Context, userId int64, merchUuid string, delTime time.Time) error
|
||||
|
||||
Origins
|
||||
Prices
|
||||
Tasks
|
||||
}
|
||||
|
||||
type Origins interface {
|
||||
|
|
@ -34,6 +37,14 @@ type Origins interface {
|
|||
deleteOriginByName(ctx context.Context, name string, deletedAt sql.NullTime) error
|
||||
}
|
||||
|
||||
type Prices interface {
|
||||
insertPrices(ctx context.Context, prices []Price) error
|
||||
}
|
||||
|
||||
type Tasks interface {
|
||||
getTaskData(ctx context.Context) ([]taskData, error)
|
||||
}
|
||||
|
||||
type repo struct {
|
||||
db *pgxpool.Pool
|
||||
}
|
||||
|
|
@ -179,6 +190,35 @@ func (r *repo) getMerchIdByUuid(ctx context.Context, userId int64, uuid string)
|
|||
return merchId, nil
|
||||
}
|
||||
|
||||
func (r *repo) getMerchUuidMap(ctx context.Context, merchUuids []string) (map[string]int64, error) {
|
||||
q := `SELECT merch_uuid, id FROM merch WHERE deleted_at IS NULL AND merch_uuid = ANY($1)`
|
||||
|
||||
rows, err := r.db.Query(ctx, q, merchUuids)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var merchUuidMap map[string]int64
|
||||
for rows.Next() {
|
||||
var (
|
||||
uuid string
|
||||
id int64
|
||||
)
|
||||
if err = rows.Scan(&uuid, &id); err != nil {
|
||||
rows.Close()
|
||||
return nil, err
|
||||
}
|
||||
merchUuidMap[uuid] = id
|
||||
}
|
||||
|
||||
rows.Close()
|
||||
if err = rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return merchUuidMap, nil
|
||||
}
|
||||
|
||||
func (r *repo) deleteOneMerchRecord(ctx context.Context, userId int64, merchUuid string, delTime time.Time) error {
|
||||
tx, err := r.db.Begin(ctx)
|
||||
if err != nil {
|
||||
|
|
@ -263,3 +303,65 @@ func (r *repo) updateExtraData(ctx context.Context, merchId int64, insertData []
|
|||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (r *repo) insertPrices(ctx context.Context, prices []Price) error {
|
||||
q := `
|
||||
INSERT INTO merch_prices (created_at, updated_at, merch_id, origin_id, price)
|
||||
SELECT $1, $2, src.merch_id, src.origin_id, src.price
|
||||
FROM UNNEST(
|
||||
$3::bigint[],
|
||||
$4::bigint[],
|
||||
$5::int[]
|
||||
) AS src (merch_id, origin_id, price)
|
||||
`
|
||||
|
||||
var (
|
||||
merchIds []int64
|
||||
originIds []int64
|
||||
priceValues []int
|
||||
)
|
||||
|
||||
for _, price := range prices {
|
||||
merchIds = append(merchIds, price.MerchId)
|
||||
originIds = append(originIds, price.OriginId)
|
||||
priceValues = append(priceValues, price.Price)
|
||||
}
|
||||
|
||||
_, err := r.db.Exec(ctx, q, merchIds, originIds, priceValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *repo) getTaskData(ctx context.Context) ([]taskData, error) {
|
||||
q := `SELECT m.merch_uuid, med.url, mo.name
|
||||
FROM merch AS m
|
||||
JOIN merch_extra_data AS med ON m.id = med.merch_id
|
||||
JOIN merch_origins AS mo ON mo.id = med.origin_id
|
||||
WHERE m.deleted_at IS NULL
|
||||
AND med.deleted_at IS NULL
|
||||
AND mo.deleted_at IS NULL
|
||||
`
|
||||
rows, err := r.db.Query(ctx, q)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []taskData
|
||||
for rows.Next() {
|
||||
var t taskData
|
||||
if err = rows.Scan(&t.MerchUuid, &t.Url, &t.OriginName); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = append(result, t)
|
||||
}
|
||||
|
||||
rows.Close()
|
||||
if err = rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue