Skip to content

Commit aeb2d8a

Browse files
committed
Add many new commands and bug fixes (see CHANGELOG.md)
1 parent f27ca46 commit aeb2d8a

File tree

13 files changed

+991
-342
lines changed

13 files changed

+991
-342
lines changed

CHANGELOG.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,30 @@
11
# Changelog
22

3+
## 0.16.0 (2020-08-17)
4+
5+
### New features
6+
7+
* [commands] Add the following Hash COMMANDS: `HDEL, HEXISTS, HGET, HGETALL, HKEYS, HLEN, HMGET, HSET, HSTRLEN, HVALS`
8+
* [commands] Add the following List COMMANDS: `LPUSH, LRANGE, LREM, LSET, LTRIM, RPOP, RPOPLPUSH`
9+
* [commands] Add the following String COMMANDS: `APPEND, MSET, MGET, STRLEN`
10+
* [client] Add `--commands` to view the list of all commands
11+
* [client] Add `--encrypt` and `--decrypt` options to encrypt/decrypt data using a GPG keypair
12+
* [client] Add `--` option to read last argument data from STDIN
13+
14+
### Bug fixes
15+
16+
* Ensure listening on a socket will abort after `*KV_abort` seconds
17+
* Reading frorm a socket shouldn't return "no data" or "unknown data" if there's no data. It should just print an empty string.
18+
* Errors should throw/raise an error with the message, for the client to parse
19+
* Perform more validations on individual commands, ex: ensuring a Key is a list, etc
20+
* Temporarily disabled integrations tests because they cause false/positives
21+
22+
### Misc changes
23+
24+
* Change the way IDENT and AUTH is performed in client and server
25+
* Client doesn't print "OK <name>" anymore for every command
26+
* Simplify much of the kv command processing code
27+
328
## 0.15.1 (2020-07-31)
429

530
* Move the global list of all keys to '%stats%/keys' so it can't be deleted or modified

COMMANDS.md

