added csv and updated migration to work better hopefully #7
@@ -1,9 +1,10 @@
|
|||||||
export const up = (pgm) => {
|
export const up = (pgm) => {
|
||||||
pgm.sql(`
|
pgm.sql(`
|
||||||
ALTER TABLE "items"
|
ALTER TABLE "items"
|
||||||
ADD CONSTRAINT "set_id"
|
ADD COLUMN "set_id" UUID,
|
||||||
|
ADD CONSTRAINT "fk_set_id"
|
||||||
FOREIGN KEY ("set_id")
|
FOREIGN KEY ("set_id")
|
||||||
REFERENCES "sets" ("id")
|
REFERENCES "sets"("id")
|
||||||
ON DELETE CASCADE;
|
ON DELETE CASCADE;
|
||||||
`)
|
`)
|
||||||
}
|
}
|
||||||
@@ -11,6 +12,7 @@ export const up = (pgm) => {
|
|||||||
export const down = (pgm) => {
|
export const down = (pgm) => {
|
||||||
pgm.sql(`
|
pgm.sql(`
|
||||||
ALTER TABLE "items"
|
ALTER TABLE "items"
|
||||||
DROP CONSTRAINT "fk_name";
|
DROP COLUMN "set_id",
|
||||||
|
DROP CONSTRAINT "fk_set_id";
|
||||||
`)
|
`)
|
||||||
}
|
}
|
||||||
|
|||||||
+193
-79
@@ -11,99 +11,213 @@ const pool = new Pool(database)
|
|||||||
|
|
||||||
// Get all items
|
// Get all items
|
||||||
router.get('/', async (req, res) => {
|
router.get('/', async (req, res) => {
|
||||||
const client = await pool.connect()
|
const client = await pool.connect()
|
||||||
try {
|
try {
|
||||||
const result = await client.query('SELECT * FROM items')
|
const result = await client.query('SELECT * FROM items')
|
||||||
res.json(result.rows)
|
res.json(result.rows)
|
||||||
} finally {
|
} finally {
|
||||||
client.release()
|
client.release()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Get a single item by id
|
// Get a single item by id
|
||||||
router.get('/:id', async (req, res) => {
|
router.get('/:id', async (req, res) => {
|
||||||
const { id } = req.params
|
const { id } = req.params
|
||||||
const client = await pool.connect()
|
const client = await pool.connect()
|
||||||
try {
|
try {
|
||||||
const result = await client.query('SELECT * FROM items WHERE id = $1', [id])
|
const result = await client.query('SELECT * FROM items WHERE id = $1', [id])
|
||||||
if (result.rows.length === 0) {
|
if (result.rows.length === 0) {
|
||||||
return res.status(404).json({ message: 'Item not found' })
|
return res.status(404).json({ message: 'Item not found' })
|
||||||
}
|
}
|
||||||
res.json(result.rows[0])
|
res.json(result.rows[0])
|
||||||
} finally {
|
} finally {
|
||||||
client.release()
|
client.release()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Create a new item
|
// Create a new item
|
||||||
router.post('/', [
|
router.post(
|
||||||
check('collection_id').not().isEmpty(),
|
'/',
|
||||||
check('image_id').not().isEmpty(),
|
[
|
||||||
check('productId').not().isEmpty(),
|
check('collection_id').not().isEmpty(),
|
||||||
check('name').not().isEmpty(),
|
check('image_id').not().isEmpty(),
|
||||||
check('cleanName').not().isEmpty(),
|
check('productId').not().isEmpty(),
|
||||||
check('extCardText').not().isEmpty(),
|
check('name').not().isEmpty(),
|
||||||
check('marketPrice').not().isEmpty(),
|
check('cleanName').not().isEmpty(),
|
||||||
check('extRarity').not().isEmpty(),
|
check('extCardText').not().isEmpty(),
|
||||||
check('set_id').not().isEmpty() // Add validation for set_id
|
check('marketPrice').not().isEmpty(),
|
||||||
], async (req, res) => {
|
check('extRarity').not().isEmpty(),
|
||||||
const errors = validationResult(req)
|
check('set_id').not().isEmpty(), // Add validation for set_id
|
||||||
if (!errors.isEmpty()) {
|
],
|
||||||
return res.status(400).json({ errors: errors.array() })
|
async (req, res) => {
|
||||||
}
|
const errors = validationResult(req)
|
||||||
const { collection_id, image_id, productId, name, cleanName, extCardText, marketPrice, extRarity, set_id } = req.body
|
if (!errors.isEmpty()) {
|
||||||
const client = await pool.connect()
|
return res.status(400).json({ errors: errors.array() })
|
||||||
try {
|
}
|
||||||
const result = await client.query('INSERT INTO items (collection_id, image_id, productId, name, cleanName, extCardText, marketPrice, extRarity, set_id, created_at, updated_at) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, NOW(), NOW()) RETURNING *', [collection_id, image_id, productId, name, cleanName, extCardText, marketPrice, extRarity, set_id])
|
const {
|
||||||
res.status(201).json(result.rows[0])
|
collection_id,
|
||||||
} finally {
|
image_id,
|
||||||
client.release()
|
productId,
|
||||||
}
|
name,
|
||||||
})
|
cleanName,
|
||||||
|
extCardText,
|
||||||
|
marketPrice,
|
||||||
|
extRarity,
|
||||||
|
set_id,
|
||||||
|
} = req.body
|
||||||
|
const client = await pool.connect()
|
||||||
|
try {
|
||||||
|
const result = await client.query(
|
||||||
|
'INSERT INTO items (collection_id, image_id, productId, name, cleanName, extCardText, marketPrice, extRarity, set_id, created_at, updated_at) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, NOW(), NOW()) RETURNING *',
|
||||||
|
[
|
||||||
|
collection_id,
|
||||||
|
image_id,
|
||||||
|
productId,
|
||||||
|
name,
|
||||||
|
cleanName,
|
||||||
|
extCardText,
|
||||||
|
marketPrice,
|
||||||
|
extRarity,
|
||||||
|
set_id,
|
||||||
|
]
|
||||||
|
)
|
||||||
|
res.status(201).json(result.rows[0])
|
||||||
|
} finally {
|
||||||
|
client.release()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// Update an existing item
|
// Update an existing item
|
||||||
router.put('/:id', async (req, res) => {
|
router.put('/:id', async (req, res) => {
|
||||||
const { id } = req.params
|
const { id } = req.params
|
||||||
const updates = {}
|
const updates = {}
|
||||||
if (req.body.collection_id) updates.collection_id = req.body.collection_id
|
if (req.body.collection_id) updates.collection_id = req.body.collection_id
|
||||||
if (req.body.image_id) updates.image_id = req.body.image_id
|
if (req.body.image_id) updates.image_id = req.body.image_id
|
||||||
if (req.body.productId) updates.productId = req.body.productId
|
if (req.body.productId) updates.productId = req.body.productId
|
||||||
if (req.body.name) updates.name = req.body.name
|
if (req.body.name) updates.name = req.body.name
|
||||||
if (req.body.cleanName) updates.cleanName = req.body.cleanName
|
if (req.body.cleanName) updates.cleanName = req.body.cleanName
|
||||||
if (req.body.extCardText) updates.extCardText = req.body.extCardText
|
if (req.body.extCardText) updates.extCardText = req.body.extCardText
|
||||||
if (req.body.marketPrice) updates.marketPrice = req.body.marketPrice
|
if (req.body.marketPrice) updates.marketPrice = req.body.marketPrice
|
||||||
if (req.body.extRarity) updates.extRarity = req.body.extRarity
|
if (req.body.extRarity) updates.extRarity = req.body.extRarity
|
||||||
const client = await pool.connect()
|
const client = await pool.connect()
|
||||||
try {
|
try {
|
||||||
if (Object.keys(updates).length > 0) {
|
if (Object.keys(updates).length > 0) {
|
||||||
const updateFields = Object.keys(updates).map(key => `${key} = $${Object.keys(updates).indexOf(key) + 2}`).join(', ')
|
const updateFields = Object.keys(updates)
|
||||||
updates.updated_at = 'NOW()'
|
.map((key) => `${key} = $${Object.keys(updates).indexOf(key) + 2}`)
|
||||||
const result = await client.query(`UPDATE items SET ${updateFields}, updated_at = $${Object.keys(updates).length + 1} WHERE id = $1 RETURNING *`, [id, ...Object.values(updates)])
|
.join(', ')
|
||||||
return res.json(result.rows[0])
|
updates.updated_at = 'NOW()'
|
||||||
}
|
const result = await client.query(
|
||||||
if (result.rows.length === 0) {
|
`UPDATE items SET ${updateFields}, updated_at = $${Object.keys(updates).length + 1} WHERE id = $1 RETURNING *`,
|
||||||
return res.status(404).json({ message: 'Item not found' })
|
[id, ...Object.values(updates)]
|
||||||
} else {
|
)
|
||||||
return res.status(204).json()
|
return res.json(result.rows[0])
|
||||||
}
|
}
|
||||||
} finally {
|
if (result.rows.length === 0) {
|
||||||
client.release()
|
return res.status(404).json({ message: 'Item not found' })
|
||||||
}
|
} else {
|
||||||
|
return res.status(204).json()
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
client.release()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Delete an item
|
// Delete an item
|
||||||
router.delete('/:id', async (req, res) => {
|
router.delete('/:id', async (req, res) => {
|
||||||
const { id } = req.params
|
const { id } = req.params
|
||||||
const client = await pool.connect()
|
const client = await pool.connect()
|
||||||
try {
|
try {
|
||||||
const result = await client.query('DELETE FROM items WHERE id = $1', [id])
|
const result = await client.query('DELETE FROM items WHERE id = $1', [id])
|
||||||
if (result.rows.length === 0) {
|
if (result.rows.length === 0) {
|
||||||
return res.status(404).json({ message: 'Item not found' })
|
return res.status(404).json({ message: 'Item not found' })
|
||||||
}
|
}
|
||||||
res.json({ message: 'Item deleted' })
|
res.json({ message: 'Item deleted' })
|
||||||
} finally {
|
} finally {
|
||||||
client.release()
|
client.release()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Create a new item from CSV
|
||||||
|
router.post(
|
||||||
|
'/csv',
|
||||||
|
[
|
||||||
|
check('collection_id').not().isEmpty(),
|
||||||
|
check('set_id').not().isEmpty(), // Add validation for set_id
|
||||||
|
],
|
||||||
|
async (req, res) => {
|
||||||
|
const errors = validationResult(req)
|
||||||
|
if (!errors.isEmpty()) {
|
||||||
|
return res.status(400).json({ errors: errors.array() })
|
||||||
|
}
|
||||||
|
const { collection_id, set_id } = req.body
|
||||||
|
const csvBuffer = req.files.file.buffer.toString('utf8')
|
||||||
|
const csvLines = csvBuffer
|
||||||
|
.split('\n')
|
||||||
|
.filter((line) => line.trim().length > 0)
|
||||||
|
const client = await pool.connect()
|
||||||
|
try {
|
||||||
|
// Insert each row into the items table
|
||||||
|
for (const line of csvLines) {
|
||||||
|
const [
|
||||||
|
productId,
|
||||||
|
name,
|
||||||
|
cleanName,
|
||||||
|
imageUrl,
|
||||||
|
categoryId,
|
||||||
|
groupId,
|
||||||
|
url,
|
||||||
|
modifiedOn,
|
||||||
|
imageCount,
|
||||||
|
extCardText,
|
||||||
|
extUPC,
|
||||||
|
lowPrice,
|
||||||
|
midPrice,
|
||||||
|
highPrice,
|
||||||
|
marketPrice,
|
||||||
|
directLowPrice,
|
||||||
|
subTypeName,
|
||||||
|
extNumber,
|
||||||
|
extRarity,
|
||||||
|
extCardType,
|
||||||
|
extHP,
|
||||||
|
extStage,
|
||||||
|
extAttack1,
|
||||||
|
extWeakness,
|
||||||
|
extRetreatCost,
|
||||||
|
extAttack2,
|
||||||
|
extResistance,
|
||||||
|
] = line.split(',').map((value) => value.trim())
|
||||||
|
// Fetch the image from imageUrl
|
||||||
|
const imageResponse = await fetch(imageUrl)
|
||||||
|
const imageBuffer = await imageResponse.buffer()
|
||||||
|
|
||||||
|
// Insert the image into the images table
|
||||||
|
const insertImageResult = await client.query(
|
||||||
|
'INSERT INTO images (file, image) VALUES ($1::TEXT, $2::BYTEA) RETURNING id',
|
||||||
|
[`${productId}.jpg`, imageBuffer]
|
||||||
|
)
|
||||||
|
|
||||||
|
await client.query(
|
||||||
|
'INSERT INTO items (collection_id, image_id, productId, name, cleanName, extCardText, marketPrice, extRarity, set_id, created_at, updated_at) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, NOW(), NOW())',
|
||||||
|
[
|
||||||
|
collection_id,
|
||||||
|
insertImageResult.rows[0].id,
|
||||||
|
productId,
|
||||||
|
name,
|
||||||
|
cleanName,
|
||||||
|
extCardText,
|
||||||
|
marketPrice,
|
||||||
|
extRarity,
|
||||||
|
set_id,
|
||||||
|
]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
res.status(201).json({ message: 'Items created' })
|
||||||
|
} finally {
|
||||||
|
client.release()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
export default router
|
export default router
|
||||||
|
|||||||
Reference in New Issue
Block a user