-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathElementUtils.js
More file actions
200 lines (159 loc) · 5.7 KB
/
ElementUtils.js
File metadata and controls
200 lines (159 loc) · 5.7 KB
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
// lib deps
var uniq = require('lodash.uniq');
// project deps
var ElementTriplesBlock = require('./element/ElementTriplesBlock');
var ElementFilter = require('./element/ElementFilter');
var ElementGroup = require('./element/ElementGroup');
var ElementSubQuery = require('./element/ElementSubQuery');
var TripleUtils = require('./../rdf/TripleUtils');
var VarUtils = require('./VarUtils');
var GenSym = require('./GenSym');
var GeneratorBlacklist = require('./GeneratorBlacklist');
var HashBidiMap = require('../util/collection/HashBidiMap');
//var ObjectUtils = require('../util/ObjectUtils'); // node-equals
var NodeFactory = require('../rdf/NodeFactory');
var Query = require('./Query');
var ExprAggregator = require('./expr/ExprAggregator');
var AggCount = require('./agg/AggCount');
var ElementUtils = {
isEmpty: function(element) {
var result = element == null || element instanceof ElementGroup && element.getArgs().length === 0;
return result;
},
groupIfNeeded: function(elements) {
var result = elements.length != 1
? new ElementGroup(elements)
: elements[0]
;
return result;
},
createQueryCountRows: function(element, countVar, rowLimit) {
var e;
if(rowLimit == null) {
e = element;
} else {
var subQuery = new Query();
subQuery.setQuerySelectType();
subQuery.setQueryPattern(element);
subQuery.setQueryResultStar(true);
subQuery.setLimit(rowLimit);
e = new ElementSubQuery(element);
}
var result = new Query();
result.setQuerySelectType();
result.setQueryPattern(e);
result.getProject().add(countVar, new ExprAggregator(null, new AggCount()));
return result;
},
createFilterElements: function(exprs) {
var result = exprs.map(function(expr) {
var r = new ElementFilter(expr);
return r;
});
return result;
},
// TODO Get rid of this method
// @Deprecated
createElementsTriplesBlock: function(triples) {
var result = [];
if (triples.length > 0) {
var element = new ElementTriplesBlock(triples);
result.push(element);
}
return result;
},
/**
* Returns a map that maps *each* variable from vbs to a name that does not appear in vas.
*/
createDistinctVarMap: function(vas, vbs, generator) {
var vans = vas.map(VarUtils.getVarName);
if (generator == null) {
var g = new GenSym('v');
generator = new GeneratorBlacklist(g, vans);
}
// Rename all variables that are in common
// FIXME: fnNodeEquals is not defined (commented out in sponate-utils.js as of 2014-06-05)
var result = new HashBidiMap();
// var rename = {};
vbs.forEach(function(oldVar) {
var vbn = oldVar.getName();
var newVar;
if (vans.indexOf(vbn) !== -1) {
var newName = generator.next();
newVar = NodeFactory.createVar(newName);
} else {
newVar = oldVar;
}
// rename[vcn] = newVar;
// TODO Somehow re-use existing var objects...
// var oldVar = ns.Node.v(vcn);
result.put(oldVar, newVar);
});
return result;
},
/**
* distinctMap is the result of making vbs and vas distinct
*
* [?s ?o] [?s ?p] join on ?o = ?s
*
* Step 1: Make overlapping vars distinct
* [?s ?o] [?x ?p] -> {?s: ?x, ?p: ?p}
*
* Step 2: Make join vars common again
* [?s ?o] [?x ?s] -> {?s: ?x, ?p: ?s}
*/
createJoinVarMap: function(sourceVars, targetVars, sourceJoinVars, targetJoinVars, generator) {
if (sourceJoinVars.length !== targetJoinVars.length) {
console.log('[ERROR] Cannot join on different number of columns');
throw 'Bailing out';
}
var result = ElementUtils.createDistinctVarMap(sourceVars, targetVars, generator);
for (var i = 0; i < sourceJoinVars.length; ++i) {
var sourceJoinVar = sourceJoinVars[i];
var targetJoinVar = targetJoinVars[i];
// Map targetVar to sourceVar
result.put(targetJoinVar, sourceJoinVar);
// rename[targetVar.getName()] = sourceVar;
}
return result;
},
/**
* Var map must be a bidi map
*/
createRenamedElement: function(element, varMap) {
var fnSubst = VarUtils.fnSubst(varMap);
// debugger;
var newElement = element.copySubstitute(fnSubst);
return newElement;
},
/**
* Returns a new array of those triples, that are directly part of the given array of elements.
*
*/
getElementsDirectTriples: function(elements) {
var result = [];
for(var i = 0; i < elements.length; ++i) {
var element = elements[i];
if(element instanceof ElementTriplesBlock) {
result.push.apply(result, element.triples);
}
}
return result;
},
freshVar: function(element, baseVarName) {
var gen = this.freshVarGen(element, baseVarName);
var result = gen.next();
//console.log('freshVar: ' + result);
return result;
},
/**
* Creates a generator for fresh variables not appearing in the element
*/
freshVarGen: function(element, baseVarName) {
baseVarName = baseVarName || 'v';
var blacklistVars = element.getVarsMentioned();
var result = VarUtils.freshVarGen(baseVarName, blacklistVars);
return result;
}
};
module.exports = ElementUtils;