Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,9 @@ deploy/digitalocean/droplet/scripts/99-img-check.sh



# local gate-4 probe harness (issue #424), never committed
/probe-424.ts
# local gate-4 probe harness (issue #424), never committed. Globbed rather than named:
# PR #511 committed probe-libsql.ts and two probe-results-*.json files because the harness
# was named per engine and the literal `/probe-424.ts` matched none of them.
/probe-*.ts
/probe-results/
/probe-results*.json
6 changes: 3 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Guidance for Claude Code in this repo — conventions, rules, and gotchas only.

## Project Overview

Web-based SQL IDE for cloud-native teams: PostgreSQL, MySQL, SQLite, Oracle, SQL Server, MongoDB, Redis, Couchbase, ClickHouse, Apache Druid, Elasticsearch, OpenSearch, Apache Trino, Apache Cassandra (plus the embedded LibreDB) + AI query assistance. Runs **two ways** — a standalone Next.js app AND a published npm package (CLI plus an embeddable library surface); `build:lib` (tsup) produces the package dist. The two modes render different chrome, so a UI change verified in one is not verified in the other.
Web-based SQL IDE for cloud-native teams: PostgreSQL, MySQL, SQLite, libSQL, Oracle, SQL Server, MongoDB, Redis, Couchbase, ClickHouse, Apache Druid, Elasticsearch, OpenSearch, Apache Trino, Apache Cassandra (plus the embedded LibreDB) + AI query assistance. Runs **two ways** — a standalone Next.js app AND a published npm package (CLI plus an embeddable library surface); `build:lib` (tsup) produces the package dist. The two modes render different chrome, so a UI change verified in one is not verified in the other.

## Branching & PRs

Expand Down Expand Up @@ -69,8 +69,8 @@ After every code change, run all six locally before claiming done — they match

### Rules & patterns

