Skip to content

victormeloasm/frogdb

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FrogDB logo

FrogDB

SQLite made scriptable for shell programmers.

A tiny, practical, native C++23 CLI for people who are tired of using fragile .txt files as databases in shell scripts.

License: MIT C++23 SQLite Shell friendly


What is FrogDB?

FrogDB is a command-line SQLite tool designed for shell programmers.

It gives Bash, Shell and automation scripts a clean database interface without forcing you to write raw SQL for every tiny task.

Instead of this:

grep "^victor:" users.txt | cut -d: -f2

Use this:

EMAIL=$(frogdb app.db get users.email name=Victor --raw)
echo "$EMAIL"

FrogDB is for that moment when a .txt, .csv, .conf or improvised log file has become too fragile, but using a full database client still feels too heavy.

It is intentionally simple:

one binary
one SQLite file
shell-friendly output
scriptable commands
no database server required

GitHub description

Recommended repository description:

SQLite made scriptable for shell programmers.

Alternative slogan:

Stop grepping text files. Query your scripts.

Features

  • Native C++23 command-line tool.
  • SQLite backend by default.
  • Optional encrypted database support through SQLCipher.
  • Built for Bash/Shell automation.
  • Output modes for humans and scripts:
    • table
    • raw
    • JSON
    • CSV
    • env
  • Easy shell variable extraction.
  • Prepared statements for generated SQL values.
  • Identifier allowlist for table and column names.
  • Protection against accidental mass update/delete.
  • Simple backups.
  • MIT licensed.
  • Source-only distribution: compile locally on your own machine.

Why not just use text files?

Text files are fine until they are not.

This is okay:

echo "victor:victor@example.com" >> users.txt

Until you need:

spaces
quotes
commas
newlines
unique values
updates
deletes
filters
counts
exports
safe parsing
real structure

Then your script becomes a pile of grep, cut, awk, sed, escaping bugs and sadness.

FrogDB lets your shell script use SQLite without turning your script into a SQL client wrapper nightmare.


Installation from GitHub

Clone the repository:

git clone https://github.com/victormeloasm/frogdb.git
cd frogdb

Install dependencies on Ubuntu/Debian:

sudo apt update
sudo apt install clang lld make libsqlite3-dev sqlite3

Build:

make

Check:

./frogdb --version

Install system-wide:

sudo make install

Now you can run:

frogdb --version

Uninstall:

sudo make uninstall

Build with SQLCipher encryption support

FrogDB works as a normal SQLite CLI by default.

If you want encrypted database files, build with SQLCipher:

sudo apt update
sudo apt install clang lld make sqlcipher libsqlcipher-dev
make clean
make sqlcipher

Check:

./frogdb --version

Expected output:

frogdb 0.2.0 sqlcipher

Install the SQLCipher-enabled build:

sudo make install-sqlcipher

Fixing clock/timestamp warnings

If make says something like:

make: aviso: O arquivo 'Makefile' está com a hora adiantada
make: aviso: O relógio está errado. Sua compilação pode ficar incompleta.

Touch the extracted files and rebuild:

find . -exec touch {} +
make clean
make

For SQLCipher:

find . -exec touch {} +
make clean
make sqlcipher

If it keeps happening, fix your system clock:

timedatectl
sudo timedatectl set-ntp true

Quick start

Create a database:

frogdb init app.db

Create a table:

frogdb app.db table users \
  id:int:pk:auto \
  name:text:notnull \
  email:text:unique \
  age:int \
  created_at:text

Insert rows:

frogdb app.db insert users \
  name="Victor" \
  email="victor@example.com" \
  age=30 \
  created_at="$(date -Is)"

frogdb app.db insert users \
  name="SapoGPT" \
  email="sapo@example.com" \
  age=9000 \
  created_at="$(date -Is)"

List rows:

frogdb app.db list users

Find rows:

frogdb app.db find users name=Victor

Get a single field:

frogdb app.db get users.email name=Victor --raw

Use it in a shell variable:

EMAIL=$(frogdb app.db get users.email name=Victor --raw)
echo "$EMAIL"

Shell variable mode

The heart of FrogDB is shell scripting.

Raw output

Use --raw when you want a clean value:

NAME=$(frogdb app.db get users.name id=1 --raw)
EMAIL=$(frogdb app.db get users.email id=1 --raw)

echo "$NAME <$EMAIL>"

Env output

Use env when you want shell assignments:

frogdb app.db env users id=1

Example output:

id='1'
name='Victor'
email='victor@example.com'
age='30'
created_at='2026-06-05T20:00:00-03:00'

Load it into your current shell:

eval "$(frogdb app.db env users id=1)"

echo "$name"
echo "$email"

FrogDB shell-escapes values for this mode.


Output formats

Table

Best for humans:

frogdb app.db list users --table

Raw

Best for variables and pipes:

frogdb app.db get users.email id=1 --raw

JSON

Best for tools like jq:

frogdb app.db list users --json

Example:

frogdb app.db list users --json | jq .

CSV

Best for spreadsheets or export:

frogdb app.db export users --csv > users.csv

Command reference

Initialize database

frogdb init <db>

Example:

frogdb init app.db

Create table

frogdb <db> table <table> <column:type[:flags]>...

Example:

