Skip to content

Commit 95aa578

Browse files
authored
Merge branch 'googleapis:main' into main
2 parents 50914dc + 055f2f7 commit 95aa578

19 files changed

+816
-128
lines changed

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,21 @@
44

55
[1]: https://www.npmjs.com/package/nodejs-spanner?activeTab=versions
66

7+
## [7.9.0](https://github.com/googleapis/nodejs-spanner/compare/v7.8.0...v7.9.0) (2024-06-21)
8+
9+
10+
### Features
11+
12+
* **spanner:** Add support for batchWrite ([#2054](https://github.com/googleapis/nodejs-spanner/issues/2054)) ([06aab6e](https://github.com/googleapis/nodejs-spanner/commit/06aab6e39bbce9e3786f1ac631c80e8909197e92))
13+
14+
15+
### Bug Fixes
16+
17+
* **deps:** Update dependency google-gax to v4.3.4 ([#2051](https://github.com/googleapis/nodejs-spanner/issues/2051)) ([80abf06](https://github.com/googleapis/nodejs-spanner/commit/80abf06ba8ef9497318ffc597b83fb63e4408f9c))
18+
* **deps:** Update dependency google-gax to v4.3.5 ([#2055](https://github.com/googleapis/nodejs-spanner/issues/2055)) ([702c9b0](https://github.com/googleapis/nodejs-spanner/commit/702c9b0f34e6cc34233c5aa52b97601b19f70980))
19+
* **deps:** Update dependency google-gax to v4.3.6 ([#2057](https://github.com/googleapis/nodejs-spanner/issues/2057)) ([74ebf1e](https://github.com/googleapis/nodejs-spanner/commit/74ebf1e45cddf614c180295f3a761a8f84c5cb32))
20+
* **deps:** Update dependency google-gax to v4.3.7 ([#2068](https://github.com/googleapis/nodejs-spanner/issues/2068)) ([28fec6c](https://github.com/googleapis/nodejs-spanner/commit/28fec6ca505d78d725efc123950be978e0c84ab7))
21+
722
## [7.8.0](https://github.com/googleapis/nodejs-spanner/compare/v7.7.0...v7.8.0) (2024-05-24)
823

924

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ Samples are in the [`samples/`](https://github.com/googleapis/nodejs-spanner/tre
102102
| Backups-restore | [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/backups-restore.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-spanner&page=editor&open_in_editor=samples/backups-restore.js,samples/README.md) |
103103
| Backups-update | [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/backups-update.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-spanner&page=editor&open_in_editor=samples/backups-update.js,samples/README.md) |
104104
| Backups | [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/backups.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-spanner&page=editor&open_in_editor=samples/backups.js,samples/README.md) |
105+
| Batch Write | [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/batch-write.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-spanner&page=editor&open_in_editor=samples/batch-write.js,samples/README.md) |
105106
| Batch | [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/batch.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-spanner&page=editor&open_in_editor=samples/batch.js,samples/README.md) |
106107
| CRUD | [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/crud.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-spanner&page=editor&open_in_editor=samples/crud.js,samples/README.md) |
107108
| Creates a new database with a specific default leader | [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/database-create-with-default-leader.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-spanner&page=editor&open_in_editor=samples/database-create-with-default-leader.js,samples/README.md) |

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@google-cloud/spanner",
33
"description": "Cloud Spanner Client Library for Node.js",
4-
"version": "7.8.0",
4+
"version": "7.9.0",
55
"license": "Apache-2.0",
66
"author": "Google Inc.",
77
"engines": {
@@ -66,7 +66,7 @@
6666
"events-intercept": "^2.0.0",
6767
"extend": "^3.0.2",
6868
"google-auth-library": "^9.0.0",
69-
"google-gax": "4.3.6",
69+
"google-gax": "4.3.7",
7070
"grpc-gcp": "^1.0.0",
7171
"is": "^3.2.1",
7272
"lodash.snakecase": "^4.1.1",
@@ -93,7 +93,7 @@
9393
"@types/request": "^2.48.3",
9494
"@types/sinon": "^17.0.0",
9595
"@types/through2": "^2.0.34",
96-
"@types/uuid": "^9.0.0",
96+
"@types/uuid": "^10.0.0",
9797
"binary-search-bounds": "^2.0.4",
9898
"c8": "^8.0.1",
9999
"codecov": "^3.0.2",
@@ -117,7 +117,7 @@
117117
"time-span": "^4.0.0",
118118
"tmp": "^0.2.0",
119119
"typescript": "^5.1.6",
120-
"uuid": "^9.0.0",
120+
"uuid": "^10.0.0",
121121
"yargs": "^17.0.0"
122122
}
123123
}

samples/README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ and automatic, synchronous replication for high availability.
2727
* [Backups-restore](#backups-restore)
2828
* [Backups-update](#backups-update)
2929
* [Backups](#backups)
30+
* [Batch Write](#batch-write)
3031
* [Batch](#batch)
3132
* [CRUD](#crud)
3233
* [Creates a new database with a specific default leader](#creates-a-new-database-with-a-specific-default-leader)
@@ -354,6 +355,23 @@ __Usage:__
354355

355356

356357

358+
### Batch Write
359+
360+
View the [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/batch-write.js).
361+
362+
[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-spanner&page=editor&open_in_editor=samples/batch-write.js,samples/README.md)
363+
364+
__Usage:__
365+
366+
367+
`node batch-write.js <INSTANCE_ID> <DATABASE_ID> <PROJECT_ID>`
368+
369+
370+
-----
371+
372+
373+
374+
357375
### Batch
358376

359377
View the [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/batch.js).

samples/batch-write.js

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/**
2+
* Copyright 2024 Google LLC
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
// sample-metadata:
17+
// title: Batch Write
18+
// usage: node batch-write.js <INSTANCE_ID> <DATABASE_ID> <PROJECT_ID>
19+
20+
'use strict';
21+
22+
async function main(
23+
instanceId = 'my-instance',
24+
databaseId = 'my-database',
25+
projectId = 'my-project-id'
26+
) {
27+
// [START spanner_batch_write_at_least_once]
28+
29+
// Imports the Google Cloud client library
30+
const {Spanner, MutationGroup} = require('@google-cloud/spanner');
31+
32+
/**
33+
* TODO(developer): Uncomment the following lines before running the sample.
34+
*/
35+
// const instanceId = 'my-instance';
36+
// const databaseId = 'my-database';
37+
// const projectId = 'my-project-id';
38+
39+
// Creates a client
40+
const spanner = new Spanner({
41+
projectId: projectId,
42+
});
43+
44+
// Gets a reference to a Cloud Spanner instance and database
45+
const instance = spanner.instance(instanceId);
46+
const database = instance.database(databaseId);
47+
48+
// Create Mutation Groups
49+
/**
50+
* Related mutations should be placed in a group, such as insert mutations for both a parent and a child row.
51+
* A group must contain related mutations.
52+
* Please see {@link https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.v1#google.spanner.v1.BatchWriteRequest.MutationGroup}
53+
* for more details and examples.
54+
*/
55+
const mutationGroup1 = new MutationGroup();
56+
mutationGroup1.insert('Singers', {
57+
SingerId: 1,
58+
FirstName: 'Scarlet',
59+
LastName: 'Terry',
60+
});
61+
62+
const mutationGroup2 = new MutationGroup();
63+
mutationGroup2.insert('Singers', {
64+
SingerId: 2,
65+
FirstName: 'Marc',
66+
});
67+
mutationGroup2.insert('Singers', {
68+
SingerId: 3,
69+
FirstName: 'Catalina',
70+
LastName: 'Smith',
71+
});
72+
mutationGroup2.insert('Albums', {
73+
AlbumId: 1,
74+
SingerId: 2,
75+
AlbumTitle: 'Total Junk',
76+
});
77+
mutationGroup2.insert('Albums', {
78+
AlbumId: 2,
79+
SingerId: 3,
80+
AlbumTitle: 'Go, Go, Go',
81+
});
82+
83+
const options = {
84+
transactionTag: 'batch-write-tag',
85+
};
86+
87+
try {
88+
database
89+
.batchWriteAtLeastOnce([mutationGroup1, mutationGroup2], options)
90+
.on('error', console.error)
91+
.on('data', response => {
92+
// Check the response code of each response to determine whether the mutation group(s) were applied successfully.
93+
if (response.status.code === 0) {
94+
console.log(
95+
`Mutation group indexes ${
96+
response.indexes
97+
}, have been applied with commit timestamp ${Spanner.timestamp(
98+
response.commitTimestamp
99+
).toJSON()}`
100+
);
101+
}
102+
// Mutation groups that fail to commit trigger a response with a non-zero status code.
103+
else {
104+
console.log(
105+
`Mutation group indexes ${response.indexes}, could not be applied with error code ${response.status.code}, and error message ${response.status.message}`
106+
);
107+
}
108+
})
109+
.on('end', () => {
110+
console.log('Request completed successfully');
111+
});
112+
} catch (err) {
113+
console.log(err);
114+
}
115+
// [END spanner_batch_write_at_least_once]
116+
}
117+
118+
process.on('unhandledRejection', err => {
119+
console.error(err.message);
120+
process.exitCode = 1;
121+
});
122+
123+
main(...process.argv.slice(2));

samples/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"dependencies": {
1818
"@google-cloud/kms": "^4.0.0",
1919
"@google-cloud/precise-date": "^4.0.0",
20-
"@google-cloud/spanner": "^7.8.0",
20+
"@google-cloud/spanner": "^7.9.0",
2121
"yargs": "^17.0.0",
2222
"protobufjs": "^7.0.0"
2323
},

samples/proto-query-data.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
'use strict';
1616

17-
// eslint-disable-next-line node/no-unpublished-require
17+
// eslint-disable-next-line n/no-unpublished-require
1818
const singer = require('./resource/singer.js');
1919
const music = singer.examples.spanner.music;
2020

samples/proto-update-data-dml.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
'use strict';
1616

17-
// eslint-disable-next-line node/no-unpublished-require
17+
// eslint-disable-next-line n/no-unpublished-require
1818
const singer = require('./resource/singer.js');
1919
const music = singer.examples.spanner.music;
2020

samples/proto-update-data.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
'use strict';
1616

17-
// eslint-disable-next-line node/no-unpublished-require
17+
// eslint-disable-next-line n/no-unpublished-require
1818
const singer = require('./resource/singer.js');
1919
const music = singer.examples.spanner.music;
2020

samples/system-test/spanner.test.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ const requestTagCommand = 'node request-tag.js';
4040
const timestampCmd = 'node timestamp.js';
4141
const structCmd = 'node struct.js';
4242
const dmlCmd = 'node dml.js';
43+
const batchWriteCmd = 'node batch-write.js';
4344
const datatypesCmd = 'node datatypes.js';
4445
const backupsCmd = 'node backups.js';
4546
const instanceCmd = 'node instance.js';
@@ -967,6 +968,27 @@ describe('Autogenerated Admin Clients', () => {
967968
assert.match(output, new RegExp('Virginia Watson'));
968969
});
969970

971+
// batch_write
972+
it('should perform CRUD operations using batch write', async () => {
973+
const output = execSync(
974+
`${batchWriteCmd} ${INSTANCE_ID} ${DATABASE_ID} ${PROJECT_ID}`
975+
).toString();
976+
977+
const successRegex =
978+
/Mutation group indexes [\d,]+ have been applied with commit timestamp \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z/;
979+
const failureRegex =
980+
/Mutation group indexes [\d,]+, could not be applied with error code \d+, and error message .+/;
981+
982+
const successMatch = successRegex.test(output);
983+
const errorMatch = failureRegex.test(output);
984+
985+
if (successMatch || errorMatch) {
986+
assert.include(output, 'Request completed successfully');
987+
} else {
988+
assert.ifError(output);
989+
}
990+
});
991+
970992
// create_table_with_datatypes
971993
it('should create Venues example table with supported datatype columns', async () => {
972994
const output = execSync(

0 commit comments

Comments
 (0)