Permalink
Browse files

feat: add transaction support (#161)

  • Loading branch information...
XadillaX committed Dec 18, 2017
1 parent 93e74bd commit a70f782a5d9b8122d1bf13e4bb5d0d2b06a79d49
@@ -1,22 +1,19 @@
# Toshihiko

[![Greenkeeper badge](https://badges.greenkeeper.io/XadillaX/Toshihiko.svg)](https://greenkeeper.io/)
[![Toshihiko](http://img.shields.io/npm/v/toshihiko.svg)](https://www.npmjs.org/package/toshihiko)
[![Toshihiko](http://img.shields.io/npm/dm/toshihiko.svg)](https://www.npmjs.org/package/toshihiko)
[![Build Status](https://travis-ci.org/XadillaX/Toshihiko.svg?branch=feature/v1)](https://travis-ci.org/XadillaX/Toshihiko)
[![Coverage Status](https://img.shields.io/coveralls/XadillaX/Toshihiko/feature/v1.svg)](https://coveralls.io/r/XadillaX/Toshihiko?branch=feature/v1)
[![License](https://img.shields.io/npm/l/toshihiko.svg?style=flat)](https://www.npmjs.org/package/toshihiko)
[![Dependency Status](https://david-dm.org/XadillaX/Toshihiko.svg)](https://david-dm.org/XadillaX/Toshihiko)

[![Greenkeeper badge](https://badges.greenkeeper.io/XadillaX/Toshihiko.svg)](https://greenkeeper.io/)
[![Star at GitHub](https://img.shields.io/github/stars/XadillaX/toshihiko.svg?style=social&label=Star)](https://github.com/xadillax/toshihiko)

[![NPM](https://nodei.co/npm/toshihiko.png?downloads=true&downloadRank=true)](https://nodei.co/npm/toshihiko/) [![NPM](https://nodei.co/npm-dl/toshihiko.png?months=6&height=3)](https://nodei.co/npm/toshihiko/)

Yet another simple ORM for Node.js.

## Installation

```sh
```console
$ npm install toshihiko --save
```

@@ -26,7 +23,7 @@ $ npm install toshihiko --save

> Toshihiko is releasing 1.x, and new document for 1.x is under writing. We'll see you soon.
>
> You can have a preview [here](http://docs.toshihikojs.com/en/latest/).
> You can have a preview **[HERE](http://docs.toshihikojs.com/en/latest/)**.
## Contribute

@@ -86,6 +86,15 @@ Model.index("a");

Querying format for `index` should refer [here](../querying#index).

### conn - Force use a certain connection

```javascript
// Use a certain connection
Model.conn(conn);
```

Querying format for `conn` should refer [here](../querying#conn).

## Action

### find - Find a list of records
@@ -231,3 +240,56 @@ Model.findById({ key1: 1, key2: 2 }, function(err, record) {
// Promise
Model.findById(1).then().error();
```

## Transaction

`Model` provides three functions to do transactions.

### beginTransaction - Begin a transaction and returns the connection

This function will get a connection and begin a transaction with it. Then this function returns the connection just got.

**All queries and updates using this connection before committed or rolled-back will in the transaction.**

> Refer: [`Query::conn()`](../querying#conn).
```javascript
Model.beginTransaction(function(err, conn) {
// `conn` is the connection transacted
});
```

> Please **DO NOT** use a connection anymore after that connection's transaction being committed or rolled-back since that
> connection will be released.
### commit - Commit the transaction

This function will commit a transaction in a certain connection and release that connection.

```javascript
Model.beginTransaction(function(err, conn) {
DO_SOMETHING(function() {
Model.commit(conn, function(err) {
// Transaction was committed and the connection was released
});
});
});
```

> Refer: https://github.com/mysqljs/mysql#transactions
### rollback - Rollback the transaction

This function will rollback a transaction in a certain connection and release that connection.

```javascript
Model.beginTransaction(function(err, conn) {
DO_SOMETHING(function() {
Model.rollback(conn, function(err) {
// Transaction was rolled-back and the connection was released
});
});
});
```

> Refer: https://github.com/mysqljs/mysql#transactions
@@ -252,6 +252,33 @@ The only argument you should pass is a single index key name **(NOT A COLUMN NAM
eg. If you've created an index key named `this_is_an_index` and you want to forcely use this index while querying, you
only need to pass the key name `this_is_an_index` into `.index()`.

## Conn

This will be useful in `Model.conn` or `Query.conn`.

Force using a connection in this query. Usually be used in transaction.

```javascript
.conn(conn);
```

E.g.

```javascript
Model.beginTransaction(function(err, conn) {
Model.where({ foo: 1 }).conn(conn).findOne(function(err, foo) {
foo.foo = 2;
foo.update(conn, function(err) {
Model.commit(conn, function(err) {
//
});
});
});
});
```

> Refer: [`Model::beginTransaction()`](./model/usage#beginTransaction).
## Crowd Update

This will be useful in `Model.update(data, callback)`.
@@ -48,6 +48,11 @@ const record = model.build({ ... });
record.insert(function(err, record) {
console.log(err, record);
});
// or use a certain connection
record.insert(conn, function(err, record) {
console.log(err, record);
});
```

### Update
@@ -61,6 +66,11 @@ model.where({ ... }).findOne(function(err, record) {
record.update(function(err, record) {
console.log(err, record);
});
// or use a certain connection
record.update(conn, function(err, record) {
console.log(err, record);
});
});
```

@@ -74,6 +84,11 @@ model.where({ ... }).findOne(function(err, record) {
record.delete(function(err) {
console.log(err);
});
// or use a certain connection
record.delete(conn, function(err) {
console.log(err);
});
});
```

@@ -85,6 +100,11 @@ This is a convenient function. If your `Yukari` object is created via `.build()`
record.save(function(err, record) {
console.log(err, record);
});
// or use a certain connection
record.save(conn, function(err, record) {
console.log(err, record);
});
```

### To JSON
@@ -90,7 +90,7 @@ class Adapter extends EventEmitter {
* @param {Object} data data to be inserted
* @param {Function} callback the callback function
*/
insert(model, data, callback) {
insert(model, conn, data, callback) {
process.nextTick(function() {
callback(new Error("this adapter's insert function is not implemented yet."));
});
@@ -103,7 +103,7 @@ class Adapter extends EventEmitter {
* @param {Object} data data to be updated
* @param {Function} callback the callback function
*/
update(model, pk, data, callback) {
update(model, conn, pk, data, callback) {
process.nextTick(function() {
callback(new Error("this adapter's update function is not implemented yet."));
});
@@ -128,6 +128,38 @@ class Adapter extends EventEmitter {
getDBName() {
return "";
}

/**
* beginTransaction
* @param {Function} callback the callback function
*/
beginTransaction(callback) {
process.nextTick(function() {
callback(new Error("this adapter's beginTransaction function is not implemented yet."));
});
}

/**
* commit
* @param {Connection} conn the connection to be committed
* @param {Function} callback the callback function
*/
commit(conn, callback) {
process.nextTick(function() {
callback(new Error("this adapter's commit function is not implemented yet."));
});
}

/**
* rollback
* @param {Connection} conn the connection to be rolled-back
* @param {Function} callback the callback function
*/
rollback(conn, callback) {
process.nextTick(function() {
callback(new Error("this adapter's rollback function is not implemented yet."));
});
}
}

module.exports = Adapter;
Oops, something went wrong.

0 comments on commit a70f782

Please sign in to comment.