Skip to content

Commit

Permalink
spanner: make getTransaction public (#2344)
Browse files Browse the repository at this point in the history
  • Loading branch information
callmehiphop authored and stephenplusplus committed Jun 26, 2017
1 parent cbbbf6c commit ca0d96c
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 74 deletions.
133 changes: 72 additions & 61 deletions packages/spanner/src/database.js
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,77 @@ Database.prototype.getSchema = function(callback) {
});
};

/**
* Get a read/write ready Transaction object.
*
* @param {object=} options - [Transaction options](https://cloud.google.com/spanner/docs/timestamp-bounds).
* @param {number} options.timeout - Specify a timeout for the transaction. The
* transaction will be ran in its entirety, however if an abort error is
* returned the transaction will be retried if the timeout has not been met.
* Default: `60000` (milliseconds)
* @param {boolean} options.readOnly - Specifies if the transaction is
* read-only. Default: `false`.
* @param {number} options.exactStaleness - Executes all reads at the timestamp
* that is `exactStaleness` old.
* @param {date} options.readTimestamp - Execute all reads at the given
* timestamp.
* @param {boolean} options.returnTimestamp - If `true`, returns the read
* timestamp.
* @param {boolean} options.strong - Read at the timestamp where all previously
* committed transactions are visible.
* @param {function} callback - The callback function.
* @param {?error} callback.err - An error returned while getting the
* transaction object.
* @param {module:spanner/transaction} transaction - The transaction object.
*
* @example
* database.getTransaction(function(err, transaction) {});
*
* //-
* // If the callback is omitted, we'll return a Promise.
* //-
* database.getTransaction().then(function(data) {
* var transaction = data[0];
* });
*/
Database.prototype.getTransaction = function(options, callback) {
var self = this;

if (is.fn(options)) {
callback = options;
options = null;
}

if (!options || !options.readOnly) {
this.pool_.getWriteSession(function(err, session, transaction) {
callback(err, transaction);
});
return;
}

this.pool_.getSession(function(err, session) {
if (err) {
callback(err);
return;
}

options = extend({}, options);
delete options.readOnly;

var transaction = self.pool_.createTransaction_(session, options);

transaction.begin(function(err) {
if (err) {
transaction.end();
callback(err);
return;
}

callback(null, transaction);
});
});
};

/**
* Execute a SQL statement on this database.
*
Expand Down Expand Up @@ -811,7 +882,7 @@ Database.prototype.runTransaction = function(options, runFn) {

options = extend({}, options);

this.getTransaction_(options, function(err, transaction) {
this.getTransaction(options, function(err, transaction) {
if (err) {
runFn(err);
return;
Expand Down Expand Up @@ -1004,66 +1075,6 @@ Database.prototype.getSession_ = function(callback) {
this.pool_.getSession(callback);
};

/**
* Get a read/write ready Transaction object.
*
* @private
*
* @param {object=} options - Transaction options.
* @param {boolean} options.readOnly - Specifies if the transaction is read
* only.
* @param {function} callback - The callback function.
* @param {?error} callback.err - An error returned while getting the
* transaction object.
* @param {module:spanner/transaction} transaction - The transaction object.
*
* @example
* database.getTransaction(function(err, transaction) {});
*
* //-
* // If the callback is omitted, we'll return a Promise.
* //-
* database.getTransaction().then(function(data) {
* var transaction = data[0];
* });
*/
Database.prototype.getTransaction_ = function(options, callback) {
var self = this;

if (is.fn(options)) {
callback = options;
options = null;
}

if (!options || !options.readOnly) {
this.pool_.getWriteSession(function(err, session, transaction) {
callback(err, transaction);
});
return;
}

this.pool_.getSession(function(err, session) {
if (err) {
callback(err);
return;
}

options = extend({}, options);
delete options.readOnly;

var transaction = self.pool_.createTransaction_(session, options);

transaction.begin(function(err) {
if (err) {
callback(err);
return;
}

callback(null, transaction);
});
});
};

