Skip to content

Commit 9e599af

Browse files
Ace Nassrijmdobry
Ace Nassri
authored andcommitted
Query sample + tests (#166)
* First draft of SyncQuery sample + tests * Fix comments; TODO add async queries * Add async queries * Fix typo * Minor tweak * Add polling for async queries * Change comments * Move from gcloud to google-cloud/bigquery + tweak cmdline args * Add comments * Minor comment change * Fix comments
1 parent 683f4dc commit 9e599af

File tree

4 files changed

+501
-0
lines changed

4 files changed

+501
-0
lines changed

bigquery/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"system-test": "mocha -R spec -t 120000 --require intelli-espower-loader ../system-test/_setup.js system-test/*.test.js"
1010
},
1111
"dependencies": {
12+
"@google-cloud/bigquery": "^0.1.1",
1213
"async": "^1.5.2",
1314
"gcloud": "^0.37.0",
1415
"request": "^2.72.0"

bigquery/query.js

+177
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
// Copyright 2016, Google, Inc.
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
// [START complete]
15+
/**
16+
* Command-line application to perform an synchronous query in BigQuery.
17+
*
18+
* This sample is used on this page:
19+
*
20+
* https://cloud.google.com/bigquery/querying-data
21+
*
22+
* For more information, see the README.md under /bigquery.
23+
*/
24+
25+
'use strict';
26+
27+
// [START auth]
28+
// By default, gcloud will authenticate using the service account file specified
29+
// by the GOOGLE_APPLICATION_CREDENTIALS environment variable and use the
30+
// project specified by the GCLOUD_PROJECT environment variable. See
31+
// https://googlecloudplatform.github.io/gcloud-node/#/docs/guides/authentication
32+
var BigQuery = require('@google-cloud/bigquery');
33+
34+
// Instantiate the bigquery client
35+
var bigquery = BigQuery();
36+
// [END auth]
37+
38+
// [START sync_query]
39+
/**
40+
* Run a synchronous query.
41+
* @param {string} query The BigQuery query to run, as a string.
42+
* @param {function} callback Callback function to receive query results.
43+
*/
44+
function syncQuery (query, callback) {
45+
if (!query) {
46+
return callback(new Error('"query" is required!'));
47+
}
48+
49+
// Construct query object.
50+
// Query options list: https://cloud.google.com/bigquery/docs/reference/v2/jobs/query
51+
var queryObj = {
52+
query: query,
53+
timeoutMs: 10000 // Time out after 10 seconds.
54+
};
55+
56+
// Run query
57+
bigquery.query(queryObj, function (err, rows) {
58+
if (err) {
59+
return callback(err);
60+
}
61+
62+
console.log('SyncQuery: found %d rows!', rows.length);
63+
return callback(null, rows);
64+
});
65+
}
66+
// [END sync_query]
67+
68+
// [START async_query]
69+
/**
70+
* Run an asynchronous query.
71+
* @param {string} query The BigQuery query to run, as a string.
72+
* @param {function} callback Callback function to receive job data.
73+
*/
74+
function asyncQuery (query, callback) {
75+
if (!query) {
76+
return callback(new Error('"query" is required!'));
77+
}
78+
79+
// Construct query object
80+
// Query options list: https://cloud.google.com/bigquery/docs/reference/v2/jobs/query
81+
var queryObj = {
82+
query: query
83+
};
84+
85+
// Submit query asynchronously
86+
bigquery.startQuery(queryObj, function (err, job) {
87+
if (err) {
88+
return callback(err);
89+
}
90+
91+
console.log('AsyncQuery: submitted job %s!', job.id);
92+
return callback(null, job);
93+
});
94+
}
95+
96+
/**
97+
* Poll an asynchronous query job for results.
98+
* @param {object} jobId The ID of the BigQuery job to poll.
99+
* @param {function} callback Callback function to receive query results.
100+
*/
101+
function asyncPoll (jobId, callback) {
102+
if (!jobId) {
103+
return callback(new Error('"jobId" is required!'));
104+
}
105+
106+
// Check for job status
107+
var job = bigquery.job(jobId);
108+
job.getMetadata(function (err, metadata) {
109+
if (err) {
110+
return callback(err);
111+
}
112+
console.log('Job status: %s', metadata.status.state);
113+
114+
// If job is done, get query results; if not, return an error.
115+
if (metadata.status.state === 'DONE') {
116+
job.getQueryResults(function (err, rows) {
117+
if (err) {
118+
return callback(err);
119+
}
120+
121+
console.log('AsyncQuery: polled job %s; got %d rows!', jobId, rows.length);
122+
return callback(null, rows);
123+
});
124+
} else {
125+
return callback(new Error('Job %s is not done', jobId));
126+
}
127+
});
128+
}
129+
// [END async_query]
130+
131+
// [START usage]
132+
function printUsage () {
133+
console.log('Usage:');
134+
console.log('\nCommands:\n');
135+
console.log('\tnode query sync QUERY');
136+
console.log('\tnode query async QUERY');
137+
console.log('\tnode query poll JOB_ID');
138+
console.log('\nExamples:\n');
139+
console.log('\tnode query sync "SELECT * FROM publicdata:samples.natality LIMIT 5;"');
140+
console.log('\tnode query async "SELECT * FROM publicdata:samples.natality LIMIT 5;"');
141+
console.log('\tnode query poll 12345');
142+
}
143+
// [END usage]
144+
145+
// The command-line program:
146+
var program = {
147+
// Print usage instructions.
148+
printUsage: printUsage,
149+
150+
// Exports
151+
asyncQuery: asyncQuery,
152+
asyncPoll: asyncPoll,
153+
syncQuery: syncQuery,
154+
bigquery: bigquery,
155+
156+
// Run the sample.
157+
main: function (args, cb) {
158+
var command = args.shift();
159+
var arg = args.shift();
160+
if (command === 'sync') {
161+
this.syncQuery(arg, cb);
162+
} else if (command === 'async') {
163+
this.asyncQuery(arg, cb);
164+
} else if (command === 'poll') {
165+
this.asyncPoll(arg, cb);
166+
} else {
167+
this.printUsage();
168+
}
169+
}
170+
};
171+
172+
if (module === require.main) {
173+
program.main(process.argv.slice(2), console.log);
174+
}
175+
// [END complete]
176+
177+
module.exports = program;

bigquery/system-test/query.test.js

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright 2016, Google, Inc.
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
'use strict';
15+
16+
var example = require('../query');
17+
18+
describe('bigquery:query', function () {
19+
describe('sync_query', function () {
20+
it('should fetch data given a query', function (done) {
21+
example.syncQuery('SELECT * FROM publicdata:samples.natality LIMIT 5;',
22+
function (err, data) {
23+
assert.ifError(err);
24+
assert.notEqual(data, null);
25+
assert(Array.isArray(data));
26+
assert(data.length === 5);
27+
done();
28+
}
29+
);
30+
});
31+
});
32+
33+
describe('async_query', function () {
34+
it('should submit a job and fetch its results', function (done) {
35+
example.asyncQuery('SELECT * FROM publicdata:samples.natality LIMIT 5;',
36+
function (err, job) {
37+
assert.ifError(err);
38+
assert.notEqual(job.id, null);
39+
40+
var poller = function (tries) {
41+
example.asyncPoll(job.id, function (err, data) {
42+
if (!err || tries === 0) {
43+
assert.ifError(err);
44+
assert.notEqual(data, null);
45+
assert(Array.isArray(data));
46+
assert(data.length === 5);
47+
done();
48+
} else {
49+
setTimeout(function () { poller(tries - 1); }, 1000);
50+
}
51+
});
52+
};
53+
54+
poller(5);
55+
}
56+
);
57+
});
58+
});
59+
});

0 commit comments

Comments
 (0)