/** @module controllers */
const BaseDatabaseController = require("./BaseDatabaseController");
/** Default metadata for spine images */
const spineImagesDefaultMeta = {
"crowdApproved": false,
"crowdConfirmations": 0,
"crowdRejections": 0,
};
/** Class representing a spine image controller. */
class SpineImageController extends BaseDatabaseController {
/** Create a spine image controller. */
constructor() {
super();
}
/**
* Get a spine image by id.
*
* @param {number} id
* @returns {Promise<object>}
*/
async byId(id) {
const spineImageResponse = await this._query('SELECT * FROM spine_images WHERE id = ?', id);
if (spineImageResponse.length !== 1) {
return null;
}
return spineImageResponse[0];
}
/**
* Get spine images by edition.
*
* @param {number} editionId
* @returns {Promise<object[]>}
*/
async byEdition(editionId) {
const spineImagesResponse = await this._query('SELECT * FROM spine_images WHERE edition_id = ?', editionId);
return spineImagesResponse;
}
/**
* Get spine images that have been crowd approved.
*
* @param {number} amount
* @param {boolean} approved
* @returns {Promise<object[]>}
*/
async byCrowdApproved(amount = 5, approved = true) {
const spineImagesResponse = await this._query('SELECT si.* FROM spine_images AS si JOIN spine_images_meta AS sim WHERE name = "crowdApproved" AND value = ? AND sim.image_id = si.id ORDER BY RAND() LIMIT ?', approved, parseInt(amount));
return spineImagesResponse;
}
/**
* Insert a spine image.
*
* @param {number} editionId
* @param {string} filepath
* @returns {Promise<object>}
*/
async insert(editionId, filepath) {
const dbInsertion = await this._query('INSERT INTO spine_images (edition_id, filepath) VALUES (?, ?)', editionId, filepath);
if (!dbInsertion.insertId) {
throw new Error('Failed to save spine image');
}
for (const key in spineImagesDefaultMeta) {
await this._query('INSERT INTO spine_images_meta (image_id, name, value) VALUES (?, ?, ?)', dbInsertion.insertId, key, spineImagesDefaultMeta[key]);
}
return await this.byId(dbInsertion.insertId);
}
/**
* Set a meta value for a spine image.
*
* @param {number} imageId
* @param {string} name
* @param {any} value
* @returns {Promise<void>}
*/
async setMeta(imageId, name, value) {
const existsCheck = await this._query('SELECT * FROM spine_images_meta WHERE image_id = ? AND name = ?', imageId, name);
if (!existsCheck) {
await this._query('INSERT INTO spine_images_meta (image_id, name, value) VALUES (?, ?, ?)', imageId, name, value);
} else {
await this._query('UPDATE spine_images_meta SET value = ? WHERE image_id = ? AND name = ?', value, imageId, name);
}
}
/**
* Get a meta value for a spine image.
*
* @param {number} imageId
* @param {string} name
* @returns {Promise<any>}
*/
async getMeta(imageId, name) {
const meta = await this._query('SELECT * FROM spine_images_meta WHERE image_id = ? AND name = ?', imageId, name);
if (meta.length === 0) {
return null;
}
return meta[0].value;
}
/**
* Delete a spine image.
*
* @param {number} id
* @returns {Promise<void>}
*/
async delete(id) {
await this._query('DELETE FROM spine_images WHERE id = ?', id);
// Delete all contributions to this spine image
await this._query('DELETE uc FROM user_contributions AS uc JOIN contribution_types AS ct WHERE uc.contribution_type_id = ct.id AND ct.code = "ADD_SPINE_IMAGE" AND uc.contribution_record_id = ?', id);
}
}
module.exports = SpineImageController;