@bee.js/node 0.0.51 → 0.0.53
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/beeRequest.js +46 -43
- package/beehive.js +491 -491
- package/index.js +14 -14
- package/lib/DBA/beeDBA.js +133 -133
- package/lib/DEV/beeDEV.js +41 -41
- package/lib/JWT/beeJWT.js +71 -71
- package/lib/ORM/beeORM.js +364 -364
- package/lib/WEB/freeRoute.js +4 -4
- package/lib/WEB/route.js +27 -27
- package/lib/beeHive/create.js +71 -52
- package/lib/beeHive/headers.js +9 -9
- package/lib/beeHive/load.js +19 -19
- package/lib/beeHive/log.js +2 -2
- package/lib/beeHive/routes.js +34 -34
- package/lib/beeHive/start.js +29 -29
- package/package.json +40 -40
- package/security/index.js +8 -8
- package/services/CRON.js +8 -8
- package/services/EMAIL.js +2 -2
- package/services/HTTP.js +32 -32
- package/services/HTTPS.js +31 -31
- package/services/LOGS.js +7 -7
- package/services/SCRIPT.js +13 -13
- package/services/SHELL.js +2 -2
- package/services/index.js +9 -9
- package/tools/beeTools.js +18 -18
- package/tools/guid.js +15 -15
- package/tools/hash.js +6 -6
- package/tools/model.js +20 -20
- package/tools/slug.js +16 -16
- package/tools/string.js +55 -55
package/beehive.js
CHANGED
|
@@ -1,492 +1,492 @@
|
|
|
1
|
-
const log = require('./lib/beeHive/log')
|
|
2
|
-
const headers = require('./lib/beeHive/headers')
|
|
3
|
-
const beeORM = require('./lib/ORM/beeORM')
|
|
4
|
-
const beeDBA = require('./lib/DBA/beeDBA')
|
|
5
|
-
const beeJWT = require('./lib/JWT/beeJWT')
|
|
6
|
-
const beeTools = require('./tools/beeTools')
|
|
7
|
-
|
|
8
|
-
module.exports = function hive(req = {}, res = {}, model = null) {
|
|
9
|
-
|
|
10
|
-
model = model && typeof(model)==="string"
|
|
11
|
-
? global.configs.models[model]
|
|
12
|
-
: model
|
|
13
|
-
|
|
14
|
-
let script = [{ main: true, model: model, ids: [], select: [], where: [], binds: [], orderBy: [], limit: [], fields: [] }]
|
|
15
|
-
let data = res.data || {}
|
|
16
|
-
let counters = res.counters || {}
|
|
17
|
-
let inserts = res.inserts || []
|
|
18
|
-
let debug = res.debug || []
|
|
19
|
-
let error = res.error || false
|
|
20
|
-
let errorCode = res.errorCode || 0
|
|
21
|
-
let mainContainer = null
|
|
22
|
-
let models = global.models
|
|
23
|
-
let relWhere = {}
|
|
24
|
-
|
|
25
|
-
const dbExec = async function(SQL, binds = [], params = {}) {
|
|
26
|
-
|
|
27
|
-
let result = []
|
|
28
|
-
|
|
29
|
-
try {
|
|
30
|
-
if(global.configs.debug)
|
|
31
|
-
console.log(`
|
|
32
|
-
${SQL}
|
|
33
|
-
`)
|
|
34
|
-
|
|
35
|
-
global.beeDBPool = global.beeDBPool || beeORM.createPool(global.configs)
|
|
36
|
-
result = await global.beeDBPool.query(SQL, binds)
|
|
37
|
-
|
|
38
|
-
} catch(e) {
|
|
39
|
-
log("####### DB ERROR:")
|
|
40
|
-
log(e)
|
|
41
|
-
error = e
|
|
42
|
-
errorCode = 502
|
|
43
|
-
} finally {
|
|
44
|
-
if(global.configs.debug) debug.push(SQL)
|
|
45
|
-
if(global.configs.debug && binds) debug.push(binds)
|
|
46
|
-
|
|
47
|
-
if(params.container) {
|
|
48
|
-
data[params.container] = result[0]
|
|
49
|
-
|
|
50
|
-
if(counters)
|
|
51
|
-
counters[params.container] = (result[0] || []).length
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return result[0]
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return Object.assign(
|
|
59
|
-
{},
|
|
60
|
-
res, {
|
|
61
|
-
data,
|
|
62
|
-
counters,
|
|
63
|
-
inserts,
|
|
64
|
-
debug,
|
|
65
|
-
error,
|
|
66
|
-
errorCode,
|
|
67
|
-
script,
|
|
68
|
-
models,
|
|
69
|
-
beeDBA,
|
|
70
|
-
token: beeJWT,
|
|
71
|
-
configs: this.config,
|
|
72
|
-
headers,
|
|
73
|
-
dbExec,
|
|
74
|
-
|
|
75
|
-
dbEngine: async function() {
|
|
76
|
-
|
|
77
|
-
error = !script[0].model
|
|
78
|
-
? `MODEL NOT FOUND` // TODO refazer
|
|
79
|
-
: error
|
|
80
|
-
|
|
81
|
-
if(error) return this
|
|
82
|
-
|
|
83
|
-
let sqlSelect = beeORM.sqlSelect
|
|
84
|
-
let q = beeORM.quote
|
|
85
|
-
let relTables = []
|
|
86
|
-
let relIds = []
|
|
87
|
-
let relNow = null
|
|
88
|
-
let relPrev = null
|
|
89
|
-
let relJoin = {}
|
|
90
|
-
let parentTable = null
|
|
91
|
-
let i = -1
|
|
92
|
-
|
|
93
|
-
for(let _script of script) {
|
|
94
|
-
i++
|
|
95
|
-
|
|
96
|
-
let model = _script.model
|
|
97
|
-
let binds = _script.binds || []
|
|
98
|
-
let modelName = model.name || model.table
|
|
99
|
-
data[modelName] = null
|
|
100
|
-
|
|
101
|
-
if(i === 0) {
|
|
102
|
-
mainContainer = modelName
|
|
103
|
-
ids = model.ids
|
|
104
|
-
} else {
|
|
105
|
-
ids = relTables.filter((a) => a.table == model.table)[0]//['idsFromFieldB']
|
|
106
|
-
ids = ids ? ids.idsFromFieldB : []
|
|
107
|
-
|
|
108
|
-
parentTable = script[i-1].model.table
|
|
109
|
-
|
|
110
|
-
// rels
|
|
111
|
-
for(let _relField in model.relations) {
|
|
112
|
-
let array = model.relations[_relField].split('.')
|
|
113
|
-
let _parentTable = array[0]
|
|
114
|
-
let _parentField = array[1].split(' ')[0]
|
|
115
|
-
|
|
116
|
-
binds = binds.length
|
|
117
|
-
? binds
|
|
118
|
-
: script[0].binds
|
|
119
|
-
|
|
120
|
-
if(_parentTable !== parentTable) continue
|
|
121
|
-
|
|
122
|
-
relJoin[_parentTable] = !relJoin[_parentTable]
|
|
123
|
-
? `INNER JOIN ${q(_parentTable)} ON ${q(_parentTable)}.${_parentField} = ${models[modelName].table}.${_relField} `
|
|
124
|
-
: relJoin[_parentTable] + `AND ${q(_parentTable)}.${_parentField} = ${models[modelName].table}.${_relField} `
|
|
125
|
-
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
let fields = script[0]['fields'].concat((req.onlyFields||{})[model.table] || [])
|
|
130
|
-
|
|
131
|
-
let SQL = sqlSelect(
|
|
132
|
-
model,
|
|
133
|
-
ids,
|
|
134
|
-
{
|
|
135
|
-
select: script[0]['select'],
|
|
136
|
-
where: script[0]['where'],
|
|
137
|
-
orderBy: script[0]['orderBy'],
|
|
138
|
-
limit: script[0]['limit'],
|
|
139
|
-
joins: '',
|
|
140
|
-
fields,
|
|
141
|
-
middlewareParams: req.middleware,
|
|
142
|
-
},
|
|
143
|
-
);
|
|
144
|
-
|
|
145
|
-
if(i > 0)
|
|
146
|
-
for(let ii = i-1; ii>=0; ii--)
|
|
147
|
-
SQL[2] += relJoin[script[ii].model.table]
|
|
148
|
-
|
|
149
|
-
relWhere[model.table] = SQL[3]
|
|
150
|
-
|
|
151
|
-
await dbExec(SQL.join('').trim()+';', binds, {container: modelName})
|
|
152
|
-
|
|
153
|
-
continue
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
return
|
|
157
|
-
},
|
|
158
|
-
|
|
159
|
-
relations: function(rels, _default = '') {
|
|
160
|
-
rels = rels || _default
|
|
161
|
-
|
|
162
|
-
if(!rels) return this
|
|
163
|
-
|
|
164
|
-
rels = rels.split('.')
|
|
165
|
-
|
|
166
|
-
for(let model of rels)
|
|
167
|
-
if(models[model])
|
|
168
|
-
script.push( { model: models[model], relation: true } )
|
|
169
|
-
else
|
|
170
|
-
(error = `RELATION ${model} NOT FOUND`) && (errorCode = 500)
|
|
171
|
-
|
|
172
|
-
return this
|
|
173
|
-
},
|
|
174
|
-
|
|
175
|
-
select: function(model, ids) {
|
|
176
|
-
|
|
177
|
-
model = (typeof(model)==="string") ? models[model] : model
|
|
178
|
-
|
|
179
|
-
script.push( { model: model, ids: ids } )
|
|
180
|
-
|
|
181
|
-
return this
|
|
182
|
-
},
|
|
183
|
-
|
|
184
|
-
get: async function() {
|
|
185
|
-
|
|
186
|
-
await this.dbEngine()
|
|
187
|
-
|
|
188
|
-
return this
|
|
189
|
-
},
|
|
190
|
-
|
|
191
|
-
find: async function(...values) {
|
|
192
|
-
if(values.length)
|
|
193
|
-
(model.indexes.keys || Object.keys(model.schema)[0])
|
|
194
|
-
.split(",")
|
|
195
|
-
.map((pk, i) => {
|
|
196
|
-
console.log(pk)
|
|
197
|
-
script[0].where.push(`${pk.trim()} = ?`)
|
|
198
|
-
script[0].binds.push(values[i])
|
|
199
|
-
})
|
|
200
|
-
|
|
201
|
-
await this.dbEngine()
|
|
202
|
-
|
|
203
|
-
data[mainContainer] = data[mainContainer][0]
|
|
204
|
-
|
|
205
|
-
return this
|
|
206
|
-
},
|
|
207
|
-
|
|
208
|
-
first: async function() { //TODO auditar
|
|
209
|
-
|
|
210
|
-
await this.dbEngine()
|
|
211
|
-
|
|
212
|
-
if((mainContainer && data[mainContainer]))
|
|
213
|
-
data[mainContainer] = data[mainContainer][0]
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
return this
|
|
217
|
-
},
|
|
218
|
-
|
|
219
|
-
last: async function() {
|
|
220
|
-
|
|
221
|
-
await this.dbEngine()
|
|
222
|
-
|
|
223
|
-
data[mainContainer] = data[mainContainer][data[mainContainer].length-1]
|
|
224
|
-
|
|
225
|
-
return this
|
|
226
|
-
},
|
|
227
|
-
|
|
228
|
-
where: function(where, binds) {
|
|
229
|
-
|
|
230
|
-
script[0]['where'].push(where)
|
|
231
|
-
|
|
232
|
-
if(binds)
|
|
233
|
-
script[0]['binds'] = script[0]['binds'].concat(binds)
|
|
234
|
-
|
|
235
|
-
return this
|
|
236
|
-
},
|
|
237
|
-
|
|
238
|
-
whereIf: function(condition, where, binds) {
|
|
239
|
-
if(condition)
|
|
240
|
-
script[0]['where'].push(where)
|
|
241
|
-
|
|
242
|
-
if(condition && binds)
|
|
243
|
-
script[0]['binds'].push(typeof(binds) === "function" ? binds() : binds)
|
|
244
|
-
|
|
245
|
-
return this
|
|
246
|
-
},
|
|
247
|
-
|
|
248
|
-
whereIn: function(field, array = []) {
|
|
249
|
-
array = array
|
|
250
|
-
.map(row => {
|
|
251
|
-
let val = row[field]
|
|
252
|
-
|
|
253
|
-
switch (model.schema[field].type) {
|
|
254
|
-
case "char":
|
|
255
|
-
case "varchar":
|
|
256
|
-
case "text":
|
|
257
|
-
case "string":
|
|
258
|
-
return `'${val}'`
|
|
259
|
-
case "guid":
|
|
260
|
-
case "uuid":
|
|
261
|
-
return val ? beeTools.guidToBin(val) : null
|
|
262
|
-
default:
|
|
263
|
-
return val
|
|
264
|
-
}
|
|
265
|
-
})
|
|
266
|
-
.join(",")
|
|
267
|
-
|
|
268
|
-
script[0]['where'].push(`${model.table}.${field} IN(${array})`)
|
|
269
|
-
|
|
270
|
-
return this
|
|
271
|
-
},
|
|
272
|
-
|
|
273
|
-
binds: function(...params) {
|
|
274
|
-
|
|
275
|
-
params.map(bind=> script[0]['binds'].push(bind))
|
|
276
|
-
|
|
277
|
-
return this
|
|
278
|
-
},
|
|
279
|
-
|
|
280
|
-
orderBy: function(...fields) {
|
|
281
|
-
|
|
282
|
-
script[0]['orderBy'].push(fields.join(', '))
|
|
283
|
-
|
|
284
|
-
return this
|
|
285
|
-
},
|
|
286
|
-
|
|
287
|
-
orderByIf: function(condition, ...fields) {
|
|
288
|
-
if (condition)
|
|
289
|
-
script[0]['orderBy'].push(fields.join(', '))
|
|
290
|
-
|
|
291
|
-
return this
|
|
292
|
-
},
|
|
293
|
-
|
|
294
|
-
limit: function(...params) {
|
|
295
|
-
|
|
296
|
-
script[0]['limit'].push(params.join(","))
|
|
297
|
-
|
|
298
|
-
return this
|
|
299
|
-
},
|
|
300
|
-
|
|
301
|
-
fields: function(...fields) {
|
|
302
|
-
|
|
303
|
-
script[0]['fields'] = fields
|
|
304
|
-
|
|
305
|
-
return this
|
|
306
|
-
},
|
|
307
|
-
|
|
308
|
-
fieldsIf: function(condition, fields) {
|
|
309
|
-
|
|
310
|
-
if(condition)
|
|
311
|
-
script[0]['fields'] = fields
|
|
312
|
-
|
|
313
|
-
return this
|
|
314
|
-
},
|
|
315
|
-
|
|
316
|
-
search: function(string = "", fields = [], relevance = [1, 2, 3, 4, 5]) {
|
|
317
|
-
if(!string) return this
|
|
318
|
-
|
|
319
|
-
let where = []
|
|
320
|
-
let orderBy = []
|
|
321
|
-
let words = string.split(" ")
|
|
322
|
-
fields = beeORM.parseArray(fields)
|
|
323
|
-
fields = fields.length ? fields : Object.keys(model.schema)
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
fields
|
|
327
|
-
.map((field)=> {
|
|
328
|
-
|
|
329
|
-
orderBy.push(`WHEN ${field} = '${string}' THEN ${relevance[0]} WHEN ${field} LIKE '${string}%' THEN ${relevance[1]} WHEN ${field} LIKE '%${string}%' THEN ${relevance[2]} WHEN ${field} LIKE '%${string.replace(/ /g, "%")}%' THEN ${relevance[3]}`)
|
|
330
|
-
|
|
331
|
-
words
|
|
332
|
-
.map((word, i)=> {
|
|
333
|
-
|
|
334
|
-
where.push(`${field} LIKE '%${word}%'`)
|
|
335
|
-
|
|
336
|
-
if(words.length > 1)
|
|
337
|
-
orderBy.push(`WHEN ${field} = '${word}' THEN ${(relevance[4] * (i+1))} WHEN ${field} LIKE '${word}%' THEN ${(relevance[4] * (i+1)) + relevance[1]} WHEN ${field} LIKE '%${word}%' THEN ${(relevance[4] * (i+1)) + relevance[2]}`)
|
|
338
|
-
})
|
|
339
|
-
})
|
|
340
|
-
|
|
341
|
-
script[0]['where'].push(`(${where.join(' OR ')})`)
|
|
342
|
-
script[0]['orderBy'].unshift(`CASE ${orderBy.join(' ')} ELSE ${100000} END ASC`)
|
|
343
|
-
|
|
344
|
-
return this
|
|
345
|
-
},
|
|
346
|
-
|
|
347
|
-
insert: async function(_data, params = {}) {
|
|
348
|
-
|
|
349
|
-
//data = beeORM.forceData(data, req)
|
|
350
|
-
|
|
351
|
-
if(model.relations && params.relations)
|
|
352
|
-
await Promise
|
|
353
|
-
.all(
|
|
354
|
-
Object
|
|
355
|
-
.keys(model.relations)
|
|
356
|
-
.map(async field => {
|
|
357
|
-
let where = []
|
|
358
|
-
let array = model.relations[field].split(" ")[0].split(".")
|
|
359
|
-
let parentTable = array[0]
|
|
360
|
-
let parentField = array[1]
|
|
361
|
-
let parentRels = global.configs.models[parentTable].relations
|
|
362
|
-
|
|
363
|
-
Object
|
|
364
|
-
.keys(parentRels)
|
|
365
|
-
.map(fieldRel => where.push(`${fieldRel} = '${params.relations[parentTable][fieldRel]}'`))
|
|
366
|
-
|
|
367
|
-
let SQL = `SELECT ${parentField} FROM ${parentTable} WHERE ${where.join(" AND ")}`
|
|
368
|
-
|
|
369
|
-
SQL = await dbExec(SQL)
|
|
370
|
-
|
|
371
|
-
Array.isArray(_data)
|
|
372
|
-
? _data.map(a => a[parentField] = SQL[0][parentField])
|
|
373
|
-
: _data[parentField] = SQL[0][parentField]
|
|
374
|
-
})
|
|
375
|
-
)
|
|
376
|
-
|
|
377
|
-
let onlyFields = script[0].fields.concat((req.onlyFields||{})[model.table] || [])
|
|
378
|
-
let sql = beeORM.sqlInsertUpdate(model, _data, onlyFields, 'INSERT')
|
|
379
|
-
|
|
380
|
-
_data = await dbExec(sql.SQL, sql.binds)
|
|
381
|
-
|
|
382
|
-
inserts.push({..._data, model: model.table})
|
|
383
|
-
this.insertId = _data.insertId
|
|
384
|
-
|
|
385
|
-
return {...this, result: {...sql.result,..._data}}
|
|
386
|
-
},
|
|
387
|
-
|
|
388
|
-
update: async function(data, ids = []) { // TODO criar auditoria
|
|
389
|
-
|
|
390
|
-
//data = beeORM.forceData(data, req)
|
|
391
|
-
|
|
392
|
-
let onlyFields = script[0].fields.concat((req.onlyFields||{})[model.table] || [])
|
|
393
|
-
let sql = beeORM.sqlInsertUpdate(model, data, onlyFields, 'UPDATE')
|
|
394
|
-
|
|
395
|
-
sql.SQL += beeORM.modelSqlWhere(model, ids, req.middleware)
|
|
396
|
-
sql.SQL += script[0]['where'].length
|
|
397
|
-
? (!ids.length ? ' WHERE ' : ' AND ') + script[0]['where'].join(" AND ")
|
|
398
|
-
: ''
|
|
399
|
-
|
|
400
|
-
data = await dbExec(sql.SQL, script[0]['binds'])
|
|
401
|
-
|
|
402
|
-
return {...this, result: {...sql.result, ...data}}
|
|
403
|
-
},
|
|
404
|
-
|
|
405
|
-
delete: async function(ids) {
|
|
406
|
-
|
|
407
|
-
const q = beeORM.quote
|
|
408
|
-
|
|
409
|
-
ids = ids && typeof(ids) !== 'object'
|
|
410
|
-
? ids.toString().split(',')
|
|
411
|
-
: ids
|
|
412
|
-
|
|
413
|
-
SQL = 'DELETE FROM ' + q(model.table)
|
|
414
|
-
SQL += beeORM.modelSqlWhere(model, ids, req.middleware)
|
|
415
|
-
SQL += script[0]['where'].length
|
|
416
|
-
? (!ids.length ? ' WHERE ' : ' AND ') + script[0]['where'].join(" AND ")
|
|
417
|
-
: ''
|
|
418
|
-
|
|
419
|
-
data = await dbExec(SQL)
|
|
420
|
-
|
|
421
|
-
return this
|
|
422
|
-
},
|
|
423
|
-
|
|
424
|
-
table: async function(table, where) {
|
|
425
|
-
|
|
426
|
-
const q = beeORM.quote
|
|
427
|
-
|
|
428
|
-
SQL = 'SELECT * FROM ' + q(table)
|
|
429
|
-
SQL += where ? ` WHERE ${where};` : ''
|
|
430
|
-
|
|
431
|
-
let result = await dbExec(SQL)
|
|
432
|
-
|
|
433
|
-
data[table] = result
|
|
434
|
-
counters[table] = result.length
|
|
435
|
-
mainContainer = table;
|
|
436
|
-
|
|
437
|
-
return this
|
|
438
|
-
},
|
|
439
|
-
|
|
440
|
-
query: async function(SQL, binds = [], container = 'query') {
|
|
441
|
-
|
|
442
|
-
let result = await dbExec(SQL, binds, {container: container})
|
|
443
|
-
|
|
444
|
-
counters[container] = (result) ? result.length : 0
|
|
445
|
-
|
|
446
|
-
return this
|
|
447
|
-
},
|
|
448
|
-
|
|
449
|
-
response: function(sendData = data, action = null, status) {
|
|
450
|
-
|
|
451
|
-
let out = {data: sendData, counters, action, error}
|
|
452
|
-
|
|
453
|
-
if(inserts.length)
|
|
454
|
-
out.inserts = inserts
|
|
455
|
-
|
|
456
|
-
if(global.configs.debug)
|
|
457
|
-
out.debug = debug
|
|
458
|
-
|
|
459
|
-
if(status)
|
|
460
|
-
res.status(status).send(out)
|
|
461
|
-
else
|
|
462
|
-
switch(req.method) {
|
|
463
|
-
case 'DELETE' :
|
|
464
|
-
res.status(action ? errorCode || 200 : 204).json(out)
|
|
465
|
-
break
|
|
466
|
-
case 'POST':
|
|
467
|
-
res.status(errorCode || 201).json(out)
|
|
468
|
-
break
|
|
469
|
-
case 'PUT':
|
|
470
|
-
res.status(errorCode || 200).json(out) // TODO deletar props irrelevantes no output
|
|
471
|
-
break
|
|
472
|
-
default:
|
|
473
|
-
res.status(errorCode || 200).json(out)
|
|
474
|
-
}
|
|
475
|
-
},
|
|
476
|
-
|
|
477
|
-
responseError: function(error, errorCode) {
|
|
478
|
-
|
|
479
|
-
let out = {error: {message: error || 'an error has occurred'}}
|
|
480
|
-
|
|
481
|
-
if(global.configs.debug)
|
|
482
|
-
out.debug = debug
|
|
483
|
-
|
|
484
|
-
res.status(errorCode || 500).send(out)
|
|
485
|
-
},
|
|
486
|
-
|
|
487
|
-
ifNull(param) {
|
|
488
|
-
return !this.data ? param : this
|
|
489
|
-
},
|
|
490
|
-
}
|
|
491
|
-
)
|
|
1
|
+
const log = require('./lib/beeHive/log')
|
|
2
|
+
const headers = require('./lib/beeHive/headers')
|
|
3
|
+
const beeORM = require('./lib/ORM/beeORM')
|
|
4
|
+
const beeDBA = require('./lib/DBA/beeDBA')
|
|
5
|
+
const beeJWT = require('./lib/JWT/beeJWT')
|
|
6
|
+
const beeTools = require('./tools/beeTools')
|
|
7
|
+
|
|
8
|
+
module.exports = function hive(req = {}, res = {}, model = null) {
|
|
9
|
+
|
|
10
|
+
model = model && typeof(model)==="string"
|
|
11
|
+
? global.configs.models[model]
|
|
12
|
+
: model
|
|
13
|
+
|
|
14
|
+
let script = [{ main: true, model: model, ids: [], select: [], where: [], binds: [], orderBy: [], limit: [], fields: [] }]
|
|
15
|
+
let data = res.data || {}
|
|
16
|
+
let counters = res.counters || {}
|
|
17
|
+
let inserts = res.inserts || []
|
|
18
|
+
let debug = res.debug || []
|
|
19
|
+
let error = res.error || false
|
|
20
|
+
let errorCode = res.errorCode || 0
|
|
21
|
+
let mainContainer = null
|
|
22
|
+
let models = global.models
|
|
23
|
+
let relWhere = {}
|
|
24
|
+
|
|
25
|
+
const dbExec = async function(SQL, binds = [], params = {}) {
|
|
26
|
+
|
|
27
|
+
let result = []
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
if(global.configs.debug)
|
|
31
|
+
console.log(`
|
|
32
|
+
${SQL}
|
|
33
|
+
`)
|
|
34
|
+
|
|
35
|
+
global.beeDBPool = global.beeDBPool || beeORM.createPool(global.configs)
|
|
36
|
+
result = await global.beeDBPool.query(SQL, binds)
|
|
37
|
+
|
|
38
|
+
} catch(e) {
|
|
39
|
+
log("####### DB ERROR:")
|
|
40
|
+
log(e)
|
|
41
|
+
error = e
|
|
42
|
+
errorCode = 502
|
|
43
|
+
} finally {
|
|
44
|
+
if(global.configs.debug) debug.push(SQL)
|
|
45
|
+
if(global.configs.debug && binds) debug.push(binds)
|
|
46
|
+
|
|
47
|
+
if(params.container) {
|
|
48
|
+
data[params.container] = result[0]
|
|
49
|
+
|
|
50
|
+
if(counters)
|
|
51
|
+
counters[params.container] = (result[0] || []).length
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return result[0]
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return Object.assign(
|
|
59
|
+
{},
|
|
60
|
+
res, {
|
|
61
|
+
data,
|
|
62
|
+
counters,
|
|
63
|
+
inserts,
|
|
64
|
+
debug,
|
|
65
|
+
error,
|
|
66
|
+
errorCode,
|
|
67
|
+
script,
|
|
68
|
+
models,
|
|
69
|
+
beeDBA,
|
|
70
|
+
token: beeJWT,
|
|
71
|
+
configs: this.config,
|
|
72
|
+
headers,
|
|
73
|
+
dbExec,
|
|
74
|
+
|
|
75
|
+
dbEngine: async function() {
|
|
76
|
+
|
|
77
|
+
error = !script[0].model
|
|
78
|
+
? `MODEL NOT FOUND` // TODO refazer
|
|
79
|
+
: error
|
|
80
|
+
|
|
81
|
+
if(error) return this
|
|
82
|
+
|
|
83
|
+
let sqlSelect = beeORM.sqlSelect
|
|
84
|
+
let q = beeORM.quote
|
|
85
|
+
let relTables = []
|
|
86
|
+
let relIds = []
|
|
87
|
+
let relNow = null
|
|
88
|
+
let relPrev = null
|
|
89
|
+
let relJoin = {}
|
|
90
|
+
let parentTable = null
|
|
91
|
+
let i = -1
|
|
92
|
+
|
|
93
|
+
for(let _script of script) {
|
|
94
|
+
i++
|
|
95
|
+
|
|
96
|
+
let model = _script.model
|
|
97
|
+
let binds = _script.binds || []
|
|
98
|
+
let modelName = model.name || model.table
|
|
99
|
+
data[modelName] = null
|
|
100
|
+
|
|
101
|
+
if(i === 0) {
|
|
102
|
+
mainContainer = modelName
|
|
103
|
+
ids = model.ids
|
|
104
|
+
} else {
|
|
105
|
+
ids = relTables.filter((a) => a.table == model.table)[0]//['idsFromFieldB']
|
|
106
|
+
ids = ids ? ids.idsFromFieldB : []
|
|
107
|
+
|
|
108
|
+
parentTable = script[i-1].model.table
|
|
109
|
+
|
|
110
|
+
// rels
|
|
111
|
+
for(let _relField in model.relations) {
|
|
112
|
+
let array = model.relations[_relField].split('.')
|
|
113
|
+
let _parentTable = array[0]
|
|
114
|
+
let _parentField = array[1].split(' ')[0]
|
|
115
|
+
|
|
116
|
+
binds = binds.length
|
|
117
|
+
? binds
|
|
118
|
+
: script[0].binds
|
|
119
|
+
|
|
120
|
+
if(_parentTable !== parentTable) continue
|
|
121
|
+
|
|
122
|
+
relJoin[_parentTable] = !relJoin[_parentTable]
|
|
123
|
+
? `INNER JOIN ${q(_parentTable)} ON ${q(_parentTable)}.${_parentField} = ${models[modelName].table}.${_relField} `
|
|
124
|
+
: relJoin[_parentTable] + `AND ${q(_parentTable)}.${_parentField} = ${models[modelName].table}.${_relField} `
|
|
125
|
+
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
let fields = script[0]['fields'].concat((req.onlyFields||{})[model.table] || [])
|
|
130
|
+
|
|
131
|
+
let SQL = sqlSelect(
|
|
132
|
+
model,
|
|
133
|
+
ids,
|
|
134
|
+
{
|
|
135
|
+
select: script[0]['select'],
|
|
136
|
+
where: script[0]['where'],
|
|
137
|
+
orderBy: script[0]['orderBy'],
|
|
138
|
+
limit: script[0]['limit'],
|
|
139
|
+
joins: '',
|
|
140
|
+
fields,
|
|
141
|
+
middlewareParams: req.middleware,
|
|
142
|
+
},
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
if(i > 0)
|
|
146
|
+
for(let ii = i-1; ii>=0; ii--)
|
|
147
|
+
SQL[2] += relJoin[script[ii].model.table]
|
|
148
|
+
|
|
149
|
+
relWhere[model.table] = SQL[3]
|
|
150
|
+
|
|
151
|
+
await dbExec(SQL.join('').trim()+';', binds, {container: modelName})
|
|
152
|
+
|
|
153
|
+
continue
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return
|
|
157
|
+
},
|
|
158
|
+
|
|
159
|
+
relations: function(rels, _default = '') {
|
|
160
|
+
rels = rels || _default
|
|
161
|
+
|
|
162
|
+
if(!rels) return this
|
|
163
|
+
|
|
164
|
+
rels = rels.split('.')
|
|
165
|
+
|
|
166
|
+
for(let model of rels)
|
|
167
|
+
if(models[model])
|
|
168
|
+
script.push( { model: models[model], relation: true } )
|
|
169
|
+
else
|
|
170
|
+
(error = `RELATION ${model} NOT FOUND`) && (errorCode = 500)
|
|
171
|
+
|
|
172
|
+
return this
|
|
173
|
+
},
|
|
174
|
+
|
|
175
|
+
select: function(model, ids) {
|
|
176
|
+
|
|
177
|
+
model = (typeof(model)==="string") ? models[model] : model
|
|
178
|
+
|
|
179
|
+
script.push( { model: model, ids: ids } )
|
|
180
|
+
|
|
181
|
+
return this
|
|
182
|
+
},
|
|
183
|
+
|
|
184
|
+
get: async function() {
|
|
185
|
+
|
|
186
|
+
await this.dbEngine()
|
|
187
|
+
|
|
188
|
+
return this
|
|
189
|
+
},
|
|
190
|
+
|
|
191
|
+
find: async function(...values) {
|
|
192
|
+
if(values.length)
|
|
193
|
+
(model.indexes.keys || Object.keys(model.schema)[0])
|
|
194
|
+
.split(",")
|
|
195
|
+
.map((pk, i) => {
|
|
196
|
+
console.log(pk)
|
|
197
|
+
script[0].where.push(`${pk.trim()} = ?`)
|
|
198
|
+
script[0].binds.push(values[i])
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
await this.dbEngine()
|
|
202
|
+
|
|
203
|
+
data[mainContainer] = data[mainContainer][0]
|
|
204
|
+
|
|
205
|
+
return this
|
|
206
|
+
},
|
|
207
|
+
|
|
208
|
+
first: async function() { //TODO auditar
|
|
209
|
+
|
|
210
|
+
await this.dbEngine()
|
|
211
|
+
|
|
212
|
+
if((mainContainer && data[mainContainer]))
|
|
213
|
+
data[mainContainer] = data[mainContainer][0]
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
return this
|
|
217
|
+
},
|
|
218
|
+
|
|
219
|
+
last: async function() {
|
|
220
|
+
|
|
221
|
+
await this.dbEngine()
|
|
222
|
+
|
|
223
|
+
data[mainContainer] = data[mainContainer][data[mainContainer].length-1]
|
|
224
|
+
|
|
225
|
+
return this
|
|
226
|
+
},
|
|
227
|
+
|
|
228
|
+
where: function(where, binds) {
|
|
229
|
+
|
|
230
|
+
script[0]['where'].push(where)
|
|
231
|
+
|
|
232
|
+
if(binds)
|
|
233
|
+
script[0]['binds'] = script[0]['binds'].concat(binds)
|
|
234
|
+
|
|
235
|
+
return this
|
|
236
|
+
},
|
|
237
|
+
|
|
238
|
+
whereIf: function(condition, where, binds) {
|
|
239
|
+
if(condition)
|
|
240
|
+
script[0]['where'].push(where)
|
|
241
|
+
|
|
242
|
+
if(condition && binds)
|
|
243
|
+
script[0]['binds'].push(typeof(binds) === "function" ? binds() : binds)
|
|
244
|
+
|
|
245
|
+
return this
|
|
246
|
+
},
|
|
247
|
+
|
|
248
|
+
whereIn: function(field, array = []) {
|
|
249
|
+
array = array
|
|
250
|
+
.map(row => {
|
|
251
|
+
let val = row[field]
|
|
252
|
+
|
|
253
|
+
switch (model.schema[field].type) {
|
|
254
|
+
case "char":
|
|
255
|
+
case "varchar":
|
|
256
|
+
case "text":
|
|
257
|
+
case "string":
|
|
258
|
+
return `'${val}'`
|
|
259
|
+
case "guid":
|
|
260
|
+
case "uuid":
|
|
261
|
+
return val ? beeTools.guidToBin(val) : null
|
|
262
|
+
default:
|
|
263
|
+
return val
|
|
264
|
+
}
|
|
265
|
+
})
|
|
266
|
+
.join(",")
|
|
267
|
+
|
|
268
|
+
script[0]['where'].push(`${model.table}.${field} IN(${array})`)
|
|
269
|
+
|
|
270
|
+
return this
|
|
271
|
+
},
|
|
272
|
+
|
|
273
|
+
binds: function(...params) {
|
|
274
|
+
|
|
275
|
+
params.map(bind=> script[0]['binds'].push(bind))
|
|
276
|
+
|
|
277
|
+
return this
|
|
278
|
+
},
|
|
279
|
+
|
|
280
|
+
orderBy: function(...fields) {
|
|
281
|
+
|
|
282
|
+
script[0]['orderBy'].push(fields.join(', '))
|
|
283
|
+
|
|
284
|
+
return this
|
|
285
|
+
},
|
|
286
|
+
|
|
287
|
+
orderByIf: function(condition, ...fields) {
|
|
288
|
+
if (condition)
|
|
289
|
+
script[0]['orderBy'].push(fields.join(', '))
|
|
290
|
+
|
|
291
|
+
return this
|
|
292
|
+
},
|
|
293
|
+
|
|
294
|
+
limit: function(...params) {
|
|
295
|
+
|
|
296
|
+
script[0]['limit'].push(params.join(","))
|
|
297
|
+
|
|
298
|
+
return this
|
|
299
|
+
},
|
|
300
|
+
|
|
301
|
+
fields: function(...fields) {
|
|
302
|
+
|
|
303
|
+
script[0]['fields'] = fields
|
|
304
|
+
|
|
305
|
+
return this
|
|
306
|
+
},
|
|
307
|
+
|
|
308
|
+
fieldsIf: function(condition, fields) {
|
|
309
|
+
|
|
310
|
+
if(condition)
|
|
311
|
+
script[0]['fields'] = fields
|
|
312
|
+
|
|
313
|
+
return this
|
|
314
|
+
},
|
|
315
|
+
|
|
316
|
+
search: function(string = "", fields = [], relevance = [1, 2, 3, 4, 5]) {
|
|
317
|
+
if(!string) return this
|
|
318
|
+
|
|
319
|
+
let where = []
|
|
320
|
+
let orderBy = []
|
|
321
|
+
let words = string.split(" ")
|
|
322
|
+
fields = beeORM.parseArray(fields)
|
|
323
|
+
fields = fields.length ? fields : Object.keys(model.schema)
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
fields
|
|
327
|
+
.map((field)=> {
|
|
328
|
+
|
|
329
|
+
orderBy.push(`WHEN ${field} = '${string}' THEN ${relevance[0]} WHEN ${field} LIKE '${string}%' THEN ${relevance[1]} WHEN ${field} LIKE '%${string}%' THEN ${relevance[2]} WHEN ${field} LIKE '%${string.replace(/ /g, "%")}%' THEN ${relevance[3]}`)
|
|
330
|
+
|
|
331
|
+
words
|
|
332
|
+
.map((word, i)=> {
|
|
333
|
+
|
|
334
|
+
where.push(`${field} LIKE '%${word}%'`)
|
|
335
|
+
|
|
336
|
+
if(words.length > 1)
|
|
337
|
+
orderBy.push(`WHEN ${field} = '${word}' THEN ${(relevance[4] * (i+1))} WHEN ${field} LIKE '${word}%' THEN ${(relevance[4] * (i+1)) + relevance[1]} WHEN ${field} LIKE '%${word}%' THEN ${(relevance[4] * (i+1)) + relevance[2]}`)
|
|
338
|
+
})
|
|
339
|
+
})
|
|
340
|
+
|
|
341
|
+
script[0]['where'].push(`(${where.join(' OR ')})`)
|
|
342
|
+
script[0]['orderBy'].unshift(`CASE ${orderBy.join(' ')} ELSE ${100000} END ASC`)
|
|
343
|
+
|
|
344
|
+
return this
|
|
345
|
+
},
|
|
346
|
+
|
|
347
|
+
insert: async function(_data, params = {}) {
|
|
348
|
+
|
|
349
|
+
//data = beeORM.forceData(data, req)
|
|
350
|
+
|
|
351
|
+
if(model.relations && params.relations)
|
|
352
|
+
await Promise
|
|
353
|
+
.all(
|
|
354
|
+
Object
|
|
355
|
+
.keys(model.relations)
|
|
356
|
+
.map(async field => {
|
|
357
|
+
let where = []
|
|
358
|
+
let array = model.relations[field].split(" ")[0].split(".")
|
|
359
|
+
let parentTable = array[0]
|
|
360
|
+
let parentField = array[1]
|
|
361
|
+
let parentRels = global.configs.models[parentTable].relations
|
|
362
|
+
|
|
363
|
+
Object
|
|
364
|
+
.keys(parentRels)
|
|
365
|
+
.map(fieldRel => where.push(`${fieldRel} = '${params.relations[parentTable][fieldRel]}'`))
|
|
366
|
+
|
|
367
|
+
let SQL = `SELECT ${parentField} FROM ${parentTable} WHERE ${where.join(" AND ")}`
|
|
368
|
+
|
|
369
|
+
SQL = await dbExec(SQL)
|
|
370
|
+
|
|
371
|
+
Array.isArray(_data)
|
|
372
|
+
? _data.map(a => a[parentField] = SQL[0][parentField])
|
|
373
|
+
: _data[parentField] = SQL[0][parentField]
|
|
374
|
+
})
|
|
375
|
+
)
|
|
376
|
+
|
|
377
|
+
let onlyFields = script[0].fields.concat((req.onlyFields||{})[model.table] || [])
|
|
378
|
+
let sql = beeORM.sqlInsertUpdate(model, _data, onlyFields, 'INSERT')
|
|
379
|
+
|
|
380
|
+
_data = await dbExec(sql.SQL, sql.binds)
|
|
381
|
+
|
|
382
|
+
inserts.push({..._data, model: model.table})
|
|
383
|
+
this.insertId = _data.insertId
|
|
384
|
+
|
|
385
|
+
return {...this, result: {...sql.result,..._data}}
|
|
386
|
+
},
|
|
387
|
+
|
|
388
|
+
update: async function(data, ids = []) { // TODO criar auditoria
|
|
389
|
+
|
|
390
|
+
//data = beeORM.forceData(data, req)
|
|
391
|
+
|
|
392
|
+
let onlyFields = script[0].fields.concat((req.onlyFields||{})[model.table] || [])
|
|
393
|
+
let sql = beeORM.sqlInsertUpdate(model, data, onlyFields, 'UPDATE')
|
|
394
|
+
|
|
395
|
+
sql.SQL += beeORM.modelSqlWhere(model, ids, req.middleware)
|
|
396
|
+
sql.SQL += script[0]['where'].length
|
|
397
|
+
? (!ids.length ? ' WHERE ' : ' AND ') + script[0]['where'].join(" AND ")
|
|
398
|
+
: ''
|
|
399
|
+
|
|
400
|
+
data = await dbExec(sql.SQL, script[0]['binds'])
|
|
401
|
+
|
|
402
|
+
return {...this, result: {...sql.result, ...data}}
|
|
403
|
+
},
|
|
404
|
+
|
|
405
|
+
delete: async function(ids) {
|
|
406
|
+
|
|
407
|
+
const q = beeORM.quote
|
|
408
|
+
|
|
409
|
+
ids = ids && typeof(ids) !== 'object'
|
|
410
|
+
? ids.toString().split(',')
|
|
411
|
+
: ids
|
|
412
|
+
|
|
413
|
+
SQL = 'DELETE FROM ' + q(model.table)
|
|
414
|
+
SQL += beeORM.modelSqlWhere(model, ids, req.middleware)
|
|
415
|
+
SQL += script[0]['where'].length
|
|
416
|
+
? (!ids.length ? ' WHERE ' : ' AND ') + script[0]['where'].join(" AND ")
|
|
417
|
+
: ''
|
|
418
|
+
|
|
419
|
+
data = await dbExec(SQL)
|
|
420
|
+
|
|
421
|
+
return this
|
|
422
|
+
},
|
|
423
|
+
|
|
424
|
+
table: async function(table, where) {
|
|
425
|
+
|
|
426
|
+
const q = beeORM.quote
|
|
427
|
+
|
|
428
|
+
SQL = 'SELECT * FROM ' + q(table)
|
|
429
|
+
SQL += where ? ` WHERE ${where};` : ''
|
|
430
|
+
|
|
431
|
+
let result = await dbExec(SQL)
|
|
432
|
+
|
|
433
|
+
data[table] = result
|
|
434
|
+
counters[table] = result.length
|
|
435
|
+
mainContainer = table;
|
|
436
|
+
|
|
437
|
+
return this
|
|
438
|
+
},
|
|
439
|
+
|
|
440
|
+
query: async function(SQL, binds = [], container = 'query') {
|
|
441
|
+
|
|
442
|
+
let result = await dbExec(SQL, binds, {container: container})
|
|
443
|
+
|
|
444
|
+
counters[container] = (result) ? result.length : 0
|
|
445
|
+
|
|
446
|
+
return this
|
|
447
|
+
},
|
|
448
|
+
|
|
449
|
+
response: function(sendData = data, action = null, status) {
|
|
450
|
+
|
|
451
|
+
let out = {data: sendData, counters, action, error}
|
|
452
|
+
|
|
453
|
+
if(inserts.length)
|
|
454
|
+
out.inserts = inserts
|
|
455
|
+
|
|
456
|
+
if(global.configs.debug)
|
|
457
|
+
out.debug = debug
|
|
458
|
+
|
|
459
|
+
if(status)
|
|
460
|
+
res.status(status).send(out)
|
|
461
|
+
else
|
|
462
|
+
switch(req.method) {
|
|
463
|
+
case 'DELETE' :
|
|
464
|
+
res.status(action ? errorCode || 200 : 204).json(out)
|
|
465
|
+
break
|
|
466
|
+
case 'POST':
|
|
467
|
+
res.status(errorCode || 201).json(out)
|
|
468
|
+
break
|
|
469
|
+
case 'PUT':
|
|
470
|
+
res.status(errorCode || 200).json(out) // TODO deletar props irrelevantes no output
|
|
471
|
+
break
|
|
472
|
+
default:
|
|
473
|
+
res.status(errorCode || 200).json(out)
|
|
474
|
+
}
|
|
475
|
+
},
|
|
476
|
+
|
|
477
|
+
responseError: function(error, errorCode) {
|
|
478
|
+
|
|
479
|
+
let out = {error: {message: error || 'an error has occurred'}}
|
|
480
|
+
|
|
481
|
+
if(global.configs.debug)
|
|
482
|
+
out.debug = debug
|
|
483
|
+
|
|
484
|
+
res.status(errorCode || 500).send(out)
|
|
485
|
+
},
|
|
486
|
+
|
|
487
|
+
ifNull(param) {
|
|
488
|
+
return !this.data ? param : this
|
|
489
|
+
},
|
|
490
|
+
}
|
|
491
|
+
)
|
|
492
492
|
}
|