Repository: basho/riak-nodejs-client (js)

Issue:
Support for setting `Content Encoding` on RiakObjects [JIRA: CLIENTS-429]
We use the content encoding field when storing compressed objects in Riak. This is currently supported in RiakPBC client (https://github.com/nlf/riakpbc), which we are moving from.

I have added the field and raised a PR if that helps.

Pull request:
Add "Content Encoding" to RiakObject
Fixes #69 (CLIENTS-429)

Patch:
diff --git a/lib/commands/kv/riakobject.js b/lib/commands/kv/riakobject.js
index ef2c13f..3666e28 100644
--- a/lib/commands/kv/riakobject.js
+++ b/lib/commands/kv/riakobject.js
@@ -142,6 +142,26 @@ RiakObject.prototype = {
     getContentType : function() {
         return this.contentType;
     },
+    /**
+     * Set the content encoding.
+     *
+     * @method setContentEncoding
+     * @param {String} contentEncoding the content encoding
+     * @chainable
+     */
+    setContentEncoding : function(contentEncoding) {
+        this.contentEncoding = contentEncoding;
+        return this;
+    },
+    /**
+     * Get the content encoding
+     *
+     * @method getContentEncoding
+     * @returns {String} the content encoding
+     */
+    getContentEncoding : function() {
+        return this.contentEncoding;
+    },
     /**
      * Set the user meta data.
      * 
@@ -348,13 +368,16 @@ module.exports.createFromRpbContent = function(rpbContent, convertToJs) {
     if (rpbContent.getContentType()) {
         ro.contentType = rpbContent.getContentType().toString('utf8');
     }
+
+    if (rpbContent.getContentEncoding()) {
+        ro.contentEncoding = rpbContent.getContentEncoding().toString('utf8');
+    }
     
     if (rpbContent.getLastMod()) {
         var lm = rpbContent.getLastMod();
         var lmu = rpbContent.getLastModUsecs();
         ro.lastModified = ((lm * 1000) + (lmu / 1000));
     }
-
     
     ro.isTombstone = rpbContent.getDeleted() ? true : false;
     
@@ -437,6 +460,10 @@ module.exports.populateRpbContentFromRiakObject = function(ro) {
         rpbContent.setContentType(new Buffer(ro.getContentType()));
     }
 
+    if (ro.getContentEncoding()) {
+        rpbContent.setContentEncoding(new Buffer(ro.getContentEncoding()));
+    }
+
     var i, pair;
     if (ro.hasIndexes()) {
         var allIndexes = ro.getIndexes();


Test patch:
diff --git a/test/integration/kv/storevalue.js b/test/integration/kv/storevalue.js
index b7341d5..b9d327c 100644
--- a/test/integration/kv/storevalue.js
+++ b/test/integration/kv/storevalue.js
@@ -16,6 +16,7 @@
 
 var Test = require('../testparams');
 var StoreValue = require('../../../lib/commands/kv/storevalue');
+var RiakObject = require('../../../lib/commands/kv/riakobject');
 var RiakNode = require('../../../lib/core/riaknode');
 var RiakCluster = require('../../../lib/core/riakcluster');
 var assert = require('assert');
@@ -179,6 +180,40 @@ describe('StoreValue - Integration', function() {
        
    });
    
+   it('Should store a RiakObject and generate a key, returning it', function(done) {
+        var ro = new RiakObject();
+        ro.setBucket(Test.bucketName + '_sv');
+        ro.setContentType('text/plain');
+        ro.setContentEncoding('utf8');
+        ro.setValue('this is a string');
+
+        var callback = function(err, resp) {
+            assert(!err, err);
+            assert(resp.generatedKey);
+
+            var obj = resp.values.shift();
+
+            var val = obj.getValue().toString('utf8');
+            assert.equal(val, 'this is a string');
+
+            var contentType = obj.getContentType().toString('utf8');
+            assert.equal(contentType, 'text/plain');
+
+            var contentEncoding = obj.getContentEncoding().toString('utf8');
+            assert.equal(contentEncoding, 'utf8');
+
+            done();
+        };
+
+        var store = new StoreValue.Builder()
+            .withContent(ro)
+            .withCallback(callback)
+            .withReturnBody(true)
+            .build();
+
+        cluster.execute(store);
+   });
+   
    after(function(done) {
         Test.cleanBucket(cluster, 'default', Test.bucketName + '_sv', function() { 
             Test.cleanBucket(cluster, Test.bucketType, Test.bucketName + '_sv', function() {
@@ -186,7 +221,6 @@ describe('StoreValue - Integration', function() {
                 cluster.stop();
             });
         });
-        
    });
    
 });
diff --git a/test/unit/storevalue.js b/test/unit/storevalue.js
index fe610bf..76db32d 100644
--- a/test/unit/storevalue.js
+++ b/test/unit/storevalue.js
@@ -26,12 +26,12 @@ var assert = require('assert');
 describe('StoreValue', function() {
     describe('Build', function() {
         it('should build a RpbPutReq correctly', function(done) {
-            
             var value = 'this is a value';
             var riakObject = new RiakObject();
             riakObject.setUserMeta([{key: 'metaKey1', value: 'metaValue1'}]);
             riakObject.addToIndex('email_bin','roach@basho.com');
             riakObject.setContentType('application/json');
+            riakObject.setContentEncoding('gzip');
             riakObject.setValue('this is a value');
             riakObject.setLinks([{bucket: 'b', key: 'k', tag: 't'},
                 {bucket: 'b', key: 'k2', tag: 't2'}]);
@@ -66,33 +66,36 @@ describe('StoreValue', function() {
             assert.equal(protobuf.getReturnHead(), true);
             assert.equal(protobuf.getIfNotModified(), true);
             assert.equal(protobuf.getIfNoneMatch(), true);
-            assert.equal(protobuf.getContent().getValue().toString('utf8'), value);
-            assert.equal(protobuf.getContent().getContentType().toString('utf8'), 'application/json');
-            assert(protobuf.getContent().getIndexes().length === 1);
-            assert.equal(protobuf.getContent().getIndexes()[0].key.toString('utf8'), 'email_bin');
-            assert.equal(protobuf.getContent().getIndexes()[0].value.toString('utf8'), 'roach@basho.com');
-            assert(protobuf.getContent().getUsermeta().length === 1);
-            assert.equal(protobuf.getContent().getUsermeta()[0].key.toString('utf8'), 'metaKey1');
-            assert.equal(protobuf.getContent().getUsermeta()[0].value.toString('utf8'), 'metaValue1');
-            assert.equal(protobuf.getContent().getLinks()[0].bucket.toString('utf8'), 'b');
-            assert.equal(protobuf.getContent().getLinks()[0].key.toString('utf8'), 'k');
-            assert.equal(protobuf.getContent().getLinks()[0].tag.toString('utf8'), 't');
-            assert.equal(protobuf.getContent().getLinks()[1].bucket.toString('utf8'), 'b');
-            assert.equal(protobuf.getContent().getLinks()[1].key.toString('utf8'), 'k2');
-            assert.equal(protobuf.getContent().getLinks()[1].tag.toString('utf8'), 't2');
+
+            var content = protobuf.getContent();
+            assert.equal(content.getValue().toString('utf8'), value);
+            assert.equal(content.getContentType().toString('utf8'), 'application/json');
+            assert.equal(content.getContentEncoding().toString('utf8'), 'gzip');
+            assert(content.getIndexes().length === 1);
+            assert.equal(content.getIndexes()[0].key.toString('utf8'), 'email_bin');
+            assert.equal(content.getIndexes()[0].value.toString('utf8'), 'roach@basho.com');
+            assert(content.getUsermeta().length === 1);
+            assert.equal(content.getUsermeta()[0].key.toString('utf8'), 'metaKey1');
+            assert.equal(content.getUsermeta()[0].value.toString('utf8'), 'metaValue1');
+            assert.equal(content.getLinks()[0].bucket.toString('utf8'), 'b');
+            assert.equal(content.getLinks()[0].key.toString('utf8'), 'k');
+            assert.equal(content.getLinks()[0].tag.toString('utf8'), 't');
+            assert.equal(content.getLinks()[1].bucket.toString('utf8'), 'b');
+            assert.equal(content.getLinks()[1].key.toString('utf8'), 'k2');
+            assert.equal(content.getLinks()[1].tag.toString('utf8'), 't2');
             assert.equal(protobuf.getTimeout(), 20000);
             done();
-            
         });
         
         it('Should take the key, bucket, type and vclock from a RiakObject', function(done) {
-           
             var value = 'this is a value';
             var riakObject = new RiakObject()
                     .setKey('key')
                     .setBucket('bucket_name')
                     .setBucketType('bucket_type')
                     .setVClock(new Buffer('1234'))
+                    .setContentType('text/plain')
+                    .setContentEncoding('utf8')
                     .setValue('this is a value');
             
             var storeCommand = new StoreValue.Builder()
@@ -106,9 +109,12 @@ describe('StoreValue', function() {
             assert.equal(protobuf.getBucket().toString('utf8'), 'bucket_name');
             assert.equal(protobuf.getKey().toString('utf8'), 'key');
             assert.equal(protobuf.getVclock().toString('utf8'), '1234');
-            assert.equal(protobuf.getContent().getValue().toString('utf8'), 'this is a value');
+
+            var content = protobuf.getContent();
+            assert.equal(content.getContentType().toString('utf8'), 'text/plain');
+            assert.equal(content.getContentEncoding().toString('utf8'), 'utf8');
+            assert.equal(content.getValue().toString('utf8'), 'this is a value');
             done();
-            
         });
         
         it('should take a RpbPutResp and call the users callback with the response', function(done) {
@@ -182,7 +188,6 @@ describe('StoreValue', function() {
        
             storeCommand.onRiakError(rpbErrorResp);
            
-           
         });
         
     });