diff --git a/lib/bigquery/dataset.js b/lib/bigquery/dataset.js index 2ebcf3413cd..5907600e3f1 100644 --- a/lib/bigquery/dataset.js +++ b/lib/bigquery/dataset.js @@ -28,6 +28,12 @@ var extend = require('extend'); */ var Table = require('./table.js'); +/** + * @type {module:common/streamrouter} + * @private + */ +var streamRouter = require('../common/stream-router.js'); + /** * @type {module:common/util} * @private @@ -177,6 +183,26 @@ Dataset.prototype.getMetadata = function(callback) { * dataset.getTables(function(err, tables, nextQuery, apiResponse) { * // If `nextQuery` is non-null, there are more results to fetch. * }); + * + * //- + * // Get the tables as a readable object stream. + * // `table` is a Table object + * //- + * dataset.getTables() + * .on('error', console.error) + * .on('data', function(table) {}) + * .on('end', function() { + * // All tables have been retrieved + * }); + * + * //- + * // If you anticipate many results, you can end a stream early to prevent + * // unnecessary processing and API requests. + * //- + * dataset.getTables() + * .on('data', function(table) { + * this.end(); + * }); */ Dataset.prototype.getTables = function(query, callback) { var that = this; @@ -291,4 +317,11 @@ Dataset.prototype.makeReq_ = function(method, path, query, body, callback) { this.bigQuery.makeReq_(method, path, query, body, callback); }; +/*! Developer Documentation + * + * These methods can be used with either a callback or as a readable object + * stream. `streamRouter` is used to add this dual behavior. + */ +streamRouter.extend(Dataset, 'getTables'); + module.exports = Dataset; diff --git a/system-test/bigquery.js b/system-test/bigquery.js index dbb7c001a81..fe087ab7467 100644 --- a/system-test/bigquery.js +++ b/system-test/bigquery.js @@ -21,6 +21,7 @@ var assert = require('assert'); var async = require('async'); var Dataset = require('../lib/bigquery/dataset'); +var Table = require('../lib/bigquery/table'); var env = require('./env'); var fs = require('fs'); var Job = require('../lib/bigquery/job'); @@ -272,6 +273,28 @@ describe('BigQuery', function() { }); }); }); + + it('should get tables', function(done) { + dataset.getTables(function(err, tables) { + assert.ifError(err); + assert(tables[0] instanceof Table); + done(); + }); + }); + + it('should get tables as a stream', function(done) { + var tableEmitted = false; + + dataset.getTables() + .on('error', done) + .on('data', function(table) { + tableEmitted = table instanceof Table; + }) + .on('end', function() { + assert.strictEqual(tableEmitted, true); + done(); + }); + }); }); describe('BigQuery/Table', function() { diff --git a/test/bigquery/dataset.js b/test/bigquery/dataset.js index bf0213de331..9f6175aa760 100644 --- a/test/bigquery/dataset.js +++ b/test/bigquery/dataset.js @@ -18,20 +18,62 @@ 'use strict'; +// If we don't stub see4_crc32 and use mockery, we get "Module did not self- +// register". +var crc = require('sse4_crc32'); + var assert = require('assert'); -var Dataset = require('../../lib/bigquery/dataset'); -var Table = require('../../lib/bigquery/table'); var util = require('../../lib/common/util'); +var mockery = require('mockery'); + +var extended = false; +var fakeStreamRouter = { + extend: function(Class, methods) { + if (Class.name !== 'Dataset') { + return; + } + + methods = util.arrayize(methods); + assert.equal(Class.name, 'Dataset'); + assert.deepEqual(methods, ['getTables']); + extended = true; + } +}; describe('BigQuery/Dataset', function() { var BIGQUERY = { projectId: 'my-project' }; var DATASET_ID = 'kittens'; + var Dataset; + var Table; var ds; + before(function() { + mockery.registerMock('sse4_crc32', crc); + mockery.registerMock('../common/stream-router.js', fakeStreamRouter); + mockery.enable({ + useCleanCache: true, + warnOnUnregistered: false + }); + + Dataset = require('../../lib/bigquery/dataset'); + Table = require('../../lib/bigquery/table'); + }); + + after(function() { + mockery.deregisterAll(); + mockery.disable(); + }); + beforeEach(function() { ds = new Dataset(BIGQUERY, DATASET_ID); }); + describe('instantiation', function() { + it('should extend the correct methods', function() { + assert(extended); // See `fakeStreamRouter.extend` + }); + }); + describe('createTable', function() { var SCHEMA_OBJECT = { fields: [ @@ -299,9 +341,10 @@ describe('BigQuery/Dataset', function() { ds.makeReq_ = function(method, path, query, body, callback) { callback(null, { nextPageToken: token }); }; - ds.getTables(function(err, tables, nextQuery) { + ds.getTables({ maxResults: 5 }, function(err, tables, nextQuery) { assert.deepEqual(nextQuery, { - pageToken: token + pageToken: token, + maxResults: 5 }); done(); });