From 317975b25100f4a7059edcb9120995b1278b51c3 Mon Sep 17 00:00:00 2001 From: steffnay Date: Sun, 24 Mar 2019 09:17:38 -0700 Subject: [PATCH 01/10] first attempt to add geo. trying to locate which portions of code need to be touched. tests totally failing --- src/index.ts | 46 +++++++++++++++++++++++++++++++++++++++++ system-test/bigquery.ts | 7 +++++++ 2 files changed, 53 insertions(+) diff --git a/src/index.ts b/src/index.ts index d6bf4a6a..71939442 100644 --- a/src/index.ts +++ b/src/index.ts @@ -445,6 +445,10 @@ export class BigQuery extends common.Service { value = BigQuery.timestamp(new Date(value * 1000)); break; } + case 'GEOGRAPHY': { + value = BigQuery.geography(value); + break; + } default: break; } @@ -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. * @@ -1559,6 +1595,16 @@ export class BigQueryDate { } } +/** + * Geography class for BigQuery. + */ +export class Geography { + value: string; + constructor(value: string) { + this.value = value; + } +} + /** * Timestamp class for BigQuery. */ diff --git a/system-test/bigquery.ts b/system-test/bigquery.ts index ab4ccc0d..b9e1b732 100644 --- a/system-test/bigquery.ts +++ b/system-test/bigquery.ts @@ -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', @@ -1299,6 +1303,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')); @@ -1309,6 +1314,7 @@ describe('BigQuery', () => { 'time:TIME', 'timestamp:TIMESTAMP', 'numeric:NUMERIC', + 'geography:GEOGRAPHY' ].join(', '), }); }); @@ -1320,6 +1326,7 @@ describe('BigQuery', () => { time: TIME, timestamp: TIMESTAMP, numeric: NUMERIC, + geography: GEOGRAPHY, }); }); }); From 46739014ce2b720f26feefcc80eb51a0532ba03c Mon Sep 17 00:00:00 2001 From: steffnay Date: Sun, 24 Mar 2019 15:19:51 -0700 Subject: [PATCH 02/10] linted --- system-test/.eslintrc.yml | 6 ++++++ system-test/bigquery.ts | 8 ++------ 2 files changed, 8 insertions(+), 6 deletions(-) create mode 100644 system-test/.eslintrc.yml diff --git a/system-test/.eslintrc.yml b/system-test/.eslintrc.yml new file mode 100644 index 00000000..2e6882e4 --- /dev/null +++ b/system-test/.eslintrc.yml @@ -0,0 +1,6 @@ +--- +env: + mocha: true +rules: + node/no-unpublished-require: off + no-console: off diff --git a/system-test/bigquery.ts b/system-test/bigquery.ts index b9e1b732..d0853646 100644 --- a/system-test/bigquery.ts +++ b/system-test/bigquery.ts @@ -1309,12 +1309,8 @@ describe('BigQuery', () => { table = dataset.table(generateName('table')); return table.create({ schema: [ - 'date:DATE', - 'datetime:DATETIME', - 'time:TIME', - 'timestamp:TIMESTAMP', - 'numeric:NUMERIC', - 'geography:GEOGRAPHY' + 'date:DATE', 'datetime:DATETIME', 'time:TIME', 'timestamp:TIMESTAMP', + 'numeric:NUMERIC', 'geography:GEOGRAPHY' ].join(', '), }); }); From 9f0be52ae7783ca234c12c041171c90297e2ad41 Mon Sep 17 00:00:00 2001 From: Dave Gramlich Date: Mon, 25 Mar 2019 19:07:55 -0400 Subject: [PATCH 03/10] exclude geography from being promisified --- src/index.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 71939442..d7e2e539 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1579,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', + ], }); /** From 7658d027b93e220fc336ccb7750169ec50d86680 Mon Sep 17 00:00:00 2001 From: Dave Gramlich Date: Mon, 25 Mar 2019 19:08:14 -0400 Subject: [PATCH 04/10] add geography to custom class list for encoding values --- src/table.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/table.ts b/src/table.ts index ad99166d..492f8591 100644 --- a/src/table.ts +++ b/src/table.ts @@ -520,6 +520,7 @@ class Table extends common.ServiceObject { 'BigQueryDatetime', 'BigQueryTime', 'BigQueryTimestamp', + 'Geography', ]; const constructorName = value.constructor.name; const isCustomType = From 39e003be0d88d8506bd6b8ebe4304f9ee4d551d9 Mon Sep 17 00:00:00 2001 From: steffany brown Date: Mon, 25 Mar 2019 20:05:27 -0700 Subject: [PATCH 05/10] add unit and system tests for geography --- system-test/bigquery.ts | 28 ++++++++++++++++++++++++++++ test/index.ts | 29 +++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/system-test/bigquery.ts b/system-test/bigquery.ts index d0853646..befd5202 100644 --- a/system-test/bigquery.ts +++ b/system-test/bigquery.ts @@ -1031,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( { @@ -1248,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( { diff --git a/test/index.ts b/test/index.ts index a61efe4a..c2ac7746 100644 --- a/test/index.ts +++ b/test/index.ts @@ -48,6 +48,7 @@ const fakePfy = extend({}, pfy, { 'dataset', 'date', 'datetime', + 'geography', 'job', 'time', 'timestamp', @@ -572,6 +573,34 @@ describe('BigQuery', () => { assert.strictEqual(timestamp.value, EXPECTED_VALUE); }); }); + // ************* + // ******** + // ***** + // *** + // * + describe('geography', () => { + const INPUT_STRING = 'POINT(1 2)'; + + it.skip('should expose static and instance constructors', () => { + const staticG = BigQuery.geography(INPUT_STRING); + assert(staticG instanceof BigQuery.geography); + assert(staticG instanceof bq.geography); + + const instanceG = bq.geography(INPUT_STRING); + assert(instanceG instanceof BigQuery.geography); + assert(instanceG instanceof bq.geography); + }); + + it('should have the correct constructor name', () => { + const geography = bq.geography(INPUT_STRING); + assert.strictEqual(geography.constructor.name, 'Geography'); + }); + + it('should accept a string', () => { + const geography = bq.geography(INPUT_STRING); + assert.strictEqual(geography.value, INPUT_STRING); + }); + }); describe('getType_', () => { it('should return correct types', () => { From 24aacefe489fa09a8d6f63eb08d8114f2495a3c4 Mon Sep 17 00:00:00 2001 From: steffany brown Date: Tue, 26 Mar 2019 03:54:56 -0700 Subject: [PATCH 06/10] Added test --- system-test/.eslintrc.yml | 6 ------ test/index.ts | 37 ++++++++++++++++++++++--------------- 2 files changed, 22 insertions(+), 21 deletions(-) delete mode 100644 system-test/.eslintrc.yml diff --git a/system-test/.eslintrc.yml b/system-test/.eslintrc.yml deleted file mode 100644 index 2e6882e4..00000000 --- a/system-test/.eslintrc.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -env: - mocha: true -rules: - node/no-unpublished-require: off - no-console: off diff --git a/test/index.ts b/test/index.ts index c2ac7746..2185d2cd 100644 --- a/test/index.ts +++ b/test/index.ts @@ -244,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', () => { @@ -254,15 +261,9 @@ describe('BigQuery', () => { { raw: { f: [ - {v: '3'}, - {v: 'Milo'}, - {v: String(now.valueOf() / 1000)}, - {v: 'false'}, - {v: 'true'}, - {v: '5.222330009847'}, - {v: '30.2232138'}, - {v: '3.14'}, - { + {v: '3'}, {v: 'Milo'}, {v: String(now.valueOf() / 1000)}, + {v: 'false'}, {v: 'true'}, {v: '5.222330009847'}, + {v: '30.2232138'}, {v: '3.14'}, { v: [ { v: '10', @@ -276,9 +277,7 @@ describe('BigQuery', () => { }, ], }, - {v: null}, - {v: buffer.toString('base64')}, - { + {v: null}, {v: buffer.toString('base64')}, { v: [ { v: { @@ -297,9 +296,8 @@ describe('BigQuery', () => { }, ], }, - {v: 'date-input'}, - {v: 'datetime-input'}, - {v: 'time-input'}, + {v: 'date-input'}, {v: 'datetime-input'}, {v: 'time-input'}, + {v: 'geography-input'} ], }, expected: { @@ -337,6 +335,10 @@ describe('BigQuery', () => { input: 'time-input', type: 'fakeTime', }, + geography: { + input: 'geography-input', + type: 'fakeGeography', + }, }, }, ]; @@ -399,6 +401,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); From bdc3f2f736cb7268af5a85fa5803c6c395903df1 Mon Sep 17 00:00:00 2001 From: steffany brown Date: Sat, 30 Mar 2019 15:25:51 -0700 Subject: [PATCH 07/10] remove unnecessary comments --- test/index.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/test/index.ts b/test/index.ts index 2185d2cd..6118cb62 100644 --- a/test/index.ts +++ b/test/index.ts @@ -580,11 +580,7 @@ describe('BigQuery', () => { assert.strictEqual(timestamp.value, EXPECTED_VALUE); }); }); - // ************* - // ******** - // ***** - // *** - // * + describe('geography', () => { const INPUT_STRING = 'POINT(1 2)'; From 62fc5b0e321c9de61415a562034b3256ce5d9738 Mon Sep 17 00:00:00 2001 From: steffany brown Date: Mon, 1 Apr 2019 13:36:16 -0700 Subject: [PATCH 08/10] update geography tests, removed skipped test --- test/index.ts | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/test/index.ts b/test/index.ts index 6118cb62..999d1c06 100644 --- a/test/index.ts +++ b/test/index.ts @@ -584,23 +584,13 @@ describe('BigQuery', () => { describe('geography', () => { const INPUT_STRING = 'POINT(1 2)'; - it.skip('should expose static and instance constructors', () => { - const staticG = BigQuery.geography(INPUT_STRING); - assert(staticG instanceof BigQuery.geography); - assert(staticG instanceof bq.geography); - - const instanceG = bq.geography(INPUT_STRING); - assert(instanceG instanceof BigQuery.geography); - assert(instanceG instanceof bq.geography); - }); - it('should have the correct constructor name', () => { - const geography = bq.geography(INPUT_STRING); + const geography = BigQuery.geography(INPUT_STRING); assert.strictEqual(geography.constructor.name, 'Geography'); }); it('should accept a string', () => { - const geography = bq.geography(INPUT_STRING); + const geography = BigQuery.geography(INPUT_STRING); assert.strictEqual(geography.value, INPUT_STRING); }); }); From c101f85135136ec20920daba7bd78348b90f5c9e Mon Sep 17 00:00:00 2001 From: Dave Gramlich Date: Mon, 1 Apr 2019 17:40:46 -0400 Subject: [PATCH 09/10] add unit test for geography instance method --- test/index.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/index.ts b/test/index.ts index 999d1c06..3c9585e0 100644 --- a/test/index.ts +++ b/test/index.ts @@ -593,6 +593,17 @@ describe('BigQuery', () => { 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_', () => { From 0775162f53139ce350524cba95b25a25187396a6 Mon Sep 17 00:00:00 2001 From: Dave Gramlich Date: Mon, 1 Apr 2019 17:43:15 -0400 Subject: [PATCH 10/10] add trailing commas --- system-test/bigquery.ts | 8 ++++++-- test/index.ts | 22 ++++++++++++++++------ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/system-test/bigquery.ts b/system-test/bigquery.ts index befd5202..f6ced2a5 100644 --- a/system-test/bigquery.ts +++ b/system-test/bigquery.ts @@ -1337,8 +1337,12 @@ describe('BigQuery', () => { table = dataset.table(generateName('table')); return table.create({ schema: [ - 'date:DATE', 'datetime:DATETIME', 'time:TIME', 'timestamp:TIMESTAMP', - 'numeric:NUMERIC', 'geography:GEOGRAPHY' + 'date:DATE', + 'datetime:DATETIME', + 'time:TIME', + 'timestamp:TIMESTAMP', + 'numeric:NUMERIC', + 'geography:GEOGRAPHY', ].join(', '), }); }); diff --git a/test/index.ts b/test/index.ts index 3c9585e0..de4c3d77 100644 --- a/test/index.ts +++ b/test/index.ts @@ -261,9 +261,15 @@ describe('BigQuery', () => { { raw: { f: [ - {v: '3'}, {v: 'Milo'}, {v: String(now.valueOf() / 1000)}, - {v: 'false'}, {v: 'true'}, {v: '5.222330009847'}, - {v: '30.2232138'}, {v: '3.14'}, { + {v: '3'}, + {v: 'Milo'}, + {v: String(now.valueOf() / 1000)}, + {v: 'false'}, + {v: 'true'}, + {v: '5.222330009847'}, + {v: '30.2232138'}, + {v: '3.14'}, + { v: [ { v: '10', @@ -277,7 +283,9 @@ describe('BigQuery', () => { }, ], }, - {v: null}, {v: buffer.toString('base64')}, { + {v: null}, + {v: buffer.toString('base64')}, + { v: [ { v: { @@ -296,8 +304,10 @@ describe('BigQuery', () => { }, ], }, - {v: 'date-input'}, {v: 'datetime-input'}, {v: 'time-input'}, - {v: 'geography-input'} + {v: 'date-input'}, + {v: 'datetime-input'}, + {v: 'time-input'}, + {v: 'geography-input'}, ], }, expected: {