Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
e895ae1
docs: add MongoDB storage backend design document
diegotoledano95 Jun 6, 2026
04c7543
feat: add MongoDB storage backend (extenddb-storage-mongodb)
diegotoledano95 Jun 6, 2026
f64cc35
chore: add MongoDB test configuration and runner updates
diegotoledano95 Jun 6, 2026
1024010
docs: add MongoDB backend documentation
diegotoledano95 Jun 6, 2026
8bf6c55
fix(mongodb): emit DynamoDB-compliant event names in stream records
diegotoledano95 Jul 17, 2026
3f63a3d
fix(mongodb): reject BETWEEN with low > high on query key path
diegotoledano95 Jul 17, 2026
1dd4ce2
fix(mongodb): populate CancellationReason.Item on condition-check fai…
diegotoledano95 Jul 17, 2026
b93891c
fix(mongodb): reject numeric key values that exceed Decimal128 precision
diegotoledano95 Jul 17, 2026
3d172ea
chore(mongodb): rustfmt after contract fixes
diegotoledano95 Jul 17, 2026
3ba36a6
chore(mongodb): resolve clippy collapsible_match warning in data_engi…
diegotoledano95 Jul 17, 2026
1648513
chore(mongodb): collapse nested if/if let per clippy
diegotoledano95 Jul 21, 2026
7dcfd49
fix(mongodb): per-shard sequence number counter
diegotoledano95 Jul 17, 2026
50fa8ee
fix(mongodb): TTL-invalidate GSI cache entries for multi-instance safety
diegotoledano95 Jul 17, 2026
ea8de08
fix(mongodb): query tables collection by _id compound key in backup e…
diegotoledano95 Jul 17, 2026
3523b3f
refactor(mongodb): use server-side $out for backup and restore
diegotoledano95 Jul 17, 2026
d67f35d
test(mongodb): pure-Rust BSON filter interpreter for pushdown parity
diegotoledano95 Jul 17, 2026
a112a85
test(mongodb): proptest harness for pushdown-parity between compiler …
diegotoledano95 Jul 17, 2026
e61b787
feat(mongodb): enable selective filter pushdown for conditional writes
diegotoledano95 Jul 17, 2026
788a157
fix(mongodb): reject ProvisionedThroughput on PAY_PER_REQUEST in Upda…
diegotoledano95 Jul 21, 2026
422e3bd
fix(mongodb): persist and return TableClass, SSESpecification, OnDema…
diegotoledano95 Jul 21, 2026
8cc46da
fix(mongodb): scope stream shards by table_id to prevent cross-tenant…
diegotoledano95 Jul 21, 2026
dac66dd
fix(mongodb): use netstring encoding for composite _id to avoid delim…
diegotoledano95 Jul 21, 2026
f0b4ed9
fix(mongodb): propagate stream records and GSI updates inside Transac…
diegotoledano95 Jul 21, 2026
5c0a5c4
fix(mongodb): assign stream sequence numbers inside the write transac…
diegotoledano95 Jul 21, 2026
8fa0288
fix(mongodb): embed base-table keys as first-class fields on index do…
diegotoledano95 Jul 21, 2026
d0c825f
fix(mongodb): emit INSERT (not MODIFY) when UpdateItem creates an item
diegotoledano95 Jul 21, 2026
ad2040d
fix(mongodb): unique index on idempotency tokens + E11000 race handling
diegotoledano95 Jul 21, 2026
73a53fc
fix(mongodb): preserve sort-key range on Query pagination resume
diegotoledano95 Jul 21, 2026
fcd84af
fix(mongodb): enforce 24-hour stream retention
diegotoledano95 Jul 21, 2026
27db867
fix(mongodb): make UpdateTable stream enable idempotent
diegotoledano95 Jul 21, 2026
cafa6c3
fix(mongodb): bump _v on UpdateItem native fast path
diegotoledano95 Jul 21, 2026
4a2f610
fix(mongodb): capture pre-image on UpdateItem so GSI deltas apply
diegotoledano95 Jul 21, 2026
1ea3b79
fix(mongodb): retry transient write conflicts (folds D-M2, D-M3)
diegotoledano95 Jul 21, 2026
bc43300
fix(mongodb): async GSI backfill on UpdateTable
diegotoledano95 Jul 21, 2026
2d4d9ec
fix(mongodb): validate index-key types on write
diegotoledano95 Jul 21, 2026
821403a
fix(mongodb): store binary sort keys as hex strings
diegotoledano95 Jul 21, 2026
3090f87
fix(mongodb): don't drop items in Parallel Scan under key-hash skew
diegotoledano95 Jul 22, 2026
2f15ae9
fix(mongodb): reject non-primary read preferences
diegotoledano95 Jul 22, 2026
5ddc1de
fix(mongodb): keep idempotency retention ≤10 min
diegotoledano95 Jul 22, 2026
06274b3
fix(mongodb): index stream_records(shard_id, sequence_number)
diegotoledano95 Jul 22, 2026
edf3fb8
fix(mongodb): index GSI/LSI data collections on create
diegotoledano95 Jul 22, 2026
e2582f9
fix(mongodb): match postgres stream_label format
diegotoledano95 Jul 22, 2026
0e6e1c2
fix(mongodb): stub out obsolete non-transactional write_stream_record
diegotoledano95 Jul 22, 2026
7725626
fix(mongodb): correct begins_with upper bound on string sort keys
diegotoledano95 Jul 22, 2026
7b76a4c
fix(mongodb): lock in pushdown analyzer exclusions
diegotoledano95 Jul 22, 2026
21294f6
feat(): add mongodb storage backend rfc
diegotoledano95 Jul 8, 2026
fe9637b
docs(rfc): update RFC-206 to match implementation
diegotoledano95 Jul 17, 2026
61488e3
docs: rewrite RFC-206 and design doc to describe current backend
diegotoledano95 Jul 22, 2026
21e7dcc
chore(mongodb): remove crate-wide allow(unused) and dead code
diegotoledano95 Jul 22, 2026
124c8e9
fix(mongodb): replace broken WorkerStore impl with an explicit no-op
diegotoledano95 Jul 22, 2026
796e2fa
fix(mongodb): propagate stale-index delete_one error
diegotoledano95 Jul 22, 2026
5b6f173
fix(mongodb): make init_stream_shards idempotent on E11000
diegotoledano95 Jul 22, 2026
1379d0a
fix(mongodb): sessionless fast paths for unconditional single-item wr…
diegotoledano95 Jul 22, 2026
ae831fa
test(mongodb): RFC-0003 §4 concurrency conformance
diegotoledano95 Jul 22, 2026
42c58f8
fix(mongodb): surface single-item retry exhaustion as TransactionConf…
diegotoledano95 Jul 22, 2026
8c8636a
fix(mongodb): zeroize encryption key in MongoCredentialStore on drop
diegotoledano95 Jul 17, 2026
f6140fa
fix(mongodb): warn at startup when MongoDB connection is not using TLS
diegotoledano95 Jul 17, 2026
9aca12b
fix(mongodb): redact userinfo password before persisting connection s…
diegotoledano95 Jul 17, 2026
a929b9f
fix(mongodb): fail closed when access key is_active flag is missing
diegotoledano95 Jul 17, 2026
46ede88
feat(devtools): add --backend flag to run-tests for mongo integration
diegotoledano95 Jul 23, 2026
9d7ce6d
docs(mongodb): bump minimum MongoDB version to 7.0
diegotoledano95 Jul 23, 2026
094ac12
feat(devtools): add run-mongodb-tests orchestrator
diegotoledano95 Jul 23, 2026
475ff87
fix(mongodb): scope get_stream_records to the shards owning account
diegotoledano95 Jul 30, 2026
ebd2288
chore(devtools): fix run-mongodb-tests server lifecycle to satisfy st…
diegotoledano95 Jul 30, 2026
02a900a
fix(mongodb): mark Field vs Field comparisons as not pushable
diegotoledano95 Jul 30, 2026
d0e1813
fix(mongodb): compute binary begins_with upper bound in hex-string space
diegotoledano95 Jul 30, 2026
068e8ed
fix(mongodb): implement transient table CREATING state
diegotoledano95 Jul 30, 2026
b05f594
chore(mongodb): adopt set_backend registration and adapt to post-#218…
diegotoledano95 Jul 30, 2026
2fdff8b
chore(mongodb): populate TableKeyInfo secondary-index lists
diegotoledano95 Jul 30, 2026
a7d70fa
style(mongodb): satisfy cargo fmt check
diegotoledano95 Aug 4, 2026
e2e4b22
test(mongodb): cover restore reporting ACTIVE before the data copy co…
LeeroyHannigan Aug 4, 2026
4864b77
fix(mongodb): set restored table ACTIVE only after the data copy comp…
diegotoledano95 Aug 4, 2026
7659a7d
fix(mongodb): harden connection and credential handling
diegotoledano95 Aug 5, 2026
70c6124
fix(mongodb): stop deriving Serialize on MongoStorageConfig
diegotoledano95 Aug 5, 2026
c845e7e
fix(mongodb): scope restore backup lookup to the account
diegotoledano95 Aug 5, 2026
c836074
fix(devtools): isolate run-mongodb-tests container and output per run
diegotoledano95 Aug 5, 2026
c4686de
test(rust): binary begins_with edges and field-vs-field conditions
diegotoledano95 Aug 5, 2026
64c0d8b
ci(mongodb): add MongoDB integration workflow
diegotoledano95 Aug 5, 2026
83e40cc
fix(mongodb): warn when GSI backfill returns an empty, non-final batch
diegotoledano95 Aug 5, 2026
1a3d41a
docs(mongodb): document f64-precision bound on inverted BETWEEN keys
diegotoledano95 Aug 5, 2026
56a8769
docs(mongodb): correct CI/test description and bump design doc to 7.0
diegotoledano95 Aug 5, 2026
e759498
test(rust): use a multi-byte all-0xFF begins_with prefix
diegotoledano95 Aug 5, 2026
b652e12
Merge origin/main into rfc/mongodb-backend
diegotoledano95 Aug 6, 2026
86eec2b
Merge remote-tracking branch 'origin' into rfc/mongodb-backend
diegotoledano95 Aug 6, 2026
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
67 changes: 67 additions & 0 deletions .github/workflows/integration-mongodb.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Copyright 2026 ExtendDB contributors
# SPDX-License-Identifier: Apache-2.0
name: MongoDB Integration Tests

