Get started

Add the SDK,
then create a database.

The supported application crate is netbadb-sdk. The default feature is embedded. Disable default features and enable remote for a Protocol v1 client only. Toolchain 1.97.1; MSRV 1.85.0.

1. Add the dependency

The crate is published from the workspace repository. Cargo resolves the netbadb-sdk package in that git workspace.

[dependencies]
netbadb-sdk = { git = "https://github.com/sskycn/netbadb" }
[dependencies]
netbadb-sdk = { git = "https://github.com/sskycn/netbadb", default-features = false, features = ["remote"] }

2. Embedded create, insert, and query

Database::create refuses to overwrite an existing database or WAL slot. insert and execute run as implicit transactions. create_index backfills current rows and registers a non-unique single-column index. analyze writes a fresh optimizer snapshot; DML does not refresh it automatically.

use netbadb_sdk::{
    ColumnDef, ColumnId, Database, DatabaseError, PhysicalType, ScalarValue, TableDef, TableId,
    TypeSpec,
};

fn users() -> TableDef {
    TableDef::new(
        TableId(1),
        "users",
        vec![
            ColumnDef::new(
                ColumnId(1),
                "id",
                TypeSpec::Semantic {
                    name: "UserId".into(),
                    physical: PhysicalType::UInt64,
                },
            ),
            ColumnDef::new(ColumnId(2), "name", TypeSpec::Physical(PhysicalType::Text)),
        ],
    )
}

fn main() -> Result<(), DatabaseError> {
    let mut database = Database::create("users.db", users())?;
    database.insert(&[
        ScalarValue::UInt64(1),
        ScalarValue::Text("Ada".into()),
    ])?;
    database.create_index(TableId(1), ColumnId(1))?;
    database.analyze(TableId(1))?;
    let _rows = database.query("SELECT id, name FROM users WHERE id = 1")?;
    database.close()
}

3. Inspect the catalog and plan

Inspection compiles and plans a statement without executing it. It does not scan heaps, refresh ANALYZE, acquire the writer, or append WAL.

use netbadb_sdk::inspection;

let catalog = database.inspect_catalog()?;
println!("{}", inspection::render_catalog(&catalog));

let statement = database.inspect_statement(
    "SELECT id FROM users WHERE id = 1",
)?;
println!("{}", inspection::render_statement(&statement));

4. Start netbadbd

The server opens existing heap files declared by deployment manifest v4. Loopback plaintext requires exactly one local_plaintext principal. Non-loopback listening requires mutual TLS.

{
  "version": 4,
  "listen": "127.0.0.1:7878",
  "authorization": {
    "local_plaintext": {
      "tables": [
        { "table_id": 1, "read": true, "write": true, "transaction": true, "analyze": true }
      ]
    },
    "clients": []
  },
  "tables": [
    {
      "path": "users.db",
      "id": 1,
      "name": "users",
      "columns": [
        { "id": 1, "name": "id", "physical_type": "uint64", "semantic_type": "UserId", "nullable": false },
        { "id": 2, "name": "name", "physical_type": "text", "nullable": false }
      ]
    }
  ]
}
cargo run -p netbadbd -- --manifest server.json

5. Connect a remote client

Plaintext is accepted only when the resolved TCP peer is loopback. Remote deployments require verified mutual TLS. There is no connection pool, automatic retry, or multiplexing.

use netbadb_sdk::remote;

let mut client = remote::Client::connect(
    remote::Config::new("127.0.0.1:7878"),
)?;
client.ping()?;
let mut rows = client.query("SELECT id, name FROM users ORDER BY id")?;
while let Some(values) = rows.next_row()? {
    println!("{values:?}");
}

6. Inspect files from the command line

Stop netbadbd and any embedded process using the same files first. The CLI opens tables with normal startup recovery and never executes the inspected SQL.

cargo run -p netbadb -- inspect catalog --manifest server.json

cargo run -p netbadb -- inspect statement \
  --manifest server.json \
  --sql "SELECT id FROM users WHERE id = 1"

Go client

The Go module is an independent Protocol v1 client. It uses no cgo or Rust FFI. Dial performs Hello automatically.

client, err := netbadb.Dial(ctx, netbadb.Config{
    Address: "localhost:7878",
})
if err != nil { /* handle */ }
defer client.Close()

rows, err := client.Query(ctx, "SELECT id, name FROM users ORDER BY id")

Build from source

git clone https://github.com/sskycn/netbadb.git
cd netbadb
make test

Operating constraints

  • One writer per open database object. Read-only transactions do not reserve the writer.
  • Readers are not isolated and may observe an active writer's buffered changes.
  • A successful commit means the Commit record is durable; heap pages may remain buffered until flush or close.
  • SQL index DDL is not available. Call create_index from the embedded API.
  • Cross-table write transactions are not supported.
  • Experimental on-disk formats reject older versions. There is no migration path.

License

NetbaDB is licensed under AGPL-3.0-or-later. If you modify the program and let users interact with it over a network, you must provide the corresponding source.