-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathquery-object.js
54 lines (49 loc) · 2.32 KB
/
query-object.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
const {
whateverTheyPutIn,
tableNameOrSubquery,
joinClauseHandler,
columnParam,
staticText,
} = require(`./clause-handlers`)
const sqlString = require(`sqlstring`)
const { combineClauses } = require(`./combinable-logic.js`)
const { build } = require(`./build-logic.js`)
const q = clauses => ({
select: addToClause(clauses, `select`, (...args) => whateverTheyPutIn(`, `, `, `, ...args)),
from: addToClause(clauses, `from`, tableNameOrSubquery),
join: addToClause(clauses, `join`, (...args) => joinClauseHandler(``, ...args)),
leftJoin: addToClause(clauses, `join`, (...args) => joinClauseHandler(`LEFT `, ...args)),
where: addToClause(clauses, `where`, (...args) => columnParam(` AND `, { like: false }, ...args)),
whereLike: addToClause(clauses, `where`, (...args) => columnParam(` AND `, { like: true }, ...args)),
orWhere: addToClause(clauses, `where`, (...args) => columnParam(` OR `, { like: false }, ...args)),
orWhereLike: addToClause(clauses, `where`, (...args) => columnParam(` OR `, { like: true }, ...args)),
having: addToClause(clauses, `having`, (...args) => columnParam(` AND `, { like: false }, ...args)),
orHaving: addToClause(clauses, `having`, (...args) => columnParam(` OR `, { like: false }, ...args)),
groupBy: addToClause(clauses, `groupBy`, (...args) => whateverTheyPutIn(`, `, `, `, ...args)),
orderBy: addToClause(clauses, `orderBy`, (...args) => whateverTheyPutIn(`, `, `, `, ...args)),
limit: addToClause(clauses, `limit`, (...args) => whateverTheyPutIn(`, `, `, `, ...args)),
forUpdate: addToClause(clauses, `lock`, () => staticText(`FOR UPDATE`)),
lockInShareMode: addToClause(clauses, `lock`, () => staticText(`LOCK IN SHARE MODE`)),
build: joinedBy => build(clauses, joinedBy),
getClauses: () => copy(clauses),
toString: joinedBy => {
const { sql, values } = build(clauses, joinedBy)
return sqlString.format(sql, values)
},
union: query => combineClauses(clauses, `UNION`, query.getClauses()),
unionAll: query => combineClauses(clauses, `UNION ALL`, query.getClauses()),
})
function addToClause(clauses, key, stringBuilder) {
return (...args) => {
const newClauses = copy(clauses)
newClauses[key].push(stringBuilder(...args))
return q(newClauses)
}
}
function copy(o) {
return Object.keys(o).reduce((newObject, key) => {
newObject[key] = o[key].slice()
return newObject
}, {})
}
module.exports = q