Skip to content

Commit 41c8831

Browse files
committed
Merge pull request #32 from mechanicalpulse/gh-issue-10-transaction-support
#10 - transaction support via knex
2 parents 800788e + 49bb7cc commit 41c8831

File tree

6 files changed

+137
-8
lines changed

6 files changed

+137
-8
lines changed

mocha.start.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ var globals = module.exports = {
3838
}],
3939
TYPES_EXCEPT_FUNCTION: ['string', 123, 123.123, null, undefined, {}, [], true, false],
4040
assert: assert,
41-
adapter: undefined
41+
adapter: undefined,
42+
co: require('co')
4243
};
4344

4445
var test = new mocha();

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"babel-loader": "5.3.2",
3232
"bluebird": "2.10.2",
3333
"chai": "3.3.0",
34+
"co": "^4.6.0",
3435
"co-mocha": "1.1.2",
3536
"mocha": "2.3.3",
3637
"standard": "5.3.1",

src/index.js

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@ function getTable (resourceConfig) {
1919
return resourceConfig.table || underscore(resourceConfig.name)
2020
}
2121

22-
function filterQuery (resourceConfig, params) {
22+
function filterQuery (resourceConfig, params, options) {
2323
let table = getTable(resourceConfig)
24-
let query = this.query.select(`${table}.*`).from(table)
24+
let query = options && options.transaction || this.query
25+
query = query.select(`${table}.*`).from(table)
2526
params = params || {}
2627
params.where = params.where || {}
2728
params.orderBy = params.orderBy || params.sort
@@ -301,7 +302,8 @@ class DSSqlAdapter {
301302
let instance
302303
options = options || {}
303304
options.with = options.with || []
304-
return this.query
305+
let query = options && options.transaction || this.query
306+
return query
305307
.select('*')
306308
.from(getTable(resourceConfig))
307309
.where(resourceConfig.idAttribute, toString(id))
@@ -328,7 +330,8 @@ class DSSqlAdapter {
328330

329331
create (resourceConfig, attrs, options) {
330332
attrs = DSUtils.removeCircular(DSUtils.omit(attrs, resourceConfig.relationFields || []))
331-
return this.query(getTable(resourceConfig))
333+
let query = options && options.transaction || this.query
334+
return query(getTable(resourceConfig))
332335
.insert(attrs, resourceConfig.idAttribute)
333336
.then(ids => {
334337
if (attrs[resourceConfig.idAttribute]) {
@@ -343,7 +346,8 @@ class DSSqlAdapter {
343346

344347
update (resourceConfig, id, attrs, options) {
345348
attrs = DSUtils.removeCircular(DSUtils.omit(attrs, resourceConfig.relationFields || []))
346-
return this.query(getTable(resourceConfig))
349+
let query = options && options.transaction || this.query
350+
return query(getTable(resourceConfig))
347351
.where(resourceConfig.idAttribute, toString(id))
348352
.update(attrs)
349353
.then(() => this.find(resourceConfig, id, options))
@@ -364,8 +368,9 @@ class DSSqlAdapter {
364368
})
365369
}
366370

367-
destroy (resourceConfig, id) {
368-
return this.query(getTable(resourceConfig))
371+
destroy (resourceConfig, id, options) {
372+
let query = options && options.transaction || this.query
373+
return query(getTable(resourceConfig))
369374
.where(resourceConfig.idAttribute, toString(id))
370375
.del().then(() => undefined)
371376
}

test/create_trx.spec.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
describe('DSSqlAdapter#create + transaction', function () {
2+
it('commit should persist created user in a sql db', function* () {
3+
var id;
4+
5+
yield adapter.query.transaction(co.wrap(function * (trx) {
6+
var createUser = yield adapter.create(User, {name: 'Jane'}, {transaction: trx});
7+
id = createUser.id;
8+
assert.equal(createUser.name, 'Jane');
9+
assert.isDefined(createUser.id);
10+
}));
11+
12+
var findUser = yield adapter.find(User, id);
13+
assert.isObject(findUser, 'user committed to database');
14+
assert.equal(findUser.name, 'Jane');
15+
assert.isDefined(findUser.id);
16+
assert.equalObjects(findUser, {id: id, name: 'Jane', age: null, profileId: null});
17+
});
18+
19+
it('rollback should not persist created user in a sql db', function* () {
20+
var id;
21+
22+
try {
23+
yield adapter.query.transaction(co.wrap(function * (trx) {
24+
var createUser = yield adapter.create(User, {name: 'John'}, {transaction: trx});
25+
id = createUser.id;
26+
assert.equal(createUser.name, 'John');
27+
assert.isDefined(createUser.id);
28+
29+
throw new Error('rollback');
30+
}));
31+
} catch (err) {
32+
assert.equal(err.message, 'rollback');
33+
}
34+
35+
try {
36+
var findUser = yield adapter.find(User, id);
37+
throw new Error('user committed to database');
38+
} catch(err) {
39+
assert.equal(err.message, 'Not Found!');
40+
}
41+
});
42+
});

test/destroy_trx.spec.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
describe('DSSqlAdapter#destroy + transaction', function () {
2+
it('commit should destroy a user from a Sql db', function* () {
3+
var createUser = yield adapter.create(User, {name: 'John'})
4+
var id = createUser.id;
5+
6+
yield adapter.query.transaction(co.wrap(function * (trx) {
7+
return adapter.destroy(User, id, {transaction: trx});
8+
}));
9+
10+
try {
11+
var findUser = yield adapter.find(User, id);
12+
throw new Error('Should not have reached here!');
13+
} catch (err) {
14+
assert.equal(err.message, 'Not Found!');
15+
}
16+
});
17+
18+
it('rollback should not destroy a user from a Sql db', function* () {
19+
var createUser = yield adapter.create(User, {name: 'John'})
20+
var id = createUser.id;
21+
22+
try {
23+
yield adapter.query.transaction(co.wrap(function * (trx) {
24+
yield adapter.destroy(User, createUser.id, {transaction: trx});
25+
26+
throw new Error('rollback');
27+
}));
28+
} catch (err) {
29+
assert.equal(err.message, 'rollback');
30+
}
31+
32+
var findUser = yield adapter.find(User, id);
33+
assert.isObject(findUser, 'user still exists');
34+
});
35+
});

test/update_trx.spec.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
describe('DSSqlAdapter#update + transaction', function () {
2+
it('commit should update a user in a Sql db', function* () {
3+
var user = yield adapter.create(User, {name: 'John'})
4+
var id = user.id;
5+
assert.equal(user.name, 'John');
6+
assert.isDefined(user.id);
7+
8+
yield adapter.query.transaction(co.wrap(function * (trx) {
9+
var updatedUser = yield adapter.update(User, id, {name: 'Johnny'}, {transaction: trx});
10+
assert.equal(updatedUser.name, 'Johnny');
11+
assert.isDefined(updatedUser.id);
12+
assert.equalObjects(updatedUser, {id: id, name: 'Johnny', age: null, profileId: null});
13+
}));
14+
15+
var foundUser = yield adapter.find(User, id);
16+
assert.equal(foundUser.name, 'Johnny');
17+
assert.isDefined(foundUser.id);
18+
assert.equalObjects(foundUser, {id: id, name: 'Johnny', age: null, profileId: null});
19+
});
20+
21+
it('rollback should not update a user in a Sql db', function* () {
22+
var user = yield adapter.create(User, {name: 'John'})
23+
var id = user.id;
24+
assert.equal(user.name, 'John');
25+
assert.isDefined(user.id);
26+
27+
try {
28+
yield adapter.query.transaction(co.wrap(function * (trx) {
29+
var updatedUser = yield adapter.update(User, id, {name: 'Johnny'}, {transaction: trx});
30+
assert.equal(updatedUser.name, 'Johnny');
31+
assert.isDefined(updatedUser.id);
32+
assert.equalObjects(updatedUser, {id: id, name: 'Johnny', age: null, profileId: null});
33+
34+
throw new Error('rollback');
35+
}));
36+
} catch (err) {
37+
assert.equal(err.message, 'rollback');
38+
}
39+
40+
var foundUser = yield adapter.find(User, id);
41+
assert.equal(foundUser.name, 'John');
42+
assert.isDefined(foundUser.id);
43+
assert.equalObjects(foundUser, {id: id, name: 'John', age: null, profileId: null});
44+
});
45+
});

0 commit comments

Comments
 (0)