on:
pull_request:
merge_group:
push:
branches: [main]

permissions:
contents: read

# The MongoDB backend needs a replica set (single-node --replSet + rs.initiate()
# + wait-for-PRIMARY) for transactions and streams, which GitHub `services:`
# cannot express. `devtools/run-mongodb-tests` performs that bootstrap, then
# init/serve/provision extenddb and delegates the workload to
# `run-tests --backend mongodb`, tearing everything down on exit. Both jobs
# reuse it so CI runs the exact path developers run locally (no drift), while
# splitting pytest and rust into parallel jobs the way integration.yml does.
jobs:
mongodb-pytest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
cache-on-failure: true
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install Python dependencies
run: pip install -r requirements.txt
- name: Build release (mongodb backend)
run: cargo build --release --no-default-features --features mongodb
- name: Run MongoDB pytest suite
run: devtools/run-mongodb-tests -- --pytest --comprehensive --parallel

mongodb-rust:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
cache-on-failure: true
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install Python dependencies
run: pip install -r requirements.txt
- name: Build release (mongodb backend)
run: cargo build --release --no-default-features --features mongodb
- name: Run MongoDB rust integration suite
run: devtools/run-mongodb-tests -- --rust --rust-integration

mongodb-integration:
runs-on: ubuntu-latest
needs: [mongodb-pytest, mongodb-rust]
if: always()
steps:
- run: |
if [ "${{ needs.mongodb-pytest.result }}" != "success" ] || \
[ "${{ needs.mongodb-rust.result }}" != "success" ]; then
exit 1
fi
37 changes: 29 additions & 8 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ by AWS engineers. It is not a fork of DynamoDB and contains no DynamoDB source c
protocol: any AWS SDK, CLI, or tool that works with DynamoDB works with ExtendDB, unchanged.

