Added countries & cities REST services

This commit is contained in:
fkereki
2018-06-07 00:38:16 -04:00
parent abaeb6c089
commit 4101f57b25
7 changed files with 743 additions and 43 deletions
+171
View File
@@ -0,0 +1,171 @@
/* @flow */
"use strict";
// eslint-disable
const getCity = async (res: any, dbConn: any, city: string) => {
try {
res.set("Connection", "close");
let sqlQuery = "";
sqlQuery = `
SELECT *
FROM cities
WHERE cityId=?
`;
const cities = await dbConn.query(sqlQuery, [city]);
if (cities.length === 0) {
res.status(404).send("City not found");
} else {
res
.status(200)
.set("Content-Type", "application/json")
.send(JSON.stringify(cities));
}
} catch (e) {
res.status(500).send("Server error");
}
};
const deleteCity = async (res: any, dbConn: any, city: string) => {
try {
res.set("Connection", "close");
const deleteCity = `
DELETE FROM cities
WHERE cityId=?
`;
const result = await dbConn.query(deleteCity, [city]);
if (result.info.affectedRows > 0) {
res.status(204).send();
} else {
res.status(404).send("City not found");
}
} catch (e) {
res.status(500).send("Server error");
}
};
const postCity = async (
res: any,
dbConn: any,
name: string,
latitude: number,
longitude: number,
population: number,
country: string,
region: string
) => {
res.set("Connection", "close");
if (!name) {
res.status(400).send("Missing name");
return;
}
try {
const sqlRegion = `
SELECT 1
FROM regions
WHERE countryCode=? AND regionCode=?
`;
const regions = await dbConn.query(sqlRegion, [country, region]);
if (regions.length === 0) {
res.status(403).send("Region must exist");
return;
}
const sqlGetId = `
SELECT MAX(CAST(cityId AS INTEGER)) AS maxr
FROM cities
`;
const cities = await dbConn.query(sqlGetId);
const newId = cities.length === 0 ? 1 : 1 + Number(cities[0].maxr);
const sqlAddCity = `
INSERT INTO cities SET
cityId=?
cityName=?,
latitude=?,
longitude=?,
population=?,
countryCode=?,
regionCode=?
`;
const result = await dbConn.query(sqlAddCity, [
newId,
name,
latitude,
longitude,
population,
country,
region
]);
if (result.info.affectedRows > 0) {
res
.status(201)
.header("Location", `/cities/${newId}`)
.send("City created");
} else {
res.status(409).send("City not created");
}
} catch (e) {
res.status(500).send("Server error");
}
};
const putCity = async (
res: any,
dbConn: any,
city: string,
name: string,
latitude: number,
longitude: number,
population: number,
country: string,
region: string
) => {
res.set("Connection", "close");
if (!name) {
res.status(400).send("Missing name");
return;
}
try {
const sqlUpdateCity = `
UPDATE cities
SET
cityName=?,
latitude=?,
longitude=?,
population=?,
countryCode=?,
regionCode=?
WHERE cityId=?
`;
const result = await dbConn.query(sqlUpdateCity, [
name,
latitude,
longitude,
population,
country,
region,
city
]);
if (result.info.affectedRows > 0) {
res.status(204).send();
} else {
res.status(409).send("City not updated");
}
} catch (e) {
res.status(500).send("Server error");
}
};
module.exports = { getCity, deleteCity, postCity, putCity };
+107
View File
@@ -0,0 +1,107 @@
/* @flow */
"use strict";
const getCountry = async (res: any, dbConn: any, country: ?string) => {
try {
res.set("Connection", "close");
let sqlQuery = "";
let countries;
if (country == null) {
sqlQuery = `
SELECT cc.*
FROM countries cc
ORDER BY cc.countryCode
`;
countries = await dbConn.query(sqlQuery);
} else {
sqlQuery = `
SELECT cc.*
FROM countries cc
WHERE cc.countryCode=?
`;
countries = await dbConn.query(sqlQuery, [country]);
}
if (countries.length > 0) {
res
.status(200)
.set("Content-Type", "application/json")
.send(JSON.stringify(countries));
} else {
res.status(404).send("Not found");
}
} catch (e) {
res.status(500).send("Server error");
}
};
const deleteCountry = async (res: any, dbConn: any, country: string) => {
try {
res.set("Connection", "close");
const sqlRegions = `
SELECT 1 FROM regions
WHERE countryCode=?
LIMIT 1
`;
const regions = await dbConn.query(sqlRegions, [country]);
if (regions.length > 0) {
res.status(405).send("Cannot delete a country with regions");
return;
}
const deleteCountry = `
DELETE FROM countries
WHERE countryCode=?
`;
const result = await dbConn.query(deleteCountry, [country]);
if (result.info.affectedRows > 0) {
res.status(204).send();
} else {
res.status(404).send("Country not found");
}
} catch (e) {
res.status(500).send("Server error");
}
};
const putCountry = async (
res: any,
dbConn: any,
country: string,
name: string
) => {
res.set("Connection", "close");
if (!name) {
res.status(400).send("Missing name");
return;
}
try {
const sqlInsertOrUpdateCountry = `
INSERT INTO countries (countryCode, countryName)
VALUES (?, ?)
ON DUPLICATE KEY UPDATE
countryName = ?
`;
const result = await dbConn.query(sqlInsertOrUpdateCountry, [
country,
name,
name
]);
if (result.info.affectedRows > 0) {
res.status(204).send();
} else {
res.status(409).send("Country not updated");
}
} catch (e) {
res.status(500).send("Server error");
}
};
module.exports = { getCountry, deleteCountry, putCountry };
+53 -37
View File
@@ -8,7 +8,10 @@ const getRegion = async (
region: ?string
) => {
try {
res.set("Connection", "close");
let sqlQuery = "";
let regions;
if (country == null) {
sqlQuery = `
SELECT rr.*
@@ -16,17 +19,19 @@ const getRegion = async (
JOIN countries cc
ON cc.countryCode=rr.countryCode
ORDER BY cc.countryCode, rr.regionCode
`;
`;
regions = await dbConn.query(sqlQuery);
} else if (region == null) {
sqlQuery = `
SELECT 1
FROM countries
WHERE countryCode="${country}"
WHERE countryCode=?
`;
const countries = await dbConn.query(sqlQuery);
const countries = await dbConn.query(sqlQuery, [country]);
if (countries.length === 0) {
return res.status(404).send("Country not found");
res.status(404).send("Country not found");
return;
}
sqlQuery = `
@@ -34,23 +39,22 @@ const getRegion = async (
FROM regions rr
JOIN countries cc
ON cc.countryCode=rr.countryCode
WHERE rr.countryCode="${country}"
WHERE rr.countryCode=?
ORDER BY rr.regionCode
`;
regions = await dbConn.query(sqlQuery, [country]);
} else {
sqlQuery = `
SELECT rr.*
FROM regions rr
JOIN countries cc
ON cc.countryCode=rr.countryCode
WHERE rr.countryCode="${country}"
AND rr.regionCode="${region}"
WHERE rr.countryCode=?
AND rr.regionCode=?
`;
regions = await dbConn.query(sqlQuery, [country, region]);
}
res.set("Connection", "close");
const regions = await dbConn.query(sqlQuery);
if (regions.length > 0 || region === null) {
res
.status(200)
@@ -75,26 +79,27 @@ const deleteRegion = async (
const sqlCities = `
SELECT 1 FROM cities
WHERE countryCode="${country}"
AND regionCode="${region}"
WHERE countryCode=?
AND regionCode=?
LIMIT 1
`;
const cities = await dbConn.query(sqlCities);
const cities = await dbConn.query(sqlCities, [country, region]);
if (cities.length > 0) {
res.status(405).send("Cannot delete a region with cities");
} else {
const deleteRegion = `
return;
}
const deleteRegion = `
DELETE FROM regions
WHERE countryCode="${country}"
AND regionCode="${region}"
WHERE countryCode=?
AND regionCode=?
`;
const result = await dbConn.query(deleteRegion);
if (result.info.affectedRows > 0) {
res.status(204).send();
} else {
res.status(404).send("Region not found");
}
const result = await dbConn.query(deleteRegion, [country, region]);
if (result.info.affectedRows > 0) {
res.status(204).send();
} else {
res.status(404).send("Region not found");
}
} catch (e) {
res.status(500).send("Server error");
@@ -110,37 +115,43 @@ const postRegion = async (
res.set("Connection", "close");
if (!name) {
return res.status(400).send("Missing name");
res.status(400).send("Missing name");
return;
}
try {
const sqlCountry = `
SELECT 1
FROM countries
WHERE countryCode="${country}"
WHERE countryCode=?
`;
const countries = await dbConn.query(sqlCountry);
const countries = await dbConn.query(sqlCountry, [country]);
if (countries.length === 0) {
res.status(403).send("Country must exist");
return;
}
const sqlGetId = `
SELECT MAX(CAST(regionCode AS INTEGER)) AS maxr
FROM regions
WHERE countryCode="${country}"
WHERE countryCode=?
`;
const regions = await dbConn.query(sqlGetId);
const regions = await dbConn.query(sqlGetId, [country]);
const newId =
regions.length === 0 ? 1 : 1 + Number(regions[0].maxr);
const sqlAddRegion = `
INSERT INTO regions SET
countryCode="${country}",
regionCode="${newId}",
regionName="${name}"
countryCode=?,
regionCode=?,
regionName=?
`;
const result = await dbConn.query(sqlAddRegion);
const result = await dbConn.query(sqlAddRegion, [
country,
newId,
name
]);
if (result.info.affectedRows > 0) {
res
.status(201)
@@ -164,18 +175,23 @@ const putRegion = async (
res.set("Connection", "close");
if (!name) {
return res.status(400).send("Missing name");
res.status(400).send("Missing name");
return;
}
try {
const sqlUpdateRegion = `
UPDATE regions
SET regionName="${name}"
WHERE countryCode="${country}"
AND regionCode="${region}"
SET regionName=?
WHERE countryCode=?
AND regionCode=?
`;
const result = await dbConn.query(sqlUpdateRegion);
const result = await dbConn.query(sqlUpdateRegion, [
name,
country,
region
]);
if (result.info.affectedRows > 0) {
res.status(204).send();
+67 -3
View File
@@ -23,6 +23,26 @@ app.use(bodyParser.urlencoded({ extended: false }));
and the logic for validating a JWT, as shown earlier
*/
const {
getCountry,
deleteCountry,
putCountry
} = require("./restful_countries.js");
app.get("/countries", (req, res) => getCountry(res, dbConn));
app.get("/countries/:country", (req, res) =>
getCountry(res, dbConn, req.params.country)
);
app.delete("/countries/:country", (req, res) =>
deleteCountry(res, dbConn, req.params.country)
);
app.put("/countries/:country", (req, res) =>
putCountry(res, dbConn, req.params.country, req.body.name)
);
const {
getRegion,
deleteRegion,
@@ -30,13 +50,13 @@ const {
putRegion
} = require("./restful_regions.js");
app.get("/regions/", (req, res) => getRegion(res, dbConn));
app.get("/regions", (req, res) => getRegion(res, dbConn));
app.get("/regions/:country/", (req, res) =>
app.get("/regions/:country", (req, res) =>
getRegion(res, dbConn, req.params.country)
);
app.get("/regions/:country/:region/", (req, res) =>
app.get("/regions/:country/:region", (req, res) =>
getRegion(res, dbConn, req.params.country, req.params.region)
);
@@ -58,6 +78,50 @@ app.put("/regions/:country/:region", (req, res) =>
)
);
const {
getCity,
deleteCity,
postCity,
putCity
} = require("./restful_cities.js");
// We do not allow calling /cities to get every city in the world
app.get("/cities/:city", (req, res) =>
getCity(res, dbConn, req.params.city)
);
app.delete("/cities/:city", (req, res) =>
deleteCity(res, dbConn, req.params.city)
);
app.post("/cities/:city", (req, res) =>
postCity(
res,
dbConn,
req.body.name,
req.body.latitude,
req.body.longitude,
req.body.population,
req.body.country,
req.body.region
)
);
app.put("/cities/:city", (req, res) =>
putCity(
res,
dbConn,
req.params.city,
req.body.name,
req.body.latitude,
req.body.longitude,
req.body.population,
req.body.country,
req.body.region
)
);
// eslint-disable-next-line no-unused-vars
app.use((err, req, res, next) => {
console.error("Error....", err.message);
+171
View File
@@ -0,0 +1,171 @@
/* @flow */
"use strict";
// eslint-disable
const getCity = async (res: any, dbConn: any, city: string) => {
try {
res.set("Connection", "close");
let sqlQuery = "";
sqlQuery = `
SELECT *
FROM cities
WHERE cityId=?
`;
const cities = await dbConn.query(sqlQuery, [city]);
if (cities.length === 0) {
res.status(404).send("City not found");
} else {
res
.status(200)
.set("Content-Type", "application/json")
.send(JSON.stringify(cities));
}
} catch (e) {
res.status(500).send("Server error");
}
};
const deleteCity = async (res: any, dbConn: any, city: string) => {
try {
res.set("Connection", "close");
const deleteCity = `
DELETE FROM cities
WHERE cityId=?
`;
const result = await dbConn.query(deleteCity, [city]);
if (result.info.affectedRows > 0) {
res.status(204).send();
} else {
res.status(404).send("City not found");
}
} catch (e) {
res.status(500).send("Server error");
}
};
const postCity = async (
res: any,
dbConn: any,
name: string,
latitude: number,
longitude: number,
population: number,
country: string,
region: string
) => {
res.set("Connection", "close");
if (!name) {
res.status(400).send("Missing name");
return;
}
try {
const sqlRegion = `
SELECT 1
FROM regions
WHERE countryCode=? AND regionCode=?
`;
const regions = await dbConn.query(sqlRegion, [country, region]);
if (regions.length === 0) {
res.status(403).send("Region must exist");
return;
}
const sqlGetId = `
SELECT MAX(CAST(cityId AS INTEGER)) AS maxr
FROM cities
`;
const cities = await dbConn.query(sqlGetId);
const newId = cities.length === 0 ? 1 : 1 + Number(cities[0].maxr);
const sqlAddCity = `
INSERT INTO cities SET
cityId=?
cityName=?,
latitude=?,
longitude=?,
population=?,
countryCode=?,
regionCode=?
`;
const result = await dbConn.query(sqlAddCity, [
newId,
name,
latitude,
longitude,
population,
country,
region
]);
if (result.info.affectedRows > 0) {
res
.status(201)
.header("Location", `/cities/${newId}`)
.send("City created");
} else {
res.status(409).send("City not created");
}
} catch (e) {
res.status(500).send("Server error");
}
};
const putCity = async (
res: any,
dbConn: any,
city: string,
name: string,
latitude: number,
longitude: number,
population: number,
country: string,
region: string
) => {
res.set("Connection", "close");
if (!name) {
res.status(400).send("Missing name");
return;
}
try {
const sqlUpdateCity = `
UPDATE cities
SET
cityName=?,
latitude=?,
longitude=?,
population=?,
countryCode=?,
regionCode=?
WHERE cityId=?
`;
const result = await dbConn.query(sqlUpdateCity, [
name,
latitude,
longitude,
population,
country,
region,
city
]);
if (result.info.affectedRows > 0) {
res.status(204).send();
} else {
res.status(409).send("City not updated");
}
} catch (e) {
res.status(500).send("Server error");
}
};
module.exports = { getCity, deleteCity, postCity, putCity };
+107
View File
@@ -0,0 +1,107 @@
/* @flow */
"use strict";
const getCountry = async (res: any, dbConn: any, country: ?string) => {
try {
res.set("Connection", "close");
let sqlQuery = "";
let countries;
if (country == null) {
sqlQuery = `
SELECT cc.*
FROM countries cc
ORDER BY cc.countryCode
`;
countries = await dbConn.query(sqlQuery);
} else {
sqlQuery = `
SELECT cc.*
FROM countries cc
WHERE cc.countryCode=?
`;
countries = await dbConn.query(sqlQuery, [country]);
}
if (countries.length > 0) {
res
.status(200)
.set("Content-Type", "application/json")
.send(JSON.stringify(countries));
} else {
res.status(404).send("Not found");
}
} catch (e) {
res.status(500).send("Server error");
}
};
const deleteCountry = async (res: any, dbConn: any, country: string) => {
try {
res.set("Connection", "close");
const sqlRegions = `
SELECT 1 FROM regions
WHERE countryCode=?
LIMIT 1
`;
const regions = await dbConn.query(sqlRegions, [country]);
if (regions.length > 0) {
res.status(405).send("Cannot delete a country with regions");
return;
}
const deleteCountry = `
DELETE FROM countries
WHERE countryCode=?
`;
const result = await dbConn.query(deleteCountry, [country]);
if (result.info.affectedRows > 0) {
res.status(204).send();
} else {
res.status(404).send("Country not found");
}
} catch (e) {
res.status(500).send("Server error");
}
};
const putCountry = async (
res: any,
dbConn: any,
country: string,
name: string
) => {
res.set("Connection", "close");
if (!name) {
res.status(400).send("Missing name");
return;
}
try {
const sqlInsertOrUpdateCountry = `
INSERT INTO countries (countryCode, countryName)
VALUES (?, ?)
ON DUPLICATE KEY UPDATE
countryName = ?
`;
const result = await dbConn.query(sqlInsertOrUpdateCountry, [
country,
name,
name
]);
if (result.info.affectedRows > 0) {
res.status(204).send();
} else {
res.status(409).send("Country not updated");
}
} catch (e) {
res.status(500).send("Server error");
}
};
module.exports = { getCountry, deleteCountry, putCountry };
+67 -3
View File
@@ -79,6 +79,26 @@ app.use((req, res, next) => {
});
});
const {
getCountry,
deleteCountry,
putCountry
} = require("./restful_countries.js");
app.get("/countries", (req, res) => getCountry(res, dbConn));
app.get("/countries/:country", (req, res) =>
getCountry(res, dbConn, req.params.country)
);
app.delete("/countries/:country", (req, res) =>
deleteCountry(res, dbConn, req.params.country)
);
app.put("/countries/:country", (req, res) =>
putCountry(res, dbConn, req.params.country, req.body.name)
);
const {
getRegion,
deleteRegion,
@@ -86,13 +106,13 @@ const {
putRegion
} = require("./restful_regions.js");
app.get("/regions/", (req, res) => getRegion(res, dbConn));
app.get("/regions", (req, res) => getRegion(res, dbConn));
app.get("/regions/:country/", (req, res) =>
app.get("/regions/:country", (req, res) =>
getRegion(res, dbConn, req.params.country)
);
app.get("/regions/:country/:region/", (req, res) =>
app.get("/regions/:country/:region", (req, res) =>
getRegion(res, dbConn, req.params.country, req.params.region)
);
@@ -114,6 +134,50 @@ app.put("/regions/:country/:region", (req, res) =>
)
);
const {
getCity,
deleteCity,
postCity,
putCity
} = require("./restful_cities.js");
// We do not allow calling /cities to get every city in the world
app.get("/cities/:city", (req, res) =>
getCity(res, dbConn, req.params.city)
);
app.delete("/cities/:city", (req, res) =>
deleteCity(res, dbConn, req.params.city)
);
app.post("/cities/:city", (req, res) =>
postCity(
res,
dbConn,
req.body.name,
req.body.latitude,
req.body.longitude,
req.body.population,
req.body.country,
req.body.region
)
);
app.put("/cities/:city", (req, res) =>
putCity(
res,
dbConn,
req.params.city,
req.body.name,
req.body.latitude,
req.body.longitude,
req.body.population,
req.body.country,
req.body.region
)
);
// eslint-disable-next-line no-unused-vars
app.use((err, req, res, next) => {
console.error("Error....", err.message);