Hello,
I’m having an issue where I’m using a N1qlQuery to return a list of objects, and then selecting one of those objects, modifying its data, and then attempting to update it with conditional update (using CAS)…
The CAS returned by a query appears to be invalid for an update. Consider this code:
var payload = {"new":"item"}; bucket.insert(guid(), payload, function(err, result) { // Wait 3 seconds to validate that the query will return the inserted object. setTimeout(function() { bucket.query(queryBuilder.fromString("SELECT *,meta() AS `path` FROM `default` WHERE new=\"item\""), function(err, result) { var doc = result[0]; bucket.replace(doc.path.id, doc, {cas: doc.path.cas}, function(err,result) { if(err) { console.log("An error occurred: "); console.log(err); } else { console.log(result); } bucket.disconnect(); }); }); }, 3000); });
This will output:
TypeError: cas option needs to be a CAS object or string. at Bucket._checkCasOption (/Users/mattpryor/projects/xtranet-api/node_modules/couchbase/lib/bucket.js:1147:13) at Bucket._store (/Users/mattpryor/projects/xtranet-api/node_modules/couchbase/lib/bucket.js:1555:8) at Bucket.replace (/Users/mattpryor/projects/xtranet-api/node_modules/couchbase/lib/bucket.js:1642:8)
If I instead cast the returned CAS to a string, using {cas: doc.path.cas.toString}
, I will get a different error:
CouchbaseError: The key already exists in the server. If you have supplied a CAS then the key exists with a CAS value different than specified
I would expect that the CAS returned from the Query would match the CAS returned from a GET, but it seems that is not the case as well, consider the following code:
var payload = {"new":"item"}; var id = guid(); bucket.insert(id, payload, function(err, result) { setTimeout(function() { bucket.get(id, function(err, result) { console.log("GET cas: " + result.cas); }); bucket.query(queryBuilder.fromString("SELECT *,meta() AS `path` FROM `default` WHERE new=\"item\""), function(err, result) { console.log("QUERY cas: " + result[0].path.cas); }); }, 3000); });
This will output something like the following:
GET cas: CouchbaseCas<103571374997504> QUERY cas: 5047431593984
I had expected that these 2 values would match.
If I do a get, then the replace using the retrieved CAS, then everything works.
Is there something I am missing, or is this a bug?
Thanks,
Matthew Pryor
I’m using Couchbase Server Enterprise 4.5.0, and the Node SDK version: 2.2.1 on OSX El Capitan