Lines changed: 287 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,287 @@
1+
2+
# List of commands
3+
4+
Most `COMMANDS` take the exact same arguments, and return the same type of value, as their respective [Redis™ commands](https://redis.io/commands).
5+
6+
| Command | Description |
7+
| ---- | ---- |
8+
| [APPEND](#append) key value | Append a value to a key |
9+
| [BGSAVE](#bgsave) | Asynchronously save the dataset to disk |
10+
| [CLIENT ID](#client-id) | Returns the client ID for the current connection |
11+
| [CLIENT KILL ID](#client-kill-id) id [id ..] | Kill the connection of a client |
12+
| [CLIENT LIST](#client-list) | Get the list of client connections |
13+
| [CONVERT](#convert) | Convert a plaintext database to binary or vice-versa |
14+
| [DEL](#del) key [key ..] | Delete one or more keys |
15+
| [EXISTS](#exists) key [key ..] | Determine if a key exists |
16+
| [GET](#get) key | Get the value of a key |
17+
| [GETSET](#getset) key value | Set the string value of a key and return its old value |
18+
| [HDEL](#hdel) key field [field ..] | Delete one or more hash fields |
19+
| [HEXISTS](#hexists) key field | Determine if a hash field exists |
20+
| [HGET](#hget) key field | Get the value of a hash field |
21+
| [HGETALL](#hgetall) key | Get all the fields and values in a hash |
22+
| [HKEYS](#hkeys) key | Get all the fields in a hash |
23+
| [HLEN](#hlen) key | Get the number of fields in a hash |
24+
| [HMGET](#hmget) key field [field ..] | Get the values of all the given hash fields |
25+
| [HSET](#hset) key field value [field value ..] | Set the string value of a hash field |
26+
| [HSTRLEN](#hstrlen) key field | Get the length of the value of a hash field |
27+
| [HVALS](#hvals) key | Get all the values in a hash |
28+
| [INFO](#info) [section] | Get information and statistics about the server |
29+
| [LINDEX](#lindex) key index | Get an element from a list by its index |
30+
| [LLEN](#llen) key | Get the length of a list |
31+
| [LPOP](#lpop) key | Remove and get the first element in a list |
32+
| [LPOPRPUSH](#lpoprpush) source destination | Remove the first element in a list, append it to another list and return it |
33+
| [LPUSH](#lpush) key element [element ..] | Prepend one or multiple elements to a list |
34+
| [LRANGE](#lrange) key start stop | Get a range of elements from a list |
35+
| [LREM](#lrem) key count element | Remove elements from a list |
36+
| [LSET](#lset) key index element | Set the value of an element in a list by its index |
37+
| [LTRIM](#ltrim) key start stop | Trim a list to the specified range |
38+
| [MGET](#mget) key [key ..] | Get the values of all the given keys |
39+
| [MSET](#mset) key value [key value ..] | Set multiple keys to multiple values |
40+
| [PING](#ping) [message] | Ping the server |
41+
| [RPOP](#rpop) key | Remove and get the last element in a list |
42+
| [RPOLRPUSH](#rpolrpush) source destination | Remove the last element in a list, prepend it to another list and return it |
43+
| [RPUSH](#rpush) key element [element ..] | Append one or multiple elements to a list |
44+
| [SAVE](#save) | Synchronously save the dataset to disk |
45+
| [SET](#set) key value | Set the string value of a key |
46+
| [STRLEN](#strlen) key | Get the length of the value stored in a key |
47+
48+
49+
## APPEND
50+
51+
#### APPEND key value
52+
53+
If key already exists and is a string, this command appends the value at the end of the string.
54+
55+
#### Return values
56+
57+
* **Integer**: the length of the string after the append operation
58+
* **NIL**: if key is not a string or does not exist
59+
60+
#### CLI example
61+
62+
```bash
63+
./client.l --pass yourpass EXISTS mykey
64+
0
65+
./client.l --pass yourpass SET mykey "Hello"
66+
OK
67+
./client.l --pass yourpass APPEND mykey " World"
68+
11
69+
./client.l --pass yourpass GET mykey
70+
Hello World
71+
```
72+
73+
#### PicoLisp example
74+
75+
```picolisp
76+
: (kv-send-data '("EXISTS" "mykey"))
77+
-> 0
78+
: (kv-send-data '("SET" "mykey" "Hello"))
79+
-> "OK"
80+
: (kv-send-data '("APPEND" "mykey" " World"))
81+
-> 11
82+
: (kv-send-data '("GET" "mykey"))
83+
-> "Hello World"
84+
: (kv-send-data '("APPEND" "doesntexist" "test"))
85+
-> NIL
86+
```
87+
88+
## BGSAVE
89+
90+
#### BGSAVE
91+
92+
Save the DB in background.
93+
94+
The KV server forks, the parent continues to serve the clients, the child saves the DB
95+
on disk then exits.
96+
97+
An error is returned if there is already a background save running or if there is another non-background-save process running.
98+
99+
#### Return values
100+
101+
* **String**: `Background saving started` if the `BGSAVE` started correctly or `Error: DB is locked for writing` if the DB is locked.
102+
103+
#### CLI example
104+
105+
```bash
106+
./client.l --pass yourpass BGSAVE
107+
Background saving started
108+
```
109+
110+
#### PicoLisp example
111+
112+
```picolisp
113+
: (kv-send-data '("BGSAVE"))
114+
-> "Background saving started"
115+
```
116+
## CLIENT ID
117+
118+
#### CLIENT ID
119+
120+
The command just returns the ID of the current connection. Every connection ID has certain guarantees:
121+
122+
1. It is never repeated, so if `CLIENT ID` returns the same number, the caller can be sure that the underlying client did not disconnect and reconnect the connection, but it is still the same connection.
123+
2. The ID is monotonically incremental. If the ID of a connection is greater than the ID of another connection, it is guaranteed that the second connection was established with the server at a later time.
124+
125+
#### Return values
126+
127+
* **Integer**: The id of the client.
128+
129+
#### CLI example
130+
131+
```bash
132+
./client.l --pass yourpass CLIENT ID
133+
1
134+
./client.l --pass yourpass CLIENT ID
135+
2
136+
```
137+
138+
#### PicoLisp example
139+
140+
```picolisp
141+
: (kv-send-data '("CLIENT" "ID"))
142+
-> 3
143+
```
144+
145+
## CLIENT KILL ID
146+
147+
#### CLIENT ID id [id ..]
148+
149+
The command allows to end one or more client connections by their unique `ID` field.
150+
151+
#### Return values
152+
153+
* **String**: the number of clients connections ended.
154+
155+
#### CLI example
156+
157+
```bash
158+
./client.l --pass yourpass CLIENT KILL ID 2
159+
1
160+
```
161+
162+
#### PicoLisp example
163+
164+
```picolisp
165+
: (kv-send-data '("CLIENT" "KILL" "ID" "2"))
166+
-> 0
167+
```
168+
169+
## CLIENT LIST
170+
171+
#### CLIENT LIST
172+
173+
Returns information and statistics about the client connections server in a mostly human readable format.
174+
175+
The KV server forks, the parent continues to serve the clients, the child saves the DB
176+
on disk then exits.
177+
178+
An error is returned if there is already a background save running or if there is another non-background-save process running.
179+
180+
#### Return values
181+
182+
* **Multi-line String**: a unique string, formatted as follows:
183+
* One client connection per line (separated by `\n` newline/linefeed)
184+
* Each line is composed of a succession of `property=value` fields separated by a space character.
185+
186+
Here is the meaning of the fields:
187+
188+
* `id`: a unique auto-incrementing 64-bit client ID
189+
* `pid`: process ID of the forked child handling the request
190+
* `name`: name set by the client, with `--name` or autogenerated
191+
* `addr`: address of the client
192+
* `port`: source port of the client
193+
* `fd`: file descriptor corresponding to the socket
194+
195+
#### CLI example
196+
197+
```bash
198+
./client.l --pass yourpass CLIENT LIST
199+
id=1 pid=16929 name=4AF35825 addr=::1 port=49774 fd=7
200+
```
201+
202+
#### PicoLisp example
203+
204+
```picolisp
205+
: (kv-send-data '("CLIENT" "LIST"))
206+
-> "id=2 pid=10019 name=79738D13 addr=::1 port=50956 fd=7"
207+
```
208+
209+
## CONVERT
210+
211+
#### CONVERT
212+
213+
Convert a plaintext database to binary or vice-versa.
214+
215+
The KV server by default saves data on disk in plaintext format, which can be modified by hand by anyone with practically no PicoLisp knowledge. The disadvantage with plaintext is its on-disk footprint is quite large compared to binary. For small datasets the difference is negligible, but it could also affect performance when first loading the database.
216+
217+
While the server is running, it is possible to dump the database to disk using a different format, for example: if it's currently saving in plaintext, `CONVERT` will dump it to disk in binary. All future saves will also be in binary until the server is restarted, or until another `CONVERT` command is sent (which would convert it back to plaintext).
218+
219+
Using the CLI tool:
220+
221+
* The default filename for binary format is `kv.bin`.
222+
* The default filename for plaintext format is `kv.db`.
223+
224+
Using the PicoLisp server library `libkv.l`:
225+
226+
The database filename can be changed through the `*KV_db` variable, example `(setq *KV_db "/path/to/db.bin")`
227+
228+
* To enable `binary` saving in PicoLisp, use `(on *KV_binary)`
229+
* To disable `binary` saving in PicoLisp, use `(off *KV_binary)`
230+
231+
#### Return values
232+
233+
* **String**: `OK` if the database was converted successfully.
234+
235+
#### CLI example
236+
237+
```bash
238+
./client.l --pass yourpass CONVERT
239+
OK
240+
```
241+
242+
#### PicoLisp example
243+
244+
```picolisp
245+
: (kv-send-data '("CONVERT"))
246+
-> "OK"
247+
```
248+
249+
## DEL
250+
251+
#### DEL key [key ..]
252+
253+
Removes the specified keys. All given keys are removed whether they exist or not.
254+
255+
#### Return values
256+
257+
* **Integer**: The number of keys that were removed.
258+
259+
#### CLI example
260+
261+
```bash
262+
./client.l --pass yourpass SET key1 "Hello"
263+
OK
264+
./client.l --pass yourpass SET key2 "World"
265+
OK
266+
./client.l --pass yourpass DEL key1 key2 key3
267+
3
268+
```
269+
270+
#### PicoLisp example
271+
272+
```picolisp
273+
: (kv-send-data '("SET" "key1" "Hello"))
274+
-> "OK"
275+
: (kv-send-data '("SET" "key2" "World"))
276+
-> "OK"
277+
: (kv-send-data '("DEL" "key1" "key2" "key3"))
278+
-> 3
279+
```
280+
281+
# License
282+
283+
This documentation copies in part the [Redis documentation](https://github.com/redis/redis-io), distributed under the [Creative Commons Attribution-ShareAlike 4.0 International license](https://creativecommons.org/licenses/by-sa/4.0/) license, and is modified to match the [PicoLisp KV](https://github.com/aw/picolisp-kv) library code.
284+
285+
This documentation is licensed under [Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)](https://creativecommons.org/licenses/by-sa/4.0/).
286+
287+
Copyright (c) 2020 Alexander Williams, On-Prem <license@on-premises.com>

0 commit comments

Comments
 (0)