dart で mysql にアクセスする

dart で mysql を扱うときのメモ。
dart の mysql ドライバーには sqljocky というのがあるようなので使ってみる。
dartEditor っていう Eclipse の亜種みたいのがあるのでそれ使ってもいいかもだけどとりえあず今回はなしで。

インストール

OSX で作業してるので dart のインストールは homebrew でささっと。

brew install dart

dart には pub というパッケージマネージャがあるのでこれを使ってインストールする。
まずアプリケーションのホームディレクトリに pubspec.yaml というファイルを作成し、以下のように記述する

name: appname
dependencies:
  sqljocky: any

dependencies 以下に依存モジュールを記述していく。any はバージョンの指定で、any だとたぶん最新版がインストールされる。バージョンを指定したい場合には

dependencies:
  sqljocky: 0.5.1

のように記述する。pubspec.yaml の準備が完了したら pub コマンドを実行する

pub install

pub に付いて詳しくは Getting Started | Pub Package Manager を参照した。

mysql にアクセス

まずはインストールした sqljocky モジュールを import する。

import 'package:sqljocky/sqljocky.dart';

昔 #import だった気がするけど変わったのかな。結構前から変わってるのかも。

実際に mysql にアクセスするコードは以下の感じ。

void main () {
  var pool = new ConnectionPool(
    host: 'localhost',
    user: 'user',
    password: 'pass',
    db: 'test',
    max: 1
  );

  pool.query('select * from user').then((result) {
    result.stream.listen((row) {
      print(row[0]);
    }, onDone: () {
      pool.close();
    });
  });
}

node書いてる人とかだとコード見ればだいたい何やってるかわかりそう。
dart でもIOはだいたいノンブロッキングになっていることが多いようで、query メソッドの返り値はDBから取得したレコードとかじゃなく、Future 型のオブジェクト。

この Future オブジェクトというのは jQuery の Deferred.promise オブジェクトとだいたいおんなじものだと思ってよさそう。dart:async モジュールにリファレンスがある

Future<T> abstract class / dart:async Library / Dart API Reference

ちゃんと見てないけど、then に渡すコールバックに渡されてくる result オブジェクトをまた listen すると、一行取得するごとにその下のコールバックが呼ばれる。DBのレコードをModelオブジェクトにマッピングするのはここでやれば良さそう。
全部読み終わると onDone に渡したコールバックが呼ばれる、って言う感じ。

then の呼び出しはまた新しい Future オブジェクトを返すので、select した結果をもとにどうこうしたい場合には、thenをつなげるとよい

pool.query(...).then((...) {
  ...
}).then((...) {
  ...
})

といった感じになる。非同期処理で同期的な処理を書くのがどうしても冗長だし直感的じゃないコードになるのだけど何かいい方法/書き方ないのだろうか。。

What is Dart?

What is Dart?