-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Add pg-transaction module #3516
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
6f7ac5f
Add pg-transaction module
brianc 922c28a
Lets try skipping pg-transaction on node 16
brianc b7f9806
vibe
brianc 09ecec8
add ts-node to root deps
brianc b5174f3
Omit node 16 test conditional (not used anymore)
brianc 37cb1ff
Remove node 16 from test matrix
brianc b954f53
Try to fix weird lint error
brianc File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
25 changes: 25 additions & 0 deletions
packages/pg-transaction/package.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
{ | ||
"name": "pg-transaction", | ||
"version": "2.0.0", | ||
"main": "dist/index.js", | ||
"license": "MIT", | ||
"scripts": { | ||
"build": "tsc", | ||
"start": "node dist/index.js", | ||
"pretest": "tsc", | ||
"test": "mocha dist/**/*.test.js" | ||
}, | ||
"dependencies": { | ||
"@types/node": "^20.0.0", | ||
"typescript": "^5.8.3" | ||
}, | ||
"engines": { | ||
"node": ">=18.0.0" | ||
}, | ||
"devDependencies": { | ||
"@types/mocha": "^10.0.10", | ||
"@types/pg": "^8.10.9", | ||
"mocha": "^10.8.2", | ||
"pg": "^8.11.3" | ||
} | ||
} |
74 changes: 74 additions & 0 deletions
packages/pg-transaction/src/index.test.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import { strict as assert } from 'assert' | ||
import { Client } from 'pg' | ||
import { transaction } from '.' | ||
|
||
class DisposableClient extends Client { | ||
// overwrite the query method and log the arguments and then dispatch to the original method | ||
override query(...args: any[]): any { | ||
// console.log('Executing query:', ...args); | ||
// @ts-ignore | ||
return super.query(...args) | ||
} | ||
|
||
async [Symbol.asyncDispose]() { | ||
await this.end() | ||
} | ||
} | ||
|
||
async function getClient(): Promise<DisposableClient> { | ||
const client = new DisposableClient() | ||
await client.connect() | ||
await client.query('CREATE TEMP TABLE test_table (id SERIAL PRIMARY KEY, name TEXT)') | ||
return client | ||
} | ||
|
||
describe('transaction', () => { | ||
it('should create a client with an empty temp table', async () => { | ||
await using client = await getClient() | ||
const { rowCount } = await client.query('SELECT * FROM test_table') | ||
assert.equal(rowCount, 0, 'Temp table should be empty on creation') | ||
}) | ||
|
||
it('automatically commits on success', async () => { | ||
await using client = await getClient() | ||
|
||
const result = await transaction(client, async () => { | ||
await client.query('INSERT INTO test_table (name) VALUES (1ドル)', ['test']) | ||
const { rows } = await client.query('SELECT * FROM test_table') | ||
return rows[0].name // Should return 'test' | ||
}) | ||
|
||
assert.equal(result, 'test') | ||
}) | ||
|
||
it('automatically rolls back on error', async () => { | ||
await using client = await getClient() | ||
|
||
// Assert that the transaction function rejects with the expected error | ||
await assert.rejects( | ||
async () => { | ||
await transaction(client, async () => { | ||
await client.query('INSERT INTO test_table (name) VALUES (1ドル)', ['test']) | ||
await client.query('SELECT * FROM test_table') | ||
throw new Error('Simulated error') // This will trigger a rollback | ||
}) | ||
}, | ||
{ | ||
name: 'Error', | ||
message: 'Simulated error', | ||
} | ||
) | ||
|
||
// Verify that the transaction rolled back | ||
const { rowCount } = await client.query('SELECT * FROM test_table') | ||
assert.equal(rowCount, 0, 'Table should be empty after rollback') | ||
}) | ||
|
||
it('can return nothing from the transaction with correct type', async () => { | ||
await using client = await getClient() | ||
|
||
const _: void = await transaction(client, async () => { | ||
await client.query('INSERT INTO test_table (name) VALUES (1ドル)', ['test']) | ||
}) | ||
}) | ||
}) |
42 changes: 42 additions & 0 deletions
packages/pg-transaction/src/index.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { Client } from 'pg' | ||
|
||
async function doTransaction(client: Client) { | ||
await client.query('BEGIN') | ||
|
||
let shouldRollback = false | ||
let disposed = false | ||
|
||
return { | ||
async [Symbol.asyncDispose]() { | ||
if (disposed) return | ||
disposed = true | ||
|
||
if (shouldRollback) { | ||
await client.query('ROLLBACK') | ||
} else { | ||
await client.query('COMMIT') | ||
} | ||
}, | ||
|
||
rollback() { | ||
shouldRollback = true | ||
}, | ||
} | ||
} | ||
|
||
// Auto-rollback wrapper that catches errors automatically | ||
async function transaction<T>(client: Client, fn: () => Promise<T>): Promise<T> { | ||
await using txn = await doTransaction(client) | ||
|
||
try { | ||
const result = await fn() | ||
// If we get here, success - transaction will auto-commit | ||
return result | ||
} catch (error) { | ||
// If error occurs, mark for rollback | ||
txn.rollback() | ||
throw error | ||
} | ||
} | ||
|
||
export { transaction as transaction } |
16 changes: 16 additions & 0 deletions
packages/pg-transaction/tsconfig.eslint.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"compilerOptions": { | ||
"target": "es2022", | ||
"module": "commonjs", | ||
"lib": ["es2022"], | ||
"outDir": "./dist", | ||
"rootDir": "./src", | ||
"declaration": true, | ||
"esModuleInterop": true, | ||
"forceConsistentCasingInFileNames": true, | ||
"strict": true, | ||
"skipLibCheck": true | ||
}, | ||
"include": ["src/**/*"], | ||
"exclude": ["node_modules", "dist", "test"] | ||
} |
16 changes: 16 additions & 0 deletions
packages/pg-transaction/tsconfig.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"compilerOptions": { | ||
"target": "es2022", | ||
"module": "commonjs", | ||
"lib": ["es2022", "ESNext.Disposable"], | ||
"outDir": "./dist", | ||
"rootDir": "./src", | ||
"declaration": true, | ||
"esModuleInterop": true, | ||
"forceConsistentCasingInFileNames": true, | ||
"strict": true, | ||
"skipLibCheck": true | ||
}, | ||
"include": ["src/**/*"], | ||
"exclude": ["node_modules", "dist", "test"] | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.