Repository navigation
Releases: QuantyRoot/QuantyDatabase
Release list
QuantyDB 0.4.0 — the first one you can install
QuantyDB 0.4.0 is the first release you can install.
Until now there was a repository and a cargo build. Now there are
binaries for six platforms, signed apt and dnf repositories, a Homebrew
formula, an AUR package, a one-line installer and a way to update. The
status word moves from pre-alpha to alpha for that reason and no other:
nothing got safer overnight, but there is finally something to install.
Install
curl -fsSL https://quantyroot.github.io/QuantyDatabase/install.sh | sh
Debian, Ubuntu, Raspberry Pi OS:
curl -fsSL https://quantyroot.github.io/QuantyDatabase/gpg.key \
| sudo gpg --dearmor -o /usr/share/keyrings/quantydb.gpg
echo "deb [signed-by=/usr/share/keyrings/quantydb.gpg] \
https://quantyroot.github.io/QuantyDatabase/apt stable main" \
| sudo tee /etc/apt/sources.list.d/quantydb.list
sudo apt update && sudo apt install quantydb
Fedora, RHEL, openSUSE:
sudo curl -fsSL https://quantyroot.github.io/QuantyDatabase/quantydb.repo \
-o /etc/yum.repos.d/quantydb.repo
sudo dnf install quantydb
macOS and Linux with Homebrew:
brew tap quantyroot/quantydb https://github.com/QuantyRoot/QuantyDatabase
brew install quantydb
Arch: yay -S quantydb-bin. From source: cargo install quantydb-cli,
which needs Rust 1.89 and nothing else.
x86_64 and arm64 on Linux, both architectures on macOS, x86_64 on
Windows. Each binary is built and tested on the machine it is for; none
of them is cross compiled.
What is new
The server closes when you ask it to. It had a shutdown flag that
nothing ever set, so every stop was a crash. Recoverable, exercised by a
few thousand kills on every push, and not the same as closing:
connections were dropped mid-answer and the file lock was taken back by
the kernel rather than given up. SIGINT, SIGTERM and SIGHUP now set that
flag, and the test asserts the part that would rot quietly, which is that
the database opens afterwards.
quantydb setup writes a database, a private token file and
optionally a systemd unit that runs as a person rather than as root. It
starts nothing and overwrites nothing. quantydb uninstall takes the
service and the binary away and never the database or the token file, and
only removes a unit that runs the binary you are asking, so a copy in a
downloads folder cannot take out the one you installed.
quantydb update --file installs a binary you already have, keeping
the old one beside it. It refuses a file shorter than its own headers
describe, which is what half a download looks like. Fetching a release
over the network needs TLS, which is written here rather than pulled in
and is not written yet.
A kqueue backend for the reactor, so its tests run on macOS rather
than only compiling there.
Search, blobs and index suggestions from the phases before this one:
a suggestion measured 167x against the scan it replaces.
What this does not do yet
The wire is not encrypted. Tokens cross it in the clear on every
connection, so anyone who can watch the traffic can take one and use it
again. TLS is a phase of its own. Keep quantydb serve on loopback or
behind wireguard, an ssh tunnel or a TLS proxy. The server says so every
time it starts, and louder when the address is not a loopback one.
quantydb serve is Linux only. The reactor has a kqueue backend and
its tests pass on macOS, but no kernel except Linux spreads accepted
connections across workers: two hundred connections went 0/0/0/200 across
reuseport listeners on Darwin and 0/0/22/178 across workers sharing one,
against 39/48/54/59 on Linux. A macOS server would run on one worker
whichever shape it picked. The tool, the library and both query languages
run everywhere.
The formats will still change before 1.0. Old formats are not
migrated. This is alpha, and it says so on the tin.
By the numbers
| Dependencies | 0, and the lock file is checked on every push |
| Tests | 580 functions, 14 jobs, 3 operating systems |
| Fuzzing per push | 4 fuzzers, 10 minutes each |
| Crash testing per push | 2300 kill -9s, every file recovered |
| Soak | 1.8 million statements in 30 minutes, 0 failed |
| Idle connections | 10000 held, under 1 kB of memory each |
Full changes in CHANGELOG.md. Why anything is the way it
is, with what it cost, in DECISIONS.md.
v0.2.0: SQL, the SQLite importer, and no dependencies
Phase 4 is complete: seven of seven acceptance criteria, each backed by a
test rather than a claim.
What is new since v0.1.1
A SQL front end alongside QQL, lowering onto the same plans, so the
planner, executor and transaction rules are shared. Inner and left joins
with three probe strategies, and begin/commit/rollback across
statements. SQL this dialect does not support is refused by name, with a
position, in a golden test covering 33 constructs.
A SQLite importer that reads the file format directly. No SQLite
library, no C toolchain, no ffi. It reads what SQLite writes, including
tables without rowids, uncheckpointed write-ahead logs, text in utf-16, and
columns added by a later alter table. It runs in two passes: the first
decides what the database becomes and writes nothing, the second executes
that decision, so problems arrive as a report a minute in rather than as a
failure ten minutes into writing.
A command line tool.
quanty import app.sqlite app.qdb
quanty run app.qdb "get users { name } where score > 100"No dependencies. The checksum and the locks under the storage core are
written out rather than pulled in, so the lock file holds this workspace and
nothing else. What that costs was measured rather than assumed: 1.8
microseconds per 4 KiB page against 1.0 with the CPU instruction. See
ADR-020.
The acceptance runs
Each an hour, on one core:
- SQL parser: 4244088000 inputs parsed, no panic, no broken roundtrip
- SQLite reader: 1831872 damaged and hostile files read, 12 billion cells,
no panic and no wrong data - chinook: 15607 rows imported and compared value for value against the
source, through a reader that is itself checked against SQLite's own
digests
What this is not yet
Speed is unmeasured. There is no benchmark against SQLite or anything else
in this repo, so no claim is made about performance. There is no server, no
network protocol and no client for any language other than Rust; that is
phase 5.