2018/02/05

ばーてぃかるぱみゅぱみゅあげいん!!! Text::VerticalTable

昔、App::YG っていうモジュールでログを MySQL の \G のごとくバーティカルに表示する yg ってコマンドを書いたことがあったんだけど、そのコマンドでは例えば、以下のようなことができます。

$ yg apache_log
******************** 1 ********************
     Host: 127.0.0.1
    Ident: -
 Authuser: -
     Date: 30/Sep/2012:12:34:56 +0900
  Request: GET /foo HTTP/1.0
   Status: 200
    Bytes: 123
  Referer: http://example.com/foo
UserAgent: Mozilla/5.0

******************** 2 ********************
     Host: 127.0.0.1
    Ident: -
 Authuser: -
     Date: 30/Sep/2012:12:34:57 +0900
  Request: GET /bar HTTP/1.0
   Status: 200
    Bytes: 124
  Referer: http://example.com/bar
UserAgent: Mozilla/5.1

んで、それから5年くらいたって、このたび DBIx::QueryLog の explain 結果を同じ感じに縦表示したくていろいろいじってたんですが、Text::ASCIITable だとちょっとヘッダが消しきれなかったり無駄表示が気になってしまって(実は頑張れば罫線消せるけど)、キーバリュー構造のテーブルを簡単に作れるモジュールを新たに書きました。

Text::VerticalTable

こんな感じです。

use Text::VerticalTable;

my $t = Text::VerticalTable->new;
$t->setHead('explain result');
$t->addRow(id => 1);
$t->addRow(select_type => 'SIMPLE');
$t->addRow(table => 'foo');

print $t;

# Result:
********** 1. explain result **********
         id: 1
select_type: SIMPLE
      table: foo

ヘッダ行の見た目が決め打ち気味なのでちょっといじれるようにしたいと思ったりしましたがいったんここまでで CPANize しました。

DBIx::QueryLog の sub _explain でコードリファレンス返してるあたりを以下のような感じに書き換えると、

return sub {
    my %args = @_;

    return $sth->fetchall_arrayref(+{}) unless defined $args{print} and $args{print};

    require Text::VerticalTable;
    my $t = Text::VerticalTable->new;
    $t->setHead('explain result');
    my @cols = @{$sth->{NAME}};
    for my $records (@{$sth->fetchall_arrayref}) {
        my $count = 0;
        for my $value (@{$records}) {
            $t->addRow([$cols[$count], defined($value) ? $value : 'NULL']);
            $count++;
        }
    }

    return $t;
};

以下のような感じで explain が出るようになります。

********** 1. explain result **********
           id: 1
  select_type: SIMPLE
        table: group
   partitions: NULL
         type: ref
possible_keys: user_id
          key: user_id
      key_len: 8
          ref: const
         rows: 2
     filtered: 50
        Extra: Using index condition; Using where

最&高

サイト内検索