@platformatic/sql-mapper 0.6.1 → 0.7.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.
- package/lib/entity.js +39 -2
- package/lib/queries/mysql-shared.js +34 -2
- package/lib/queries/pg.js +14 -0
- package/lib/queries/shared.js +17 -1
- package/lib/queries/sqlite.js +3 -0
- package/package.json +1 -1
- package/test/entity.test.js +35 -1
- package/test/helper.js +5 -0
- package/test/updateMany.test.js +318 -0
package/lib/entity.js
CHANGED
|
@@ -116,6 +116,24 @@ function createMapper (defaultDb, sql, log, table, fields, primaryKey, relations
|
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
async function updateMany (args) {
|
|
120
|
+
const db = args.tx || defaultDb
|
|
121
|
+
const fieldsToRetrieve = computeFields(args.fields).map((f) => sql.ident(f))
|
|
122
|
+
if (args.input === undefined) {
|
|
123
|
+
throw new Error('Input not provided.')
|
|
124
|
+
}
|
|
125
|
+
const input = fixInput(args.input)
|
|
126
|
+
let now
|
|
127
|
+
if (autoTimestamp && fields.updated_at) {
|
|
128
|
+
now = new Date()
|
|
129
|
+
input.updated_at = now
|
|
130
|
+
}
|
|
131
|
+
const criteria = computeCriteria(args)
|
|
132
|
+
|
|
133
|
+
const res = await queries.updateMany(db, sql, table, criteria, input, fieldsToRetrieve)
|
|
134
|
+
return res.map(fixOutput)
|
|
135
|
+
}
|
|
136
|
+
|
|
119
137
|
function computeFields (fields) {
|
|
120
138
|
if (!fields) {
|
|
121
139
|
return Object.values(inputToFieldMap)
|
|
@@ -264,7 +282,8 @@ function createMapper (defaultDb, sql, log, table, fields, primaryKey, relations
|
|
|
264
282
|
count,
|
|
265
283
|
insert,
|
|
266
284
|
save,
|
|
267
|
-
delete: _delete
|
|
285
|
+
delete: _delete,
|
|
286
|
+
updateMany
|
|
268
287
|
}
|
|
269
288
|
}
|
|
270
289
|
|
|
@@ -276,12 +295,30 @@ async function buildEntity (db, sql, log, table, queries, autoTimestamp, ignore)
|
|
|
276
295
|
sqlType: column.udt_name,
|
|
277
296
|
isNullable: column.is_nullable === 'YES'
|
|
278
297
|
}
|
|
298
|
+
|
|
299
|
+
// To get enum values in mysql and mariadb
|
|
300
|
+
/* istanbul ignore next */
|
|
301
|
+
if (column.udt_name === 'enum') {
|
|
302
|
+
acc[column.column_name].enum = column.column_type.match(/'(.+?)'/g).map(enumValue => enumValue.slice(1, enumValue.length - 1))
|
|
303
|
+
}
|
|
304
|
+
|
|
279
305
|
if (autoTimestamp && (column.column_name === 'updated_at' || column.column_name === 'inserted_at')) {
|
|
280
306
|
acc[column.column_name].autoTimestamp = true
|
|
281
307
|
}
|
|
282
308
|
return acc
|
|
283
309
|
}, {})
|
|
284
|
-
|
|
310
|
+
// To get enum values in pg
|
|
311
|
+
/* istanbul ignore next */
|
|
312
|
+
if (db.isPg) {
|
|
313
|
+
const enums = await queries.listEnumValues(db, sql, table)
|
|
314
|
+
for (const enumValue of enums) {
|
|
315
|
+
if (!fields[enumValue.column_name].enum) {
|
|
316
|
+
fields[enumValue.column_name].enum = [enumValue.enumlabel]
|
|
317
|
+
} else {
|
|
318
|
+
fields[enumValue.column_name].enum.push(enumValue.enumlabel)
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
285
322
|
const currentRelations = []
|
|
286
323
|
|
|
287
324
|
const constraintsList = await queries.listConstraints(db, sql, table)
|
|
@@ -11,7 +11,7 @@ async function listTables (db, sql) {
|
|
|
11
11
|
|
|
12
12
|
async function listColumns (db, sql, table) {
|
|
13
13
|
const res = await db.query(sql`
|
|
14
|
-
SELECT column_name as column_name, data_type as udt_name, is_nullable as is_nullable
|
|
14
|
+
SELECT column_name as column_name, data_type as udt_name, is_nullable as is_nullable, column_type as column_type
|
|
15
15
|
FROM information_schema.columns
|
|
16
16
|
WHERE table_name = ${table}
|
|
17
17
|
AND table_schema = (SELECT DATABASE())
|
|
@@ -54,9 +54,41 @@ async function updateOne (db, sql, table, input, primaryKey, fieldsToRetrieve) {
|
|
|
54
54
|
return res[0]
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
async function updateMany (db, sql, table, criteria, input, fieldsToRetrieve) {
|
|
58
|
+
const pairs = Object.keys(input).map((key) => {
|
|
59
|
+
const value = input[key]
|
|
60
|
+
return sql`${sql.ident(key)} = ${value}`
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
const selectIds = sql`
|
|
64
|
+
SELECT id
|
|
65
|
+
FROM ${sql.ident(table)}
|
|
66
|
+
WHERE ${sql.join(criteria, sql` AND `)}
|
|
67
|
+
`
|
|
68
|
+
const resp = await db.query(selectIds)
|
|
69
|
+
const ids = resp.map(({ id }) => id)
|
|
70
|
+
|
|
71
|
+
const update = sql`
|
|
72
|
+
UPDATE ${sql.ident(table)}
|
|
73
|
+
SET ${sql.join(pairs, sql`, `)}
|
|
74
|
+
WHERE ${sql.join(criteria, sql` AND `)}
|
|
75
|
+
`
|
|
76
|
+
|
|
77
|
+
await db.query(update)
|
|
78
|
+
|
|
79
|
+
const select = sql`
|
|
80
|
+
SELECT ${sql.join(fieldsToRetrieve, sql`, `)}
|
|
81
|
+
FROM ${sql.ident(table)}
|
|
82
|
+
WHERE id IN (${ids});
|
|
83
|
+
`
|
|
84
|
+
const res = await db.query(select)
|
|
85
|
+
return res
|
|
86
|
+
}
|
|
87
|
+
|
|
57
88
|
module.exports = {
|
|
58
89
|
listTables,
|
|
59
90
|
listColumns,
|
|
60
91
|
listConstraints,
|
|
61
|
-
updateOne
|
|
92
|
+
updateOne,
|
|
93
|
+
updateMany
|
|
62
94
|
}
|
package/lib/queries/pg.js
CHANGED
|
@@ -77,3 +77,17 @@ async function updateOne (db, sql, table, input, primaryKey, fieldsToRetrieve) {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
module.exports.updateOne = updateOne
|
|
80
|
+
|
|
81
|
+
module.exports.updateMany = shared.updateMany
|
|
82
|
+
|
|
83
|
+
async function listEnumValues (db, sql, table) {
|
|
84
|
+
return (await db.query(sql`
|
|
85
|
+
SELECT udt_name, enumlabel, column_name
|
|
86
|
+
FROM pg_enum e
|
|
87
|
+
JOIN pg_type t ON e.enumtypid = t.oid
|
|
88
|
+
JOIN information_schema.columns c on c.udt_name = t.typname
|
|
89
|
+
WHERE table_name = ${table};
|
|
90
|
+
`))
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
module.exports.listEnumValues = listEnumValues
|
package/lib/queries/shared.js
CHANGED
|
@@ -92,9 +92,25 @@ function insertPrep (inputs, inputToFieldMap, fields, sql) {
|
|
|
92
92
|
return { keys, values }
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
async function updateMany (db, sql, table, criteria, input, fieldsToRetrieve) {
|
|
96
|
+
const pairs = Object.keys(input).map((key) => {
|
|
97
|
+
const value = input[key]
|
|
98
|
+
return sql`${sql.ident(key)} = ${value}`
|
|
99
|
+
})
|
|
100
|
+
const update = sql`
|
|
101
|
+
UPDATE ${sql.ident(table)}
|
|
102
|
+
SET ${sql.join(pairs, sql`, `)}
|
|
103
|
+
WHERE ${sql.join(criteria, sql` AND `)}
|
|
104
|
+
RETURNING ${sql.join(fieldsToRetrieve, sql`, `)}
|
|
105
|
+
`
|
|
106
|
+
const res = await db.query(update)
|
|
107
|
+
return res
|
|
108
|
+
}
|
|
109
|
+
|
|
95
110
|
module.exports = {
|
|
96
111
|
insertOne,
|
|
97
112
|
insertPrep,
|
|
98
113
|
deleteAll,
|
|
99
|
-
insertMany
|
|
114
|
+
insertMany,
|
|
115
|
+
updateMany
|
|
100
116
|
}
|
package/lib/queries/sqlite.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const { randomUUID } = require('crypto')
|
|
4
|
+
const shared = require('./shared')
|
|
4
5
|
|
|
5
6
|
async function listTables (db, sql) {
|
|
6
7
|
const tables = await db.query(sql`
|
|
@@ -167,3 +168,5 @@ async function deleteAll (db, sql, table, criteria, fieldsToRetrieve) {
|
|
|
167
168
|
}
|
|
168
169
|
|
|
169
170
|
module.exports.deleteAll = deleteAll
|
|
171
|
+
|
|
172
|
+
module.exports.updateMany = shared.updateMany
|
package/package.json
CHANGED
package/test/entity.test.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const { test } = require('tap')
|
|
4
4
|
|
|
5
|
-
const { clear, connInfo, isSQLite, isMysql } = require('./helper')
|
|
5
|
+
const { clear, connInfo, isSQLite, isMysql, isPg } = require('./helper')
|
|
6
6
|
const { connect } = require('..')
|
|
7
7
|
const fakeLogger = {
|
|
8
8
|
trace: () => {},
|
|
@@ -604,3 +604,37 @@ test('include all fields', async ({ pass, teardown, same, equal }) => {
|
|
|
604
604
|
}])
|
|
605
605
|
}
|
|
606
606
|
})
|
|
607
|
+
|
|
608
|
+
test('include possible values of enum columns', { skip: isSQLite }, async ({ same, teardown }) => {
|
|
609
|
+
async function onDatabaseLoad (db, sql) {
|
|
610
|
+
await clear(db, sql)
|
|
611
|
+
teardown(() => db.dispose())
|
|
612
|
+
|
|
613
|
+
if (isPg) {
|
|
614
|
+
await db.query(sql`
|
|
615
|
+
CREATE TYPE pagetype as enum ('blank', 'non-blank');
|
|
616
|
+
CREATE TABLE pages (
|
|
617
|
+
id INTEGER PRIMARY KEY,
|
|
618
|
+
title VARCHAR(42),
|
|
619
|
+
type pagetype
|
|
620
|
+
);`)
|
|
621
|
+
} else {
|
|
622
|
+
await db.query(sql`CREATE TABLE pages (
|
|
623
|
+
id INTEGER PRIMARY KEY,
|
|
624
|
+
title VARCHAR(42),
|
|
625
|
+
type ENUM ('blank', 'non-blank')
|
|
626
|
+
);
|
|
627
|
+
`)
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
const mapper = await connect({
|
|
631
|
+
connectionString: connInfo.connectionString,
|
|
632
|
+
log: fakeLogger,
|
|
633
|
+
onDatabaseLoad,
|
|
634
|
+
ignore: {},
|
|
635
|
+
hooks: {}
|
|
636
|
+
})
|
|
637
|
+
const pageEntity = mapper.entities.page
|
|
638
|
+
const typeField = pageEntity.fields.type
|
|
639
|
+
same(typeField.enum, ['blank', 'non-blank'])
|
|
640
|
+
})
|
package/test/helper.js
CHANGED
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { test } = require('tap')
|
|
4
|
+
const { connect } = require('..')
|
|
5
|
+
const { clear, connInfo, isSQLite, isMysql } = require('./helper')
|
|
6
|
+
const { setTimeout } = require('timers/promises')
|
|
7
|
+
const fakeLogger = {
|
|
8
|
+
trace: () => {},
|
|
9
|
+
error: () => {}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
test('updateMany successful', async ({ pass, teardown, same }) => {
|
|
13
|
+
const mapper = await connect({
|
|
14
|
+
...connInfo,
|
|
15
|
+
log: fakeLogger,
|
|
16
|
+
async onDatabaseLoad (db, sql) {
|
|
17
|
+
teardown(() => db.dispose())
|
|
18
|
+
pass('onDatabaseLoad called')
|
|
19
|
+
|
|
20
|
+
await clear(db, sql)
|
|
21
|
+
|
|
22
|
+
if (isSQLite) {
|
|
23
|
+
await db.query(sql`CREATE TABLE posts (
|
|
24
|
+
id INTEGER PRIMARY KEY,
|
|
25
|
+
title VARCHAR(42),
|
|
26
|
+
long_text TEXT,
|
|
27
|
+
counter INTEGER
|
|
28
|
+
);`)
|
|
29
|
+
} else {
|
|
30
|
+
await db.query(sql`CREATE TABLE posts (
|
|
31
|
+
id SERIAL PRIMARY KEY,
|
|
32
|
+
title VARCHAR(42),
|
|
33
|
+
long_text TEXT,
|
|
34
|
+
counter INTEGER
|
|
35
|
+
);`)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
const entity = mapper.entities.post
|
|
41
|
+
|
|
42
|
+
const posts = [{
|
|
43
|
+
title: 'Dog',
|
|
44
|
+
longText: 'Foo',
|
|
45
|
+
counter: 10
|
|
46
|
+
}, {
|
|
47
|
+
title: 'Cat',
|
|
48
|
+
longText: 'Bar',
|
|
49
|
+
counter: 20
|
|
50
|
+
}, {
|
|
51
|
+
title: 'Mouse',
|
|
52
|
+
longText: 'Baz',
|
|
53
|
+
counter: 30
|
|
54
|
+
}, {
|
|
55
|
+
title: 'Duck',
|
|
56
|
+
longText: 'A duck tale',
|
|
57
|
+
counter: 40
|
|
58
|
+
}]
|
|
59
|
+
|
|
60
|
+
await entity.insert({
|
|
61
|
+
inputs: posts
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
await entity.updateMany({
|
|
65
|
+
where: {
|
|
66
|
+
counter: {
|
|
67
|
+
gte: 30
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
input: {
|
|
71
|
+
title: 'Updated title'
|
|
72
|
+
}
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
const updatedPosts = await entity.find({})
|
|
76
|
+
|
|
77
|
+
same(updatedPosts, [{
|
|
78
|
+
id: '1',
|
|
79
|
+
title: 'Dog',
|
|
80
|
+
longText: 'Foo',
|
|
81
|
+
counter: 10
|
|
82
|
+
}, {
|
|
83
|
+
id: '2',
|
|
84
|
+
title: 'Cat',
|
|
85
|
+
longText: 'Bar',
|
|
86
|
+
counter: 20
|
|
87
|
+
}, {
|
|
88
|
+
id: '3',
|
|
89
|
+
title: 'Updated title',
|
|
90
|
+
longText: 'Baz',
|
|
91
|
+
counter: 30
|
|
92
|
+
}, {
|
|
93
|
+
id: '4',
|
|
94
|
+
title: 'Updated title',
|
|
95
|
+
longText: 'A duck tale',
|
|
96
|
+
counter: 40
|
|
97
|
+
}])
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
test('updateMany will return the updated values', async ({ pass, teardown, same }) => {
|
|
101
|
+
const mapper = await connect({
|
|
102
|
+
...connInfo,
|
|
103
|
+
log: fakeLogger,
|
|
104
|
+
async onDatabaseLoad (db, sql) {
|
|
105
|
+
teardown(() => db.dispose())
|
|
106
|
+
pass('onDatabaseLoad called')
|
|
107
|
+
|
|
108
|
+
await clear(db, sql)
|
|
109
|
+
|
|
110
|
+
if (isSQLite) {
|
|
111
|
+
await db.query(sql`CREATE TABLE posts (
|
|
112
|
+
id INTEGER PRIMARY KEY,
|
|
113
|
+
title VARCHAR(42),
|
|
114
|
+
long_text TEXT,
|
|
115
|
+
counter INTEGER
|
|
116
|
+
);`)
|
|
117
|
+
} else {
|
|
118
|
+
await db.query(sql`CREATE TABLE posts (
|
|
119
|
+
id SERIAL PRIMARY KEY,
|
|
120
|
+
title VARCHAR(42),
|
|
121
|
+
long_text TEXT,
|
|
122
|
+
counter INTEGER
|
|
123
|
+
);`)
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
const entity = mapper.entities.post
|
|
129
|
+
|
|
130
|
+
const posts = [{
|
|
131
|
+
title: 'Dog',
|
|
132
|
+
longText: 'Foo',
|
|
133
|
+
counter: 10
|
|
134
|
+
}, {
|
|
135
|
+
title: 'Cat',
|
|
136
|
+
longText: 'Bar',
|
|
137
|
+
counter: 20
|
|
138
|
+
}, {
|
|
139
|
+
title: 'Mouse',
|
|
140
|
+
longText: 'Baz',
|
|
141
|
+
counter: 30
|
|
142
|
+
}, {
|
|
143
|
+
title: 'Duck',
|
|
144
|
+
longText: 'A duck tale',
|
|
145
|
+
counter: 40
|
|
146
|
+
}]
|
|
147
|
+
|
|
148
|
+
await entity.insert({
|
|
149
|
+
inputs: posts
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
const updatedPosts = await entity.updateMany({
|
|
153
|
+
where: {
|
|
154
|
+
counter: {
|
|
155
|
+
gte: 30
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
input: {
|
|
159
|
+
title: 'Updated title'
|
|
160
|
+
},
|
|
161
|
+
fields: ['id', 'counter']
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
same(updatedPosts, [{
|
|
165
|
+
id: '3',
|
|
166
|
+
counter: 30
|
|
167
|
+
}, {
|
|
168
|
+
id: '4',
|
|
169
|
+
counter: 40
|
|
170
|
+
}])
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
test('updateMany missing input', async ({ pass, teardown, rejects }) => {
|
|
174
|
+
const mapper = await connect({
|
|
175
|
+
...connInfo,
|
|
176
|
+
log: fakeLogger,
|
|
177
|
+
async onDatabaseLoad (db, sql) {
|
|
178
|
+
teardown(() => db.dispose())
|
|
179
|
+
pass('onDatabaseLoad called')
|
|
180
|
+
|
|
181
|
+
await clear(db, sql)
|
|
182
|
+
|
|
183
|
+
if (isSQLite) {
|
|
184
|
+
await db.query(sql`CREATE TABLE posts (
|
|
185
|
+
id INTEGER PRIMARY KEY,
|
|
186
|
+
title VARCHAR(42),
|
|
187
|
+
long_text TEXT,
|
|
188
|
+
counter INTEGER
|
|
189
|
+
);`)
|
|
190
|
+
} else {
|
|
191
|
+
await db.query(sql`CREATE TABLE posts (
|
|
192
|
+
id SERIAL PRIMARY KEY,
|
|
193
|
+
title VARCHAR(42),
|
|
194
|
+
long_text TEXT,
|
|
195
|
+
counter INTEGER
|
|
196
|
+
);`)
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
const entity = mapper.entities.post
|
|
202
|
+
|
|
203
|
+
const posts = [{
|
|
204
|
+
title: 'Dog',
|
|
205
|
+
longText: 'Foo',
|
|
206
|
+
counter: 10
|
|
207
|
+
}, {
|
|
208
|
+
title: 'Cat',
|
|
209
|
+
longText: 'Bar',
|
|
210
|
+
counter: 20
|
|
211
|
+
}, {
|
|
212
|
+
title: 'Mouse',
|
|
213
|
+
longText: 'Baz',
|
|
214
|
+
counter: 30
|
|
215
|
+
}, {
|
|
216
|
+
title: 'Duck',
|
|
217
|
+
longText: 'A duck tale',
|
|
218
|
+
counter: 40
|
|
219
|
+
}]
|
|
220
|
+
|
|
221
|
+
await entity.insert({
|
|
222
|
+
inputs: posts
|
|
223
|
+
})
|
|
224
|
+
|
|
225
|
+
rejects(entity.updateMany({
|
|
226
|
+
where: {
|
|
227
|
+
counter: {
|
|
228
|
+
gte: 30
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}), new Error('Input not provided.'))
|
|
232
|
+
})
|
|
233
|
+
|
|
234
|
+
test('updateMany successful and update updated_at', async ({ pass, teardown, same, notSame }) => {
|
|
235
|
+
const mapper = await connect({
|
|
236
|
+
...connInfo,
|
|
237
|
+
autoTimestamp: true,
|
|
238
|
+
log: fakeLogger,
|
|
239
|
+
async onDatabaseLoad (db, sql) {
|
|
240
|
+
teardown(() => db.dispose())
|
|
241
|
+
pass('onDatabaseLoad called')
|
|
242
|
+
|
|
243
|
+
await clear(db, sql)
|
|
244
|
+
|
|
245
|
+
if (isSQLite) {
|
|
246
|
+
await db.query(sql`CREATE TABLE posts (
|
|
247
|
+
id INTEGER PRIMARY KEY,
|
|
248
|
+
title VARCHAR(42),
|
|
249
|
+
long_text TEXT,
|
|
250
|
+
counter INTEGER,
|
|
251
|
+
inserted_at TIMESTAMP,
|
|
252
|
+
updated_at TIMESTAMP
|
|
253
|
+
);`)
|
|
254
|
+
} else if (isMysql) {
|
|
255
|
+
await db.query(sql`CREATE TABLE posts (
|
|
256
|
+
id SERIAL PRIMARY KEY,
|
|
257
|
+
title VARCHAR(42),
|
|
258
|
+
long_text TEXT,
|
|
259
|
+
counter INTEGER,
|
|
260
|
+
inserted_at TIMESTAMP NULL DEFAULT NULL,
|
|
261
|
+
updated_at TIMESTAMP NULL DEFAULT NULL
|
|
262
|
+
);`)
|
|
263
|
+
} else {
|
|
264
|
+
await db.query(sql`CREATE TABLE posts (
|
|
265
|
+
id SERIAL PRIMARY KEY,
|
|
266
|
+
title VARCHAR(42),
|
|
267
|
+
long_text TEXT,
|
|
268
|
+
counter INTEGER,
|
|
269
|
+
inserted_at TIMESTAMP,
|
|
270
|
+
updated_at TIMESTAMP
|
|
271
|
+
);`)
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
})
|
|
275
|
+
|
|
276
|
+
const entity = mapper.entities.post
|
|
277
|
+
|
|
278
|
+
const posts = [{
|
|
279
|
+
title: 'Dog',
|
|
280
|
+
longText: 'Foo',
|
|
281
|
+
counter: 10
|
|
282
|
+
}, {
|
|
283
|
+
title: 'Cat',
|
|
284
|
+
longText: 'Bar',
|
|
285
|
+
counter: 20
|
|
286
|
+
}, {
|
|
287
|
+
title: 'Mouse',
|
|
288
|
+
longText: 'Baz',
|
|
289
|
+
counter: 30
|
|
290
|
+
}, {
|
|
291
|
+
title: 'Duck',
|
|
292
|
+
longText: 'A duck tale',
|
|
293
|
+
counter: 40
|
|
294
|
+
}]
|
|
295
|
+
|
|
296
|
+
await entity.insert({
|
|
297
|
+
inputs: posts
|
|
298
|
+
})
|
|
299
|
+
const createdPost3 = (await entity.find({ where: { id: { eq: '3' } } }))[0]
|
|
300
|
+
|
|
301
|
+
await setTimeout(1000) // await 1s
|
|
302
|
+
|
|
303
|
+
await entity.updateMany({
|
|
304
|
+
where: {
|
|
305
|
+
counter: {
|
|
306
|
+
gte: 30
|
|
307
|
+
}
|
|
308
|
+
},
|
|
309
|
+
input: {
|
|
310
|
+
title: 'Updated title'
|
|
311
|
+
}
|
|
312
|
+
})
|
|
313
|
+
|
|
314
|
+
const updatedPost3 = (await entity.find({ where: { id: { eq: '3' } } }))[0]
|
|
315
|
+
same(updatedPost3.title, 'Updated title')
|
|
316
|
+
same(createdPost3.insertedAt, updatedPost3.insertedAt)
|
|
317
|
+
notSame(createdPost3.updatedAt, updatedPost3.updatedAt)
|
|
318
|
+
})
|