Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(geo): add support for geography #397

Merged
merged 14 commits into from
Apr 2, 2019
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 55 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,10 @@ export class BigQuery extends common.Service {
value = BigQuery.timestamp(new Date(value * 1000));
break;
}
case 'GEOGRAPHY': {
steffnay marked this conversation as resolved.
Show resolved Hide resolved
value = BigQuery.geography(value);
break;
}
default:
break;
}
Expand Down Expand Up @@ -692,6 +696,38 @@ export class BigQuery extends common.Service {
return BigQuery.timestamp(value);
}

/**
* A geography value represents a surface area on the Earth
* in Well-known Text (WKT) format.
*
* @method BigQuery.geography
* @param {string} value The geospatial data.
*
* @example
* const {BigQuery} = require('@google-cloud/bigquery');
* const geography = BigQuery.geography('POINT(1, 2)');
*/

/**
* A geography value represents a surface area on the Earth
* in Well-known Text (WKT) format.
*
* @method BigQuery#geography
* @param {string} value The geospatial data.
*
* @example
* const {BigQuery} = require('@google-cloud/bigquery');
* const bigquery = new BigQuery();
* const geography = bigquery.geography('POINT(1, 2)');
*/
static geography(value: string) {
return new Geography(value);
}

geography(value: string) {
return BigQuery.geography(value);
}

/**
* Detect a value's type.
*
Expand Down Expand Up @@ -1543,7 +1579,15 @@ paginator.extend(BigQuery, ['getDatasets', 'getJobs']);
* that a callback is omitted.
*/
promisifyAll(BigQuery, {
exclude: ['dataset', 'date', 'datetime', 'job', 'time', 'timestamp'],
exclude: [
'dataset',
'date',
'datetime',
'geography',
'job',
'time',
'timestamp',
],
});

/**
Expand All @@ -1559,6 +1603,16 @@ export class BigQueryDate {
}
}

/**
* Geography class for BigQuery.
*/
export class Geography {
value: string;
constructor(value: string) {
this.value = value;
}
}

/**
* Timestamp class for BigQuery.
*/
Expand Down
1 change: 1 addition & 0 deletions src/table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,7 @@ class Table extends common.ServiceObject {
'BigQueryDatetime',
'BigQueryTime',
'BigQueryTimestamp',
'Geography',
];
const constructorName = value.constructor.name;
const isCustomType =
Expand Down
35 changes: 35 additions & 0 deletions system-test/bigquery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ describe('BigQuery', () => {
const query = 'SELECT url FROM `publicdata.samples.github_nested` LIMIT 100';

const SCHEMA = [
{
name: 'place',
type: 'GEOGRAPHY',
},
{
name: 'id',
type: 'INTEGER',
Expand Down Expand Up @@ -1027,6 +1031,19 @@ describe('BigQuery', () => {
});
});

it('should work with GEOGRAPHY types', done => {
bigquery.query(
{
query: 'SELECT ? geography',
params: [bigquery.geography('POINT(1 2)')],
},
(err, rows) => {
assert.ifError(err);
assert.strictEqual(rows!.length, 1);
done();
});
});

it('should work with multiple types', done => {
bigquery.query(
{
Expand Down Expand Up @@ -1244,6 +1261,21 @@ describe('BigQuery', () => {
});
});

it('should work with GEOGRAPHY types', done => {
bigquery.query(
{
query: 'SELECT @place geography',
params: {
place: bigquery.geography('POINT(1 2)'),
},
},
(err, rows) => {
assert.ifError(err);
assert.strictEqual(rows!.length, 1);
done();
});
});

it('should work with multiple types', done => {
bigquery.query(
{
Expand Down Expand Up @@ -1299,6 +1331,7 @@ describe('BigQuery', () => {
const TIME = bigquery.time('14:00:00');
const TIMESTAMP = bigquery.timestamp(new Date());
const NUMERIC = new Big('123.456');
const GEOGRAPHY = bigquery.geography('POINT(1 2)');

before(() => {
table = dataset.table(generateName('table'));
Expand All @@ -1309,6 +1342,7 @@ describe('BigQuery', () => {
'time:TIME',
'timestamp:TIMESTAMP',
'numeric:NUMERIC',
'geography:GEOGRAPHY',
].join(', '),
});
});
Expand All @@ -1320,6 +1354,7 @@ describe('BigQuery', () => {
time: TIME,
timestamp: TIMESTAMP,
numeric: NUMERIC,
geography: GEOGRAPHY,
});
});
});
Expand Down
43 changes: 43 additions & 0 deletions test/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ const fakePfy = extend({}, pfy, {
'dataset',
'date',
'datetime',
'geography',
'job',
'time',
'timestamp',
Expand Down Expand Up @@ -243,6 +244,13 @@ describe('BigQuery', () => {
input,
};
});

sandbox.stub(BigQuery, 'geography').callsFake(input => {
return {
type: 'fakeGeography',
input,
};
});
});

it('should merge the schema and flatten the rows', () => {
Expand Down Expand Up @@ -299,6 +307,7 @@ describe('BigQuery', () => {
{v: 'date-input'},
{v: 'datetime-input'},
{v: 'time-input'},
{v: 'geography-input'},
],
},
expected: {
Expand Down Expand Up @@ -336,6 +345,10 @@ describe('BigQuery', () => {
input: 'time-input',
type: 'fakeTime',
},
geography: {
input: 'geography-input',
type: 'fakeGeography',
},
},
},
];
Expand Down Expand Up @@ -398,6 +411,11 @@ describe('BigQuery', () => {
type: 'TIME',
});

schemaObject.fields.push({
name: 'geography',
type: 'GEOGRAPHY',
});

const rawRows = rows.map(x => x.raw);
const mergedRows = BigQuery.mergeSchemaWithRows_(schemaObject, rawRows);

Expand Down Expand Up @@ -573,6 +591,31 @@ describe('BigQuery', () => {
});
});

describe('geography', () => {
const INPUT_STRING = 'POINT(1 2)';

it('should have the correct constructor name', () => {
const geography = BigQuery.geography(INPUT_STRING);
assert.strictEqual(geography.constructor.name, 'Geography');
});

it('should accept a string', () => {
const geography = BigQuery.geography(INPUT_STRING);
assert.strictEqual(geography.value, INPUT_STRING);
});

it('should call through to the static method', () => {
const fakeGeography = {value: 'foo'};

sandbox.stub(BigQuery, 'geography')
.withArgs(INPUT_STRING)
.returns(fakeGeography);

const geography = bq.geography(INPUT_STRING);
assert.strictEqual(geography, fakeGeography);
});
});

describe('getType_', () => {
it('should return correct types', () => {
assert.strictEqual(BigQuery.getType_(bq.date()).type, 'DATE');
Expand Down