/** @module classes */
const BookController = require('../../controllers/BookController.js');
const AuthorController = require('../../controllers/AuthorController.js');
const EditionController = require('../../controllers/EditionController.js');
const BaseFactory = require('../Base.js');
/** Class representing a Book. */
class Book {
/**
* Create a book.
* @param {number} id
* @param {string} title
* @param {Date} publicationDate
* @param {Date} createdAt
* @param {Date} updatedAt
* @param {string} subtitle
*/
constructor(id, title, publicationDate, createdAt, updatedAt, subtitle = null) {
this.id = id;
this.title = title;
this.subtitle = subtitle;
this.publicationDate = publicationDate;
this.createdAt = createdAt;
this.updatedAt = updatedAt;
}
/**
* Get the authors of the book.
*
* @param {bool} forceRefresh
* @returns {Promise<object[]>}
*/
async getAuthors(forceRefresh = false) {
if (this.authors && !forceRefresh) {
return this.authors;
}
this.authors = await new AuthorController().byBook(this.id);
return this.authors;
}
/**
* Get the editions of the book.
*
* @param {bool} forceRefresh
* @returns {Promise<object[]>}
*/
async getEditions(forceRefresh = false) {
if (this.editions && !forceRefresh) {
return this.editions;
}
this.editions = await new EditionController().byBook(this);
return this.editions;
}
/** Refreshes data from the database that has been pulled at least once before in this instance. */
async refresh() {
if (this.authors) {
await this.getAuthors(true);
}
if (this.editions) {
await this.getEditions(true);
}
}
}
/** Class representing a book factory. */
class BookFactory extends BaseFactory {
/** Set the id of the book. */
setId(id) {
this.id = id;
return this;
}
/** Set the title of the book. */
setTitle(title) {
this.title = title;
return this;
}
/** Set the subtitle of the book. */
setSubtitle(subtitle) {
this.subtitle = subtitle;
return this;
}
/** Set the publication date of the book. */
setPublicationDate(publicationDate) {
this.publicationDate = publicationDate;
return this;
}
/** Set the created at date of the book. */
setCreatedAt(createdAt) {
this.createdAt = createdAt;
return this;
}
/** Set the updated at date of the book. */
setUpdatedAt(updatedAt) {
this.updatedAt = updatedAt;
return this;
}
/** Load a book from a database object. */
load(dbObject) {
this.setId(dbObject.id);
this.setTitle(dbObject.title);
this.setSubtitle(dbObject.subtitle);
this.setPublicationDate(new Date(dbObject.publication_date));
this.setCreatedAt(new Date(dbObject.created_at));
this.setUpdatedAt(new Date(dbObject.updated_at));
return this;
}
/** Create the book. */
async create() {
if (!this.id) {
return null;
} else if (!this.title && !this.subtitle && !this.publicationDate && !this.createdAt && !this.updatedAt) {
this.load(await new BookController().byId(this.id));
}
return new Book(this.id, this.title, this.publicationDate, this.createdAt, this.updatedAt, this.subtitle);
}
}
module.exports = { BookFactory, Book };