Skip to content

Commit 4b447e7

Browse files
authored
breaking: refactor(transaction): split logic into new classes (#506)
* refactor(transaction): split logic into new classes Previously all transaction logic was housed in a single class. This refactor breaks the logic up into multiple classes: Snapshot - read only transactions Transaction - read/write transactions PartitionedDml - dml capable transaction
1 parent 17c0ba2 commit 4b447e7

25 files changed

+4260
-4734
lines changed

package.json

-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@
6363
"merge-stream": "^1.0.1",
6464
"p-limit": "^2.0.0",
6565
"p-queue": "^3.0.0",
66-
"p-retry": "^3.0.0",
6766
"protobufjs": "^6.8.6",
6867
"split-array-stream": "^2.0.0",
6968
"stack-trace": "0.0.10",

samples/dml.js

+8-8
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ function insertUsingDml(instanceId, databaseId, projectId) {
4242
return;
4343
}
4444
try {
45-
const rowCount = await transaction.runUpdate({
45+
const [rowCount] = await transaction.runUpdate({
4646
sql:
4747
'INSERT Singers (SingerId, FirstName, LastName) VALUES (10, @firstName, @lastName)',
4848
params: {
@@ -93,7 +93,7 @@ function updateUsingDml(instanceId, databaseId, projectId) {
9393
return;
9494
}
9595
try {
96-
const rowCount = await transaction.runUpdate({
96+
const [rowCount] = await transaction.runUpdate({
9797
sql: `UPDATE Albums SET MarketingBudget = MarketingBudget * 2
9898
WHERE SingerId = 1 and AlbumId = 1`,
9999
});
@@ -137,7 +137,7 @@ function deleteUsingDml(instanceId, databaseId, projectId) {
137137
return;
138138
}
139139
try {
140-
const rowCount = await transaction.runUpdate({
140+
const [rowCount] = await transaction.runUpdate({
141141
sql: `DELETE Singers WHERE FirstName = 'Alice'`,
142142
});
143143

@@ -180,7 +180,7 @@ function updateUsingDmlWithTimestamp(instanceId, databaseId, projectId) {
180180
return;
181181
}
182182
try {
183-
const rowCount = await transaction.runUpdate({
183+
const [rowCount] = await transaction.runUpdate({
184184
sql: `UPDATE Albums
185185
SET LastUpdateTime = PENDING_COMMIT_TIMESTAMP()
186186
WHERE SingerId = 1`,
@@ -281,7 +281,7 @@ function updateUsingDmlWithStruct(instanceId, databaseId, projectId) {
281281
return;
282282
}
283283
try {
284-
const rowCount = await transaction.runUpdate({
284+
const [rowCount] = await transaction.runUpdate({
285285
sql: `UPDATE Singers SET LastName = 'Grant'
286286
WHERE STRUCT<FirstName STRING, LastName STRING>(FirstName, LastName) = @name`,
287287
params: {
@@ -328,7 +328,7 @@ function writeUsingDml(instanceId, databaseId, projectId) {
328328
return;
329329
}
330330
try {
331-
const rowCount = await transaction.runUpdate({
331+
const [rowCount] = await transaction.runUpdate({
332332
sql: `INSERT Singers (SingerId, FirstName, LastName) VALUES
333333
(12, 'Melissa', 'Garcia'),
334334
(13, 'Russell', 'Morales'),
@@ -481,7 +481,7 @@ async function updateUsingPartitionedDml(instanceId, databaseId, projectId) {
481481
const database = instance.database(databaseId);
482482

483483
try {
484-
const rowCount = await database.runPartitionedUpdate({
484+
const [rowCount] = await database.runPartitionedUpdate({
485485
sql: `UPDATE Albums SET MarketingBudget = 100000 WHERE SingerId > 1`,
486486
});
487487
console.log(`Successfully updated ${rowCount} records.`);
@@ -516,7 +516,7 @@ async function deleteUsingPartitionedDml(instanceId, databaseId, projectId) {
516516
const database = instance.database(databaseId);
517517

518518
try {
519-
const rowCount = await database.runPartitionedUpdate({
519+
const [rowCount] = await database.runPartitionedUpdate({
520520
sql: `DELETE Singers WHERE SingerId > 10`,
521521
});
522522
console.log(`Successfully deleted ${rowCount} records.`);

samples/transaction.js

+3-6
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ function readOnlyTransaction(instanceId, databaseId, projectId) {
3838

3939
// Gets a transaction object that captures the database state
4040
// at a specific point in time
41-
database.runTransaction({readOnly: true}, async (err, transaction) => {
41+
database.getSnapshot(async (err, transaction) => {
4242
if (err) {
4343
console.error(err);
4444
return;
@@ -60,9 +60,6 @@ function readOnlyTransaction(instanceId, databaseId, projectId) {
6060

6161
const queryTwo = {
6262
columns: ['SingerId', 'AlbumId', 'AlbumTitle'],
63-
keySet: {
64-
all: true,
65-
},
6663
};
6764

6865
// Read #2, using the `read` method. Even if changes occur
@@ -80,12 +77,12 @@ function readOnlyTransaction(instanceId, databaseId, projectId) {
8077
});
8178

8279
console.log('Successfully executed read-only transaction.');
83-
await transaction.end();
8480
} catch (err) {
8581
console.error('ERROR:', err);
8682
} finally {
83+
transaction.end();
8784
// Close the database when finished.
88-
database.close();
85+
await database.close();
8986
}
9087
});
9188
// [END spanner_read_only_transaction]

src/batch-transaction.ts

+32-20
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,18 @@ import {promisifyAll} from '@google-cloud/promisify';
1818
import * as extend from 'extend';
1919
import * as is from 'is';
2020
import {codec} from './codec';
21-
import {Transaction} from './transaction';
21+
import {Snapshot} from './transaction';
2222

2323
/**
2424
* Use a BatchTransaction object to create partitions and read/query against
2525
* your Cloud Spanner database.
2626
*
2727
* @class
28-
* @extends Transaction
28+
* @extends Snapshot
2929
*
30-
* @param {TransactionOptions} [options] [Transaction options](https://cloud.google.com/spanner/docs/timestamp-bounds).
30+
* @param {TimestampBounds} [options] [Timestamp Bounds](https://cloud.google.com/spanner/docs/timestamp-bounds).
3131
*/
32-
class BatchTransaction extends Transaction {
33-
readTimestamp?: {};
34-
35-
constructor(session) {
36-
super(session, {readOnly: true});
37-
}
32+
class BatchTransaction extends Snapshot {
3833
/**
3934
* Closes all open resources.
4035
*
@@ -117,15 +112,18 @@ class BatchTransaction extends Transaction {
117112
sql: query,
118113
};
119114
}
120-
const reqOpts = codec.encodeQuery(query);
121-
const gaxOpts = query.gaxOptions;
115+
116+
const reqOpts = Object.assign({}, query, Snapshot.encodeParams(query));
117+
118+
delete reqOpts.gaxOptions;
119+
delete reqOpts.types;
122120

123121
this.createPartitions_(
124122
{
125123
client: 'SpannerClient',
126124
method: 'partitionQuery',
127125
reqOpts,
128-
gaxOpts,
126+
gaxOpts: query.gaxOptions,
129127
},
130128
callback);
131129
}
@@ -146,18 +144,27 @@ class BatchTransaction extends Transaction {
146144
});
147145
config.reqOpts = extend({}, query);
148146
delete query.partitionOptions;
149-
this.request(config, (err, resp) => {
147+
this.session.request(config, (err, resp) => {
150148
if (err) {
151149
callback(err, null, resp);
152150
return;
153151
}
152+
154153
const partitions = resp.partitions.map(partition => {
155154
return extend({}, query, partition);
156155
});
156+
157157
if (resp.transaction) {
158-
this.id = resp.transaction.id;
159-
this.readTimestamp = resp.transaction.readTimestamp;
158+
const {id, readTimestamp} = resp.transaction;
159+
160+
this.id = id;
161+
162+
if (readTimestamp) {
163+
this.readTimestampProto = readTimestamp;
164+
this.readTimestamp = codec.convertProtoTimestampToDate(readTimestamp);
165+
}
160166
}
167+
161168
callback(null, partitions, resp);
162169
});
163170
}
@@ -190,15 +197,20 @@ class BatchTransaction extends Transaction {
190197
* @returns {Promise<CreateReadPartitionsResponse>}
191198
*/
192199
createReadPartitions(options, callback) {
193-
const reqOpts = codec.encodeRead(options);
194-
const gaxOpts = options.gaxOptions;
200+
const reqOpts = Object.assign({}, options, {
201+
keySet: Snapshot.encodeKeySet(options),
202+
});
203+
204+
delete reqOpts.gaxOptions;
205+
delete reqOpts.keys;
206+
delete reqOpts.ranges;
195207

196208
this.createPartitions_(
197209
{
198210
client: 'SpannerClient',
199211
method: 'partitionRead',
200212
reqOpts,
201-
gaxOpts,
213+
gaxOpts: options.gaxOptions,
202214
},
203215
callback);
204216
}
@@ -302,9 +314,9 @@ class BatchTransaction extends Transaction {
302314
*/
303315
identifier() {
304316
return {
305-
transaction: this.id.toString('base64'),
317+
transaction: (this.id! as Buffer).toString('base64'),
306318
session: this.session.id,
307-
timestamp: this.readTimestamp,
319+
timestamp: this.readTimestampProto,
308320
};
309321
}
310322
}

0 commit comments

Comments
 (0)