Overview
Mori sits between your application and two databases: the production database (read-only) and the Shadow database (read-write). Every query is intercepted, classified, routed, and — when needed — results from both databases are merged transparently.
Components
Protocol Handler — Speaks the target database’s native wire protocol. Accepts connections, performs handshake/authentication, parses incoming messages, serializes outgoing results. Indistinguishable from a real database server to the application. Classifier — Parses each query to determine operation type (READ, WRITE, DDL, TRANSACTION), affected tables, extractable primary keys, and whether it’s a JOIN. Lightweight syntactic analysis — fast, sits in the hot path.
Router — Takes classifier output + delta/tombstone state and selects an execution strategy. The core decision point.
Delta Manager — Maintains the Delta Map and Tombstone Set. Supports transaction staging: additions are staged within a transaction, promoted on COMMIT, discarded on ROLLBACK.
Schema Registry — Tracks per-table schema divergence. Used to adapt Prod rows during reads (inject NULLs for new columns, strip dropped columns, rename, cast types) and during hydration.
Transaction Manager — Per-connection transaction state. Coordinates transactions across Prod (read-only) and Shadow (read-write). Enforces staged delta semantics.
Engine Manager — Connection pools to Prod and Shadow. Each app connection gets one dedicated Prod connection (read-only) and one dedicated Shadow connection (read-write).
Merge Engine — Combines Prod and Shadow results during reads. Handles single-table merges, JOIN patching, over-fetching for LIMIT queries, row filtering, and schema adaptation.
Write Engine — INSERT (Shadow-only), UPDATE (hydrate + Shadow), DELETE (Shadow + tombstone). Coordinates with Delta Manager on every mutation.

