Skip to content
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

Add transaction method #144

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,10 @@ Destroy a batch, and releases any locks it has acquired on the db.

Call this if you want to abort a batch without flushing it.

#### `const output = await db.transaction((batch) => {})`

Makes a new locked batch, gives a callback for operations, and flushes or closes if any error.

#### `const stream = db.createReadStream([range], [options])`

Make a read stream. Sort order is based on the binary value of the keys.
Expand Down
17 changes: 17 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,23 @@ class Hyperbee extends ReadyResource {
return new Batch(this, this.core, mutexify(), true, opts)
}

async transaction (cb) {
const batch = this.batch()
let output = null

try {
await batch.lock()
output = await cb(batch)
} catch (err) {
await batch.close()
throw err
}

await batch.flush()

return output
}

del (key, opts) {
const b = new Batch(this, this.core, null, true, opts)
return b.del(key, opts)
Expand Down
28 changes: 28 additions & 0 deletions test/batches.js
Original file line number Diff line number Diff line change
Expand Up @@ -284,3 +284,31 @@ test('batches close when instance closes', async function (t) {

await d.close()
})

test('transaction', async function (t) {
const db = create()

const id = await db.transaction(async function (b) {
await b.put('/users/1')
return 123
})

t.is(id, 123)
t.ok(await db.get('/users/1'))
})

test('transaction does not commit if any error', async function (t) {
const db = create()

try {
await db.transaction(async function (b) {
await b.put('/users/1')
throw new Error('Failed')
})
t.fail('Should have failed')
} catch (err) {
t.is(err.message, 'Failed')
}

t.absent(await db.get('/users/1'))
})