This repository has been archived on 2024-02-11. You can view files and clone it, but cannot push or open issues or pull requests.
Files
restful-api-task/services/NotesService.js
2021-10-15 02:15:38 +03:00

180 lines
4.5 KiB
JavaScript

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<void>}
*/
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