2
----------------------------------------------------------------------------
3
The HandlerSocket protocol
5
----------------------------------------------------------------------------
8
- The HandlerSocket protocol is line-based. Each line ends with LF(0x0a).
9
- Each line consists a concatenation of tokens separated by HT(0x09).
10
- A token is either NULL or an encoded string. Note that you need to
11
distinguish NULL from an empty string, as most DBMs does so.
12
- NULL is expressed as a single NUL(0x00).
13
- An encoded string is a string with the following encoding rules.
14
- Characters in the range [0x10 - 0xff] are not encoded.
15
- A character in the range [0x00 - 0x0f] is prefixed by 0x01 and
16
shifted by 0x40. For example, 0x03 is encoded as 0x01 0x43.
17
- Note that a string can be empty. A continuation of 0x09 0x09 means that
18
there is an empty string between them. A continuation of 0x09 0x0a means
19
that there is an empty string at the end of the line.
21
----------------------------------------------------------------------------
24
- The HandlerSocket protocol is a simple request/response protocol. After a
25
connection is established, the client side sends a request, and then the
26
server side sends a response.
27
- A request/response consists of a single line.
28
- Requests can be pipelined; That is, you can send multiple requests (ie.
29
lines) at one time, and receive responses for them at one time.
31
----------------------------------------------------------------------------
34
The 'open_index' request has the following syntax.
36
P <indexid> <dbname> <tablename> <indexname> <columns>
38
- <indexid> is a number in decimal.
39
- <dbname>, <tablename>, and <indexname> are strings. To open the primary
40
key, use PRIMARY as <indexname>.
41
- <columns> is a comma-separated list of column names.
43
Once an 'open_index' request is issued, the HandlerSocket plugin opens the
44
specified index and keep it open until the client connection is closed. Each
45
open index is identified by <indexid>. If <indexid> is already open, the old
46
open index is closed. You can open the same combination of <dbname>
47
<tablename> <indexname> multple times, possibly with different <columns>.
48
For efficiency, keep <indexid> small as far as possible.
50
----------------------------------------------------------------------------
53
The 'find' request has the following syntax.
55
<indexid> <op> <vlen> <v1> ... <vn> <limit> <offset>
57
- <indexid> is a number. This number must be an <indexid> specified by a
58
'open_index' request executed previously on the same connection.
59
- <op> specifies the comparison operation to use. The current version of
60
HandlerSocket supports '=', '>', '>=', '<', and '<='.
61
- <vlen> indicates the length of the trailing parameters <v1> ... <vn>. This
62
must be smaller than or equal to the number of index columns specified by
63
specified by the corresponding 'open_index' request.
64
- <v1> ... <vn> specify the index column values to fetch.
65
- <limit> and <offset> are numbers. These parameters can be omitted. When
66
omitted, it works as if 1 and 0 are specified.
68
----------------------------------------------------------------------------
69
Updating/Deleting data
71
The 'find_modify' request has the following syntax.
73
<indexid> <op> <vlen> <v1> ... <vn> <limit> <offset> <mop> <m1> ... <mk>
75
- <mop> is either 'U' (update) or 'D' (delete).
76
- <m1> ... <mk> specifies the column values to set. The length of <m1> ...
77
<mk> must be smaller than or equal to the length of <columns> specified by
78
the corresponding 'open_index' request. If <mop> is 'D', these parameters
81
----------------------------------------------------------------------------
84
The 'insert' request has the following syntax.
86
<indexid> '+' <vlen> <v1> ... <vn>
88
- <vlen> indicates the length of the trailing parameters <v1> ... <vn>. This
89
must be smaller than or equal to the length of <columns> specified by the
90
corresponding 'open_index' request.
91
- <v1> ... <vn> specify the column values to set. For columns not in
92
<columns>, the default values for each column are set.
94
----------------------------------------------------------------------------
97
HandlerSocket returns a response of the following syntax for each request.
99
<errorcode> <numcolumns> <r1> ... <rn>
101
- <errorcode> indicates whether the request has successfully executed or not.
102
'0' means success. Non-zero means an error.
103
- <numcolumns> indicates the number of columns of the result set.
104
- <r1> ... <rn> is the result set. The length of <r1> ... <rn> is always a
105
multiple of <numcolumns>. It is possible that <r1> ... <rn> is empty.
107
If <errorcode> is non-zero, <numcolumns> is always 1 and <r1> indicates a
108
human-readable error message, though sometimes <r1> is not provided.
110
----------------------------------------------------------------------------
111
Response for 'open_index'
113
If 'open_index' is succeeded, HandlerSocket returns a line of the following
118
----------------------------------------------------------------------------
121
If 'find' is succeeded, HandlerSocket returns a line of the following
124
0 <numcolumns> <r1> ... <rn>
126
- <numcolumns> always equals to the length of <columns> of the corresponding
127
'open_index' request.
128
- <r1> ... <rn> is the result set. If N rows are found, the length of <r1>
129
... <rn> becomes ( <numcolumns> * N ).
131
----------------------------------------------------------------------------
132
Response for 'find_modify'
134
If 'find_modify' is succeeded, HandlerSocket returns a line of the following
139
- <nummod> is the number of modified rows.
141
----------------------------------------------------------------------------
142
Response for 'insert'
144
If 'insert' is succeeded, HanderSocket returns a line of the following