From 7297c0a16bfa1f3aa4bd2a74c4dfe2fb72e24093 Mon Sep 17 00:00:00 2001 From: Samuel Enocsson Date: Mon, 8 Jun 2026 09:50:03 +0200 Subject: [PATCH] fix: preserve predicted_rating via UPSERT in savePlayerToDB (#11) INSERT OR REPLACE deletes the existing row and resets columns absent from the VALUES list (predicted_rating, std_dev, last_round_update, excluded_rounds_count, cutoff_rating) to NULL. Refresh-all called this for every player, wiping predicted ratings table-wide. Switch to a SQLite UPSERT keyed on pdga_number that updates only the four scraped columns in place, leaving the predicted-rating columns and the 24h-cooldown timestamp untouched. Mirror course.js's lastID==0 SELECT fallback so the function still returns a real player id on the update path. --- src/models/player.js | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/models/player.js b/src/models/player.js index 733c138..5f3f2c7 100644 --- a/src/models/player.js +++ b/src/models/player.js @@ -17,12 +17,27 @@ function getPlayerFromDB(pdgaNumber) { function savePlayerToDB(playerData) { return new Promise((resolve, reject) => { db.run( - `INSERT OR REPLACE INTO players (pdga_number, name, current_rating, rating_change, last_updated) - VALUES (?, ?, ?, ?, datetime('now'))`, + // UPSERT (not INSERT OR REPLACE): updating in place preserves columns not + // listed here — predicted_rating, std_dev, last_round_update, + // excluded_rounds_count, cutoff_rating. INSERT OR REPLACE would delete the + // existing row and reset those to their DEFAULT (NULL). + `INSERT INTO players (pdga_number, name, current_rating, rating_change, last_updated) + VALUES (?, ?, ?, ?, datetime('now')) + ON CONFLICT(pdga_number) DO UPDATE SET + name = excluded.name, + current_rating = excluded.current_rating, + rating_change = excluded.rating_change, + last_updated = excluded.last_updated`, [playerData.pdgaNumber, playerData.name, playerData.rating, playerData.ratingChange], function(err) { - if (err) reject(err); - else resolve(this.lastID); + if (err) return reject(err); + // node-sqlite3 leaves lastID = 0 when ON CONFLICT triggers an UPDATE. + // Fall back to a SELECT to get the real id in that case. + if (this.lastID !== 0) return resolve(this.lastID); + db.get('SELECT id FROM players WHERE pdga_number = ?', [playerData.pdgaNumber], (err2, row) => { + if (err2) reject(err2); + else resolve(row ? row.id : 0); + }); } ); }); -- 2.52.0