-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature db update #22
Changes from all commits
19164ab
f6d9327
9699426
103451c
c7a0367
2413794
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
node_modules | ||
src/data/* | ||
data/* | ||
.vscode |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,9 @@ | |
* Author: Sandro Speth | ||
* Author: Tobias Wältken | ||
*/ | ||
|
||
/* jslint esversion: 6 */ | ||
|
||
// Imports | ||
const sqlite3 = require('sqlite3'); | ||
const express = require('express'); | ||
|
@@ -17,10 +20,8 @@ const dirname = fs.realpathSync('./'); | |
// Database | ||
var db = new sqlite3.Database(dirname + '/data/history.db'); | ||
// Arrays | ||
var beverages = JSON.parse(fs.readFileSync(dirname + '/data/beverages.json', 'utf8')); | ||
var auth = JSON.parse(fs.readFileSync(dirname + '/data/auth.json', 'utf8')); | ||
// NodeJS HashMap | ||
var users = new HashMap(JSON.parse(fs.readFileSync(dirname + '/data/users.json', 'utf8'))); | ||
var tokens = new HashMap(); | ||
|
||
/** | ||
|
@@ -43,11 +44,6 @@ function contains(array, item) { | |
return bool; | ||
} | ||
|
||
// Actual wrong method | ||
function isTimePassed(date) { | ||
return !(+(new Date(new Date(date).getTime() + 30000)) > +(new Date())); | ||
} | ||
|
||
/** | ||
* This function wraps a given middleware function with a check for the user | ||
* tokens in the request to reduce code clutter. | ||
|
@@ -152,31 +148,31 @@ api.get('/token', adminAccess(function (req, res) { | |
api.post('/orders', userAccess(function (req, res) { | ||
let user = req.query.user; | ||
let beverage = req.query.beverage; | ||
|
||
if (user == undefined || beverage == undefined || | ||
user === '' || beverage === '' || !contains(users.keys(), user) || !contains(beverages, beverage)) { | ||
user === '' || beverage === '') { | ||
res.status(400).end('Fail to order the beverage for the user'); | ||
return; | ||
} else { | ||
let cost = 0; | ||
for (i = 0; i < beverages.length; i++) { | ||
if (beverages[i].name === beverage) { | ||
cost = beverages[i].price; | ||
beverages[i].count--; | ||
fs.writeFile(dirname + '/data/beverages.json', JSON.stringify(beverages), 'utf8', function(error) { | ||
console.log('[API] [FAIL] can\'t write /data/beverages.json'); | ||
}); | ||
break; | ||
let stmt = db.prepare("SELECT price, stock FROM Beverages WHERE name = ?;"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Name it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should be new issue There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
stmt.get(beverage, function(err, result) { | ||
if (result == undefined) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Check There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
console.log('[API] [FAIL] can\'t find beverage '+beverage); | ||
return; | ||
} | ||
} | ||
|
||
users.get(user).balance -= cost; | ||
fs.writeFile(dirname + '/data/users.json', JSON.stringify(users), 'utf8'); | ||
|
||
var stmt = db.prepare("INSERT INTO History(id, user, reason, amount, timestamp) VALUES (?, ?, ?, ?, ?);"); | ||
stmt.run(uuidv4(), user, beverage, -cost, new Date().toUTCString()); | ||
stmt.finalize(); | ||
|
||
let cost = result.price; | ||
|
||
let stmt1 = db.prepare("UPDATE Beverages SET stock = stock-1 WHERE name = ?;"); | ||
stmt1.run(beverage); | ||
|
||
let stmt2 = db.prepare("UPDATE Users SET balance = balance - ? WHERE name = ?;"); | ||
stmt2.run(cost, user); | ||
|
||
var stmt3 = db.prepare("INSERT INTO History(id, user, reason, amount, beverage, beverage_count) VALUES (?, ?, ?, ?, ?, ?);"); | ||
stmt3.run(uuidv4(), user, beverage, -cost, beverage, 1); | ||
}); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [important] missing the check if the given username exists! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. checking if user exists is needed in more than one method and should be as simple as a method call. The problem is, that sql statements work with callbacks. I don't have a good solution yet for this. => should be a new issue There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
||
|
||
res.sendStatus(200); | ||
} | ||
})); | ||
|
@@ -189,7 +185,8 @@ api.get('/orders', userAccess(function (req, res) { | |
} | ||
|
||
let histories = []; | ||
db.each("SELECT id, user, reason, amount, timestamp FROM History LIMIT " + limit, function(err, row) { | ||
var stmt = db.prepare("SELECT id, user, reason, amount, beverage, beverage_count, timestamp FROM History ORDER BY timestamp DESC LIMIT ?;"); | ||
stmt.each(limit, function(err, row) { | ||
histories.push(row); | ||
}, function() { | ||
res.status(200).end(JSON.stringify(histories)); | ||
|
@@ -199,15 +196,16 @@ api.get('/orders', userAccess(function (req, res) { | |
api.get('/orders/:userId', userAccess(function (req, res) { | ||
let userId = req.params.userId; | ||
let limit = req.query.limit; | ||
if (userId === undefined || userId === '' || !users.has(userId)) { | ||
if (userId === undefined || userId === '') { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. missing the check if the given username exists! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
res.status(404).end('User not found'); | ||
return; | ||
} else { | ||
if (limit === undefined) { | ||
limit = 1000; | ||
} | ||
let userHistories = []; | ||
db.each("SELECT id, user, reason, amount, timestamp FROM History WHERE user = '" + userId + "' LIMIT " + limit, function(err, row) { | ||
var stmt = db.prepare("SELECT id, user, reason, amount, beverage, beverage_count, timestamp FROM History WHERE user = ? ORDER BY timestamp DESC LIMIT ?;"); | ||
stmt.each(userId, limit, function(err, row) { | ||
userHistories.push(row); | ||
}, function() { | ||
res.status(200).end(JSON.stringify(userHistories)); | ||
|
@@ -216,51 +214,82 @@ api.get('/orders/:userId', userAccess(function (req, res) { | |
})); | ||
|
||
api.delete('/orders/:orderId', function (req, res) { | ||
// FIXME think about using userAccess, adminAcces or keep it locally when | ||
// solving Issue#5 (https://github.com/spethso/Drinklist/issues/5) | ||
let orderId = req.params.orderId; | ||
let token = req.header('X-Auth-Token'); | ||
if (!tokens.has(token)) { | ||
console.log('[API] [WARN] Wrong token ' + token); | ||
res.status(403).end('Forbidden'); | ||
return; | ||
} | ||
//if (!tokens.get(token).root) { | ||
// res.status(401).end('Unauthorized'); | ||
// return; | ||
//} | ||
if (orderId != undefined && orderId != '') { | ||
let deleted = true; //TODO check for error in sql | ||
|
||
var stmt = db.prepare("DELETE FROM History WHERE id == ?;"); | ||
stmt.run(orderId); | ||
stmt.finalize(); | ||
let stmt = db.prepare("SELECT timestamp > (DATETIME('now', '-30 seconds', 'localtime')) as fresh, id, user, amount, beverage, beverage_count, timestamp FROM History WHERE id = ? LIMIT 1;"); | ||
stmt.get(orderId, function(err, result) { | ||
if (result == undefined) { | ||
// no order to delete! | ||
return; | ||
} | ||
|
||
if (deleted) { | ||
res.sendStatus(200); | ||
} else { | ||
res.sendStatus(400); | ||
} | ||
if (result.fresh == false && !tokens.get(token).root) { | ||
// too late to delete | ||
res.sendStatus(400); | ||
return; | ||
} | ||
|
||
function updateUserAndBeverage(result) { | ||
if (result.amount !== 0 && result.user !== '') { | ||
let stmt = db.prepare("UPDATE Users SET balance = balance - ? WHERE name = ?;"); | ||
stmt.run(result.amount, result.user); | ||
} | ||
|
||
if (result.beverage !== '') { | ||
let stmt = db.prepare("UPDATE Beverages SET stock = stock + ? WHERE name = ?"); | ||
stmt.run(result.beverage_count, result.beverage); | ||
} | ||
} | ||
|
||
if (result.fresh) { | ||
updateUserAndBeverage(result); | ||
var stmt = db.prepare("DELETE FROM History WHERE id = ?;"); | ||
stmt.run(orderId); | ||
stmt.finalize(); | ||
res.sendStatus(200); | ||
} else { | ||
let stmt = db.prepare("SELECT * FROM History WHERE reason = ? LIMIT 1;"); | ||
stmt.get(result.id, function(err, existing) { | ||
if (existing == undefined) { // prevent double undo | ||
updateUserAndBeverage(result); | ||
let stmt = db.prepare("INSERT INTO History(id, user, reason, amount, beverage, beverage_count) VALUES (?, ?, ?, ?, ?, ?);"); | ||
stmt.run(uuidv4(), result.user, result.id, -result.amount, result.beverage, -result.beverage_count); | ||
res.sendStatus(200); | ||
} else { | ||
// double undo error code here... | ||
res.sendStatus(500); | ||
} | ||
}); | ||
} | ||
}); | ||
} else { | ||
res.sendStatus(400); | ||
} | ||
}); | ||
|
||
api.get('/beverages', userAccess(function (req, res) { | ||
res.status(200).end(JSON.stringify(beverages)); | ||
let beverages = []; | ||
var stmt = db.prepare("SELECT name, stock, price FROM Beverages ORDER BY name;"); | ||
stmt.each(function(err, row) { | ||
beverages.push(row); | ||
}, function() { | ||
res.status(200).end(JSON.stringify(beverages)); | ||
}); | ||
})); | ||
|
||
api.post('/beverages', adminAccess(function (req, res) { | ||
let bev = req.query.beverage; | ||
let price = req.query.price; | ||
if (bev != undefined && price != undefined && bev != '') { | ||
let beverage = { | ||
name: bev, | ||
price: price, | ||
count: 0 | ||
}; | ||
beverages.push(beverage); | ||
fs.writeFile(dirname + '/data/beverages.json', JSON.stringify(beverages), 'utf8'); | ||
let stmt = db.prepare("INSERT INTO Beverages (name, price) VALUES (?, ?)"); | ||
stmt.run(bev, price); | ||
res.sendStatus(200); | ||
} else { | ||
throw new Error('Test Error'); | ||
|
@@ -272,19 +301,13 @@ api.patch('/beverages/:beverage', adminAccess(function (req, res) { | |
let price = req.query.price; | ||
let count = req.query.count; | ||
if (bev != undefined && bev != '') { | ||
for (let i = 0; i < beverages.length; i++) { | ||
let beverage = beverages[i]; | ||
console.log(beverage); | ||
if (beverage.name == bev) { | ||
if (price != undefined) { | ||
beverage.price = price; | ||
} | ||
if (count != undefined) { | ||
beverage.count += new Number(count); | ||
} | ||
fs.writeFile(dirname + '/data/beverages.json', JSON.stringify(beverages), 'utf8'); | ||
break; | ||
} | ||
if (price != undefined) { | ||
let stmt = db.prepere("UPDATE Beverages SET price = ? WHERE name = ?;"); | ||
stmt.run(parseInt(price), bev); | ||
} | ||
if (count != undefined) { | ||
let stmt = db.prepere("UPDATE Beverages SET stock = stock + ? WHERE name = ?;"); | ||
stmt.run(parseInt(count), bev); | ||
} | ||
res.sendStatus(200); | ||
} else { | ||
|
@@ -295,16 +318,8 @@ api.patch('/beverages/:beverage', adminAccess(function (req, res) { | |
api.delete('/beverages/:beverage', adminAccess(function (req, res) { | ||
let bev = req.params.beverage; | ||
if (bev != undefined && bev != '') { | ||
let index = 0; | ||
for (let i = 0; i < beverages.length; i++) { | ||
let beverage = beverages[i]; | ||
if (beverage.name == bev) { | ||
index = i; | ||
break; | ||
} | ||
} | ||
beverages.splice(index, 1); | ||
fs.writeFile(dirname + '/data/beverages.json', JSON.stringify(beverages), 'utf8'); | ||
let stmt = db.prepare("DELETE FROM Beverages WHERE name = ?;"); | ||
stmt.run(bev); | ||
res.sendStatus(200); | ||
} else { | ||
res.sendStatus(400); | ||
|
@@ -313,31 +328,46 @@ api.delete('/beverages/:beverage', adminAccess(function (req, res) { | |
|
||
api.get('/users', userAccess(function (req, res) { | ||
let token = req.header('X-Auth-Token'); | ||
|
||
let users = []; | ||
var stmt = db.prepare("SELECT name FROM Users ORDER BY name;"); | ||
var stmtAdmin = db.prepare("SELECT name, balance FROM Users ORDER BY name;"); | ||
if (!tokens.get(token).root) { | ||
res.status(200).end(JSON.stringify(users.keys())); | ||
stmt.each(function(err, row) { | ||
users.push(row.name); | ||
}, function() { | ||
res.status(200).end(JSON.stringify(users)); | ||
}); | ||
} else { | ||
res.status(200).end(JSON.stringify(users.values())); | ||
stmtAdmin.each(function(err, row) { | ||
users.push(row); | ||
}, function() { | ||
res.status(200).end(JSON.stringify(users)); | ||
}); | ||
} | ||
})); | ||
|
||
api.get('/users/:userId', userAccess(function (req, res) { | ||
let userId = req.params.userId; | ||
if (userId === undefined || userId === '' || !users.has(userId)) { | ||
var stmt = db.prepare("SELECT name, balance FROM Users WHERE name = ?;"); | ||
if (userId === undefined || userId === '') { | ||
res.status(404).end('User not found'); | ||
} else { | ||
res.status(200).end(JSON.stringify(users.get(userId))); | ||
stmt.get(userId, function(err, result) { | ||
if (result == undefined) { | ||
res.status(404).end('User not found'); | ||
return; | ||
} | ||
res.status(200).end(JSON.stringify(result)); | ||
}); | ||
} | ||
})); | ||
|
||
api.post('/users/:userId', adminAccess(function (req, res) { | ||
let userId = req.params.userId; | ||
if (userId != undefined && userId != '') { | ||
let user = { | ||
name: userId, | ||
balance: 0 | ||
}; | ||
users.set(userId, user); | ||
fs.writeFile(dirname + '/data/users.json', JSON.stringify(users), 'utf8'); | ||
let stmt = db.prepare("INSERT INTO Users (name) VALUES (?);"); | ||
stmt.run(userId); | ||
res.sendStatus(200); | ||
} else { | ||
res.sendStatus(400); | ||
|
@@ -346,11 +376,10 @@ api.post('/users/:userId', adminAccess(function (req, res) { | |
|
||
api.delete('/users/:userId', adminAccess(function (req, res) { | ||
let userId = req.params.userId; | ||
if (userId != undefined && userId != '' && users.has(userId)) { | ||
let user = users.get(userId); | ||
users.remove(userId); | ||
fs.writeFile(dirname + '/data/users.json', JSON.stringify(users), 'utf8'); | ||
res.status(200).send(JSON.stringify(user)); | ||
if (userId != undefined && userId != '') { | ||
let stmt = db.prepare("DELETE FROM Users WHERE name = ?;"); | ||
stmt.run(userId); | ||
res.sendStatus(200); | ||
} else { | ||
res.sendStatus(400); | ||
} | ||
|
@@ -361,15 +390,15 @@ api.patch('/users/:userId', adminAccess(function (req, res) { | |
let amount = req.query.amount; | ||
let reason = req.query.reason; | ||
if (userId != undefined && amount != undefined && reason != undefined | ||
&& userId != '' && reason != '' && amount != '' && users.has(userId)) { | ||
&& userId != '' && reason != '' && amount != '') { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add user check There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
amount = new Number(amount); | ||
var stmt = db.prepare("INSERT INTO History(id, user, reason, amount, timestamp) VALUES (?, ?, ?, ?, ?);"); | ||
stmt.run(uuidv4(), userId, reason, amount, new Date().toUTCString()); | ||
|
||
var stmt = db.prepare("INSERT INTO History(id, user, reason, amount) VALUES (?, ?, ?, ?);"); | ||
stmt.run(uuidv4(), userId, reason, amount); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. rename There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
stmt.finalize(); | ||
|
||
users.get(userId).balance += amount; | ||
fs.writeFile(dirname + '/data/users.json', JSON.stringify(users), 'utf8'); | ||
let stmt2 = db.prepare("UPDATE Users SET balance = balance + ? WHERE name = ?;"); | ||
stmt2.run(amount, userId); | ||
res.sendStatus(200); | ||
} else { | ||
res.sendStatus(400); | ||
|
@@ -388,4 +417,4 @@ api.post('/logout', function (req, res) { | |
api.use(function (err, req, res, next) { | ||
console.error(err.stack); | ||
res.status(500).send('We messed up, sry!'); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe create/decide on project wide jslint settings to enforce a uniform coding style
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be another issue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is now #23