Files
pdga-rating/src/models/course.js
T
Samuel Enocsson 9cb78c9c98 fix: address code-review findings from pass 1 + 2 (#8)
- Fix saveCourseToDB returning 0 on conflict by falling back to SELECT
- Fix inactive layouts showing 'Never played' when last_played exists
- Add .icon-btn.spinning to courses.css for refresh button feedback
- Remove duplicate .btn-primary from courses.css (use shared.css version)
- Tokenize rating tier colors into --rating-tier-{high,mid,low} CSS vars
- Convert var to const/let throughout courses.js
- Fix logger.error calls to use {err} object form (pino convention)
- Extract RATING_TIER_HIGH/MID constants in course-layouts.ejs scriptlet
- Remove dead href='#' View all link from courses.ejs (deferred)
- Pass total prop explicitly from course-table.ejs to course-cards.ejs
- Remove dead #search-results-info selector from mobile.css
- Remove redundant .replace(/"/g, '"') from data attributes in course-table.ejs
2026-05-25 09:54:15 +02:00

109 lines
3.0 KiB
JavaScript

const { db } = require('../db');
function saveCourseToDB(courseData) {
return new Promise((resolve, reject) => {
db.run(
`INSERT INTO courses (name, link, city, last_updated)
VALUES (?, ?, ?, datetime('now'))
ON CONFLICT(link) DO UPDATE SET name = excluded.name, city = excluded.city, last_updated = datetime('now')`,
[courseData.name, courseData.link, courseData.city],
function(err) {
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 courses WHERE link = ?', [courseData.link], (err2, row) => {
if (err2) reject(err2);
else resolve(row ? row.id : 0);
});
}
);
});
}
function getAllCoursesFromDB() {
return new Promise((resolve, reject) => {
db.all(
'SELECT * FROM courses ORDER BY name ASC',
[],
(err, rows) => {
if (err) reject(err);
else resolve(rows);
}
);
});
}
function saveLayoutToDB(courseId, layoutData) {
return new Promise((resolve, reject) => {
db.run(
`INSERT OR IGNORE INTO layouts (course_id, name, par)
VALUES (?, ?, ?)`,
[courseId, layoutData.name, layoutData.par],
function(err) {
if (err) reject(err);
else resolve(this.lastID);
}
);
});
}
function getLayoutsForCourse(courseId) {
return new Promise((resolve, reject) => {
db.all(
'SELECT * FROM layouts WHERE course_id = ? ORDER BY last_played DESC, name ASC',
[courseId],
(err, rows) => {
if (err) reject(err);
else resolve(rows);
}
);
});
}
function updateLayoutRating(courseId, layoutName, par, meanRating, ratingCount, lastPlayed = null) {
return new Promise((resolve, reject) => {
db.run(
`UPDATE layouts
SET mean_rating = ?, rating_count = ?, last_calculated = datetime('now'), last_played = ?
WHERE course_id = ? AND name = ? AND par = ?`,
[meanRating, ratingCount, lastPlayed, courseId, layoutName, par],
function(err) {
if (err) reject(err);
else resolve(this.changes);
}
);
});
}
function getOrCreateLayout(courseId, name, par) {
return new Promise((resolve, reject) => {
db.get(
'SELECT id FROM layouts WHERE course_id = ? AND name = ? AND par = ?',
[courseId, name, par],
(err, row) => {
if (err) return reject(err);
if (row) return resolve(row.id);
db.run(
'INSERT INTO layouts (course_id, name, par) VALUES (?, ?, ?)',
[courseId, name, par],
function(err) {
if (err) reject(err);
else resolve(this.lastID);
}
);
}
);
});
}
module.exports = {
saveCourseToDB,
getAllCoursesFromDB,
saveLayoutToDB,
getLayoutsForCourse,
getOrCreateLayout,
updateLayoutRating
};