MySQLのJavaScript Connector mysql-jsを使ってみた


本記事の内容は技術的に誤っている場合がありますので注意深くご覧ください。
誤りに関してはコメントでご指摘いただけるようお願いします。

本記事では、まずサンプルを動かすところまで記載します。

# mysql-jsとは

MySQLのnode.jsのコネクタ。
レポジトリの説明書きは2015/07/31時点で、「MySQL NoSQL Connector for node.js」となっています。
元々は、NoSQLを扱うMySQL Cluster向けに開発され、MySQL Serverにも拡張されたと推測されます。

基本的なSQL操作をSQL文を書かずに出来るようにし、オブジェクト指向プログラミングの恩恵がうけられるようになる他、PromiseやA+といったコールバックへの対応がされているなどの利点があります。
mysql-jsのパッケージのバージョンは、version 1.0.0(2015/06/06段階)となっておりますが、十分にリスクや制限事項を検討した上で利用する必要がありそうです。

Repository
https://github.com/mysql/mysql-js

MySQL公式サイト: MySQL Cluster API Developer Guide :: 5 MySQL NoSQL Connector for JavaScript
https://dev.mysql.com/doc/ndbapi/en/ndb-nodejs.html

Related Documents(MySQL High Availability)
http://mysqlhighavailability.com/the-javascript-connector-for-mysql-you-never-heard-of/

