From f6d008d9b2f1fbf1b30491529b73f20322b87389 Mon Sep 17 00:00:00 2001 From: Ace Nassri Date: Fri, 7 Jul 2017 10:14:25 -0700 Subject: [PATCH] Add bind params to Spanner samples (#418) --- spanner/README.md | 2 ++ spanner/indexing.js | 33 +++++++++++++++++++++++------ spanner/system-test/spanner.test.js | 7 ++++++ 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/spanner/README.md b/spanner/README.md index 2140ed7fc7..71b177b9ce 100644 --- a/spanner/README.md +++ b/spanner/README.md @@ -102,6 +102,8 @@ Commands: createStoringIndex Creates a new value-storing index in an example Cloud Spanner table. queryIndex Executes a read-only SQL query against an example Cloud Spanner table using an existing index. + Returns results with titles between a start title (default: + 'Ardvark') and an end title (default: 'Goo'). readIndex Reads data from an example Cloud Spanner table using an existing index. readStoringIndex Reads data from an example Cloud Spanner table using an existing diff --git a/spanner/indexing.js b/spanner/indexing.js index 978d6c9d38..a9b23f4397 100644 --- a/spanner/indexing.js +++ b/spanner/indexing.js @@ -88,7 +88,7 @@ function createStoringIndex (instanceId, databaseId) { // [END create_storing_index] } -function queryDataWithIndex (instanceId, databaseId) { +function queryDataWithIndex (instanceId, databaseId, startTitle, endTitle) { // [START query_data_with_index] // Imports the Google Cloud client library const Spanner = require('@google-cloud/spanner'); @@ -100,6 +100,10 @@ function queryDataWithIndex (instanceId, databaseId) { // const instanceId = 'my-instance'; // const databaseId = 'my-database'; + // Uncomment these lines to specify the start and end title(s) + // const startTitle = 'Ardvark'; + // const endTitle = 'Goo'; + // Gets a reference to a Cloud Spanner instance and database const instance = spanner.instance(instanceId); const database = instance.database(databaseId); @@ -107,7 +111,11 @@ function queryDataWithIndex (instanceId, databaseId) { const query = { sql: `SELECT AlbumId, AlbumTitle, MarketingBudget FROM Albums@{FORCE_INDEX=AlbumsByAlbumTitle} - WHERE AlbumTitle >= 'Ardvark' AND AlbumTitle < 'Goo'` + WHERE AlbumTitle >= @startTitle AND AlbumTitle <= @endTitle`, + params: { + startTitle: startTitle, + endTitle: endTitle + } }; // Queries rows from the Albums table @@ -117,7 +125,8 @@ function queryDataWithIndex (instanceId, databaseId) { rows.forEach((row) => { const json = row.toJSON(); - console.log(`AlbumId: ${json.AlbumId.value}, AlbumTitle: ${json.AlbumTitle}, MarketingBudget: ${json.MarketingBudget.value}`); + const marketingBudget = json.MarketingBudget ? json.MarketingBudget.value : null; // This value is nullable + console.log(`AlbumId: ${json.AlbumId.value}, AlbumTitle: ${json.AlbumTitle}, MarketingBudget: ${marketingBudget}`); }); }); // [END query_data_with_index] @@ -222,9 +231,21 @@ const cli = require(`yargs`) ) .command( `queryIndex `, - `Executes a read-only SQL query against an example Cloud Spanner table using an existing index.`, - {}, - (opts) => queryDataWithIndex(opts.instanceName, opts.databaseName) + `Executes a read-only SQL query against an example Cloud Spanner table using an existing index. + Returns results with titles between a start title (default: 'Ardvark') and an end title (default: 'Goo').`, + { + startTitle: { + type: 'string', + alias: 's', + default: 'Ardvark' + }, + endTitle: { + type: 'string', + alias: 'e', + default: 'Goo' + } + }, + (opts) => queryDataWithIndex(opts.instanceName, opts.databaseName, opts.startTitle, opts.endTitle) ) .command( `readIndex `, diff --git a/spanner/system-test/spanner.test.js b/spanner/system-test/spanner.test.js index 3d335a3e9a..ddce1e9a8e 100644 --- a/spanner/system-test/spanner.test.js +++ b/spanner/system-test/spanner.test.js @@ -114,6 +114,13 @@ test.serial(`should create a storing index in an example table`, async (t) => { test.serial(`should query an example table with an index and return matching rows`, async (t) => { const output = await tools.runAsync(`${indexingCmd} queryIndex ${INSTANCE_ID} ${DATABASE_ID}`, cwd); t.true(output.includes(`AlbumId: 1, AlbumTitle: Go, Go, Go, MarketingBudget:`)); + t.false(output.includes(`AlbumId: 2, AlbumTitle: Total Junk, MarketingBudget:`)); +}); + +test.serial(`should respect query boundaries when querying an example table with an index`, async (t) => { + const output = await tools.runAsync(`${indexingCmd} queryIndex ${INSTANCE_ID} ${DATABASE_ID} -s Ardvark -e Zoo`, cwd); + t.true(output.includes(`AlbumId: 1, AlbumTitle: Go, Go, Go, MarketingBudget:`)); + t.true(output.includes(`AlbumId: 2, AlbumTitle: Total Junk, MarketingBudget:`)); }); // read_data_with_index