1 | import Promise from 'bluebird';
|
2 | import debug from './debug';
|
3 |
|
4 | const makeAsyncApi = client => {
|
5 | function query(sql, ...values) {
|
6 | return query.queryArgs(sql, values);
|
7 | }
|
8 |
|
9 | query.query = (sql, ...values) => query.queryArgs(sql, values);
|
10 | query.queryArgs = (sql, values) =>
|
11 | new Promise((resolve, reject) => {
|
12 | debug('query params: %j query: %j', values, sql);
|
13 | client.query(sql, values, (err, result) => {
|
14 | if (err) {
|
15 | debug('%s query(%j, %j)', err, sql, values);
|
16 | return reject(err);
|
17 | }
|
18 | debug('query ok: %d rows', result.rowCount);
|
19 | return resolve(result);
|
20 | });
|
21 | });
|
22 |
|
23 | query.rows = (sql, ...values) => query.rowsArgs(sql, values);
|
24 | query.rowsArgs = async (sql, values) => (await query.queryArgs(sql, values)).rows;
|
25 |
|
26 | query.row = (sql, ...values) => query.rowArgs(sql, values);
|
27 | query.rowArgs = async (sql, values) => {
|
28 | const result = await query.queryArgs(sql, values);
|
29 | if (result.rowCount !== 1)
|
30 | throw new Error(`SQL: Expected exactly one row result but ${result.rowCount} returned`);
|
31 | return result.rows[0];
|
32 | };
|
33 |
|
34 | query.value = async (sql, ...values) => query.valueArgs(sql, values);
|
35 | query.valueArgs = async (sql, values) => {
|
36 |
|
37 |
|
38 | const opts = typeof(sql) === 'string'
|
39 | ? {text: sql, rowMode: 'array'}
|
40 | : {...sql, rowMode: 'array'};
|
41 | const result = await query.rowArgs(opts, values);
|
42 | if (result.length !== 1)
|
43 | throw new Error(`SQL: Expected exactly one column but ${result.length} returned`);
|
44 | return result[0];
|
45 | };
|
46 |
|
47 | query.inTransaction = false;
|
48 |
|
49 | query.startTransaction = () => {
|
50 | query.inTransaction = true;
|
51 | return query.query('BEGIN');
|
52 | };
|
53 |
|
54 | query.commit = () => {
|
55 | query.inTransaction = false;
|
56 | return query.query('COMMIT');
|
57 | };
|
58 |
|
59 | query.rollback = () => {
|
60 | query.inTransaction = false;
|
61 | return query.query('ROLLBACK');
|
62 | };
|
63 |
|
64 | query.end = async () => {
|
65 | if (query.inTransaction) {
|
66 | await query.rollback();
|
67 | throw new Error('Transaction started manually but not closed. Automatic rollback');
|
68 | }
|
69 | };
|
70 |
|
71 | return query;
|
72 | };
|
73 |
|
74 | export default makeAsyncApi;
|