dobo 2.19.1 → 2.20.0

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.
@@ -430,3 +430,12 @@ export function preparePagination (filter = {}, options = {}) {
430
430
  const sort = buildSort(sortInput, options.allowSortUnindexed)
431
431
  return { limit, page, skip, sort }
432
432
  }
433
+
434
+ export async function clearCache (id) {
435
+ const { clear } = this.app.bajoCache
436
+ if (!clear) return
437
+ await clear({ key: `dobo|${this.name}|getRecord|${id}` })
438
+ await clear({ key: `dobo|${this.name}|findRecord` })
439
+ await clear({ key: `dobo|${this.name}|findAllRecord` })
440
+ await clear({ key: `dobo|${this.name}|findOneRecord` })
441
+ }
@@ -4,45 +4,50 @@ const action = 'findAllRecord'
4
4
  async function native (...args) {
5
5
  const { isSet } = this.app.lib.aneka
6
6
  const { getDefaultValues, t } = this.app.dobo
7
- const { pick, omit } = this.app.lib._
7
+ const { pick, omit, cloneDeep } = this.app.lib._
8
8
  const [params = {}, opts = {}] = args
9
+ const { get, set } = this.app.bajoCache ?? {}
9
10
  opts.dataOnly = opts.dataOnly ?? true
10
11
  const { dataOnly } = opts
11
12
  const { filter, options } = await getFilterAndOptions.call(this, params, opts, action)
12
13
  const { hardCap, warnings } = getDefaultValues(options)
13
14
  if (dataOnly) options.count = false
14
15
  const { noResultSanitizer } = options
15
- try {
16
- await execHook.call(this, 'beforeFindRecord', filter, options)
17
- await execModelHook.call(this, 'beforeFindRecord', filter, options)
18
- await execDynHook.call(this, 'beforeFindRecord', filter, options)
19
- let result = options.record ?? (await this.driver._findAllRecord(this, filter, options)) ?? {}
20
- result.limit = filter.limit
21
- result.filter = pick(filter, ['query', 'match', 'sort'])
22
- result.warnings = result.warnings ?? []
23
- if (!options.count) result = omit(result, ['count', 'pages'])
24
- else if (options.count && result.count > hardCap) {
25
- result.warnings.push(t('hardCapWarning%s%s', result.count, hardCap))
26
- result.count = hardCap
27
- result.hardCapped = true
16
+ await execHook.call(this, 'beforeFindRecord', filter, options)
17
+ await execModelHook.call(this, 'beforeFindRecord', filter, options)
18
+ await execDynHook.call(this, 'beforeFindRecord', filter, options)
19
+ const cFilter = cloneDeep(filter)
20
+ if (get) {
21
+ const resp = await get({ model: this, action, filter: cFilter, options })
22
+ if (resp) {
23
+ resp.cached = true
24
+ return dataOnly ? resp.data : resp
28
25
  }
29
- result.pages = options.count ? Math.ceil(result.count / filter.limit) : undefined
30
- if (!warnings) delete result.warnings
26
+ }
27
+ let result = options.record ?? (await this.driver._findAllRecord(this, filter, options)) ?? {}
28
+ result.limit = filter.limit
29
+ result.filter = pick(filter, ['query', 'match', 'sort'])
30
+ result.warnings = result.warnings ?? []
31
+ if (!options.count) result = omit(result, ['count', 'pages'])
32
+ else if (options.count && result.count > hardCap) {
33
+ result.warnings.push(t('hardCapWarning%s%s', result.count, hardCap))
34
+ result.count = hardCap
35
+ result.hardCapped = true
36
+ }
37
+ result.pages = options.count ? Math.ceil(result.count / filter.limit) : undefined
38
+ if (!warnings) delete result.warnings
31
39
 
32
- if (!noResultSanitizer) {
33
- for (const idx in result.data) {
34
- result.data[idx] = await this.sanitizeRecord(result.data[idx], options)
35
- }
40
+ if (!noResultSanitizer) {
41
+ for (const idx in result.data) {
42
+ result.data[idx] = await this.sanitizeRecord(result.data[idx], options)
36
43
  }
37
- if (isSet(options.refs)) await getMultiRefs.call(this, result.data, options)
38
- await execDynHook.call(this, 'afterFindRecord', filter, result, options)
39
- await execModelHook.call(this, 'afterFindRecord', filter, result, options)
40
- await execHook.call(this, 'afterFindRecord', filter, result, options)
41
- return dataOnly ? result.data : result
42
- } catch (err) {
43
- if (err.code === 'cachedResult') return err.data
44
- throw err
45
44
  }
45
+ if (isSet(options.refs)) await getMultiRefs.call(this, result.data, options)
46
+ await execDynHook.call(this, 'afterFindRecord', filter, result, options)
47
+ await execModelHook.call(this, 'afterFindRecord', filter, result, options)
48
+ await execHook.call(this, 'afterFindRecord', filter, result, options)
49
+ if (set) await set({ model: this, action, filter: cFilter, options, result })
50
+ return dataOnly ? result.data : result
46
51
  }
47
52
 
48
53
  async function loop (...args) {
@@ -69,45 +69,50 @@ async function findRecord (...args) {
69
69
  const { getDefaultValues, t } = this.app.dobo
70
70
  const [params = {}, opts = {}] = args
71
71
  const { isSet } = this.app.lib.aneka
72
- const { pick, omit } = this.app.lib._
72
+ const { pick, omit, cloneDeep } = this.app.lib._
73
+ const { get, set } = this.app.bajoCache ?? {}
73
74
  opts.dataOnly = opts.dataOnly ?? true
74
75
  const { dataOnly } = opts
75
76
  const { filter, options } = await getFilterAndOptions.call(this, params, opts, action)
76
77
  const { hardCap, warnings } = getDefaultValues(options)
77
78
  if (dataOnly) options.count = false
78
79
  const { noResultSanitizer } = options
79
- try {
80
- await execHook.call(this, 'beforeFindRecord', filter, options)
81
- await execModelHook.call(this, 'beforeFindRecord', filter, options)
82
- await execDynHook.call(this, 'beforeFindRecord', filter, options)
83
- let result = options.record ?? (await this.driver._findRecord(this, filter, options)) ?? {}
84
- result.page = filter.page
85
- result.limit = filter.limit
86
- result.filter = pick(filter, ['query', 'match', 'sort'])
87
- result.warnings = result.warnings ?? []
88
- if (!options.count) result = omit(result, ['count', 'pages'])
89
- else if (options.count && result.count > hardCap) {
90
- result.warnings.push(t('hardCapWarning%s%s', result.count, hardCap))
91
- result.count = hardCap
92
- result.hardCapped = true
80
+ await execHook.call(this, 'beforeFindRecord', filter, options)
81
+ await execModelHook.call(this, 'beforeFindRecord', filter, options)
82
+ await execDynHook.call(this, 'beforeFindRecord', filter, options)
83
+ const cFilter = cloneDeep(filter)
84
+ if (get) {
85
+ const resp = await get({ model: this, action, filter: cFilter, options })
86
+ if (resp) {
87
+ resp.cached = true
88
+ return dataOnly ? resp.data : resp
93
89
  }
94
- result.pages = options.count ? Math.ceil(result.count / filter.limit) : undefined
95
- if (!warnings) delete result.warnings
90
+ }
91
+ let result = options.record ?? (await this.driver._findRecord(this, filter, options)) ?? {}
92
+ result.page = filter.page
93
+ result.limit = filter.limit
94
+ result.filter = pick(filter, ['query', 'search', 'sort'])
95
+ result.warnings = result.warnings ?? []
96
+ if (!options.count) result = omit(result, ['count', 'pages'])
97
+ else if (options.count && result.count > hardCap) {
98
+ result.warnings.push(t('hardCapWarning%s%s', result.count, hardCap))
99
+ result.count = hardCap
100
+ result.hardCapped = true
101
+ }
102
+ result.pages = options.count ? Math.ceil(result.count / filter.limit) : undefined
103
+ if (!warnings) delete result.warnings
96
104
 
97
- if (!noResultSanitizer) {
98
- for (const idx in result.data) {
99
- result.data[idx] = await this.sanitizeRecord(result.data[idx], options)
100
- }
105
+ if (!noResultSanitizer) {
106
+ for (const idx in result.data) {
107
+ result.data[idx] = await this.sanitizeRecord(result.data[idx], options)
101
108
  }
102
- if (isSet(options.refs)) await getMultiRefs.call(this, result.data, options)
103
- await execDynHook.call(this, 'afterFindRecord', filter, result, options)
104
- await execModelHook.call(this, 'afterFindRecord', filter, result, options)
105
- await execHook.call(this, 'afterFindRecord', filter, result, options)
106
- return dataOnly ? result.data : result
107
- } catch (err) {
108
- if (err.code === 'cachedResult') return err.data
109
- throw err
110
109
  }
110
+ if (isSet(options.refs)) await getMultiRefs.call(this, result.data, options)
111
+ await execDynHook.call(this, 'afterFindRecord', filter, result, options)
112
+ await execModelHook.call(this, 'afterFindRecord', filter, result, options)
113
+ await execHook.call(this, 'afterFindRecord', filter, result, options)
114
+ if (set) await set({ model: this, action, filter: cFilter, options, result })
115
+ return dataOnly ? result.data : result
111
116
  }
112
117
 
113
118
  export default findRecord
@@ -48,29 +48,33 @@ async function getRecord (...args) {
48
48
  const { getDefaultValues } = this.app.dobo
49
49
  const { isEmpty } = this.app.lib._
50
50
  const { isSet } = this.app.lib.aneka
51
+ const { get, set } = this.app.bajoCache ?? {}
51
52
  opts.dataOnly = opts.dataOnly ?? true
52
53
  const { dataOnly } = opts
53
54
  const { options } = await getFilterAndOptions.call(this, null, opts, action)
54
55
  const { noResultSanitizer } = options
55
56
  id = this.sanitizeId(id)
56
- try {
57
- await execHook.call(this, 'beforeGetRecord', id, options)
58
- await execModelHook.call(this, 'beforeGetRecord', id, options)
59
- await execDynHook.call(this, 'beforeGetRecord', id, options)
60
- const result = options.record ?? (await this.driver._getRecord(this, id, options)) ?? {}
61
- const { warnings } = getDefaultValues(options)
62
- if (!warnings) delete result.warnings
63
- if (isEmpty(result.data) && !options.throwNotFound) return dataOnly ? undefined : { data: undefined }
64
- if (!noResultSanitizer) result.data = await this.sanitizeRecord(result.data, options)
65
- if (isSet(options.refs)) await getSingleRef.call(this, result.data, options)
66
- await execDynHook.call(this, 'afterGetRecord', id, result, options)
67
- await execModelHook.call(this, 'afterGetRecord', id, result, options)
68
- await execHook.call(this, 'afterGetRecord', id, result, options)
69
- return dataOnly ? result.data : result
70
- } catch (err) {
71
- if (err.code === 'cachedResult') return err.data
72
- throw err
57
+ await execHook.call(this, 'beforeGetRecord', id, options)
58
+ await execModelHook.call(this, 'beforeGetRecord', id, options)
59
+ await execDynHook.call(this, 'beforeGetRecord', id, options)
60
+ if (get) {
61
+ const resp = await get({ model: this, action, id, options })
62
+ if (resp) {
63
+ resp.cached = true
64
+ return dataOnly ? resp.data : resp
65
+ }
73
66
  }
67
+ const result = options.record ?? (await this.driver._getRecord(this, id, options)) ?? {}
68
+ const { warnings } = getDefaultValues(options)
69
+ if (!warnings) delete result.warnings
70
+ if (isEmpty(result.data) && !options.throwNotFound) return dataOnly ? undefined : { data: undefined }
71
+ if (!noResultSanitizer) result.data = await this.sanitizeRecord(result.data, options)
72
+ if (isSet(options.refs)) await getSingleRef.call(this, result.data, options)
73
+ await execDynHook.call(this, 'afterGetRecord', id, result, options)
74
+ await execModelHook.call(this, 'afterGetRecord', id, result, options)
75
+ await execHook.call(this, 'afterGetRecord', id, result, options)
76
+ if (set) await set({ model: this, action, id, options, result })
77
+ return dataOnly ? result.data : result
74
78
  }
75
79
 
76
80
  export default getRecord
@@ -1,4 +1,4 @@
1
- import { getFilterAndOptions, execHook, execModelHook, execDynHook, getSingleRef, handleReq } from './_util.js'
1
+ import { getFilterAndOptions, execHook, execModelHook, execDynHook, getSingleRef, handleReq, clearCache } from './_util.js'
2
2
  const action = 'removeRecord'
3
3
 
4
4
  /**
@@ -45,6 +45,7 @@ async function removeRecord (...args) {
45
45
  await execModelHook.call(this, 'beforeRemoveRecord', id, options)
46
46
  await execDynHook.call(this, 'beforeRemoveRecord', id, options)
47
47
  const result = options.record ?? (await this.driver._removeRecord(this, id, options)) ?? {}
48
+ await clearCache.call(this, id)
48
49
  if (noResult) return
49
50
  const { warnings } = getDefaultValues(options)
50
51
  if (!warnings) delete result.warnings
@@ -1,4 +1,4 @@
1
- import { getFilterAndOptions, execHook, execValidation, execModelHook, execDynHook, getSingleRef, handleReq } from './_util.js'
1
+ import { getFilterAndOptions, execHook, execValidation, execModelHook, execDynHook, getSingleRef, handleReq, clearCache } from './_util.js'
2
2
  import { onlyTypes } from './create-record.js'
3
3
  const action = 'updateRecord'
4
4
 
@@ -67,6 +67,7 @@ async function updateRecord (...args) {
67
67
  await execDynHook.call(this, 'beforeUpdateRecord', id, input, options)
68
68
  if (!noValidation) await execValidation.call(this, input, options)
69
69
  const result = options.record ?? (await this.driver._updateRecord(this, id, input, options)) ?? {}
70
+ await clearCache.call(this, id)
70
71
  if (noResult) return
71
72
  const { warnings } = getDefaultValues(options)
72
73
  if (!warnings) delete result.warnings
@@ -1,4 +1,4 @@
1
- import { getFilterAndOptions, execHook, execModelHook, execDynHook, execValidation, getSingleRef, handleReq } from './_util.js'
1
+ import { getFilterAndOptions, execHook, execModelHook, execDynHook, execValidation, getSingleRef, handleReq, clearCache } from './_util.js'
2
2
  const action = 'upsertRecord'
3
3
 
4
4
  async function native (body = {}, opts = {}) {
@@ -16,6 +16,7 @@ async function native (body = {}, opts = {}) {
16
16
  await execModelHook.call(this, 'beforeUpsertRecord', input, options)
17
17
  await execDynHook.call(this, 'beforeUpsertRecord', input, options)
18
18
  const result = options.record ?? (await this.driver._upsertRecord(this, input, options)) ?? {}
19
+ await clearCache.call(this, body.id)
19
20
  if (noResult) return
20
21
  const { warnings } = getDefaultValues(options)
21
22
  if (!warnings) delete result.warnings
@@ -39,7 +40,7 @@ async function manual (body = {}, options = {}) {
39
40
  } catch (err) {
40
41
  }
41
42
  }
42
- const id = get(old, 'dara.id')
43
+ const id = get(old, 'data.id')
43
44
  if (id) return await this.updateRecord(old.data.id, omit(body, ['id']), options)
44
45
  return await this.createRecord(body, options)
45
46
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dobo",
3
- "version": "2.19.1",
3
+ "version": "2.20.0",
4
4
  "description": "DBMS for Bajo Framework",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/wiki/CHANGES.md CHANGED
@@ -2,9 +2,10 @@
2
2
 
3
3
  ## 2026-04-21
4
4
 
5
- - [2.5.1] Bug fix in ```collect-models.js```, now values are sanitized with ```parseObject()```
6
- - [2.5.1] Bug fix in ```options.dataOnly``` on all model methods
7
- - [2.5.1] Add ```options.noMagic```
5
+ - [2.19.1] Bug fix in ```collect-models.js```, now values are sanitized with ```parseObject()```
6
+ - [2.19.1] Bug fix in ```options.dataOnly``` on all model methods
7
+ - [2.19.1] Add ```options.noMagic```
8
+ - [2.20.0] Revert back to NOT using hooks for caching
8
9
 
9
10
  ## 2026-04-19
10
11