mock sync group editing: edit, save, and delete listings
This commit is contained in:
@@ -7,6 +7,8 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
@@ -45,6 +47,11 @@ type (
|
||||
Description string
|
||||
Count int64
|
||||
}
|
||||
|
||||
ListingWithOrderIndex struct {
|
||||
Listing
|
||||
OrderIndex int
|
||||
}
|
||||
)
|
||||
|
||||
func NewStore(logger *logging.Logger, db *pgxpool.Pool) *Store {
|
||||
@@ -648,6 +655,212 @@ func (db *Store) StartEditingMockSyncGroup(ctx context.Context, acctID, syncGrou
|
||||
return v.Int64, v.Valid, nil
|
||||
}
|
||||
|
||||
func (db *Store) SaveMockSyncGroupBeingEdited(ctx context.Context, acctID int64) (syncGroupID int64, err error) {
|
||||
err = db.beginTxn(ctx, func(tx pgx.Tx) error {
|
||||
// delete old sync group listings
|
||||
|
||||
rows, err := tx.Query(
|
||||
ctx,
|
||||
`
|
||||
WITH the_sync_group AS (
|
||||
SELECT
|
||||
sync_group_id
|
||||
FROM
|
||||
mock.sync_group_editing
|
||||
WHERE
|
||||
account_id = @account_id
|
||||
), deleted_indexes AS (
|
||||
DELETE FROM
|
||||
mock.sync_group_listing_order_indexes ind
|
||||
USING
|
||||
mock.sync_group_editing AS ed
|
||||
WHERE
|
||||
ed.account_id = @account_id
|
||||
AND ind.sync_group_id = ed.sync_group_id
|
||||
RETURNING
|
||||
sync_group_id
|
||||
)
|
||||
SELECT
|
||||
sync_group_id
|
||||
FROM
|
||||
deleted_indexes
|
||||
LIMIT
|
||||
1
|
||||
`,
|
||||
pgx.NamedArgs{
|
||||
"account_id": acctID,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to query editing sync group: %w", err)
|
||||
}
|
||||
|
||||
if syncGroupID, err = pgx.CollectExactlyOneRow(rows, pgx.RowTo[int64]); err != nil {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return consts.ErrNotFound
|
||||
}
|
||||
return fmt.Errorf("failed to scan row: %w", err)
|
||||
}
|
||||
|
||||
var listingCount int
|
||||
for _, in := range getAllMockShopSchemaInfos() {
|
||||
// look up edited sync group listings
|
||||
|
||||
rows, err := tx.Query(
|
||||
ctx,
|
||||
fmt.Sprintf(
|
||||
`
|
||||
SELECT
|
||||
order_index,
|
||||
shop_id,
|
||||
listing_id
|
||||
FROM
|
||||
%s el
|
||||
WHERE
|
||||
account_id = @account_id
|
||||
`,
|
||||
in.syncGroupEditingListingTable,
|
||||
),
|
||||
pgx.NamedArgs{
|
||||
"account_id": acctID,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to perform query: %w", err)
|
||||
}
|
||||
|
||||
vs, err := pgx.CollectRows(rows, pgx.RowToStructByNameLax[struct {
|
||||
Order_index int
|
||||
Shop_id pgtype.Text
|
||||
Listing_id pgtype.Text
|
||||
}])
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to scan rows: %w", err)
|
||||
}
|
||||
|
||||
if len(vs) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// fail if any shop_id's or listing_id's are NULL
|
||||
for _, v := range vs {
|
||||
if !v.Shop_id.Valid {
|
||||
return fmt.Errorf("%w: shop id missing on listing", consts.ErrConflict)
|
||||
}
|
||||
if !v.Listing_id.Valid {
|
||||
return fmt.Errorf("%w: listing id missing on listing", consts.ErrConflict)
|
||||
}
|
||||
}
|
||||
|
||||
// create new sync group listing order indexes
|
||||
|
||||
values := make([]string, len(vs))
|
||||
args := make(pgx.NamedArgs, len(vs))
|
||||
for i, v := range vs {
|
||||
values[i] = fmt.Sprintf("(@sync_group_id_%[1]d, @order_index_%[1]d)", i)
|
||||
args[fmt.Sprintf("sync_group_id_%d", i)] = syncGroupID
|
||||
args[fmt.Sprintf("order_index_%d", i)] = v.Order_index
|
||||
}
|
||||
listingCount += len(vs)
|
||||
|
||||
_, err = tx.Exec(
|
||||
ctx,
|
||||
fmt.Sprintf(
|
||||
`
|
||||
INSERT INTO
|
||||
mock.sync_group_listing_order_indexes (
|
||||
sync_group_id,
|
||||
order_index
|
||||
)
|
||||
VALUES
|
||||
%s
|
||||
`,
|
||||
strings.Join(values, ", "),
|
||||
),
|
||||
args,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete rows for sync group listing order indexes: %w", err)
|
||||
}
|
||||
|
||||
// create new sync group listings
|
||||
|
||||
values = make([]string, len(vs))
|
||||
args = make(pgx.NamedArgs, len(vs))
|
||||
for i, v := range vs {
|
||||
values[i] = fmt.Sprintf("(@account_id_%[1]d, @sync_group_id_%[1]d, @shop_id_%[1]d, @listing_id_%[1]d, @order_index_%[1]d)", i)
|
||||
args[fmt.Sprintf("account_id_%d", i)] = acctID
|
||||
args[fmt.Sprintf("sync_group_id_%d", i)] = syncGroupID
|
||||
args[fmt.Sprintf("shop_id_%d", i)] = v.Shop_id
|
||||
args[fmt.Sprintf("listing_id_%d", i)] = v.Listing_id
|
||||
args[fmt.Sprintf("order_index_%d", i)] = v.Order_index
|
||||
}
|
||||
|
||||
_, err = tx.Exec(
|
||||
ctx,
|
||||
fmt.Sprintf(
|
||||
`
|
||||
INSERT INTO
|
||||
%s (
|
||||
account_id,
|
||||
sync_group_id,
|
||||
shop_id,
|
||||
listing_id,
|
||||
order_index
|
||||
)
|
||||
VALUES
|
||||
%s
|
||||
`,
|
||||
in.syncGroupListingsTable,
|
||||
strings.Join(values, ", "),
|
||||
),
|
||||
args,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to perform query inserting new sync group listings: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// there must be at least two listings per sync group
|
||||
|
||||
if listingCount < 2 {
|
||||
return fmt.Errorf("%w: invalid number of listings for sync group: %d: minimum of two required", consts.ErrConflict, listingCount)
|
||||
}
|
||||
|
||||
// delete the sync group editing record
|
||||
// this will cascade the editing listing records
|
||||
|
||||
rows, err = tx.Query(
|
||||
ctx,
|
||||
`
|
||||
DELETE FROM
|
||||
mock.sync_group_editing
|
||||
WHERE
|
||||
account_id = @account_id
|
||||
RETURNING
|
||||
sync_group_id
|
||||
`,
|
||||
pgx.NamedArgs{
|
||||
"account_id": acctID,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to perform query deleting editing sync group: %w", err)
|
||||
}
|
||||
|
||||
if syncGroupID, err = pgx.CollectExactlyOneRow(rows, pgx.RowTo[int64]); err != nil {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return consts.ErrNotFound
|
||||
}
|
||||
return fmt.Errorf("failed to scan row: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return syncGroupID, err
|
||||
}
|
||||
|
||||
func (db *Store) CancelEditingOfMockSyncGroupForAccount(ctx context.Context, acctID int64) (prevSyncGroupID int64, prevSyncGroupExists bool, err error) {
|
||||
rows, err := db.db.Query(
|
||||
ctx,
|
||||
@@ -678,6 +891,156 @@ func (db *Store) CancelEditingOfMockSyncGroupForAccount(ctx context.Context, acc
|
||||
return prevSyncGroupID, true, nil
|
||||
}
|
||||
|
||||
func (db *Store) GetMockSyncGroupEditingListings(ctx context.Context, acctID int64) ([]ListingWithOrderIndex, error) {
|
||||
var (
|
||||
listings []ListingWithOrderIndex
|
||||
allOrderIndexes []int
|
||||
)
|
||||
//orderIndexPerListing := make(map[Platform]map[string]int)
|
||||
|
||||
err := db.beginReadonlyTxn(ctx, func(tx pgx.Tx) error {
|
||||
// get the mock sync group editing listings from each table
|
||||
|
||||
for _, in := range getAllMockShopSchemaInfos() {
|
||||
rows, err := tx.Query(
|
||||
ctx,
|
||||
fmt.Sprintf(
|
||||
`
|
||||
SELECT
|
||||
eli.shop_id,
|
||||
eli.listing_id,
|
||||
eli.order_index,
|
||||
li.name,
|
||||
li.count,
|
||||
li.sku,
|
||||
li.description,
|
||||
sh.name as shop_name
|
||||
FROM
|
||||
%s AS eli
|
||||
LEFT JOIN
|
||||
%s AS li
|
||||
USING
|
||||
(account_id, shop_id, listing_id)
|
||||
JOIN
|
||||
%s AS sh
|
||||
USING
|
||||
(account_id, shop_id)
|
||||
WHERE
|
||||
account_id = @account_id
|
||||
`,
|
||||
in.syncGroupEditingListingTable,
|
||||
in.listingsTable,
|
||||
in.shopTable,
|
||||
),
|
||||
pgx.NamedArgs{
|
||||
"account_id": acctID,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to perform query to get mock sync group editing listings: %w", err)
|
||||
}
|
||||
|
||||
vs, err := pgx.CollectRows(rows, pgx.RowToStructByNameLax[struct {
|
||||
Shop_id string
|
||||
Listing_id pgtype.Text
|
||||
Order_index int
|
||||
Name pgtype.Text
|
||||
Count pgtype.Int8
|
||||
Sku pgtype.Text
|
||||
Description pgtype.Text
|
||||
Shop_name string
|
||||
}])
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to scan rows: %w", err)
|
||||
}
|
||||
|
||||
for _, v := range vs {
|
||||
listings = append(listings, ListingWithOrderIndex{
|
||||
Listing: Listing{
|
||||
AccountShopListingIDs: NewAccountIDs(acctID).
|
||||
ShopID(in.platform, v.Shop_id).
|
||||
ListingID(v.Listing_id.String),
|
||||
ShopName: v.Shop_name,
|
||||
SKU: v.Sku.String,
|
||||
Name: v.Name.String,
|
||||
Description: v.Description.String,
|
||||
Count: v.Count.Int64,
|
||||
},
|
||||
OrderIndex: v.Order_index,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// loading the empty indexes, too
|
||||
rows, err := tx.Query(
|
||||
ctx,
|
||||
`
|
||||
SELECT
|
||||
order_index
|
||||
FROM
|
||||
mock.sync_group_editing_listing_order_indexes
|
||||
WHERE
|
||||
account_id = @account_id
|
||||
`,
|
||||
pgx.NamedArgs{
|
||||
"account_id": acctID,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to perform query: %w", err)
|
||||
}
|
||||
|
||||
if allOrderIndexes, err = pgx.CollectRows(rows, pgx.RowTo[int]); err != nil {
|
||||
return fmt.Errorf("failed to scan rows: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
slices.SortFunc(listings, func(a, b ListingWithOrderIndex) int {
|
||||
return a.OrderIndex - b.OrderIndex
|
||||
})
|
||||
|
||||
indexPerOrderIndex := make(map[int]int)
|
||||
for i, v := range listings {
|
||||
indexPerOrderIndex[v.OrderIndex] = i
|
||||
}
|
||||
|
||||
for _, i := range allOrderIndexes {
|
||||
if _, ok := indexPerOrderIndex[i]; ok {
|
||||
continue
|
||||
}
|
||||
|
||||
for j := i - 1; j >= 0; j -= 1 {
|
||||
index, ok := indexPerOrderIndex[j]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
// insert the new empty listing into the list
|
||||
|
||||
listings = slices.Insert(listings, index+1, ListingWithOrderIndex{
|
||||
Listing: Listing{
|
||||
AccountShopListingIDs: NewAccountIDs(acctID).
|
||||
ShopID("", "").
|
||||
ListingID(""),
|
||||
},
|
||||
OrderIndex: i,
|
||||
})
|
||||
|
||||
indexPerOrderIndex[i] = index + 1
|
||||
for k, v := range indexPerOrderIndex {
|
||||
if k > i {
|
||||
indexPerOrderIndex[k] = v + 1
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return listings, err
|
||||
}
|
||||
|
||||
func (db *Store) MockSyncGroupIsBeingEdited(ctx context.Context, acctID, syncGroupID int64) (bool, error) {
|
||||
rows, err := db.db.Query(
|
||||
ctx,
|
||||
@@ -709,6 +1072,395 @@ func (db *Store) MockSyncGroupIsBeingEdited(ctx context.Context, acctID, syncGro
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (db *Store) GetMockSyncGroupEditingListing(ctx context.Context, acctID, syncGroupID, orderIndex int64) (*Listing, error) {
|
||||
var listing *Listing
|
||||
|
||||
err := db.beginReadonlyTxn(ctx, func(tx pgx.Tx) error {
|
||||
// assert the sync group is being edited
|
||||
|
||||
rows, err := tx.Query(
|
||||
ctx,
|
||||
`
|
||||
SELECT
|
||||
true
|
||||
FROM
|
||||
mock.sync_group_editing
|
||||
WHERE
|
||||
account_id = @account_id
|
||||
AND sync_group_id = @sync_group_id
|
||||
`,
|
||||
pgx.NamedArgs{
|
||||
"account_id": acctID,
|
||||
"sync_group_id": syncGroupID,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to perform query: %w", err)
|
||||
}
|
||||
|
||||
if _, err := pgx.CollectExactlyOneRow(rows, pgx.RowTo[bool]); err != nil {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return consts.ErrNotFound
|
||||
}
|
||||
return fmt.Errorf("failed to scan rows: %w", err)
|
||||
}
|
||||
|
||||
// find the editing listing
|
||||
|
||||
for _, in := range getAllMockShopSchemaInfos() {
|
||||
rows, err := tx.Query(
|
||||
ctx,
|
||||
fmt.Sprintf(
|
||||
`
|
||||
SELECT
|
||||
eli.shop_id,
|
||||
eli.listing_id,
|
||||
eli.order_index,
|
||||
li.name,
|
||||
li.count,
|
||||
li.sku,
|
||||
li.description,
|
||||
sh.name as shop_name
|
||||
FROM
|
||||
%s AS eli
|
||||
JOIN
|
||||
%s AS li
|
||||
USING
|
||||
(account_id, shop_id, listing_id)
|
||||
JOIN
|
||||
%s AS sh
|
||||
USING
|
||||
(account_id, shop_id)
|
||||
WHERE
|
||||
account_id = @account_id
|
||||
AND eli.order_index = @order_index
|
||||
`,
|
||||
in.syncGroupEditingListingTable,
|
||||
in.listingsTable,
|
||||
in.shopTable,
|
||||
),
|
||||
pgx.NamedArgs{
|
||||
"account_id": acctID,
|
||||
"order_index": orderIndex,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to perform query to get mock sync group editing listings: %w", err)
|
||||
}
|
||||
|
||||
v, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByNameLax[struct {
|
||||
Shop_id string
|
||||
Listing_id string
|
||||
Order_index int
|
||||
Name string
|
||||
Count int64
|
||||
Sku string
|
||||
Description string
|
||||
Shop_name string
|
||||
}])
|
||||
if err != nil {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
continue
|
||||
}
|
||||
return fmt.Errorf("failed to scan rows: %w", err)
|
||||
}
|
||||
|
||||
listing = &Listing{
|
||||
AccountShopListingIDs: NewAccountIDs(acctID).
|
||||
ShopID(in.platform, v.Shop_id).
|
||||
ListingID(v.Listing_id),
|
||||
ShopName: v.Shop_name,
|
||||
SKU: v.Sku,
|
||||
Name: v.Name,
|
||||
Description: v.Description,
|
||||
Count: v.Count,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
return consts.ErrNotFound
|
||||
})
|
||||
|
||||
return listing, err
|
||||
}
|
||||
|
||||
func (db *Store) AddListingToMockSyncGroupBeingEdited(ctx context.Context, acctID int64) (syncGroupID int64, orderIndex int, err error) {
|
||||
err = db.beginTxn(ctx, func(tx pgx.Tx) error {
|
||||
// assert the sync group is being edited
|
||||
|
||||
rows, err := tx.Query(
|
||||
ctx,
|
||||
`
|
||||
SELECT
|
||||
sync_group_id
|
||||
FROM
|
||||
mock.sync_group_editing
|
||||
WHERE
|
||||
account_id = @account_id
|
||||
`,
|
||||
pgx.NamedArgs{
|
||||
"account_id": acctID,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to perform query: %w", err)
|
||||
}
|
||||
|
||||
syncGroupID, err = pgx.CollectExactlyOneRow(rows, pgx.RowTo[int64])
|
||||
if err != nil {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return consts.ErrNotFound
|
||||
}
|
||||
return fmt.Errorf("failed to scan rows: %w", err)
|
||||
}
|
||||
|
||||
rows, err = tx.Query(
|
||||
ctx,
|
||||
`
|
||||
WITH new_order_index AS (
|
||||
SELECT
|
||||
COALESCE(MAX(order_index)+1, 0) AS order_index
|
||||
FROM
|
||||
mock.sync_group_editing_listing_order_indexes
|
||||
)
|
||||
INSERT INTO
|
||||
mock.sync_group_editing_listing_order_indexes (
|
||||
account_id,
|
||||
order_index
|
||||
)
|
||||
SELECT
|
||||
@account_id,
|
||||
new_order_index.order_index
|
||||
FROM
|
||||
new_order_index
|
||||
RETURNING
|
||||
order_index
|
||||
`,
|
||||
pgx.NamedArgs{
|
||||
"account_id": acctID,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to insert new order index row: %w", err)
|
||||
}
|
||||
|
||||
orderIndex, err = pgx.CollectExactlyOneRow(rows, pgx.RowTo[int])
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to scan rows: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
return syncGroupID, orderIndex, err
|
||||
}
|
||||
|
||||
func (db *Store) SetShopInListingInMockSyncGroupBeingEdited(ctx context.Context, acctID, syncGroupID int64, orderIndex int, platform Platform, shopID string) error {
|
||||
in, ok := getMockShopSchemaInfo(platform)
|
||||
if !ok {
|
||||
return consts.ErrNotFound
|
||||
}
|
||||
|
||||
return db.beginTxn(ctx, func(tx pgx.Tx) error {
|
||||
// assert the sync group is being edited
|
||||
|
||||
rows, err := tx.Query(
|
||||
ctx,
|
||||
`
|
||||
SELECT
|
||||
true
|
||||
FROM
|
||||
mock.sync_group_editing
|
||||
WHERE
|
||||
account_id = @account_id
|
||||
AND sync_group_id = @sync_group_id
|
||||
`,
|
||||
pgx.NamedArgs{
|
||||
"account_id": acctID,
|
||||
"sync_group_id": syncGroupID,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to perform query: %w", err)
|
||||
}
|
||||
|
||||
if _, err := pgx.CollectExactlyOneRow(rows, pgx.RowTo[bool]); err != nil {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return consts.ErrNotFound
|
||||
}
|
||||
return fmt.Errorf("failed to scan rows: %w", err)
|
||||
}
|
||||
|
||||
// delete old listing: this will delete the store-specific listing row implicitly without the lookup
|
||||
|
||||
tags, err := tx.Exec(
|
||||
ctx,
|
||||
`
|
||||
DELETE FROM
|
||||
mock.sync_group_editing_listing_order_indexes
|
||||
WHERE
|
||||
account_id = @account_id
|
||||
AND order_index = @order_index
|
||||
`,
|
||||
pgx.NamedArgs{
|
||||
"account_id": acctID,
|
||||
"order_index": orderIndex,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to deleted order index record: %w", err)
|
||||
}
|
||||
if tags.RowsAffected() == 0 {
|
||||
return consts.ErrNotFound
|
||||
}
|
||||
|
||||
// create new listing
|
||||
|
||||
_, err = tx.Exec(
|
||||
ctx,
|
||||
fmt.Sprintf(
|
||||
`
|
||||
WITH new_order_index_row(account_id, order_index) AS (
|
||||
INSERT INTO
|
||||
mock.sync_group_editing_listing_order_indexes (
|
||||
account_id,
|
||||
order_index
|
||||
)
|
||||
VALUES (
|
||||
@account_id,
|
||||
@order_index
|
||||
)
|
||||
RETURNING
|
||||
account_id,
|
||||
order_index
|
||||
)
|
||||
INSERT INTO
|
||||
%s AS eli (
|
||||
account_id,
|
||||
order_index,
|
||||
shop_id
|
||||
)
|
||||
SELECT
|
||||
account_id,
|
||||
order_index,
|
||||
@shop_id as shop_id
|
||||
FROM
|
||||
new_order_index_row
|
||||
`,
|
||||
in.syncGroupEditingListingTable,
|
||||
),
|
||||
pgx.NamedArgs{
|
||||
"account_id": acctID,
|
||||
"order_index": orderIndex,
|
||||
"shop_id": shopID,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to perform query to insert mock sync group editing listings: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (db *Store) SetListingInListingInMockSyncGroupBeingEdited(ctx context.Context, acctID, syncGroupID int64, orderIndex int, listingID string) error {
|
||||
return db.beginTxn(ctx, func(tx pgx.Tx) error {
|
||||
// assert the sync group is being edited
|
||||
|
||||
rows, err := tx.Query(
|
||||
ctx,
|
||||
`
|
||||
SELECT
|
||||
true
|
||||
FROM
|
||||
mock.sync_group_editing
|
||||
WHERE
|
||||
account_id = @account_id
|
||||
AND sync_group_id = @sync_group_id
|
||||
`,
|
||||
pgx.NamedArgs{
|
||||
"account_id": acctID,
|
||||
"sync_group_id": syncGroupID,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to perform query: %w", err)
|
||||
}
|
||||
|
||||
if _, err := pgx.CollectExactlyOneRow(rows, pgx.RowTo[bool]); err != nil {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return consts.ErrNotFound
|
||||
}
|
||||
return fmt.Errorf("failed to scan rows: %w", err)
|
||||
}
|
||||
|
||||
// update the editing listing
|
||||
|
||||
for _, in := range getAllMockShopSchemaInfos() {
|
||||
tag, err := tx.Exec(
|
||||
ctx,
|
||||
fmt.Sprintf(
|
||||
`
|
||||
UPDATE
|
||||
%s AS eli
|
||||
SET
|
||||
listing_id = @listing_id
|
||||
WHERE
|
||||
account_id = @account_id
|
||||
AND order_index = @order_index
|
||||
`,
|
||||
in.syncGroupEditingListingTable,
|
||||
),
|
||||
pgx.NamedArgs{
|
||||
"account_id": acctID,
|
||||
"order_index": orderIndex,
|
||||
"listing_id": listingID,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to perform query to update mock sync group editing listings: %w", err)
|
||||
}
|
||||
|
||||
switch n := tag.RowsAffected(); n {
|
||||
case 0:
|
||||
continue
|
||||
case 1:
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("unexpected number of rows affected: %d", n)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
return consts.ErrNotFound
|
||||
})
|
||||
}
|
||||
|
||||
func (db *Store) DeleteListingInListingInMockSyncGroupBeingEdited(ctx context.Context, acctID int64, orderIndex int) error {
|
||||
tag, err := db.db.Exec(
|
||||
ctx,
|
||||
`
|
||||
DELETE FROM
|
||||
mock.sync_group_editing_listing_order_indexes
|
||||
WHERE
|
||||
account_id = @account_id
|
||||
AND order_index = @order_index
|
||||
`,
|
||||
pgx.NamedArgs{
|
||||
"account_id": acctID,
|
||||
"order_index": orderIndex,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to perform query: %w", err)
|
||||
}
|
||||
if tag.RowsAffected() == 0 {
|
||||
return consts.ErrNotFound
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// additional context
|
||||
|
||||
func (db *Store) GetAccountPointerByUserID(ctx context.Context, userID string) (*Account, error) {
|
||||
@@ -721,3 +1473,11 @@ func (db *Store) GetAccountPointerByUserID(ctx context.Context, userID string) (
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (db *Store) beginReadonlyTxn(ctx context.Context, cb func(pgx.Tx) error) error {
|
||||
return pgx.BeginTxFunc(ctx, db.db, pgx.TxOptions{AccessMode: pgx.ReadOnly}, cb)
|
||||
}
|
||||
|
||||
func (db *Store) beginTxn(ctx context.Context, cb func(pgx.Tx) error) error {
|
||||
return pgx.BeginFunc(ctx, db.db, cb)
|
||||
}
|
||||
|
||||
@@ -69,14 +69,34 @@ func (v_ctx *StoreWithContext) StartEditingMockSyncGroup(acctID int64, syncGroup
|
||||
return v_ctx.Store.StartEditingMockSyncGroup(v_ctx.ctx, acctID, syncGroupID)
|
||||
}
|
||||
|
||||
func (v_ctx *StoreWithContext) CancelEditingOfMockSyncGroupForAccount(acctID int64) (int64, bool, error) {
|
||||
return v_ctx.Store.CancelEditingOfMockSyncGroupForAccount(v_ctx.ctx, acctID)
|
||||
}
|
||||
|
||||
func (v_ctx *StoreWithContext) GetMockSyncGroupEditingListings(acctID int64) ([]ListingWithOrderIndex, error) {
|
||||
return v_ctx.Store.GetMockSyncGroupEditingListings(v_ctx.ctx, acctID)
|
||||
}
|
||||
|
||||
func (v_ctx *StoreWithContext) MockSyncGroupIsBeingEdited(acctID int64, syncGroupID int64) (bool, error) {
|
||||
return v_ctx.Store.MockSyncGroupIsBeingEdited(v_ctx.ctx, acctID, syncGroupID)
|
||||
}
|
||||
|
||||
func (v_ctx *StoreWithContext) GetMockSyncGroupEditingListing(acctID int64, syncGroupID int64, orderIndex int64) (*Listing, error) {
|
||||
return v_ctx.Store.GetMockSyncGroupEditingListing(v_ctx.ctx, acctID, syncGroupID, orderIndex)
|
||||
}
|
||||
|
||||
func (v_ctx *StoreWithContext) SetShopInListingInMockSyncGroupBeingEdited(acctID int64, syncGroupID int64, orderIndex int, platform Platform, shopID string) error {
|
||||
return v_ctx.Store.SetShopInListingInMockSyncGroupBeingEdited(v_ctx.ctx, acctID, syncGroupID, orderIndex, platform, shopID)
|
||||
}
|
||||
|
||||
func (v_ctx *StoreWithContext) GetAccountPointerByUserID(userID string) (*Account, error) {
|
||||
return v_ctx.Store.GetAccountPointerByUserID(v_ctx.ctx, userID)
|
||||
}
|
||||
|
||||
func (v_ctx *StoreWithContext) beginReadonlyTxn(cb func(pgx.Tx) error) error {
|
||||
return v_ctx.Store.beginReadonlyTxn(v_ctx.ctx, cb)
|
||||
}
|
||||
|
||||
func (v_ctx *StoreWithContext) CreateMockShop(acctID int64, platform Platform, name string) (uuid.UUID, error) {
|
||||
return v_ctx.Store.CreateMockShop(v_ctx.ctx, acctID, platform, name)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user