90 lines
3.8 KiB
Go
90 lines
3.8 KiB
Go
package queries
|
|
|
|
import "database/sql"
|
|
|
|
func EnsureProductSeriesAutoInfraTables(pg *sql.DB) error {
|
|
stmts := []string{
|
|
`
|
|
CREATE TABLE IF NOT EXISTS mk_product_series_rule (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
series_id BIGINT NOT NULL REFERENCES dfgrp(id) ON DELETE CASCADE,
|
|
size_group TEXT NOT NULL DEFAULT '',
|
|
size_code TEXT NOT NULL,
|
|
ratio_qty INTEGER NOT NULL DEFAULT 1,
|
|
priority INTEGER NOT NULL DEFAULT 0,
|
|
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
|
source TEXT NOT NULL DEFAULT 'manual',
|
|
notes TEXT NOT NULL DEFAULT '',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
CONSTRAINT ck_mk_product_series_rule_ratio CHECK (ratio_qty > 0),
|
|
CONSTRAINT uq_mk_product_series_rule UNIQUE (series_id, size_group, size_code)
|
|
)`,
|
|
`CREATE INDEX IF NOT EXISTS ix_mk_product_series_rule_series ON mk_product_series_rule (series_id, is_active)`,
|
|
`CREATE INDEX IF NOT EXISTS ix_mk_product_series_rule_group ON mk_product_series_rule (size_group, size_code)`,
|
|
`
|
|
CREATE TABLE IF NOT EXISTS mk_product_series_stock_state (
|
|
row_key TEXT PRIMARY KEY,
|
|
product_code TEXT NOT NULL,
|
|
color_code TEXT NOT NULL,
|
|
dim3_code TEXT NOT NULL DEFAULT '',
|
|
stock_hash TEXT NOT NULL DEFAULT '',
|
|
total_qty NUMERIC(18,2) NOT NULL DEFAULT 0,
|
|
last_seen_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
)`,
|
|
`CREATE INDEX IF NOT EXISTS ix_mk_product_series_stock_state_product ON mk_product_series_stock_state (product_code, updated_at DESC)`,
|
|
`
|
|
CREATE TABLE IF NOT EXISTS mk_product_series_recalc_queue (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
row_key TEXT NOT NULL,
|
|
product_code TEXT NOT NULL,
|
|
color_code TEXT NOT NULL,
|
|
dim3_code TEXT NOT NULL DEFAULT '',
|
|
reason TEXT NOT NULL DEFAULT '',
|
|
status TEXT NOT NULL DEFAULT 'pending',
|
|
attempts SMALLINT NOT NULL DEFAULT 0,
|
|
available_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
queued_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
processed_at TIMESTAMPTZ,
|
|
last_error TEXT NOT NULL DEFAULT '',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
CONSTRAINT ck_mk_product_series_recalc_queue_status CHECK (status IN ('pending','processing','done','failed'))
|
|
)`,
|
|
`CREATE INDEX IF NOT EXISTS ix_mk_product_series_recalc_queue_status ON mk_product_series_recalc_queue (status, available_at, queued_at)`,
|
|
`CREATE UNIQUE INDEX IF NOT EXISTS uq_mk_product_series_recalc_queue_pending ON mk_product_series_recalc_queue (row_key) WHERE status IN ('pending','processing')`,
|
|
`
|
|
CREATE TABLE IF NOT EXISTS mk_product_series_job_log (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
job_name TEXT NOT NULL,
|
|
reason TEXT NOT NULL DEFAULT '',
|
|
started_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
finished_at TIMESTAMPTZ,
|
|
status TEXT NOT NULL DEFAULT 'running',
|
|
scanned_rows INTEGER NOT NULL DEFAULT 0,
|
|
changed_rows INTEGER NOT NULL DEFAULT 0,
|
|
processed_rows INTEGER NOT NULL DEFAULT 0,
|
|
written_rows INTEGER NOT NULL DEFAULT 0,
|
|
skipped_rows INTEGER NOT NULL DEFAULT 0,
|
|
error_text TEXT NOT NULL DEFAULT ''
|
|
)`,
|
|
`CREATE INDEX IF NOT EXISTS ix_mk_product_series_job_log_started ON mk_product_series_job_log (started_at DESC)`,
|
|
}
|
|
for _, stmt := range stmts {
|
|
if _, err := pg.Exec(stmt); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
_, err := pg.Exec(`
|
|
INSERT INTO mk_product_series_rule (series_id, size_group, size_code, ratio_qty, priority, source, notes)
|
|
SELECT d.id, '', BTRIM(x.size_code), 1, 0, 'dfgrp_title', 'auto-seeded from dfgrp.title'
|
|
FROM dfgrp d
|
|
CROSS JOIN LATERAL regexp_split_to_table(COALESCE(d.title, ''), '-') AS x(size_code)
|
|
WHERE d.master='zbggseri'
|
|
AND BTRIM(x.size_code) <> ''
|
|
ON CONFLICT (series_id, size_group, size_code) DO NOTHING
|
|
`)
|
|
return err
|
|
}
|