/**
* Create a Session object.
*
Expand Down
2 changes: 1 addition & 1 deletion packages/spanner/src/transaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ Transaction.prototype.request = function(config, callback) {
delete reqOpts.gaxOptions;

config.method(reqOpts, gaxOptions, function(err, resp) {
if (!err || err.code !== ABORTED) {
if (!self.runFn_ || !err || err.code !== ABORTED) {
callback(err, resp);
return;
}
Expand Down
27 changes: 16 additions & 11 deletions packages/spanner/test/database.js
Original file line number Diff line number Diff line change
Expand Up @@ -798,7 +798,7 @@ describe('Database', function() {

describe('runTransaction', function() {
it('should get a Transaction object', function(done) {
database.getTransaction_ = function() {
database.getTransaction = function() {
done();
};

Expand All @@ -808,7 +808,7 @@ describe('Database', function() {
it('should execute callback with error', function(done) {
var error = new Error('Error.');

database.getTransaction_ = function(options, callback) {
database.getTransaction = function(options, callback) {
callback(error);
};

Expand All @@ -831,7 +831,7 @@ describe('Database', function() {
return fakeDate;
};

database.getTransaction_ = function(options, callback) {
database.getTransaction = function(options, callback) {
assert.deepEqual(options, OPTIONS);
callback(null, TRANSACTION);
};
Expand All @@ -855,7 +855,7 @@ describe('Database', function() {
timeout: 1000
};

database.getTransaction_ = function(options, callback) {
database.getTransaction = function(options, callback) {
callback(null, TRANSACTION);
};

Expand Down Expand Up @@ -1045,7 +1045,7 @@ describe('Database', function() {
});
});

describe('getTransaction_', function() {
describe('getTransaction', function() {
describe('write mode', function() {
it('should get a session from the pool', function(done) {
var error = new Error('Error.');
Expand All @@ -1058,7 +1058,7 @@ describe('Database', function() {
}
};

database.getTransaction_(function(err, transaction_) {
database.getTransaction(function(err, transaction_) {
assert.strictEqual(err, error);
assert.strictEqual(transaction_, transaction);
done();
Expand All @@ -1079,7 +1079,7 @@ describe('Database', function() {
}
};

database.getTransaction_(OPTIONS, assert.ifError);
database.getTransaction(OPTIONS, assert.ifError);
});

it('should return an error if could not get session', function(done) {
Expand All @@ -1091,7 +1091,7 @@ describe('Database', function() {
}
};

database.getTransaction_(OPTIONS, function(err) {
database.getTransaction(OPTIONS, function(err) {
assert.strictEqual(err, error);
done();
});
Expand Down Expand Up @@ -1121,7 +1121,7 @@ describe('Database', function() {
}
};

database.getTransaction_(OPTIONS, assert.ifError);
database.getTransaction(OPTIONS, assert.ifError);
});

it('should begin a transaction', function(done) {
Expand All @@ -1141,7 +1141,7 @@ describe('Database', function() {
}
};

database.getTransaction_(OPTIONS, function(err, transaction) {
database.getTransaction(OPTIONS, function(err, transaction) {
assert.ifError(err);
assert.strictEqual(transaction, TRANSACTION);
done();
Expand All @@ -1150,11 +1150,15 @@ describe('Database', function() {

it('should return an error if transaction cannot begin', function(done) {
var error = new Error('err');
var endCalled = false;

var SESSION = {};
var TRANSACTION = {
begin: function(callback) {
callback(error);
},
end: function() {
endCalled = true;
}
};

Expand All @@ -1167,8 +1171,9 @@ describe('Database', function() {
}
};

database.getTransaction_(OPTIONS, function(err) {
database.getTransaction(OPTIONS, function(err) {
assert.strictEqual(err, error);
assert.strictEqual(endCalled, true);
done();
});
});
Expand Down
2 changes: 1 addition & 1 deletion packages/spanner/test/session-pool.js
Original file line number Diff line number Diff line change
Expand Up @@ -940,7 +940,7 @@ describe('SessionPool', function() {

sessionPool.requestStream(CONFIG)
.on('data', function(data) {
assert.strictEqual(data, responseData);
assert.deepEqual(data, responseData);
done();
});

Expand Down
13 changes: 13 additions & 0 deletions packages/spanner/test/transaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,10 @@ describe('Transaction', function() {
return true;
};

transaction.runFn_ = function() {
done(new Error('Should not have been called.'));
};

transaction.request(config, function() {
done(new Error('Should not have been called.'));
});
Expand Down Expand Up @@ -519,6 +523,15 @@ describe('Transaction', function() {
done(new Error('Should not have been called.'));
});
});

it('should return the aborted error if no runFn', function(done) {
transaction.runFn_ = null;

transaction.request(config, function(err) {
assert.strictEqual(err, abortedError);
done();
});
});
});
});

Expand Down

0 comments on commit ca0d96c

Please sign in to comment.