dobo 2.11.1 → 2.11.3
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/index.js +3 -0
- package/lib/collect-models.js +7 -2
- package/lib/factory/model/find-all-record.js +25 -16
- package/lib/factory/model/find-one-record.js +1 -1
- package/lib/factory/model/find-record.js +18 -14
- package/lib/factory/model/get-record.js +12 -11
- package/lib/factory/model.js +0 -1
- package/package.json +1 -1
- package/wiki/CHANGES.md +5 -0
package/index.js
CHANGED
|
@@ -153,6 +153,9 @@ async function factory (pkgName) {
|
|
|
153
153
|
hardLimit: 10000,
|
|
154
154
|
maxPage: 50,
|
|
155
155
|
sort: ['dt:-1', 'updatedAt:-1', 'updated_at:-1', 'createdAt:-1', 'createdAt:-1', 'ts:-1', 'username', 'name']
|
|
156
|
+
},
|
|
157
|
+
cache: {
|
|
158
|
+
ttlDur: '10s'
|
|
156
159
|
}
|
|
157
160
|
},
|
|
158
161
|
memDb: {
|
package/lib/collect-models.js
CHANGED
|
@@ -227,8 +227,8 @@ export async function sanitizeAll (model) {
|
|
|
227
227
|
async function createSchema (item) {
|
|
228
228
|
const { readConfig } = this.app.bajo
|
|
229
229
|
const { fastGlob } = this.app.lib
|
|
230
|
-
const { find, isPlainObject, orderBy } = this.app.lib._
|
|
231
|
-
const { mergeObjectsByKey } = this.app.lib.aneka
|
|
230
|
+
const { find, isPlainObject, orderBy, get, cloneDeep } = this.app.lib._
|
|
231
|
+
const { mergeObjectsByKey, defaultsDeep } = this.app.lib.aneka
|
|
232
232
|
if (item.file && !item.base) item.base = path.basename(item.file, path.extname(item.file))
|
|
233
233
|
item.attachment = item.attachment ?? true
|
|
234
234
|
const feats = item.features ?? []
|
|
@@ -255,6 +255,11 @@ async function createSchema (item) {
|
|
|
255
255
|
if (!item.connection && conn === 'default') item.connection = this.getConnection('memory')
|
|
256
256
|
}
|
|
257
257
|
if (!item.connection) this.fatal('unknownConn%s%s', conn, item.name)
|
|
258
|
+
const defCache = cloneDeep(get(this, 'app.bajoCache.config.default', this.config.default.cache))
|
|
259
|
+
item.cache = item.cache ?? item.connection.options.cache ?? defCache
|
|
260
|
+
if (item.cache === true) item.cache = get(item, 'connection.options.cache', defCache)
|
|
261
|
+
else if (item.cache === false) item.cache = { ttlDur: 0 }
|
|
262
|
+
item.cache = defaultsDeep(get(this, `app.bajoCache.config.dobo.${item.name}`), item.cache)
|
|
258
263
|
await findAllProps.call(this, item, props, indexes)
|
|
259
264
|
await findAllFeats.call(this, item, feats, indexes)
|
|
260
265
|
await findAllIndexes.call(this, item, indexes)
|
|
@@ -1,21 +1,28 @@
|
|
|
1
1
|
import { getMultiRefs, execHook, execModelHook, execDynHook, getFilterAndOptions, cloneOptions } from './_util.js'
|
|
2
2
|
const action = 'findAllRecord'
|
|
3
3
|
|
|
4
|
-
async function native (
|
|
4
|
+
async function native (...args) {
|
|
5
5
|
const { isSet } = this.app.lib.aneka
|
|
6
|
-
const {
|
|
6
|
+
const { cloneDeep } = this.app.lib._
|
|
7
|
+
const [params = {}, opts = {}] = args
|
|
8
|
+
const { dataOnly = true } = opts
|
|
9
|
+
const { get: getCache, set: setCache } = this.app.bajoCache ?? {}
|
|
10
|
+
const { filter, options } = await getFilterAndOptions.call(this, params, opts, action)
|
|
7
11
|
if (dataOnly) options.count = false
|
|
8
12
|
let { noResultSanitizer, noCache } = options
|
|
9
|
-
if (!this.cacheable) noCache = true
|
|
10
13
|
await execHook.call(this, 'beforeFindRecord', filter, options)
|
|
11
14
|
await execModelHook.call(this, 'beforeFindRecord', filter, options)
|
|
12
15
|
await execDynHook.call(this, 'beforeFindRecord', filter, options)
|
|
13
|
-
if (
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
if (this.cache.ttlDur === 0 || options.record) noCache = true
|
|
17
|
+
const cacheFilter = cloneDeep(filter)
|
|
18
|
+
if (!noCache && getCache) {
|
|
19
|
+
const result = await getCache({ model: this, filter: cacheFilter, options })
|
|
20
|
+
if (result) {
|
|
21
|
+
for (const idx in result.data) {
|
|
22
|
+
result.data[idx] = await this.sanitizeRecord(result.data[idx], options)
|
|
23
|
+
}
|
|
24
|
+
result.cached = true
|
|
25
|
+
return dataOnly ? result.data : result
|
|
19
26
|
}
|
|
20
27
|
}
|
|
21
28
|
const result = options.record ?? (await this.driver._findAllRecord(this, filter, options)) ?? {}
|
|
@@ -28,12 +35,17 @@ async function native (filter, options, dataOnly) {
|
|
|
28
35
|
await execDynHook.call(this, 'afterFindRecord', filter, result, options)
|
|
29
36
|
await execModelHook.call(this, 'afterFindRecord', filter, result, options)
|
|
30
37
|
await execHook.call(this, 'afterFindRecord', filter, result, options)
|
|
31
|
-
if (
|
|
38
|
+
if (!noCache && setCache) {
|
|
39
|
+
await setCache({ model: this, filter: cacheFilter, result, options })
|
|
40
|
+
result.cached = false
|
|
41
|
+
}
|
|
32
42
|
return dataOnly ? result.data : result
|
|
33
43
|
}
|
|
34
44
|
|
|
35
|
-
async function loop (
|
|
45
|
+
async function loop (...args) {
|
|
36
46
|
const { cloneDeep } = this.app.lib._
|
|
47
|
+
const [params = {}, opts = {}] = args
|
|
48
|
+
const { dataOnly = true } = opts
|
|
37
49
|
const { filter, options } = await getFilterAndOptions.call(this, params, opts, action)
|
|
38
50
|
const { maxLimit, hardLimit } = this.app.dobo.config.default.filter
|
|
39
51
|
const nFilter = cloneDeep(filter || {})
|
|
@@ -64,13 +76,10 @@ async function loop (params, opts, dataOnly) {
|
|
|
64
76
|
async function findAllRecord (...args) {
|
|
65
77
|
// can't use action here, because people tends to use is without arguments
|
|
66
78
|
// if (args.length === 0) return this.action(action, ...args)
|
|
67
|
-
const [params = {}, opts = {}] = args
|
|
68
|
-
const { dataOnly = true } = opts
|
|
69
79
|
if (this.driver.findAllRecord) {
|
|
70
|
-
|
|
71
|
-
return await native.call(this, filter, options, dataOnly)
|
|
80
|
+
return await native.call(this, ...args)
|
|
72
81
|
}
|
|
73
|
-
return await loop.call(this,
|
|
82
|
+
return await loop.call(this, ...args)
|
|
74
83
|
}
|
|
75
84
|
|
|
76
85
|
export default findAllRecord
|
|
@@ -15,7 +15,7 @@ async function findOneRecord (...args) {
|
|
|
15
15
|
nFilter.limit = 1
|
|
16
16
|
const result = await this.findRecord(nFilter, nOptions)
|
|
17
17
|
const data = result.data[0]
|
|
18
|
-
return dataOnly ? data : { data }
|
|
18
|
+
return dataOnly ? data : { data, cached: result.cached, warnings: result.warnings }
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
export default findOneRecord
|
|
@@ -68,26 +68,27 @@ async function findRecord (...args) {
|
|
|
68
68
|
if (args.length === 0) return this.action(action, ...args)
|
|
69
69
|
const [params = {}, opts = {}] = args
|
|
70
70
|
const { isSet } = this.app.lib.aneka
|
|
71
|
-
const {
|
|
71
|
+
const { cloneDeep } = this.app.lib._
|
|
72
72
|
const { dataOnly = true } = opts
|
|
73
|
+
const { get: getCache, set: setCache } = this.app.bajoCache ?? {}
|
|
73
74
|
const { filter, options } = await getFilterAndOptions.call(this, params, opts, action)
|
|
74
75
|
if (dataOnly) options.count = false
|
|
75
76
|
let { noResultSanitizer, noCache } = options
|
|
76
|
-
if (!this.cacheable || !options.record) noCache = true
|
|
77
|
-
if (!noCache) {
|
|
78
|
-
try {
|
|
79
|
-
await runHook('cache:getByFilter', this, filter)
|
|
80
|
-
} catch (err) {
|
|
81
|
-
if (err.code === 'CACHED_RESULT') {
|
|
82
|
-
const result = err.payload
|
|
83
|
-
result.cache = true
|
|
84
|
-
return dataOnly ? result.data : result
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
77
|
await execHook.call(this, 'beforeFindRecord', filter, options)
|
|
89
78
|
await execModelHook.call(this, 'beforeFindRecord', filter, options)
|
|
90
79
|
await execDynHook.call(this, 'beforeFindRecord', filter, options)
|
|
80
|
+
if (this.cache.ttlDur === 0 || options.record) noCache = true
|
|
81
|
+
const cacheFilter = cloneDeep(filter)
|
|
82
|
+
if (!noCache && getCache) {
|
|
83
|
+
const result = await getCache({ model: this, filter: cacheFilter, options })
|
|
84
|
+
if (result) {
|
|
85
|
+
for (const idx in result.data) {
|
|
86
|
+
result.data[idx] = await this.sanitizeRecord(result.data[idx], options)
|
|
87
|
+
}
|
|
88
|
+
result.cached = true
|
|
89
|
+
return dataOnly ? result.data : result
|
|
90
|
+
}
|
|
91
|
+
}
|
|
91
92
|
const result = options.record ?? (await this.driver._findRecord(this, filter, options)) ?? {}
|
|
92
93
|
if (!noResultSanitizer) {
|
|
93
94
|
for (const idx in result.data) {
|
|
@@ -98,7 +99,10 @@ async function findRecord (...args) {
|
|
|
98
99
|
await execDynHook.call(this, 'afterFindRecord', filter, result, options)
|
|
99
100
|
await execModelHook.call(this, 'afterFindRecord', filter, result, options)
|
|
100
101
|
await execHook.call(this, 'afterFindRecord', filter, result, options)
|
|
101
|
-
if (!noCache
|
|
102
|
+
if (!noCache && setCache) {
|
|
103
|
+
await setCache({ model: this, filter: cacheFilter, result, options })
|
|
104
|
+
result.cached = false
|
|
105
|
+
}
|
|
102
106
|
return dataOnly ? result.data : result
|
|
103
107
|
}
|
|
104
108
|
|
|
@@ -47,7 +47,7 @@ async function getRecord (...args) {
|
|
|
47
47
|
let [id, opts = {}] = args
|
|
48
48
|
const { isEmpty } = this.app.lib._
|
|
49
49
|
const { isSet } = this.app.lib.aneka
|
|
50
|
-
const {
|
|
50
|
+
const { get: getCache, set: setCache } = this.app.bajoCache ?? {}
|
|
51
51
|
const { dataOnly = true } = opts
|
|
52
52
|
const { options } = await getFilterAndOptions.call(this, null, opts, action)
|
|
53
53
|
let { noResultSanitizer, noCache } = options
|
|
@@ -56,15 +56,13 @@ async function getRecord (...args) {
|
|
|
56
56
|
await execHook.call(this, 'beforeGetRecord', id, options)
|
|
57
57
|
await execModelHook.call(this, 'beforeGetRecord', id, options)
|
|
58
58
|
await execDynHook.call(this, 'beforeGetRecord', id, options)
|
|
59
|
-
if (
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
return dataOnly ? result.data : result
|
|
67
|
-
}
|
|
59
|
+
if (this.cache.ttlDur === 0 || options.record) noCache = true
|
|
60
|
+
if (!noCache && getCache) {
|
|
61
|
+
const result = await getCache({ model: this, id, options })
|
|
62
|
+
if (result) {
|
|
63
|
+
result.data = await this.sanitizeRecord(result.data, options)
|
|
64
|
+
result.cached = true
|
|
65
|
+
return dataOnly ? result.data : result
|
|
68
66
|
}
|
|
69
67
|
}
|
|
70
68
|
const result = options.record ?? (await this.driver._getRecord(this, id, options)) ?? {}
|
|
@@ -74,7 +72,10 @@ async function getRecord (...args) {
|
|
|
74
72
|
await execDynHook.call(this, 'afterGetRecord', id, result, options)
|
|
75
73
|
await execModelHook.call(this, 'afterGetRecord', id, result, options)
|
|
76
74
|
await execHook.call(this, 'afterGetRecord', id, result, options)
|
|
77
|
-
if (!noCache
|
|
75
|
+
if (!noCache && setCache) {
|
|
76
|
+
await setCache({ model: this, id, result, options })
|
|
77
|
+
result.cached = false
|
|
78
|
+
}
|
|
78
79
|
return dataOnly ? result.data : result
|
|
79
80
|
}
|
|
80
81
|
|
package/lib/factory/model.js
CHANGED
package/package.json
CHANGED
package/wiki/CHANGES.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Changes
|
|
2
2
|
|
|
3
|
+
## 2026-03-25
|
|
4
|
+
|
|
5
|
+
- [2.11.2] Bug fix in result sets cache
|
|
6
|
+
- [2.11.3] Bug fix in cache handling if ```bajoCache``` isn't loaded
|
|
7
|
+
|
|
3
8
|
## 2026-03-17
|
|
4
9
|
|
|
5
10
|
- [2.11.1] Bug fix on ```model.validate()```: if ```partial``` is true, set ```fields``` from ```body``` keys
|