This project transforms relational models into explicit KV models that run directly on ToplingDB / RocksDB, avoiding the RDBMS (relational database) abstraction tax.
It is delivered as an AI coding skill and cross-agent plugin, not an ORM, SQL compatibility layer, or runtime library. The skill gives Cursor, Claude Code, and Codex the same rules and templates so an agent can generate storage code without inventing key layouts ad hoc.
In real products, the hard part is not Put
/Get
. It is what happens after entities, relationships, and indexes pile up: how keys are split, ordered, range-deleted, migrated, and kept operable for years. Ad-hoc design, or AI left to freestyle, often ships a layout that runs today and needs a rewrite in six months.
Manually mapping data models made up of entities, relationships, and indexes to KV, with no SQL layer in between, has long been common practice in production systems. Popular public blockchains such as Sui, the Move-based Aptos, and the sharded NEAR derive their exceptional performance from this very approach. In fact, a look at their code shows that their data models are standard relational models, yet they all independently translate those relational models into KV by hand and store them in RocksDB.
In the past, this approach to mapping relational models directly onto KV stores was expensive to develop: key spaces, encoding, consistency, and pruning all had to be designed by hand, putting it within reach only of projects that could afford dedicated storage teams. Today, this project codifies that expertise as an AI coding skill, enabling agents to follow consistent rules and deliver designs and implementations that once required storage specialists.
- Inventory the entities, identifiers, relationships, indexes, ownership, retention, and consistency constraints in the relational model.
- Enumerate the required point lookups, prefix scans, ranges, writes, and deletes. Access patterns—not the existing SQL tables alone—determine the KV model.
- Derive the primary, relationship, reverse, and secondary-index key spaces; fix each key's field order and scan boundaries.
- Assign logical key-space identities, then choose keyPrefix or an intentional CF namespace without mixing logical identity with physical placement.
- Define a bytewise-ordered business-key encoding and generate matching bounded encode/decode code for every key shape.
- Map logical key spaces to RocksDB column families and engine options, adding SidePlugin configuration for ToplingDB targets. Then specify atomic update groups, pruning, range deletion, and migration rules.
- Review the access patterns and key-space contract before accepting generated code or engine configuration.
Generated storage designs use the default BytewiseComparator
, so every key preserves its intended order under memcmp
. Scalar keys remain the default; composite keys are introduced only when an access pattern needs multiple ordered fields. Floating keys use the FoundationDB tuple-layer transform and preserve IEEE 754 totalOrder
, so -0.0
and +0.0
remain distinct unless the application normalizes them before encoding.
Use this project when the domain is naturally described with entities and relationships, the production data should live directly on ToplingDB / RocksDB, and point, prefix, and range access must remain predictable. It is especially useful when performance matters and AI-generated storage code must remain reviewable and migration-aware.
It is not a drop-in replacement for arbitrary SQL queries, an automatic data migrator, or a reason to force every relational workload onto embedded KV.
Install the plugin or personal skill for your coding agent. Then provide the domain model, required access patterns, consistency rules, deletion/retention requirements, and current ToplingDB / RocksDB constraints. For example:
Use the $relational-to-kv skill to design this model for ToplingDB.
Start from the listed read/write/scan/delete access patterns,
then produce the Key Space Catalog, key code, CF layout,
consistency/pruning plan, and migration notes.
Review the access-pattern decisions and Catalog first; only then accept the generated encoding and engine configuration.
For RocksDB targets, use the same workflow and deliver RocksDB column-family and Options configuration instead of SidePlugin configuration.
As a plugin (recommended) — official local path ~/.cursor/plugins/local
(docs):
git clone https://github.com/rockeet/relational-to-kv.git
ln -sfn "$PWD/relational-to-kv" ~/.cursor/plugins/local/relational-to-kv
Then restart Cursor or run Developer: Reload Window. Manage under Customize.
As a personal skill (flat skill folder):
ln -sfn "$PWD/relational-to-kv/skills/relational-to-kv" ~/.cursor/skills/relational-to-kv
Point Claude Code at the plugin root (--plugin-dir
or plugin manager). Manifest is .claude-plugin/plugin.json
; skills stay under root skills/
(docs).
git clone https://github.com/rockeet/relational-to-kv.git
claude --plugin-dir "$PWD/relational-to-kv"
Or install via Claude Code’s plugin manager from this repository. Invoke as /relational-to-kv:relational-to-kv
(plugin namespace + skill folder name).
Optional personal skill symlink:
ln -sfn "$PWD/relational-to-kv/skills/relational-to-kv" ~/.claude/skills/relational-to-kv
Manifest is .codex-plugin/plugin.json
; only that file belongs under .codex-plugin/
. Skills live under root skills/
(docs).
git clone https://github.com/rockeet/relational-to-kv.git
Optional personal skill symlink:
ln -sfn "$PWD/relational-to-kv/skills/relational-to-kv" ~/.codex/skills/relational-to-kv
| Deliverable | Contents |
|---|---|
| Key Space Catalog | One reviewed inventory of entities, relationships, indexes, namespaces, and key-space IDs where applicable |
| Key schema and C++ code | Ordered business-key fields, memcmp-safe encoding, bounded EncodeKey/DecodeKey, and user-key assembly |
| CF and engine configuration | Explicit mapping from logical key identity to physical CFs; CF / Options for RocksDB, plus SidePlugin configuration for ToplingDB |
| Consistency and pruning plan | Atomic update groups, reverse indexes, range-delete boundaries, retention, and migration notes |
The human remains responsible for business semantics and access-pattern choices. The agent makes those decisions explicit and implements the resulting contract consistently.
| File | Role |
|---|---|
skills/relational-to-kv/SKILL.md |
|
| Entry / router (English; loaded by agents) | |
encoding.md |
|
| Framework / Scalar / Composite encoding | |
patterns.md |
|
| P1–P8, AP1–AP12, namespace trade-offs | |
templates.md |
|
| Deliverable templates | |
examples.md |
|
| Golden-path examples | |
reference.md |
|
| ToplingDB / SidePlugin / memcmp_coding paths |
Chinese human-readable copies: *.zh.md
(content preserved; cross-linked to English).
relational-to-kv/
├── plugin.json # Agent Plugins (Cursor loads this)
├── .cursor-plugin/plugin.json # Cursor Plugin manifest
├── .claude-plugin/plugin.json # Claude Code manifest (only file in that dir)
├── .codex-plugin/plugin.json # Codex manifest (only file in that dir)
├── skills/
│ └── relational-to-kv/
│ ├── SKILL.md # English entry (agent)
│ ├── *.md # English child docs
│ └── *.zh.md # Chinese copies for human readers
├── tests/ # Repository-level unit and contract tests
│ ├── cpp/ # Encoding helpers + C++ unit tests
│ ├── test_repository.py # Manifests, links, docs/API contract
│ └── run_tests.sh # Local test entry point
├── README.md
├── README.zh.md
└── LICENSE
Platform references:
- Cursor / Agent Plugins: Plugins,Agent Plugins authoring - Claude Code: Plugins,Plugins reference - Codex: Build plugins,Package your plugin
Tests live at repository root, outside the skill folder, so test-only material is never loaded into an agent's skill context.
./tests/run_tests.sh
The runner recompiles the required Topling-zip sources instead of linking stale objects. It checks bounded raw-buffer memory-block round trips, the DataIO as_memcmp
stream contract, and byte equivalence between them, runs ASan/UBSan builds, then checks manifests, Markdown links, bilingual structure, and documented APIs.
The test runner does not assume a machine-specific ~/osc/toplingdb
checkout.
To use an existing full ToplingDB working tree, pass its root explicitly. The runner reads
${TOPLINGDB_ROOT}/sideplugin/topling-zip
and never fetches or modifies that checkout:
TOPLINGDB_ROOT=/path/to/toplingdb ./tests/run_tests.sh
If
TOPLINGDB_ROOT
is unset, the first run shallow-clonestopling/topling-zipwith its requiredboost-include
submodule into${XDG_CACHE_HOME:-~/.cache}/relational-to-kv/topling-zip
. Later runs reuse that cache and compile the checked-out source again. SetTOPLINGDB_CACHE_ROOT=/path/to/cache
to relocate it.
The runner validates that either checkout contains the required signed, real, and string as_memcmp
APIs plus the std::string*
append encoder and bounded output decoder before compiling, so an incompatible explicit checkout or stale cache fails with an actionable message instead of obscure compiler errors. git
, GCC or Clang with C++17 support, and network access on the first automatic-clone run are required. Set CXX
to select GCC or Clang; set SKIP_SANITIZERS=1
only when sanitizers are unavailable.
Additional systems that keep business state on embedded KV (shapes differ; useful for comparison):
| Kind | Examples | Notes |
|---|---|---|
| Chain, RocksDB for part of the stack | ||
Substrate / PolkadotBitcoin Core;Ethereum clients (Geth, …)Kafka Streams;Apache FlinkUber Cherami, etc.See also: Aptos's schema layer traces back to Diem SchemaDB.
SQL systems such as MySQL with MyRocks/MyTopling, TiDB over TiKV, and CockroachDB embody a different form of the same idea: the product itself is a relational database backed by a KV storage engine. This project brings that architecture directly to application data models, mapping their relational structure onto ToplingDB / RocksDB and thereby eliminating the RDBMS (relational database) abstraction tax.