Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -431,37 +431,6 @@ WHERE is_active = TRUE
|
||||
return out
|
||||
}
|
||||
|
||||
loadDimCombosFromCache := func(productCode string) ([]dimCombo, error) {
|
||||
productCode = strings.TrimSpace(productCode)
|
||||
if productCode == "" {
|
||||
return nil, nil
|
||||
}
|
||||
rows, err := pgTx.QueryContext(ctx, `
|
||||
SELECT dim1, dim3
|
||||
FROM mk_mmitem_dim_combo
|
||||
WHERE product_code = $1
|
||||
ORDER BY dim1, dim3_key
|
||||
`, productCode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
out := make([]dimCombo, 0, 32)
|
||||
for rows.Next() {
|
||||
var d1 int64
|
||||
var d3 sql.NullInt64
|
||||
if err := rows.Scan(&d1, &d3); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if d1 <= 0 {
|
||||
continue
|
||||
}
|
||||
out = append(out, dimCombo{Dim1: d1, Dim3: d3})
|
||||
}
|
||||
return out, rows.Err()
|
||||
}
|
||||
|
||||
parseDimID := func(s string) (int64, bool) {
|
||||
s = strings.TrimSpace(s)
|
||||
if s == "" {
|
||||
@@ -812,7 +781,7 @@ filtered AS (
|
||||
AND price > 0
|
||||
),
|
||||
grouped AS (
|
||||
-- Ensure one row per business key to avoid unique violations under strict constraints (e.g. uq_sdprc_3).
|
||||
-- Ensure one row per business key to avoid unique violations under strict constraints.
|
||||
SELECT
|
||||
sdprcgrp_id,
|
||||
currency AS crn,
|
||||
@@ -822,16 +791,35 @@ grouped AS (
|
||||
FROM filtered
|
||||
GROUP BY sdprcgrp_id, currency, dim1, dim3
|
||||
),
|
||||
upserted AS (
|
||||
updated AS (
|
||||
UPDATE sdprc s
|
||||
SET prc = g.prc,
|
||||
zlins_dttm = now()
|
||||
FROM grouped g
|
||||
WHERE s.mmitem_id = $2::bigint
|
||||
AND s.sdprcgrp_id = g.sdprcgrp_id
|
||||
AND s.crn = g.crn
|
||||
AND s.dim1 = g.dim1
|
||||
AND COALESCE(s.dim3, 0) = COALESCE(g.dim3, 0)
|
||||
AND s.prc IS DISTINCT FROM g.prc
|
||||
RETURNING 1
|
||||
),
|
||||
inserted AS (
|
||||
INSERT INTO sdprc (mmitem_id, sdprcgrp_id, crn, dim1, dim3, prc, zlins_dttm)
|
||||
SELECT $2::bigint, g.sdprcgrp_id, g.crn, g.dim1, g.dim3, g.prc, now()
|
||||
FROM grouped g
|
||||
ON CONFLICT ON CONSTRAINT uq_sdprc_3
|
||||
DO UPDATE SET prc = EXCLUDED.prc, zlins_dttm = EXCLUDED.zlins_dttm
|
||||
WHERE sdprc.prc IS DISTINCT FROM EXCLUDED.prc
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM sdprc s
|
||||
WHERE s.mmitem_id = $2::bigint
|
||||
AND s.sdprcgrp_id = g.sdprcgrp_id
|
||||
AND s.crn = g.crn
|
||||
AND s.dim1 = g.dim1
|
||||
AND COALESCE(s.dim3, 0) = COALESCE(g.dim3, 0)
|
||||
)
|
||||
RETURNING 1
|
||||
)
|
||||
SELECT COUNT(*)::int FROM upserted;
|
||||
SELECT ((SELECT COUNT(*) FROM updated) + (SELECT COUNT(*) FROM inserted))::int;
|
||||
`
|
||||
var inserted int
|
||||
if err := pgTx.QueryRowContext(ctx, q, raw, mmItemID).Scan(&inserted); err != nil {
|
||||
@@ -1083,28 +1071,8 @@ VALUES (
|
||||
_ = upsertDimCombosCache(code, dims) // best-effort cache fill
|
||||
}
|
||||
|
||||
// 2) Cache fallback (fast).
|
||||
cacheStarted := time.Now()
|
||||
if len(dims) == 0 {
|
||||
cached, cacheErr := loadDimCombosFromCache(code)
|
||||
if cacheErr == nil && len(cached) > 0 {
|
||||
dims = cached
|
||||
logger.Info("save:pg:dims:cache:hit",
|
||||
"product_code", code,
|
||||
"dims", len(dims),
|
||||
"duration_ms", time.Since(cacheStarted).Milliseconds(),
|
||||
)
|
||||
} else if cacheErr != nil {
|
||||
logger.Error("save:pg:dims:cache-load:error", "product_code", code, "err", cacheErr)
|
||||
} else {
|
||||
logger.Info("save:pg:dims:cache:miss",
|
||||
"product_code", code,
|
||||
"duration_ms", time.Since(cacheStarted).Milliseconds(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// 3) Last resort: MSSQL stock tokens (legacy).
|
||||
// 2) Last resort: MSSQL stock tokens, then seed mmitem_dim. Do not use
|
||||
// mk_mmitem_dim_combo as a write source; stale cache rows can create wrong keys.
|
||||
if len(dims) == 0 {
|
||||
d, err := loadDimsFromMssqlStock(code)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user