Skip to content
This repository was archived by the owner on May 25, 2025. It is now read-only.

Commit 4bf6b81

Browse files
committed
chore: apply comments
1 parent cb8794b commit 4bf6b81

File tree

3 files changed

+99
-19
lines changed

3 files changed

+99
-19
lines changed

src/commondao/common.dao.model.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -285,20 +285,30 @@ export interface CommonDaoPatchByIdOptions<DBM extends BaseDBEntity>
285285
extends CommonDaoSaveBatchOptions<DBM> {
286286
/**
287287
* Defaults to false.
288-
* With false, if the row doesn't exist - it will be auto-created with `dao.create`.
289-
* With true, if the row doesn't exist - it will throw an error.
288+
* With false, if the row doesn't exist - it will throw an error.
289+
* With true, if the row doesn't exist - it will be auto-created with `dao.create`.
290290
*
291291
* Use true when you expect the row to exist and it would be an error if it doesn't.
292292
*/
293-
requireToExist?: boolean
293+
createIfMissing?: boolean
294294
}
295295

296296
export interface CommonDaoPatchOptions<DBM extends BaseDBEntity>
297297
extends CommonDaoSaveBatchOptions<DBM> {
298298
/**
299299
* If true - patch will skip loading from DB, and will just optimistically patch passed object.
300+
*
301+
* Consequently, when the row doesn't exist - it will be auto-created with `dao.create`.
300302
*/
301303
skipDBRead?: boolean
304+
/**
305+
* Defaults to false.
306+
* With false, if the row doesn't exist - it will throw an error.
307+
* With true, if the row doesn't exist - it will be auto-created with `dao.create`.
308+
*
309+
* Use true when you expect the row to exist and it would be an error if it doesn't.
310+
*/
311+
createIfMissing?: boolean
302312
}
303313

