From a4452f489eaf7a9b05d26acdcee1c0ae37a154a2 Mon Sep 17 00:00:00 2001 From: Osman Elsahib Date: Tue, 15 Sep 2020 22:11:42 +0100 Subject: [PATCH 01/10] finished all the query statements --- week-1/mandatory/2-classes-db/task.md | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/week-1/mandatory/2-classes-db/task.md b/week-1/mandatory/2-classes-db/task.md index 735de6ae..38b11243 100644 --- a/week-1/mandatory/2-classes-db/task.md +++ b/week-1/mandatory/2-classes-db/task.md @@ -2,13 +2,21 @@ ## Submission -Below you will find a set of tasks for you to complete to consolidate and extend your learning from this week. You will find it beneficial to complete the reading tasks before attempting some of these. +Below you will find a set of tasks for you to complete to consolidate and extend your learning from this week. You will find it beneficial to complete the reading tasks before attempting some of these. To submit this homework write the correct commands for each question here: ```sql - - +1. select * from rooms where rate > 100; +2. select * from reservations where (checkin_date >= '2020-09-01' and checkin_date <='2020-09-30') and checkout_date - checkin_date < 3; +3. select * from customers where city like 'M%'; +4. insert into room_types values('PENTHOUSE','185.00'); +5. insert into rooms (room_no, rate, room_type) values(501,(select def_rate from room_types where room_type = 'PENTHOUSE'),'PENTHOUSE'),(502,(select def_rate from room_types where room_type = 'PENTHOUSE'),'PENTHOUSE'); +6. insert into rooms (room_no, rate, room_type) values(503,143.00,'PREMIER PLUS'); +7. select all from reservations where checkin_date >= '2020-08-01' and checkin_date <= '2020-08-31'; / select count(id) from reservations where checkin_date >= '2020-08-01' and checkin_date <= '2020-08-31'; +8. select sum(checkout_date - checkin_date) from reservations where room_no between 200 and 299; +9. select sum(total),avg(total) from invoices where total > 300; +10. select sum(case when room_no between 100 and 199 then checkout_date - checkin_date end) as first_floor, sum(case when room_no between 200 and 299 then checkout_date - checkin_date end) as second_floor, sum(case when room_no between 300 and 399 then checkout_date - checkin_date end) as third_floor from reservations; ``` When you have finished all of the questions - open a pull request with your answers to the `Databases-Homework` repository. @@ -18,6 +26,7 @@ When you have finished all of the questions - open a pull request with your answ If you haven't completed all the exercises from this lesson then do that first. ### Tasks + 1. Which rooms have a rate of more than 100.00? 2. List the reservations that have a checkin date this month and are for more than three nights. 3. List all customers from cities that begin with the letter 'M'. @@ -33,4 +42,4 @@ Using what you can learn about aggregate functions in the w3schools SQL classes 7. The hotel manager wishes to know how many rooms were occupied any time during the previous month - find that information. 8. Get the total number of nights that customers stayed in rooms on the second floor (rooms 201 - 299). 9. How many invoices are for more than £300.00 and what is their grand total and average amount? -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**) +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**) From 1485709f9139f27f0bac6cedbc8a4df6ce9dac1f Mon Sep 17 00:00:00 2001 From: Osman Elsahib Date: Tue, 15 Sep 2020 22:24:18 +0100 Subject: [PATCH 02/10] forgot about the 4th floor --- week-1/mandatory/2-classes-db/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/week-1/mandatory/2-classes-db/task.md b/week-1/mandatory/2-classes-db/task.md index 38b11243..93b8479d 100644 --- a/week-1/mandatory/2-classes-db/task.md +++ b/week-1/mandatory/2-classes-db/task.md @@ -16,7 +16,7 @@ To submit this homework write the correct commands for each question here: 7. select all from reservations where checkin_date >= '2020-08-01' and checkin_date <= '2020-08-31'; / select count(id) from reservations where checkin_date >= '2020-08-01' and checkin_date <= '2020-08-31'; 8. select sum(checkout_date - checkin_date) from reservations where room_no between 200 and 299; 9. select sum(total),avg(total) from invoices where total > 300; -10. select sum(case when room_no between 100 and 199 then checkout_date - checkin_date end) as first_floor, sum(case when room_no between 200 and 299 then checkout_date - checkin_date end) as second_floor, sum(case when room_no between 300 and 399 then checkout_date - checkin_date end) as third_floor from reservations; +10. select sum(case when room_no between 100 and 199 then checkout_date - checkin_date end) as first_floor, sum(case when room_no between 200 and 299 then checkout_date - checkin_date end) as second_floor, sum(case when room_no between 300 and 399 then checkout_date - checkin_date end) as third_floor, sum(case when room_no between 400 and 499 then checkout_date - checkin_date end) as fourth_floor from reservations; ``` When you have finished all of the questions - open a pull request with your answers to the `Databases-Homework` repository. From 222be0abd0e2478b32bd5cfa44515163e5a10dbf Mon Sep 17 00:00:00 2001 From: Osman Elsahib Date: Mon, 21 Sep 2020 14:46:16 +0100 Subject: [PATCH 03/10] HW submission --- week-2/mandatory/2-ecommerce-db/ERD.png | Bin 0 -> 13290 bytes week-2/mandatory/2-ecommerce-db/task.md | 15 ++++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 week-2/mandatory/2-ecommerce-db/ERD.png diff --git a/week-2/mandatory/2-ecommerce-db/ERD.png b/week-2/mandatory/2-ecommerce-db/ERD.png new file mode 100644 index 0000000000000000000000000000000000000000..b0d7ef56e41757da97d37884f6ff134705501085 GIT binary patch literal 13290 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 literal 0 HcmV?d00001 diff --git a/week-2/mandatory/2-ecommerce-db/task.md b/week-2/mandatory/2-ecommerce-db/task.md index c48d2286..718cbefd 100644 --- a/week-2/mandatory/2-ecommerce-db/task.md +++ b/week-2/mandatory/2-ecommerce-db/task.md @@ -8,7 +8,20 @@ Below you will find a set of tasks for you to complete to set up a database for To submit this homework write the correct commands for each question here: ```sql - +1. select * from customers where country = 'United States'; +2. select * from customers order by name; +3. select * from products where product_name like '%socks%'; +4. select a.prod_id, p.product_name,a.supp_id,a.unit_price from product_availability a join products p on p.id = a.prod_id where a.unit_price > 100; +5. select * from product_availability order by unit_price DESC limit 5; +6. select p.product_name,a.unit_price,s.supplier_name from product_availability a join products p on p.id = a.prod_id join suppliers s on a.supp_id = s.id; +7. select p.product_name,s.supplier_name from product_availability a join products p on p.id = a.prod_id join suppliers s on a.supp_id = s.id where s.country = 'United Kingdom'; +8-a. select o.id as Order_ID,o.order_reference, o.order_date, a.unit_price * i.quantity as total from order_items i join orders o on o.id=i.order_id join product_availability a on (i.product_id = a.prod_id and i.supplier_id = a.supp_id) where o.customer_id = 1; +8-b. select o.id as Order_ID,p.product_name, o.order_reference, o.order_date, a.unit_price * i.quantity as total from order_items i join orders o on o.id=i.order_id join product_availability a on (i.product_id = a.prod_id and i.supplier_id = a.supp_id) join products p on p.id = a.prod_id where o.customer_id = 1; +9. select o.id as Order_ID, p.product_name from orders o join order_items i on o.id = i.order_id join customers c on c.id = o.customer_id join products p on p.id = i.product_id where c.name = 'Hope Crosby'; +10. select p.product_name, a.unit_price, i.quantity from order_items i join orders o on o.id=i.order_id join product_availability a on (i.product_id = a.prod_id and i.supplier_id = a.supp_id) join products p on p.id = a.prod_id where o.order_reference = 'ORD006'; +11. select c.name, o.order_reference, o.order_date, p.product_name, s.supplier_name, i.quantity from order_items i join product_availability a on (i.product_id = a.prod_id and i.supplier_id = a.supp_id) join orders o on o.id = i.order_id join customers c on o.customer_id = c.id join products p on a.prod_id = p.id join suppliers s on a.supp_id = s.id; +12. select distinct c.name from order_items i join orders o on i.order_id = o.id join customers c on c.id = o.customer_id join suppliers s on i.supplier_id = s.id where s.country = 'China'; +13. select c.name, o.order_reference, o.order_date, sum(i.quantity * a.unit_price) as total from orders o join customers c on o.customer_id = c.id join order_items i on i.order_id = o.id join product_availability a on (i.product_id = a.prod_id and i.supplier_id = a.supp_id) group by c.name, o.order_reference, o.order_date order by total DESC; ``` From a93b5195fc93d25d9aa01a020343558c4e3920d9 Mon Sep 17 00:00:00 2001 From: Osman Elsahib Date: Mon, 21 Sep 2020 17:56:29 +0100 Subject: [PATCH 04/10] Finished API --- .gitignore | 1 + week-2/mandatory/3-api/package-lock.json | 485 +++++++++++++++++++++++ week-2/mandatory/3-api/package.json | 15 + week-2/mandatory/3-api/server.js | 34 ++ 4 files changed, 535 insertions(+) create mode 100644 .gitignore 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/server.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..b512c09d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file 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..ac376746 --- /dev/null +++ b/week-2/mandatory/3-api/package-lock.json @@ -0,0 +1,485 @@ +{ + "name": "cyf-ecommerce-api", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + } + }, + "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==" + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "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==" + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" + }, + "mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "requires": { + "mime-db": "1.44.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "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==" + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "pg": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.3.3.tgz", + "integrity": "sha512-wmUyoQM/Xzmo62wgOdQAn5tl7u+IA1ZYK7qbuppi+3E+Gj4hlUxVHjInulieWrd0SfHi/ADriTb5ILJ/lsJrSg==", + "requires": { + "buffer-writer": "2.0.0", + "packet-reader": "1.0.0", + "pg-connection-string": "^2.3.0", + "pg-pool": "^3.2.1", + "pg-protocol": "^1.2.5", + "pg-types": "^2.1.0", + "pgpass": "1.x", + "semver": "4.3.2" + } + }, + "pg-connection-string": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.3.0.tgz", + "integrity": "sha512-ukMTJXLI7/hZIwTW7hGMZJ0Lj0S2XQBCJ4Shv4y1zgQ/vqVea+FLhzywvPj0ujSuofu+yA4MYHGZPTsgjBgJ+w==" + }, + "pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==" + }, + "pg-pool": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.2.1.tgz", + "integrity": "sha512-BQDPWUeKenVrMMDN9opfns/kZo4lxmSWhIqo+cSAF7+lfi9ZclQbr9vfnlNaPr8wYF3UYjm5X0yPAhbcgqNOdA==" + }, + "pg-protocol": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.2.5.tgz", + "integrity": "sha512-1uYCckkuTfzz/FCefvavRywkowa6M5FohNMF5OjKrqo9PSR8gYc8poVmwwYQaBxhmQdBjhtP514eXy9/Us2xKg==" + }, + "pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "requires": { + "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" + } + }, + "pgpass": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.2.tgz", + "integrity": "sha1-Knu0G2BltnkH6R2hsHwYR8h3swY=", + "requires": { + "split": "^1.0.0" + } + }, + "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==" + }, + "postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=" + }, + "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==" + }, + "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==", + "requires": { + "xtend": "^4.0.0" + } + }, + "proxy-addr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + } + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + }, + "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==" + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "semver": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.2.tgz", + "integrity": "sha1-x6BxWKgL7dBSNVt3DYLWZA+AO+c=" + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + } + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "requires": { + "through": "2" + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + } + } +} diff --git a/week-2/mandatory/3-api/package.json b/week-2/mandatory/3-api/package.json new file mode 100644 index 00000000..6ed18b79 --- /dev/null +++ b/week-2/mandatory/3-api/package.json @@ -0,0 +1,15 @@ +{ + "name": "cyf-ecommerce-api", + "version": "1.0.0", + "description": "Node App to that connects to a simple PostgreSQL database.", + "main": "server.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Osman Elsahib", + "license": "ISC", + "dependencies": { + "express": "^4.17.1", + "pg": "^8.3.3" + } +} diff --git a/week-2/mandatory/3-api/server.js b/week-2/mandatory/3-api/server.js new file mode 100644 index 00000000..3008b07b --- /dev/null +++ b/week-2/mandatory/3-api/server.js @@ -0,0 +1,34 @@ +const express = require("express"); +const app = express(); + +const { Pool } = require("pg"); + +const db = new Pool({ + user: "admin", // replace with you username + host: "localhost", + database: "cyf_ecommerce", + password: "password", + port: 5432, +}); + +app.get("/customers", (req, res) => { + db.query("SELECT * FROM customers", (error, result) => { + res.json(result.rows); + }); +}); + +app.get("/suppliers", (req, res) => { + db.query("SELECT * FROM suppliers", (error, result) => { + res.json(result.rows); + }); +}); + +app.get("/products", (req, res) => { + db.query("SELECT p.product_name, a.unit_price , s.supplier_name from products p join product_availability a on p.id = a.prod_id join suppliers s on s.id = a.supp_id", (error, result) => { + res.json(result.rows); + }); +}); + +app.listen(3000, function () { + console.log("Server is listening on port 3000."); +}); From bdf26fe933e7ea5c6cdd1e785338273aa7a31c37 Mon Sep 17 00:00:00 2001 From: Osman Elsahib Date: Wed, 23 Sep 2020 18:08:09 +0100 Subject: [PATCH 05/10] implementing mentor comments on server.js --- week-2/mandatory/2-ecommerce-db/task.md | 2 ++ week-2/mandatory/3-api/server.js | 37 ++++++++++++++++++++----- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/week-2/mandatory/2-ecommerce-db/task.md b/week-2/mandatory/2-ecommerce-db/task.md index 718cbefd..82a08d34 100644 --- a/week-2/mandatory/2-ecommerce-db/task.md +++ b/week-2/mandatory/2-ecommerce-db/task.md @@ -7,7 +7,9 @@ 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 + 1. select * from customers where country = 'United States'; 2. select * from customers order by name; 3. select * from products where product_name like '%socks%'; diff --git a/week-2/mandatory/3-api/server.js b/week-2/mandatory/3-api/server.js index 3008b07b..f973e373 100644 --- a/week-2/mandatory/3-api/server.js +++ b/week-2/mandatory/3-api/server.js @@ -13,20 +13,43 @@ const db = new Pool({ app.get("/customers", (req, res) => { db.query("SELECT * FROM customers", (error, result) => { - res.json(result.rows); + if (error) { + console.log("pg error code:", error.code); + res.status(500).json("There seems to be a problem with our servers"); + throw error; + } else { + res.status(200).json(result.rows); + } }); }); app.get("/suppliers", (req, res) => { - db.query("SELECT * FROM suppliers", (error, result) => { - res.json(result.rows); - }); + db.query("SELECT * FROM suppliers", (error, result) => { + if (error) { + console.log("pg error code:", error.code); + res + .status(500) + .json("We have a database error, please contact site admin."); + } else { + res.status(200).json(result.rows); + } + }); }); app.get("/products", (req, res) => { - db.query("SELECT p.product_name, a.unit_price , s.supplier_name from products p join product_availability a on p.id = a.prod_id join suppliers s on s.id = a.supp_id", (error, result) => { - res.json(result.rows); - }); + db.query( + "SELECT p.product_name, a.unit_price , s.supplier_name from products p join product_availability a on p.id = a.prod_id join suppliers s on s.id = a.supp_id", + (error, result) => { + if (error) { + console.log("pg error code:", error.code); + res + .status(500) + .json("We have a database error, please contact site admin."); + } else { + res.status(200).json(result.rows); + } + } + ); }); app.listen(3000, function () { From 0b729e638cd2afbf77aa9763615f8953862c8c7e Mon Sep 17 00:00:00 2001 From: Osman Elsahib Date: Thu, 24 Sep 2020 13:28:36 +0100 Subject: [PATCH 06/10] fixing numer 8 --- cyf_ecommerce | 72 +++++++++++++++++++++++++ week-2/mandatory/2-ecommerce-db/task.md | 6 +-- 2 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 cyf_ecommerce diff --git a/cyf_ecommerce b/cyf_ecommerce new file mode 100644 index 00000000..3ae971df --- /dev/null +++ b/cyf_ecommerce @@ -0,0 +1,72 @@ + order_id | order_reference | order_date | total +----------+-----------------+------------+------- + 1 | ORD001 | 2019-06-01 | 18 + 1 | ORD001 | 2019-06-01 | 25 + 2 | ORD002 | 2019-07-15 | 32 + 2 | ORD002 | 2019-07-15 | 10 + 3 | ORD003 | 2019-07-11 | 40 + 3 | ORD003 | 2019-07-11 | 40 +(6 rows) + + order_id | order_reference | order_date | total +----------+-----------------+------------+------- + 1 | ORD001 | 2019-06-01 | 18 + 1 | ORD001 | 2019-06-01 | 25 + 2 | ORD002 | 2019-07-15 | 32 + 2 | ORD002 | 2019-07-15 | 10 + 3 | ORD003 | 2019-07-11 | 40 + 3 | ORD003 | 2019-07-11 | 40 +(6 rows) + + order_id | order_reference | order_date | total +----------+-----------------+------------+------- + 1 | ORD001 | 2019-06-01 | 18 + 1 | ORD001 | 2019-06-01 | 25 + 2 | ORD002 | 2019-07-15 | 32 + 2 | ORD002 | 2019-07-15 | 10 + 3 | ORD003 | 2019-07-11 | 40 + 3 | ORD003 | 2019-07-11 | 40 +(6 rows) + + order_id | product_name | order_reference | order_date | total +----------+-------------------------+-----------------+------------+------- + 1 | Tee Shirt Olympic Games | ORD001 | 2019-06-01 | 18 + 1 | Super warm socks | ORD001 | 2019-06-01 | 25 + 2 | Super warm socks | ORD002 | 2019-07-15 | 32 + 2 | Le Petit Prince | ORD002 | 2019-07-15 | 10 + 3 | Coffee Cup | ORD003 | 2019-07-11 | 40 + 3 | Ball | ORD003 | 2019-07-11 | 40 +(6 rows) + + order_id | order_reference | order_date | total +----------+-----------------+------------+------- + 1 | ORD001 | 2019-06-01 | 18 + 1 | ORD001 | 2019-06-01 | 25 + 2 | ORD002 | 2019-07-15 | 32 + 2 | ORD002 | 2019-07-15 | 10 + 3 | ORD003 | 2019-07-11 | 40 + 3 | ORD003 | 2019-07-11 | 40 +(6 rows) + + List of relations + Schema | Name | Type | Owner +--------+----------------------+-------+------- + public | customers | table | admin + public | order_items | table | admin + public | orders | table | admin + public | product_availability | table | admin + public | products | table | admin + public | suppliers | table | admin +(6 rows) + + List of relations + Schema | Name | Type | Owner +--------+----------------------+-------+------- + public | customers | table | admin + public | order_items | table | admin + public | orders | table | admin + public | product_availability | table | admin + public | products | table | admin + public | suppliers | table | admin +(6 rows) + diff --git a/week-2/mandatory/2-ecommerce-db/task.md b/week-2/mandatory/2-ecommerce-db/task.md index 82a08d34..79286713 100644 --- a/week-2/mandatory/2-ecommerce-db/task.md +++ b/week-2/mandatory/2-ecommerce-db/task.md @@ -19,6 +19,7 @@ To submit this homework write the correct commands for each question here: 7. select p.product_name,s.supplier_name from product_availability a join products p on p.id = a.prod_id join suppliers s on a.supp_id = s.id where s.country = 'United Kingdom'; 8-a. select o.id as Order_ID,o.order_reference, o.order_date, a.unit_price * i.quantity as total from order_items i join orders o on o.id=i.order_id join product_availability a on (i.product_id = a.prod_id and i.supplier_id = a.supp_id) where o.customer_id = 1; 8-b. select o.id as Order_ID,p.product_name, o.order_reference, o.order_date, a.unit_price * i.quantity as total from order_items i join orders o on o.id=i.order_id join product_availability a on (i.product_id = a.prod_id and i.supplier_id = a.supp_id) join products p on p.id = a.prod_id where o.customer_id = 1; +8-c. select o.id as Order_ID, o.order_reference, o.order_date, sum(a.unit_price * i.quantity) as total from order_items i join orders o on o.id=i.order_id join product_availability a on (i.product_id = a.prod_id and i.supplier_id = a.supp_id) where o.customer_id = 1 group by o.id; (after mentor explanation) 9. select o.id as Order_ID, p.product_name from orders o join order_items i on o.id = i.order_id join customers c on c.id = o.customer_id join products p on p.id = i.product_id where c.name = 'Hope Crosby'; 10. select p.product_name, a.unit_price, i.quantity from order_items i join orders o on o.id=i.order_id join product_availability a on (i.product_id = a.prod_id and i.supplier_id = a.supp_id) join products p on p.id = a.prod_id where o.order_reference = 'ORD006'; 11. select c.name, o.order_reference, o.order_date, p.product_name, s.supplier_name, i.quantity from order_items i join product_availability a on (i.product_id = a.prod_id and i.supplier_id = a.supp_id) join orders o on o.id = i.order_id join customers c on o.customer_id = c.id join products p on a.prod_id = p.id join suppliers s on a.supp_id = s.id; @@ -56,10 +57,9 @@ Once you understand the database that you are going to work with, solve the foll 5. Retrieve the 5 most expensive products 6. Retrieve all the products with their corresponding suppliers. The result should only contain the columns `product_name`, `unit_price` and `supplier_name` 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). +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` 10. Retrieve all the products in the order `ORD006`. The result should only contain the columns `product_name`, `unit_price` and `quantity`. 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`. 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. - +13. List all orders giving customer name, order reference, order date and order total amount (quantity \* unit price) in descending order of total. From c1304d0bf3fc0a70b86929cd1696a9c3827d3bae Mon Sep 17 00:00:00 2001 From: Osman Elsahib Date: Wed, 30 Sep 2020 10:20:41 +0100 Subject: [PATCH 07/10] working availability --- week-2/mandatory/3-api/server.js | 158 ++++++++++++++++++++++++++++--- 1 file changed, 146 insertions(+), 12 deletions(-) diff --git a/week-2/mandatory/3-api/server.js b/week-2/mandatory/3-api/server.js index f973e373..1ab2650f 100644 --- a/week-2/mandatory/3-api/server.js +++ b/week-2/mandatory/3-api/server.js @@ -10,12 +10,15 @@ const db = new Pool({ password: "password", port: 5432, }); +app.use(express.json()); + +let serverError = "We have a server error, please contact site admin."; app.get("/customers", (req, res) => { db.query("SELECT * FROM customers", (error, result) => { if (error) { console.log("pg error code:", error.code); - res.status(500).json("There seems to be a problem with our servers"); + res.status(500).json(serverError); throw error; } else { res.status(200).json(result.rows); @@ -23,28 +26,34 @@ app.get("/customers", (req, res) => { }); }); -app.get("/suppliers", (req, res) => { - db.query("SELECT * FROM suppliers", (error, result) => { +app.get("/customers/:customerID", (req, res) => { + let id = parseInt(req.params.customerID); + db.query("SELECT * FROM customers where id = $1", [id], (error, result) => { if (error) { console.log("pg error code:", error.code); - res - .status(500) - .json("We have a database error, please contact site admin."); + res.status(500).json(serverError); + throw error; } else { - res.status(200).json(result.rows); + if (result.rows.length > 0) { + res.status(200).json(result.rows[0]); + } else { + res.status(404).json("There is no customer with this ID"); + } } }); }); -app.get("/products", (req, res) => { +app.get("/customers/by-name/:name", (req, res) => { + let name = req.params.name.toLowerCase(); + db.query( - "SELECT p.product_name, a.unit_price , s.supplier_name from products p join product_availability a on p.id = a.prod_id join suppliers s on s.id = a.supp_id", + "SELECT * FROM customers where Lower(name) LIKE $1 || '%'", + [name], (error, result) => { if (error) { console.log("pg error code:", error.code); - res - .status(500) - .json("We have a database error, please contact site admin."); + res.status(500).json(serverError); + throw error; } else { res.status(200).json(result.rows); } @@ -52,6 +61,131 @@ app.get("/products", (req, res) => { ); }); +app.get("/suppliers", (req, res) => { + db.query("SELECT * FROM suppliers", (error, result) => { + if (error) { + console.log("pg error code:", error.code); + res.status(500).json(serverError); + } else { + res.status(200).json(result.rows); + } + }); +}); + +app.get("/products", (req, res) => { + let name = req.query.name; + if (name) { + name.toLowerCase(); + db.query( + "SELECT p.product_name, a.unit_price , s.supplier_name from products p join product_availability a on p.id = a.prod_id join suppliers s on s.id = a.supp_id where Lower(p.product_name) like '%'||$1||'%'", + [name], + (error, result) => { + if (error) { + console.log("pg error code:", error.code); + res.status(500).json(serverError); + } else { + res.status(200).json(result.rows); + } + } + ); + } else { + db.query( + "SELECT p.product_name, a.unit_price , s.supplier_name from products p join product_availability a on p.id = a.prod_id join suppliers s on s.id = a.supp_id", + (error, result) => { + if (error) { + console.log("pg error code:", error.code); + res.status(500).json(serverError); + } else { + res.status(200).json(result.rows); + } + } + ); + } +}); + +app.post("/customers", (req, res) => { + let name = req.body.name, + address = req.body.address, + city = req.body.city, + country = req.body.country; + let sql = + "INSERT INTO customers (name, address, city, country) " + + "VALUES ($1, $2, $3, $4) returning id"; + let attributes = [name, address, city, country]; + + db.query(sql, attributes, (error, result) => { + if (error) { + console.log("pg error code:", error.code); + res.status(500).json(serverError); + } else { + res + .status(201) + .json(`A new customer is created with the ID ${result.rows[0].id}`); + } + }); +}); + +app.post("/products", (req, res) => { + let product = req.body.productName; + let sql = "insert into products (product_name)" + "values ($1) returning id"; + db.query(sql, [product], (error, result) => { + if (error) { + console.log("pg error code:", error.code); + res.status(500).json(serverError); + } else { + res.status(201).json(`Product added with the ID ${result.rows[0].id}`); + } + }); +}); + +app.post("/availability", (req, res) => { + let price = parseInt(req.body.price), + product = parseInt(req.body.product_id), + supplier = parseInt(req.body.supplier_id); + let sql_prod = "select id from products where id = $1 ", + sql_supp = " select id from suppliers where id = $1 ", + sql_insert = + "insert into product_availability (prod_id,supp_id,unit_price)" + + "values ($1,$2,$3)"; + if (price > 0) { + db.query(sql_supp, [supplier], (error, result) => { + if (error) { + console.log("pg error code:", error.code); + res.status(500).json(serverError); + } else if (result.rows.length > 0) { + db.query(sql_prod, [product], (error, result) => { + if (error) { + console.log("pg error code:", error.code); + res.status(500).json(serverError); + } else if (result.rows.length > 0) { + db.query( + sql_insert, + [product, supplier, price], + (error, result) => { + res.status(201).json("Product price added."); + } + ); + } else { + res.status(404).json("Can't find a product with this ID"); + } + }); + } else { + res.status(404).json("Can't find a supplier with this ID"); + } + }); + } else { + res.status(400).json("The price needs to be larger than 0"); + } +}); + +app.post("/customers/:customerId/orders",(req,res)=>{ + let id = parseInt(req.params.customerId), + sql_orders = "insert into orders (order_date, order_reference, customer_id)"+ + "values (current_date,$1,$2)", + sql_customers = "select * from customers where id = $1", + sql_orderNumber = "select order_reference from orders order by id DESC limit 1" + +}) app.listen(3000, function () { console.log("Server is listening on port 3000."); }); From 1af67c28e47e265b0c72fe01c1a61a57108ac6a3 Mon Sep 17 00:00:00 2001 From: Osman Elsahib Date: Wed, 30 Sep 2020 13:44:00 +0100 Subject: [PATCH 08/10] working towards the end --- week-2/mandatory/3-api/server.js | 182 +++++++++++++++++++++++++++++-- 1 file changed, 170 insertions(+), 12 deletions(-) diff --git a/week-2/mandatory/3-api/server.js b/week-2/mandatory/3-api/server.js index 1ab2650f..9b30d5e7 100644 --- a/week-2/mandatory/3-api/server.js +++ b/week-2/mandatory/3-api/server.js @@ -37,7 +37,7 @@ app.get("/customers/:customerID", (req, res) => { if (result.rows.length > 0) { res.status(200).json(result.rows[0]); } else { - res.status(404).json("There is no customer with this ID"); + res.status(404).json(`There is no customer with this ID ${id}`); } } }); @@ -158,13 +158,14 @@ app.post("/availability", (req, res) => { console.log("pg error code:", error.code); res.status(500).json(serverError); } else if (result.rows.length > 0) { - db.query( - sql_insert, - [product, supplier, price], - (error, result) => { + db.query(sql_insert, [product, supplier, price], (error) => { + if (error) { + console.log("pg error code:", error.code); + res.status(500).json(serverError); + } else { res.status(201).json("Product price added."); } - ); + }); } else { res.status(404).json("Can't find a product with this ID"); } @@ -178,14 +179,171 @@ app.post("/availability", (req, res) => { } }); -app.post("/customers/:customerId/orders",(req,res)=>{ +app.post("/customers/:customerId/orders", (req, res) => { let id = parseInt(req.params.customerId), - sql_orders = "insert into orders (order_date, order_reference, customer_id)"+ - "values (current_date,$1,$2)", - sql_customers = "select * from customers where id = $1", - sql_orderNumber = "select order_reference from orders order by id DESC limit 1" + sql_orders = + "insert into orders (order_date, order_reference, customer_id)" + + "values (current_date,$1,$2) returning order_reference", + sql_customers = "select * from customers where id = $1", + sql_orderNumber = + "select order_reference from orders order by id DESC limit 1"; -}) + db.query(sql_customers, [id], (error, result) => { + if (error) { + console.log("pg error code:", error.code); + res.status(500).json(serverError); + } else if (result.rows.length > 0) { + db.query(sql_orderNumber, (error, result) => { + if (error) { + console.log("pg error code:", error.code); + res.status(500).json(serverError); + } else { + let lastOrder = result.rows[0].order_reference; + //orderRef functions are borrowed from https://electrictoolbox.com/pad-number-zeroes-javascript/ and SOF site + let orderRef = lastOrder.replace(/(\d+)+/g, function (match, number) { + function pad(number, length) { + let str = "" + number; + while (str.length < length) { + str = "0" + str; + } + return str; + } + return pad(parseInt(number) + 1, 3); + }); + db.query(sql_orders, [orderRef, id], (error, result) => { + if (error) { + console.log("pg error code:", error.code); + res.status(500).json(serverError); + } else { + res + .status(201) + .json( + `Order placed with reference ${result.rows[0].order_reference}` + ); + } + }); + } + }); + } + }); +}); + +app.put("/customers/:customerId", (req, res) => { + const id = parseInt(req.params.customerId), + name = req.body.name, + address = req.body.address, + city = req.body.city, + country = req.body.country; + db.query("SELECT * FROM customers where id = $1", [id], (error, result) => { + if (error) { + console.log("pg error code:", error.code); + res.status(500).json(serverError); + throw error; + } else { + if (result.rows.length > 0) { + db.query( + "update customers set name = $1, address = $2, city = $3,country = $4 where id = $5", + [name, address, city, country, id], + (error) => { + if (error) { + console.log("pg error code:", error.code); + res.status(500).json(serverError); + throw error; + } else { + res.status(200).json(`Customer with ID ${id} data updated.`); + } + } + ); + } else { + res.status(404).json(`There is no customer with this ID ${id}`); + } + } + }); +}); + +app.delete("/orders/:orderId", (req, res) => { + let id = req.params.orderId; + db.query("SELECT * FROM orders where id = $1", [id], (error, result) => { + if (error) { + console.log("pg error code:", error.code); + res.status(500).json(serverError); + throw error; + } else { + if (result.rows.length > 0) { + db.query( + "delete from order_items where order_id = $1", + [id], + (error) => { + if (error) { + console.log("pg error code:", error.code); + res.status(500).json(serverError); + throw error; + } else { + db.query("delete from orders where id = $1", [id], (error) => { + if (error) { + console.log("pg error code:", error.code); + res.status(500).json(serverError); + throw error; + } else { + res + .status(200) + .json(`Order ${id} and all it's Items are deleted`); + } + }); + } + } + ); + } else { + res.status(404).json(`There is no order with this ID ${id}`); + } + } + }); +}); +app.delete("/customers/:customerId", (req, res) => { + let id = req.params.customerId; + db.query("SELECT * FROM customers where id = $1", [id], (error, result) => { + if (error) { + console.log("pg error code:", error.code); + res.status(500).json(serverError); + throw error; + } else { + if (result.rows.length > 0) { + db.query( + "select * from orders where customer_id = $1", + [id], + (error, result) => { + if (error) { + console.log("pg error code:", error.code); + res.status(500).json(serverError); + throw error; + } else if (result.rows.length > 0) { + res + .status(200) + .json(`Can't delete customer with id ${id}. They have orders`); + } else { + db.query("delete from customers where id = $1", [id], (error) => { + if (error) { + console.log("pg error code:", error.code); + res.status(500).json(serverError); + throw error; + } else { + res.status(200).json(`Customer with ID ${id} is deleted`); + } + }); + } + } + ); + } else { + res.status(404).json(`There is no customer with this ID ${id}`); + } + } + }); +}); + +app.get("/customers/:customerId/orders", (req, res) => { + let id = req.params.customerId; + +}); app.listen(3000, function () { console.log("Server is listening on port 3000."); }); From 144622a2f6948dd54fa4d6f5315a1727b076f704 Mon Sep 17 00:00:00 2001 From: Osman Elsahib Date: Wed, 30 Sep 2020 14:08:12 +0100 Subject: [PATCH 09/10] phew, I think I got them all now. --- week-2/mandatory/3-api/server.js | 35 +++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/week-2/mandatory/3-api/server.js b/week-2/mandatory/3-api/server.js index 9b30d5e7..03c9e3eb 100644 --- a/week-2/mandatory/3-api/server.js +++ b/week-2/mandatory/3-api/server.js @@ -342,8 +342,41 @@ app.delete("/customers/:customerId", (req, res) => { app.get("/customers/:customerId/orders", (req, res) => { let id = req.params.customerId; - + db.query("SELECT * FROM customers where id = $1", [id], (error, result) => { + if (error) { + console.log("pg error code:", error.code); + res.status(500).json(serverError); + throw error; + } else { + if (result.rows.length > 0) { + db.query( + "select o.order_reference as OrderRef, o.order_date as OrderDate," + + "p.product_name ProductNames, a.unit_price as UnitPrice,s.supplier_name as Supplier," + + "i.quantity as Quantity from order_items i join orders o on o.id=i.order_id " + + "join product_availability a on (i.product_id = a.prod_id and i.supplier_id = a.supp_id)" + + "join products p on p.id = a.prod_id join suppliers s on s.id = a.supp_id where o.customer_id = $1", + [id], + (error, result) => { + if (error) { + console.log("pg error code:", error.code); + res.status(500).json(serverError); + throw error; + } else { + res.status(200).json(result.rows); + } + } + ); + } else { + res + .status(404) + .json( + `There is no customer with this ID ${id} or they haven't ordered yet.` + ); + } + } + }); }); + app.listen(3000, function () { console.log("Server is listening on port 3000."); }); From 02635e52e9bc056e39fd36d636f4e690581e63dc Mon Sep 17 00:00:00 2001 From: Osman Elsahib Date: Wed, 30 Sep 2020 14:11:21 +0100 Subject: [PATCH 10/10] enhancements --- week-2/mandatory/3-api/server.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/week-2/mandatory/3-api/server.js b/week-2/mandatory/3-api/server.js index 03c9e3eb..fef80cbf 100644 --- a/week-2/mandatory/3-api/server.js +++ b/week-2/mandatory/3-api/server.js @@ -300,7 +300,7 @@ app.delete("/orders/:orderId", (req, res) => { }); }); app.delete("/customers/:customerId", (req, res) => { - let id = req.params.customerId; + let id = parseInt(req.params.customerId); db.query("SELECT * FROM customers where id = $1", [id], (error, result) => { if (error) { console.log("pg error code:", error.code); @@ -341,7 +341,7 @@ app.delete("/customers/:customerId", (req, res) => { }); app.get("/customers/:customerId/orders", (req, res) => { - let id = req.params.customerId; + let id = parseInt(req.params.customerId); db.query("SELECT * FROM customers where id = $1", [id], (error, result) => { if (error) { console.log("pg error code:", error.code);