@platformatic/sql-mapper 3.52.0 → 3.52.2
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/index.js +38 -5
- package/lib/entity.js +19 -8
- package/lib/queries/mariadb.js +1 -1
- package/lib/queries/mysql-shared.js +21 -0
- package/lib/queries/pg.js +19 -0
- package/lib/queries/sqlite.js +8 -0
- package/package.json +3 -3
package/index.js
CHANGED
|
@@ -223,6 +223,12 @@ export async function connect ({
|
|
|
223
223
|
if (!dbschema) {
|
|
224
224
|
dbschema = await queries.listTables(db, sql, schemaList)
|
|
225
225
|
|
|
226
|
+
// Also introspect database views
|
|
227
|
+
if (queries.listViews) {
|
|
228
|
+
const views = await queries.listViews(db, sql, schemaList)
|
|
229
|
+
dbschema = dbschema.concat(views)
|
|
230
|
+
}
|
|
231
|
+
|
|
226
232
|
// TODO make this parallel or a single query
|
|
227
233
|
for (const wrap of dbschema) {
|
|
228
234
|
const { table, schema } = wrap
|
|
@@ -271,7 +277,7 @@ export async function connect ({
|
|
|
271
277
|
}
|
|
272
278
|
}
|
|
273
279
|
|
|
274
|
-
for (const { table, schema, columns, constraints } of dbschema) {
|
|
280
|
+
for (const { table, schema, columns, constraints, isView } of dbschema) {
|
|
275
281
|
// The following line is a safety net when developing this module,
|
|
276
282
|
// it should never happen.
|
|
277
283
|
/* istanbul ignore next */
|
|
@@ -298,10 +304,11 @@ export async function connect ({
|
|
|
298
304
|
limit,
|
|
299
305
|
schemaList,
|
|
300
306
|
columns,
|
|
301
|
-
constraints
|
|
307
|
+
constraints,
|
|
308
|
+
isView
|
|
302
309
|
)
|
|
303
|
-
// Check for primary key of all entities
|
|
304
|
-
if (entity.primaryKeys.size === 0) {
|
|
310
|
+
// Check for primary key of all entities (views are allowed without PKs)
|
|
311
|
+
if (entity.primaryKeys.size === 0 && !isView) {
|
|
305
312
|
log.warn({ table }, 'Cannot find any primary keys for table')
|
|
306
313
|
continue
|
|
307
314
|
}
|
|
@@ -386,7 +393,19 @@ async function dropTable (db, sql, table) {
|
|
|
386
393
|
}
|
|
387
394
|
return table
|
|
388
395
|
} catch (err) {
|
|
389
|
-
// ignore, it will be dropped on the next
|
|
396
|
+
// ignore, it will be dropped on the next round
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
async function dropView (db, sql, view) {
|
|
401
|
+
try {
|
|
402
|
+
if (db.isSQLite) {
|
|
403
|
+
await db.query(sql`DROP VIEW ${sql(view)};`)
|
|
404
|
+
} else {
|
|
405
|
+
await db.query(sql`DROP VIEW ${sql(view)} CASCADE;`)
|
|
406
|
+
}
|
|
407
|
+
} catch {
|
|
408
|
+
// ignore
|
|
390
409
|
}
|
|
391
410
|
}
|
|
392
411
|
|
|
@@ -403,6 +422,20 @@ export async function dropAllTables (db, sql, schemas) {
|
|
|
403
422
|
queries = queriesFactory.sqlite
|
|
404
423
|
}
|
|
405
424
|
|
|
425
|
+
// Drop views first since they may depend on tables
|
|
426
|
+
if (queries.listViews) {
|
|
427
|
+
const views = (await queries.listViews(db, sql, schemas)).map(v => {
|
|
428
|
+
/* istanbul ignore next */
|
|
429
|
+
if (v.schema) {
|
|
430
|
+
return `${v.schema}.${v.table}`
|
|
431
|
+
}
|
|
432
|
+
return v.table
|
|
433
|
+
})
|
|
434
|
+
for (const view of views) {
|
|
435
|
+
await dropView(db, sql, view)
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
|
|
406
439
|
const tables = new Set(
|
|
407
440
|
(await queries.listTables(db, sql, schemas)).map(t => {
|
|
408
441
|
/* istanbul ignore next */
|
package/lib/entity.js
CHANGED
|
@@ -29,7 +29,8 @@ function createMapper (
|
|
|
29
29
|
useSchemaInName,
|
|
30
30
|
limitConfig,
|
|
31
31
|
columns,
|
|
32
|
-
constraintsList
|
|
32
|
+
constraintsList,
|
|
33
|
+
isView
|
|
33
34
|
) {
|
|
34
35
|
/* istanbul ignore next */ // Ignoring because this won't be fully covered by DB not supporting schemas (SQLite)
|
|
35
36
|
const entityName = useSchemaInName ? toUpperFirst(`${camelcase(schema)}${toSingular(table)}`) : toSingular(table)
|
|
@@ -430,7 +431,7 @@ function createMapper (
|
|
|
430
431
|
return res.map(fixOutput)
|
|
431
432
|
}
|
|
432
433
|
|
|
433
|
-
|
|
434
|
+
const entity = {
|
|
434
435
|
name: entityName,
|
|
435
436
|
singularName,
|
|
436
437
|
pluralName,
|
|
@@ -443,11 +444,17 @@ function createMapper (
|
|
|
443
444
|
fixOutput,
|
|
444
445
|
find,
|
|
445
446
|
count,
|
|
446
|
-
|
|
447
|
-
save,
|
|
448
|
-
delete: _delete,
|
|
449
|
-
updateMany
|
|
447
|
+
isView: !!isView
|
|
450
448
|
}
|
|
449
|
+
|
|
450
|
+
if (!isView) {
|
|
451
|
+
entity.insert = insert
|
|
452
|
+
entity.save = save
|
|
453
|
+
entity.delete = _delete
|
|
454
|
+
entity.updateMany = updateMany
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
return entity
|
|
451
458
|
}
|
|
452
459
|
|
|
453
460
|
export function buildEntity (
|
|
@@ -463,7 +470,8 @@ export function buildEntity (
|
|
|
463
470
|
limitConfig,
|
|
464
471
|
schemaList,
|
|
465
472
|
columns,
|
|
466
|
-
constraintsList
|
|
473
|
+
constraintsList,
|
|
474
|
+
isView
|
|
467
475
|
) {
|
|
468
476
|
const columnsNames = columns.map(c => c.column_name)
|
|
469
477
|
for (const ignoredColumn of Object.keys(ignore)) {
|
|
@@ -623,7 +631,10 @@ export function buildEntity (
|
|
|
623
631
|
autoTimestamp,
|
|
624
632
|
schema,
|
|
625
633
|
useSchemaInName,
|
|
626
|
-
limitConfig
|
|
634
|
+
limitConfig,
|
|
635
|
+
undefined,
|
|
636
|
+
undefined,
|
|
637
|
+
isView
|
|
627
638
|
)
|
|
628
639
|
entity.relations = currentRelations
|
|
629
640
|
|
package/lib/queries/mariadb.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { listColumns, listConstraints, listTables, updateMany, updateOne } from './mysql-shared.js'
|
|
1
|
+
export { listColumns, listConstraints, listTables, listViews, updateMany, updateOne } from './mysql-shared.js'
|
|
2
2
|
export { deleteAll, insertMany, insertOne } from './shared.js'
|
|
@@ -7,6 +7,7 @@ export async function listTables (db, sql, schemas) {
|
|
|
7
7
|
SELECT TABLE_SCHEMA, TABLE_NAME
|
|
8
8
|
FROM information_schema.tables
|
|
9
9
|
WHERE table_schema in (${schemaList})
|
|
10
|
+
AND TABLE_TYPE = 'BASE TABLE'
|
|
10
11
|
`)
|
|
11
12
|
return res.map(r => ({ schema: r.TABLE_SCHEMA, table: r.TABLE_NAME }))
|
|
12
13
|
} else {
|
|
@@ -14,6 +15,7 @@ export async function listTables (db, sql, schemas) {
|
|
|
14
15
|
SELECT TABLE_SCHEMA, TABLE_NAME
|
|
15
16
|
FROM information_schema.tables
|
|
16
17
|
WHERE table_schema = (SELECT DATABASE())
|
|
18
|
+
AND TABLE_TYPE = 'BASE TABLE'
|
|
17
19
|
`)
|
|
18
20
|
return res.map(r => ({ schema: r.TABLE_SCHEMA, table: r.TABLE_NAME }))
|
|
19
21
|
}
|
|
@@ -106,4 +108,23 @@ export async function updateMany (db, sql, table, schema, criteria, input, field
|
|
|
106
108
|
return res
|
|
107
109
|
}
|
|
108
110
|
|
|
111
|
+
export async function listViews (db, sql, schemas) {
|
|
112
|
+
if (schemas) {
|
|
113
|
+
const schemaList = sql.__dangerous__rawValue(schemas.map(s => `'${s}'`))
|
|
114
|
+
const res = await db.query(sql`
|
|
115
|
+
SELECT TABLE_SCHEMA, TABLE_NAME
|
|
116
|
+
FROM information_schema.views
|
|
117
|
+
WHERE table_schema in (${schemaList})
|
|
118
|
+
`)
|
|
119
|
+
return res.map(r => ({ schema: r.TABLE_SCHEMA, table: r.TABLE_NAME, isView: true }))
|
|
120
|
+
} else {
|
|
121
|
+
const res = await db.query(sql`
|
|
122
|
+
SELECT TABLE_SCHEMA, TABLE_NAME
|
|
123
|
+
FROM information_schema.views
|
|
124
|
+
WHERE table_schema = (SELECT DATABASE())
|
|
125
|
+
`)
|
|
126
|
+
return res.map(r => ({ schema: r.TABLE_SCHEMA, table: r.TABLE_NAME, isView: true }))
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
109
130
|
export const hasILIKE = false
|
package/lib/queries/pg.js
CHANGED
|
@@ -111,4 +111,23 @@ export async function listEnumValues (db, sql, table, schema) {
|
|
|
111
111
|
return db.query(query)
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
+
export async function listViews (db, sql, schemas) {
|
|
115
|
+
if (schemas) {
|
|
116
|
+
const schemaList = sql.__dangerous__rawValue(schemas.map(s => `'${s}'`))
|
|
117
|
+
const res = await db.query(sql`
|
|
118
|
+
SELECT viewname, schemaname
|
|
119
|
+
FROM pg_catalog.pg_views
|
|
120
|
+
WHERE
|
|
121
|
+
schemaname in (${schemaList})`)
|
|
122
|
+
return res.map(r => ({ schema: r.schemaname, table: r.viewname, isView: true }))
|
|
123
|
+
}
|
|
124
|
+
const res = await db.query(sql`
|
|
125
|
+
SELECT viewname, schemaname
|
|
126
|
+
FROM pg_catalog.pg_views
|
|
127
|
+
WHERE
|
|
128
|
+
schemaname = current_schema()
|
|
129
|
+
`)
|
|
130
|
+
return res.map(r => ({ schema: r.schemaname, table: r.viewname, isView: true }))
|
|
131
|
+
}
|
|
132
|
+
|
|
114
133
|
export const hasILIKE = true
|
package/lib/queries/sqlite.js
CHANGED
|
@@ -231,4 +231,12 @@ export async function updateMany (db, sql, table, schema, criteria, input, field
|
|
|
231
231
|
return res
|
|
232
232
|
}
|
|
233
233
|
|
|
234
|
+
export async function listViews (db, sql) {
|
|
235
|
+
const res = await db.query(sql`
|
|
236
|
+
SELECT name FROM sqlite_master
|
|
237
|
+
WHERE type='view'
|
|
238
|
+
`)
|
|
239
|
+
return res.map(r => ({ schema: null, table: r.name, isView: true }))
|
|
240
|
+
}
|
|
241
|
+
|
|
234
242
|
export const hasILIKE = false
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/sql-mapper",
|
|
3
|
-
"version": "3.52.
|
|
3
|
+
"version": "3.52.2",
|
|
4
4
|
"description": "A data mapper utility for SQL databases",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"camelcase": "^6.3.0",
|
|
36
36
|
"fastify-plugin": "^5.0.0",
|
|
37
37
|
"inflected": "^2.1.0",
|
|
38
|
-
"@platformatic/foundation": "3.52.
|
|
39
|
-
"@platformatic/telemetry": "3.52.
|
|
38
|
+
"@platformatic/foundation": "3.52.2",
|
|
39
|
+
"@platformatic/telemetry": "3.52.2"
|
|
40
40
|
},
|
|
41
41
|
"tsd": {
|
|
42
42
|
"directory": "test/types"
|