Improve API controllers: case-insensitive search, scoped queries, cleanup
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
@@ -1,13 +1,5 @@
|
|||||||
const db = require('../config/db');
|
const db = require('../config/db');
|
||||||
const axios = require('axios');
|
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) {
|
async function getCardImage(req, res) {
|
||||||
const { cardId } = req.params;
|
const { cardId } = req.params;
|
||||||
|
|
||||||
|
|||||||
@@ -1,33 +1,48 @@
|
|||||||
const db = require('../config/db');
|
const db = require('../config/db');
|
||||||
|
|
||||||
/**
|
|
||||||
* GET /exportCards
|
|
||||||
* Returns all cards with their printings and amount_owned
|
|
||||||
*/
|
|
||||||
async function exportCards(req, res) {
|
async function exportCards(req, res) {
|
||||||
try {
|
const { search, type } = req.query;
|
||||||
// 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
|
|
||||||
`);
|
|
||||||
|
|
||||||
// Fetch all printings with sets and rarities
|
try {
|
||||||
const [printings] = await db.execute(`
|
const conditions = [];
|
||||||
SELECT csr.card_id, csr.set_id, csr.card_set_code AS set_code, csr.amount_owned,
|
const cardParams = [];
|
||||||
|
|
||||||
|
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,
|
s.set_name,
|
||||||
r.id AS rarity_id, r.rarity_name, r.rarity_code
|
r.id AS rarity_id, r.rarity_name, r.rarity_code
|
||||||
FROM card_sets_rarity csr
|
FROM card_sets_rarity csr
|
||||||
JOIN sets s ON csr.set_id = s.id
|
JOIN sets s ON csr.set_id = s.id
|
||||||
JOIN rarities r ON csr.rarity_id = r.id
|
JOIN rarities r ON csr.rarity_id = r.id
|
||||||
`);
|
WHERE csr.card_id IN (${placeholders})`,
|
||||||
|
cardIds
|
||||||
|
);
|
||||||
|
|
||||||
// Map printings to cards
|
|
||||||
const cardMap = {};
|
const cardMap = {};
|
||||||
cards.forEach(card => {
|
cards.forEach(card => { cardMap[card.id] = { ...card, printings: [] }; });
|
||||||
cardMap[card.id] = { ...card, printings: [] };
|
|
||||||
});
|
|
||||||
|
|
||||||
printings.forEach(p => {
|
printings.forEach(p => {
|
||||||
if (cardMap[p.card_id]) {
|
if (cardMap[p.card_id]) {
|
||||||
cardMap[p.card_id].printings.push({
|
cardMap[p.card_id].printings.push({
|
||||||
@@ -37,7 +52,7 @@ async function exportCards(req, res) {
|
|||||||
rarity_id: p.rarity_id,
|
rarity_id: p.rarity_id,
|
||||||
rarity_name: p.rarity_name,
|
rarity_name: p.rarity_name,
|
||||||
rarity_code: p.rarity_code,
|
rarity_code: p.rarity_code,
|
||||||
amount_owned: p.amount_owned || 0
|
amount_owned: p.amount_owned ?? 0,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -122,6 +122,7 @@ async function importCardsInternal() {
|
|||||||
await conn.execute(`
|
await conn.execute(`
|
||||||
INSERT INTO card_images (card_id, image_url)
|
INSERT INTO card_images (card_id, image_url)
|
||||||
VALUES (?, ?)
|
VALUES (?, ?)
|
||||||
|
ON DUPLICATE KEY UPDATE image_url = VALUES(image_url)
|
||||||
`, [card.id, img.image_url]);
|
`, [card.id, img.image_url]);
|
||||||
addedImages++;
|
addedImages++;
|
||||||
}
|
}
|
||||||
@@ -136,7 +137,6 @@ async function importCardsInternal() {
|
|||||||
conn.release();
|
conn.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
batch.length = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const durationSeconds = ((Date.now() - startTime) / 1000).toFixed(2);
|
const durationSeconds = ((Date.now() - startTime) / 1000).toFixed(2);
|
||||||
|
|||||||
@@ -1,16 +1,10 @@
|
|||||||
const db = require('../config/db');
|
const { getLocalDBVersion } = require('../models/dbVersionModel');
|
||||||
|
|
||||||
async function getDatabaseVersion(req, res) {
|
async function getDatabaseVersion(req, res) {
|
||||||
try {
|
try {
|
||||||
const [rows] = await db.execute(`
|
const version = await getLocalDBVersion();
|
||||||
SELECT database_version, last_update
|
if (!version) return res.json({ database_version: 'unknown' });
|
||||||
FROM db_version
|
res.json({ database_version: version.database_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 });
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to fetch DB version:', err);
|
console.error('Failed to fetch DB version:', err);
|
||||||
res.status(500).json({ error: 'Failed to fetch database version' });
|
res.status(500).json({ error: 'Failed to fetch database version' });
|
||||||
|
|||||||
Reference in New Issue
Block a user