Skip to content

syncliteio/synclite-db

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 

Repository files navigation

SyncLite DB — Language-Agnostic Sync-Ready Database Server

Part of the SyncLite Platform — Build Anything, Sync Anywhere.

What is SyncLite DB?

SyncLite DB is a standalone, sync-enabled database server that wraps popular embedded databases — SQLite, DuckDB, Apache Derby, H2, and HyperSQL — and exposes them over HTTP as a JSON API.

Whereas SyncLite Logger is an embeddable JDBC library for Java and Python, SyncLite DB is the language-agnostic alternative: any application written in any language (Java, Python, C++, C#, Go, Rust, Ruby, Node.js, and more) can send SQL requests as JSON over HTTP and have them executed on the embedded database and automatically synced through the SyncLite pipeline to the destination database.

Your App (any language)  ──HTTP/JSON──▶  SyncLite DB Server  ──▶  Staging Storage  ──▶  SyncLite Consolidator  ──▶  Destination

Key Features

  • Language-agnostic — plain HTTP + JSON; no language-specific SDK required
  • All SyncLite device types — SQLITE, DUCKDB, DERBY, H2, HYPERSQL, STREAMING, and all APPENDER variants
  • Full transaction support — begin / execute / commit / rollback with transaction handles
  • Result set pagination — fetch large result sets in pages using resultset-handle
  • Authentication — Bearer token auth and HMAC app-auth
  • Batch operations — batched INSERT / UPDATE / DELETE in a single HTTP call
  • Zero schema changes — your app sends standard SQL; SyncLite DB handles the logging

Starting the Server

# Windows
synclite-db.bat --config synclite_db.conf

# Linux / macOS
synclite-db.sh --config synclite_db.conf

The server binds to http://localhost:<configured-port> by default.

HTTP/JSON API

Initialize a database

POST /synclite
{
  "db-type": "SQLITE",
  "db-path": "/home/alice/synclite/job1/myapp.db",
  "synclite-logger-config": "/home/alice/synclite/job1/synclite_logger.conf",
  "sql": "initialize"
}

Create a table

{
  "db-path": "/home/alice/synclite/job1/myapp.db",
  "sql": "CREATE TABLE IF NOT EXISTS events(id INT, payload TEXT)"
}

Batched insert

{
  "db-path": "/home/alice/synclite/job1/myapp.db",
  "sql": "INSERT INTO events VALUES(?, ?)",
  "arguments": [[1, "edge-event-1"], [2, "edge-event-2"]]
}

Explicit transaction

// Begin
{ "db-path": "...", "sql": "begin" }

// Execute inside transaction
{ "db-path": "...", "sql": "INSERT INTO events VALUES(?, ?)", "txn-handle": "<uuid>", "arguments": [[3, "three"]] }

// Commit
{ "db-path": "...", "sql": "commit", "txn-handle": "<uuid>" }

Querying data — SELECT, result set handling, and pagination

Basic SELECT

POST /synclite
{
  "db-path": "/home/alice/synclite/job1/myapp.db",
  "sql": "SELECT id, name, score FROM players ORDER BY id",
  "resultset-include-metadata": "ON"
}

Response:

{
  "result": true,
  "message": "OK",
  "column-metadata": [
    { "label": "id",    "type": "INTEGER" },
    { "label": "name",  "type": "TEXT"    },
    { "label": "score", "type": "INTEGER" }
  ],
  "resultset": [
    { "id": 1, "name": "Alice", "score": 100 },
    { "id": 2, "name": "Bob",   "score": 200 }
  ],
  "has-more": false
}
  • resultset — array of row objects (JSON format, default). Each object is { columnName: value, … }.
  • column-metadata — present when "resultset-include-metadata": "ON". Each entry has label (column name) and type.
  • has-moretrue when additional pages exist. A resultset-handle UUID is also returned to fetch them.

Pagination — large result sets

Use resultset-pagination-size in the initial request. The server returns the first page and a resultset-handle. Call "request-type": "next" with that handle to retrieve subsequent pages until has-more is false.

Step 1 — Initial query (page size = 100):

{
  "db-path": "/home/alice/synclite/job1/myapp.db",
  "sql": "SELECT id, name, score FROM players ORDER BY id",
  "resultset-pagination-size": 100,
  "resultset-include-metadata": "ON"
}

Response (first page, more rows available):

{
  "result": true,
  "message": "OK",
  "column-metadata": [ { "label": "id", "type": "INTEGER" }, { "label": "name", "type": "TEXT" }, { "label": "score", "type": "INTEGER" } ],
  "resultset": [ { "id": 1, "name": "Alice", "score": 100 }, "…99 more rows…" ],
  "resultset-handle": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "has-more": true
}

Step 2 — Fetch next page:

{
  "request-type": "next",
  "resultset-handle": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "resultset-pagination-size": 100
}

Repeat until has-more is false. The handle is automatically released on the last page, or if the session times out.

Full pagination loop in Python:

r = execute_sql(db_path, None, "SELECT id, name, score FROM players ORDER BY id",
                resultset_pagination_size=100, include_metadata=True)

# Print header
print("\t".join(col["label"] for col in r.column_metadata))

current = r
while True:
    for row in current.result_set:
        print(f"{row['id']}\t{row['name']}\t{row['score']}")
    if not current.has_more or not current.resultset_handle:
        break
    current = next_page(current.resultset_handle)
    if not current.result:
        raise Exception(f"Pagination error: {current.message}")

DB data format — columnar arrays

Pass "resultset-data-format": "DB" (with metadata on) to receive rows as value arrays instead of {name: value} objects. This reduces payload size for wide tables.

{
  "db-path": "/home/alice/synclite/job1/myapp.db",
  "sql": "SELECT id, name, score FROM players ORDER BY id",
  "resultset-data-format": "DB",
  "resultset-include-metadata": "ON"
}

Response:

{
  "result": true,
  "column-metadata": [ { "label": "id" }, { "label": "name" }, { "label": "score" } ],
  "resultset": [
    [1, "Alice", 100],
    [2, "Bob",   200]
  ],
  "has-more": false
}

Column order in each row array matches the order of column-metadata. The same resultset-data-format field can be passed to "request-type": "next" calls.

Close

{ "db-path": "...", "sql": "close" }

SDK Samples

Ready-to-run client samples are in sdk-source/ covering all core API patterns:

Language Directory
Java sdk-source/java/
Python sdk-source/python/
C# sdk-source/c#/
C++ sdk-source/cpp/
Go sdk-source/go/
Rust sdk-source/rust/
Ruby sdk-source/ruby/
Node.js sdk-source/node.js/

See sdk-source/GETTING_STARTED.md for run instructions and sdk-source/LANGUAGE_QUICKSTART.md for per-language setup.

Build

cd synclite-db/db
mvn -Drevision=oss clean install

Built artifact: db/target/synclite-db-oss.jar

Related Components

Component Role
SyncLite Logger Native Java/Python JDBC driver (embedded, no HTTP overhead)
SyncLite Client CLI client that can connect to SyncLite DB
SyncLite Consolidator Consumes the sync logs and replicates to destination

Documentation & Community


← Back to the SyncLite Platform README

About

SyncLiteDB : A Lightweight Sync-Ready Single Node Database

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors