The shell

Open a database file and run FenecQL on it, one statement at a time. It is the quickest way to learn the language, and to look inside a file a server or an app keeps.

Quickstart

fenec comes beside fenec-server in every way of installing it (Install), and the steps below need nothing else. Give it a file of its own, scratch.fenec here: not one a server has open, such as the Quickstart's notes.fenec, since two processes writing one file would corrupt it.

  1. Open a file. It is made if there is none.

    fenec scratch.fenec
    prints
    fenecdb 0.1.12 — scratch.fenec
    `.help` for help, `.quit` to exit
  2. At the prompt, make a collection, each field typed and the ones you filter, order and search by indexed, and write two rows. A write ends at a ;.

    fenec> create collection notes (title text @text, year int @sorted)
    collection `notes` created
    fenec> put notes [{title: "Dunes", year: 2021}, {title: "Night at the oasis", year: 2024}];
    2 records (133.38µs)
  3. Read them back by a filter and an order, then search the words, a typo and all. The timings are yours.

    fenec> get notes where year >= 2020 order year desc
    id  title               year
    --  ------------------  ----
    2   Night at the oasis  2024
    1   Dunes               2021
    (2 rows, 149.12µs)
    fenec> get notes select title match title "oasys" fuzzy
    title               _score
    ------------------  ------
    Night at the oasis  0.6224
    (1 rows, 27.33µs)
    fenec> .quit

The file is the database: fenec scratch.fenec opens it again with its rows, and fenec-server --file scratch.fenec serves it once the shell has quit. FenecQL is a tour of the language in this shell, from a first write to a lookup and a total.

Running statements

fenec scratch.fenec                          # interactive
fenec scratch.fenec -c 'get notes limit 5'   # one statement, then exit
echo 'get notes' | fenec scratch.fenec       # from a pipe
fenec scratch.fenec < seed.fenecql           # a script
fenec --version                              # fenec <version>, and nothing opened

--version, or -V, prints the shell's version on stdout and exits 0 without opening a file; fenec version, with no dashes, opens a file named version, as any other word does. Releases up to 0.1.12 have no --version: the first line an interactive session prints names theirs.

Inside the shell, a line that begins with a . is the shell's own:

CommandWhat it does
.helpthe summary of FenecQL and of these commands
.tablesthe collections
.statsstorage statistics
.functionsthe registered functions and plugins
.save <path>writes a snapshot of the database to a file
.checkpointrewrites the file and saves the vector graphs in it, so the next open is fast
.quitexits

Statements over several lines

A statement may run over several lines, and the shell runs it only once nothing after it can go on with it. Typed, a read or a schema change written on one line runs at Enter. A write, and a read written over several lines, wait for the next line: one that goes on with them — where, order, and — joins them, and an empty line or another statement runs them first. A ; after a statement runs it at once. So del notes with where id = 3 on the line under it deletes one row. A . command leaves a waiting statement waiting — .tables to look a name up before the where — and .quit leaves it unrun.

Ending each write with a ;, as the session above does, is the habit that behaves the same everywhere, including in releases up to 0.1.10: they run every line whose brackets close, so there del notes deletes every row before a where under it is refused.

How a pipe, a paste and -c are read

Piped from a file, a statement runs once the next one begins, and a paste is read the same way, its lines all there at once — a . command in either waits behind the statement before it, and runs once that has. -c reads its text whole, as POST /query does, so a text that does not parse runs nothing. A line that begins no statement — a where after a read that already ran at Enter, a wher mistyped, a clause written past a ; — is refused, and so is the statement before it, which it may have meant to go on with: del notes; where id = 3 deletes nothing.

A paste the terminal delivers in pieces further apart than 40 ms is read as typed lines, and a pasted statement whose last line has no newline yet waits for Enter like a typed one.

What else the program does

The same fenec is the tool for a file or a server beyond the prompt. fenec --help lists each with its flags.

  • fenec import copies a SQLite file or a PostgreSQL table into a collection, and --follow keeps a PostgreSQL copy up to date: Import.
  • fenec backup, archive, restore, prune and verify take a running server whole, keep its writes and rebuild it as it stood at a moment: Replication.
  • fenec types writes TypeScript, Python, Go or C# types from a database file: TypeScript.
  • fenec mcp serves a file, or a server, to an agent over stdio: Agents and MCP.