Skip to content

Commit 0013a63

Browse files
committed
feat: add *beginTransactionScope(scope)
1 parent 41588a4 commit 0013a63

File tree

3 files changed

+196
-0
lines changed

3 files changed

+196
-0
lines changed

README.md

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,111 @@ console.log(result);
108108
changedRows: 0 }
109109
```
110110

111+
### Update
112+
113+
- Update a row with primary key: `id`
114+
115+
```js
116+
let row = {
117+
id: 123,
118+
name: 'fengmk2',
119+
otherField: 'other field value',
120+
modifiedAt: db.literals.now, // `now()` on db server
121+
};
122+
let result = yield db.update('table-name', row);
123+
console.log(result);
124+
{ fieldCount: 0,
125+
affectedRows: 1,
126+
insertId: 0,
127+
serverStatus: 2,
128+
warningCount: 0,
129+
message: '(Rows matched: 1 Changed: 1 Warnings: 0',
130+
protocol41: true,
131+
changedRows: 1 }
132+
```
133+
134+
- Update a row with `options.where` and `options.columns`
135+
136+
```js
137+
let row = {
138+
name: 'fengmk2',
139+
otherField: 'other field value',
140+
modifiedAt: db.literals.now, // `now()` on db server
141+
};
142+
let result = yield db.update('table-name', row, {
143+
where: { name: row.name },
144+
columns: [ 'otherField', 'modifiedAt' ]
145+
});
146+
console.log(result);
147+
{ fieldCount: 0,
148+
affectedRows: 1,
149+
insertId: 0,
150+
serverStatus: 2,
151+
warningCount: 0,
152+
message: '(Rows matched: 1 Changed: 1 Warnings: 0',
153+
protocol41: true,
154+
changedRows: 1 }
155+
```
156+
157+
### Get
158+
159+
- Get a row
160+
161+
```js
162+
let row = yield db.get('table-name', { name: 'fengmk2' });
163+
164+
=> SELECT * FROM `table-name` WHERE `name` = 'fengmk2'
165+
```
166+
167+
### Select
168+
169+
- Select all rows
170+
171+
```js
172+
let rows = yield db.select('table-name');
173+
174+
=> SELECT * FROM `table-name`
175+
```
176+
177+
- Select rows with condition
178+
179+
```js
180+
let rows = yield db.select('table-name', {
181+
where: {
182+
type: 'javascript'
183+
},
184+
columns: ['author', 'title'],
185+
orders: [['id', 'desc']]
186+
});
187+
188+
=> SELECT `author`, `title` FROM `table-name`
189+
WHERE `type` = 'javascript' ORDER BY `id` DESC
190+
```
191+
192+
### Delete
193+
194+
- Delete with condition
195+
196+
```js
197+
let result = yield db.delete('table-name', {
198+
name: 'fengmk2'
199+
});
200+
201+
=> DELETE FROM `table-name` WHERE `name` = 'fengmk2'
202+
```
203+
204+
### Count
205+
206+
- Get count from a table with condition
207+
208+
```js
209+
let count = yield db.count('table-name', {
210+
type: 'javascript'
211+
});
212+
213+
=> SELECT COUNT(*) AS count FROM `table-name` WHERE `type` = 'javascript';
214+
```
215+
111216
### Transactions
112217

113218
beginTransaction, commit or rollback
@@ -126,6 +231,22 @@ try {
126231
}
127232
```
128233

234+
#### Transaction with scope
235+
236+
API: `*beginTransactionScope(scope)`
237+
238+
All query run in scope will under a same transaction.
239+
We will auto commit or rollback for you.
240+
241+
```js
242+
var result = yield db.beginTransactionScope(function* (conn) {
243+
yield tran.insert(table, row1);
244+
yield tran.update(table, row2);
245+
return { success: true };
246+
});
247+
// if error throw on scope, will auto rollback
248+
```
249+
129250
### Raw Queries
130251

131252
- Query with arguments
@@ -162,6 +283,11 @@ TBD
162283
- *delete(table, where)
163284
- *count(table, where)
164285

286+
#### Transactions
287+
288+
- *beginTransaction()
289+
- *beginTransactionScope(scope)
290+
165291
### Utils
166292

167293
- escape(value, stringifyObjects, timeZone)

lib/client.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,21 @@ proto.beginTransaction = function* () {
7777

7878
return new RDSTransaction(conn);
7979
};
80+
81+
/**
82+
* Auto commit or rollback on a transaction scope
83+
*
84+
* @param {Function*} scope
85+
* @return {Object} scope return result
86+
*/
87+
proto.beginTransactionScope = function* (scope) {
88+
let tran = yield this.beginTransaction();
89+
try {
90+
let result = yield scope(tran);
91+
yield tran.commit();
92+
return result;
93+
} catch (err) {
94+
yield tran.rollback();
95+
throw err;
96+
}
97+
};

test/client.test.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,58 @@ describe('client.test.js', function () {
225225
});
226226
});
227227

228+
describe('beginTransactionScope(scope)', function () {
229+
it('should beginTransactionScope() error', function* () {
230+
let db = rds({});
231+
try {
232+
yield db.beginTransactionScope(function* () {});
233+
throw new Error('should not run this');
234+
} catch (err) {
235+
assert.equal(err.name, 'RDSClientGetConnectionError');
236+
}
237+
});
238+
239+
it('should insert 2 rows in a transaction', function* () {
240+
let result = yield this.db.beginTransactionScope(function* (conn) {
241+
yield conn.query('insert into ??(name, email, gmt_create, gmt_modified) \
242+
values(?, ?, now(), now())',
243+
[table, prefix + 'beginTransactionScope1', prefix + 'm@beginTransactionScope1.com']);
244+
yield conn.query('insert into ??(name, email, gmt_create, gmt_modified) \
245+
values(?, ?, now(), now())',
246+
[table, prefix + 'beginTransactionScope2', prefix + 'm@beginTransactionScope1.com']);
247+
return true;
248+
});
249+
250+
assert.equal(result, true);
251+
252+
let rows = yield this.db.query('select * from ?? where email=? order by id',
253+
[table, prefix + 'm@beginTransactionScope1.com']);
254+
assert.equal(rows.length, 2);
255+
assert.equal(rows[0].name, prefix + 'beginTransactionScope1');
256+
assert.equal(rows[1].name, prefix + 'beginTransactionScope2');
257+
});
258+
259+
it('should rollback when query fail', function* () {
260+
try {
261+
yield this.db.beginTransactionScope(function* (conn) {
262+
yield conn.query('insert into ??(name, email, gmt_create, gmt_modified) \
263+
values(?, ?, now(), now())',
264+
[table, prefix + 'beginTransactionScope-fail1', 'm@beginTransactionScope-fail.com']);
265+
yield conn.query('insert into ??(name, email, gmt_create, gmt_modified) \
266+
valuefail(?, ?, now(), now())',
267+
[table, prefix + 'beginTransactionScope-fail12', 'm@beginTransactionScope-fail.com']);
268+
return true;
269+
});
270+
} catch (err) {
271+
assert.equal(err.code, 'ER_PARSE_ERROR');
272+
}
273+
274+
let rows = yield this.db.query('select * from ?? where email=? order by id',
275+
[table, prefix + 'm@beginTransactionScope-fail.com']);
276+
assert.equal(rows.length, 0);
277+
});
278+
});
279+
228280
describe('get(table, obj, options), select(table, options)', function () {
229281
before(function* () {
230282
let result = yield this.db.insert(table, {

0 commit comments

Comments
 (0)