304314
/**

src/commondao/common.dao.test.ts

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,14 @@ test('should propagate pipe errors', async () => {
156156

157157
test('patchById', async () => {
158158
const id = '123456'
159+
const testItem: TestItemBM = {
160+
id,
161+
k1: 'k1',
162+
created: 1529539200 as UnixTimestamp,
163+
updated: 1529539200 as UnixTimestamp,
164+
}
165+
await dao.save(testItem)
166+
159167
const r = await dao.patchById(id, {
160168
k1: 'k111',
161169
})
@@ -173,7 +181,7 @@ test('patchById', async () => {
173181
`)
174182
})
175183

176-
test('patchById requireToExist', async () => {
184+
test('patchById createIfMissing false', async () => {
177185
const id = '123456'
178186
expect(
179187
await pExpectedErrorString(
@@ -183,11 +191,11 @@ test('patchById requireToExist', async () => {
183191
k1: 'k111',
184192
},
185193
{
186-
requireToExist: true,
194+
createIfMissing: false,
187195
},
188196
),
189197
),
190-
).toMatchInlineSnapshot(`"AssertionError: TEST_TABLE.patchById row is required, but missing"`)
198+
).toMatchInlineSnapshot(`"AssertionError: DB row required, but not found in TEST_TABLE"`)
191199
})
192200

193201
describe('patch', () => {
@@ -222,10 +230,10 @@ describe('patch', () => {
222230
}),
223231
)
224232

225-
expect(error).toBe('AppError: DB row required, but not found in TEST_TABLE')
233+
expect(error).toBe(`AssertionError: DB row required, but not found in TEST_TABLE`)
226234
})
227235

228-
test('should not throw when data does not exist but `skipDBRead` is specified', async () => {
236+
test('should create the data when it does not exist and `skipDBRead` is specified', async () => {
229237
const testItem: TestItemBM = {
230238
id: 'id1',
231239
k1: 'k1',
@@ -246,6 +254,55 @@ describe('patch', () => {
246254
const updatedTestItem = await dao.requireById('id1')
247255
expect(updatedTestItem).toMatchObject({ k1: 'k111' })
248256
})
257+
258+
test('should create the data when it does not exist and `createIfMissing` is specified', async () => {
259+
const testItem: TestItemBM = {
260+
id: 'id1',
261+
k1: 'k1',
262+
created: 1529539200 as UnixTimestamp,
263+
updated: 1529539200 as UnixTimestamp,
264+
}
265+
266+
await dao.patch(
267+
testItem,
268+
{
269+
k1: 'k111',
270+
},
271+
{
272+
createIfMissing: true,
273+
},
274+
)
275+
276+
const updatedTestItem = await dao.requireById('id1')
277+
expect(updatedTestItem).toMatchObject({ k1: 'k111' })
278+
})
279+
280+
test('should throw when `skipDBRead` is true and `createIfMissing` is `false`', async () => {
281+
const testItem: TestItemBM = {
282+
id: 'id1',
283+
k1: 'k1',
284+
created: 1529539200 as UnixTimestamp,
285+
updated: 1529539200 as UnixTimestamp,
286+
}
287+
await dao.save(testItem)
288+
289+
const error = await pExpectedErrorString(
290+
dao.patch(
291+
testItem,
292+
{
293+
k1: 'k111',
294+
},
295+
{
296+
skipDBRead: true,
297+
createIfMissing: false,
298+
},
299+
),
300+
)
301+
302+
expect(error).toBe(
303+
'AssertionError: When `skipDBRead` is set to `true`, `createIfMissing` must not be `false`',
304+
)
305+
})
249306
})
250307

251308
test('patch', async () => {

src/commondao/common.dao.ts

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,7 @@ export class CommonDao<BM extends BaseDBEntity, DBM extends BaseDBEntity = BM, I
679679
}
680680
} else {
681681
const table = opt.table || this.cfg.table
682-
_assert(!opt.requireToExist, `${table}.patchById row is required, but missing`, {
682+
_assert(opt.createIfMissing, `DB row required, but not found in ${table}`, {
683683
id,
684684
table,
685685
})
@@ -717,6 +717,10 @@ export class CommonDao<BM extends BaseDBEntity, DBM extends BaseDBEntity = BM, I
717717
}
718718

719719
if (opt.skipDBRead) {
720+
_assert(
721+
opt.createIfMissing === undefined || opt.createIfMissing,
722+
'When `skipDBRead` is set to `true`, `createIfMissing` must not be `false`',
723+
)
720724
const patched: BM = {
721725
...bm,
722726
...patch,
@@ -728,24 +732,33 @@ export class CommonDao<BM extends BaseDBEntity, DBM extends BaseDBEntity = BM, I
728732
}
729733
Object.assign(bm, patch)
730734
} else {
731-
const loaded = await this.requireById(bm.id as ID, {
735+
const loaded = await this.getById(bm.id as ID, {
732736
// Skipping validation here for performance reasons.
733737
// Validation is going to happen on save anyway, just down below.
734738
skipValidation: true,
735739
...opt,
736740
})
737741

738-
const loadedWithPatch: BM = {
739-
...loaded,
740-
...patch,
741-
}
742+
if (loaded) {
743+
const loadedWithPatch: BM = {
744+
...loaded,
745+
...patch,
746+
}
742747

743-
// Make `bm` exactly the same as `loadedWithPatch`
744-
_objectAssignExact(bm, loadedWithPatch)
748+
// Make `bm` exactly the same as `loadedWithPatch`
749+
_objectAssignExact(bm, loadedWithPatch)
745750

746-
if (_deepJsonEquals(loaded, loadedWithPatch)) {
747-
// Skipping the save operation, as data is the same
748-
return bm
751+
if (_deepJsonEquals(loaded, loadedWithPatch)) {
752+
// Skipping the save operation, as data is the same
753+
return bm
754+
}
755+
} else {
756+
const table = opt.table || this.cfg.table
757+
_assert(opt.createIfMissing, `DB row required, but not found in ${table}`, {
758+
id: bm.id,
759+
table,
760+
})
761+
Object.assign(bm, patch)
749762
}
750763
}
751764

0 commit comments

Comments
 (0)