Quick Start

There are two ways in. Embed KvSQL Engine in a Rust program, or run the KvSQL DB server and use it from any language over HTTP.

The Engine in a Rust Program

Add the engine as a Git dependency. It has no dependencies of its own.

[dependencies]
kvsql-engine = { git = "https://github.com/softdevstudio/kvsql", tag = "v0.1.0" }

Open a file, write some keys and read them back:

use kvsql_engine::Db;

fn main() -> kvsql_engine::Result<()> {
    let db = Db::open("app.kvsql")?;

    // Several changes, committed together.
    let mut tx = db.begin_write()?;
    tx.put("users", b"42", b"Ada")?;
    tx.put("users", b"43", b"Grace")?;
    tx.commit()?;

    let name = db.get("users", b"42")?;                     // Some(b"Ada")
    let some = db.scan("users", b"40", Some(b"50"), 100)?;  // keys 40 up to 50
    println!("{:?} {}", name, some.len());
    Ok(())
}

Now SQL on the same records. A table is a keyspace with a schema, and each row sits under its primary key:

use kvsql_engine::{Db, sql::Value};

let db = Db::open("app.kvsql")?;
db.execute("CREATE TABLE people (id INTEGER PRIMARY KEY, name TEXT, city TEXT);
            CREATE INDEX people_city ON people(city)", &[])?;
db.execute("INSERT INTO people VALUES (1, 'Ada', 'London'), (2, 'Grace', 'New York')", &[])?;

// The SQL door.
let r = db.execute("SELECT name FROM people WHERE city = ?", &[Value::Text("London".into())])?;

// The key door: the same row, no parsing.
let row = db.get_row("people", &Value::Int(1))?;

// Writes through the key door keep the index right.
let mut tx = db.begin_write()?;
tx.put_row("people", &[Value::Int(3), Value::Text("Alan".into()), Value::Text("London".into())])?;
tx.commit()?;

A write transaction sees its own changes, and dropping it without commit discards them. Readers work on a snapshot of the last commit and never wait for the writer.

The Server and the Shell

Download the archive for your system. It holds kvsqld and kvsql. Start the server on a file:

kvsqld --db app.kvsql            # listens on 127.0.0.1:7878

Use it from the shell:

kvsql -c "CREATE TABLE notes (id INTEGER PRIMARY KEY, body TEXT)"
kvsql -c "INSERT INTO notes VALUES (1, 'first')" -c "SELECT * FROM notes"
kvsql < schema.sql               # run a script

Or from anything that speaks HTTP:

curl -s localhost:7878/sql -d '{"sql":"SELECT body FROM notes WHERE id = ?","params":[1]}'
curl -s localhost:7878/rows/notes/1                         # the key door
curl -s -X PUT localhost:7878/kv/sessions/s1 --data-binary 'hello'
curl -s localhost:7878/kv/sessions/s1

Every request is one transaction, and a write is answered only after it is on disk. Set --token to require a bearer token. There is no TLS, so keep the server on localhost or a private network, or put a proxy in front of it.

The shell also opens a file directly when no server is running:

kvsql --file app.kvsql -c ".keyspaces" -c ".verify"

Next Steps