@platformatic/sql-mapper 3.4.1 → 3.5.1
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/README.md +1 -1
- package/eslint.config.js +2 -2
- package/{mapper.d.ts → index.d.ts} +68 -10
- package/{mapper.js → index.js} +164 -75
- package/lib/cache.js +17 -16
- package/lib/clean-up.js +3 -7
- package/lib/connection-info.js +2 -4
- package/lib/cursor.js +94 -0
- package/lib/entity.js +182 -68
- package/lib/errors.js +66 -22
- package/lib/queries/index.js +4 -23
- package/lib/queries/mariadb.js +2 -11
- package/lib/queries/mysql-shared.js +9 -19
- package/lib/queries/mysql.js +12 -26
- package/lib/queries/pg.js +12 -29
- package/lib/queries/shared.js +26 -29
- package/lib/queries/sqlite.js +17 -33
- package/lib/telemetry.js +7 -14
- package/lib/utils.js +12 -23
- package/package.json +18 -15
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @platformatic/sql-mapper
|
|
2
2
|
|
|
3
|
-
Check out the full documentation on [our website](https://docs.platformatic.dev/docs/
|
|
3
|
+
Check out the full documentation on [our website](https://docs.platformatic.dev/docs/reference/sql-mapper/overview).
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
package/eslint.config.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
|
|
1
|
+
import neostandard from 'neostandard'
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
export default neostandard({ ts: true })
|
|
@@ -69,6 +69,12 @@ export interface DBEntityField {
|
|
|
69
69
|
autoTimestamp?: boolean
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
export type WhereClause = {
|
|
73
|
+
or?: WhereCondition[];
|
|
74
|
+
} | {
|
|
75
|
+
[columnName: string]: WhereCondition[string];
|
|
76
|
+
}
|
|
77
|
+
|
|
72
78
|
export interface WhereCondition {
|
|
73
79
|
[columnName: string]: {
|
|
74
80
|
/**
|
|
@@ -134,12 +140,16 @@ export interface WhereCondition {
|
|
|
134
140
|
}
|
|
135
141
|
}
|
|
136
142
|
|
|
143
|
+
export type Cursor = {
|
|
144
|
+
[columnName: string]: string | number | boolean | null,
|
|
145
|
+
}
|
|
146
|
+
|
|
137
147
|
interface Find<EntityFields> {
|
|
138
148
|
(options?: {
|
|
139
149
|
/**
|
|
140
150
|
* SQL where condition.
|
|
141
151
|
*/
|
|
142
|
-
where?:
|
|
152
|
+
where?: WhereClause,
|
|
143
153
|
/**
|
|
144
154
|
* List of fields to be returned for each object
|
|
145
155
|
*/
|
|
@@ -156,10 +166,29 @@ interface Find<EntityFields> {
|
|
|
156
166
|
* Number of entities to skip.
|
|
157
167
|
*/
|
|
158
168
|
offset?: number,
|
|
169
|
+
/**
|
|
170
|
+
* If false pagination is disabled.
|
|
171
|
+
* @default true
|
|
172
|
+
*/
|
|
173
|
+
paginate?: boolean,
|
|
174
|
+
/**
|
|
175
|
+
* Cursor to paginate the results.
|
|
176
|
+
*/
|
|
177
|
+
cursor?: Cursor,
|
|
178
|
+
/**
|
|
179
|
+
* If set to false, the previous page will be fetched in cursor pagination.
|
|
180
|
+
* @default true
|
|
181
|
+
*/
|
|
182
|
+
nextPage?: boolean,
|
|
159
183
|
/**
|
|
160
184
|
* If present, the entity participates in transaction
|
|
161
185
|
*/
|
|
162
186
|
tx?: Database
|
|
187
|
+
/**
|
|
188
|
+
* Passing this to all sql-mapper functions allow to apply
|
|
189
|
+
* authorization rules to the database queries (amongst other things).
|
|
190
|
+
*/
|
|
191
|
+
ctx?: PlatformaticContext
|
|
163
192
|
}): Promise<Partial<EntityFields>[]>
|
|
164
193
|
}
|
|
165
194
|
|
|
@@ -168,11 +197,16 @@ interface Count {
|
|
|
168
197
|
/**
|
|
169
198
|
* SQL where condition.
|
|
170
199
|
*/
|
|
171
|
-
where?:
|
|
200
|
+
where?: WhereClause,
|
|
172
201
|
/**
|
|
173
202
|
* If present, the entity participates in transaction
|
|
174
203
|
*/
|
|
175
|
-
tx?: Database
|
|
204
|
+
tx?: Database,
|
|
205
|
+
/**
|
|
206
|
+
* Passing this to all sql-mapper functions allow to apply
|
|
207
|
+
* authorization rules to the database queries (amongst other things).
|
|
208
|
+
*/
|
|
209
|
+
ctx?: PlatformaticContext
|
|
176
210
|
}): Promise<number>
|
|
177
211
|
}
|
|
178
212
|
|
|
@@ -189,7 +223,12 @@ interface Insert<EntityFields> {
|
|
|
189
223
|
/**
|
|
190
224
|
* If present, the entity participates in transaction
|
|
191
225
|
*/
|
|
192
|
-
tx?: Database
|
|
226
|
+
tx?: Database,
|
|
227
|
+
/**
|
|
228
|
+
* Passing this to all sql-mapper functions allow to apply
|
|
229
|
+
* authorization rules to the database queries (amongst other things).
|
|
230
|
+
*/
|
|
231
|
+
ctx?: PlatformaticContext
|
|
193
232
|
}): Promise<Partial<EntityFields>[]>
|
|
194
233
|
}
|
|
195
234
|
|
|
@@ -206,7 +245,12 @@ interface Save<EntityFields> {
|
|
|
206
245
|
/**
|
|
207
246
|
* If present, the entity participates in transaction
|
|
208
247
|
*/
|
|
209
|
-
tx?: Database
|
|
248
|
+
tx?: Database,
|
|
249
|
+
/**
|
|
250
|
+
* Passing this to all sql-mapper functions allow to apply
|
|
251
|
+
* authorization rules to the database queries (amongst other things).
|
|
252
|
+
*/
|
|
253
|
+
ctx?: PlatformaticContext
|
|
210
254
|
}): Promise<Partial<EntityFields>>
|
|
211
255
|
}
|
|
212
256
|
|
|
@@ -215,7 +259,7 @@ interface Delete<EntityFields> {
|
|
|
215
259
|
/**
|
|
216
260
|
* SQL where condition.
|
|
217
261
|
*/
|
|
218
|
-
where?:
|
|
262
|
+
where?: WhereClause,
|
|
219
263
|
/**
|
|
220
264
|
* List of fields to be returned for each object
|
|
221
265
|
*/
|
|
@@ -223,7 +267,12 @@ interface Delete<EntityFields> {
|
|
|
223
267
|
/**
|
|
224
268
|
* If present, the entity participates in transaction
|
|
225
269
|
*/
|
|
226
|
-
tx?: Database
|
|
270
|
+
tx?: Database,
|
|
271
|
+
/**
|
|
272
|
+
* Passing this to all sql-mapper functions allow to apply
|
|
273
|
+
* authorization rules to the database queries (amongst other things).
|
|
274
|
+
*/
|
|
275
|
+
ctx?: PlatformaticContext
|
|
227
276
|
}): Promise<Partial<EntityFields>[]>,
|
|
228
277
|
}
|
|
229
278
|
|
|
@@ -232,11 +281,11 @@ interface UpdateMany<EntityFields> {
|
|
|
232
281
|
/**
|
|
233
282
|
* SQL where condition.
|
|
234
283
|
*/
|
|
235
|
-
where
|
|
284
|
+
where?: WhereClause,
|
|
236
285
|
/**
|
|
237
286
|
* Entity fields to update.
|
|
238
287
|
*/
|
|
239
|
-
input: EntityFields
|
|
288
|
+
input: Partial<EntityFields>,
|
|
240
289
|
/**
|
|
241
290
|
* List of fields to be returned for each object
|
|
242
291
|
*/
|
|
@@ -244,7 +293,12 @@ interface UpdateMany<EntityFields> {
|
|
|
244
293
|
/**
|
|
245
294
|
* If present, the entity participates in transaction
|
|
246
295
|
*/
|
|
247
|
-
tx?: Database
|
|
296
|
+
tx?: Database,
|
|
297
|
+
/**
|
|
298
|
+
* Passing this to all sql-mapper functions allow to apply
|
|
299
|
+
* authorization rules to the database queries (amongst other things).
|
|
300
|
+
*/
|
|
301
|
+
ctx?: PlatformaticContext
|
|
248
302
|
}): Promise<Partial<EntityFields>[]>
|
|
249
303
|
}
|
|
250
304
|
|
|
@@ -265,6 +319,10 @@ export interface Entity<EntityFields = any> {
|
|
|
265
319
|
* The primary key of the database entity.
|
|
266
320
|
*/
|
|
267
321
|
primaryKey: string,
|
|
322
|
+
/**
|
|
323
|
+
* Primary keys of the database entity.
|
|
324
|
+
*/
|
|
325
|
+
primaryKeys: Set<string>,
|
|
268
326
|
/**
|
|
269
327
|
* The table of the database entity.
|
|
270
328
|
*/
|
package/{mapper.js → index.js}
RENAMED
|
@@ -1,19 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
import { findNearestString } from '@platformatic/foundation'
|
|
2
|
+
import fp from 'fastify-plugin'
|
|
3
|
+
import { setupCache } from './lib/cache.js'
|
|
4
|
+
import { buildCleanUp } from './lib/clean-up.js'
|
|
5
|
+
import { getConnectionInfo } from './lib/connection-info.js'
|
|
6
|
+
import { buildEntity } from './lib/entity.js'
|
|
7
|
+
import {
|
|
8
|
+
CannotFindEntityError,
|
|
9
|
+
ConnectionStringRequiredError,
|
|
10
|
+
SpecifyProtocolError,
|
|
11
|
+
TableMustBeAStringError
|
|
12
|
+
} from './lib/errors.js'
|
|
13
|
+
import * as queriesFactory from './lib/queries/index.js'
|
|
14
|
+
import { setupTelemetry } from './lib/telemetry.js'
|
|
15
|
+
import { areSchemasSupported } from './lib/utils.js'
|
|
13
16
|
|
|
14
17
|
// Ignore the function as it is only used only for MySQL and PostgreSQL
|
|
15
18
|
/* istanbul ignore next */
|
|
16
|
-
async function buildConnection (
|
|
19
|
+
async function buildConnection (
|
|
20
|
+
log,
|
|
21
|
+
createConnectionPool,
|
|
22
|
+
connectionString,
|
|
23
|
+
poolSize,
|
|
24
|
+
schema,
|
|
25
|
+
idleTimeoutMilliseconds,
|
|
26
|
+
queueTimeoutMilliseconds,
|
|
27
|
+
acquireLockTimeoutMilliseconds
|
|
28
|
+
) {
|
|
17
29
|
const db = await createConnectionPool({
|
|
18
30
|
connectionString,
|
|
19
31
|
bigIntMode: 'string',
|
|
@@ -22,40 +34,56 @@ async function buildConnection (log, createConnectionPool, connectionString, poo
|
|
|
22
34
|
queueTimeoutMilliseconds,
|
|
23
35
|
acquireLockTimeoutMilliseconds,
|
|
24
36
|
onQueryStart: (_query, { text, values }) => {
|
|
25
|
-
log.trace(
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
37
|
+
log.trace(
|
|
38
|
+
{
|
|
39
|
+
query: {
|
|
40
|
+
text,
|
|
41
|
+
values
|
|
42
|
+
}
|
|
29
43
|
},
|
|
30
|
-
|
|
44
|
+
'start query'
|
|
45
|
+
)
|
|
31
46
|
},
|
|
32
47
|
onQueryResults: (_query, { text }, results) => {
|
|
33
|
-
log.trace(
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
48
|
+
log.trace(
|
|
49
|
+
{
|
|
50
|
+
query: {
|
|
51
|
+
text,
|
|
52
|
+
results: results.length
|
|
53
|
+
}
|
|
37
54
|
},
|
|
38
|
-
|
|
55
|
+
'end query'
|
|
56
|
+
)
|
|
39
57
|
},
|
|
40
58
|
onQueryError: (_query, { text }, err) => {
|
|
41
|
-
log.error(
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
59
|
+
log.error(
|
|
60
|
+
{
|
|
61
|
+
query: {
|
|
62
|
+
text,
|
|
63
|
+
error: err.message
|
|
64
|
+
}
|
|
45
65
|
},
|
|
46
|
-
|
|
66
|
+
'query error'
|
|
67
|
+
)
|
|
47
68
|
},
|
|
48
|
-
schema
|
|
69
|
+
schema
|
|
49
70
|
})
|
|
50
71
|
return db
|
|
51
72
|
}
|
|
52
73
|
|
|
53
74
|
const defaultAutoTimestampFields = {
|
|
54
75
|
createdAt: 'created_at',
|
|
55
|
-
updatedAt: 'updated_at'
|
|
76
|
+
updatedAt: 'updated_at'
|
|
56
77
|
}
|
|
57
78
|
|
|
58
|
-
async function createConnectionPool ({
|
|
79
|
+
export async function createConnectionPool ({
|
|
80
|
+
log,
|
|
81
|
+
connectionString,
|
|
82
|
+
poolSize,
|
|
83
|
+
idleTimeoutMilliseconds,
|
|
84
|
+
queueTimeoutMilliseconds,
|
|
85
|
+
acquireLockTimeoutMilliseconds
|
|
86
|
+
}) {
|
|
59
87
|
let db
|
|
60
88
|
let sql
|
|
61
89
|
|
|
@@ -63,13 +91,31 @@ async function createConnectionPool ({ log, connectionString, poolSize, idleTime
|
|
|
63
91
|
|
|
64
92
|
/* istanbul ignore next */
|
|
65
93
|
if (connectionString.indexOf('postgres') === 0) {
|
|
66
|
-
const createConnectionPoolPg =
|
|
67
|
-
db = await buildConnection(
|
|
94
|
+
const { default: createConnectionPoolPg } = await import('@databases/pg')
|
|
95
|
+
db = await buildConnection(
|
|
96
|
+
log,
|
|
97
|
+
createConnectionPoolPg,
|
|
98
|
+
connectionString,
|
|
99
|
+
poolSize,
|
|
100
|
+
null,
|
|
101
|
+
idleTimeoutMilliseconds,
|
|
102
|
+
queueTimeoutMilliseconds,
|
|
103
|
+
acquireLockTimeoutMilliseconds
|
|
104
|
+
)
|
|
68
105
|
sql = createConnectionPoolPg.sql
|
|
69
106
|
db.isPg = true
|
|
70
107
|
} else if (connectionString.indexOf('mysql') === 0) {
|
|
71
|
-
const createConnectionPoolMysql =
|
|
72
|
-
db = await buildConnection(
|
|
108
|
+
const { default: createConnectionPoolMysql } = await import('@databases/mysql')
|
|
109
|
+
db = await buildConnection(
|
|
110
|
+
log,
|
|
111
|
+
createConnectionPoolMysql,
|
|
112
|
+
connectionString,
|
|
113
|
+
poolSize,
|
|
114
|
+
null,
|
|
115
|
+
idleTimeoutMilliseconds,
|
|
116
|
+
queueTimeoutMilliseconds,
|
|
117
|
+
acquireLockTimeoutMilliseconds
|
|
118
|
+
)
|
|
73
119
|
sql = createConnectionPoolMysql.sql
|
|
74
120
|
const version = (await db.query(sql`SELECT VERSION()`))[0]['VERSION()']
|
|
75
121
|
db.version = version
|
|
@@ -78,27 +124,34 @@ async function createConnectionPool ({ log, connectionString, poolSize, idleTime
|
|
|
78
124
|
db.isMySql = true
|
|
79
125
|
}
|
|
80
126
|
} else if (connectionString.indexOf('sqlite') === 0) {
|
|
81
|
-
const sqlite =
|
|
127
|
+
const { default: sqlite } = await import('@matteo.collina/sqlite-pool')
|
|
82
128
|
const path = connectionString.replace('sqlite://', '')
|
|
83
|
-
db = sqlite.default(
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
129
|
+
db = sqlite.default(
|
|
130
|
+
connectionString === 'sqlite://:memory:' ? undefined : path,
|
|
131
|
+
{},
|
|
132
|
+
{
|
|
133
|
+
// TODO make this configurable
|
|
134
|
+
maxSize: 1,
|
|
135
|
+
// TODO make this configurable
|
|
136
|
+
// 10s max time to wait for a connection
|
|
137
|
+
releaseTimeoutMilliseconds: 10000,
|
|
138
|
+
onQuery ({ text, values }) {
|
|
139
|
+
log.trace(
|
|
140
|
+
{
|
|
141
|
+
query: {
|
|
142
|
+
text
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
'query'
|
|
146
|
+
)
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
)
|
|
97
150
|
sql = sqlite.sql
|
|
98
151
|
db.isSQLite = true
|
|
99
152
|
db.sql = sql
|
|
100
153
|
} else {
|
|
101
|
-
throw new
|
|
154
|
+
throw new SpecifyProtocolError()
|
|
102
155
|
}
|
|
103
156
|
|
|
104
157
|
// These info are necessary for telemetry attributes
|
|
@@ -108,17 +161,40 @@ async function createConnectionPool ({ log, connectionString, poolSize, idleTime
|
|
|
108
161
|
return { db, sql }
|
|
109
162
|
}
|
|
110
163
|
|
|
111
|
-
async function connect ({
|
|
164
|
+
export async function connect ({
|
|
165
|
+
connectionString,
|
|
166
|
+
log,
|
|
167
|
+
onDatabaseLoad,
|
|
168
|
+
poolSize,
|
|
169
|
+
include = {},
|
|
170
|
+
ignore = {},
|
|
171
|
+
autoTimestamp = true,
|
|
172
|
+
hooks = {},
|
|
173
|
+
schema,
|
|
174
|
+
limit = {},
|
|
175
|
+
dbschema,
|
|
176
|
+
cache,
|
|
177
|
+
idleTimeoutMilliseconds,
|
|
178
|
+
queueTimeoutMilliseconds,
|
|
179
|
+
acquireLockTimeoutMilliseconds
|
|
180
|
+
}) {
|
|
112
181
|
if (typeof autoTimestamp === 'boolean' && autoTimestamp === true) {
|
|
113
182
|
autoTimestamp = defaultAutoTimestampFields
|
|
114
183
|
}
|
|
115
184
|
// TODO validate config using the schema
|
|
116
185
|
if (!connectionString) {
|
|
117
|
-
throw new
|
|
186
|
+
throw new ConnectionStringRequiredError()
|
|
118
187
|
}
|
|
119
188
|
|
|
120
189
|
let queries
|
|
121
|
-
const { db, sql } = await createConnectionPool({
|
|
190
|
+
const { db, sql } = await createConnectionPool({
|
|
191
|
+
log,
|
|
192
|
+
connectionString,
|
|
193
|
+
poolSize,
|
|
194
|
+
queueTimeoutMilliseconds,
|
|
195
|
+
acquireLockTimeoutMilliseconds,
|
|
196
|
+
idleTimeoutMilliseconds
|
|
197
|
+
})
|
|
122
198
|
|
|
123
199
|
/* istanbul ignore next */
|
|
124
200
|
if (db.isPg) {
|
|
@@ -200,7 +276,7 @@ async function connect ({ connectionString, log, onDatabaseLoad, poolSize, inclu
|
|
|
200
276
|
// it should never happen.
|
|
201
277
|
/* istanbul ignore next */
|
|
202
278
|
if (typeof table !== 'string') {
|
|
203
|
-
throw new
|
|
279
|
+
throw new TableMustBeAStringError(table)
|
|
204
280
|
}
|
|
205
281
|
// If include is being used and a table is not explicitly included add it to the ignore object
|
|
206
282
|
if (Object.keys(include).length && !include[table]) {
|
|
@@ -209,7 +285,21 @@ async function connect ({ connectionString, log, onDatabaseLoad, poolSize, inclu
|
|
|
209
285
|
if (ignore[table] === true) {
|
|
210
286
|
continue
|
|
211
287
|
}
|
|
212
|
-
const entity = buildEntity(
|
|
288
|
+
const entity = buildEntity(
|
|
289
|
+
db,
|
|
290
|
+
sql,
|
|
291
|
+
log,
|
|
292
|
+
table,
|
|
293
|
+
queries,
|
|
294
|
+
autoTimestamp,
|
|
295
|
+
schema,
|
|
296
|
+
useSchema,
|
|
297
|
+
ignore[table] || {},
|
|
298
|
+
limit,
|
|
299
|
+
schemaList,
|
|
300
|
+
columns,
|
|
301
|
+
constraints
|
|
302
|
+
)
|
|
213
303
|
// Check for primary key of all entities
|
|
214
304
|
if (entity.primaryKeys.size === 0) {
|
|
215
305
|
log.warn({ table }, 'Cannot find any primary keys for table')
|
|
@@ -231,7 +321,7 @@ async function connect ({ connectionString, log, onDatabaseLoad, poolSize, inclu
|
|
|
231
321
|
entities,
|
|
232
322
|
cleanUpAllEntities: buildCleanUp(db, sql, log, entities, queries),
|
|
233
323
|
addEntityHooks,
|
|
234
|
-
dbschema
|
|
324
|
+
dbschema
|
|
235
325
|
}
|
|
236
326
|
|
|
237
327
|
if (cache) {
|
|
@@ -247,7 +337,7 @@ async function connect ({ connectionString, log, onDatabaseLoad, poolSize, inclu
|
|
|
247
337
|
function addEntityHooks (entityName, hooks) {
|
|
248
338
|
const entity = entities[entityName]
|
|
249
339
|
if (!entity) {
|
|
250
|
-
throw new
|
|
340
|
+
throw new CannotFindEntityError(entityName)
|
|
251
341
|
}
|
|
252
342
|
for (const key of Object.keys(hooks)) {
|
|
253
343
|
if (hooks[key] && entity[key]) {
|
|
@@ -260,7 +350,7 @@ async function connect ({ connectionString, log, onDatabaseLoad, poolSize, inclu
|
|
|
260
350
|
async function sqlMapper (app, opts) {
|
|
261
351
|
const mapper = await connect({
|
|
262
352
|
log: app.log,
|
|
263
|
-
...opts
|
|
353
|
+
...opts
|
|
264
354
|
})
|
|
265
355
|
|
|
266
356
|
app.onClose(() => mapper.db.dispose())
|
|
@@ -276,7 +366,7 @@ async function sqlMapper (app, opts) {
|
|
|
276
366
|
app.addHook('onRequest', function (req, reply, done) {
|
|
277
367
|
req.platformaticContext = {
|
|
278
368
|
app: this, // uses the encapsulated fastify instance of the route
|
|
279
|
-
reply
|
|
369
|
+
reply
|
|
280
370
|
}
|
|
281
371
|
done()
|
|
282
372
|
})
|
|
@@ -300,7 +390,7 @@ async function dropTable (db, sql, table) {
|
|
|
300
390
|
}
|
|
301
391
|
}
|
|
302
392
|
|
|
303
|
-
async function dropAllTables (db, sql, schemas) {
|
|
393
|
+
export async function dropAllTables (db, sql, schemas) {
|
|
304
394
|
let queries
|
|
305
395
|
/* istanbul ignore next */
|
|
306
396
|
if (db.isPg) {
|
|
@@ -313,13 +403,15 @@ async function dropAllTables (db, sql, schemas) {
|
|
|
313
403
|
queries = queriesFactory.sqlite
|
|
314
404
|
}
|
|
315
405
|
|
|
316
|
-
const tables = new Set(
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
406
|
+
const tables = new Set(
|
|
407
|
+
(await queries.listTables(db, sql, schemas)).map(t => {
|
|
408
|
+
/* istanbul ignore next */
|
|
409
|
+
if (t.schema) {
|
|
410
|
+
return `${t.schema}.${t.table}`
|
|
411
|
+
}
|
|
412
|
+
return t.table
|
|
413
|
+
})
|
|
414
|
+
)
|
|
323
415
|
let count = 0
|
|
324
416
|
|
|
325
417
|
while (tables.size > 0) {
|
|
@@ -341,10 +433,7 @@ async function dropAllTables (db, sql, schemas) {
|
|
|
341
433
|
}
|
|
342
434
|
}
|
|
343
435
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
module.exports.utils = require('./lib/utils')
|
|
349
|
-
module.exports.errors = errors
|
|
350
|
-
module.exports.dropAllTables = dropAllTables
|
|
436
|
+
export const plugin = fp(sqlMapper)
|
|
437
|
+
export default plugin
|
|
438
|
+
export * as errors from './lib/errors.js'
|
|
439
|
+
export * as utils from './lib/utils.js'
|
package/lib/cache.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
const { createCache } = require('async-cache-dedupe')
|
|
1
|
+
import { createCache } from 'async-cache-dedupe'
|
|
3
2
|
|
|
4
|
-
function setupCache (res, opts) {
|
|
3
|
+
export function setupCache (res, opts) {
|
|
5
4
|
// TODO validate opts
|
|
6
5
|
if (opts === true) {
|
|
7
6
|
opts = { ttl: 0 }
|
|
@@ -17,18 +16,22 @@ function setupCache (res, opts) {
|
|
|
17
16
|
const fnName = `${entity.name}Find`
|
|
18
17
|
const originalFn = entity.find
|
|
19
18
|
|
|
20
|
-
cache.define(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
cache.define(
|
|
20
|
+
fnName,
|
|
21
|
+
{
|
|
22
|
+
serialize (query) {
|
|
23
|
+
const serialized = {
|
|
24
|
+
...query,
|
|
25
|
+
ctx: undefined
|
|
26
|
+
}
|
|
27
|
+
return serialized
|
|
25
28
|
}
|
|
26
|
-
return serialized
|
|
27
29
|
},
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
async function (query) {
|
|
31
|
+
const res = await originalFn.call(entity, query)
|
|
32
|
+
return res
|
|
33
|
+
}
|
|
34
|
+
)
|
|
32
35
|
|
|
33
36
|
addEntityHooks(entity.singularName, {
|
|
34
37
|
find (originalFn, query) {
|
|
@@ -36,11 +39,9 @@ function setupCache (res, opts) {
|
|
|
36
39
|
return originalFn(query)
|
|
37
40
|
}
|
|
38
41
|
return cache[fnName](query)
|
|
39
|
-
}
|
|
42
|
+
}
|
|
40
43
|
})
|
|
41
44
|
}
|
|
42
45
|
|
|
43
46
|
return cache
|
|
44
47
|
}
|
|
45
|
-
|
|
46
|
-
module.exports = setupCache
|
package/lib/clean-up.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
import { Sorter } from '@hapi/topo'
|
|
2
|
+
import { tableName } from './utils.js'
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
const { Sorter } = require('@hapi/topo')
|
|
5
|
-
|
|
6
|
-
function buildCleanUp (db, sql, logger, entities) {
|
|
4
|
+
export function buildCleanUp (db, sql, logger, entities) {
|
|
7
5
|
return async function cleanUp () {
|
|
8
6
|
logger.trace('cleaning up')
|
|
9
7
|
await db.tx(async tx => {
|
|
@@ -32,5 +30,3 @@ function buildCleanUp (db, sql, logger, entities) {
|
|
|
32
30
|
})
|
|
33
31
|
}
|
|
34
32
|
}
|
|
35
|
-
|
|
36
|
-
module.exports = buildCleanUp
|
package/lib/connection-info.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// The most general way to get the connection info is through the driver.
|
|
2
2
|
// In this way, we don't need to do any assumptions about the connection string
|
|
3
3
|
// (with the exception of SQLite)
|
|
4
|
-
|
|
4
|
+
export async function getConnectionInfo (db, connectionString) {
|
|
5
5
|
let database, host, port, user
|
|
6
6
|
let dbSystem = 'unknown'
|
|
7
7
|
if (db.isPg) {
|
|
@@ -35,8 +35,6 @@ const getConnectionInfo = async (db, connectionString) => {
|
|
|
35
35
|
isPg: !!db.isPg,
|
|
36
36
|
isMySql: !!db.isMySql,
|
|
37
37
|
isSQLite: !!db.isSQLite,
|
|
38
|
-
dbSystem
|
|
38
|
+
dbSystem
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
|
-
|
|
42
|
-
module.exports = { getConnectionInfo }
|