/
lookup-by-query.js
122 lines (94 loc) · 3.12 KB
/
lookup-by-query.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
'use strict';
const queryBuilder = require('./query-builder');
module.exports = function(informationSchema, db) {
const {
tableName,
getModel,
castObjectFromDb
} = informationSchema;
const {
query,
} = db;
const {
buildWhere,
buildAttributes
} = queryBuilder(informationSchema);
return {
count,
all
};
function all(model, filter) {
const table = tableName(model);
const queryParams = [];
const attributes = buildAttributes(model, filter && filter.attributes, queryParams);
let sql = `SELECT ${ attributes } FROM ${ table }`;
if (filter) {
if (filter.where) {
sql += ' ' + buildWhere(model, filter.where, queryParams, true);
}
if (filter.group) {
sql += ' ' + buildGroupBy(filter.group);
}
if (filter.order) {
sql += ' ' + buildOrderBy(filter.order);
}
if (filter.limit) {
sql += ' ' + buildLimit(filter.limit, filter.offset || 0);
}
}
return query(sql, queryParams)
.then(records => {
const objs = records.map(record => castObjectFromDb(model, record));
if (filter && filter.include) {
return new Promise((resolve, reject) => {
getModel(model).model.include(objs, filter.include, (err, result) => {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
}
return objs;
});
function buildOrderBy(order) {
if (typeof order === 'string') {
order = [ order ];
}
return 'ORDER BY ' + order.map(o => {
const t = o.split(/\s+/);
if (t.length === 1) {
return '`' + o + '`';
}
return '`' + t[0] + '` ' + t[1];
}).join(', ');
}
function buildGroupBy(group) {
if (typeof group === 'string') {
group = [ group ];
}
return 'GROUP BY ' + group.map(o => {
const t = o.split(/\s+/);
if (t.length === 1) {
return '`' + o + '`';
}
return '`' + t[0] + '` ' + t[1];
}).join(', ');
}
function buildLimit(limit, offset) {
return 'LIMIT ' + (offset ? (offset + ', ' + limit) : limit);
}
}
function count(model, where) {
const table = tableName(model);
const queryParams = [];
where = buildWhere(model, where, queryParams);
if (where) {
where = 'WHERE ' + where;
}
const sql = `SELECT count(*) as cnt FROM ${table} ${where}`;
return query(sql, queryParams)
.then(result => result[0].cnt);
}
};