diff --git a/src/database.js b/src/database.js index b7e180f80..15c9ff92b 100644 --- a/src/database.js +++ b/src/database.js @@ -622,6 +622,12 @@ Database.prototype.getTransaction = function(options, callback) { * @param {string|object} query A SQL query or query object. See an * [ExecuteSqlRequest](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.v1#google.spanner.v1.ExecuteSqlRequest) * object. + * @param {boolean} [query.json=false] Receive the rows as serialized objects. + * This is the equivalent of calling `toJSON()` on each row. + * @param {object} [query.jsonOptions] Configuration options for the serialized + * objects. + * @param {boolean} [query.jsonOptions.wrapNumbers=false] Protect large integer + * values outside of the range of JavaScript Number. * @param {object} [query.params] A map of parameter name to values. * @param {object} [query.types] A map of parameter types. * @param {DatabaseRunRequest} [options] [Transaction options](https://cloud.google.com/spanner/docs/timestamp-bounds). @@ -642,9 +648,9 @@ Database.prototype.getTransaction = function(options, callback) { * // Error handling omitted. * } * - * const row1 = rows[0]; + * const firstRow = rows[0]; * - * // row1 = [ + * // firstRow = [ * // { * // name: 'SingerId', * // value: '1' @@ -665,9 +671,26 @@ Database.prototype.getTransaction = function(options, callback) { * // Error handling omitted. * } * - * const row1 = rows[0]; + * const firstRow = rows[0]; * - * // row1.toJSON() = { + * // firstRow.toJSON() = { + * // SingerId: '1', + * // Name: 'Eddie Wilson' + * // } + * }); + * + * //- + * // Alternatively, set `query.json` to `true`, and this step will be performed + * // automaticaly. + * //- + * database.run(query, function(err, rows) { + * if (err) { + * // Error handling omitted. + * } + * + * const firstRow = rows[0]; + * + * // firstRow = { * // SingerId: '1', * // Name: 'Eddie Wilson' * // } @@ -800,6 +823,24 @@ Database.prototype.run = function(query, options, callback) { * }); * * //- + * // Alternatively, set `query.json` to `true`, and this step will be performed + * // automaticaly. + * //- + * query.json = true; + * + * database.runStream(query) + * .on('error', function(err) {}) + * .on('data', function(row) { + * // row = { + * // SingerId: '1', + * // Name: 'Eddie Wilson' + * // } + * }) + * .on('end', function() { + * // All results retrieved. + * }); + * + * //- * // The SQL query string can contain parameter placeholders. A parameter * // placeholder consists of '@' followed by the parameter name. * //- @@ -862,8 +903,8 @@ Database.prototype.runStream = function(query, options) { }; } - delete reqOpts.toJSON; - delete reqOpts.toJSONOptions; + delete reqOpts.json; + delete reqOpts.jsonOptions; function makeRequest(resumeToken) { return self.pool_.requestStream({ @@ -874,8 +915,8 @@ Database.prototype.runStream = function(query, options) { } return new PartialResultStream(makeRequest, { - toJSON: query.toJSON, - toJSONOptions: query.toJSONOptions, + json: query.json, + jsonOptions: query.jsonOptions, }); }; diff --git a/src/partial-result-stream.js b/src/partial-result-stream.js index f475e60ff..b04f55494 100644 --- a/src/partial-result-stream.js +++ b/src/partial-result-stream.js @@ -108,10 +108,8 @@ function partialResultStream(requestFn, options) { rowChunks = []; - if (options.toJSON) { - formattedRows = formattedRows.map( - exec('toJSON', options.toJSONOptions) - ); + if (options.json) { + formattedRows = formattedRows.map(exec('toJSON', options.jsonOptions)); } split(formattedRows, userStream, function() { diff --git a/src/table.js b/src/table.js index ca1090847..2e0d56036 100644 --- a/src/table.js +++ b/src/table.js @@ -388,6 +388,12 @@ Table.prototype.insert = function(keyVals, callback) { * yielded. If using a composite key, provide an array within this array. * See the example below. * @property {string} [index] The name of an index on the table. + * @property {boolean} [json=false] Receive the rows as serialized objects. This + * is the equivalent of calling `toJSON()` on each row. + * @property {object} [jsonOptions] Configuration options for the serialized + * objects. + * @property {boolean} [jsonOptions.wrapNumbers=false] Protect large integer + * values outside of the range of JavaScript Number. * @property {object} [keySet] Defines a collection of keys and/or key ranges to * read. * @property {number} [limit] The number of rows to yield. @@ -447,9 +453,9 @@ Table.prototype.insert = function(keyVals, callback) { * // Error handling omitted. * } * - * const row1 = rows[0]; + * const firstRow = rows[0]; * - * // row1 = [ + * // firstRow = [ * // { * // name: 'SingerId', * // value: '1' @@ -481,15 +487,18 @@ Table.prototype.insert = function(keyVals, callback) { * //- * // Rows are returned as an array of object arrays. Each object has a `name` * // and `value` property. To get a serialized object, call `toJSON()`. + * // + * // Alternatively, set `query.json` to `true`, and this step will be performed + * // automaticaly. * //- * table.read(query, function(err, rows) { * if (err) { * // Error handling omitted. * } * - * const row1 = rows[0]; + * const firstRow = rows[0]; * - * // rows1.toJSON() = { + * // firstRow.toJSON() = { * // SingerId: '1', * // Name: 'Eddie Wilson' * // } diff --git a/src/transaction-request.js b/src/transaction-request.js index f77df7253..228b0aa21 100644 --- a/src/transaction-request.js +++ b/src/transaction-request.js @@ -211,6 +211,32 @@ TransactionRequest.fromProtoTimestamp_ = function(value) { * }); * * //- + * // Alternatively, set `query.json` to `true`, and this step will be performed + * // automaticaly. + * //- + * database.runTransaction(function(err, transaction) { + * if (err) { + * // Error handling omitted. + * } + * + * transaction.createReadStream('Singers', { + * keys: ['1'], + * columns: ['SingerId', 'name'], + * json: true, + * }) + * .on('error', function(err) {}) + * .on('data', function(row) { + * // row = { + * // SingerId: '1', + * // Name: 'Eddie Wilson' + * // } + * }) + * .on('end', function() { + * // All results retrieved. + * }); + * }); + * + * //- * // If you anticipate many results, you can end a stream early to prevent * // unnecessary processing and API requests. * //- @@ -244,8 +270,8 @@ TransactionRequest.prototype.createReadStream = function(table, query) { query ); - delete reqOpts.toJSON; - delete reqOpts.toJSONOptions; + delete reqOpts.json; + delete reqOpts.jsonOptions; if (this.transaction && this.id) { reqOpts.transaction = { @@ -297,8 +323,8 @@ TransactionRequest.prototype.createReadStream = function(table, query) { } return new PartialResultStream(makeRequest, { - toJSON: query.toJSON, - toJSONOptions: query.toJSONOptions, + json: query.json, + jsonOptions: query.jsonOptions, }); }; @@ -467,6 +493,12 @@ TransactionRequest.prototype.insert = function(table, keyVals, callback) { * yielded. If using a composite key, provide an array within this array. * See the example below. * @property {string} [index] The name of an index on the table. + * @property {boolean} [json=false] Receive the rows as serialized objects. This + * is the equivalent of calling `toJSON()` on each row. + * @property {object} [jsonOptions] Configuration options for the serialized + * objects. + * @property {boolean} [jsonOptions.wrapNumbers=false] Protect large integer + * values outside of the range of JavaScript Number. */ /** * @typedef {array} TransactionRequestReadResponse @@ -522,9 +554,9 @@ TransactionRequest.prototype.insert = function(table, keyVals, callback) { * // Error handling omitted. * } * - * const row1 = rows[0]; + * const firstRow = rows[0]; * - * // row1 = [ + * // firstRow = [ * // { * // name: 'SingerId', * // value: '1' @@ -571,9 +603,37 @@ TransactionRequest.prototype.insert = function(table, keyVals, callback) { * // Error handling omitted. * } * - * const row1 = rows[0]; + * const firstRow = rows[0]; + * + * // firstRow.toJSON() = { + * // SingerId: '1', + * // Name: 'Eddie Wilson' + * // } + * + * // End the transaction. Note that no callback is provided. + * transaction.end(); + * }); + * }); + * + * //- + * // Alternatively, set `query.json` to `true`, and this step will be performed + * // automaticaly. + * //- + * database.runTransaction(function(err, transaction) { + * if (err) { + * // Error handling omitted. + * } + * + * query.json = true; + * + * transaction.read('Singers', query, function(err, rows) { + * if (err) { + * // Error handling omitted. + * } + * + * const firstRow = rows[0]; * - * // row1.toJSON() = { + * // firstRow = { * // SingerId: '1', * // Name: 'Eddie Wilson' * // } diff --git a/system-test/spanner.js b/system-test/spanner.js index d80fc6be4..fb764f1e4 100644 --- a/system-test/spanner.js +++ b/system-test/spanner.js @@ -964,7 +964,7 @@ describe('Spanner', function() { .createReadStream({ keys: [id], columns: ['SingerId', 'name'], - toJSON: true, + json: true, }) .on('error', done) .on('data', function(row) { @@ -1001,8 +1001,8 @@ describe('Spanner', function() { .createReadStream({ keys: [id], columns: ['SingerId', 'Int'], - toJSON: true, - toJSONOptions: {wrapNumbers: true}, + json: true, + jsonOptions: {wrapNumbers: true}, }) .on('error', done) .on('data', function(row) { diff --git a/test/database.js b/test/database.js index 6fff96588..47c638e0c 100644 --- a/test/database.js +++ b/test/database.js @@ -623,28 +623,28 @@ describe('Database', function() { assert(stream instanceof FakePartialResultStream); }); - it('should pass toJSON, toJSONOptions to PartialResultStream', function() { + it('should pass json, jsonOptions to PartialResultStream', function() { var query = extend({}, QUERY); - query.toJSON = {}; - query.toJSONOptions = {}; + query.json = {}; + query.jsonOptions = {}; var stream = database.runStream(query); assert.deepStrictEqual(stream.calledWith_[1], { - toJSON: query.toJSON, - toJSONOptions: query.toJSONOptions, + json: query.json, + jsonOptions: query.jsonOptions, }); }); - it('should not pass toJSON, toJSONOptions to request', function(done) { + it('should not pass json, jsonOptions to request', function(done) { database.pool_.requestStream = function(config) { - assert.strictEqual(config.reqOpts.toJSON, undefined); - assert.strictEqual(config.reqOpts.toJSONOptions, undefined); + assert.strictEqual(config.reqOpts.json, undefined); + assert.strictEqual(config.reqOpts.jsonOptions, undefined); done(); }; var query = extend({}, QUERY); - query.toJSON = {}; - query.toJSONOptions = {}; + query.json = {}; + query.jsonOptions = {}; var stream = database.runStream(query); var makeRequestFn = stream.calledWith_[0]; diff --git a/test/partial-result-stream.js b/test/partial-result-stream.js index 484dede83..9eea20474 100644 --- a/test/partial-result-stream.js +++ b/test/partial-result-stream.js @@ -246,8 +246,8 @@ describe('PartialResultStream', function() { it('should return the formatted row as JSON', function(done) { var options = { - toJSON: true, - toJSONOptions: {}, + json: true, + jsonOptions: {}, }; var partialResultStream = partialResultStreamModule(function() { @@ -256,7 +256,7 @@ describe('PartialResultStream', function() { var formattedRow = { toJSON: function(options_) { - assert.strictEqual(options_, options.toJSONOptions); + assert.strictEqual(options_, options.jsonOptions); done(); }, }; diff --git a/test/transaction-request.js b/test/transaction-request.js index 91c5e89cd..8c25936cd 100644 --- a/test/transaction-request.js +++ b/test/transaction-request.js @@ -537,28 +537,28 @@ describe('TransactionRequest', function() { makeRequestFn(resumeToken); }); - it('should accept toJSON and toJSONOptions', function() { + it('should accept json and jsonOptions', function() { var query = { - toJSON: {}, - toJSONOptions: {}, + json: {}, + jsonOptions: {}, }; var stream = transactionRequest.createReadStream(TABLE, query); var streamOptions = stream.calledWith_[1]; - assert.strictEqual(streamOptions.toJSON, query.toJSON); - assert.strictEqual(streamOptions.toJSONOptions, query.toJSONOptions); + assert.strictEqual(streamOptions.json, query.json); + assert.strictEqual(streamOptions.jsonOptions, query.jsonOptions); }); - it('should delete toJSON, toJSONOptions from reqOpts', function(done) { + it('should delete json, jsonOptions from reqOpts', function(done) { var query = { - toJSON: {}, - toJSONOptions: {}, + json: {}, + jsonOptions: {}, }; transactionRequest.requestStream = function(config) { - assert.strictEqual(config.reqOpts.toJSON, undefined); - assert.strictEqual(config.reqOpts.toJSONOptions, undefined); + assert.strictEqual(config.reqOpts.json, undefined); + assert.strictEqual(config.reqOpts.jsonOptions, undefined); done(); };