Getting Started

Quick Start

CleaveDB operates over a TCP Protocol (port 8300), a WebSocket Protocol (port 8301), and an HTTP REST API (port 8302). All client connections must authenticate with a valid username and password before executing CleaveQL queries.

Node.js (WebSocket)

The WebSocket protocol is ideal for long-lived, stateful connections and enables real-time Pub/Sub features like LISTEN TO bucket.

npm i cleavedb
index.js
const WebSocket = require('ws');

const ws = new WebSocket('ws://127.0.0.1:8301');

ws.on('open', function open() {
  // 1. Authenticate
  ws.send(JSON.stringify({
    action: 'authenticate',
    username: 'david',
    password: 'perez'
  }));
});

let authenticated = false;

ws.on('message', function incoming(data) {
  const response = JSON.parse(data);
  
  if (!authenticated) {
    if (response[0].status === 'ok') {
      authenticated = true;
      // 2. Run Queries
      ws.send('FIND users');
    } else {
      console.error('Auth Failed!');
    }
  } else {
    console.log('Query Result:', response);
  }
});

Python (WebSockets)

client.py
import asyncio
import websockets
import json

async def connect_ws():
    async with websockets.connect("ws://127.0.0.1:8301") as ws:
        # 1. Authenticate
        await ws.send(json.dumps({"action": "authenticate", "username": "david", "password": "perez"}))
        auth_res = json.loads(await ws.recv())
        
        if auth_res[0].get("status") != "ok":
            return print("Auth failed!")
            
        # 2. Run Queries
        await ws.send('POUR INTO users "bot" {"name": "AI"}')
        print("WS Query Result:", await ws.recv())

asyncio.run(connect_ws())

Python (Raw TCP)

TCP is the most performant way to interact with the engine. The wire protocol requires newline-delimited requests, with JSON array responses.

main.py
import asyncio
import json

async def connect_tcp():
    reader, writer = await asyncio.open_connection('127.0.0.1', 8300)
    
    # 1. Authenticate
    auth_payload = {"action": "login", "username": "david", "password": "perez"}
    writer.write((json.dumps(auth_payload) + "\n").encode())
    await writer.drain()
    
    response = await reader.readline()
    if json.loads(response).get("status") != "ok":
        return print("Auth failed!")
        
    # 2. Run Queries (Newline delimited)
    writer.write(b'FIND users\n')
    await writer.drain()
    
    query_result = await reader.readline()
    print("TCP Query Result:", query_result.decode())

asyncio.run(connect_tcp())

HTTP REST API & cURL

CleaveDB supports zero-dependency REST requests on port 8302. You can run raw CleaveQL queries via HTTP POST, or use standard RESTful routing. Authentication is handled via Basic Auth.

Terminal (REST)
# Run a raw CleaveQL Query
curl -X POST http://127.0.0.1:8302/api/v1/query \
  -H "Authorization: Basic ZGF2aWQ6cGVyZXo=" \
  -d "FIND THE TALLY OF users"

# Standard RESTful CRUD
curl -X POST http://127.0.0.1:8302/api/v1/users \
  -H "Authorization: Basic ZGF2aWQ6cGVyZXo=" \
  -d '{"name": "API User", "age": 25}'

CLI WebSocket Client (wscat)

For real-time Pub/Sub subscriptions (like LISTEN TO users) directly from your terminal, use a websocket tool like wscat:

Terminal (wscat)
# Install wscat
npm install -g wscat

# Connect and authenticate
wscat -c ws://127.0.0.1:8301

# Send your credentials
> {"action": "authenticate", "username": "david", "password": "perez"}
< [{"status": "ok", "message": "Authenticated as david"}]

# Run a query
> FIND users
< [{"status": "ok", "documents": [...]}]

Realtime Subscriptions (LISTEN)

CleaveDB isn't just a database; it can act as a fully-fledged real-time Pub/Sub message broker. By connecting a WebSocket client to port 8301, you can subscribe to specific documents or entire buckets. Any POUR, CHANGE, or LINK executed anywhere on the database will instantly push JSON events to your frontend.

/* Subscribe to all events in the chat bucket */
LISTEN TO chat

/* Subscribe exclusively to updates on David's profile */
LISTEN TO users "david"

Interactive Chat Demo

To see the full power of real-time CleaveQL subscriptions in action, we included a highly-responsive interactive CLI chat simulation using purely CleaveDB WebSockets (complete with real-time Facebook Messenger style typing indicators!).

Terminal (Split View)
# 1. Start the server
python cleavedb_server.py

# 2. Open Terminal A
python tests/websocket/david.py

# 3. Open Terminal B
python tests/websocket/jessy.py

Type a message in one terminal and watch it appear instantly in the other via WebSockets!

Multi-Node Raft Consensus (High Availability Cluster)

CleaveDB is fully distributed. Using a custom Python-native Raft Consensus implementation, CleaveDB provides Zero-Downtime, Disaster Survival, and High Availability replication.

When you send a POUR or CHANGE write command to the cluster, the Leader node intercepts it. The command is mathematically appended to the distributed Raft Log. Once the majority (Quorum) acknowledges writing the WAL, it is committed to memory. If a node crashes, the cluster seamlessly elects a new leader with no data loss!

Run multiple nodes to form a cluster:

Terminal (Node 1, 2, 3)
python cleavedb_server.py --port 8301 --raft-port 8311 --peers 127.0.0.1:8321,127.0.0.1:8331 --data node1
python cleavedb_server.py --port 8311 --raft-port 8321 --peers 127.0.0.1:8311,127.0.0.1:8331 --data node2
python cleavedb_server.py --port 8321 --raft-port 8331 --peers 127.0.0.1:8311,127.0.0.1:8321 --data node3

Note: TCP connections bypass Raft and write directly to the local engine. Only WebSocket and HTTP requests replicate through the Raft Consensus group.

Client Lifecycle & Wire Protocol

1. Authentication Phase

Clients must immediately authenticate via register, login, or forgot over the socket.

2. Query Phase

Send raw CleaveQL strings over the socket. Responses are returned as JSON Arrays.

3. Disconnection

Use logout to drop back to the login screen, or exit to terminate the connection entirely.

CLI Built-in Commands

CommandDescription
help / ?Print the complete CleaveQL manual inside the shell
logoutClose active session, return to login screen
cls / clearClear terminal screen
exit / quitClose connection and exit shell process