masterrecord 0.0.24 → 0.0.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DeleteManager.js +51 -0
- package/Entity/EntityModel.js +94 -30
- package/Entity/EntityModelBuilder.js +6 -28
- package/Entity/EntityTrackerModel.js +200 -20
- package/InsertManager.js +138 -0
- package/MYSQLEngine.js +409 -0
- package/Masterrecord.js +178 -119
- package/Migrations/cli.js +3 -2
- package/Migrations/migrations.js +45 -26
- package/QueryLanguage/queryManager.js +66 -0
- package/QueryLanguage/queryMethods.js +171 -0
- package/QueryLanguage/queryScript.js +331 -0
- package/SQLLiteEngine.js +409 -0
- package/Tools.js +97 -34
- package/package.json +7 -11
- package/QueryLanguage/_Expression.js +0 -322
- package/QueryLanguage/_LogicalQuery.js +0 -23
- package/QueryLanguage/_OperatorList.js +0 -88
- package/QueryLanguage/_QueryModel.js +0 -442
- package/QueryLanguage/_Tokenization.js +0 -173
- package/QueryLanguage/__Query.js +0 -386
- package/QueryLanguage/_simpleQuery.js +0 -184
- package/QueryLanguage/queryBuilder.js +0 -52
- package/SQLiteEngine.js +0 -56
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
// ALL THIS SHOULD DO IS BUILD A SQL QUERY
|
|
2
|
+
// version 1.0.222
|
|
3
|
+
// TODO: change name of queryManager to select manager;
|
|
4
|
+
var entityTrackerModel = require('masterrecord/Entity/EntityTrackerModel');
|
|
5
|
+
var tools = require('masterrecord/Tools');
|
|
6
|
+
var queryScript = require('masterrecord/QueryLanguage/queryScript');
|
|
7
|
+
|
|
8
|
+
class queryMethods{
|
|
9
|
+
|
|
10
|
+
constructor(entity, context) {
|
|
11
|
+
this.__entity = entity;
|
|
12
|
+
this.__context = context;
|
|
13
|
+
this.__queryObject = new queryScript();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// build a single entity
|
|
17
|
+
__singleEntityBuilder(dataModel){
|
|
18
|
+
var $that = this;
|
|
19
|
+
if(dataModel){
|
|
20
|
+
var ent = new entityTrackerModel();
|
|
21
|
+
var mod = ent.build(dataModel, $that.__entity, $that.__context);
|
|
22
|
+
mod.__state = "track";
|
|
23
|
+
$that.__context.__track(mod);
|
|
24
|
+
return mod;
|
|
25
|
+
}else{
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// build multiple entities
|
|
31
|
+
__multipleEntityBuilder(entityValue){
|
|
32
|
+
var $that = this;
|
|
33
|
+
var listArray = [];
|
|
34
|
+
if(entityValue){
|
|
35
|
+
for(let i = 0; i < entityValue.length; i++){
|
|
36
|
+
listArray.push($that.__singleEntityBuilder(entityValue[i]));
|
|
37
|
+
}
|
|
38
|
+
return listArray;
|
|
39
|
+
}else{
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
__reset(){
|
|
45
|
+
this.__queryObject.reset();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
raw(query){
|
|
49
|
+
|
|
50
|
+
this.__queryObject.raw(query);
|
|
51
|
+
return this;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
where(query, ...args){
|
|
55
|
+
var str = query.toString();
|
|
56
|
+
if(args){
|
|
57
|
+
for(let argument in args){
|
|
58
|
+
var item = args[argument];
|
|
59
|
+
str = str.replace("$$", item);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
this.__queryObject.where(str, this.__entity.__name);
|
|
63
|
+
return this;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// when you dont want to use lazy loading and want it called at that moment
|
|
67
|
+
//Eagerly loading
|
|
68
|
+
include(query, ...args){
|
|
69
|
+
var str = query.toString();
|
|
70
|
+
if(args){
|
|
71
|
+
for(let argument in args){
|
|
72
|
+
var item = args[argument];
|
|
73
|
+
str = str.replace("$$", item);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
this.__queryObject.include(str, this.__entity.__name);
|
|
77
|
+
return this;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// only takes a array of selected items
|
|
81
|
+
select(query, ...args){
|
|
82
|
+
var str = query.toString();
|
|
83
|
+
if(args){
|
|
84
|
+
for(let argument in args){
|
|
85
|
+
var item = args[argument];
|
|
86
|
+
str = str.replace("$$", item);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
this.__queryObject.select(str, this.__entity.__name);
|
|
90
|
+
return this;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
// do join on two tables = inner join
|
|
96
|
+
join(){
|
|
97
|
+
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
skip(){
|
|
101
|
+
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
limit(){
|
|
105
|
+
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
oderBy(){
|
|
109
|
+
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
groupBy(){
|
|
113
|
+
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
contains(){
|
|
117
|
+
// https://entityframework.net/knowledge-base/3491721/linq-to-entities---where-in-clause-in-query
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
count(){
|
|
121
|
+
// trying to match string select and relace with select Count(*);
|
|
122
|
+
var entityValue = this.__context._SQLEngine.getCount(this.__queryObject, this.__entity, this.__context);
|
|
123
|
+
var val = entityValue[Object.keys(entityValue)[0]];
|
|
124
|
+
this.__reset();
|
|
125
|
+
return val;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
single(){
|
|
129
|
+
var entityValue = this.__context._SQLEngine.get(this.__queryObject.script, this.__entity, this.__context);
|
|
130
|
+
var sing = this.__singleEntityBuilder(entityValue, this._queryBuilder);
|
|
131
|
+
this.__reset();
|
|
132
|
+
return sing;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
toList(){
|
|
136
|
+
var entityValue = this.__context._SQLEngine.all(this.__queryObject.script, this.__entity, this.__context);
|
|
137
|
+
var toLi = this.__multipleEntityBuilder(entityValue, this._queryBuilder);
|
|
138
|
+
this.__reset();
|
|
139
|
+
return toLi;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
asQueryable(){
|
|
143
|
+
// returns the sql created and does not make a call to DB
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
add(entityValue){
|
|
147
|
+
// This will call context API to REMOVE entity to update list
|
|
148
|
+
tools.clearAllProto(entityValue);
|
|
149
|
+
entityValue.__state = "insert";
|
|
150
|
+
entityValue.__entity = this.__entity;
|
|
151
|
+
entityValue.__context = this.__context;
|
|
152
|
+
this.__context.__track(entityValue);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
remove(entityValue){
|
|
156
|
+
entityValue.__state = "delete";
|
|
157
|
+
entityValue.__entity = this.__entity;
|
|
158
|
+
entityValue.__context = this.__context;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
track(entityValue){
|
|
162
|
+
entityValue.__state = "track";
|
|
163
|
+
tools.clearAllProto(entityValue);
|
|
164
|
+
entityValue.__entity = this.__entity;
|
|
165
|
+
entityValue.__context = this.__context;
|
|
166
|
+
this.__context.__track(entityValue);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
module.exports = queryMethods;
|
|
171
|
+
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
// version 1.0.1
|
|
2
|
+
|
|
3
|
+
const LOG_OPERATORS_REGEX = /(\|\|)|(&&)/;
|
|
4
|
+
var tools = require('../Tools');
|
|
5
|
+
|
|
6
|
+
class queryScript{
|
|
7
|
+
|
|
8
|
+
constructor(){ }
|
|
9
|
+
|
|
10
|
+
script = {
|
|
11
|
+
select : false,
|
|
12
|
+
where: false,
|
|
13
|
+
include : [],
|
|
14
|
+
raw: false,
|
|
15
|
+
entity : "",
|
|
16
|
+
entityMap : []
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
reset(){
|
|
21
|
+
this.script = {
|
|
22
|
+
select : false,
|
|
23
|
+
where: false,
|
|
24
|
+
include : [],
|
|
25
|
+
raw: false,
|
|
26
|
+
entity : "",
|
|
27
|
+
entityMap : []
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
getScript(){
|
|
32
|
+
return this.script;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
raw(query){
|
|
36
|
+
this.script.raw = query;
|
|
37
|
+
return this.script;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
where(text, entityName){
|
|
41
|
+
this.buildScript(text, "where", this.script, entityName);
|
|
42
|
+
return this.script;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
include(text, entityName){
|
|
46
|
+
this.buildScript(text, "include", this.script, entityName);
|
|
47
|
+
return this.script;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
select(text, entityName){
|
|
51
|
+
this.buildScript(text, "select", this.script, entityName);
|
|
52
|
+
return this.script;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
count(queryString){
|
|
56
|
+
var matched = queryString.match(/(?<=select)(.*?)from/gmi );
|
|
57
|
+
matched[0] = matched[0].replace("from", "");
|
|
58
|
+
var cleanQuery = queryString.replace(/^(.*?)from/gmi, "");
|
|
59
|
+
var str = `Select Count(${matched[0]}) from ${cleanQuery}`
|
|
60
|
+
|
|
61
|
+
return str;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
buildScript(text, type, obj, entityName){
|
|
65
|
+
|
|
66
|
+
var groups = this.splitByFunctions(text);
|
|
67
|
+
var cachedExpr = {}; // this function will just get the high leve
|
|
68
|
+
if(groups.length > 0){
|
|
69
|
+
|
|
70
|
+
cachedExpr.entity = this.getEntity(text);
|
|
71
|
+
|
|
72
|
+
if(!this.isMapped(entityName, obj.entityMap)){
|
|
73
|
+
|
|
74
|
+
obj.entityMap.push({
|
|
75
|
+
name: entityName,
|
|
76
|
+
entity : cachedExpr.entity
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
obj.entity = cachedExpr.entity
|
|
80
|
+
//tools.getRandomLetter(1)
|
|
81
|
+
cachedExpr[entityName] = this.splitGroupsByLogicalOperators(groups);
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
// lets break the string into a list of functions
|
|
85
|
+
this.buildFields(text, cachedExpr);
|
|
86
|
+
|
|
87
|
+
if(type === "include"){
|
|
88
|
+
if(cachedExpr.selectFields){
|
|
89
|
+
if(!this.isMapped(cachedExpr.selectFields[0], obj.entityMap)){
|
|
90
|
+
obj.entityMap.push({
|
|
91
|
+
name: tools.capitalizeFirstLetter(cachedExpr.selectFields[0]),
|
|
92
|
+
entity : tools.getRandomLetter(1, obj.entityMap)
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
this.describeExpressionParts(cachedExpr[entityName], cachedExpr.selectFields[0], obj.entityMap);
|
|
99
|
+
if(type === "include"){
|
|
100
|
+
obj[type].push(cachedExpr)
|
|
101
|
+
}
|
|
102
|
+
else{
|
|
103
|
+
obj[type] = cachedExpr;
|
|
104
|
+
}
|
|
105
|
+
obj.parentName = entityName;
|
|
106
|
+
return cachedExpr;
|
|
107
|
+
|
|
108
|
+
}
|
|
109
|
+
else{
|
|
110
|
+
// this means cachedExpr is not formated as: a => a
|
|
111
|
+
if(type === "select"){
|
|
112
|
+
obj.select = {
|
|
113
|
+
"selectFields": JSON.parse(text)
|
|
114
|
+
}
|
|
115
|
+
return obj.select;
|
|
116
|
+
}
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
buildFields(text, desc){
|
|
123
|
+
var match = text.match(/^([\w\d$_]+?)\s*=>((?:\{\sreturn\s)?[\s\S]*(?:\})?)/);
|
|
124
|
+
if(match){
|
|
125
|
+
const entity = match[1];
|
|
126
|
+
let exprStr = match[2];
|
|
127
|
+
const fields = [];
|
|
128
|
+
|
|
129
|
+
exprStr.replace(new RegExp(entity + "\\.([\\w_]+)", "g"), function (_, field) {
|
|
130
|
+
if (!fields.includes(field)) fields.push(field);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
desc.expr = exprStr.trim()
|
|
134
|
+
desc.selectFields = fields
|
|
135
|
+
return desc;
|
|
136
|
+
}
|
|
137
|
+
else{
|
|
138
|
+
return null;
|
|
139
|
+
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
MATCH_ENTITY_REGEXP(entityName) {
|
|
144
|
+
return new RegExp("(^|[^\\w\\d])" + entityName + "[ \\.\\)]");
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
OPERATORS_REGEX(entityName){
|
|
148
|
+
return new RegExp("(?:^|[^\\w\\d])" + entityName
|
|
149
|
+
+ "\\.((?:\\.?[\\w\\d_\\$]+)+)(?:\\((.*?)\\))?(?:\\s*(>|<|(?:===)|(?:!==)|(?:==)|(?:!=)|(?:=)|(?:<=)|(?:>=)|(?:in))\\s*(.*))?")
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
splitGroupsByLogicalOperators(groups, nested = false) {
|
|
153
|
+
let parts = {}, tmp;
|
|
154
|
+
for (let part of groups) {
|
|
155
|
+
|
|
156
|
+
//tmp = this.splitByLogicalOperators(part.query, entityRegExp)
|
|
157
|
+
tmp = this.extractInside(part.query, part.name);
|
|
158
|
+
if(tmp){
|
|
159
|
+
part.inside = tmp;
|
|
160
|
+
parts[part.name] = part;
|
|
161
|
+
}
|
|
162
|
+
else{
|
|
163
|
+
part.inside = part.query;
|
|
164
|
+
parts[part.name] = part;
|
|
165
|
+
}
|
|
166
|
+
part.inside = part.inside.replace("&&", "and");
|
|
167
|
+
part.query = part.query.replace("&&", "and");
|
|
168
|
+
part.inside = part.inside.replace("||", "or");
|
|
169
|
+
part.query = part.query.replace("||", "or");
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return parts;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
splitByFunctions(str) {
|
|
177
|
+
const regex = /(?<=\.(?=[A-z]+\())([^(]+)\((.+?)\)(?!\))/g;
|
|
178
|
+
let m;
|
|
179
|
+
const items = [];
|
|
180
|
+
while ((m = regex.exec(str)) !== null) {
|
|
181
|
+
// This is necessary to avoid infinite loops with zero-width matches
|
|
182
|
+
if (m.index === regex.lastIndex) {
|
|
183
|
+
regex.lastIndex++;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const [, fName, query] = m;
|
|
187
|
+
items.push(
|
|
188
|
+
{name: fName, query: `${fName}(${query})`}
|
|
189
|
+
)
|
|
190
|
+
}
|
|
191
|
+
if(items.length === 0){
|
|
192
|
+
items.push({name: "NOFUNCTIONS", query: str})
|
|
193
|
+
}
|
|
194
|
+
return items;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
describeExpressionParts(parts, parentField, entityMap) {
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
for (let item in parts) {
|
|
202
|
+
let match, fields, func, arg;
|
|
203
|
+
var part = parts[item];
|
|
204
|
+
part.expressions = [];
|
|
205
|
+
var partQuery = part.inside;
|
|
206
|
+
var entity = this.getEntity(partQuery);
|
|
207
|
+
var exprPartRegExp = this.OPERATORS_REGEX(entity);
|
|
208
|
+
// check if query contains an AND.
|
|
209
|
+
var splitByAnd = partQuery.split("and");
|
|
210
|
+
for (let splitAnds in splitByAnd) {
|
|
211
|
+
|
|
212
|
+
if (match = splitByAnd[splitAnds].match(exprPartRegExp)) {
|
|
213
|
+
fields = match[1].split(".");
|
|
214
|
+
func = (match[2] ? fields[fields.length - 1] : (match[3] || "exists"));
|
|
215
|
+
|
|
216
|
+
if (func == "==" || func == "===") {
|
|
217
|
+
func = "=";
|
|
218
|
+
}
|
|
219
|
+
else if (func == "!==") {
|
|
220
|
+
func = "!=";
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
arg = match[2] || match[4];
|
|
224
|
+
if (arg == "true" || arg == "false") {
|
|
225
|
+
arg = arg == "true";
|
|
226
|
+
}
|
|
227
|
+
else if (arg && arg.charAt(0) == arg.charAt(arg.length - 1) && (arg.charAt(0) == "'" || arg.charAt(0) == '"')) {
|
|
228
|
+
arg = arg.slice(1, -1);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
part.entity = entity;
|
|
232
|
+
if(this.isFunction(part.name)){
|
|
233
|
+
var scriptInner = {
|
|
234
|
+
include : [],
|
|
235
|
+
entityMap : entityMap
|
|
236
|
+
};
|
|
237
|
+
this.buildScript(part.inside, part.name, scriptInner, parentField, true);
|
|
238
|
+
parts.parentName = scriptInner.parentName;
|
|
239
|
+
part[scriptInner.parentName] = {};
|
|
240
|
+
if(part.name === "where"){
|
|
241
|
+
part.parentName = scriptInner.parentName;
|
|
242
|
+
part.entity = scriptInner.where.entity;
|
|
243
|
+
part.expr = scriptInner.where.expr;
|
|
244
|
+
part.selectFields = scriptInner.where.selectFields;
|
|
245
|
+
part[scriptInner.parentName] = scriptInner.where[scriptInner.parentName];
|
|
246
|
+
}
|
|
247
|
+
if(part.name === "include"){
|
|
248
|
+
part.parentName = scriptInner.parentName;
|
|
249
|
+
part.entity = scriptInner.include.entity;
|
|
250
|
+
part.expr = scriptInner.include.expr;
|
|
251
|
+
part.selectFields = scriptInner.include.selectFields;
|
|
252
|
+
part[scriptInner.parentName] = scriptInner.include[scriptInner.parentName];
|
|
253
|
+
|
|
254
|
+
}
|
|
255
|
+
if(part.name === "select"){
|
|
256
|
+
part.parentName = scriptInner.parentName;
|
|
257
|
+
part.entity = scriptInner.select.entity;
|
|
258
|
+
part.expr = scriptInner.select.expr;
|
|
259
|
+
part.selectFields = scriptInner.select.selectFields;
|
|
260
|
+
part[scriptInner.parentName] = scriptInner.select[scriptInner.parentName];
|
|
261
|
+
}
|
|
262
|
+
//part.inner = scriptInner;
|
|
263
|
+
}
|
|
264
|
+
else{
|
|
265
|
+
part.expressions.push({
|
|
266
|
+
field: fields[0],
|
|
267
|
+
func : func.toLowerCase(),
|
|
268
|
+
arg : arg
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return parts;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
getEntity(str){
|
|
281
|
+
var clean = str.replace(/\s/g, '');
|
|
282
|
+
return clean.substring(0, 1);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
isMapped(name, maps){
|
|
286
|
+
for (let item in maps) {
|
|
287
|
+
var map = maps[item];
|
|
288
|
+
if(tools.capitalizeFirstLetter(name) === map.name){
|
|
289
|
+
return true
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return false;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
//const res1 = extractInside(`User.include(a => a.Profile.where(r => r.name.startWith(i))).single()`, 'where');
|
|
296
|
+
// const res2 = extractInside(`User.include(a => a.Profile.select(r => r.name === "rick")).single()`, 'select');
|
|
297
|
+
extractInside(str, fname) {
|
|
298
|
+
if(this.isFunction(fname)){
|
|
299
|
+
const startIndex = str.indexOf(fname) + fname.length;
|
|
300
|
+
const stack = [];
|
|
301
|
+
for (let i = startIndex; i < str.length; i++) {
|
|
302
|
+
if(str[i] === '(') {
|
|
303
|
+
stack.push(str[i]);
|
|
304
|
+
|
|
305
|
+
} else if (str[i] === ')') {
|
|
306
|
+
stack.pop();
|
|
307
|
+
}
|
|
308
|
+
if(stack.length === 0) {
|
|
309
|
+
return str.substring(startIndex+1, i);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return str;
|
|
313
|
+
}
|
|
314
|
+
else{
|
|
315
|
+
return null;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
isFunction(func){
|
|
320
|
+
var funcList = ["where", "select", "include"]
|
|
321
|
+
for(var i =0; i < funcList.length; i++){
|
|
322
|
+
if(funcList[i] === func){
|
|
323
|
+
return true
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
return false;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
module.exports = queryScript;
|