- **Language:** Rust (edition 2024, MSRV 1.88+)
- **Storage backend:** PostgreSQL 14+
- **Storage backends:** PostgreSQL 14+ (default), MongoDB 7.0+ (feature flag `mongodb`)
- **Architecture:** Async (tokio), trait-based storage abstraction
- **Authentication:** Mandatory SigV4 with built-in IAM (users, groups, roles, policies)
- **TLS:** Mandatory (self-signed cert generated by default)
Expand Down Expand Up @@ -51,7 +51,8 @@ extenddb/

The `TableEngine` trait in `crates/storage/src/lib.rs` defines the storage interface. All storage backends implement this trait:

- **Current:** `storage-postgres` (PostgreSQL)
- `storage-postgres` (PostgreSQL) — default backend
- `storage-mongodb` (MongoDB) — feature flag `mongodb`

The trait uses RPITIT (return-position impl Trait in traits) for async methods — no `#[async_trait]` macro.

Expand All @@ -66,12 +67,14 @@ extenddb (bin)
│ ├─> extenddb-core (pure sync, no async)
│ └─> extenddb-storage (trait definitions)
├─> extenddb-auth
└─> extenddb-storage-postgres
├─> extenddb-storage-postgres (feature: postgres)
└─> extenddb-storage-mongodb (feature: mongodb)
```

- **extenddb-core:** Pure synchronous Rust. No async, no I/O. Types, validation, expression parsing.
- **extenddb-storage:** Trait definitions only. No implementation.
- **extenddb-storage-postgres:** Concrete PostgreSQL implementation.
- **extenddb-storage-mongodb:** Concrete MongoDB implementation.
- **extenddb-engine:** Operation handlers that call storage traits.
- **extenddb-server:** HTTP server, management API, web console.
- **extenddb-auth:** SigV4 signature verification, IAM policy evaluation.
Expand All @@ -82,15 +85,25 @@ extenddb (bin)
### Prerequisites

- Rust 1.88+ (`rustup update`)
- PostgreSQL 14+ running locally (see `docs/local-postgres-setup.md`)
- Storage backend (one of):
- PostgreSQL 14+ running locally (see `docs/local-postgres-setup.md`)
- MongoDB 7.0+ with replica set (see `docs/local-mongodb-setup.md`)
- Python 3.10+ for tests (`python3 -m venv ~/venvs/extenddb-venv && source ~/venvs/extenddb-venv/bin/activate && pip install -r requirements.txt`)

### Build

```bash
# PostgreSQL backend (default)
cargo build --release

# MongoDB backend (backends are mutually exclusive — disable default postgres)
cargo build --release --no-default-features --features mongodb
```

Backends are selected by mutually exclusive Cargo features (`postgres`,
`mongodb`, `sqlite`); a build enabling more than one is rejected at compile
time. Each binary serves exactly one backend.

Binary: `target/release/extenddb`

### Unit Test
Expand All @@ -109,11 +122,15 @@ cargo clippy --all-targets -- -D warnings
### Initialize (first time only)

```bash
# PostgreSQL (default)
./target/release/extenddb init --config extenddb.toml

# MongoDB
./target/release/extenddb init --backend mongodb --config extenddb.toml
```

This creates:
- PostgreSQL databases (`extenddb_catalog`, `extenddb_account_<id>`)
- Databases (`extenddb_catalog`, `extenddb_data`)
- Admin user credentials (printed to stdout — save the password!)
- Self-signed TLS certificate at `~/.extenddb/tls/cert.pem`
- Config file `extenddb.toml`
Expand Down Expand Up @@ -357,6 +374,9 @@ Expression parsing lives in `crates/core/src/expression/`. This is pure sync Rus
| Differences from DynamoDB | `docs/differences-from-dynamodb.md` | Behavioral differences |
| Troubleshooting | `docs/troubleshooting.md` | Common errors and solutions |
| Storage Component Design | `docs/design/04-component-storage.md` | Storage trait design |
| MongoDB Design | `docs/design/13-storage-mongodb.md` | MongoDB backend architecture |
| Local PostgreSQL Setup | `docs/local-postgres-setup.md` | PostgreSQL installation and config |
| Local MongoDB Setup | `docs/local-mongodb-setup.md` | MongoDB installation and config |
| Testing Design | `docs/design/09-testing.md` | Test strategy and infrastructure |
| Extending Storage | `12-backend-plugin-architecture.md` | Guide to implementing storage backends |

Expand Down Expand Up @@ -448,9 +468,10 @@ Activate when the user asks about installing, configuring, running, or debugging
1. **TLS is mandatory** — server refuses to start without it. Use `AWS_CA_BUNDLE` for self-signed certs.
2. **Auth is mandatory** — all requests must be SigV4-signed. Use `extenddb manage` or web console to create credentials.
3. **Account isolation** — all operations are scoped to `account_id`. Different accounts can have tables with the same name.
4. **PostgreSQL must be running** — `extenddb init` and `extenddb serve` require a running PostgreSQL instance.
5. **Python venv** — activate the venv before running tests: `source ~/venvs/extenddb-venv/bin/activate`
6. **Test credentials** — run `devtools/provision-test-credentials` before pytest to create test users and keys.
4. **Storage backend must be running** — `extenddb init` and `extenddb serve` require a running PostgreSQL or MongoDB instance.
5. **MongoDB requires a replica set** — even single-node MongoDB must be configured with `--replSet` for transactions and streams.
6. **Python venv** — activate the venv before running tests: `source ~/venvs/extenddb-venv/bin/activate`
7. **Test credentials** — run `devtools/provision-test-credentials` before pytest to create test users and keys.

## Getting Help

Expand Down
Loading
Loading