Skip to content

Commit

Permalink
JSCBC-435: Added missing multi-value subdoc operations.
Browse files Browse the repository at this point in the history
Motivation
----------
A couple of sub-document operations which enabled performing
array operations involving multiple values were missing from
the SDK.

Changes
-------
Implemented the missing arrayAppendAll, arrayPrependAll and
arrayInsertAll methods, which enable you to perform the
named operations against multiple values as opposed to
only a single value.

Change-Id: I8e1f1cf9f633d3cf9a89d270e962ef8c5bfa9d6e
Reviewed-on: http://review.couchbase.org/88892
Reviewed-by: Sergey Avseyev <sergey.avseyev@gmail.com>
Tested-by: Brett Lawson <brett19@gmail.com>
  • Loading branch information
brett19 committed Feb 8, 2018
1 parent 37bfdd7 commit 4bba345
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 6 deletions.
62 changes: 59 additions & 3 deletions lib/bucket.js
Original file line number Diff line number Diff line change
Expand Up @@ -3053,7 +3053,7 @@ MutateInBuilder.prototype.remove = function(path, options) {
*/
MutateInBuilder.prototype.arrayPrepend = function(path, value, options) {
return this._addOp(binding.Constants.SDCMD_ARRAY_ADD_FIRST,
path, _parseSdOpts(options), value);
path, _parseSdOpts(options), [value]);
};

/**
Expand All @@ -3062,6 +3062,25 @@ MutateInBuilder.prototype.arrayPrepend = function(path, value, options) {
*/
MutateInBuilder.prototype.pushFront = MutateInBuilder.prototype.arrayPrepend;

/**
* Adds an array push all front operation to this mutation operation set.
*
* @param {string} path
* @param {Object[]} values
* @param {Object} [options]
* @param {boolean} [options.createParents]
* @param {boolean} [options.xattr]
* @param {boolean} [options.xattrMacro]
* @returns {MutateInBuilder}
*
* @since 2.4.4
* @committed
*/
MutateInBuilder.prototype.arrayPrependAll = function(path, values, options) {
return this._addOp(binding.Constants.SDCMD_ARRAY_ADD_FIRST,
path, _parseSdOpts(options), values);
};

/**
* Adds an array push back operation to this mutation operation set.
*
Expand All @@ -3078,7 +3097,7 @@ MutateInBuilder.prototype.pushFront = MutateInBuilder.prototype.arrayPrepend;
*/
MutateInBuilder.prototype.arrayAppend = function(path, value, options) {
return this._addOp(binding.Constants.SDCMD_ARRAY_ADD_LAST,
path, _parseSdOpts(options), value);
path, _parseSdOpts(options), [value]);
};

/**
Expand All @@ -3087,6 +3106,25 @@ MutateInBuilder.prototype.arrayAppend = function(path, value, options) {
*/
MutateInBuilder.prototype.pushBack = MutateInBuilder.prototype.arrayAppend;

/**
* Adds an array push all back operation to this mutation operation set.
*
* @param {string} path
* @param {Object[]} values
* @param {Object} [options]
* @param {boolean} [options.createParents]
* @param {boolean} [options.xattr]
* @param {boolean} [options.xattrMacro]
* @returns {MutateInBuilder}
*
* @since 2.4.4
* @committed
*/
MutateInBuilder.prototype.arrayAppendAll = function(path, values, options) {
return this._addOp(binding.Constants.SDCMD_ARRAY_ADD_LAST,
path, _parseSdOpts(options), values);
};

/**
* Adds an array insert operation to this mutation operation set.
*
Expand All @@ -3102,7 +3140,25 @@ MutateInBuilder.prototype.pushBack = MutateInBuilder.prototype.arrayAppend;
*/
MutateInBuilder.prototype.arrayInsert = function(path, value, options) {
return this._addOp(binding.Constants.SDCMD_ARRAY_INSERT,
path, _parseSdOpts(options), value);
path, _parseSdOpts(options), [value]);
};

/**
* Adds an array insert all operation to this mutation operation set.
*
* @param {string} path
* @param {Object[]} values
* @param {Object} [options]
* @param {boolean} [options.xattr]
* @param {boolean} [options.xattrMacro]
* @returns {MutateInBuilder}
*
* @since 2.4.4
* @committed
*/
MutateInBuilder.prototype.arrayInsertAll = function(path, values, options) {
return this._addOp(binding.Constants.SDCMD_ARRAY_INSERT,
path, _parseSdOpts(options), values);
};

