Skip to content

Commit a22408c

Browse files
committed
feat: add native client support for getTransactionStatus()
- Add getTransactionStatus() to pg-native using libpq's PQtransactionStatus() with status mapping (0->I, 2->T, 3->E) - Update pg native client wrapper to delegate to pg-native - Remove native guard from txstatus tests (now runs in both modes) - Bump libpq to ^1.10.0 for transactionStatus() binding support
1 parent dafc9b4 commit a22408c

5 files changed

Lines changed: 88 additions & 79 deletions

File tree

packages/pg-native/index.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ const types = require('pg-types')
66
const buildResult = require('./lib/build-result')
77
const CopyStream = require('./lib/copy-stream')
88

9+
// https://www.postgresql.org/docs/current/libpq-status.html#LIBPQ-PQTRANSACTIONSTATUS
10+
// 0=IDLE, 1=ACTIVE, 2=INTRANS, 3=INERROR
11+
const statusMap = { 0: 'I', 2: 'T', 3: 'E' }
12+
913
const Client = (module.exports = function (config) {
1014
if (!(this instanceof Client)) {
1115
return new Client(config)
@@ -145,6 +149,10 @@ Client.prototype.escapeIdentifier = function (value) {
145149
return this.pq.escapeIdentifier(value)
146150
}
147151

152+
Client.prototype.getTransactionStatus = function () {
153+
return statusMap[this.pq.transactionStatus()] ?? null
154+
}
155+
148156
// export the version number so we can check it in node-postgres
149157
module.exports.version = require('./package.json').version
150158

packages/pg-native/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
},
3535
"homepage": "https://github.com/brianc/node-postgres/tree/master/packages/pg-native",
3636
"dependencies": {
37-
"libpq": "^1.8.15",
37+
"libpq": "^1.10.0",
3838
"pg-types": "2.2.0"
3939
},
4040
"devDependencies": {

packages/pg/lib/native/client.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,5 @@ Client.prototype.isConnected = function () {
323323
}
324324

325325
Client.prototype.getTransactionStatus = function () {
326-
// not supported in native client
327-
return null
326+
return this.native.getTransactionStatus()
328327
}

packages/pg/test/integration/client/txstatus-tests.js

Lines changed: 68 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -4,82 +4,79 @@ const suite = new helper.Suite()
44
const pg = helper.pg
55
const assert = require('assert')
66

7-
// txStatus tracking is not supported in native client
8-
if (!helper.args.native) {
9-
suite.test('txStatus tracking', function (done) {
10-
const client = new pg.Client()
11-
client.connect(
12-
assert.success(function () {
13-
// Run a simple query to initialize txStatus
14-
client.query(
15-
'SELECT 1',
16-
assert.success(function () {
17-
// Test 1: Initial state after query (should be idle)
18-
assert.equal(client.getTransactionStatus(), 'I', 'should start in idle state')
7+
suite.test('txStatus tracking', function (done) {
8+
const client = new pg.Client()
9+
client.connect(
10+
assert.success(function () {
11+
// Run a simple query to initialize txStatus
12+
client.query(
13+
'SELECT 1',
14+
assert.success(function () {
15+
// Test 1: Initial state after query (should be idle)
16+
assert.equal(client.getTransactionStatus(), 'I', 'should start in idle state')
1917

20-
// Test 2: BEGIN transaction
21-
client.query(
22-
'BEGIN',
23-
assert.success(function () {
24-
assert.equal(client.getTransactionStatus(), 'T', 'should be in transaction state')
18+
// Test 2: BEGIN transaction
19+
client.query(
20+
'BEGIN',
21+
assert.success(function () {
22+
assert.equal(client.getTransactionStatus(), 'T', 'should be in transaction state')
2523

26-
// Test 3: COMMIT
27-
client.query(
28-
'COMMIT',
29-
assert.success(function () {
30-
assert.equal(client.getTransactionStatus(), 'I', 'should return to idle after commit')
24+
// Test 3: COMMIT
25+
client.query(
26+
'COMMIT',
27+
assert.success(function () {
28+
assert.equal(client.getTransactionStatus(), 'I', 'should return to idle after commit')
3129

32-
client.end(done)
33-
})
34-
)
35-
})
36-
)
37-
})
38-
)
39-
})
40-
)
41-
})
30+
client.end(done)
31+
})
32+
)
33+
})
34+
)
35+
})
36+
)
37+
})
38+
)
39+
})
4240

43-
suite.test('txStatus error state', function (done) {
44-
const client = new pg.Client()
45-
client.connect(
46-
assert.success(function () {
47-
// Run a simple query to initialize txStatus
48-
client.query(
49-
'SELECT 1',
50-
assert.success(function () {
51-
client.query(
52-
'BEGIN',
53-
assert.success(function () {
54-
// Execute invalid SQL to trigger error state
55-
client.query('INVALID SQL SYNTAX', function (err) {
56-
assert(err, 'should receive error from invalid query')
41+
suite.test('txStatus error state', function (done) {
42+
const client = new pg.Client()
43+
client.connect(
44+
assert.success(function () {
45+
// Run a simple query to initialize txStatus
46+
client.query(
47+
'SELECT 1',
48+
assert.success(function () {
49+
client.query(
50+
'BEGIN',
51+
assert.success(function () {
52+
// Execute invalid SQL to trigger error state
53+
client.query('INVALID SQL SYNTAX', function (err) {
54+
assert(err, 'should receive error from invalid query')
5755

58-
// Issue a sync query to ensure ReadyForQuery has been processed
59-
// This guarantees transaction status has been updated
60-
client.query('SELECT 1', function () {
61-
// This callback fires after ReadyForQuery is processed
62-
assert.equal(client.getTransactionStatus(), 'E', 'should be in error state')
56+
// Issue a sync query to ensure ReadyForQuery has been processed
57+
// This guarantees transaction status has been updated
58+
client.query('SELECT 1', function () {
59+
// This callback fires after ReadyForQuery is processed
60+
assert.equal(client.getTransactionStatus(), 'E', 'should be in error state')
6361

64-
// Rollback to recover
65-
client.query(
66-
'ROLLBACK',
67-
assert.success(function () {
68-
assert.equal(
69-
client.getTransactionStatus(),
70-
'I',
71-
'should return to idle after rollback from error'
72-
)
73-
client.end(done)
74-
})
75-
)
76-
})
62+
// Rollback to recover
63+
client.query(
64+
'ROLLBACK',
65+
assert.success(function () {
66+
assert.equal(
67+
client.getTransactionStatus(),
68+
'I',
69+
'should return to idle after rollback from error'
70+
)
71+
client.end(done)
72+
})
73+
)
7774
})
7875
})
79-
)
80-
})
81-
)
82-
})
83-
)
84-
})
85-
}
76+
})
77+
)
78+
})
79+
)
80+
})
81+
)
82+
})

yarn.lock

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5955,13 +5955,13 @@ levn@~0.3.0:
59555955
prelude-ls "~1.1.2"
59565956
type-check "~0.3.2"
59575957

5958-
libpq@^1.8.15:
5959-
version "1.8.15"
5960-
resolved "https://registry.yarnpkg.com/libpq/-/libpq-1.8.15.tgz#bf9cea8e59e1a4a911d06df01d408213a09925ad"
5961-
integrity sha512-4lSWmly2Nsj3LaTxxtFmJWuP3Kx+0hYHEd+aNrcXEWT0nKWaPd9/QZPiMkkC680zeALFGHQdQWjBvnilL+vgWA==
5958+
libpq@^1.10.0:
5959+
version "1.10.0"
5960+
resolved "https://registry.yarnpkg.com/libpq/-/libpq-1.10.0.tgz#238d01d416abca8768aab09bc82d81af9c7ffa23"
5961+
integrity sha512-PHY+JGD3+9X5b2emXLh+WJEnz1jhczO1xs25ZH0xbMWvQi+Hd9X/mTZOrGA99Rcw/DvNjsBRlegroqigpNfaJA==
59625962
dependencies:
59635963
bindings "1.5.0"
5964-
nan "~2.22.2"
5964+
nan "~2.23.1"
59655965

59665966
lines-and-columns@^1.1.6:
59675967
version "1.1.6"
@@ -6686,6 +6686,11 @@ nan@~2.22.2:
66866686
resolved "https://registry.yarnpkg.com/nan/-/nan-2.22.2.tgz#6b504fd029fb8f38c0990e52ad5c26772fdacfbb"
66876687
integrity sha512-DANghxFkS1plDdRsX0X9pm0Z6SJNN6gBdtXfanwoZ8hooC5gosGFSBGRYHUVPz1asKA/kMRqDRdHrluZ61SpBQ==
66886688

6689+
nan@~2.23.1:
6690+
version "2.23.1"
6691+
resolved "https://registry.yarnpkg.com/nan/-/nan-2.23.1.tgz#6f86a31dd87e3d1eb77512bf4b9e14c8aded3975"
6692+
integrity sha512-r7bBUGKzlqk8oPBDYxt6Z0aEdF1G1rwlMcLk8LCOMbOzf0mG+JUfUzG4fIMWwHWP0iyaLWEQZJmtB7nOHEm/qw==
6693+
66896694
nanoid@^3.3.11:
66906695
version "3.3.11"
66916696
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b"

0 commit comments

Comments
 (0)