frogdb app.db table users \
  id:int:pk:auto \
  name:text:notnull \
  email:text:unique \
  age:int

Supported type aliases:

int
integer
text
real
blob
numeric
datetime
bool

Supported flags:

pk
auto
notnull
unique

Column example:

id:int:pk:auto
email:text:unique
name:text:notnull

Insert

frogdb <db> insert <table> key=value ...

Example:

frogdb app.db insert users name="Victor" email="victor@example.com" age=30

List

frogdb <db> list <table>

Example:

frogdb app.db list users

With filter:

frogdb app.db list users name=Victor

With limit:

frogdb app.db list users --limit 10

Find

frogdb <db> find <table> key=value ...

Example:

frogdb app.db find users email="victor@example.com"

Get field

frogdb <db> get <table.column> key=value ... --raw

Example:

EMAIL=$(frogdb app.db get users.email name=Victor --raw)

Env

frogdb <db> env <table> key=value ...

Example:

eval "$(frogdb app.db env users name=Victor)"

Update

Use --where for safe updates:

frogdb app.db set users age=31 --where name=Victor

FrogDB refuses mass updates by default:

frogdb app.db set users status=done

To update all rows intentionally:

frogdb app.db set users status=done --all --yes

Delete

Delete with filter:

frogdb app.db del users name=Victor

FrogDB refuses deleting everything by default:

frogdb app.db del users

To delete all rows intentionally:

frogdb app.db del users --all --yes

Count

frogdb app.db count users

With filter:

frogdb app.db count users age=30

List tables

frogdb app.db tables

Show schema

frogdb app.db schema

For one table:

frogdb app.db schema users

Raw SQL

frogdb app.db sql "SELECT id, name, email FROM users WHERE age >= 18" --table

JSON:

frogdb app.db sql "SELECT * FROM users" --json

CSV:

frogdb app.db sql "SELECT * FROM users" --csv

Raw SQL mode is intentionally raw. Use it carefully.

Export

frogdb app.db export users --csv > users.csv
frogdb app.db export users --json > users.json

Backup

frogdb app.db backup

Or choose the backup path:

frogdb app.db backup app.db.bak

Encrypted databases

SQLite itself does not provide password encryption in the standard library.

FrogDB supports encrypted database files when compiled with SQLCipher:

make sqlcipher

Create encrypted DB:

frogdb --ask-key init secrets.db --encrypted

Create table:

frogdb --ask-key secrets.db table secrets \
  id:int:pk:auto \
  name:text:unique \
  value:text

Insert secret:

frogdb --ask-key secrets.db insert secrets name=token value="abc123"

Read secret:

TOKEN=$(frogdb --ask-key secrets.db get secrets.value name=token --raw)
echo "$TOKEN"

Key options

Interactive prompt:

frogdb --ask-key secrets.db list secrets

Environment variable:

export FROGDB_KEY='strong password here'
frogdb --env-key secrets.db list secrets

Key file:

printf '%s' 'strong password here' > .frogdb_key
chmod 600 .frogdb_key

frogdb --key-file .frogdb_key secrets.db list secrets

Direct key:

frogdb --key 'strong password here' secrets.db list secrets

Direct --key works, but it is discouraged because it can leak through shell history or process lists.


Examples

Replace a config file

Instead of:

echo "theme=dark" >> config.txt
grep '^theme=' config.txt | cut -d= -f2

Use:

frogdb config.db table settings key:text:pk value:text
frogdb config.db insert settings key=theme value=dark

THEME=$(frogdb config.db get settings.value key=theme --raw)
echo "$THEME"

Job queue

frogdb jobs.db table jobs \
  id:int:pk:auto \
  name:text:notnull \
  status:text \
  created_at:text

frogdb jobs.db insert jobs \
  name=backup \
  status=pending \
  created_at="$(date -Is)"

JOB_ID=$(frogdb jobs.db get jobs.id name=backup --raw)

frogdb jobs.db set jobs status=done --where id="$JOB_ID"

Simple local inventory

frogdb inventory.db table assets \
  id:int:pk:auto \
  hostname:text:unique \
  ip:text \
  role:text

frogdb inventory.db insert assets hostname=server01 ip=10.0.0.10 role=web
frogdb inventory.db insert assets hostname=server02 ip=10.0.0.11 role=db

frogdb inventory.db find assets role=web --json

Script-friendly loop

frogdb app.db list users --csv | while IFS=, read -r id name email age; do
  echo "$id -> $email"
done

For more robust CSV parsing, use a CSV-aware tool.


Security model

FrogDB is designed for local automation.

Generated commands use prepared statements for values.

Table and column names are validated using a strict identifier allowlist:

[A-Za-z_][A-Za-z0-9_]*

This protects generated commands from obvious SQL injection through identifiers.

The sql command is raw SQL by design. It is for users who intentionally want direct SQL access.

Encrypted database support requires SQLCipher. A normal SQLite build does not encrypt the database.


Project philosophy

FrogDB exists because shell scripts deserve better than fragile text parsing.

The goal is not to replace SQLite.

The goal is to make SQLite feel natural from shell scripts:

value=$(frogdb db get table.column key=value --raw)

Small. Fast. Native. Scriptable. Useful.


License

MIT License.

Created by Víctor Duarte Melo.

About

FrogDB — SQLite made scriptable for shell programmers.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors