PHPアプリのDB schemaをRubyのActiveRecordだけでdumpする

背景

schema.rbが欲しいのです。

我々は賢いので。

賢いかどうかはともかく、DB schema を手軽に確認する方法として schema.rb はそこそこ優れてると思うわけですよ。少なくとも何百とテーブルがあるわけじゃないならね。インデントも揃ってるし、SQL よりは読みやすく感じる。しかもこれが自動で更新され続けるんだから Rails をやる時は schema.rb は重宝します。特に普段触っていないものは。

ActiveRecordだけでschema dumpする

基本的には

ruby - ActiveRecord Schema Dump without rails - Stack Overflow

のお話。ただし注意点があって、

  • establish_connection は ConnectionPool を返す
  • そこからさらに connection を取得しないと Dumper に渡せない

具体的に言うと

AR::SD.dump(AR::Base.establish_connection.connection)

になるってことです。

上のコードはこれを避けるためなのか ActiveRecord::Base.connection を直接渡しているんだけど、手元ではうまく動かなかったので、動きを追ったらそうだった、ということでした。

Rails風にDB接続設定を持つPHPアプリのDBをActiveRecordでdump

上の方法で schema.rb は作成できるようになったけど、問題は DBMS 接続情報をどう取得するか。Rails なら database.yml になっているのでそれさえ探せばいいんだけど、この方式になっているフレームワークばかりではない。

具体的に今回のターゲットは Laravel なんだけど、Laravel の場合は大丈夫。

app/config/database.php にある

return array(
  'default'    => xxxx,
  'connection' => array(
    ...
  )
);

の部分に接続情報はまとまっている。この情報だけを取得するための以下のようなコードを用意する。

wrapper_script.php

<?php
print json_encode(require('app/config/database.php'));

これでデータベース接続情報を JSON で stdout に出力できる。こいつを Ruby 側から

JSON.parse(`php wrapper_script.php`)

とすれば Ruby のオブジェクトとして PHP アプリの接続情報を取得できる。あとは Ruby 側で好きに加工すればよい。

※ 先頭の <?php は特に忘れやすいので注意!!!

残りの課題は

  • driver -> adapter 変換
  • dsn -> 個別情報分解

の辺り。

探してみたけど、Ruby には単体の DSN parser はなさそうなので、自分で書いた方が早いかもしれない。それか

larskanis/ruby-odbc: ODBC binding for Ruby

辺りを使うと何か嬉しいことがあるかも。そこは試してませんので悪しからず。

More