@platformatic/sql-mapper 0.13.1 → 0.14.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/queries/sqlite.js +56 -50
- package/package.json +1 -1
- package/test/entity.test.js +104 -2
package/lib/queries/sqlite.js
CHANGED
|
@@ -85,67 +85,73 @@ async function listConstraints (db, sql, table) {
|
|
|
85
85
|
module.exports.listConstraints = listConstraints
|
|
86
86
|
|
|
87
87
|
async function insertOne (db, sql, table, schema, input, primaryKeys, fieldsToRetrieve) {
|
|
88
|
-
const fieldNames = Object.keys(input)
|
|
89
|
-
const keysToSql = fieldNames.map((key) => sql.ident(key))
|
|
90
|
-
const valuesToSql = fieldNames.map((key) => sql.value(input[key]))
|
|
91
|
-
|
|
92
88
|
const primaryKeyValues = {}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
89
|
+
|
|
90
|
+
let hasAutoIncrementPK = false
|
|
91
|
+
|
|
96
92
|
for (const { key, sqlType } of primaryKeys) {
|
|
97
|
-
|
|
98
|
-
|
|
93
|
+
let primaryKeyValue = input[key]
|
|
94
|
+
|
|
99
95
|
/* istanbul ignore next */
|
|
100
|
-
if (
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
96
|
+
if (primaryKeyValue === undefined) {
|
|
97
|
+
if (sqlType === 'uuid') {
|
|
98
|
+
primaryKeyValue = randomUUID()
|
|
99
|
+
} else if (!hasAutoIncrementPK) {
|
|
100
|
+
primaryKeyValue = null
|
|
101
|
+
hasAutoIncrementPK = true
|
|
102
|
+
} else {
|
|
103
|
+
throw new Error('SQLite only supports autoIncrement on one column')
|
|
104
|
+
}
|
|
105
|
+
input[key] = primaryKeyValue
|
|
110
106
|
}
|
|
111
|
-
|
|
107
|
+
|
|
108
|
+
primaryKeyValues[key] = primaryKeyValue
|
|
112
109
|
}
|
|
113
110
|
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
sql`, `
|
|
117
|
-
)
|
|
111
|
+
const insertedKeys = []
|
|
112
|
+
const insertedValues = []
|
|
118
113
|
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
sql
|
|
122
|
-
|
|
114
|
+
for (const [key, value] of Object.entries(input)) {
|
|
115
|
+
insertedKeys.push(sql.ident(key))
|
|
116
|
+
insertedValues.push(sql.value(value))
|
|
117
|
+
}
|
|
123
118
|
|
|
124
|
-
const
|
|
125
|
-
INSERT INTO ${sql.ident(table)} (${
|
|
126
|
-
VALUES(${
|
|
119
|
+
const insertRawQuery = sql`
|
|
120
|
+
INSERT INTO ${sql.ident(table)} (${sql.join(insertedKeys, sql`, `)})
|
|
121
|
+
VALUES(${sql.join(insertedValues, sql`, `)})
|
|
127
122
|
`
|
|
128
|
-
await db.query(insert)
|
|
129
|
-
|
|
130
|
-
if (!useUUID && primaryKeys.length === 1) {
|
|
131
|
-
const res2 = await db.query(sql`
|
|
132
|
-
SELECT last_insert_rowid()
|
|
133
|
-
`)
|
|
134
|
-
|
|
135
|
-
primaryKeyValues[primaryKeys[0].key] = res2[0]['last_insert_rowid()']
|
|
136
|
-
}
|
|
137
123
|
|
|
138
|
-
|
|
139
|
-
|
|
124
|
+
if (fieldsToRetrieve.length === 0) {
|
|
125
|
+
await db.query(insertRawQuery)
|
|
126
|
+
return {}
|
|
127
|
+
} else {
|
|
128
|
+
return db.tx(async (transaction) => {
|
|
129
|
+
await transaction.query(insertRawQuery)
|
|
130
|
+
|
|
131
|
+
let selectInsertedRawQuery = null
|
|
132
|
+
if (hasAutoIncrementPK) {
|
|
133
|
+
selectInsertedRawQuery = sql`
|
|
134
|
+
SELECT ${sql.join(fieldsToRetrieve, sql`, `)}
|
|
135
|
+
FROM ${sql.ident(table)}
|
|
136
|
+
WHERE _rowid_ = last_insert_rowid()
|
|
137
|
+
`
|
|
138
|
+
} else {
|
|
139
|
+
const where = []
|
|
140
|
+
for (const [key, value] of Object.entries(primaryKeyValues)) {
|
|
141
|
+
where.push(sql`${sql.ident(key)} = ${sql.value(value)}`)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
selectInsertedRawQuery = sql`
|
|
145
|
+
SELECT ${sql.join(fieldsToRetrieve, sql`, `)}
|
|
146
|
+
FROM ${sql.ident(table)}
|
|
147
|
+
WHERE ${sql.join(where, sql` AND `)}
|
|
148
|
+
`
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const [insertedRaw] = await transaction.query(selectInsertedRawQuery)
|
|
152
|
+
return insertedRaw
|
|
153
|
+
})
|
|
140
154
|
}
|
|
141
|
-
|
|
142
|
-
const res = await db.query(sql`
|
|
143
|
-
SELECT ${sql.join(fieldsToRetrieve, sql`, `)}
|
|
144
|
-
FROM ${sql.ident(table)}
|
|
145
|
-
WHERE ${sql.join(where, sql` AND `)}
|
|
146
|
-
`)
|
|
147
|
-
|
|
148
|
-
return res[0]
|
|
149
155
|
}
|
|
150
156
|
|
|
151
157
|
module.exports.insertOne = insertOne
|
package/package.json
CHANGED
package/test/entity.test.js
CHANGED
|
@@ -43,7 +43,7 @@ test('entity fields', async ({ equal, not, same, teardown }) => {
|
|
|
43
43
|
equal(pageEntity.camelCasedFields.id.primaryKey, true)
|
|
44
44
|
})
|
|
45
45
|
|
|
46
|
-
test('entity API',
|
|
46
|
+
test('entity API', async ({ equal, same, teardown, rejects }) => {
|
|
47
47
|
async function onDatabaseLoad (db, sql) {
|
|
48
48
|
await clear(db, sql)
|
|
49
49
|
teardown(() => db.dispose())
|
|
@@ -168,7 +168,7 @@ test('empty save', async ({ equal, same, teardown, rejects }) => {
|
|
|
168
168
|
same(insertResult, { id: '1', theTitle: null })
|
|
169
169
|
})
|
|
170
170
|
|
|
171
|
-
test('insert with explicit PK value', async ({ same, teardown }) => {
|
|
171
|
+
test('insert with explicit integer PK value', async ({ same, teardown }) => {
|
|
172
172
|
async function onDatabaseLoad (db, sql) {
|
|
173
173
|
await clear(db, sql)
|
|
174
174
|
teardown(() => db.dispose())
|
|
@@ -195,6 +195,108 @@ test('insert with explicit PK value', async ({ same, teardown }) => {
|
|
|
195
195
|
})
|
|
196
196
|
})
|
|
197
197
|
|
|
198
|
+
test('insert with explicit uuid PK value', { skip: !isSQLite }, async ({ same, teardown }) => {
|
|
199
|
+
async function onDatabaseLoad (db, sql) {
|
|
200
|
+
await clear(db, sql)
|
|
201
|
+
teardown(() => db.dispose())
|
|
202
|
+
await db.query(sql`CREATE TABLE pages (
|
|
203
|
+
id uuid PRIMARY KEY,
|
|
204
|
+
title varchar(255) NOT NULL
|
|
205
|
+
);`)
|
|
206
|
+
}
|
|
207
|
+
const mapper = await connect({
|
|
208
|
+
connectionString: connInfo.connectionString,
|
|
209
|
+
log: fakeLogger,
|
|
210
|
+
onDatabaseLoad,
|
|
211
|
+
ignore: {},
|
|
212
|
+
hooks: {}
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
const pageEntity = mapper.entities.page
|
|
216
|
+
const [newPage] = await pageEntity.insert({
|
|
217
|
+
fields: ['id', 'title'],
|
|
218
|
+
inputs: [{
|
|
219
|
+
id: '00000000-0000-0000-0000-000000000013',
|
|
220
|
+
title: '13th page with explicit id equal to 13'
|
|
221
|
+
}]
|
|
222
|
+
})
|
|
223
|
+
same(newPage, {
|
|
224
|
+
id: '00000000-0000-0000-0000-000000000013',
|
|
225
|
+
title: '13th page with explicit id equal to 13'
|
|
226
|
+
})
|
|
227
|
+
})
|
|
228
|
+
|
|
229
|
+
test('insert with explicit uuid PK value without rowid', { skip: !isSQLite }, async ({ same, teardown }) => {
|
|
230
|
+
async function onDatabaseLoad (db, sql) {
|
|
231
|
+
await clear(db, sql)
|
|
232
|
+
teardown(() => db.dispose())
|
|
233
|
+
await db.query(sql`CREATE TABLE pages (
|
|
234
|
+
id uuid PRIMARY KEY,
|
|
235
|
+
title varchar(255) NOT NULL
|
|
236
|
+
) WITHOUT ROWID;`)
|
|
237
|
+
}
|
|
238
|
+
const mapper = await connect({
|
|
239
|
+
connectionString: connInfo.connectionString,
|
|
240
|
+
log: fakeLogger,
|
|
241
|
+
onDatabaseLoad,
|
|
242
|
+
ignore: {},
|
|
243
|
+
hooks: {}
|
|
244
|
+
})
|
|
245
|
+
|
|
246
|
+
const pageEntity = mapper.entities.page
|
|
247
|
+
const [newPage] = await pageEntity.insert({
|
|
248
|
+
fields: ['id', 'title'],
|
|
249
|
+
inputs: [{
|
|
250
|
+
id: '00000000-0000-0000-0000-000000000013',
|
|
251
|
+
title: '13th page with explicit id equal to 13'
|
|
252
|
+
}]
|
|
253
|
+
})
|
|
254
|
+
same(newPage, {
|
|
255
|
+
id: '00000000-0000-0000-0000-000000000013',
|
|
256
|
+
title: '13th page with explicit id equal to 13'
|
|
257
|
+
})
|
|
258
|
+
})
|
|
259
|
+
|
|
260
|
+
test('insert without fields to retrieve', { skip: !isSQLite }, async ({ same, teardown }) => {
|
|
261
|
+
async function onDatabaseLoad (db, sql) {
|
|
262
|
+
await clear(db, sql)
|
|
263
|
+
teardown(() => db.dispose())
|
|
264
|
+
await db.query(sql`CREATE TABLE pages (
|
|
265
|
+
id INTEGER PRIMARY KEY,
|
|
266
|
+
title varchar(255) NOT NULL
|
|
267
|
+
);`)
|
|
268
|
+
}
|
|
269
|
+
const mapper = await connect({
|
|
270
|
+
connectionString: connInfo.connectionString,
|
|
271
|
+
log: fakeLogger,
|
|
272
|
+
onDatabaseLoad,
|
|
273
|
+
ignore: {},
|
|
274
|
+
hooks: {}
|
|
275
|
+
})
|
|
276
|
+
|
|
277
|
+
const pageEntity = mapper.entities.page
|
|
278
|
+
await pageEntity.insert({
|
|
279
|
+
fields: [],
|
|
280
|
+
inputs: [{
|
|
281
|
+
id: '13',
|
|
282
|
+
title: '13th page with explicit id equal to 13'
|
|
283
|
+
}]
|
|
284
|
+
})
|
|
285
|
+
|
|
286
|
+
const [newPage] = await pageEntity.find({
|
|
287
|
+
where: {
|
|
288
|
+
id: {
|
|
289
|
+
eq: '13'
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
})
|
|
293
|
+
|
|
294
|
+
same(newPage, {
|
|
295
|
+
id: '13',
|
|
296
|
+
title: '13th page with explicit id equal to 13'
|
|
297
|
+
})
|
|
298
|
+
})
|
|
299
|
+
|
|
198
300
|
test('[SQLite] - UUID', { skip: !isSQLite }, async ({ pass, teardown, same, equal }) => {
|
|
199
301
|
const mapper = await connect({
|
|
200
302
|
connectionString: connInfo.connectionString,
|