@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 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 roundon the next roundon the next roundon the next round
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
- return {
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
- insert,
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
 
@@ -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
@@ -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.0",
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.0",
39
- "@platformatic/telemetry": "3.52.0"
38
+ "@platformatic/foundation": "3.52.2",
39
+ "@platformatic/telemetry": "3.52.2"
40
40
  },
41
41
  "tsd": {
42
42
  "directory": "test/types"