/**
Expand Down
16 changes: 13 additions & 3 deletions src/operations.cc
Original file line number Diff line number Diff line change
Expand Up @@ -557,20 +557,24 @@ NAN_METHOD(CouchbaseImpl::fnMutateIn) {
}

int dataCount = 0;
int isMultiValued = 0;
switch(sdcmd.sdcmd) {
case LCB_SDCMD_REMOVE:
dataCount = 2;
break;
case LCB_SDCMD_REPLACE:
case LCB_SDCMD_ARRAY_INSERT:
case LCB_SDCMD_DICT_ADD:
case LCB_SDCMD_DICT_UPSERT:
case LCB_SDCMD_ARRAY_ADD_FIRST:
case LCB_SDCMD_ARRAY_ADD_LAST:
case LCB_SDCMD_ARRAY_ADD_UNIQUE:
case LCB_SDCMD_COUNTER:
dataCount = 3;
break;
case LCB_SDCMD_ARRAY_INSERT:
case LCB_SDCMD_ARRAY_ADD_FIRST:
case LCB_SDCMD_ARRAY_ADD_LAST:
dataCount = 3;
isMultiValued = 1;
break;
default:
return Nan::ThrowError(Error::create("unexpected optype"));
}
Expand Down Expand Up @@ -599,6 +603,12 @@ NAN_METHOD(CouchbaseImpl::fnMutateIn) {
&sdcmd.value.u_buf.contig.bytes,
&sdcmd.value.u_buf.contig.nbytes,
info[index + 3]);

if (isMultiValued != 0) {
// Strip the brackets off of this.
*((char*)&sdcmd.value.u_buf.contig.bytes) += 1;
sdcmd.value.u_buf.contig.nbytes -= 2;
}
}

specs.push_back(sdcmd);
Expand Down
57 changes: 57 additions & 0 deletions test/subdoc.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,61 @@ describe('#subdoc', function () {
}));
}));
});

it('should use arrayAppend and arrayAppendAll correctly', function(done) {
var itemMap = {test: [1, 2, 3]};

H.b.upsert('sdArrAppend', itemMap, H.okCallback(function() {
H.b.mutateIn('sdArrAppend')
.arrayAppend('test', 4)
.execute(H.okCallback(function(res) {
H.b.mutateIn('sdArrAppend')
.arrayAppendAll('test', [5, 6, 7])
.execute(H.okCallback(function(res) {
H.b.get('sdArrAppend', H.okCallback(function (res) {
assert.deepEqual(res.value.test, [1, 2, 3, 4, 5, 6, 7]);
done();
}));
}));
}));
}));
});

it('should use arrayPrepend and arrayPrependAll correctly', function(done) {
var itemMap = {test: [5, 6, 7]};

H.b.upsert('sdArrPrepend', itemMap, H.okCallback(function() {
H.b.mutateIn('sdArrPrepend')
.arrayPrepend('test', 4)
.execute(H.okCallback(function(res) {
H.b.mutateIn('sdArrPrepend')
.arrayPrependAll('test', [1, 2, 3])
.execute(H.okCallback(function(res) {
H.b.get('sdArrPrepend', H.okCallback(function (res) {
assert.deepEqual(res.value.test, [1, 2, 3, 4, 5, 6, 7]);
done();
}));
}));
}));
}));
});

it('should use arrayInsert and arrayInsertAll correctly', function(done) {
var itemMap = {test: [1, 2, 6, 7]};

H.b.upsert('sdArrInsert', itemMap, H.okCallback(function() {
H.b.mutateIn('sdArrInsert')
.arrayInsert('test[2]', 3)
.execute(H.okCallback(function(res) {
H.b.mutateIn('sdArrInsert')
.arrayInsertAll('test[3]', [4, 5])
.execute(H.okCallback(function(res) {
H.b.get('sdArrInsert', H.okCallback(function (res) {
assert.deepEqual(res.value.test, [1, 2, 3, 4, 5, 6, 7]);
done();
}));
}));
}));
}));
});
});

0 comments on commit 4bba345

Please sign in to comment.