-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathorder.js
169 lines (156 loc) · 5.79 KB
/
order.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
'use strict';
const _ = require('underscore');
//Database functions
const pg = require('pg');
let pool = new pg.Pool({
host: 'localhost',
database: 'booktown'
});
function runQuery(query, argsArray, callback) {
pool.connect((err, client, done) => {
if (err) {
//likely a connection error that will print to console.
done();
throw err;
}
client.query(query, argsArray, (err, results) => {
done(); //call done to release the client to the connection pool.
callback(err, results); //make it the callers responsiblity for checking for query errors.
});
});
}
const yargs = require('yargs');
const args = yargs
.alias('i', 'orderId')
.describe('i', 'order id to operate on')
.alias('b', 'bookId')
.describe('b', 'book id to operate on')
.alias('q', 'quantity')
.describe('q', 'the quantity of the book')
.alias('a', 'action')
.demand('a')
.describe('a', 'action to take [create, addItem, removeItem, updateItem, list, delete]')
.argv;
require('console.table');
function printer(words) {
return function(err, results) {
if (err) {
console.error(err);
} else {
if (words && words !== '') {
console.log(words);
}
if (results.rows.length > 0) {
console.table(results.rows);
}
}
process.exit();
}
}
const json2csv = require('json2csv');
function printCsv(err, results) {
if (err) {
console.error(err);
} else {
console.log(json2csv({
data: results.rows
}));
}
process.exit();
}
function ensureRequired(map, fields, checkers) {
if (fields.length !== checkers.length) {
throw 'invalid fields and checkers';
}
let valid = _.all(fields, (f, i) => {
return checkers[i](map[f]);
});
if (!valid) {
throw 'checkers did not pass'
}
}
function rollback(client) {
client.query('ROLLBACK', function() {
client.end();
});
}
try {
var query;
var params;
switch (args.action) {
case 'create':
query = 'insert into orders (created, creator) values ($1, $2) returning *';
params = [new Date().toISOString(), process.env.USER];
runQuery(query, params, printer('created order'));
break;
case 'addItem':
ensureRequired(args, ['orderId', 'bookId', 'quantity'], [_.isNumber, _.isNumber, _.isNumber]);
query = 'insert into line_items (order_id, book_id, quantity) values ($1, $2, $3) returning *';
params = [args.orderId, args.bookId, args.quantity];
runQuery(query, params, printer('added line item with book_id ' + args.bookId + ' to order_id ' + args.orderId));
break;
case 'removeItem':
ensureRequired(args, ['orderId', 'bookId'], [_.isNumber, _.isNumber]);
query = 'delete from line_items where order_id = $1 and book_id = $2';
params = [args.orderId, args.bookId];
runQuery(query, params, printer('deleted line_items from order_id ' + args.orderId + ' with book_id ' + args.bookId));
break;
case 'updateItem':
ensureRequired(args, ['orderId', 'bookId', 'quantity'], [_.isNumber, _.isNumber, _.isNumber]);
query = 'update line_items set quantity = $1 where order_id = $2 and book_id = $3';
params = [args.quantity, args.orderId, args.bookId];
runQuery(query, params, printer('updated line_items for order_id ' + args.orderId));
break;
case 'list':
ensureRequired(args, ['orderId'], [_.isNumber]);
query = `
select order_id, to_char(created, 'DD Mon YYYY') as created, creator, book_id, title, quantity from orders
join line_items on orders.id = line_items.order_id
join books on line_items.book_id = books.id
where orders.id = $1;
`;
params = [args.orderId];
runQuery(query, params, args.csv ? printCsv : printer())
break;
case 'delete':
ensureRequired(args, ['orderId'], [_.isNumber]);
params = [args.orderId];
pool.connect((err, client, done) => {
if (err) {
throw err;
}
client.query('BEGIN', (err, result) => {
if (err) {
console.error(err);
return rollback(client);
}
client.query('delete from line_items where order_id = $1', params, (err, result) => {
if (result.rowCount > 0) {
console.log('line items from order', args.orderId, 'deleted.');
}
if (err) {
return rollback(client);
}
client.query('delete from orders where id = $1', params, (err, result) => {
if (err) {
console.error(err);
return rollback(client);
}
if (result.rowCount === 0) {
console.log('No order with id', args.orderId);
return rollback(client);
}
console.log(result);
client.query('COMMIT', client.end.bind(client));
});
});
})
});
break;
default:
console.log('Action not supported');
}
} catch (e) {
console.error(e);
process.exit(1);
}