ot2sy39's note

twitter 140文字じゃ書けないときの外部エントリみたいな

awkでsqlite3.exeの即席フロントエンドを作った

Windowsでsqlite3を使うにはRubyPHPなどから適当なライブラリ経由でアクセスする必要があると思い込んでいて、職場のリソース逼迫シンクライアントだと環境整えるハードル高いと感じてたのだが、↓のエントリをみて、sqlite3.exeとgawk.exeの2個だけでいけるじゃんと気づいた。

d.hatena.ne.jp

というわけで手元にあったsqlite3のDBを操作するラッパーというか即席フロントエンドをawkで作ってみた。

BEGIN {
  db = "test.db"
  command = "sqlite3 -header -column " db " \" %s \""
  printf "command? "
}

/^\.exit$/  { exit }

/^!/  {
    caution=1
    sub(/^[!]/, "")
}

/^[0-9]+$/  {
    sql=sprintf("select * from testtable where id=%s", $1)
}

/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/ {
    sql=sprintf("select * from testtable where ip=%s", $1)
}

/^[a-zA-Z][a-zA-Z0-9_-]+$/ {
    sql=sprintf("select * from testtable where host like \"%s%\"", $1)
}

sql!="" {
    print sql
    if(caution) {
        printf("execute? (y/n) ")
        getline can_execute
        if(can_execute ~ /^[Yy]/)
            system(sprintf(command, sql))
    } else {
        system(sprintf(command, sql))
    }
    caution==0
    sql=""
    caution=0
    printf "command? "
}

骨子はこんな感じ。自分用なので正規表現は超手抜き。実行はgawk.exe -f test.awkてな感じで実行するだけ。

サンプルはちょっとしたネットワーク管理表を操作するイメージコード。プロンプトで数値を入れると該当idのレコードを、ドット区切りの4つの数値を入れるとipアドレスとみなしてそのIPを持つホストのレコードを、英字で始まる1単語を入れるとその単語に前方一致するホストのレコードを表示する。

実使用しているコードはテーブルも1つじゃないし、もう少し複雑なクエリを出す構文なんかも用意してるけど割愛。常用するクエリをどんどん取り入れてやると捗る。

不安なときは入力の先頭に!をつけると、実行前に本当に実行するか聞いてくるようにした。

まあSQL文を手入力するような工程はあまりないだろうけど、手元のちょっとしたデータ整理用にsqlite3使うにはそこそこ便利で、即席な割にいいもの作った感がある。

言語設計者はこれを一億倍したくらいの充足感あるんだろーなー。