From fc599c5aea63e9e518cddaf42e32407be53bb1d4 Mon Sep 17 00:00:00 2001 From: Maksim Lukianenko Date: Sat, 26 Aug 2023 14:36:40 +0100 Subject: [PATCH 1/5] chore(README.md): update README.md with tasks and their respective SQL queries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat(README.md): add task 1 to README.md to list rooms with a rate of more than 100.00 feat(README.md): add task 2 to README.md to list reservations with a checkin date this month and for more than three nights feat(README.md): add task 3 to README.md to list customers from cities that begin with the letter 'M' feat(README.md): add task 4 to README.md to create a new room type PENTHOUSE with a default rate of £185.00 feat(README.md): add task 5 to README.md to add new rooms 501 and 502 as room type PENTHOUSE with the default rate feat(README.md): add task 6 to README.md to add a new room 503 as a PREMIER PLUS type with a room rate of 143.00 to reflect improved views over the city --- README.md | 161 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 160 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5200ed75..fe393665 100644 --- a/README.md +++ b/README.md @@ -1 +1,160 @@ -# Databases-Homework \ No newline at end of file +# Databases-Homework + +### Tasks + +1. Which rooms have a rate of more than 100.00? + +PREMIER +PREMIER PLUS +FAMILY + +2. List the reservations that have a checkin date this month and are for more than three nights. + +cyf_hotels=# select cust_id, room_no, checkout_date - checkin_date as nights from reservations where checkin_date > '2023-08-01' and (checkout_date - checkin_date) > 2; +cust_id | room_no | nights +---------+---------+-------- +4 | 312 | 3 +131 | 301 | 6 +117 | 101 | 4 +119 | | 5 +64 | | 3 +51 | | 4 +46 | | 4 +19 | | 5 +108 | | 3 +9 | 305 | 6 +91 | 211 | 5 +41 | 302 | 5 +106 | 206 | 5 +123 | | 4 +16 | | 6 +126 | | 5 +97 | | 3 +20 | | 4 +15 | | 4 +79 | | 3 +40 | | 3 +9 | | 3 +26 | | 3 +96 | | 6 +35 | | 5 +38 | | 5 +96 | | 5 +12 | | 3 +63 | | 5 +66 | | 3 +44 | | 4 +129 | | 4 +55 | | 4 +93 | | 4 +98 | | 6 +(35 rows) + +3. List all customers from cities that begin with the letter 'M'. + +cyf_hotels=# select \* from customers where city like 'M%'; +id | name | email | phone | address | city | postcode | country +-----+---------------------+------------------------------+--------------------+--------------------------------------------+-------------+----------+------------- +3 | Alice Evans | alice.evans001@hotmail.com | 0161 345 6789 | 3 High Road | Manchester | m13 4ef | UK +4 | Mohammed Trungpa | mo.trungpa@hotmail.com | 0161 456 7890 | 25 Blue Road | Manchester | M25 6GH | UK +6 | Nadia Sethuraman | nadia.sethuraman@mail.com | | 135 Green Street | Manchester | M10 4BG | UK +8 | Martín Sommer | martin.sommer@dfgg.net | (91) 555 22 82 | C/ Romero, 33 | Madrid | 28016 | Spain +9 | Laurence Lebihan | laurence.lebihan@xmzx.net | 91.24.4555 | 12, rue des Bouchers | Marseille | 13008 | France +14 | Peter Ferguson | peter.ferguson@mxnx.net | 03 9520 4555 | 636 St Kilda Road, Level 3 | Melbourne | 3004 | Australia +22 | Diego Freyre | diego.freyre@amyr.net | (91) 555 94 44 | C/ Moralzarzal, 86 | Madrid | 28034 | Spain +41 | Rachel Ashworth | rachel.ashworth@rzyb.net | (171) 555-1555 | Fauntleroy Circus | Manchester | EC2 5NT | UK +55 | Jean Fresnière | jean.fresnière@uxsm.net | (514) 555-8054 | 43 rue St. Laurent | Montréal | H1J 1C3 | Canada +56 | Alejandra Camino | alejandra.camino@omet.net | (91) 745 6555 | Gran Vía, 1 | Madrid | 28001 | Spain +66 | Peter Franken | peter.franken@fszx.net | 089-0877555 | Berliner Platz 43 | München | 80805 | Germany +88 | Jesus Fernandez | jesus.fernandez@cgxs.net | +34 913 728 555 | Merchants House, 27-30 Merchant's Quay | Madrid | 28023 | Spain +91 | Laurence Lebihan | laurence.lebihan@xmzx.net | 91.24.4555 | 12, rue des Bouchers | Marseille | 13008 | France +95 | Karin Josephs | karin.josephs@gyfv.net | 0251-555259 | Luisenstr. 48 | Münster | 44087 | Germany +103 | Arnold Cruz | arnold.cruz@awqa.net | +63 2 555 3587 | 15 McCallum Street, NatWest Center #13-03 | Makati City | 1227 MM | Philippines +105 | Akiko Shimamura | akiko.shimamura@pipl.net | +81 3 3584 0555 | 2-2-8 Roppongi | Minato-ku | 106-0032 | Japan +109 | Michael Donnermeyer | michael.donnermeyer@lvpk.net | +49 89 61 08 9555 | Hansastr. 15 | Munich | 80686 | Germany +118 | Martín Sommer | martín.sommer@wcoa.net | (91) 555 22 82 | C/ Araquil, 67 | Madrid | 28023 | Spain +121 | Carmen Anton | carmen.anton@bhmy.net | +34 913 728555 | c/ Gobelas, 19-1 Urb. La Florida | Madrid | 28023 | Spain +123 | Franco Ricotti | franco.ricotti@ycbk.net | +39 022515555 | 20093 Cologno Monzese, Alessandro Volta 16 | Milan | | Italy +125 | Hanna Moos | hanna.moos@fmga.net | 0621-08555 | Forsterstr. 57 | Mannheim | 68306 | Germany +(21 rows) + +4. Make a new room type of PENTHOUSE with a default rate of £185.00 + +cyf_hotels=# select \* from room_types; +room_type | def_rate +--------------+---------- +FAMILY | 123.00 +PREMIER | 110.00 +PREMIER PLUS | 123.00 +PREMIUM | 85.00 +PREMIUM PLUS | 98.00 +PENTHOUSE | 185.00 +(6 rows) + +5. Add new rooms, 501 and 502 as room type PENTHOUSE and set the room rate of each to the default value (as in the new room type). + +cyf_hotels=# insert into rooms (room_no, rate, room_type) values (501, 185.00, 'PENTHOUSE'), (502, 185.00, 'PENTHOUSE'); +INSERT 0 2 +cyf_hotels=# select \* from rooms; +room_no | rate | room_type | no_guests +---------+--------+--------------+----------- +101 | 85.00 | PREMIUM | 2 +102 | 85.00 | PREMIUM | 2 +103 | 85.00 | PREMIUM | 2 +104 | 85.00 | PREMIUM | 2 +105 | 85.00 | PREMIUM | 2 +106 | 85.00 | PREMIUM | 2 +107 | 85.00 | PREMIUM | 2 +108 | 98.00 | PREMIUM PLUS | 2 +109 | 98.00 | PREMIUM PLUS | 2 +110 | 98.00 | PREMIUM PLUS | 2 +111 | 98.00 | PREMIUM PLUS | 2 +112 | 98.00 | PREMIUM PLUS | 2 +201 | 85.00 | PREMIUM | 2 +202 | 85.00 | PREMIUM | 2 +203 | 85.00 | PREMIUM | 2 +204 | 85.00 | PREMIUM | 2 +205 | 85.00 | PREMIUM | 3 +206 | 85.00 | PREMIUM | 3 +207 | 85.00 | PREMIUM | 3 +208 | 98.00 | PREMIUM PLUS | 2 +209 | 98.00 | PREMIUM PLUS | 2 +210 | 98.00 | PREMIUM PLUS | 2 +211 | 98.00 | PREMIUM PLUS | 3 +212 | 98.00 | PREMIUM PLUS | 3 +301 | 110.00 | PREMIER | 2 +302 | 110.00 | PREMIER | 2 +303 | 110.00 | PREMIER | 2 +304 | 110.00 | PREMIER | 2 +305 | 110.00 | PREMIER | 2 +306 | 110.00 | PREMIER | 2 +307 | 110.00 | PREMIER | 2 +308 | 123.00 | PREMIER PLUS | 2 +309 | 123.00 | PREMIER PLUS | 2 +310 | 123.00 | PREMIER PLUS | 2 +311 | 123.00 | PREMIER PLUS | 2 +312 | 123.00 | PREMIER PLUS | 2 +401 | 110.00 | PREMIER | 2 +402 | 110.00 | PREMIER | 2 +403 | 110.00 | PREMIER | 2 +404 | 110.00 | PREMIER | 2 +405 | 110.00 | PREMIER | 2 +406 | 110.00 | PREMIER | 2 +407 | 110.00 | PREMIER | 2 +408 | 123.00 | PREMIER PLUS | 2 +409 | 123.00 | PREMIER PLUS | 2 +410 | 123.00 | PREMIER PLUS | 2 +411 | 123.00 | FAMILY | 4 +412 | 123.00 | FAMILY | 4 +501 | 185.00 | PENTHOUSE | + 502 | 185.00 | PENTHOUSE | +(50 rows) + +6. Add a new room 503 as a PREMIER PLUS type similar to the other PREMIER PLUS rooms in the hotel but with a room rate of 143.00 to reflect its improved views over the city. + + 412 | 123.00 | FAMILY | 4 + 501 | 185.00 | PENTHOUSE | + 502 | 185.00 | PENTHOUSE | + 503 | 143.00 | PREMIER PLUS | + + (51 rows) From 48f266678284aba7b8a757c684fb9a34c1d72bf2 Mon Sep 17 00:00:00 2001 From: Maksim Lukianenko Date: Mon, 28 Aug 2023 02:29:48 +0100 Subject: [PATCH 2/5] feat(task.md): add SQL queries to complete the ecommerce database tasks This commit adds SQL queries to complete the tasks for setting up and querying an ecommerce database. The queries include retrieving customers' names and addresses who live in the United States, retrieving customers in ascending name sequence, retrieving products whose name contains the word 'socks', retrieving products that cost more than 100, retrieving the 5 most expensive products, retrieving products with their corresponding suppliers, retrieving products sold by suppliers based in the United Kingdom, retrieving orders from a specific customer ID, retrieving orders from a customer named 'Hope Crosby', retrieving products in a specific order, retrieving products with their supplier for all orders of all customers, retrieving customers who bought a product from a supplier based in China, and listing all orders with customer name, order reference, order date, and order total amount in descending order of total. --- week-2/mandatory/2-ecommerce-db/task.md | 201 +++++++++++++++++++++++- 1 file changed, 199 insertions(+), 2 deletions(-) diff --git a/week-2/mandatory/2-ecommerce-db/task.md b/week-2/mandatory/2-ecommerce-db/task.md index c48d2286..7d60bac1 100644 --- a/week-2/mandatory/2-ecommerce-db/task.md +++ b/week-2/mandatory/2-ecommerce-db/task.md @@ -7,6 +7,7 @@ In this homework, you are going to work with an ecommerce database. In this data Below you will find a set of tasks for you to complete to set up a database for an e-commerce app. To submit this homework write the correct commands for each question here: + ```sql @@ -35,16 +36,212 @@ Open the file `cyf_ecommerce.sql` in VSCode and examine the SQL code. Take a pie Once you understand the database that you are going to work with, solve the following challenge by writing SQL queries using everything you learned about SQL: 1. Retrieve all the customers' names and addresses who live in the United States + +cyf_ecommerce=# select \* from customers where country = 'United States';; +id | name | address | city | country +----+--------------+----------------------------+------------------+--------------- +4 | Amber Tran | 6967 Ac Road | Villafranca Asti | United States +5 | Edan Higgins | Ap #840-3255 Tincidunt St. | Arles | United States +(2 rows) + 2. Retrieve all the customers in ascending name sequence + +cyf_ecommerce=# select \* from customers order by name; +id | name | address | city | country +----+--------------------+-----------------------------+------------------+---------------- +4 | Amber Tran | 6967 Ac Road | Villafranca Asti | United States +3 | Britanney Kirkland | P.O. Box 577, 5601 Sem, St. | Little Rock | United Kingdom +5 | Edan Higgins | Ap #840-3255 Tincidunt St. | Arles | United States +1 | Guy Crawford | 770-2839 Ligula Road | Paris | France +2 | Hope Crosby | P.O. Box 276, 4976 Sit Rd. | Steyr | United Kingdom +6 | Quintessa Austin | 597-2737 Nunc Rd. | Saint-Marc | United Kingdom +(6 rows) + 3. Retrieve all the products whose name contains the word `socks` + +cyf_ecommerce=# select \* from products where product_name like '%socks%'; +id | product_name +----+------------------ +4 | Super warm socks +(1 row) + 4. Retrieve all the products which cost more than 100 showing product id, name, unit price and supplier id. + +cyf_ecommerce=# SELECT product_availability.prod_id, product_availability.supp_id, product_availability.unit_price, products.product_name FROM product_availability +cyf_ecommerce-# JOIN products ON product_availability.prod_id=products.id +cyf_ecommerce-# WHERE product_availability.unit_price > 100; +prod_id | supp_id | unit_price | product_name +---------+---------+------------+---------------- +1 | 4 | 249 | Mobile Phone X +1 | 1 | 299 | Mobile Phone X +(2 rows) + 5. Retrieve the 5 most expensive products + +cyf_ecommerce=# select product_availability.prod_id, product_availability.supp_id, product_availability.unit_price, products.product_name from product_availability JOIN products ON product_availability.prod_id=products.id order by unit_price desc +cyf_ecommerce-# limit 5; +prod_id | supp_id | unit_price | product_name +---------+---------+------------+----------------- +1 | 1 | 299 | Mobile Phone X +1 | 4 | 249 | Mobile Phone X +2 | 2 | 41 | Javascript Book +2 | 1 | 40 | Javascript Book +2 | 3 | 39 | Javascript Book +(5 rows) + 6. Retrieve all the products with their corresponding suppliers. The result should only contain the columns `product_name`, `unit_price` and `supplier_name` + +cyf_ecommerce=# SELECT products.product_name, product_availability.unit_price, suppliers.supplier_name FROM products JOIN product_availability ON product_availability.prod_id=products.id JOIN suppliers ON suppliers.id=product_availability.supp_id; +product_name | unit_price | supplier_name +-------------------------+------------+--------------- +Mobile Phone X | 249 | Sainsburys +Mobile Phone X | 299 | Amazon +Javascript Book | 41 | Taobao +Javascript Book | 39 | Argos +Javascript Book | 40 | Amazon +Le Petit Prince | 10 | Sainsburys +Le Petit Prince | 10 | Amazon +Super warm socks | 10 | Sainsburys +Super warm socks | 8 | Argos +Super warm socks | 5 | Taobao +Super warm socks | 10 | Amazon +Coffee Cup | 5 | Sainsburys +Coffee Cup | 4 | Argos +Coffee Cup | 4 | Taobao +Coffee Cup | 3 | Amazon +Ball | 20 | Taobao +Ball | 15 | Sainsburys +Ball | 14 | Amazon +Tee Shirt Olympic Games | 21 | Argos +Tee Shirt Olympic Games | 18 | Taobao +Tee Shirt Olympic Games | 20 | Amazon +(21 rows) + 7. Retrieve all the products sold by suppliers based in the United Kingdom. The result should only contain the columns `product_name` and `supplier_name`. -8. Retrieve all orders, including order items, from customer ID `1`. Include order id, reference, date and total cost (calculated as quantity * unit price). + +cyf_ecommerce=# SELECT products.product_name, suppliers.supplier_name FROM products JOIN product_availability ON product_availability.prod_id=products.id JOIN suppliers ON suppliers.id=product_availability.supp_id WHERE suppliers.country = 'United Kingdom'; +product_name | supplier_name +-------------------------+--------------- +Javascript Book | Argos +Super warm socks | Argos +Coffee Cup | Argos +Tee Shirt Olympic Games | Argos +Mobile Phone X | Sainsburys +Le Petit Prince | Sainsburys +Super warm socks | Sainsburys +Coffee Cup | Sainsburys +Ball | Sainsburys +(9 rows) + +8. Retrieve all orders, including order items, from customer ID `1`. Include order id, reference, date and total cost (calculated as quantity \* unit price). + +cyf_ecommerce=# SELECT +cyf_ecommerce-# orders.id, +cyf_ecommerce-# orders.order_reference, +cyf_ecommerce-# orders.order_date, +cyf_ecommerce-# SUM(order_items.quantity \* product_availability.unit_price) as total_cost +cyf_ecommerce-# FROM orders +cyf_ecommerce-# JOIN order_items ON orders.id = order_items.order_id +cyf_ecommerce-# JOIN product_availability ON order_items.product_id = product_availability.prod_id +cyf_ecommerce-# AND order_items.supplier_id = product_availability.supp_id +cyf_ecommerce-# WHERE orders.customer_id = 1 +cyf_ecommerce-# GROUP BY orders.id, orders.order_reference, orders.order_date; +id | order_reference | order_date | total_cost +----+-----------------+------------+------------ +1 | ORD001 | 2019-06-01 | 43 +2 | ORD002 | 2019-07-15 | 42 +3 | ORD003 | 2019-07-11 | 80 +(3 rows) + 9. Retrieve all orders, including order items, from customer named `Hope Crosby` + +cyf_ecommerce=# SELECT +cyf_ecommerce-# customers.id, +cyf_ecommerce-# customers.name, +cyf_ecommerce-# orders.order_reference, +cyf_ecommerce-# order_items.quantity +cyf_ecommerce-# FROM customers +cyf_ecommerce-# JOIN orders ON customers.id = orders.customer_id +cyf_ecommerce-# JOIN order_items ON orders.id = order_items.order_id +cyf_ecommerce-# WHERE customers.name = 'Hope Crosby'; +id | name | order_reference | quantity +----+-------------+-----------------+---------- +2 | Hope Crosby | ORD004 | 1 +(1 row) + 10. Retrieve all the products in the order `ORD006`. The result should only contain the columns `product_name`, `unit_price` and `quantity`. + +cyf_ecommerce=# SELECT order_items.order_id, order_items.quantity, products.product_name, product_availability.unit_price FROM order_items JOIN products ON order_items.product_id=products.id JOIN product_availability ON order_items.product_id=product_availability.prod_id AND order_items.supplier_id=product_availability.supp_id WHERE order_items.order_id = 6; +order_id | quantity | product_name | unit_price +----------+----------+------------------+------------ +6 | 1 | Javascript Book | 41 +6 | 1 | Le Petit Prince | 10 +6 | 3 | Super warm socks | 10 +6 | 3 | Coffee Cup | 4 +(4 rows) + 11. Retrieve all the products with their supplier for all orders of all customers. The result should only contain the columns `name` (from customer), `order_reference`, `order_date`, `product_name`, `supplier_name` and `quantity`. + +cyf_ecommerce=# SELECT suppliers.supplier_name, order_items.order_id, order_items.quantity, orders.order_date, customers.name, products.product_name FROM suppliers JOIN order_items ON order_items.supplier_id=suppliers.id JOIN orders ON order_items.order_id=orders.id JOIN customers ON orders.customer_id=customers.id JOIN products ON order_items.product_id = products.id; +supplier_name | order_id | quantity | order_date | name | product_name +---------------+----------+----------+------------+--------------------+------------------------- +Taobao | 1 | 1 | 2019-06-01 | Guy Crawford | Tee Shirt Olympic Games +Taobao | 1 | 5 | 2019-06-01 | Guy Crawford | Super warm socks +Argos | 2 | 4 | 2019-07-15 | Guy Crawford | Super warm socks +Sainsburys | 2 | 1 | 2019-07-15 | Guy Crawford | Le Petit Prince +Argos | 3 | 10 | 2019-07-11 | Guy Crawford | Coffee Cup +Taobao | 3 | 2 | 2019-07-11 | Guy Crawford | Ball +Amazon | 4 | 1 | 2019-05-24 | Hope Crosby | Mobile Phone X +Argos | 5 | 2 | 2019-05-30 | Britanney Kirkland | Javascript Book +Amazon | 5 | 1 | 2019-05-30 | Britanney Kirkland | Le Petit Prince +Taobao | 6 | 3 | 2019-07-05 | Amber Tran | Coffee Cup +Taobao | 6 | 1 | 2019-07-05 | Amber Tran | Javascript Book +Sainsburys | 6 | 1 | 2019-07-05 | Amber Tran | Le Petit Prince +Sainsburys | 6 | 3 | 2019-07-05 | Amber Tran | Super warm socks +Argos | 7 | 15 | 2019-04-05 | Amber Tran | Super warm socks +Amazon | 8 | 1 | 2019-07-23 | Edan Higgins | Tee Shirt Olympic Games +Sainsburys | 8 | 1 | 2019-07-23 | Edan Higgins | Mobile Phone X +Sainsburys | 9 | 2 | 2019-07-24 | Edan Higgins | Ball +Taobao | 10 | 1 | 2019-05-10 | Edan Higgins | Ball +Amazon | 10 | 5 | 2019-05-10 | Edan Higgins | Super warm socks +(19 rows) + 12. Retrieve the names of all customers who bought a product from a supplier based in China. -13. List all orders giving customer name, order reference, order date and order total amount (quantity * unit price) in descending order of total. + cyf_ecommerce=# SELECT suppliers.supplier_name, order_items.order_id, orders.order_reference, customers.name FROM suppliers JOIN order_items ON order_items.supplier_id=suppliers.id JOIN orders ON order_items.order_id=orders.id JOIN customers ON orders.customer_id=customers.id + cyf_ecommerce-# WHERE suppliers.country = 'China'; + supplier_name | order_id | order_reference | name + ---------------+----------+-----------------+-------------- + Taobao | 1 | ORD001 | Guy Crawford + Taobao | 1 | ORD001 | Guy Crawford + Taobao | 3 | ORD003 | Guy Crawford + Taobao | 6 | ORD006 | Amber Tran + Taobao | 6 | ORD006 | Amber Tran + Taobao | 10 | ORD010 | Edan Higgins + (6 rows) + +13. List all orders giving customer name, order reference, order date and order total amount (quantity \* unit price) in descending order of total. + +cyf_ecommerce=# SELECT customers.name, orders.order_reference, orders.order_date, order_items.quantity, order_items.product_id, product_availability.unit_price, (order_items.quantity \* product_availability.unit_price) as total_cost FROM customers JOIN orders ON customers.id=orders.customer_id JOIN order_items ON order_items.order_id=orders.id JOIN product_availability ON order_items.supplier_id=product_availability.supp_id AND order_items.product_id=product_availability.prod_id ORDER BY total_cost DESC; +name | order_reference | order_date | quantity | product_id | unit_price | total_cost +--------------------+-----------------+------------+----------+------------+------------+------------ +Hope Crosby | ORD004 | 2019-05-24 | 1 | 1 | 299 | 299 +Edan Higgins | ORD008 | 2019-07-23 | 1 | 1 | 249 | 249 +Amber Tran | ORD007 | 2019-04-05 | 15 | 4 | 8 | 120 +Britanney Kirkland | ORD005 | 2019-05-30 | 2 | 2 | 39 | 78 +Edan Higgins | ORD010 | 2019-05-10 | 5 | 4 | 10 | 50 +Amber Tran | ORD006 | 2019-07-05 | 1 | 2 | 41 | 41 +Guy Crawford | ORD003 | 2019-07-11 | 10 | 5 | 4 | 40 +Guy Crawford | ORD003 | 2019-07-11 | 2 | 6 | 20 | 40 +Guy Crawford | ORD002 | 2019-07-15 | 4 | 4 | 8 | 32 +Edan Higgins | ORD009 | 2019-07-24 | 2 | 6 | 15 | 30 +Amber Tran | ORD006 | 2019-07-05 | 3 | 4 | 10 | 30 +Guy Crawford | ORD001 | 2019-06-01 | 5 | 4 | 5 | 25 +Edan Higgins | ORD008 | 2019-07-23 | 1 | 7 | 20 | 20 +Edan Higgins | ORD010 | 2019-05-10 | 1 | 6 | 20 | 20 +Guy Crawford | ORD001 | 2019-06-01 | 1 | 7 | 18 | 18 +Amber Tran | ORD006 | 2019-07-05 | 3 | 5 | 4 | 12 +Amber Tran | ORD006 | 2019-07-05 | 1 | 3 | 10 | 10 +Britanney Kirkland | ORD005 | 2019-05-30 | 1 | 3 | 10 | 10 +Guy Crawford | ORD002 | 2019-07-15 | 1 | 3 | 10 | 10 +(19 rows) From 64241c0378ff1bafe989e41af7f55e041f4f4798 Mon Sep 17 00:00:00 2001 From: Maksim Lukianenko Date: Mon, 28 Aug 2023 02:33:03 +0100 Subject: [PATCH 3/5] feat(task.md): add SQL queries to complete the ecommerce database tasks This commit adds SQL queries to complete the tasks for setting up and querying an ecommerce database. The queries include retrieving customers' names and addresses who live in the United States, retrieving customers in ascending name sequence, retrieving products whose name contains the word 'socks', retrieving products that cost more than 100, retrieving the 5 most expensive products, retrieving products with their corresponding suppliers, retrieving products sold by suppliers based in the United Kingdom, retrieving orders from a specific customer ID, retrieving orders from a customer named 'Hope Crosby', retrieving products in a specific order, retrieving products with their supplier for all orders of all customers, retrieving customers who bought a product from a supplier based in China, and listing all orders with customer name, order reference, order date, and order total amount in descending order of total. --- week-2/mandatory/2-ecommerce-db/task.md | 201 +++++++++++++++++++++++- 1 file changed, 199 insertions(+), 2 deletions(-) diff --git a/week-2/mandatory/2-ecommerce-db/task.md b/week-2/mandatory/2-ecommerce-db/task.md index c48d2286..7d60bac1 100644 --- a/week-2/mandatory/2-ecommerce-db/task.md +++ b/week-2/mandatory/2-ecommerce-db/task.md @@ -7,6 +7,7 @@ In this homework, you are going to work with an ecommerce database. In this data Below you will find a set of tasks for you to complete to set up a database for an e-commerce app. To submit this homework write the correct commands for each question here: + ```sql @@ -35,16 +36,212 @@ Open the file `cyf_ecommerce.sql` in VSCode and examine the SQL code. Take a pie Once you understand the database that you are going to work with, solve the following challenge by writing SQL queries using everything you learned about SQL: 1. Retrieve all the customers' names and addresses who live in the United States + +cyf_ecommerce=# select \* from customers where country = 'United States';; +id | name | address | city | country +----+--------------+----------------------------+------------------+--------------- +4 | Amber Tran | 6967 Ac Road | Villafranca Asti | United States +5 | Edan Higgins | Ap #840-3255 Tincidunt St. | Arles | United States +(2 rows) + 2. Retrieve all the customers in ascending name sequence + +cyf_ecommerce=# select \* from customers order by name; +id | name | address | city | country +----+--------------------+-----------------------------+------------------+---------------- +4 | Amber Tran | 6967 Ac Road | Villafranca Asti | United States +3 | Britanney Kirkland | P.O. Box 577, 5601 Sem, St. | Little Rock | United Kingdom +5 | Edan Higgins | Ap #840-3255 Tincidunt St. | Arles | United States +1 | Guy Crawford | 770-2839 Ligula Road | Paris | France +2 | Hope Crosby | P.O. Box 276, 4976 Sit Rd. | Steyr | United Kingdom +6 | Quintessa Austin | 597-2737 Nunc Rd. | Saint-Marc | United Kingdom +(6 rows) + 3. Retrieve all the products whose name contains the word `socks` + +cyf_ecommerce=# select \* from products where product_name like '%socks%'; +id | product_name +----+------------------ +4 | Super warm socks +(1 row) + 4. Retrieve all the products which cost more than 100 showing product id, name, unit price and supplier id. + +cyf_ecommerce=# SELECT product_availability.prod_id, product_availability.supp_id, product_availability.unit_price, products.product_name FROM product_availability +cyf_ecommerce-# JOIN products ON product_availability.prod_id=products.id +cyf_ecommerce-# WHERE product_availability.unit_price > 100; +prod_id | supp_id | unit_price | product_name +---------+---------+------------+---------------- +1 | 4 | 249 | Mobile Phone X +1 | 1 | 299 | Mobile Phone X +(2 rows) + 5. Retrieve the 5 most expensive products + +cyf_ecommerce=# select product_availability.prod_id, product_availability.supp_id, product_availability.unit_price, products.product_name from product_availability JOIN products ON product_availability.prod_id=products.id order by unit_price desc +cyf_ecommerce-# limit 5; +prod_id | supp_id | unit_price | product_name +---------+---------+------------+----------------- +1 | 1 | 299 | Mobile Phone X +1 | 4 | 249 | Mobile Phone X +2 | 2 | 41 | Javascript Book +2 | 1 | 40 | Javascript Book +2 | 3 | 39 | Javascript Book +(5 rows) + 6. Retrieve all the products with their corresponding suppliers. The result should only contain the columns `product_name`, `unit_price` and `supplier_name` + +cyf_ecommerce=# SELECT products.product_name, product_availability.unit_price, suppliers.supplier_name FROM products JOIN product_availability ON product_availability.prod_id=products.id JOIN suppliers ON suppliers.id=product_availability.supp_id; +product_name | unit_price | supplier_name +-------------------------+------------+--------------- +Mobile Phone X | 249 | Sainsburys +Mobile Phone X | 299 | Amazon +Javascript Book | 41 | Taobao +Javascript Book | 39 | Argos +Javascript Book | 40 | Amazon +Le Petit Prince | 10 | Sainsburys +Le Petit Prince | 10 | Amazon +Super warm socks | 10 | Sainsburys +Super warm socks | 8 | Argos +Super warm socks | 5 | Taobao +Super warm socks | 10 | Amazon +Coffee Cup | 5 | Sainsburys +Coffee Cup | 4 | Argos +Coffee Cup | 4 | Taobao +Coffee Cup | 3 | Amazon +Ball | 20 | Taobao +Ball | 15 | Sainsburys +Ball | 14 | Amazon +Tee Shirt Olympic Games | 21 | Argos +Tee Shirt Olympic Games | 18 | Taobao +Tee Shirt Olympic Games | 20 | Amazon +(21 rows) + 7. Retrieve all the products sold by suppliers based in the United Kingdom. The result should only contain the columns `product_name` and `supplier_name`. -8. Retrieve all orders, including order items, from customer ID `1`. Include order id, reference, date and total cost (calculated as quantity * unit price). + +cyf_ecommerce=# SELECT products.product_name, suppliers.supplier_name FROM products JOIN product_availability ON product_availability.prod_id=products.id JOIN suppliers ON suppliers.id=product_availability.supp_id WHERE suppliers.country = 'United Kingdom'; +product_name | supplier_name +-------------------------+--------------- +Javascript Book | Argos +Super warm socks | Argos +Coffee Cup | Argos +Tee Shirt Olympic Games | Argos +Mobile Phone X | Sainsburys +Le Petit Prince | Sainsburys +Super warm socks | Sainsburys +Coffee Cup | Sainsburys +Ball | Sainsburys +(9 rows) + +8. Retrieve all orders, including order items, from customer ID `1`. Include order id, reference, date and total cost (calculated as quantity \* unit price). + +cyf_ecommerce=# SELECT +cyf_ecommerce-# orders.id, +cyf_ecommerce-# orders.order_reference, +cyf_ecommerce-# orders.order_date, +cyf_ecommerce-# SUM(order_items.quantity \* product_availability.unit_price) as total_cost +cyf_ecommerce-# FROM orders +cyf_ecommerce-# JOIN order_items ON orders.id = order_items.order_id +cyf_ecommerce-# JOIN product_availability ON order_items.product_id = product_availability.prod_id +cyf_ecommerce-# AND order_items.supplier_id = product_availability.supp_id +cyf_ecommerce-# WHERE orders.customer_id = 1 +cyf_ecommerce-# GROUP BY orders.id, orders.order_reference, orders.order_date; +id | order_reference | order_date | total_cost +----+-----------------+------------+------------ +1 | ORD001 | 2019-06-01 | 43 +2 | ORD002 | 2019-07-15 | 42 +3 | ORD003 | 2019-07-11 | 80 +(3 rows) + 9. Retrieve all orders, including order items, from customer named `Hope Crosby` + +cyf_ecommerce=# SELECT +cyf_ecommerce-# customers.id, +cyf_ecommerce-# customers.name, +cyf_ecommerce-# orders.order_reference, +cyf_ecommerce-# order_items.quantity +cyf_ecommerce-# FROM customers +cyf_ecommerce-# JOIN orders ON customers.id = orders.customer_id +cyf_ecommerce-# JOIN order_items ON orders.id = order_items.order_id +cyf_ecommerce-# WHERE customers.name = 'Hope Crosby'; +id | name | order_reference | quantity +----+-------------+-----------------+---------- +2 | Hope Crosby | ORD004 | 1 +(1 row) + 10. Retrieve all the products in the order `ORD006`. The result should only contain the columns `product_name`, `unit_price` and `quantity`. + +cyf_ecommerce=# SELECT order_items.order_id, order_items.quantity, products.product_name, product_availability.unit_price FROM order_items JOIN products ON order_items.product_id=products.id JOIN product_availability ON order_items.product_id=product_availability.prod_id AND order_items.supplier_id=product_availability.supp_id WHERE order_items.order_id = 6; +order_id | quantity | product_name | unit_price +----------+----------+------------------+------------ +6 | 1 | Javascript Book | 41 +6 | 1 | Le Petit Prince | 10 +6 | 3 | Super warm socks | 10 +6 | 3 | Coffee Cup | 4 +(4 rows) + 11. Retrieve all the products with their supplier for all orders of all customers. The result should only contain the columns `name` (from customer), `order_reference`, `order_date`, `product_name`, `supplier_name` and `quantity`. + +cyf_ecommerce=# SELECT suppliers.supplier_name, order_items.order_id, order_items.quantity, orders.order_date, customers.name, products.product_name FROM suppliers JOIN order_items ON order_items.supplier_id=suppliers.id JOIN orders ON order_items.order_id=orders.id JOIN customers ON orders.customer_id=customers.id JOIN products ON order_items.product_id = products.id; +supplier_name | order_id | quantity | order_date | name | product_name +---------------+----------+----------+------------+--------------------+------------------------- +Taobao | 1 | 1 | 2019-06-01 | Guy Crawford | Tee Shirt Olympic Games +Taobao | 1 | 5 | 2019-06-01 | Guy Crawford | Super warm socks +Argos | 2 | 4 | 2019-07-15 | Guy Crawford | Super warm socks +Sainsburys | 2 | 1 | 2019-07-15 | Guy Crawford | Le Petit Prince +Argos | 3 | 10 | 2019-07-11 | Guy Crawford | Coffee Cup +Taobao | 3 | 2 | 2019-07-11 | Guy Crawford | Ball +Amazon | 4 | 1 | 2019-05-24 | Hope Crosby | Mobile Phone X +Argos | 5 | 2 | 2019-05-30 | Britanney Kirkland | Javascript Book +Amazon | 5 | 1 | 2019-05-30 | Britanney Kirkland | Le Petit Prince +Taobao | 6 | 3 | 2019-07-05 | Amber Tran | Coffee Cup +Taobao | 6 | 1 | 2019-07-05 | Amber Tran | Javascript Book +Sainsburys | 6 | 1 | 2019-07-05 | Amber Tran | Le Petit Prince +Sainsburys | 6 | 3 | 2019-07-05 | Amber Tran | Super warm socks +Argos | 7 | 15 | 2019-04-05 | Amber Tran | Super warm socks +Amazon | 8 | 1 | 2019-07-23 | Edan Higgins | Tee Shirt Olympic Games +Sainsburys | 8 | 1 | 2019-07-23 | Edan Higgins | Mobile Phone X +Sainsburys | 9 | 2 | 2019-07-24 | Edan Higgins | Ball +Taobao | 10 | 1 | 2019-05-10 | Edan Higgins | Ball +Amazon | 10 | 5 | 2019-05-10 | Edan Higgins | Super warm socks +(19 rows) + 12. Retrieve the names of all customers who bought a product from a supplier based in China. -13. List all orders giving customer name, order reference, order date and order total amount (quantity * unit price) in descending order of total. + cyf_ecommerce=# SELECT suppliers.supplier_name, order_items.order_id, orders.order_reference, customers.name FROM suppliers JOIN order_items ON order_items.supplier_id=suppliers.id JOIN orders ON order_items.order_id=orders.id JOIN customers ON orders.customer_id=customers.id + cyf_ecommerce-# WHERE suppliers.country = 'China'; + supplier_name | order_id | order_reference | name + ---------------+----------+-----------------+-------------- + Taobao | 1 | ORD001 | Guy Crawford + Taobao | 1 | ORD001 | Guy Crawford + Taobao | 3 | ORD003 | Guy Crawford + Taobao | 6 | ORD006 | Amber Tran + Taobao | 6 | ORD006 | Amber Tran + Taobao | 10 | ORD010 | Edan Higgins + (6 rows) + +13. List all orders giving customer name, order reference, order date and order total amount (quantity \* unit price) in descending order of total. + +cyf_ecommerce=# SELECT customers.name, orders.order_reference, orders.order_date, order_items.quantity, order_items.product_id, product_availability.unit_price, (order_items.quantity \* product_availability.unit_price) as total_cost FROM customers JOIN orders ON customers.id=orders.customer_id JOIN order_items ON order_items.order_id=orders.id JOIN product_availability ON order_items.supplier_id=product_availability.supp_id AND order_items.product_id=product_availability.prod_id ORDER BY total_cost DESC; +name | order_reference | order_date | quantity | product_id | unit_price | total_cost +--------------------+-----------------+------------+----------+------------+------------+------------ +Hope Crosby | ORD004 | 2019-05-24 | 1 | 1 | 299 | 299 +Edan Higgins | ORD008 | 2019-07-23 | 1 | 1 | 249 | 249 +Amber Tran | ORD007 | 2019-04-05 | 15 | 4 | 8 | 120 +Britanney Kirkland | ORD005 | 2019-05-30 | 2 | 2 | 39 | 78 +Edan Higgins | ORD010 | 2019-05-10 | 5 | 4 | 10 | 50 +Amber Tran | ORD006 | 2019-07-05 | 1 | 2 | 41 | 41 +Guy Crawford | ORD003 | 2019-07-11 | 10 | 5 | 4 | 40 +Guy Crawford | ORD003 | 2019-07-11 | 2 | 6 | 20 | 40 +Guy Crawford | ORD002 | 2019-07-15 | 4 | 4 | 8 | 32 +Edan Higgins | ORD009 | 2019-07-24 | 2 | 6 | 15 | 30 +Amber Tran | ORD006 | 2019-07-05 | 3 | 4 | 10 | 30 +Guy Crawford | ORD001 | 2019-06-01 | 5 | 4 | 5 | 25 +Edan Higgins | ORD008 | 2019-07-23 | 1 | 7 | 20 | 20 +Edan Higgins | ORD010 | 2019-05-10 | 1 | 6 | 20 | 20 +Guy Crawford | ORD001 | 2019-06-01 | 1 | 7 | 18 | 18 +Amber Tran | ORD006 | 2019-07-05 | 3 | 5 | 4 | 12 +Amber Tran | ORD006 | 2019-07-05 | 1 | 3 | 10 | 10 +Britanney Kirkland | ORD005 | 2019-05-30 | 1 | 3 | 10 | 10 +Guy Crawford | ORD002 | 2019-07-15 | 1 | 3 | 10 | 10 +(19 rows) From f36aaf9621f53e69fbbe15b905dba00c1fd99a40 Mon Sep 17 00:00:00 2001 From: Maksim Lukianenko Date: Mon, 28 Aug 2023 02:37:59 +0100 Subject: [PATCH 4/5] Revert "feat(task.md): add SQL queries to complete the ecommerce database tasks" This reverts commit 64241c0378ff1bafe989e41af7f55e041f4f4798. revert --- week-2/mandatory/2-ecommerce-db/task.md | 201 +----------------------- 1 file changed, 2 insertions(+), 199 deletions(-) diff --git a/week-2/mandatory/2-ecommerce-db/task.md b/week-2/mandatory/2-ecommerce-db/task.md index 7d60bac1..c48d2286 100644 --- a/week-2/mandatory/2-ecommerce-db/task.md +++ b/week-2/mandatory/2-ecommerce-db/task.md @@ -7,7 +7,6 @@ In this homework, you are going to work with an ecommerce database. In this data Below you will find a set of tasks for you to complete to set up a database for an e-commerce app. To submit this homework write the correct commands for each question here: - ```sql @@ -36,212 +35,16 @@ Open the file `cyf_ecommerce.sql` in VSCode and examine the SQL code. Take a pie Once you understand the database that you are going to work with, solve the following challenge by writing SQL queries using everything you learned about SQL: 1. Retrieve all the customers' names and addresses who live in the United States - -cyf_ecommerce=# select \* from customers where country = 'United States';; -id | name | address | city | country -----+--------------+----------------------------+------------------+--------------- -4 | Amber Tran | 6967 Ac Road | Villafranca Asti | United States -5 | Edan Higgins | Ap #840-3255 Tincidunt St. | Arles | United States -(2 rows) - 2. Retrieve all the customers in ascending name sequence - -cyf_ecommerce=# select \* from customers order by name; -id | name | address | city | country -----+--------------------+-----------------------------+------------------+---------------- -4 | Amber Tran | 6967 Ac Road | Villafranca Asti | United States -3 | Britanney Kirkland | P.O. Box 577, 5601 Sem, St. | Little Rock | United Kingdom -5 | Edan Higgins | Ap #840-3255 Tincidunt St. | Arles | United States -1 | Guy Crawford | 770-2839 Ligula Road | Paris | France -2 | Hope Crosby | P.O. Box 276, 4976 Sit Rd. | Steyr | United Kingdom -6 | Quintessa Austin | 597-2737 Nunc Rd. | Saint-Marc | United Kingdom -(6 rows) - 3. Retrieve all the products whose name contains the word `socks` - -cyf_ecommerce=# select \* from products where product_name like '%socks%'; -id | product_name -----+------------------ -4 | Super warm socks -(1 row) - 4. Retrieve all the products which cost more than 100 showing product id, name, unit price and supplier id. - -cyf_ecommerce=# SELECT product_availability.prod_id, product_availability.supp_id, product_availability.unit_price, products.product_name FROM product_availability -cyf_ecommerce-# JOIN products ON product_availability.prod_id=products.id -cyf_ecommerce-# WHERE product_availability.unit_price > 100; -prod_id | supp_id | unit_price | product_name ----------+---------+------------+---------------- -1 | 4 | 249 | Mobile Phone X -1 | 1 | 299 | Mobile Phone X -(2 rows) - 5. Retrieve the 5 most expensive products - -cyf_ecommerce=# select product_availability.prod_id, product_availability.supp_id, product_availability.unit_price, products.product_name from product_availability JOIN products ON product_availability.prod_id=products.id order by unit_price desc -cyf_ecommerce-# limit 5; -prod_id | supp_id | unit_price | product_name ----------+---------+------------+----------------- -1 | 1 | 299 | Mobile Phone X -1 | 4 | 249 | Mobile Phone X -2 | 2 | 41 | Javascript Book -2 | 1 | 40 | Javascript Book -2 | 3 | 39 | Javascript Book -(5 rows) - 6. Retrieve all the products with their corresponding suppliers. The result should only contain the columns `product_name`, `unit_price` and `supplier_name` - -cyf_ecommerce=# SELECT products.product_name, product_availability.unit_price, suppliers.supplier_name FROM products JOIN product_availability ON product_availability.prod_id=products.id JOIN suppliers ON suppliers.id=product_availability.supp_id; -product_name | unit_price | supplier_name --------------------------+------------+--------------- -Mobile Phone X | 249 | Sainsburys -Mobile Phone X | 299 | Amazon -Javascript Book | 41 | Taobao -Javascript Book | 39 | Argos -Javascript Book | 40 | Amazon -Le Petit Prince | 10 | Sainsburys -Le Petit Prince | 10 | Amazon -Super warm socks | 10 | Sainsburys -Super warm socks | 8 | Argos -Super warm socks | 5 | Taobao -Super warm socks | 10 | Amazon -Coffee Cup | 5 | Sainsburys -Coffee Cup | 4 | Argos -Coffee Cup | 4 | Taobao -Coffee Cup | 3 | Amazon -Ball | 20 | Taobao -Ball | 15 | Sainsburys -Ball | 14 | Amazon -Tee Shirt Olympic Games | 21 | Argos -Tee Shirt Olympic Games | 18 | Taobao -Tee Shirt Olympic Games | 20 | Amazon -(21 rows) - 7. Retrieve all the products sold by suppliers based in the United Kingdom. The result should only contain the columns `product_name` and `supplier_name`. - -cyf_ecommerce=# SELECT products.product_name, suppliers.supplier_name FROM products JOIN product_availability ON product_availability.prod_id=products.id JOIN suppliers ON suppliers.id=product_availability.supp_id WHERE suppliers.country = 'United Kingdom'; -product_name | supplier_name --------------------------+--------------- -Javascript Book | Argos -Super warm socks | Argos -Coffee Cup | Argos -Tee Shirt Olympic Games | Argos -Mobile Phone X | Sainsburys -Le Petit Prince | Sainsburys -Super warm socks | Sainsburys -Coffee Cup | Sainsburys -Ball | Sainsburys -(9 rows) - -8. Retrieve all orders, including order items, from customer ID `1`. Include order id, reference, date and total cost (calculated as quantity \* unit price). - -cyf_ecommerce=# SELECT -cyf_ecommerce-# orders.id, -cyf_ecommerce-# orders.order_reference, -cyf_ecommerce-# orders.order_date, -cyf_ecommerce-# SUM(order_items.quantity \* product_availability.unit_price) as total_cost -cyf_ecommerce-# FROM orders -cyf_ecommerce-# JOIN order_items ON orders.id = order_items.order_id -cyf_ecommerce-# JOIN product_availability ON order_items.product_id = product_availability.prod_id -cyf_ecommerce-# AND order_items.supplier_id = product_availability.supp_id -cyf_ecommerce-# WHERE orders.customer_id = 1 -cyf_ecommerce-# GROUP BY orders.id, orders.order_reference, orders.order_date; -id | order_reference | order_date | total_cost -----+-----------------+------------+------------ -1 | ORD001 | 2019-06-01 | 43 -2 | ORD002 | 2019-07-15 | 42 -3 | ORD003 | 2019-07-11 | 80 -(3 rows) - +8. Retrieve all orders, including order items, from customer ID `1`. Include order id, reference, date and total cost (calculated as quantity * unit price). 9. Retrieve all orders, including order items, from customer named `Hope Crosby` - -cyf_ecommerce=# SELECT -cyf_ecommerce-# customers.id, -cyf_ecommerce-# customers.name, -cyf_ecommerce-# orders.order_reference, -cyf_ecommerce-# order_items.quantity -cyf_ecommerce-# FROM customers -cyf_ecommerce-# JOIN orders ON customers.id = orders.customer_id -cyf_ecommerce-# JOIN order_items ON orders.id = order_items.order_id -cyf_ecommerce-# WHERE customers.name = 'Hope Crosby'; -id | name | order_reference | quantity -----+-------------+-----------------+---------- -2 | Hope Crosby | ORD004 | 1 -(1 row) - 10. Retrieve all the products in the order `ORD006`. The result should only contain the columns `product_name`, `unit_price` and `quantity`. - -cyf_ecommerce=# SELECT order_items.order_id, order_items.quantity, products.product_name, product_availability.unit_price FROM order_items JOIN products ON order_items.product_id=products.id JOIN product_availability ON order_items.product_id=product_availability.prod_id AND order_items.supplier_id=product_availability.supp_id WHERE order_items.order_id = 6; -order_id | quantity | product_name | unit_price -----------+----------+------------------+------------ -6 | 1 | Javascript Book | 41 -6 | 1 | Le Petit Prince | 10 -6 | 3 | Super warm socks | 10 -6 | 3 | Coffee Cup | 4 -(4 rows) - 11. Retrieve all the products with their supplier for all orders of all customers. The result should only contain the columns `name` (from customer), `order_reference`, `order_date`, `product_name`, `supplier_name` and `quantity`. - -cyf_ecommerce=# SELECT suppliers.supplier_name, order_items.order_id, order_items.quantity, orders.order_date, customers.name, products.product_name FROM suppliers JOIN order_items ON order_items.supplier_id=suppliers.id JOIN orders ON order_items.order_id=orders.id JOIN customers ON orders.customer_id=customers.id JOIN products ON order_items.product_id = products.id; -supplier_name | order_id | quantity | order_date | name | product_name ----------------+----------+----------+------------+--------------------+------------------------- -Taobao | 1 | 1 | 2019-06-01 | Guy Crawford | Tee Shirt Olympic Games -Taobao | 1 | 5 | 2019-06-01 | Guy Crawford | Super warm socks -Argos | 2 | 4 | 2019-07-15 | Guy Crawford | Super warm socks -Sainsburys | 2 | 1 | 2019-07-15 | Guy Crawford | Le Petit Prince -Argos | 3 | 10 | 2019-07-11 | Guy Crawford | Coffee Cup -Taobao | 3 | 2 | 2019-07-11 | Guy Crawford | Ball -Amazon | 4 | 1 | 2019-05-24 | Hope Crosby | Mobile Phone X -Argos | 5 | 2 | 2019-05-30 | Britanney Kirkland | Javascript Book -Amazon | 5 | 1 | 2019-05-30 | Britanney Kirkland | Le Petit Prince -Taobao | 6 | 3 | 2019-07-05 | Amber Tran | Coffee Cup -Taobao | 6 | 1 | 2019-07-05 | Amber Tran | Javascript Book -Sainsburys | 6 | 1 | 2019-07-05 | Amber Tran | Le Petit Prince -Sainsburys | 6 | 3 | 2019-07-05 | Amber Tran | Super warm socks -Argos | 7 | 15 | 2019-04-05 | Amber Tran | Super warm socks -Amazon | 8 | 1 | 2019-07-23 | Edan Higgins | Tee Shirt Olympic Games -Sainsburys | 8 | 1 | 2019-07-23 | Edan Higgins | Mobile Phone X -Sainsburys | 9 | 2 | 2019-07-24 | Edan Higgins | Ball -Taobao | 10 | 1 | 2019-05-10 | Edan Higgins | Ball -Amazon | 10 | 5 | 2019-05-10 | Edan Higgins | Super warm socks -(19 rows) - 12. Retrieve the names of all customers who bought a product from a supplier based in China. +13. List all orders giving customer name, order reference, order date and order total amount (quantity * unit price) in descending order of total. - cyf_ecommerce=# SELECT suppliers.supplier_name, order_items.order_id, orders.order_reference, customers.name FROM suppliers JOIN order_items ON order_items.supplier_id=suppliers.id JOIN orders ON order_items.order_id=orders.id JOIN customers ON orders.customer_id=customers.id - cyf_ecommerce-# WHERE suppliers.country = 'China'; - supplier_name | order_id | order_reference | name - ---------------+----------+-----------------+-------------- - Taobao | 1 | ORD001 | Guy Crawford - Taobao | 1 | ORD001 | Guy Crawford - Taobao | 3 | ORD003 | Guy Crawford - Taobao | 6 | ORD006 | Amber Tran - Taobao | 6 | ORD006 | Amber Tran - Taobao | 10 | ORD010 | Edan Higgins - (6 rows) - -13. List all orders giving customer name, order reference, order date and order total amount (quantity \* unit price) in descending order of total. - -cyf_ecommerce=# SELECT customers.name, orders.order_reference, orders.order_date, order_items.quantity, order_items.product_id, product_availability.unit_price, (order_items.quantity \* product_availability.unit_price) as total_cost FROM customers JOIN orders ON customers.id=orders.customer_id JOIN order_items ON order_items.order_id=orders.id JOIN product_availability ON order_items.supplier_id=product_availability.supp_id AND order_items.product_id=product_availability.prod_id ORDER BY total_cost DESC; -name | order_reference | order_date | quantity | product_id | unit_price | total_cost ---------------------+-----------------+------------+----------+------------+------------+------------ -Hope Crosby | ORD004 | 2019-05-24 | 1 | 1 | 299 | 299 -Edan Higgins | ORD008 | 2019-07-23 | 1 | 1 | 249 | 249 -Amber Tran | ORD007 | 2019-04-05 | 15 | 4 | 8 | 120 -Britanney Kirkland | ORD005 | 2019-05-30 | 2 | 2 | 39 | 78 -Edan Higgins | ORD010 | 2019-05-10 | 5 | 4 | 10 | 50 -Amber Tran | ORD006 | 2019-07-05 | 1 | 2 | 41 | 41 -Guy Crawford | ORD003 | 2019-07-11 | 10 | 5 | 4 | 40 -Guy Crawford | ORD003 | 2019-07-11 | 2 | 6 | 20 | 40 -Guy Crawford | ORD002 | 2019-07-15 | 4 | 4 | 8 | 32 -Edan Higgins | ORD009 | 2019-07-24 | 2 | 6 | 15 | 30 -Amber Tran | ORD006 | 2019-07-05 | 3 | 4 | 10 | 30 -Guy Crawford | ORD001 | 2019-06-01 | 5 | 4 | 5 | 25 -Edan Higgins | ORD008 | 2019-07-23 | 1 | 7 | 20 | 20 -Edan Higgins | ORD010 | 2019-05-10 | 1 | 6 | 20 | 20 -Guy Crawford | ORD001 | 2019-06-01 | 1 | 7 | 18 | 18 -Amber Tran | ORD006 | 2019-07-05 | 3 | 5 | 4 | 12 -Amber Tran | ORD006 | 2019-07-05 | 1 | 3 | 10 | 10 -Britanney Kirkland | ORD005 | 2019-05-30 | 1 | 3 | 10 | 10 -Guy Crawford | ORD002 | 2019-07-15 | 1 | 3 | 10 | 10 -(19 rows) From 912352a6952a285b712df44e4625bc77316c0415 Mon Sep 17 00:00:00 2001 From: Maksim Lukianenko Date: Mon, 28 Aug 2023 15:19:33 +0100 Subject: [PATCH 5/5] feat(README.md): add SQL queries and their results as examples for hotel management system feat(3-api): add .gitignore file to ignore node_modules directory feat(3-api): add db.js file to establish connection to PostgreSQL database feat(3-api): add package.json file with necessary dependencies and start script feat(3-api): add routes.js file with routes for /customers, /suppliers, and /products endpoints feat(3-api): add server.js file to start the Express server on a specified port --- README.md | 29 + week-2/mandatory/3-api/.gitignore | 1 + week-2/mandatory/3-api/db.js | 11 + week-2/mandatory/3-api/package-lock.json | 1099 ++++++++++++++++++++++ week-2/mandatory/3-api/package.json | 18 + week-2/mandatory/3-api/routes.js | 44 + week-2/mandatory/3-api/server.js | 10 + 7 files changed, 1212 insertions(+) create mode 100644 week-2/mandatory/3-api/.gitignore create mode 100644 week-2/mandatory/3-api/db.js create mode 100644 week-2/mandatory/3-api/package-lock.json create mode 100644 week-2/mandatory/3-api/package.json create mode 100644 week-2/mandatory/3-api/routes.js create mode 100644 week-2/mandatory/3-api/server.js diff --git a/README.md b/README.md index fe393665..8d41fac4 100644 --- a/README.md +++ b/README.md @@ -158,3 +158,32 @@ room_no | rate | room_type | no_guests 503 | 143.00 | PREMIER PLUS | (51 rows) + +7. The hotel manager wishes to know how many rooms were occupied any time during the previous month - find that information. + +cyf_hotels=# select count (id) from reservations where checkin_date between '2023-07-01' and '2023-07-31'; +count + +--- + + 41 + +(1 row) + +8. Get the total number of nights that customers stayed in rooms on the second floor (rooms 201 - 299). + +cyf_hotels=# select floor, sum(nights) as total_nights from (select trunc(room_no/100) as floor, (checkout_date - checkin_date) as nights from reservations where trunc(room_no/100)=2 ) subquery group by floor; +floor | total_nights +-------+-------------- +2 | 63 +(1 row) + +9. How many invoices are for more than £300.00 and what is their grand total and average amount? + +cyf_hotels=# select count(\*) as invoices, sum(total) as grand_total, avg(total) as average_amount from invoices where total >= 300; +invoices | grand_total | average_amount +----------+-------------+---------------------- +25 | 12928.00 | 517.1200000000000000 +(1 row) + +10. Bonus Question: list the number of nights stay for each floor of the hotel (floor no is the hundreds part of room number, e.g. room **3**12 is on floor **3**) diff --git a/week-2/mandatory/3-api/.gitignore b/week-2/mandatory/3-api/.gitignore new file mode 100644 index 00000000..b512c09d --- /dev/null +++ b/week-2/mandatory/3-api/.gitignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/week-2/mandatory/3-api/db.js b/week-2/mandatory/3-api/db.js new file mode 100644 index 00000000..9e0eb3fe --- /dev/null +++ b/week-2/mandatory/3-api/db.js @@ -0,0 +1,11 @@ +const { Pool } = require("pg"); + +const db = new Pool({ + user: "maxbmaapc", + host: "localhost", + database: "cyf_ecommerce", + password: "", + port: 5432, +}); + +module.exports = db; diff --git a/week-2/mandatory/3-api/package-lock.json b/week-2/mandatory/3-api/package-lock.json new file mode 100644 index 00000000..cb53fad4 --- /dev/null +++ b/week-2/mandatory/3-api/package-lock.json @@ -0,0 +1,1099 @@ +{ + "name": "3-api", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "3-api", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "express": "^4.18.2", + "nodemon": "^3.0.1", + "pg": "^8.11.3" + } + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "engines": { + "node": ">=8" + } + }, + "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/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer-writer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", + "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/get-intrinsic": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==" + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "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/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/nodemon": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.0.1.tgz", + "integrity": "sha512-g9AZ7HmkhQkqXkRc20w+ZfQ73cHLbE8hnPbtaFbFtCumZsjyMhKk9LajQ07U5Ux28lvFjZ5X7HvWR1xzU8jHVw==", + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^3.2.7", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/nodemon/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/packet-reader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", + "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/pg": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.3.tgz", + "integrity": "sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g==", + "dependencies": { + "buffer-writer": "2.0.0", + "packet-reader": "1.0.0", + "pg-connection-string": "^2.6.2", + "pg-pool": "^3.6.1", + "pg-protocol": "^1.6.0", + "pg-types": "^2.1.0", + "pgpass": "1.x" + }, + "engines": { + "node": ">= 8.0.0" + }, + "optionalDependencies": { + "pg-cloudflare": "^1.1.1" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } + } + }, + "node_modules/pg-cloudflare": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", + "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", + "optional": true + }, + "node_modules/pg-connection-string": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz", + "integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==" + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-pool": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.1.tgz", + "integrity": "sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==", + "peerDependencies": { + "pg": ">=8.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz", + "integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "dependencies": { + "split2": "^4.1.0" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "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/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dependencies": { + "nopt": "~1.0.10" + }, + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } +} diff --git a/week-2/mandatory/3-api/package.json b/week-2/mandatory/3-api/package.json new file mode 100644 index 00000000..d8941096 --- /dev/null +++ b/week-2/mandatory/3-api/package.json @@ -0,0 +1,18 @@ +{ + "name": "3-api", + "version": "1.0.0", + "description": "", + "main": "server.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "start": "nodemon server.js" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "express": "^4.18.2", + "nodemon": "^3.0.1", + "pg": "^8.11.3" + } +} diff --git a/week-2/mandatory/3-api/routes.js b/week-2/mandatory/3-api/routes.js new file mode 100644 index 00000000..4e07e014 --- /dev/null +++ b/week-2/mandatory/3-api/routes.js @@ -0,0 +1,44 @@ +const express = require("express"); + +const router = express.Router(); +const db = require("./db"); + +router.get("/customers", async (req, res) => { + try { + const result = await db.query("SELECT * FROM customers"); + res.json(result.rows); + } catch (error) { + console.error(error); + res.status(500).json({ error: "An error occurred" }); + } +}); + +router.get("/suppliers", async (req, res) => { + try { + const result = await db.query("SELECT * FROM suppliers"); + res.json(result.rows); + } catch (error) { + console.error(error); + res.status(500).json({ error: "An error occurred" }); + } +}); + +router.get("/products", async (req, res) => { + try { + const result = await db.query( + "SELECT \ + products.id, products.product_name, \ + product_availability.unit_price, \ + suppliers.supplier_name \ + FROM products \ + JOIN product_availability ON products.id=product_availability.prod_id \ + JOIN suppliers ON product_availability.supp_id=suppliers.id;" + ); + res.json(result.rows); + } catch (error) { + console.error(error); + res.status(500).json({ error: "An error occurred" }); + } +}); + +module.exports = router; diff --git a/week-2/mandatory/3-api/server.js b/week-2/mandatory/3-api/server.js new file mode 100644 index 00000000..b7c5a22d --- /dev/null +++ b/week-2/mandatory/3-api/server.js @@ -0,0 +1,10 @@ +const express = require("express"); +const app = express(); + +const routes = require("./routes"); + +app.use(routes); + +app.listen(process.env.PORT || 8000, () => { + console.log("Server is live on port: " + (process.env.PORT || 8000)); +});