From a55608bc46b168d265aa5465e1145b48c8b22cf9 Mon Sep 17 00:00:00 2001 From: Felipe Melo Meireles do Nascimento Date: Fri, 4 Nov 2022 19:15:34 -0300 Subject: [PATCH 1/7] resolucao exercicio bonus --- package.json | 3 +- src/interfaces/IOpsInfo.ts | 3 -- src/interfaces/index.ts | 1 - src/models/HandleFile.ts | 26 ----------- src/models/PlantModel.ts | 91 +++++++++++++++++++++----------------- src/models/connection.ts | 8 ++++ 6 files changed, 60 insertions(+), 72 deletions(-) delete mode 100644 src/interfaces/IOpsInfo.ts delete mode 100644 src/models/HandleFile.ts create mode 100644 src/models/connection.ts diff --git a/package.json b/package.json index 7cea669..6275542 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ }, "dependencies": { "body-parser": "1.20.1", - "express": "4.18.2" + "express": "4.18.2", + "mysql2": "2.3.3" } } \ No newline at end of file diff --git a/src/interfaces/IOpsInfo.ts b/src/interfaces/IOpsInfo.ts deleted file mode 100644 index c82f8e2..0000000 --- a/src/interfaces/IOpsInfo.ts +++ /dev/null @@ -1,3 +0,0 @@ -export default interface IOpsInfo { - createdPlants: number -} diff --git a/src/interfaces/index.ts b/src/interfaces/index.ts index f0a934e..5d7fd5c 100644 --- a/src/interfaces/index.ts +++ b/src/interfaces/index.ts @@ -1,2 +1 @@ -export { default as IOpsInfo } from './IOpsInfo'; export { IPlant, INewPlant } from './IPlant'; diff --git a/src/models/HandleFile.ts b/src/models/HandleFile.ts deleted file mode 100644 index eea563a..0000000 --- a/src/models/HandleFile.ts +++ /dev/null @@ -1,26 +0,0 @@ -import fs from 'fs/promises'; -import path from 'path'; - -export enum FileType { - Plants = 'plants', - OpsInfo = 'opsInfo', -} - -const PATHS = { - plants: path.join(__dirname, 'database', 'plantsData.json'), - opsInfo: path.join(__dirname, 'database', 'opsInfo.json'), -}; - -export class HandleFile { - private PATHS = PATHS; - - public async saveFile(type: FileType, data: DataType): Promise { - await fs.writeFile(this.PATHS[`${type}`], JSON.stringify(data, null, 2)); - } - - public async readFile(type: FileType): Promise { - const dataRaw = await fs.readFile(this.PATHS[`${type}`], { encoding: 'utf8' }); - const data: DataType = JSON.parse(dataRaw); - return data; - } -} diff --git a/src/models/PlantModel.ts b/src/models/PlantModel.ts index 67ebd8a..b672b4a 100644 --- a/src/models/PlantModel.ts +++ b/src/models/PlantModel.ts @@ -1,74 +1,83 @@ -import { HandleFile, FileType } from './HandleFile'; -import { IPlant, IOpsInfo } from '../interfaces'; +import { ResultSetHeader } from 'mysql2'; +import connection from './connection'; +import { IPlant } from '../interfaces'; class PlantModel { - private handleFile = new HandleFile(); - - private async updateOpsInfo(incrementAmount = 1): Promise { - const opsInfo = await this.handleFile.readFile(FileType.OpsInfo); - opsInfo.createdPlants += incrementAmount; - - await this.handleFile.saveFile(FileType.OpsInfo, opsInfo); - - return opsInfo.createdPlants; - } + private conn = connection; public async getAll(): Promise { - const plants = await this.handleFile.readFile(FileType.Plants); + const query = `SELECT + id, breed, size, needs_sun as needsSun, origin, water_Frequency as waterFrequency + FROM plants`; + const [rows] = await this.conn.execute(query); + const plants = rows as IPlant[]; return plants; } public async create(plant: Omit): Promise { - const plants = await this.getAll(); - - const newPlantId = await this.updateOpsInfo(1); - const newPlant = { id: newPlantId, ...plant }; - plants.push(newPlant); - - await this.handleFile.saveFile(FileType.Plants, plants); - + const { + breed, needsSun, origin, size, waterFrequency, + } = plant; + const query = `INSERT INTO plants (breed, needs_sun, origin, size, water_frequency) + VALUES (?, ?, ?, ?, ?)`; + const values = [breed, needsSun, origin, size, waterFrequency]; + + const [rows] = await this.conn.execute(query, values); + + const newPlant = { + id: rows.insertId, + ...plant, + }; return newPlant; } public async getById(id: string): Promise { - const plants = await this.getAll(); + const query = `SELECT + id, breed, size, needs_sun as needsSun, origin, water_Frequency as waterFrequency + FROM plants WHERE id = ?`; + const values = [id]; + const [rows] = await this.conn.execute(query, values); + + const plantById = rows as IPlant[]; + if (plantById.length === 0) return null; - const plantById = plants.find((plant) => plant.id === parseInt(id, 10)); - if (!plantById) return null; - return plantById; + return plantById[0]; } public async removeById(id: string): Promise { - const plants = await this.getAll(); - - const removedPlant = plants.find((plant) => plant.id === parseInt(id, 10)); + const removedPlant = await this.getById(id); if (!removedPlant) return null; - const newPlants = plants.filter((plant) => plant.id !== parseInt(id, 10)); - this.handleFile.saveFile(FileType.Plants, newPlants); + const query = 'DELETE FROM plants WHERE id = ?'; + const values = [id]; + await connection.execute(query, values); return removedPlant; } public async update(plant: IPlant): Promise { - const plants = await this.getAll(); + const { + id, breed, needsSun, origin, size, waterFrequency, + } = plant; - const updatedPlants = plants.map((editPlant) => { - if (plant.id === editPlant.id) return { ...plant }; - return editPlant; - }); - - await this.handleFile.saveFile(FileType.Plants, updatedPlants); + const query = `UPDATE plants + SET breed = ?, needs_sun = ?, origin = ?, size = ?, water_frequency = ? + WHERE id = ?`; + const values = [breed, needsSun, origin, size, waterFrequency, id]; + await this.conn.execute(query, values); return plant; } public async getPlantsThatNeedsSun() { - const plants = await this.getAll(); - - const filteredPlants = plants.filter((plant) => plant.needsSun); + const [rows] = await this.conn.execute( + `SELECT + id, breed, size, needs_sun as needsSun, origin, water_Frequency as waterFrequency + FROM plants WHERE needs_sun = true`, + ); - return filteredPlants; + const plants = rows as IPlant[]; + return plants; } } diff --git a/src/models/connection.ts b/src/models/connection.ts new file mode 100644 index 0000000..e3ff695 --- /dev/null +++ b/src/models/connection.ts @@ -0,0 +1,8 @@ +import mysql from 'mysql2/promise'; + +export default mysql.createPool({ + host: 'localhost', + user: 'root', + password: 'mysql', + database: 'TypeScriptExpress', +}); From 1757d0ddabe9e55f6d085d1d37f39feab4c88cef Mon Sep 17 00:00:00 2001 From: Isaac Batista Date: Mon, 7 Nov 2022 19:25:42 -0300 Subject: [PATCH 2/7] add dip --- package-lock.json | 191 +++++++++++++++++- src/controllers/PlantController.ts | 2 +- src/interfaces/IOpsInfo.ts | 3 + src/interfaces/IPlantModel.ts | 10 + src/interfaces/index.ts | 1 + src/models/FsPlantModel.ts | 76 +++++++ src/models/HandleFile.ts | 26 +++ .../{PlantModel.ts => Mysql2PlantModel.ts} | 3 +- src/router/PlantRouter.ts | 7 +- src/router/SunnyRouter.ts | 7 +- src/services/PlantService.ts | 4 +- 11 files changed, 313 insertions(+), 17 deletions(-) create mode 100644 src/interfaces/IOpsInfo.ts create mode 100644 src/interfaces/IPlantModel.ts create mode 100644 src/models/FsPlantModel.ts create mode 100644 src/models/HandleFile.ts rename src/models/{PlantModel.ts => Mysql2PlantModel.ts} (96%) diff --git a/package-lock.json b/package-lock.json index 2f545fd..ff1d9b9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,8 @@ "license": "ISC", "dependencies": { "body-parser": "1.20.1", - "express": "4.18.2" + "express": "4.18.2", + "mysql2": "2.3.3" }, "devDependencies": { "@types/express": "4.17.14", @@ -1021,6 +1022,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "engines": { + "node": ">=0.10" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -2006,6 +2015,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "dependencies": { + "is-property": "^1.0.2" + } + }, "node_modules/get-intrinsic": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", @@ -2417,6 +2434,11 @@ "node": ">=8" } }, + "node_modules/is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==" + }, "node_modules/is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -2616,6 +2638,11 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -2633,7 +2660,6 @@ "version": "4.1.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, "dependencies": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" @@ -2757,6 +2783,62 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "node_modules/mysql2": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-2.3.3.tgz", + "integrity": "sha512-wxJUev6LgMSgACDkb/InIFxDprRa6T95+VEoR+xPvtngtccNH2dGjEB/fVZ8yg1gWv1510c9CvXuJHi5zUm0ZA==", + "dependencies": { + "denque": "^2.0.1", + "generate-function": "^2.3.1", + "iconv-lite": "^0.6.3", + "long": "^4.0.0", + "lru-cache": "^6.0.0", + "named-placeholders": "^1.1.2", + "seq-queue": "^0.0.5", + "sqlstring": "^2.3.2" + }, + "engines": { + "node": ">= 8.0" + } + }, + "node_modules/mysql2/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mysql2/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mysql2/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/named-placeholders": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.2.tgz", + "integrity": "sha512-wiFWqxoLL3PGVReSZpjLVxyJ1bRqe+KKJVbr4hGs1KWfTZTQyezHFBbuKj9hsizHyGV2ne7EMjHdxEGAybD5SA==", + "dependencies": { + "lru-cache": "^4.1.3" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -3070,8 +3152,7 @@ "node_modules/pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", - "dev": true + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" }, "node_modules/punycode": { "version": "2.1.1", @@ -3385,6 +3466,11 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, + "node_modules/seq-queue": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", + "integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==" + }, "node_modules/serve-static": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", @@ -3472,6 +3558,14 @@ "source-map": "^0.6.0" } }, + "node_modules/sqlstring": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", + "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -3924,8 +4018,7 @@ "node_modules/yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", - "dev": true + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" }, "node_modules/yn": { "version": "3.1.1", @@ -4693,6 +4786,11 @@ "object-keys": "^1.1.1" } }, + "denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==" + }, "depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -5468,6 +5566,14 @@ "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "dev": true }, + "generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "requires": { + "is-property": "^1.0.2" + } + }, "get-intrinsic": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", @@ -5750,6 +5856,11 @@ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==" + }, "is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -5904,6 +6015,11 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -5918,7 +6034,6 @@ "version": "4.1.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, "requires": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" @@ -6006,6 +6121,52 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "mysql2": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-2.3.3.tgz", + "integrity": "sha512-wxJUev6LgMSgACDkb/InIFxDprRa6T95+VEoR+xPvtngtccNH2dGjEB/fVZ8yg1gWv1510c9CvXuJHi5zUm0ZA==", + "requires": { + "denque": "^2.0.1", + "generate-function": "^2.3.1", + "iconv-lite": "^0.6.3", + "long": "^4.0.0", + "lru-cache": "^6.0.0", + "named-placeholders": "^1.1.2", + "seq-queue": "^0.0.5", + "sqlstring": "^2.3.2" + }, + "dependencies": { + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, + "named-placeholders": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.2.tgz", + "integrity": "sha512-wiFWqxoLL3PGVReSZpjLVxyJ1bRqe+KKJVbr4hGs1KWfTZTQyezHFBbuKj9hsizHyGV2ne7EMjHdxEGAybD5SA==", + "requires": { + "lru-cache": "^4.1.3" + } + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -6232,8 +6393,7 @@ "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", - "dev": true + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" }, "punycode": { "version": "2.1.1", @@ -6447,6 +6607,11 @@ } } }, + "seq-queue": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", + "integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==" + }, "serve-static": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", @@ -6516,6 +6681,11 @@ "source-map": "^0.6.0" } }, + "sqlstring": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", + "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==" + }, "statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -6834,8 +7004,7 @@ "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", - "dev": true + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" }, "yn": { "version": "3.1.1", diff --git a/src/controllers/PlantController.ts b/src/controllers/PlantController.ts index d16d1ee..4774924 100644 --- a/src/controllers/PlantController.ts +++ b/src/controllers/PlantController.ts @@ -2,7 +2,7 @@ import { Request, Response, NextFunction } from 'express'; import PlantService from '../services/PlantService'; class PlantController { - public service: PlantService = new PlantService(); + constructor(private service: PlantService) {} public async getAll(_req: Request, res: Response, next: NextFunction): Promise { try { diff --git a/src/interfaces/IOpsInfo.ts b/src/interfaces/IOpsInfo.ts new file mode 100644 index 0000000..c82f8e2 --- /dev/null +++ b/src/interfaces/IOpsInfo.ts @@ -0,0 +1,3 @@ +export default interface IOpsInfo { + createdPlants: number +} diff --git a/src/interfaces/IPlantModel.ts b/src/interfaces/IPlantModel.ts new file mode 100644 index 0000000..ca72a6e --- /dev/null +++ b/src/interfaces/IPlantModel.ts @@ -0,0 +1,10 @@ +import { IPlant } from './IPlant'; + +export interface IPlantModel { + getAll(): Promise + create(plant: Omit): Promise + getById(id: string): Promise + removeById(id: string): Promise + update(plant: IPlant): Promise + getPlantsThatNeedsSun(): Promise +} \ No newline at end of file diff --git a/src/interfaces/index.ts b/src/interfaces/index.ts index 5d7fd5c..293294e 100644 --- a/src/interfaces/index.ts +++ b/src/interfaces/index.ts @@ -1 +1,2 @@ export { IPlant, INewPlant } from './IPlant'; +export { default as IOpsInfo } from './IOpsInfo'; diff --git a/src/models/FsPlantModel.ts b/src/models/FsPlantModel.ts new file mode 100644 index 0000000..974ef2d --- /dev/null +++ b/src/models/FsPlantModel.ts @@ -0,0 +1,76 @@ +import { IPlant, IOpsInfo } from '../interfaces'; +import { IPlantModel } from '../interfaces/IPlantModel'; +import { FileType, HandleFile } from './HandleFile'; + +class PlantModel implements IPlantModel { + private handleFile = new HandleFile(); + + private async updateOpsInfo(incrementAmount = 1): Promise { + const opsInfo = await this.handleFile.readFile(FileType.OpsInfo); + opsInfo.createdPlants += incrementAmount; + + await this.handleFile.saveFile(FileType.OpsInfo, opsInfo); + + return opsInfo.createdPlants; + } + + public async getAll(): Promise { + const plants = await this.handleFile.readFile(FileType.Plants); + return plants; + } + + public async create(plant: Omit): Promise { + const plants = await this.getAll(); + + const newPlantId = await this.updateOpsInfo(1); + const newPlant = { id: newPlantId, ...plant }; + plants.push(newPlant); + + await this.handleFile.saveFile(FileType.Plants, plants); + + return newPlant; + } + + public async getById(id: string): Promise { + const plants = await this.getAll(); + + const plantById = plants.find((plant) => plant.id === parseInt(id, 10)); + if (!plantById) return null; + return plantById; + } + + public async removeById(id: string): Promise { + const plants = await this.getAll(); + + const removedPlant = plants.find((plant) => plant.id === parseInt(id, 10)); + if (!removedPlant) return null; + + const newPlants = plants.filter((plant) => plant.id !== parseInt(id, 10)); + this.handleFile.saveFile(FileType.Plants, newPlants); + + return removedPlant; + } + + public async update(plant: IPlant): Promise { + const plants = await this.getAll(); + + const updatedPlants = plants.map((editPlant) => { + if (plant.id === editPlant.id) return { ...plant }; + return editPlant; + }); + + await this.handleFile.saveFile(FileType.Plants, updatedPlants); + + return plant; + } + + public async getPlantsThatNeedsSun() { + const plants = await this.getAll(); + + const filteredPlants = plants.filter((plant) => plant.needsSun); + + return filteredPlants; + } +} + +export default PlantModel; diff --git a/src/models/HandleFile.ts b/src/models/HandleFile.ts new file mode 100644 index 0000000..eea563a --- /dev/null +++ b/src/models/HandleFile.ts @@ -0,0 +1,26 @@ +import fs from 'fs/promises'; +import path from 'path'; + +export enum FileType { + Plants = 'plants', + OpsInfo = 'opsInfo', +} + +const PATHS = { + plants: path.join(__dirname, 'database', 'plantsData.json'), + opsInfo: path.join(__dirname, 'database', 'opsInfo.json'), +}; + +export class HandleFile { + private PATHS = PATHS; + + public async saveFile(type: FileType, data: DataType): Promise { + await fs.writeFile(this.PATHS[`${type}`], JSON.stringify(data, null, 2)); + } + + public async readFile(type: FileType): Promise { + const dataRaw = await fs.readFile(this.PATHS[`${type}`], { encoding: 'utf8' }); + const data: DataType = JSON.parse(dataRaw); + return data; + } +} diff --git a/src/models/PlantModel.ts b/src/models/Mysql2PlantModel.ts similarity index 96% rename from src/models/PlantModel.ts rename to src/models/Mysql2PlantModel.ts index b672b4a..8b1d871 100644 --- a/src/models/PlantModel.ts +++ b/src/models/Mysql2PlantModel.ts @@ -1,8 +1,9 @@ import { ResultSetHeader } from 'mysql2'; import connection from './connection'; import { IPlant } from '../interfaces'; +import { IPlantModel } from '../interfaces/IPlantModel'; -class PlantModel { +class PlantModel implements IPlantModel { private conn = connection; public async getAll(): Promise { diff --git a/src/router/PlantRouter.ts b/src/router/PlantRouter.ts index 367c504..b633f2e 100644 --- a/src/router/PlantRouter.ts +++ b/src/router/PlantRouter.ts @@ -2,7 +2,12 @@ import { Router } from 'express'; import PlantController from '../controllers/PlantController'; -const plantController = new PlantController(); +import Mysql2PlantModel from '../models/Mysql2PlantModel'; +import PlantService from '../services/PlantService'; + +const plantModel = new Mysql2PlantModel(); +const plantService = new PlantService(plantModel); +const plantController = new PlantController(plantService); const plantRouter = Router(); diff --git a/src/router/SunnyRouter.ts b/src/router/SunnyRouter.ts index 1c3434d..4596fcd 100644 --- a/src/router/SunnyRouter.ts +++ b/src/router/SunnyRouter.ts @@ -2,7 +2,12 @@ import { Router } from 'express'; import PlantController from '../controllers/PlantController'; -const plantController = new PlantController(); +import Mysql2PlantModel from '../models/Mysql2PlantModel'; +import PlantService from '../services/PlantService'; + +const plantModel = new Mysql2PlantModel(); +const plantService = new PlantService(plantModel); +const plantController = new PlantController(plantService); const sunnyRouter = Router(); diff --git a/src/services/PlantService.ts b/src/services/PlantService.ts index 4077092..d74b0c0 100644 --- a/src/services/PlantService.ts +++ b/src/services/PlantService.ts @@ -1,10 +1,10 @@ -import PlantModel from '../models/PlantModel'; import { INewPlant, IPlant } from '../interfaces'; +import { IPlantModel } from '../interfaces/IPlantModel'; import { NotFoundException } from './exceptions'; import PlantValidate from './validations/PlantValidate'; class PlantService { - private model: PlantModel = new PlantModel(); + constructor(private model: IPlantModel) {} public async getAll(): Promise { const plants = await this.model.getAll(); From 9b28963ec3a9e2afbea6a4d78d6ab803267f2845 Mon Sep 17 00:00:00 2001 From: Felipe Melo Meireles do Nascimento Date: Tue, 8 Nov 2022 14:34:18 -0300 Subject: [PATCH 3/7] ajustes --- package-lock.json | 1 - src/models/Mysql2PlantModel.ts | 3 +-- src/models/connection.ts | 4 ++-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index ff1d9b9..da17372 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,6 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "body-parser": "1.20.1", "express": "4.18.2", "mysql2": "2.3.3" }, diff --git a/src/models/Mysql2PlantModel.ts b/src/models/Mysql2PlantModel.ts index 8b1d871..4f4b940 100644 --- a/src/models/Mysql2PlantModel.ts +++ b/src/models/Mysql2PlantModel.ts @@ -1,7 +1,6 @@ import { ResultSetHeader } from 'mysql2'; import connection from './connection'; -import { IPlant } from '../interfaces'; -import { IPlantModel } from '../interfaces/IPlantModel'; +import { IPlantModel, IPlant } from '../interfaces'; class PlantModel implements IPlantModel { private conn = connection; diff --git a/src/models/connection.ts b/src/models/connection.ts index e3ff695..303ed96 100644 --- a/src/models/connection.ts +++ b/src/models/connection.ts @@ -3,6 +3,6 @@ import mysql from 'mysql2/promise'; export default mysql.createPool({ host: 'localhost', user: 'root', - password: 'mysql', - database: 'TypeScriptExpress', + password: '', // senha do seu banco de dados + database: 'typescript_express', }); From ad9fcbc7349d16fb45879a986fe9ab9bb0911ec4 Mon Sep 17 00:00:00 2001 From: Felipe Melo Meireles do Nascimento Date: Tue, 8 Nov 2022 16:14:19 -0300 Subject: [PATCH 4/7] ajustes --- src/interfaces/IPlantModel.ts | 4 ++-- src/models/Mysql2PlantModel.ts | 31 +++++++++---------------------- src/services/PlantService.ts | 4 ++-- 3 files changed, 13 insertions(+), 26 deletions(-) diff --git a/src/interfaces/IPlantModel.ts b/src/interfaces/IPlantModel.ts index d499111..609d211 100644 --- a/src/interfaces/IPlantModel.ts +++ b/src/interfaces/IPlantModel.ts @@ -1,9 +1,9 @@ -import { IPlant } from '.'; +import { IPlant } from './IPlant'; export default interface IPlantModel { getAll(): Promise create(plant: Omit): Promise getById(id: string): Promise - removeById(id: string): Promise + removeById(id: string): Promise update(plant: IPlant): Promise } diff --git a/src/models/Mysql2PlantModel.ts b/src/models/Mysql2PlantModel.ts index 4f4b940..abf513b 100644 --- a/src/models/Mysql2PlantModel.ts +++ b/src/models/Mysql2PlantModel.ts @@ -1,4 +1,4 @@ -import { ResultSetHeader } from 'mysql2'; +import { RowDataPacket, ResultSetHeader, OkPacket } from 'mysql2'; import connection from './connection'; import { IPlantModel, IPlant } from '../interfaces'; @@ -9,7 +9,7 @@ class PlantModel implements IPlantModel { const query = `SELECT id, breed, size, needs_sun as needsSun, origin, water_Frequency as waterFrequency FROM plants`; - const [rows] = await this.conn.execute(query); + const [rows] = await this.conn.execute(query); const plants = rows as IPlant[]; return plants; } @@ -22,10 +22,10 @@ class PlantModel implements IPlantModel { VALUES (?, ?, ?, ?, ?)`; const values = [breed, needsSun, origin, size, waterFrequency]; - const [rows] = await this.conn.execute(query, values); + const [result] = await this.conn.execute(query, values); const newPlant = { - id: rows.insertId, + id: result.insertId, ...plant, }; return newPlant; @@ -44,15 +44,13 @@ class PlantModel implements IPlantModel { return plantById[0]; } - public async removeById(id: string): Promise { - const removedPlant = await this.getById(id); - if (!removedPlant) return null; - + public async removeById(id: string): Promise { const query = 'DELETE FROM plants WHERE id = ?'; const values = [id]; - await connection.execute(query, values); - return removedPlant; + const [{ affectedRows }] = await this.conn.execute(query, values); + + return (affectedRows !== 0); } public async update(plant: IPlant): Promise { @@ -64,21 +62,10 @@ class PlantModel implements IPlantModel { SET breed = ?, needs_sun = ?, origin = ?, size = ?, water_frequency = ? WHERE id = ?`; const values = [breed, needsSun, origin, size, waterFrequency, id]; - await this.conn.execute(query, values); + await this.conn.execute(query, values); return plant; } - - public async getPlantsThatNeedsSun() { - const [rows] = await this.conn.execute( - `SELECT - id, breed, size, needs_sun as needsSun, origin, water_Frequency as waterFrequency - FROM plants WHERE needs_sun = true`, - ); - - const plants = rows as IPlant[]; - return plants; - } } export default PlantModel; diff --git a/src/services/PlantService.ts b/src/services/PlantService.ts index 8738fe3..71167b3 100644 --- a/src/services/PlantService.ts +++ b/src/services/PlantService.ts @@ -29,8 +29,8 @@ class PlantService { } public async removeById(id: string): Promise { - const plant = await this.model.removeById(id); - if (!plant) throw new NotFoundException('Plant not Found!'); + const isPlantRemoved = await this.model.removeById(id); + if (!isPlantRemoved) throw new NotFoundException('Plant not Found!'); } public async update(id: string, plant: Omit): Promise { From 9153ea77434b727648e1929713b7dfce9075b0f9 Mon Sep 17 00:00:00 2001 From: Felipe Nascimento <69821619+flpnascto@users.noreply.github.com> Date: Tue, 8 Nov 2022 16:33:19 -0300 Subject: [PATCH 5/7] ajustes --- src/models/FsPlantModel.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/models/FsPlantModel.ts b/src/models/FsPlantModel.ts index 1e0533b..46bdf9b 100644 --- a/src/models/FsPlantModel.ts +++ b/src/models/FsPlantModel.ts @@ -38,16 +38,16 @@ class PlantModel implements IPlantModel { return plantById; } - public async removeById(id: string): Promise { + public async removeById(id: string): Promise { const plants = await this.getAll(); const removedPlant = plants.find((plant) => plant.id === parseInt(id, 10)); - if (!removedPlant) return null; + if (!removedPlant) return false; const newPlants = plants.filter((plant) => plant.id !== parseInt(id, 10)); this.handleFile.saveFile(FileType.Plants, newPlants); - return removedPlant; + return true; } public async update(plant: IPlant): Promise { From a194f86e381597f542f102ca0e80425899dd455f Mon Sep 17 00:00:00 2001 From: Felipe Melo Meireles do Nascimento Date: Wed, 16 Nov 2022 17:17:58 -0300 Subject: [PATCH 6/7] fix import --- src/models/Mysql2PlantModel.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/models/Mysql2PlantModel.ts b/src/models/Mysql2PlantModel.ts index abf513b..69ee87a 100644 --- a/src/models/Mysql2PlantModel.ts +++ b/src/models/Mysql2PlantModel.ts @@ -1,6 +1,7 @@ import { RowDataPacket, ResultSetHeader, OkPacket } from 'mysql2'; import connection from './connection'; -import { IPlantModel, IPlant } from '../interfaces'; +import { IPlantModel } from './interfaces'; +import { IPlant } from '../interfaces'; class PlantModel implements IPlantModel { private conn = connection; From 35f6ba0e63c6eaecb1197711bf05a23fcc323125 Mon Sep 17 00:00:00 2001 From: Felipe Melo Meireles do Nascimento Date: Fri, 18 Nov 2022 16:44:24 -0300 Subject: [PATCH 7/7] fix: PlantModel interface --- src/models/Mysql2PlantModel.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/models/Mysql2PlantModel.ts b/src/models/Mysql2PlantModel.ts index 69ee87a..6ae2a75 100644 --- a/src/models/Mysql2PlantModel.ts +++ b/src/models/Mysql2PlantModel.ts @@ -1,9 +1,9 @@ import { RowDataPacket, ResultSetHeader, OkPacket } from 'mysql2'; import connection from './connection'; -import { IPlantModel } from './interfaces'; +import { IModel } from './interfaces'; import { IPlant } from '../interfaces'; -class PlantModel implements IPlantModel { +class PlantModel implements IModel { private conn = connection; public async getAll(): Promise {