changes
This commit is contained in:
39
main.go
39
main.go
@@ -87,10 +87,39 @@ func main() {
|
|||||||
// one row out of 6,755. A separate column is untouched by that, and "when
|
// one row out of 6,755. A separate column is untouched by that, and "when
|
||||||
// was this published" is worth knowing regardless.
|
// was this published" is worth knowing regardless.
|
||||||
//
|
//
|
||||||
// The backfill is not optional and must land in the same deploy. Membership
|
// The backfill is not optional and must land in the same deploy as the
|
||||||
// of a store catalogue is currently the *existence* of the row, so switching
|
// column. Membership of a store catalogue was the *existence* of the row,
|
||||||
// the read to `publishedat IS NOT NULL` without this empties every shop on
|
// so reading `publishedat IS NOT NULL` without it empties every shop on the
|
||||||
// the platform at once.
|
// platform at once.
|
||||||
|
//
|
||||||
|
// The backfill runs ONCE — only on the boot that adds the column.
|
||||||
|
//
|
||||||
|
// It used to run on every boot, and that quietly cancelled the whole point
|
||||||
|
// of the column. `WHERE publishedat IS NULL` matches a legacy row on the
|
||||||
|
// first boot and, on every boot after, matches exactly the products
|
||||||
|
// somebody is deliberately holding back: imported, not yet priced, waiting
|
||||||
|
// for review. A restart published all of them and backdated the release to
|
||||||
|
// the row's `created`, so it did not even look recent.
|
||||||
|
//
|
||||||
|
// Observed 2026-08-31: seventeen products imported at R mart at 15:55 sat
|
||||||
|
// correctly unpublished, and the next deploy published all seventeen
|
||||||
|
// stamped 15:55. With several deploys a day, the admin-catalogue tier could
|
||||||
|
// not survive an afternoon.
|
||||||
|
//
|
||||||
|
// Detecting "the column was just added" rather than tracking a migration
|
||||||
|
// version: the question is answerable from the schema itself, so it needs
|
||||||
|
// no new table and cannot drift out of step with one.
|
||||||
|
var hadPublishedAt int64
|
||||||
|
if err := db.DB.Raw(`
|
||||||
|
SELECT COUNT(1) FROM information_schema.columns
|
||||||
|
WHERE table_name = 'productlocations' AND column_name = 'publishedat'`).
|
||||||
|
Scan(&hadPublishedAt).Error; err != nil {
|
||||||
|
log.Fatal("could not check productlocations.publishedat:", err)
|
||||||
|
}
|
||||||
|
if hadPublishedAt == 0 {
|
||||||
|
// First boot with the column. Every existing row predates publication
|
||||||
|
// as a concept, and membership of this table WAS publication — so
|
||||||
|
// leaving them null would empty every shop on the platform at once.
|
||||||
if err := db.DB.Exec(
|
if err := db.DB.Exec(
|
||||||
`ALTER TABLE productlocations ADD COLUMN IF NOT EXISTS publishedat timestamp`).Error; err != nil {
|
`ALTER TABLE productlocations ADD COLUMN IF NOT EXISTS publishedat timestamp`).Error; err != nil {
|
||||||
log.Fatal("could not add productlocations.publishedat:", err)
|
log.Fatal("could not add productlocations.publishedat:", err)
|
||||||
@@ -101,6 +130,8 @@ func main() {
|
|||||||
WHERE publishedat IS NULL`).Error; err != nil {
|
WHERE publishedat IS NULL`).Error; err != nil {
|
||||||
log.Fatal("could not backfill productlocations.publishedat:", err)
|
log.Fatal("could not backfill productlocations.publishedat:", err)
|
||||||
}
|
}
|
||||||
|
log.Println("productlocations.publishedat added and backfilled (one time)")
|
||||||
|
}
|
||||||
|
|
||||||
// The catalogue's own stable key for an imported product.
|
// The catalogue's own stable key for an imported product.
|
||||||
//
|
//
|
||||||
|
|||||||
Reference in New Issue
Block a user