Skip to content

Quickstart ​

This page shows the first ten minutes with kinedb. You start one server and connect with the SQL shell. You create a table, change it, and read it. Then you read an old version of the table.

You need the kinedb binary or Docker. Get kinedb tells how to get them.

1. Start one server ​

With the binary:

sh
KINEDB_ROOT_PASSWORD='choose-a-password' ./kinedb --port 4820 --data-dir ./data

Or with Docker:

sh
docker run -d --name kinedb -p 4820:4820 -v kinedb-data:/data \
  -e KINEDB_ROOT_PASSWORD='choose-a-password' \
  git.kinedb.com/kinedb/kinedb:latest
  • The server keeps its data in ./data. In Docker, the data is in the volume kinedb-data.
  • The first start creates the user root, with the password of KINEDB_ROOT_PASSWORD.
  • Clients must log in by default. See Authentication.
  • The server writes log lines to its terminal. Each line has the form [kdtrace ts=<ms> <target> <level>] <message>.

When the server is ready, GET /health answers 200:

sh
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:4820/health
200

2. Connect with the SQL shell ​

The SQL shell logs in as root. It reads the password from KINEDB_ROOT_PASSWORD, and it never asks for a password.

sh
KINEDB_ROOT_PASSWORD='choose-a-password' ./kinedb --connect 127.0.0.1:4820

In Docker, the container already has the password:

sh
docker exec -it kinedb /app/kinedb --connect 127.0.0.1:4820

The shell answers:

KineDB v0.0.2 — Connected to 127.0.0.1:4820
typed rows: on
Type SQL statements, '\q' to exit, TAB for completions.

kinedb@127.0.0.1:4820>

Type \q to exit. With a wrong password, the shell writes this line and exits with 1:

Failed to log in to 127.0.0.1:4820 as 'root': Auth: invalid username or password

To run one statement and exit, add -e:

sh
KINEDB_ROOT_PASSWORD='choose-a-password' ./kinedb --connect 127.0.0.1:4820 -e "SHOW DATABASES"
database
--------
default
(1 rows)
Time: 2.78 ms

3. Create a table ​

Type each statement at the kinedb@127.0.0.1:4820> prompt. The primary key can be part of the column definition:

sql
CREATE TABLE users (id INT PRIMARY KEY, name TEXT);
OK
Time: 4.79 ms

4. Insert rows ​

sql
INSERT INTO users (id, name) VALUES (1, 'Ada'), (2, 'Grace'), (3, 'Linus');
OK: 3 row(s) inserted
Time: 160 µs

5. Read rows ​

sql
SELECT * FROM users WHERE id >= 2;
id   | name
-----+------
2    | Grace
3    | Linus
(2 rows)
Time: 140 µs

6. Change and delete rows ​

sql
UPDATE users SET name = 'Grace Hopper' WHERE id = 2;
OK: 1 row(s) updated
Time: 86 µs
sql
DELETE FROM users WHERE id = 3;
OK: 1 row(s) deleted
Time: 47 µs
sql
SELECT * FROM users;
id   | name
-----+-------------
1    | Ada
2    | Grace Hopper
(2 rows)
Time: 39 µs

7. Create an index ​

An index makes a read on a column other than the primary key fast:

sql
CREATE INDEX users_name ON users (name);
OK
Time: 12.77 ms
sql
SELECT * FROM users WHERE name = 'Ada';
id   | name
-----+-----
1    | Ada
(1 rows)
Time: 168 µs

EXPLAIN shows that the read uses the index:

sql
EXPLAIN SELECT * FROM users WHERE name = 'Ada';
step | operation           | detail
-----+---------------------+-----------------------------------------------------------
1    | index scan (prefix) | index: users_name on users (name) WHERE name = Text("Ada")
2    | pk lookup           | fetch rows by primary key (id)
(2 rows)
Time: 40 µs

8. Read an old version ​

Every commit keeps the old data readable. AS OF HEAD reads the newest commit, and AS OF HEAD~1 reads the commit before it. See Time travel and history.

Change a row, to make a new version:

sql
UPDATE users SET name = 'Ada Lovelace' WHERE id = 1;
OK: 1 row(s) updated
Time: 5.46 ms

The newest version has the new name:

sql
SELECT * FROM users;
id   | name
-----+-------------
1    | Ada Lovelace
2    | Grace Hopper
(2 rows)
Time: 65 µs

The version before the last change has the old name:

sql
SELECT * FROM users AS OF HEAD~1;
id   | name
-----+-------------
1    | Ada
2    | Grace Hopper
(2 rows)
Time: 144 µs

9. Use kinedb from an application ​

  • Over HTTP, POST /login gives a token, and POST /sql runs SQL with the token.

    sh
    TOKEN=$(curl -s -X POST http://127.0.0.1:4820/login \
      -d '{"username": "root", "password": "choose-a-password"}' | jq -r .token)
    curl -s -X POST http://127.0.0.1:4820/sql \
      -H "Authorization: Bearer $TOKEN" --data-binary 'SELECT * FROM users WHERE id = 1'
    {"columns":["id","name"],"count":1,"data":[[1,"Ada Lovelace"]],"elapsed_us":134,"type":"rows"}

    Each request runs one statement, so USE has no effect over HTTP. To use an other database, write mydb.users in the SQL, or send POST /sql?db=mydb.

  • A client library: JavaScript or Python.

  • The engine inside your application, with no server: Embedded database (JavaScript), or the kinedb crate in Rust.

Where to go next ​