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 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: {
@@ -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 (filter, options, dataOnly) {
4
+ async function native (...args) {
5
5
  const { isSet } = this.app.lib.aneka
6
- const { get, set } = this.plugin.cache ?? {}
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 (get && !noCache && !options.record) {
14
- const cachedResult = await get({ model: this.name, filter, options })
15
- if (cachedResult) {
16
- cachedResult.cached = true
17
- await execModelHook.call(this, 'afterFindRecord', filter, cachedResult, options)
18
- return dataOnly ? cachedResult.data : cachedResult
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 (set && !noCache) await set({ model: this.name, filter, options, result })
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 (params, opts, dataOnly) {
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
- const { filter, options } = await getFilterAndOptions.call(this, params, opts, action)
71
- return await native.call(this, filter, options, dataOnly)
80
+ return await native.call(this, ...args)
72
81
  }
73
- return await loop.call(this, params, opts, dataOnly)
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 { runHook } = this.app.bajo
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) await runHook('cache:setByFilter', this, filter, result, options)
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 { runHook } = this.app.bajo
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 (!noCache) {
60
- try {
61
- await runHook('cache:getById', this, id)
62
- } catch (err) {
63
- if (err.code === 'CACHED_RESULT') {
64
- const result = err.payload
65
- result.cache = true
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) await runHook('cache:setById', this, id, result, options)
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
 
@@ -72,7 +72,6 @@ async function modelFactory () {
72
72
  super(plugin)
73
73
  defaults(this, options)
74
74
  this.driver = this.connection.driver
75
- this.cacheable = this.cacheable ?? this.driver.cacheable ?? true
76
75
  }
77
76
 
78
77
  action = (name, ...args) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dobo",
3
- "version": "2.11.1",
3
+ "version": "2.11.3",
4
4
  "description": "DBMS for Bajo Framework",
5
5
  "main": "index.js",
6
6
  "scripts": {
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