From da0e3856094bab3e362b127117103fc770d3ce78 Mon Sep 17 00:00:00 2001 From: Zainab Choudhry Date: Mon, 5 Aug 2024 18:43:49 +0100 Subject: [PATCH 1/3] added get, post, put and delete functions for books --- db/index.js | 16 ++++---- package-lock.json | 63 ++++++---------------------- package.json | 4 +- src/controllers/books.controller.js | 62 ++++++++++++++++++++++++++++ src/routers/books.js | 64 ++++++++++++++++++++++++++--- src/server.js | 1 + 6 files changed, 144 insertions(+), 66 deletions(-) create mode 100644 src/controllers/books.controller.js diff --git a/db/index.js b/db/index.js index af723442..90406484 100644 --- a/db/index.js +++ b/db/index.js @@ -1,5 +1,5 @@ // Load our .env file -require('dotenv').config() +require("dotenv").config(); // Require Client obj from the postgres node module const { Client } = require("pg"); @@ -11,15 +11,15 @@ const client = { // on the contents of our env file // Create a new connection to the database using the Client // object provided by the postgres node module - const dbClient = new Client(process.env.PGURL) + const dbClient = new Client(process.env.PGURL); // connect a connection - await dbClient.connect() + await dbClient.connect(); // execute the query - const result = await dbClient.query(str, values) + const result = await dbClient.query(str, values); // close the connection - await dbClient.end() - return result - } -} + await dbClient.end(); + return result; + }, +}; module.exports = client; diff --git a/package-lock.json b/package-lock.json index 37ccdff8..1ec30345 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "body-parser": "^1.20.2", "cors": "^2.8.5", "dotenv": "^16.3.1", - "express": "^4.18.2", + "express": "^4.19.2", "faker": "^5.5.3", "morgan": "1.10.0", "pg": "8.6.0", @@ -19,7 +19,7 @@ }, "devDependencies": { "jest": "^28.1.3", - "nodemon": "^3.0.2", + "nodemon": "^3.1.4", "supertest": "^6.3.3" } }, @@ -1740,9 +1740,9 @@ "dev": true }, "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "engines": { "node": ">= 0.6" } @@ -2024,16 +2024,16 @@ } }, "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.1", + "body-parser": "1.20.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.5.0", + "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -2064,43 +2064,6 @@ "node": ">= 0.10.0" } }, - "node_modules/express/node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/express/node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/faker": { "version": "5.5.3", "resolved": "https://registry.npmjs.org/faker/-/faker-5.5.3.tgz", @@ -3586,9 +3549,9 @@ "dev": true }, "node_modules/nodemon": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.0.2.tgz", - "integrity": "sha512-9qIN2LNTrEzpOPBaWHTm4Asy1LxXLSickZStAQ4IZe7zsoIpD/A7LWxhZV3t4Zu352uBcqVnRsDXSMR2Sc3lTA==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.4.tgz", + "integrity": "sha512-wjPBbFhtpJwmIeY2yP7QF+UKzPfltVGtfce1g/bB15/8vCGZj8uxD62b/b9M9/WVgme0NZudpownKN+c0plXlQ==", "dev": true, "dependencies": { "chokidar": "^3.5.2", diff --git a/package.json b/package.json index 57d8b4fb..ce8ca94a 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "body-parser": "^1.20.2", "cors": "^2.8.5", "dotenv": "^16.3.1", - "express": "^4.18.2", + "express": "^4.19.2", "faker": "^5.5.3", "morgan": "1.10.0", "pg": "8.6.0", @@ -20,7 +20,7 @@ }, "devDependencies": { "jest": "^28.1.3", - "nodemon": "^3.0.2", + "nodemon": "^3.1.4", "supertest": "^6.3.3" }, "keywords": [] diff --git a/src/controllers/books.controller.js b/src/controllers/books.controller.js new file mode 100644 index 00000000..51df6f91 --- /dev/null +++ b/src/controllers/books.controller.js @@ -0,0 +1,62 @@ +const client = require("../../db/index"); + +const getAllBooks = async () => { + try { + const response = await client.query("SELECT * FROM books"); + return response.rows; + } catch (error) { + console.log("Error:", error); + } +}; + +const createBook = async (book) => { + try { + const response = await client.query(` + INSERT INTO books (title, type, author, topic, publication_date, pages) + VALUES + ('${book.title}', '${book.type}', '${book.author}', '${book.topic}', '${book.publication_date}', '${book.pages}' ) returning * + `); + return response.rows; + } catch (error) { + console.log("Error:", error); + } +}; + +const getBookById = async (id) => { + try { + const response = await client.query(`SELECT * FROM books WHERE id = ${id}`); + return response.rows[0]; + } catch (error) { + console.log("Error:", error); + } +}; + +const updateBook = async (id, bookInfo) => { + try { + const response = await client.query(`UPDATE books + SET title = '${bookInfo.title}', type = '${bookInfo.type}', author = '${bookInfo.author}', topic = '${bookInfo.topic}', publication_date = '${bookInfo.publication_date}', pages = '${bookInfo.pages}' + WHERE id = ${id} RETURNING *`); + + return response.rows[0]; + } catch (error) { + console.log("Error:", error); + } +}; + +const deleteBook = async (id) => { + try { + const response = await client.query( + `DELETE FROM books WHERE id = ${id} RETURNING *` + ); + return response.rows; + } catch (error) { + console.log("Error:", error); + } +} +module.exports = { + getAllBooks, + createBook, + getBookById, + updateBook, + deleteBook +}; diff --git a/src/routers/books.js b/src/routers/books.js index 1551dd87..d6950a8e 100644 --- a/src/routers/books.js +++ b/src/routers/books.js @@ -1,9 +1,61 @@ -const express = require('express') -const router = express.Router() -const db = require("../../db"); +const express = require("express"); +const router = express.Router(); +const client = require("../../db/index"); +const { + getAllBooks, + createBook, + getBookById, + updateBook, + deleteBook +} = require("../controllers/books.controller"); -router.get('/', async (req, res) => { +router.get("/", async (req, res) => { + const books = await getAllBooks(); + // console.log(books) + res.status(200).json({ + books, + }); +}); -}) +router.post("/", async (req, res) => { + const book = req.body; -module.exports = router + const newBook = await createBook(book); + + res.status(201).json({ + book: newBook, + }); +}); + +router.get("/:id", async (req, res) => { + const id = Number(req.params.id); + + const selectedBook = await getBookById(id); + + res.status(200).json({ + book: selectedBook, + }); +}); + +router.put("/:id", async (req, res) => { + const id = Number(req.params.id); + const bookInfo = req.body; + + + const bookToUpdate = await updateBook(id, bookInfo); + + res.status(201).json({ + book: bookToUpdate, + }); +}); + +router.delete("/:id", async (req, res) => { + const id = Number(req.params.id); + const bookToDelete = await deleteBook(id); + res.status(201).json({ + book: bookToDelete + }); +}); + + +module.exports = router; diff --git a/src/server.js b/src/server.js index dac55e5d..4320b930 100644 --- a/src/server.js +++ b/src/server.js @@ -1,6 +1,7 @@ const express = require("express"); const morgan = require("morgan"); const cors = require("cors"); +require("dotenv").config(); const app = express(); From b929ff54677b25c527caa3d522b0a95face8e3bb Mon Sep 17 00:00:00 2001 From: Zainab Choudhry Date: Mon, 5 Aug 2024 19:12:36 +0100 Subject: [PATCH 2/3] added get, post, put and delete functions for pets --- src/controllers/pets.controller.js | 63 ++++++++++++++++++++++++++++++ src/routers/books.js | 1 - src/routers/pets.js | 53 +++++++++++++++++++++++++ src/server.js | 3 +- 4 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 src/controllers/pets.controller.js create mode 100644 src/routers/pets.js diff --git a/src/controllers/pets.controller.js b/src/controllers/pets.controller.js new file mode 100644 index 00000000..1f5f5d58 --- /dev/null +++ b/src/controllers/pets.controller.js @@ -0,0 +1,63 @@ +const client = require("../../db/index"); + +const getAllPets = async () => { + try { + const response = await client.query("SELECT * FROM pets"); + return response.rows; + } catch (error) { + console.log("Error:", error); + } +}; + +const createPet = async (pet) => { + try { + const response = await client.query(` + INSERT INTO pets (name, age, type, breed, has_microchip) + VALUES + ('${pet.name}', '${pet.age}', '${pet.type}', '${pet.breed}', '${pet.has_microchip}') returning * + `); + return response.rows; + } catch (error) { + console.log("Error:", error); + } +}; + +const getPetById = async (id) => { + try { + const response = await client.query(`SELECT * FROM pets WHERE id = ${id}`); + return response.rows[0]; + } catch (error) { + console.log("Error:", error); + } +}; + +const updatePet = async (id, petInfo) => { + try { + const response = await client.query(`UPDATE pets + SET name = '${petInfo.name}', age = '${petInfo.age}', type = '${petInfo.type}', breed = '${petInfo.breed}', has_microchip = '${petInfo.has_microchip}' + WHERE id = ${id} RETURNING *`); + + return response.rows[0]; + } catch (error) { + console.log("Error:", error); + } +}; + +const deletePet = async (id) => { + try { + const response = await client.query( + `DELETE FROM pets WHERE id = ${id} RETURNING *` + ); + return response.rows; + } catch (error) { + console.log("Error:", error); + } +}; + +module.exports = { + getAllPets, + createPet, + getPetById, + updatePet, + deletePet +}; diff --git a/src/routers/books.js b/src/routers/books.js index d6950a8e..3a7af897 100644 --- a/src/routers/books.js +++ b/src/routers/books.js @@ -1,6 +1,5 @@ const express = require("express"); const router = express.Router(); -const client = require("../../db/index"); const { getAllBooks, createBook, diff --git a/src/routers/pets.js b/src/routers/pets.js new file mode 100644 index 00000000..4cb0cc4f --- /dev/null +++ b/src/routers/pets.js @@ -0,0 +1,53 @@ +const express = require("express"); +const router = express.Router(); +const { getAllPets, createPet, getPetById, updatePet, deletePet } = require("../controllers/pets.controller"); + +router.get("/", async (req, res) => { + const pets = await getAllPets(); + // console.log(books) + res.status(200).json({ + pets + }); +}); + +router.post("/", async (req, res) => { + const pet = req.body; + + const newPet = await createPet(pet); + + res.status(201).json({ + pet: newPet, + }); +}); + +router.get("/:id", async (req, res) => { + const id = Number(req.params.id); + + const selectedPet = await getPetById(id); + + res.status(200).json({ + pet: selectedPet, + }); +}); + +router.put("/:id", async (req, res) => { + const id = Number(req.params.id); + const petInfo = req.body; + + const petToUpdate = await updatePet(id, petInfo); + + res.status(201).json({ + pet: petToUpdate, + }); +}); + +router.delete("/:id", async (req, res) => { + const id = Number(req.params.id); + const petToDelete = await deletePet(id); + res.status(201).json({ + pet: petToDelete, + }); +}); + + +module.exports = router; \ No newline at end of file diff --git a/src/server.js b/src/server.js index 4320b930..233ceb88 100644 --- a/src/server.js +++ b/src/server.js @@ -1,7 +1,6 @@ const express = require("express"); const morgan = require("morgan"); const cors = require("cors"); -require("dotenv").config(); const app = express(); @@ -11,7 +10,9 @@ app.use(express.json()); //TODO: Implement books and pets APIs using Express Modular Routers const booksRouter = require('./routers/books.js') +const petsRouter = require('./routers/pets.js') app.use('/books', booksRouter) +app.use('/pets', petsRouter) module.exports = app From 251ab2069af19f0faae2e6a80f8a00eaf5812d09 Mon Sep 17 00:00:00 2001 From: Zainab Choudhry Date: Mon, 5 Aug 2024 19:34:00 +0100 Subject: [PATCH 3/3] Completed core + extension 2 --- src/controllers/books.controller.js | 25 +++++++++++++++---------- src/controllers/pets.controller.js | 24 ++++++++++++++---------- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/src/controllers/books.controller.js b/src/controllers/books.controller.js index 51df6f91..bdf957fd 100644 --- a/src/controllers/books.controller.js +++ b/src/controllers/books.controller.js @@ -1,3 +1,4 @@ +const { response } = require("express"); const client = require("../../db/index"); const getAllBooks = async () => { @@ -11,12 +12,16 @@ const getAllBooks = async () => { const createBook = async (book) => { try { - const response = await client.query(` - INSERT INTO books (title, type, author, topic, publication_date, pages) - VALUES - ('${book.title}', '${book.type}', '${book.author}', '${book.topic}', '${book.publication_date}', '${book.pages}' ) returning * - `); - return response.rows; + const sqlQuery = `insert into books (title, type, author, topic, publication_date, pages) values ($1, $2, $3, $4, $5, $6) returning *`; + const response = await client.query(sqlQuery, [ + book.title, + book.type, + book.author, + book.topic, + book.publication_date, + book.pages, + ]); + return response.rows[0]; } catch (error) { console.log("Error:", error); } @@ -45,10 +50,10 @@ const updateBook = async (id, bookInfo) => { const deleteBook = async (id) => { try { - const response = await client.query( - `DELETE FROM books WHERE id = ${id} RETURNING *` - ); - return response.rows; + const sqlQuery = `delete from books where id = $1 returning *`; + const response = await client.query(sqlQuery, [id]); + + return response.rows[0]; } catch (error) { console.log("Error:", error); } diff --git a/src/controllers/pets.controller.js b/src/controllers/pets.controller.js index 1f5f5d58..450d7f4a 100644 --- a/src/controllers/pets.controller.js +++ b/src/controllers/pets.controller.js @@ -11,12 +11,16 @@ const getAllPets = async () => { const createPet = async (pet) => { try { - const response = await client.query(` - INSERT INTO pets (name, age, type, breed, has_microchip) - VALUES - ('${pet.name}', '${pet.age}', '${pet.type}', '${pet.breed}', '${pet.has_microchip}') returning * - `); - return response.rows; + const sqlQuery = `insert into pets (name, age, type, breed, has_microchip) values ($1, $2, $3, $4, $5) returning *`; + const response = await client.query(sqlQuery, [ + pet.name, + pet.age, + pet.type, + pet.breed, + pet.has_microchip, + ]); + + return response.rows[0]; } catch (error) { console.log("Error:", error); } @@ -45,10 +49,10 @@ const updatePet = async (id, petInfo) => { const deletePet = async (id) => { try { - const response = await client.query( - `DELETE FROM pets WHERE id = ${id} RETURNING *` - ); - return response.rows; + const sqlQuery = `delete from pets where id = $1 returning *`; + const response = await client.query(sqlQuery, [id]); + + return response.rows[0]; } catch (error) { console.log("Error:", error); }