なお、githubの[README](https://github.com/mysql/mysql-js/blob/master/README.md)記載の主な特徴は下記の通りです。

> Key features include:
> 
> Simple API for create, read, update, delete
> Bulk operations for high performance
> Support for ACID transactions, both explicit and implicit
> Flexible mapping from JavaScript objects to relational tables
> A fluent Query language using domain model tokens
> Default mapping of a relational table to a simple object
> Complex mapping of relational tables to complex objects
> Asynchronous API using well-known node.js callback patterns
> Promises/A+, allowing easier management of callbacks
> Connection pooling, allowing in-process scale up

# Install

## 事前条件

Mac Book Airで動作確認を実施

* 事前インストール済み
 * node.js: v0.12.7
 * MySQL Server: 5.6.15 MySQL Community Server (GPL)
 * MySQL Cluster: 未インストール

## Install

#### 1. Readmeに従ってレポジトリをclone

```bash
# clone repository
$ git config --global --add core.symlinks true
$ git clone http://github.com/mysql/mysql-js
```

#### 2. npmのインストール

```bash
$ cd mysql-js
$ npm install .
npm WARN package.json database-jones@1.0.0 license should be a valid SPDX license expression

> beta-jones-ndb@0.0.1 preinstall /Users/taka-h/working/mysql-js2/mysql-js/node_modules/jones-ndb
> node configure && node-gyp rebuild

#
#                 MySQL Cluster Driver for Jones
#
#  This Driver provides high-performance native access to MySQL Cluster
#  using the NDB API.
#
#  In order to build and run the ndb adapter, you must have:
#    - An installation of MySQL Cluster 7.x or MySQL 5.6
#      including headers and shared library files [64-bit]
#    - A working C++ compiler
#
MySQL Install Path>
```

ご利用のMySQL Serverのインストールパスを指定します

```bash
MySQL Install Path> /usr/local/mysql-5.6.15-osx10.7-x86_64/

Now run this command:
	node-gyp configure build -d
  CXX(target) Release/obj.target/ndb_adapter/impl/src/common/async_common.o
In file included from ../impl/src/common/async_common.cpp:24:
In file included from ../impl/include/common/AsyncMethodCall.h:26:
In file included from ../impl/include/common/JsConverter.h:24:
../impl/include/common/JsWrapper.h:83:17: error: calling a protected constructor of class
      'v8::HandleScope'
    HandleScope scope;
                ^
/Users/taka-h/.node-gyp/0.12.7/deps/v8/include/v8.h:816:13: note: declared protected here
  V8_INLINE HandleScope() {}
            ^
In file included from ../impl/src/common/async_common.cpp:24:
In file included from ../impl/include/common/AsyncMethodCall.h:26:
In file included from ../impl/include/common/JsConverter.h:24:
../impl/include/common/JsWrapper.h:86:43: error: 'New' is a private member of

...(中略)

npm ERR! beta-jones-ndb@0.0.1 preinstall: `node configure && node-gyp rebuild`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the beta-jones-ndb@0.0.1 preinstall script 'node configure && node-gyp rebuild'.
npm ERR! This is most likely a problem with the beta-jones-ndb package,
```

beta-jones-ndbのpre installでこけます。
下記が類似事象のようです。

https://github.com/mysql/mysql-js/issues/18

beta-jones-ndbはNDBストレージエンジン用のアダプタ(主にMySQL Cluster利用の場合)ですので、MySQL Clusterを利用しない場合は不要です。

かなり乱暴ですがjones-ndbを削除してことなきを得ます...

```bash
$ cd node_modules/
node_modules 11:05:56 $ ls -la
total 48
drwxr-xr-x   8 taka-h  staff  272  8  1 10:41 .
drwxr-xr-x  19 taka-h  staff  646  8  1 11:05 ..
lrwxr-xr-x   1 taka-h  staff   17  8  1 10:41 database-jones -> ../database-jones
lrwxr-xr-x   1 taka-h  staff   14  8  1 10:41 jones-mysql -> ../jones-mysql
lrwxr-xr-x   1 taka-h  staff   12  8  1 10:41 jones-ndb -> ../jones-ndb
lrwxr-xr-x   1 taka-h  staff   17  8  1 10:41 jones-promises -> ../jones-promises
lrwxr-xr-x   1 taka-h  staff   13  8  1 10:41 jones-test -> ../jones-test
lrwxr-xr-x   1 taka-h  staff   16  8  1 10:41 unified_debug -> ../unified_debug

# えいっ
node_modules 11:06:00 $ rm -rf jones-ndb
node_modules 11:06:32 $ cd ../

mysql-js 11:06:35 $ npm install .
npm WARN package.json database-jones@1.0.0 license should be a valid SPDX license expression
```

そもそもPathの入力がNDB用なので必要なかったようです。
また、jones-mysqlがmysqlに依存しているのでそれをインストールします。

```bash
$ npm install mysql
npm WARN package.json database-jones@1.0.0 license should be a valid SPDX license expression
mysql@2.8.0 node_modules/mysql
├── bignumber.js@2.0.7
└── readable-stream@1.1.13 (isarray@0.0.1, inherits@2.0.1, string_decoder@0.10.31, core-util-is@1.0.1)
```

# サンプルを動かす

サンプルスクリプトを作成して実行させます。
MySQL 5.6では[NDBストレージエンジンが標準ではサポートされていない](https://dev.mysql.com/doc/refman/5.6/en/storage-engines.html)一方で、サンプルがことごとくNDBストレージエンジンのサンプルですので、InnoDBストレージエンジンで使えるか、といったところ含め確認します。

#### 1. テスト用のテーブルの用意

testデータベースにuserテーブルを作ります。

```sql
mysql> use test;
Database changed
mysql> CREATE TABLE user ( i INTEGER AUTO_INCREMENT, name CHAR(48), PRIMARY KEY(i) );
Query OK, 0 rows affected (0.03 sec)
```

デフォルトストレージエンジンのInnoDBでテーブルが作成されました。

#### 2. スクリプトの実行 (接続、挿入)

```js:sample.js
var jones = require("database-jones");

var connectionProperties = new jones.ConnectionProperties("mysql");

jones.openSession(connectionProperties).then(
  function(session) {
    var user = { id: null, name: "Database Jones"};
    return session.persist("user", user);
  }
).then(
  function success() { 
    console.log("Complete");
    jones.closeAllOpenSessionFactories();
  },
  function failure(error) { 
    console.log("Error", error);
  }
);
```

```bash
$ node samples.js
Complete
```

Insertが正常に成功した時のメッセージが表示されました。

```sql
mysql> select * from user;
+---+----------------+
| i | name           |
+---+----------------+
| 1 | Database Jones |
+---+----------------+
1 row in set (0.00 sec)
```

なお、MySQL Serverへは、標準で[DefaultConnectionProperties.js](https://github.com/mysql/mysql-js/blob/master/jones-mysql/DefaultConnectionProperties.js)で接続するようです。必要に応じて下記の様に上書きしてください。

```
connectionProperties.user = 'user';
connectionProperties.password = 'password';
```

#### 3. スクリプトの実行 (検索)

MySQL High Availability記載の[記事](http://mysqlhighavailability.com/the-javascript-connector-for-mysql-you-never-heard-of/)に手を加えたサンプル。
事前状態は下記の通り。先程のテーブルにいくつかデータを追加しています。

```sql
mysql> select * from user;
+---+---------------------+
| i | name                |
+---+---------------------+
| 1 | Database Jones      |
| 2 | Database Jones No 2 |
| 3 | Database Jones No 3 |
| 4 | Database Jones No 4 |
+---+---------------------+
4 rows in set (0.00 sec)
```

```js:sample2.js
var jones = require("database-jones");

var connectionProperties = new jones.ConnectionProperties("mysql");

function onFound(err, row) {
  console.log(row);
}

jones.openSession(connectionProperties).then(
  function(session) {
    // table, 検索主キー, コールバック
    return session.find("user", 2, onFound);
  }
).then(
  function success() {
    console.log("Complete");
    jones.closeAllOpenSessionFactories();
  },
  function failure(error) {
    console.log("Error", error);l
  }
);
```

データが検索できました。

```text
node sample2.js
{ i: 2, name: 'Database Jones No 2' }
Complete
```