Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/bugfix/ARSN-412-add-support-for-…
Browse files Browse the repository at this point in the history
…exists-condition' into w/8.1/bugfix/ARSN-412-add-support-for-exists-condition
  • Loading branch information
anurag4DSB committed May 3, 2024
2 parents 30eaaf1 + e369c7e commit f13ec2c
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 5 deletions.
2 changes: 1 addition & 1 deletion lib/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ export class IndexTransaction {
'missing condition for conditional put'
);
}
if (typeof condition.notExists !== 'string') {
if (typeof condition.notExists !== 'string' && typeof condition.exists !== 'string') {
throw propError(
'unsupportedConditionalOperation',
'missing key or supported condition'
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"engines": {
"node": ">=16"
},
"version": "8.1.130",
"version": "8.1.131",
"description": "Common utilities for the S3 project components",
"main": "build/index.js",
"repository": {
Expand Down
94 changes: 91 additions & 3 deletions tests/unit/db.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,21 @@ function checkKeyNotExistsInDB(db, key, cb) {
return cb(err);
}
if (value) {
return cb(errors.PreconditionFailed);
return cb(errors.EntityAlreadyExists);
}
return cb();
});
}

function checkKeyExistsInDB(db, key, callback) {
return db.get(key, err => {
if (err) {
return callback(err.notFound ? errors.NoSuchEntity : err);
}
return callback();
});
}

class ConditionalLevelDB {
constructor() {
this.db = createDb();
Expand All @@ -70,6 +79,9 @@ class ConditionalLevelDB {
case ('notExists' in cond):
checkKeyNotExistsInDB(this.db, cond.notExists, asyncCallback);
break;
case ('exists' in cond):
checkKeyExistsInDB(this.db, cond.exists, asyncCallback);
break;
default:
asyncCallback(new Error('unsupported conditional operation'));
}
Expand Down Expand Up @@ -425,7 +437,7 @@ describe('IndexTransaction', () => {
value: value3,
});
return transaction.commit(err => {
if (!err || !err.is.PreconditionFailed) {
if (!err || !err.is.EntityAlreadyExists) {
return done(new Error('should not be able to conditional put for duplicate key'));
}
return async.parallel([
Expand Down Expand Up @@ -457,11 +469,87 @@ describe('IndexTransaction', () => {
it('should not allow batch operation with unsupported condition', done => {
const transaction = new IndexTransaction();
try {
transaction.addCondition({ exists: key1 });
transaction.addCondition({ like: key1 });
done(new Error('should fail for unsupported condition, currently supported - notExists'));
} catch (err) {
assert.strictEqual(err.unsupportedConditionalOperation, true);
done();
}
});

it('should allow batch operation with key specified in exists condition is present in db', done => {
const db = new ConditionalLevelDB();
const { client } = db;
let transaction = new IndexTransaction(db);
transaction.put(key1, value1);
return async.series([
next => transaction.commit(next),
next => client.get(key1, next),
], err => {
assert.ifError(err);
// create new transaction as previous transaction is already committed
transaction = new IndexTransaction(db);
transaction.addCondition({ exists: key1 });
transaction.push({
type: 'put',
key: key1,
value: value2,
});
return async.series([
next => transaction.commit(next),
next => client.get(key1, next),
], (err, res) => {
assert.ifError(err);
assert.strictEqual(res[1], value2);
return done();
});
});
});

it('should not allow batch operation with key specified in exists condition is not in db', done => {
const db = new ConditionalLevelDB();
const { client } = db;
const transaction = new IndexTransaction(db);
transaction.addCondition({ exists: key1 });
transaction.push({
type: 'put',
key: key1,
value: value1,
});
return transaction.commit(err => {
assert.strictEqual(err && err.NoSuchEntity, true);
return checkKeyNotExistsInDB(client, key1, done);
});
});

it('should handle batch operations with multiple conditions correctly', done => {
const db = new ConditionalLevelDB();
const { client } = db;
let transaction = new IndexTransaction(db);
transaction.put(key1, value1);
return async.series([
next => transaction.commit(next),
next => client.get(key1, next),
], err => {
assert.ifError(err);
// create new transaction as previous transaction is already committed
transaction = new IndexTransaction(db);
transaction.addCondition({ exists: key1 });
transaction.addCondition({ notExists: key2 });
transaction.push({
type: 'put',
key: key1,
value: value2,
});

return async.series([
next => transaction.commit(next),
next => client.get(key1, next),
], (err, res) => {
assert.ifError(err);
assert.strictEqual(res[1], value2);
return done();
});
});
});
});

0 comments on commit f13ec2c

Please sign in to comment.