Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions week-1/mandatory/2-classes-db/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,28 @@ Below you will find a set of tasks for you to complete to consolidate and extend
To submit this homework write the correct commands for each question here:

```sql


--1
select room_no from rooms where rate>100;
--2
select * from reservations where (checkin_date between '2020-09-01' and '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 select 501 as room_no, def_rate,'PENTHOUSE' as room_type,null as no_guest from room_types where room_type='PENTHOUSE';

INSERT INTO rooms select 502 as room_no, def_rate,'PENTHOUSE' as room_type,null as no_guest from room_types where room_type='PENTHOUSE';
--6
INSERT INTO rooms VALUES (503,143.00,'PREMIER PLUS',null);
--7
select count(room_no) from reservations where (checkin_date between '2020-08-01' and '2020-08-31');
--8
select sum(checkout_date-checkin_date) from reservations where (room_no between 201 and 299);
--9
select count(res_id),sum(total),avg(total) from invoices where total >300;
--10
SELECT sum(checkout_date-checkin_date),floor(room_no/100)as floor_No from reservations group by floor(room_no/100) having floor(room_no/100)>0;
```

When you have finished all of the questions - open a pull request with your answers to the `Databases-Homework` repository.
Expand Down
28 changes: 26 additions & 2 deletions week-2/mandatory/2-ecommerce-db/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,32 @@ 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 name,address from customers where country ='United States';
--2
select * from customers order by name;
--3
select * from products where product_name like '%socks%';
--4
select p.* ,pa.unit_price,pa.supp_id from products p join product_availability pa on(p.id=pa.prod_id) where pa.unit_price>100;
--5
select p.* from products p join product_availability pa on(p.id=pa.prod_id) order by pa.unit_price desc limit 5;
--6
select p.product_name,pa.unit_price,s.supplier_name from products p join product_availability pa on(p.id=pa.prod_id)join suppliers s on (pa.supp_id=s.id) ;
--7
select p.product_name,s.supplier_name from products p join product_availability pa on(p.id=pa.prod_id)join suppliers s on (pa.supp_id=s.id) where s.country='United Kingdom' ;
--8
select o.id,o.order_reference,o.order_date,oi.quantity* pa.unit_price as total from orders o join order_items oi on(o.id=oi.order_id) join product_availability pa on(oi.product_id=pa.prod_id) where o.customer_id=1 ;
--9
select o.*,oi.* from orders o join order_items oi on(o.id=oi.order_id) join customers c on(o.customer_id=c.id) where c.name='Hope Crosby' ;
--10
select p.product_name,pa.unit_price,oi.quantity from product_availability pa join order_items oi on(pa.prod_id=oi.product_id) join products p on(oi.product_id=p.id)join orders o on(o.id=oi.order_id) where o.order_reference='ORD006'and oi.supplier_id=pa.supp_id ;
--11
select c.name,o.order_reference,o.order_date, p.product_name,s.supplier_name,oi.quantity from orders o join order_items oi on(o.id=oi.order_id) join customers c on(o.customer_id=c.id) join products p on(oi.product_id=p.id)join suppliers s on (oi.supplier_id=s.id) ;
--12
select distinct c.name from customers c join orders o on (o.customer_id=c.id)join order_items oi on(o.id=oi.order_id) join suppliers s on(s.id=oi.supplier_id) where s.country='China'
--13
select c.name,o.order_reference,o.order_date,sum(oi.quantity*pa.unit_price) as total_order from orders o join order_items oi on(o.id=oi.order_id) join customers c on(o.customer_id=c.id) join product_availability pa on(oi.product_id=pa.prod_id) group by o.id, c.name order by total_order desc;
```

When you have finished all of the questions - open a pull request with your answers to the `Databases-Homework` repository.
Expand Down
33 changes: 33 additions & 0 deletions week-2/mandatory/3-api/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const express = require("express");
const app = express();
const { Pool } = require('pg');

const pool = new Pool({
user: 'postgres',
host: 'localhost',
database: 'cyf_ecommerce',
password: 'allatif977A',
port: 5432
});

app.get("/customers", function(req, res) {
pool.query('SELECT * FROM customers', (error, result) => {
res.json(result.rows);
});
});
app.get("/suppliers", function(req, res) {
pool.query('SELECT * FROM suppliers', (error, result) => {
res.json(result.rows);
});
});
app.get("/products", function(req, res) {
pool.query('select p.product_name,pa.unit_price,s.supplier_name'+
' from products p join product_availability pa on(p.id=pa.prod_id)'+
'join suppliers s on (pa.supp_id=s.id) ;', (error, result) => {
res.json(result.rows);
});
});

app.listen(3000, function() {
console.log("Server is listening on port 3000. Ready to accept requests!");
});
258 changes: 258 additions & 0 deletions week-3/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,258 @@
const express = require("express");
const app = express();
const { Pool } = require('pg');
const bodyParser = require("body-parser");
app.use(bodyParser.json());
let supplierIdArr;
let productIdArr;
let customersIdArr;

const pool = new Pool({
user: 'postgres',
host: 'localhost',
database: 'cyf_ecommerce',
password: 'allatif977A',
port: 5432
});
pool.query('SELECT * FROM suppliers', (error, result) => {
supplierIdArr= result.rows.map(r =>r.id);})

pool.query('SELECT * FROM products', (error, result) => {
productIdArr= result.rows.map(r =>r.id);})

pool.query('SELECT * FROM customers', (error, result) => {
customersIdArr= result.rows.map(r =>r.id);})

app.get("/customers", function(req, res) {
pool.query('SELECT * FROM customers', (error, result) => {
res.json(result.rows);
});
});

app.get("/customers/by_name/:name", function(req, res) {
const cudtomerName=req.params.name.toLowerCase();
pool.query("SELECT * FROM customers where lower(name) like '%'||$1||'%'",[cudtomerName], (error, result) => {
res.json(result.rows);
});
});

app.post("/suppliers" ,function (req,res){
const newName=req.body.name;
const newCountry=req.body.country;

pool.query("SELECT 1 FROM suppliers WHERE supplier_name=$1", [newName],
(err, result) => {
if (result.rowCount > 0) { // note the use of result.rowCount
return res
.status(400)
.send("A supplier with that name already exists!");
} else {
pool.query("insert into suppliers (supplier_name,country )"+
"values($1,$2) returning id",[newName ,newCountry],(error,result)=> {
if ((error)== undefined){
//res.send("New customer added.");
//res.json(result.rows[0].id);
res.send("New supplier added.");
}
else {
res.status(400).send("wrong request "+error)
console.log(error);}
});
}})
});

// delete order item
app.delete("/order_items/:id" ,function (req,res){
const orderId=parseInt( req.params.id);

pool.query("delete from order_items where id=$1"
,[orderId],(error)=> {
if ((error)== undefined){

res.send("order_items "+orderId+" deleted.");
}
});
});
app.get("/suppliers", function(req, res) {
pool.query('SELECT * FROM suppliers', (error, result) => {
res.json(result.rows);
});
});
// app.get("/products", function(req, res) {
// pool.query('select p.product_name,pa.unit_price,s.supplier_name'+
// ' from products p join product_availability pa on(p.id=pa.prod_id)'+
// 'join suppliers s on (pa.supp_id=s.id) ;', (error, result) => {
// res.json(result.rows);
// });
// });


//Homework

//filter the list of products

app.get("/products", function(req, res) {
const searchProduct = req.query.name;
console.log(searchProduct);
if (searchProduct!=undefined)
pool.query("select p.product_name,pa.unit_price,s.supplier_name"+
' from products p join product_availability pa on(p.id=pa.prod_id)'+
"join suppliers s on (pa.supp_id=s.id) where lower(p.product_name) like '%'||$1||'%'",[searchProduct.toLowerCase()], (error, result) => {
res.json(result.rows);
})
else
pool.query('select p.product_name,pa.unit_price,s.supplier_name'+
' from products p join product_availability pa on(p.id=pa.prod_id)'+
'join suppliers s on (pa.supp_id=s.id) ;', (error, result) => {
res.json(result.rows);
});

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could avoid repetition by concatenating the "where" clause to the main query, rather than having 2 completely separate strings.


});
//new GET endpoint `/customers/:customerId`

app.get("/customers/:customerId", function(req, res) {
const cudtomerId=parseInt(req.params.customerId);
pool.query('SELECT * FROM customers where id =$1',[cudtomerId], (error, result) => {
res.json(result.rows[0]);
});
});
//new POST endpoint `/customers`

app.post("/customers" ,function (req,res){
const newName=req.body.name;
const newCity=req.body.city;
const newAdd=req.body.address;
const newCountry=req.body.country;

pool.query("insert into customers (name,city ,address,country)"+
"values($1,$2,$3,$4) returning id",[newName ,newCity ,newAdd,newCountry],(error,result)=> {
if ((error)== undefined){
//res.send("New customer added.");
res.json(result.rows[0].id);
//res.send("New customer added.");
}
else {
res.status(400).send("wrong request "+error)
}
});
});

// new POST endpoint `/products`
app.post("/products" ,function (req,res){
const newName=req.body.name;

pool.query("insert into products (product_name)"+
"values($1) returning id",[newName ],(error,result)=> {
if ((error)== undefined){
//res.send("New customer added.");
res.json(result.rows[0].id);
//res.send("New customer added.");
}
else {
res.status(400).send("wrong request "+error)
}
});
});

//new POST endpoint `/availability`
app.post("/availability" ,function (req,res){
const productId=parseInt( req.body.productId);
const supplierId=parseInt(req.body.supplierId);
const price=parseInt(req.body.price);
if (price>0 && productIdArr.includes(productId) && supplierIdArr.includes(supplierId)){
pool.query("insert into product_availability "+
"values($1,$2,$3) ",[productId,supplierId,price ],(error,result)=> {
if ((error)== undefined){
res.send("New product_availability added.");
// res.json(result.rows[0]);
//res.send("New customer added.");
}
else {
res.status(400).send("wrong request "+error)
}
});
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your idea of creating an array up front to check if the product id exists in the product table is interesting. The model answers we have been given suggest either making a query to the database inside the function or relying on foreign key constraints. I think that relying on foreign key constraints is the most common approach - if they have been set up correctly then pool.query will return a foreign key constraint error, which you can then return in the response. But what you have done is very similar to an in-memory cache which Postgres and other databases can use. It's not a bad idea, but in a real life scenario, you would probably rely on improving the inbuilt database cache to improve performance rather than creating the in-memory array yourself.

else
res.status(400).send("the price must be positive and the id of the product and the suppliere must be existed ")
});


app.post("/customers/:customerId/orders" ,function (req,res){
const orderDate= req.body.orderDate;
const orderRef=req.body.orderRef;
const customerId=parseInt(req.params.customerId);
if (customersIdArr.includes(customerId) ){
pool.query("insert into orders (order_date,order_reference,customer_id) "+
"values($1,$2,$3) ",[orderDate,orderRef,customerId ],(error,result)=> {
if ((error)== undefined){
res.send("New order added.");
// res.json(result.rows[0]);
//res.send("New customer added.");
}
else {
res.status(400).send("wrong request "+error)
}
});
}
else
res.status(400).send("The id of the customer must be existed ")
});


//PUT endpoint `/customers/:customerId`
app.put("/customers/:customerId" ,function (req,res){
const customerId=parseInt( req.params.customerId);
const newName=req.body.name;
const newCity=req.body.city;
const newAdd=req.body.address;
const newCountry=req.body.country;
if (customersIdArr.includes(customerId) ){
pool.query("update customers set name=$1 ,city =$2,address=$3 ,country=$4"+
"where id =$5"
,[newName,newCity ,newAdd,newCountry,customerId],(error)=> {
if ((error)== undefined){

res.send("customer "+customerId+" updated.");
}
});
}else
res.status(400).send("This id "+customerId +" is not existed ")
});

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my previous comment about making a query to the database rather than using an in-memory array.


//Delete order
app.delete("/orders/:orderId" ,function (req,res){
const orderId=parseInt( req.params.orderId);

pool.query("delete from order_items where order_id=$1"
,[orderId],(error)=> {
if ((error)== undefined){
pool.query("delete from orders where id=$1"
,[orderId],(error)=> {
if ((error)== undefined){

res.send("order "+orderId+" is deleted.");
}
});

}
});

});

//get all orders of specific customer
app.get("/customers/:customerId/orders", function(req, res) {
const cudtomerId=parseInt(req.params.customerId);
pool.query(' select o.order_reference,o.order_date,p.product_name,oi.quantity,s.supplier_name,pa.unit_price '+
' from orders o join order_items oi on(o.id=oi.order_id)'+
' join product_availability pa on(oi.product_id=pa.prod_id and oi.supplier_id=pa.supp_id)'+
' join products p on(p.id=pa.prod_id)'+
' join suppliers s on(s.id=pa.supp_id)'+

' where o.customer_id=$1 ',[cudtomerId], (error, result) => {
res.json(result.rows);
});
});

app.listen(3000, function() {
console.log("Server is listening on port 3000. Ready to accept requests!");
});
Copy link

@KarenPudner KarenPudner Sep 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have missed out the last but one task - to delete a customer.
Also, ideally you should handle the error case in each function and also return an appropriate status code for the successful responses and the error responses. You have used a 400 error in some cases - if the database has returned an error this is usually a 500 error, unless the error message indicates that the user has made a mistake, i.e. violating a foreign key constraint.