1 | 'use strict'
|
2 |
|
3 | const cli = require('heroku-cli-util')
|
4 |
|
5 | async function run(context, heroku) {
|
6 | const fetcher = require('../lib/fetcher')(heroku)
|
7 | const psql = require('../lib/psql')
|
8 |
|
9 | let db = await fetcher.database(context.app, context.args.database)
|
10 |
|
11 | let truncatedQueryString = prefix => {
|
12 | let column = `${prefix}query`
|
13 | if (context.flags.truncate) {
|
14 | return `CASE WHEN length(${column}) <= 40 THEN ${column} ELSE substr(${column}, 0, 39) || '…' END`
|
15 | } else {
|
16 | return column
|
17 | }
|
18 | }
|
19 |
|
20 | let query = `
|
21 | SELECT
|
22 | pg_stat_activity.pid,
|
23 | pg_class.relname,
|
24 | pg_locks.transactionid,
|
25 | pg_locks.granted,
|
26 | ${truncatedQueryString('pg_stat_activity.')} AS query_snippet,
|
27 | age(now(),pg_stat_activity.query_start) AS "age"
|
28 | FROM pg_stat_activity,pg_locks left
|
29 | OUTER JOIN pg_class
|
30 | ON (pg_locks.relation = pg_class.oid)
|
31 | WHERE pg_stat_activity.query <> '<insufficient privilege>'
|
32 | AND pg_locks.pid = pg_stat_activity.pid
|
33 | AND pg_locks.mode = 'ExclusiveLock'
|
34 | AND pg_stat_activity.pid <> pg_backend_pid() order by query_start;
|
35 | `
|
36 |
|
37 | let output = await psql.exec(db, query)
|
38 | process.stdout.write(output)
|
39 | }
|
40 |
|
41 | const cmd = {
|
42 | topic: 'pg',
|
43 | description: 'display queries with active locks',
|
44 | needsApp: true,
|
45 | needsAuth: true,
|
46 | args: [{ name: 'database', optional: true }],
|
47 | flags: [{ name: 'truncate', char: 't', description: 'truncates queries to 40 charaters' }],
|
48 | run: cli.command({ preauth: true }, run)
|
49 | }
|
50 |
|
51 | module.exports = [
|
52 | Object.assign({ command: 'locks' }, cmd)
|
53 | ]
|