
-----------------------------------------------------------------
handlersocketの通信プロトコル

-----------------------------------------------------------------
構文

・コマンド行は改行(LF)で終わる。
・コマンド行は複数のトークンからなり、トークン間はTABで区切られる。
・トークンはNULLトークンか、文字列トークンのいずれか。
・NULLトークンは単一のNUL文字であらわされる。
・文字列トークンは、0バイト以上の文字列であらわされる。ただし0x10
  未満の文字については0x01を前置し、0x40を加えたコードであらわさ
  れる。それ以外の文字はその文字自身のコードであらわされる。

-----------------------------------------------------------------
リクエストとレスポンス

・接続が確立した直後の状態では、まずクライアントがコマンド行を送
  る。(リクエスト)
・サーバはクライアントが送ったリクエストと丁度同じ数のコマンド行
  を返す。(レスポンス)
・リクエストはパイプライン化してよい。つまりクライアントは前に
  送ったリクエストに対する返事を待たずに次のリクエストを送っても
  よい。

-----------------------------------------------------------------
リクエスト

・open_index命令は次のような構文を持つ。
        'P' indexid dbname tablename indexname fieldlist
  indexidは開いている索引に付けられる番号で、同一接続上で後に実行
  する命令の、対象索引を指定するために使われる。dbname、tablename、
  indexnameはそれぞれ開きたいDB、テーブル、索引の名前。索引の名前
  として"PRIMARY"を指定するとプライマリキーが開かれる。fieldlist
  はカンマ区切りの列名のリスト。
・find命令は次のような構文を持つ。
        indexid op nflds v1 ... vn limit offset
  indexidは実行対象の索引を指定する。opは索引検索の演算子(後述)。
  v1からvnは可変長で、その個数はnflds。nfldsはindexidで指定された
  open_index命令のindexnameの索引のfieldlistのフィールド数に等し
  いか小さくなくてはならない。m2からmkは可変長で、その個数は
  indexidで指定されたopen_index命令が発行された際のfieldlistに一
  致しなければならない。コマンド行のlimit以降は省略できる。limit
  とoffsetは、検索条件に合致する列のうちレスポンスに返す列数の上
  限と、スキップする列数。limitとoffsetを省略した場合はそれぞれ1
  と0が指定されたときと同じ動作をする。find命令はレスポンスとして、
  条件に合致した列のリストを返す。opとして指定できる演算子は次の
  とおり。
      '='       -  v1 ... vnと一致するものを取得
      '>'       -  v1 ... vnより大きいものを昇順に取得
      '>='      -  v1 ... vnに一致するか大きいものを昇順に取得
      '<'       -  v1 ... vnより小さいものを降順に取得
      '<='      -  v1 ... vnに一致するか等しいものを降順に取得
  nfldsが1より大きい(v1 ... vnが2個以上)ときは辞書式順序で比較さ
  れる。
・find_modify命令は次のような構文を持つ。
        indexid op nflds v1 ... vn limit offset modop m1 ... mk
  modopより前の部分はfind命令と同等で、これによって操作対象の行を
  指定する。その操作対象の行に対しmodopで指定された変更処理を実行
  する。m1 ... mkは可変長で、省略できる。modopは次いずれか。
      'U'       -  indexidで指定されたopen_index命令のfieldlist列
                   の内容を、m1 ... mkの値で更新する。
      'D'       -  対象の行を削除する。m1 ... mkの値は無視される。
・insert命令はのような構文を持つ。
        indexid '+' nflds v1 ... vn
  indexidで指定されたテーブルに、列を挿入する。v1 ... vnは可変長
  で、その個数はnflds。nfldsはindexidで指定されたopen_index命令の
  indexnameの索引のfieldlistのフィールド数に等しいか小さくなくて
  はならない。

-----------------------------------------------------------------
レスポンス

・open_index命令が成功したとき、レスポンスは次の構文を持つ。
        '0' '1'
・find命令が成功したとき、レスポンスは次の構文を持つ。
        '0' nflds v1 ... vn
  nfldsは結果セットの列の数をあらわす。v1 ... vnは可変長で、その
  長さはnfldsの整数倍。v1 ... vnは空のこともあり、それは条件に合
  致するレコードが存在しなかったことをあらわす。結果セットが複数
  行になったときはv1 ... vnの長さがnfldsの2倍以上となり、最初の
  行から順にv1 ... vnにセットされる。
・modify命令が成功したとき、レスポンスは次の構文を持つ。
        '0' '1' nummod
  nummodは変更が施された行数。nummodが0のときは変更された行が無
  かったことをあらわす。
・insert命令が成功したとき、レスポンスは次の構文を持つ。
        '0' '1'
・命令が失敗したとき、レスポンスは命令に関わらず次の構文を持つ。
        err '1' message
  errは0以外の数値で、エラーコードをあらわす。messageは人間可読な
  エラーメッセージ。ただしmessageが無いこともある。

