//const data = require('../repositories/data.json') import * as path from 'path' import * as fs from 'fs' class NotesService { dbPath db limit constructor () { this.dbPath = path.resolve('./repositories/data.json') try { const data = fs.readFileSync(this.dbPath, 'utf8') this.db = JSON.parse(data || '[]') } catch (e) { this.db = [] } this.limit = 7 } /** * USE AT FINAL STAGE BEFORE RETURN FROM THE METHOD TO AVOID HELTER SKELTER IN THE RESULT * * @param result * @param query * @returns {*|{result: null, data: *[], query: null, message: string, type: string, status: string}} * @private */ _composeResponse (result, query) { const response = { code: 200, status: 'Accepted', message: `The database contains ${this.db.length} notes`, result: `Matched ${result.length} note(s)`, query: query, type: 'Completed', data: [], } if (result.length === 1) { response.data = result[0] } else if (result.length > 1) { response.data = result } else { response.code = 404 response.type = 'Warning' } return response } /** * * @param id * @returns {*|{result: null, data: *[], query: null, message: string, type: string, status: string}} */ getSingle (id) { //, returned LIMIT ${this.limit} ORDER BY id DESC const note = this.db.filter(el => el.id === +id) return this._composeResponse(note, `id = ${id} LIMIT 1`) } /** * * @returns {*|{result: null, data: *[], query: null, message: string, type: string, status: string}} */ get getNotes () { const notes = this.db.sort((a, b) => new Date(a.created_at) > new Date(b.created_at) ? -1 : 1) return this._composeResponse(notes.slice(0, this.limit), `ORDER BY created_at DESC LIMIT ` + this.limit) } /** * * @param id * @returns {Promise<*|{result: null, data: *[], query: null, message: string, type: string, status: string}>} */ async deleteNote (id) { const deletedNote = this.db.filter(note => note.id === +id) if (deletedNote.length === 1) { this.db = this.db.filter(note => note.id !== +id) await this.saveDatabase() } return this._composeResponse(deletedNote, `DELETED FROM db WHERE id = ${id}`) } /** * * @param data * @returns {Promise<*|{result: null, data: *[], query: null, message: string, type: string, status: string}>} */ async insertNote( data ){ const notes = this.db.sort((a, b) => new Date(a.id) > new Date(b.id) ? -1 : 1) data.id = ( notes.length >= 1 ) ? notes[0].id + 1 : 1 this.db.push(data) await this.saveDatabase() return this._composeResponse([data], `INSERT INTO database SET id = ${data.id} (AI)`) } /** * * @param data * @returns {Promise<*|{result: null, data: *[], query: null, message: string, type: string, status: string}>} */ async updateNote( data ){ const noteExists = this.db.find(note => note.id === +data.id) if( noteExists ){ noteExists.title = data.title noteExists.content = data.content noteExists.category = data.category noteExists.archive = data.archive noteExists.updated_at = data.updated_at await this.saveDatabase() return this._composeResponse([noteExists], `UPDATED WHERE id = ${data.id}`) } return this._composeResponse([], `UPDATED WHERE id = ${data.id}`) } /** * * @returns {Promise} */ async saveDatabase () { try { await fs.promises.writeFile(this.dbPath, JSON.stringify(this.db, null, 2), { encoding: 'utf-8' }) } catch (e) { console.error(e) } } /** * * @returns {{result: string, data: {}, query: string, message: string, status: string}} */ get getStats () { const stats = {} const cats = [...new Set(this.db.map(item => item.category))] if (typeof cats[0] !== 'undefined') { const isArchive = this.db.map(item => { const container = {} container[item.category] = item.archive return container }) cats.forEach((cat, i) => { stats[cat] = { total: this.db.filter(el => el.category === cat).length, archived: isArchive.filter(el => el[cat] === true).length, active: isArchive.filter(el => el[cat] === false).length, } }) } return { code: 200, status: 'Accepted', message: `The database contains ${this.db.length} notes`, result: `Aggregated data statistics`, query: `GROUP BY categories, (active|archived)`, type: 'Completed', data: stats, } } } export default NotesService