@platformatic/sql-mapper 0.15.0 → 0.16.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 +22 -15
- package/mapper.js +9 -0
- package/package.json +1 -1
- package/test/entity.test.js +34 -0
- package/test/mapper.test.js +28 -0
package/lib/queries/sqlite.js
CHANGED
|
@@ -124,33 +124,40 @@ async function insertOne (db, sql, table, schema, input, primaryKeys, fieldsToRe
|
|
|
124
124
|
if (fieldsToRetrieve.length === 0) {
|
|
125
125
|
await db.query(insertRawQuery)
|
|
126
126
|
return {}
|
|
127
|
+
} else if (typeof db.tx === 'function') {
|
|
128
|
+
return db.tx(handleAutoIncrement)
|
|
127
129
|
} else {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
+
// TODO add a log at trace level if we do this
|
|
131
|
+
// There are not nested transactions in SQLite, so we can just run the query
|
|
132
|
+
// because we are already in a transaction.
|
|
133
|
+
return handleAutoIncrement(db)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
async function handleAutoIncrement (transaction) {
|
|
137
|
+
await transaction.query(insertRawQuery)
|
|
130
138
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
139
|
+
let selectInsertedRawQuery = null
|
|
140
|
+
if (hasAutoIncrementPK) {
|
|
141
|
+
selectInsertedRawQuery = sql`
|
|
134
142
|
SELECT ${sql.join(fieldsToRetrieve, sql`, `)}
|
|
135
143
|
FROM ${sql.ident(table)}
|
|
136
144
|
WHERE _rowid_ = last_insert_rowid()
|
|
137
145
|
`
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
146
|
+
} else {
|
|
147
|
+
const where = []
|
|
148
|
+
for (const [key, value] of Object.entries(primaryKeyValues)) {
|
|
149
|
+
where.push(sql`${sql.ident(key)} = ${sql.value(value)}`)
|
|
150
|
+
}
|
|
143
151
|
|
|
144
|
-
|
|
152
|
+
selectInsertedRawQuery = sql`
|
|
145
153
|
SELECT ${sql.join(fieldsToRetrieve, sql`, `)}
|
|
146
154
|
FROM ${sql.ident(table)}
|
|
147
155
|
WHERE ${sql.join(where, sql` AND `)}
|
|
148
156
|
`
|
|
149
|
-
|
|
157
|
+
}
|
|
150
158
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
})
|
|
159
|
+
const [insertedRaw] = await transaction.query(selectInsertedRawQuery)
|
|
160
|
+
return insertedRaw
|
|
154
161
|
}
|
|
155
162
|
}
|
|
156
163
|
|
package/mapper.js
CHANGED
|
@@ -172,6 +172,15 @@ async function sqlMapper (app, opts) {
|
|
|
172
172
|
// TODO this would need to be refactored as other plugins
|
|
173
173
|
// would need to use this same namespace
|
|
174
174
|
app.decorate('platformatic', mapper)
|
|
175
|
+
|
|
176
|
+
app.decorateRequest('platformaticContext', null)
|
|
177
|
+
app.addHook('onRequest', function (req, reply, done) {
|
|
178
|
+
req.platformaticContext = {
|
|
179
|
+
app: this, // uses the encapsulated fastify instance of the route
|
|
180
|
+
reply
|
|
181
|
+
}
|
|
182
|
+
done()
|
|
183
|
+
})
|
|
175
184
|
}
|
|
176
185
|
|
|
177
186
|
module.exports = fp(sqlMapper)
|
package/package.json
CHANGED
package/test/entity.test.js
CHANGED
|
@@ -971,3 +971,37 @@ test('stored and virtual generated columns should return for pg', { skip: (isPg
|
|
|
971
971
|
}
|
|
972
972
|
}), [{ id: 2, test: 8, testStored: 16, testVirtual: 32 }])
|
|
973
973
|
})
|
|
974
|
+
|
|
975
|
+
test('nested transactions', async ({ equal, same, teardown, rejects }) => {
|
|
976
|
+
async function onDatabaseLoad (db, sql) {
|
|
977
|
+
await clear(db, sql)
|
|
978
|
+
teardown(() => db.dispose())
|
|
979
|
+
if (isSQLite) {
|
|
980
|
+
await db.query(sql`CREATE TABLE pages (
|
|
981
|
+
id INTEGER PRIMARY KEY,
|
|
982
|
+
the_title VARCHAR(42)
|
|
983
|
+
);`)
|
|
984
|
+
} else {
|
|
985
|
+
await db.query(sql`CREATE TABLE pages (
|
|
986
|
+
id SERIAL PRIMARY KEY,
|
|
987
|
+
the_title VARCHAR(255)
|
|
988
|
+
);`)
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
const mapper = await connect({
|
|
992
|
+
connectionString: connInfo.connectionString,
|
|
993
|
+
log: fakeLogger,
|
|
994
|
+
onDatabaseLoad,
|
|
995
|
+
ignore: {},
|
|
996
|
+
hooks: {}
|
|
997
|
+
})
|
|
998
|
+
|
|
999
|
+
await mapper.db.tx(async (tx) => {
|
|
1000
|
+
const insertResult = await mapper.entities.page.save({
|
|
1001
|
+
input: {},
|
|
1002
|
+
fields: ['id', 'theTitle'],
|
|
1003
|
+
tx
|
|
1004
|
+
})
|
|
1005
|
+
same(insertResult, { id: '1', theTitle: null })
|
|
1006
|
+
})
|
|
1007
|
+
})
|
package/test/mapper.test.js
CHANGED
|
@@ -193,3 +193,31 @@ test('missing connectionString', async ({ rejects }) => {
|
|
|
193
193
|
|
|
194
194
|
await rejects(app.ready(), /connectionString/)
|
|
195
195
|
})
|
|
196
|
+
|
|
197
|
+
test('platformaticContext', async ({ plan, equal, teardown }) => {
|
|
198
|
+
plan(3)
|
|
199
|
+
async function onDatabaseLoad (db, sql) {
|
|
200
|
+
teardown(async () => await clear(db, sql))
|
|
201
|
+
|
|
202
|
+
await db.query(sql`CREATE TABLE IF NOT EXISTS pages (
|
|
203
|
+
id SERIAL PRIMARY KEY,
|
|
204
|
+
title VARCHAR(255) NOT NULL
|
|
205
|
+
);`)
|
|
206
|
+
}
|
|
207
|
+
const app = fastify()
|
|
208
|
+
teardown(() => app.close())
|
|
209
|
+
app.register(plugin, {
|
|
210
|
+
connectionString: connInfo.connectionString,
|
|
211
|
+
onDatabaseLoad
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
app.get('/', function (req, reply) {
|
|
215
|
+
const ctx = req.platformaticContext
|
|
216
|
+
equal(app, ctx.app)
|
|
217
|
+
equal(reply, ctx.reply)
|
|
218
|
+
return 'hello world'
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
const res = await app.inject('/')
|
|
222
|
+
equal(res.statusCode, 200)
|
|
223
|
+
})
|