This repository has been archived by the owner on Mar 6, 2020. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathknexify.js
141 lines (119 loc) · 3.82 KB
/
knexify.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
/**
* # Knexify
*
* This is, at present, little more than a hack and needs revisiting.
* The `buildWhere` function is able to correctly transform JSON from GQL into a knex querybuilder
* How and where to do this needs to be considered.
*/
var _ = require('lodash'),
resourceContext = require('./context'),
// local functions
processFilter,
buildWhere,
whereType;
_.mixin(require('./lodash-stmt'));
// @TODO: remove this function
processFilter = function processFilter(filter, context) {
var joins = [],
addJoin,
expandAlias,
processProperty;
addJoin = function addJoin(join) {
if (joins.indexOf(join) === -1) {
joins.push(join);
}
};
expandAlias = function expandAlias(property) {
// Expand property aliases into their proper paths
if (context.propAliases && context.propAliases[property]) {
property = context.propAliases[property];
}
return property;
};
processProperty = function processProperty(property) {
var parts;
property = expandAlias(property);
// Separate property by '.'
parts = property.split('.');
// If length is 1, we only have a column name, add table name
if (parts.length === 1) {
property = context.name + '.' + property;
}
// Collect relations together into an array of 'include' properties
// This is sort of a hack for building joins and include params later
// It almost certainly doesn't belong here
if (parts.length > 1) {
addJoin(parts[0]);
// if (context.relations && context.relations.indexOf(parts[parts.length - 1]) > -1) {
// addJoin(path);
// }
}
return property;
};
// Loop through and process all the properties, really should be elsewhere
_.eachStatement(filter.statements, function (statement) {
statement.prop = processProperty(statement.prop);
});
filter.joins = joins;
return filter;
};
/**
* Detect Where Type
* @param {Object} statement
* @param {int} index
* @returns {string}
*/
whereType = function whereType(statement, index) {
var whereFunc = 'andWhere';
if (index === 0) {
whereFunc = 'where';
} else if (statement.func === 'or') {
whereFunc = 'orWhere';
}
if (statement.value === null) {
if (statement.func === 'or') {
whereFunc = statement.op === 'IS NOT' ? 'orWhereNotNull' : 'orWhereNull';
} else {
whereFunc = statement.op === 'IS NOT' ? 'whereNotNull' : 'whereNull';
}
}
return whereFunc;
};
/**
* Build Where
*
* @param {Object} qb
* @param {Array} statements
* @returns {*}
*/
buildWhere = function buildWhere(qb, statements) {
_.eachStatement(
statements,
function single(statement, index) {
// @TODO - validate value vs id here, to ensure we only pass valid things into where
qb[whereType(statement, index)](statement.prop, statement.op, statement.value);
},
function group(statement, index) {
qb[whereType(statement, index)](function (_qb) {
buildWhere(_qb, statement.group);
});
}
);
};
/**
* Knexify
* Converts a 'filter' from a set of statements in JSON form, into a set of `where` calls on a queryBuilder object
* This wrapping call to buildWhere should eventually be removed
*
* @param {Object} qb
* @param {Array} filter
* @returns {object} queryBuilder
*/
module.exports = function knexify(qb, filter) {
filter = processFilter(filter, resourceContext[qb._single.table]);
buildWhere(qb, filter.statements);
// return modified queryBuilder object for chaining
return qb;
};
// For testing only
module.exports._buildWhere = buildWhere;