> **⚠️ Providers are the lifeblood of this project — keep the triad in lockstep: code ↔ docs ↔ tests**, 1:1 per canonical type-id — the type-id set is the `DatabaseType` union in [`src/lib/types.ts`](src/lib/types.ts) (`postgres`, `mysql`, `sqlite`, `mongodb`, `redis`, `oracle`, `mssql`, `couchbase`, `clickhouse`, `druid`, `elasticsearch`, `opensearch`, `cassandra`, `trino`, plus the embedded `libredb`):
> - Code: `src/lib/db/providers/<family>/<type-id>.ts`, or `src/lib/db/providers/<family>/<type-id>/index.ts` when the provider is split across modules, as `couchbase`, `clickhouse`, `druid`, `trino` and `cassandra` are · Docs: `docs/providers/<type-id>.md` · Tests: `tests/integration/db/<type-id>-provider.test.ts`
> **⚠️ Providers are the lifeblood of this project — keep the triad in lockstep: code ↔ docs ↔ tests**, 1:1 per canonical type-id — the type-id set is the `DatabaseType` union in [`src/lib/types.ts`](src/lib/types.ts) (`postgres`, `mysql`, `sqlite`, `libsql`, `mongodb`, `redis`, `oracle`, `mssql`, `couchbase`, `clickhouse`, `druid`, `elasticsearch`, `opensearch`, `cassandra`, `trino`, plus the embedded `libredb`):
> - Code: `src/lib/db/providers/<family>/<type-id>.ts`, or `src/lib/db/providers/<family>/<type-id>/index.ts` when the provider is split across modules, as `couchbase`, `clickhouse`, `druid`, `trino`, `cassandra` and `libsql` are · Docs: `docs/providers/<type-id>.md` · Tests: `tests/integration/db/<type-id>-provider.test.ts`
> - **One directory may serve two type-ids** — `src/lib/db/providers/sql/search/` is both `elasticsearch` and `opensearch` (#424). Docs and tests stay 1:1 anyway: the invariant is per type-id, and each doc is the prime reference for its own product's measured behaviour.
> - Any change to one side MUST sync the others **in the same PR**. The doc mirrors the code and the code mirrors the doc — never let them drift.

Expand Down
5 changes: 3 additions & 2 deletions DOCKERHUB.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ The network route is the one to prefer for a real deployment: put Studio and its

## Supported databases

Fourteen external engines share one interface, and three of them are read-only because their own SQL is. The table below has fifteen rows: the fifteenth is the embedded LibreDB store, which ships inside the image rather than being a server you connect out to.
Fifteen external engines share one interface, and three of them are read-only because their own SQL is. The table below has sixteen rows: the sixteenth is the embedded LibreDB store, which ships inside the image rather than being a server you connect out to.

| Database | Driver | Highlights |
| :--- | :--- | :--- |
Expand All @@ -116,6 +116,7 @@ Fourteen external engines share one interface, and three of them are read-only b
| **Oracle** | `oracledb` (thin) | `FETCH FIRST` pagination, `V$` monitoring, `ANALYZE`, transactions |
| **SQL Server** | `mssql` | `OFFSET FETCH`, `sys.dm_*` DMVs, `DBCC CHECKDB`, Azure SQL auto-detect |
| **SQLite** | `bun:sqlite` / `node:sqlite` | File-based or in-memory databases; the driver follows the runtime, with a `LIBREDB_SQLITE_DRIVER` override |
| **libSQL** | none — HTTP | Full SQL IDE over the Hrana protocol against a libSQL server or Turso Cloud; SQLite's dialect across a network, with real per-table bytes from `dbstat` and an auth token instead of a password |
| **MongoDB** | `mongodb` | JSON query editor, find/aggregate/insert/update/delete |
| **Redis** | `ioredis` | Command editor, non-blocking `SCAN` key browser, `INFO` monitoring, per-type command generation |
| **Couchbase** | none — HTTP | SQL++ query editor, bucket/scope/collection browser, cluster health |
Expand All @@ -131,7 +132,7 @@ Fourteen external engines share one interface, and three of them are read-only b

### Engines with no provider of their own

Twenty-six further engines speak the wire protocol of one of the fourteen drivers above, so they connect through it unchanged: pick that driver in the connection dialog. The table has twenty-two rows rather than twenty-six because engines that behave identically share a row; all twenty-six are named in it. Every one of them was measured against a real instance rather than assumed, and how much of the product worked is recorded per engine.
Twenty-six further engines speak the wire protocol of one of the fifteen drivers above, so they connect through it unchanged: pick that driver in the connection dialog. The table has twenty-two rows rather than twenty-six because engines that behave identically share a row; all twenty-six are named in it. Every one of them was measured against a real instance rather than assumed, and how much of the product worked is recorded per engine.

| Engine | Connect as | Support |
| :--- | :--- | :--- |
Expand Down
15 changes: 8 additions & 7 deletions README.md

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion README_ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ LibreDB Studioは逆向きです。**データをツールのところへ持っ

### 14のエンジン、1つのインターフェース

PostgreSQL · MySQL · Oracle · SQL Server · SQLite · MongoDB · Redis · Couchbase · ClickHouse · Apache Druid · Elasticsearch · OpenSearch · Apache Trino · Apache Cassandra
PostgreSQL · MySQL · Oracle · SQL Server · SQLite · libSQL · MongoDB · Redis · Couchbase · ClickHouse · Apache Druid · Elasticsearch · OpenSearch · Apache Trino · Apache Cassandra

スキーマエクスプローラ、ER図、スキーマ差分、モニタリングは全SQLエンジンで共通です。MongoDBとRedisはSQLエンジンではないため、ER図とスキーマ差分はありません。Druid、Elasticsearch、OpenSearch、TrinoはこのビルドがパースできるURI形式を持たないためhostとportで設定する二重の例外で、生成されるマイグレーションもDDLを出力せず制約を明示します(Couchbaseのスキーマレスなコレクションも同様)。検索クラスタのER図は箱だけで線がありません。インデックスは外部キーを宣言せず、エンジンのモデルにも宣言できる外部キーが存在しないためです。

Expand All @@ -95,6 +95,7 @@ PostgreSQL · MySQL · Oracle · SQL Server · SQLite · MongoDB · Redis · Cou
| **Oracle** | `oracledb`(Thinモード) | フルSQL IDE、`FETCH FIRST N ROWS`、`V$`監視ビュー、`ANALYZE TABLE`、`ALTER INDEX REBUILD`、トランザクション |
| **SQL Server** | `mssql` (tedious) | フルSQL IDE、`TOP N` / `OFFSET FETCH`、`sys.dm_*` DMV、`UPDATE STATISTICS`、`DBCC CHECKDB`、トランザクション、Azure SQL自動判別 |
| **SQLite** | `bun:sqlite` / `node:sqlite`(実行時選択) | フルSQL IDE、ファイル型・インメモリ型 |
| **libSQL** | ドライバなし、HTTPのみ(Hranaプロトコル、`POST /v2/pipeline`、8080) | フルSQL IDE。自前運用のlibSQLサーバー(`sqld`)とTurso Cloudの両方に同じtype-idで接続します。ネットワーク越しのSQLite方言で、`dbstat`による実測のテーブル・インデックスサイズが読めます。認証情報はパスワードではなくauthトークンです。メンテナンスはReindexと整合性チェックのみ。`VACUUM`、`ANALYZE`、`PRAGMA optimize`はサーバー側が拒否します |
| **MongoDB** | `mongodb` | JSONクエリエディタ、コレクション操作(find、aggregate、insert、update、delete) |
| **Couchbase** | ドライバなし、HTTPのみ(Query + 管理REST) | フルSQL++ IDE、EXPLAIN、bucket/scope/collectionエクスプローラ、`INFER`によるカラム推論 |
| **ClickHouse** | ドライバなし、HTTPのみ(SQLインターフェース、8123) | フルSQL IDE、JSON EXPLAINツリー、システムテーブルからのスキーマ取得、`OPTIMIZE TABLE` |
Expand Down
3 changes: 2 additions & 1 deletion README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ LibreDB Studio 走另一条路:**工具去找数据,而不是把数据搬来

### 十四种引擎,一个界面

PostgreSQL · MySQL · Oracle · SQL Server · SQLite · MongoDB · Redis · Couchbase · ClickHouse · Apache Druid · Elasticsearch · OpenSearch · Apache Trino · Apache Cassandra
PostgreSQL · MySQL · Oracle · SQL Server · SQLite · libSQL · MongoDB · Redis · Couchbase · ClickHouse · Apache Druid · Elasticsearch · OpenSearch · Apache Trino · Apache Cassandra

所有 SQL 引擎共用同一套 schema 浏览器、ER 图、schema 对比和监控面板。MongoDB 和 Redis 不属于 SQL 引擎,没有 ER 图和 schema 对比;Druid、Elasticsearch、OpenSearch 和 Trino 都是双重例外:它们的 HTTP SQL 接口没有本构建能解析的 URI 形式,只能按 host/port 配置,而且生成的迁移会直接说明限制,而不是对一个 SQL 里根本没有列变更语句的引擎硬输出 DDL;Couchbase 的 schemaless collection 同理。搜索集群的 ER 图只有方框没有连线:索引不声明外键,引擎模型里也没有外键可声明。

Expand All @@ -97,6 +97,7 @@ PostgreSQL · MySQL · Oracle · SQL Server · SQLite · MongoDB · Redis · Cou
| **Oracle** | `oracledb`(Thin 模式) | 完整 SQL IDE、`FETCH FIRST N ROWS` 分页、`V$` 监控视图、`ANALYZE TABLE`、`ALTER INDEX REBUILD`、事务 |
| **SQL Server** | `mssql` (tedious) | 完整 SQL IDE、`TOP N` / `OFFSET FETCH` 分页、`sys.dm_*` DMV、`UPDATE STATISTICS`、`DBCC CHECKDB`、事务、自动识别 Azure SQL |
| **SQLite** | `bun:sqlite` / `node:sqlite`(运行时自选) | 完整 SQL IDE,文件型或内存型数据库 |
| **libSQL** | 无驱动,纯 HTTP(Hrana 协议,`POST /v2/pipeline`,8080 端口) | 完整 SQL IDE,同一个 type-id 同时连接自建 libSQL 服务器(`sqld`)与 Turso Cloud。就是跨网络的 SQLite 方言,并能通过 `dbstat` 读到真实的表与索引字节数。凭据是 auth token 而不是密码。维护操作只有 Reindex 和完整性检查:`VACUUM`、`ANALYZE`、`PRAGMA optimize` 都被服务端拒绝 |
| **MongoDB** | `mongodb` | JSON 查询编辑器,集合操作(find、aggregate、insert、update、delete) |
| **Couchbase** | 无驱动,纯 HTTP(Query + 管理 REST) | 完整 SQL++ IDE、EXPLAIN、bucket/scope/collection 浏览器、`INFER` 字段推断 |
| **ClickHouse** | 无驱动,纯 HTTP(SQL 接口,8123 端口) | 完整 SQL IDE、JSON EXPLAIN 树、系统表 schema 自省、`OPTIMIZE TABLE` |
Expand Down
12 changes: 10 additions & 2 deletions charts/libredb-studio/Chart.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
apiVersion: v2
name: libredb-studio
description: Web-based SQL IDE for cloud-native teams supporting fourteen engines - PostgreSQL, MySQL, SQLite, Oracle, SQL Server, MongoDB, Redis, Couchbase, ClickHouse, Apache Druid, Elasticsearch, OpenSearch, Apache Trino and Apache Cassandra
description: Web-based SQL IDE for cloud-native teams supporting fifteen engines - PostgreSQL, MySQL, SQLite, Oracle, SQL Server, MongoDB, Redis, Couchbase, ClickHouse, Apache Druid, Elasticsearch, OpenSearch, Apache Trino, Apache Cassandra and libSQL
type: application
version: 0.1.52
version: 0.1.53
appVersion: "0.13.4"
kubeVersion: ">=1.26.0-0"
home: https://github.com/libredb/libredb-studio
Expand Down Expand Up @@ -31,6 +31,10 @@ keywords:
# shipped in 0.12.0 (#448) - #167 makes a keyword-only fix cost a chart version
# of its own, so a new engine's keyword belongs in the release that ships it.
- cassandra
# Two keywords for one engine, and the second is the one that gets searched: the
# provider is registered as `libsql`, but the product an evaluator types is Turso.
- libsql
- turso
- web-ide
maintainers:
- name: cevheri
Expand All @@ -39,6 +43,10 @@ annotations:
artifacthub.io/category: database
artifacthub.io/license: MIT
artifacthub.io/prerelease: "false"
# False: 0.1.53 changes no packaged template and no value - it names one more engine in
# the README, the description and the keywords, libSQL, which is a new provider in the
# app rather than a chart change. The README is a packaged file, so #167 costs it a
# chart version even though nothing an operator deploys moves.
# False: 0.1.52 adds one value, config.authCookieSecure, and changes no behaviour on its
# own - unset (the default) writes no AUTH_COOKIE_SECURE and the app keeps deciding, so
# every existing install renders exactly as before. It makes an already-supported setting
Expand Down
4 changes: 2 additions & 2 deletions charts/libredb-studio/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[![Artifact Hub](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/libredb-studio)](https://artifacthub.io/packages/search?repo=libredb-studio)

Web-based SQL IDE for cloud-native teams supporting fourteen engines - PostgreSQL, MySQL, SQLite, Oracle, SQL Server, MongoDB, Redis, Couchbase, ClickHouse, Apache Druid, Elasticsearch, OpenSearch, Apache Trino and Apache Cassandra.
Web-based SQL IDE for cloud-native teams supporting fifteen engines - PostgreSQL, MySQL, SQLite, libSQL, Oracle, SQL Server, MongoDB, Redis, Couchbase, ClickHouse, Apache Druid, Elasticsearch, OpenSearch, Apache Trino and Apache Cassandra.

## Prerequisites

Expand Down Expand Up @@ -40,7 +40,7 @@ helm install libredb libredb/libredb-studio \

```bash
helm install libredb oci://ghcr.io/libredb/charts/libredb-studio \
--version 0.1.52 \
--version 0.1.53 \
--set secrets.jwtSecret=$(openssl rand -base64 32) \
--set secrets.adminPassword=MyAdmin123
```
Expand Down
51 changes: 51 additions & 0 deletions database-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,57 @@ services:
# provider hides both; the second one carries no leading dot, so the dot convention alone
# does not catch it.

# ---------------------------------------------------------------------------------------
# libSQL server (issue #424, Phase 5). SQLite over a network: one container is the whole
# server, and it is the SELF-HOSTED half of the `libsql` type-id. The other half is Turso
# Cloud, which cannot be a compose service - it is an account - so the doc records what was
# measured there and this service is what anyone can repeat.
# ---------------------------------------------------------------------------------------
libsql:
# Pinned to the exact build the provider was live-verified against, the same rule the
# trino and clickhouse services follow: the refusal wording recorded in
# docs/providers/libsql.md ("unsupported statement: VACUUM") is a claim about sqld
# 0.24.33, and Turso Cloud words the identical refusal differently.
#
# The tag is needed even though `:latest` reports the same 0.24.33: measured 2026-08-27,
# `:latest` is a ROLLING REBUILD of that version - it answers `/version` with
# `sqld 0.24.33 (f8fb14f3 2026-08-11)` where `v0.24.33` answers
# `sqld 0.24.33 (40a151bd 2025-12-19)`, two different digests under one version number.
# So `:latest` is not reproducible even while the number it prints looks pinned.
image: ghcr.io/tursodatabase/libsql-server:v0.24.33
container_name: libredb-libsql
restart: unless-stopped
environment:
# A single primary with no replica. Without it sqld starts in a mode that expects a
# primary to follow, and the first write fails rather than the server failing to start.
SQLD_NODE: primary
ports:
# 8080 carries the Hrana HTTP API AND the version route - one port, and there is no
# second protocol port to publish. Mapped to 18080 so it cannot collide with the trino
# service above, which owns 8080 on the host.
- "18080:8080"
healthcheck:
# sqld's own route, and it answers WITHOUT a token - which is exactly why it is a
# health check and not a connection test: the provider proves the credential with
# `SELECT 1` instead (see connect() in the provider).
#
# Spoken through bash's /dev/tcp rather than curl, because the image ships NEITHER
# curl NOR wget (checked before writing this, the same way the trino service's
# comment says to: `command -v wget || command -v curl` answers nothing, while
# /bin/bash and /bin/sqld are both there). A `CMD curl` here would have marked the
# service permanently unhealthy while the server answered every request.
# `CMD bash -c`, never `CMD-SHELL`: CMD-SHELL runs /bin/sh, which is dash here, and
# dash has no /dev/tcp - measured, the check failed with "cannot create
# /dev/tcp/localhost/8080: Directory nonexistent" while the server was answering.
test:
- CMD
- bash
- -c
- exec 3<>/dev/tcp/localhost/8080 && printf 'GET /health HTTP/1.0\r\n\r\n' >&3 && head -1 <&3 | grep -q 200
interval: 10s
timeout: 5s
retries: 10

# ---------------------------------------------------------------------------------------
# Apache Trino (issue #424, Phase 2). One container is the whole cluster: the coordinator
# runs the worker in-process by default, which is enough to answer every statement the
Expand Down
Loading
Loading