Skip to content

Commit 57fed2e

Browse files
committed
Add Spanner stale read sample.
1 parent 6fca8cf commit 57fed2e

File tree

4 files changed

+78
-32
lines changed

4 files changed

+78
-32
lines changed

spanner/README.md

+7-30
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<img src="https://avatars2.githubusercontent.com/u/2810941?v=3&s=96" alt="Google Cloud Platform logo" title="Google Cloud Platform" align="right" height="96" width="96"/>
22

3-
# Google Cloud Spanner Node.js Samples
3+
# Cloud Spanner: Node.js Samples
44

5-
[![Build](https://storage.googleapis.com/cloud-docs-samples-badges/GoogleCloudPlatform/nodejs-docs-samples/nodejs-docs-samples-spanner.svg)]()
5+
[![Build](https://storage.googleapis.com/.svg)]()
66

77
[Cloud Spanner](https://cloud.google.com/spanner/docs/) is a fully managed, mission-critical, relational database service that offers transactional consistency at global scale, schemas, SQL (ANSI 2011 with extensions), and automatic, synchronous replication for high availability.
88

@@ -18,19 +18,6 @@
1818

1919
## Setup
2020

21-
1. Read [Prerequisites][prereq] and [How to run a sample][run] first.
22-
1. Install dependencies:
23-
24-
With **npm**:
25-
26-
npm install
27-
28-
With **yarn**:
29-
30-
yarn install
31-
32-
[prereq]: ../README.md#prerequisites
33-
[run]: ../README.md#how-to-run-a-sample
3421

3522
## Samples
3623

@@ -70,10 +57,11 @@ __Usage:__ `node crud.js --help`
7057

7158
```
7259
Commands:
73-
update <instanceName> <databaseName> Modifies existing rows of data in an example Cloud Spanner table.
74-
query <instanceName> <databaseName> Executes a read-only SQL query against an example Cloud Spanner table.
75-
insert <instanceName> <databaseName> Inserts new rows of data into an example Cloud Spanner table.
76-
read <instanceName> <databaseName> Reads data in an example Cloud Spanner table.
60+
update <instanceName> <databaseName> Modifies existing rows of data in an example Cloud Spanner table.
61+
query <instanceName> <databaseName> Executes a read-only SQL query against an example Cloud Spanner table.
62+
insert <instanceName> <databaseName> Inserts new rows of data into an example Cloud Spanner table.
63+
read <instanceName> <databaseName> Reads data in an example Cloud Spanner table.
64+
read-stale <instanceName> <databaseName> Reads data in an example Cloud Spanner table.
7765
7866
Options:
7967
--help Show help [boolean]
@@ -151,14 +139,3 @@ For more information, see https://cloud.google.com/spanner/docs
151139

152140
## Running the tests
153141

154-
1. Set the **GCLOUD_PROJECT** and **GOOGLE_APPLICATION_CREDENTIALS** environment variables.
155-
156-
1. Run the tests:
157-
158-
With **npm**:
159-
160-
npm test
161-
162-
With **yarn**:
163-
164-
yarn test

spanner/crud.js

+50
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,50 @@ function readData (instanceId, databaseId) {
163163
// [END read_data]
164164
}
165165

166+
function readStaleData (instanceId, databaseId) {
167+
// [START read_stale_data]
168+
// Imports the Google Cloud client library
169+
const Spanner = require('@google-cloud/spanner');
170+
171+
// Instantiates a client
172+
const spanner = Spanner();
173+
174+
// Uncomment these lines to specify the instance and database to use
175+
// const instanceId = 'my-instance';
176+
// const databaseId = 'my-database';
177+
178+
// Gets a reference to a Cloud Spanner instance and database
179+
const instance = spanner.instance(instanceId);
180+
const database = instance.database(databaseId);
181+
182+
// Read rows from the Albums table
183+
const albumsTable = database.table('Albums');
184+
185+
const query = {
186+
columns: ['SingerId', 'AlbumId', 'AlbumTitle'],
187+
keySet: {
188+
all: true
189+
}
190+
};
191+
192+
const options = {
193+
// Guarantees that all writes that have committed more than 10 seconds ago
194+
// are visible
195+
exactStaleness: 10
196+
};
197+
198+
albumsTable.read(query, options)
199+
.then((results) => {
200+
const rows = results[0];
201+
202+
rows.forEach((row) => {
203+
const json = row.toJSON();
204+
console.log(`SingerId: ${json.SingerId.value}, AlbumId: ${json.AlbumId.value}, AlbumTitle: ${json.AlbumTitle}, MarketingBudget: ${json.MarketingBudget}`);
205+
});
206+
});
207+
// [END read_stale_data]
208+
}
209+
166210
const cli = require(`yargs`)
167211
.demand(1)
168212
.command(
@@ -189,6 +233,12 @@ const cli = require(`yargs`)
189233
{},
190234
(opts) => readData(opts.instanceName, opts.databaseName)
191235
)
236+
.command(
237+
`read-stale <instanceName> <databaseName>`,
238+
`Reads data in an example Cloud Spanner table.`,
239+
{},
240+
(opts) => readStaleData(opts.instanceName, opts.databaseName)
241+
)
192242
.example(`node $0 update "my-instance" "my-database"`)
193243
.example(`node $0 query "my-instance" "my-database"`)
194244
.example(`node $0 insert "my-instance" "my-database"`)

spanner/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@
2222
},
2323
"devDependencies": {
2424
"@google-cloud/nodejs-repo-tools": "1.4.17",
25-
"ava": "0.21.0",
25+
"ava": "0.22.0",
2626
"proxyquire": "1.8.0",
27-
"sinon": "3.2.0"
27+
"sinon": "3.2.1"
2828
},
2929
"cloud-repo-tools": {
3030
"requiresKeyFile": true,

spanner/system-test/spanner.test.js

+19
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,25 @@ test.serial(`should update existing rows in an example table`, async (t) => {
8989
t.true(output.includes(`Updated data.`));
9090
});
9191

92+
// read_stale_data
93+
test.serial(`should read an example table`, (t) => {
94+
t.plan(2);
95+
// read-stale-data reads data that is exactly 10 seconds old. So, make sure
96+
// 10 seconds have elapsed since the update_data test.
97+
return new Promise((resolve, reject) => {
98+
setTimeout(async () => {
99+
const output = await tools.runAsync(`${crudCmd} read-stale ${INSTANCE_ID} ${DATABASE_ID}`, cwd);
100+
try {
101+
t.regex(output, new RegExp(`SingerId: 1, AlbumId: 1, AlbumTitle: Go, Go, Go, MarketingBudget: 100000`));
102+
t.regex(output, new RegExp(`SingerId: 2, AlbumId: 2, AlbumTitle: Forever Hold your Peace, MarketingBudget: 500000`));
103+
resolve();
104+
} catch (err) {
105+
reject(err);
106+
}
107+
}, 11000);
108+
});
109+
});
110+
92111
// query_data_with_new_column
93112
test.serial(`should query an example table with an additional column and return matching rows`, async (t) => {
94113
const output = await tools.runAsync(`${schemaCmd} queryNewColumn ${INSTANCE_ID} ${DATABASE_ID}`, cwd);

0 commit comments

Comments
 (0)