LaravelでVoltDBを利用する

#Laravel+VoltDB
LaravelとNewSQLという分類で語られる機会が多くなったVoltDBを組み合わせて利用してみましょう。
とは言っても、デフォルtの状態ではもちろん利用できません。
Laravelの機能と切り分けて組み込む様な使い方であれば特に気にせず利用する事が出来ます。

が、authやcacheなど、Laravelの便利なAPIを活かせないのはもったいないので、
デフォルトで用意されているデータベースドライバーなどと同様に利用できる様に、
[Laravel.VoltDB](https://github.com/ytake/Laravel.VoltDB)というパッケージを作ったので、
簡単な利用方法を記載します。
**ただし現時点でVoltDBはwindowsに対応していません**  
##voltdb-client-php build
まず前提条件として、
PHPから利用するにはvoltdbのphp-extensionをインストールしなければなりません。
■[voltdb-client-cpp](https://github.com/VoltDB/voltdb-client-cpp)
最初に、c++クライアントをビルドして下さい

```bash：cpp build
$ git clone https://github.com/VoltDB/voltdb-client-cpp.git
$ make
```
うまくビルドできない場合は、`gcc`, `libboost`あたりをインストールして下さい。
OSにより若干異なるかもしれませんが、だいたいはビルドできるはずです。
もしうまくビルドできない場合は、`noexception` ブランチのものを利用して下さい。

■[voltdb-client-php](https://github.com/VoltDB/voltdb-client-php)
cppクライアントがビルドできたら、次はphpクライアントです

```bash:php client install
$ git clone -b native https://github.com/VoltDB/voltdb-client-php.git
$ phpize
```
cppクライアントを指定してmakeします

```bash:configure
$ ./configure --with-voltdb=../voltdb-client-cpp
$ make
```
あとはvoltdb.soを任意の場所へ設置して、 
php.ini、またはvoltdb.iniなどに記述してapache, nginx(php5-fpm)等を再起動してください

```ini
extension=voltdb.so
```

##composer install
composer.jsonは以下の様に記載します。

```json:composer.json
"require": {
    "php": ">=5.4.0",
    "ext-mcrypt": "*",
    "ext-json": "*",
    "laravel/framework": "4.2.*",
    "ytake/laravel-voltdb": "0.*"
}
```
**voltdb-client-phpが導入されていない場合は、何をどうやっても使用できません** 

インストールが終わったら、下記のものをそれぞれの`app.php`などに追記して下さい

```php:app.php
// voltDB provider登録
'providers' => [
    'Ytake\LaravelVoltDB\VoltDBServiceProvider',
];
// Facade
'aliases' => [
    'VoltDBApi' => 'Ytake\LaravelVoltDB\VoltDBFacade',
];
```

##configure
database.phpには下記の様に追記します

```php:database.php
'voltdb' => [
    'driver' => 'voltdb',
    'host' => 'localhost',
    'username' => '',
    'password' => '',
    'port' => 21212
],
```
voltdbパッケージのコンフィグを以下のコマンドでpublishします

```bash
$ php artisan config:publish ytake/laravel-voltdb
```
折角なので中身を解説

```php:
return [
    // VoltDB JSON APIを利用する場合に記述して下さい
    /** voltdb server */
    'host' => "localhost", // ドメインを指定
    /** api path */
    'path' => "/api/1.0/", // apiのURIを変更している場合はここでURI指定
    /** json interface port */
    'apiPort' => 8080, // port変更していれば指定してください
    /** ssl access */
    'ssl' => false, // sslの場合はtrue

    /** default configure */
    'default' => [
        // auth 'voltdb' driver コンフィグ
        'auth' => [
            // authドライバーで使用するvoltdbを指定 database.phpに記述してある識別子で指定
            'database' => 'voltdb',
            // デフォルトで用意してあるddlを利用せずに任意の定義を利用する場合は、
            // それぞれを任意の名前に変更するか、extendsして作り替えて下さい
            'column_name' => [
                'id' => 'USER_ID',
                'password' => 'PASSWORD',
                'remember_token' => 'REMEMBER_TOKEN'
            ],
            /** default auth procedure */
            // デフォルトで用意してあるストアドプロシージャ名です。
            // それぞれ変更する場合は、任意のストアドプロシージャにしてください
            'procedure' => [
                'findUser' => "Auth_findUser", // \Auth::loginUsingId(1) などで利用します
                'remember_token' => "Auth_rememberToken", // "remember me"で利用されます
                'update_token' => "Auth_updateToken", // "remember me"で利用されます
            ],
        ],
        'system' => [
            // for system catalog, see database.php
            // @SystemCatalogを利用したいDBを指定　database.phpに記述してある識別子で指定
            'database' => 'voltdb',
        ],
        // cache 'voltdb' driver コンフィグ
        'cache' => [
            // cacheで利用したいDBを指定　database.phpに記述してある識別子で指定
            'database' => 'voltdb',
            // cacheで利用する、デフォルトで用意してあるストアドプロシージャ名です。
            // それぞれ変更する場合は、任意のストアドプロシージャにしてください
            'procedure' => [
                'flushAll' => "Cache_flushAll", // \Cache::flush() またはartisan cache:clear
                'forget' => "Cache_forget", // \Cache::forget($key)
                'update' => "Cache_update", // \Cache::put($key, $value, $life)など
                'add' => "Cache_add", // \Cache::put($key, $value, $life)など
                'find' => "Cache_find", // \Cache::get($key)など
            ],
        ],
    ],
];
```

##Auth, Cacheドライバー
デフォルトの定義を利用する場合は、

```bash
$ php artisan ytake:voltdb-schema-publish
```
で、ディレクトリにpublishします。
デフォルトでは、`storage`配下にschemaディレクトリを作成してその中に設置します。
すでにvoltdbを利用していれば、現在使っている定義にマージしてvoltdbでddl再コンパイル等をして
再起動して下さい。
実行後に下記の様な文字が出力されますので、
localでvoltdbを起動している場合はそのままコマンドを叩けば起動します。
他の環境で動かしている場合はそれに倣って下さい

```bash
merge your ddl and start voltdb
example). $ voltdb compile /プロジェクトまでのパス/app/storage/schema/ddl.sql
example). $ voltdb voltdb create catalog.jar
```

Auth, Cacheで使える様にするには、
`app/config/auth.php`, `app/config/cache.php`のdriverを

```php
 'driver' => 'voltdb',
```
としてください。
基本的にはこれだけでvoltdbが利用される様になります。

##DB
DBファサードに統合してありますので、
既存のものとほぼ同等に利用できますが、
VoltDBの特性上、QueryBuilder, Eloquentには対応していません。
というのも、
PDOのvoltdbドライバーが無い
VoltDB自体がjava(JDBC)でプリペアドステートメントを利用しているため、phpで実装する意味が無い
クエリー文を書いて実行する事がほとんどない(ストアドプロシージャを多用する)
という理由があります
利用される状況を考えても、高速で動作させる為、
javaで実装してしまう事をおすすめします(そんなに難しくないです)

###@AdHoc
とは言っても、直接SQLを書きたい場合もあるかと思いますので、
@AdHocクエリーを利用できる様にしてあります。

```php
$sql = "INSERT INTO users (user_id, username, password, remember_token, created_at)"
    ." VALUES (" . rand() . ", 'voltdb', '" . $pass . "', null, '" . date("Y-m-d H:i:s") . "')";
\DB::connection('voltdb')->exec($sql);
$sql = "SELECT * FROM users";
\DB::connection('voltdb')->select($sql);
```

###StoredProcedure
ストアドプロシージャと、値を配列で指定するだけです

```php
\DB::connection('voltdb')->procedure('Auth_findUser', [1]);
```

##Facade
JSONインターフェースのAPIを利用する場合、
Facadeを用意してありますので、必要に応じて利用できます。

```php
// システムインフォは独立して実行できます
\VoltDBApi::request()->info()->getResult();

// ストアドプロシージャを指定して実行します
\VoltDBApi::request()->post([
    'Procedure' => 'addUser',
    'Parameters' => [1, "voltdb"]
])->getResult();
```

##Async
そこまでまだ活用していませんが、
非同期利用する場合に、用意されているdrain()などを使って実装できます

##Artisan
MySQLの"SHOW TABLES;", "SHOW COLUMNS;"やORACLEのTABの様な感じで、
consoleに出力するものがあります。

```bash
$ php artisan ytake:voltdb-system-catalog
```
用意されているシステムカタログが出力されますので、
任意のcomponent情報だけを取得する事も出来ます。(例)

```bash
$ php artisan ytake:voltdb-system-catalog -c COLUMNS
```
コンポーネントの指定方法は、
[システムカタログ](https://voltdb.com/docs/UsingVoltDB/sysprocsystemcatalog.php)
を参考にして下さい。

長いですが、こんな感じで利用できます。
MySQLやpostgreSQLの代替えで利用してもそこまで威力が発揮されませんが、
RDBMSには難しい構成で利用したり、
大規模なトラフィックに対応するシステム等で今後利用される機会が増えるかもしれません
そのうちNuoDBにも対応させようかな