今さらnode-postgres案内(1)　unix socket接続をする

#情報少ないんだが……
さて、やっぱりみんなnode.js上だとRedisとかMongoDBがお好きなんだろうか。なんかORM使ってるんだろうか。それとも、node-postgres使う人は疑問なく使えていて、それ以外の人は興味が無いんだろうか。とりあえず、node-postgresの記事って古いものが多い気がする。

ORMも良いと思うよ。でもね。SQLはSQLで良いもんだと思うんだ。ただ、DBやテーブルの作成がコードの外にあると、なんかちょっと気持ち悪い、というのもあるよね。私にとっては、SQLを忌避してORMを使う動機のうち、半分くらいがそれだ。でも、DBが無ければ作る。テーブルが無ければ作る。テーブルの仕様が想定と違うなら直す、というコードをmodelに入れちゃえば良いんだ。そうすると、SQLでも許せちゃう（※効果には個人差があります）。

なので、ちょっと基本的なところから押さえてみる。

まずは、CoffeeScriptで申し訳ないが、下の方にJavascript版も置いたので、どうしてもCoffeeScriptを読みたくない人はそちらを読んで欲しい。

node-postgresのモジュールを、変数pgに格納した。最初にやるべきことはデータベースへの接続だが、同じサーバで動かすんなら、Unix Domain Socketの方が良いよね。INET Domain Socket(TCP)よりもちょっとばかし速いしね。まあ、最近諸々C10K向けの最適化が出揃ってきたおかげで、昔みたいに帯域律速ではなくて、CPU律速になりつつあるけどさ。それはそれで最適化のしがいがあるもんね。

まあ無駄口をきいているのは、一瞬で終わりだから。下記のコード片が、DB接続の参考コードだ。UNIXドメインソケット使うなら、このようにhostを/tmpにすればいいだけ。普通IPアドレスが入るところだね。で、このように、ぶら下げた無名関数の中に続きの処理を書けばOK。簡単！　でも注意すべきところがあるから、続きで紹介するよ。

```coffeescript
      pg.connect {
        host: '/tmp'
        port: 5432
        user: 'postgres'
        password: mypassword
        database: mydbname
      }, (err,client) ->
```

全サンプルソースはこちら。続きでも、コレ使うよ。

```coffeescript
pg = require('pg')
packagejson = require('./package.json')
mydbname = packagejson.name
mypassword = 'password of your postgres'

mycreatedb = (err, config, db, next) ->
  if err
    console.log err
  else
    pg.connect config, (err,client) ->
      if err
        console.log err
      else
        querystr = 'CREATE DATABASE '+db+';'
        console.log querystr
        client.query querystr, (err,result) ->
          #こいつの返却値は要らない（既にDBがあればエラーが返るが……）
          if err
            console.log err
        #このdrain待ちは、queryと同時に仕込まないとりこぼす！
        client.on 'drain',->
          console.log 'caught drain'
          client.end()
          client.on 'end',->
            console.log 'call next'
            next null


mycreatedb null,{
  host: '/tmp'
  port: 5432
  user: 'postgres'
  password: mypassword
  database: 'template1'
}, mydbname, (err) ->
  if err
    console.log err
  else
      pg.connect {
        host: '/tmp'
        port: 5432
        user: 'postgres'
        password: mypassword
        database: mydbname
      }, (err,client) ->
        if err
          console.log err
        else
          console.log 'success!'
          querystr = "SELECT relname FROM pg_class WHERE relkind = 'r';"
          console.log querystr
          client.query querystr, (err,result) ->
            if err
              console.log err
            else
              console.log 'result!'
              for row,index in result.rows
                for key,value of row
                  console.log 'index: '+index+', key: '+key+', value: '+value
          #このdrain待ちは、queryと同時に仕込まないとりこぼす！
          client.on 'drain',->
            console.log 'caught!'
            client.end ->
              console.log 'end'
```

```js
var pg = require('pg');
var packagejson = require('./package.json');

var mydbname = packagejson.name;
var mypassword = 'password for your postgres';

var mycreatedb = function(err, config, db, next) {
  if (err) {
    console.log(err);
  } else {
    pg.connect(config, function(err, client) {
      if (err) {
        console.log(err);
      } else {
        var querystr = 'CREATE DATABASE ' + db + ';';
        console.log(querystr);
        client.query(querystr, function(err, result) {
          //こいつの返却値は要らない（既にDBがあればエラーが返るが……）
          if (err) {
            console.log(err);
          }
        });
        //このdrain待ちは、queryと同時に仕込まないとりこぼす！
        client.on('drain', function() {
          console.log('caught drain');
          client.end();
          client.on('end', function() {
            console.log('call next');
            next(null);
          });
        });
      }
    });
  }
};

mycreatedb(null, {
  host: '/tmp',
  port: 5432,
  user: 'postgres',
  password: mypassword,
  database: 'template1'
}, mydbname, function(err) {
  if (err) {
    console.log(err);
  } else {
    pg.connect({
      host: '/tmp',
      port: 5432,
      user: 'postgres',
      password: mypassword,
      database: mydbname
    }, function(err, client) {
      var querystr;
      if (err) {
        console.log(err);
      } else {
        console.log('success!');
        querystr = "SELECT relname FROM pg_class WHERE relkind = 'r';";
        console.log(querystr);
        client.query(querystr, function(err, result) {
          if (err) {
            console.log(err);
          } else {
            console.log('result!');
            var ref = result.rows;
            var index, len;
            for (index = 0, len = ref.length; index < len; ++index) {
              var key, row = ref[index];
              for (key in row) {
                console.log('index: ' + index + ', key: ' + key + ', value: ' + row[key]);
              }
            }
          }
        });
        //このdrain待ちは、queryと同時に仕込まないとりこぼす！
        client.on('drain', function() {
          console.log('caught!');
          client.end(function() {
            console.log('end');
          });
        });
      }
    });
  }
});
```