From c4c95fa97219023d59de93d957b7452e217adc6e Mon Sep 17 00:00:00 2001 From: Syco21 Date: Fri, 15 May 2026 21:41:27 +0200 Subject: [PATCH] Improve API controllers: case-insensitive search, scoped queries, cleanup --- src/controllers/cardImageController.js | 8 --- src/controllers/exportCardsController.js | 63 +++++++++++++++--------- src/controllers/importController.js | 2 +- src/controllers/versionController.js | 16 ++---- 4 files changed, 45 insertions(+), 44 deletions(-) diff --git a/src/controllers/cardImageController.js b/src/controllers/cardImageController.js index 47b8ff7..d9de604 100644 --- a/src/controllers/cardImageController.js +++ b/src/controllers/cardImageController.js @@ -1,13 +1,5 @@ const db = require('../config/db'); const axios = require('axios'); - -// Use your existing insertCardImage for initial URL insert -const { insertCardImage } = require('../models/cardImageModel'); - -/** - * GET /cardImage/:cardId - * Returns the image blob of a card. If not stored, downloads from image_url, saves to DB. - */ async function getCardImage(req, res) { const { cardId } = req.params; diff --git a/src/controllers/exportCardsController.js b/src/controllers/exportCardsController.js index f7a37b5..71dcf19 100644 --- a/src/controllers/exportCardsController.js +++ b/src/controllers/exportCardsController.js @@ -1,33 +1,48 @@ const db = require('../config/db'); -/** - * GET /exportCards - * Returns all cards with their printings and amount_owned - */ async function exportCards(req, res) { + const { search, type } = req.query; + try { - // Fetch all cards - const [cards] = await db.execute(` - SELECT id, name, card_type AS type, frame_type, level, race, attribute, link_val, tcg_date, ocg_date - FROM cards - `); + const conditions = []; + const cardParams = []; - // Fetch all printings with sets and rarities - const [printings] = await db.execute(` - SELECT csr.card_id, csr.set_id, csr.card_set_code AS set_code, csr.amount_owned, - s.set_name, - r.id AS rarity_id, r.rarity_name, r.rarity_code - FROM card_sets_rarity csr - JOIN sets s ON csr.set_id = s.id - JOIN rarities r ON csr.rarity_id = r.id - `); + if (search?.trim()) { + conditions.push('LOWER(name) LIKE ?'); + cardParams.push(`%${search.trim().toLowerCase()}%`); + } + if (type?.trim()) { + conditions.push('LOWER(card_type) LIKE ?'); + cardParams.push(`%${type.trim().toLowerCase()}%`); + } + + const where = conditions.length ? `WHERE ${conditions.join(' AND ')}` : ''; + + const [cards] = await db.execute( + `SELECT id, name, card_type AS type, frame_type, level, race, attribute, link_val, tcg_date, ocg_date + FROM cards ${where}`, + cardParams + ); + + if (cards.length === 0) return res.json([]); + + // Only fetch printings for the cards we actually returned + const cardIds = cards.map(c => c.id); + const placeholders = cardIds.map(() => '?').join(', '); + + const [printings] = await db.execute( + `SELECT csr.card_id, csr.set_id, csr.card_set_code AS set_code, csr.amount_owned, + s.set_name, + r.id AS rarity_id, r.rarity_name, r.rarity_code + FROM card_sets_rarity csr + JOIN sets s ON csr.set_id = s.id + JOIN rarities r ON csr.rarity_id = r.id + WHERE csr.card_id IN (${placeholders})`, + cardIds + ); - // Map printings to cards const cardMap = {}; - cards.forEach(card => { - cardMap[card.id] = { ...card, printings: [] }; - }); - + cards.forEach(card => { cardMap[card.id] = { ...card, printings: [] }; }); printings.forEach(p => { if (cardMap[p.card_id]) { cardMap[p.card_id].printings.push({ @@ -37,7 +52,7 @@ async function exportCards(req, res) { rarity_id: p.rarity_id, rarity_name: p.rarity_name, rarity_code: p.rarity_code, - amount_owned: p.amount_owned || 0 + amount_owned: p.amount_owned ?? 0, }); } }); diff --git a/src/controllers/importController.js b/src/controllers/importController.js index 63f1c72..9af6440 100644 --- a/src/controllers/importController.js +++ b/src/controllers/importController.js @@ -122,6 +122,7 @@ async function importCardsInternal() { await conn.execute(` INSERT INTO card_images (card_id, image_url) VALUES (?, ?) + ON DUPLICATE KEY UPDATE image_url = VALUES(image_url) `, [card.id, img.image_url]); addedImages++; } @@ -136,7 +137,6 @@ async function importCardsInternal() { conn.release(); } - batch.length = 0; } const durationSeconds = ((Date.now() - startTime) / 1000).toFixed(2); diff --git a/src/controllers/versionController.js b/src/controllers/versionController.js index f590bb8..03e864b 100644 --- a/src/controllers/versionController.js +++ b/src/controllers/versionController.js @@ -1,20 +1,14 @@ -const db = require('../config/db'); +const { getLocalDBVersion } = require('../models/dbVersionModel'); async function getDatabaseVersion(req, res) { try { - const [rows] = await db.execute(` - SELECT database_version, last_update - FROM db_version - ORDER BY last_update DESC - LIMIT 1 - `); - if (!rows.length) return res.json({ database_version: 'unknown' }); - - res.json({ database_version: rows[0].database_version }); + const version = await getLocalDBVersion(); + if (!version) return res.json({ database_version: 'unknown' }); + res.json({ database_version: version.database_version }); } catch (err) { console.error('Failed to fetch DB version:', err); res.status(500).json({ error: 'Failed to fetch database version' }); } } -module.exports = { getDatabaseVersion }; \ No newline at end of file +module.exports = { getDatabaseVersion };