Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -92,6 +92,15 @@ func productSeriesFallbackEnabled() bool {
|
||||
return raw == "1" || raw == "true" || raw == "on" || raw == "yes"
|
||||
}
|
||||
|
||||
func productSeriesFallbackAutoCreateEnabled() bool {
|
||||
// Default on: avoid manual intervention by auto-creating the fallback dfgrp row when missing.
|
||||
raw := strings.TrimSpace(strings.ToLower(os.Getenv("PRODUCT_SERIES_FALLBACK_AUTO_CREATE")))
|
||||
if raw == "" {
|
||||
return true
|
||||
}
|
||||
return raw == "1" || raw == "true" || raw == "on" || raw == "yes"
|
||||
}
|
||||
|
||||
func productSeriesFallbackCode() string {
|
||||
code := strings.TrimSpace(os.Getenv("PRODUCT_SERIES_FALLBACK_SERIES_CODE"))
|
||||
if code == "" {
|
||||
@@ -141,13 +150,61 @@ LIMIT 1
|
||||
`, code).Scan(&id, &gotCode)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
// cache negative for a short period too
|
||||
if !productSeriesFallbackAutoCreateEnabled() {
|
||||
// cache negative for a short period too
|
||||
productSeriesFallbackMu.Lock()
|
||||
productSeriesFallbackCachedCode = code
|
||||
productSeriesFallbackCachedID = 0
|
||||
productSeriesFallbackCachedAt = time.Now()
|
||||
productSeriesFallbackMu.Unlock()
|
||||
return 0, code, nil
|
||||
}
|
||||
|
||||
// Auto-create the fallback series definition (best-effort) to avoid manual steps.
|
||||
// We guard with the same mutex to avoid duplicate inserts within this process.
|
||||
productSeriesFallbackMu.Lock()
|
||||
defer productSeriesFallbackMu.Unlock()
|
||||
|
||||
// Re-check under lock in case another goroutine created it while we were waiting.
|
||||
if productSeriesFallbackCachedCode == code && productSeriesFallbackCachedID > 0 &&
|
||||
productSeriesFallbackCachedAt.After(time.Now().Add(-10*time.Minute)) {
|
||||
return productSeriesFallbackCachedID, code, nil
|
||||
}
|
||||
|
||||
var createdID int64
|
||||
createErr := pg.QueryRowContext(ctx, `
|
||||
INSERT INTO dfgrp (code, title, is_active, typ, master, parent_filter, sort_order, is_required, notes)
|
||||
SELECT $1, $1, TRUE, 'opt', 'zbggseri', '', 0, FALSE, 'auto-created fallback series'
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM dfgrp WHERE master='zbggseri' AND code=$1
|
||||
)
|
||||
RETURNING id
|
||||
`, code).Scan(&createdID)
|
||||
if createErr != nil {
|
||||
// If RETURNING didn't return because it already exists, select it now.
|
||||
var sid int64
|
||||
var scode string
|
||||
selErr := pg.QueryRowContext(ctx, `
|
||||
SELECT id, COALESCE(code,'')
|
||||
FROM dfgrp
|
||||
WHERE master='zbggseri' AND code=$1
|
||||
ORDER BY id
|
||||
LIMIT 1
|
||||
`, code).Scan(&sid, &scode)
|
||||
if selErr != nil {
|
||||
// still missing; treat as disabled for now
|
||||
productSeriesFallbackCachedCode = code
|
||||
productSeriesFallbackCachedID = 0
|
||||
productSeriesFallbackCachedAt = time.Now()
|
||||
return 0, code, nil
|
||||
}
|
||||
createdID = sid
|
||||
}
|
||||
|
||||
productSeriesFallbackCachedCode = code
|
||||
productSeriesFallbackCachedID = 0
|
||||
productSeriesFallbackCachedID = createdID
|
||||
productSeriesFallbackCachedAt = time.Now()
|
||||
productSeriesFallbackMu.Unlock()
|
||||
return 0, code, nil
|
||||
return createdID, code, nil
|
||||
}
|
||||
return 0, code, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user