Skip to content
Merged
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
bdfff9d
docs: add MongoDB storage backend design document
diegotoledano95 Jun 6, 2026
3ca3939
feat: add MongoDB storage backend (extenddb-storage-mongodb)
diegotoledano95 Jun 6, 2026
8bea956
chore: add MongoDB test configuration and runner updates
diegotoledano95 Jun 6, 2026
f36072d
docs: add MongoDB backend documentation
diegotoledano95 Jun 6, 2026
09b9607
fix(mongodb): emit DynamoDB-compliant event names in stream records
diegotoledano95 Jul 17, 2026
ca3d605
fix(mongodb): reject BETWEEN with low > high on query key path
diegotoledano95 Jul 17, 2026
74cc2a5
fix(mongodb): populate CancellationReason.Item on condition-check fai…
diegotoledano95 Jul 17, 2026
a8b246c
fix(mongodb): reject numeric key values that exceed Decimal128 precision
diegotoledano95 Jul 17, 2026
6b47a07
chore(mongodb): rustfmt after contract fixes
diegotoledano95 Jul 17, 2026
c9232ba
chore(mongodb): resolve clippy collapsible_match warning in data_engi…
diegotoledano95 Jul 17, 2026
8ffa736
chore(mongodb): collapse nested if/if let per clippy
diegotoledano95 Jul 21, 2026
7bf7c9b
fix(mongodb): per-shard sequence number counter
diegotoledano95 Jul 17, 2026
57d797f
fix(mongodb): TTL-invalidate GSI cache entries for multi-instance safety
diegotoledano95 Jul 17, 2026
abe0cbe
fix(mongodb): query tables collection by _id compound key in backup e…
diegotoledano95 Jul 17, 2026
f9ef1cd
refactor(mongodb): use server-side $out for backup and restore
diegotoledano95 Jul 17, 2026
7006547
test(mongodb): pure-Rust BSON filter interpreter for pushdown parity
diegotoledano95 Jul 17, 2026
e1ced7f
test(mongodb): proptest harness for pushdown-parity between compiler …
diegotoledano95 Jul 17, 2026
7bcdee8
feat(mongodb): enable selective filter pushdown for conditional writes
diegotoledano95 Jul 17, 2026
97bd48c
fix(mongodb): reject ProvisionedThroughput on PAY_PER_REQUEST in Upda…
diegotoledano95 Jul 21, 2026
31b083a
fix(mongodb): persist and return TableClass, SSESpecification, OnDema…
diegotoledano95 Jul 21, 2026
5d952fe
fix(mongodb): scope stream shards by table_id to prevent cross-tenant…
diegotoledano95 Jul 21, 2026
5e9396c
fix(mongodb): use netstring encoding for composite _id to avoid delim…
diegotoledano95 Jul 21, 2026
1e336e9
fix(mongodb): propagate stream records and GSI updates inside Transac…
diegotoledano95 Jul 21, 2026
4b7dccc
fix(mongodb): assign stream sequence numbers inside the write transac…
diegotoledano95 Jul 21, 2026
8a227a4
fix(mongodb): embed base-table keys as first-class fields on index do…
diegotoledano95 Jul 21, 2026
e7a4f64
fix(mongodb): emit INSERT (not MODIFY) when UpdateItem creates an item
diegotoledano95 Jul 21, 2026
1279984
fix(mongodb): unique index on idempotency tokens + E11000 race handling
diegotoledano95 Jul 21, 2026
73bb7b4
fix(mongodb): preserve sort-key range on Query pagination resume
diegotoledano95 Jul 21, 2026
e4f4a54
fix(mongodb): enforce 24-hour stream retention
diegotoledano95 Jul 21, 2026
c725216
fix(mongodb): make UpdateTable stream enable idempotent
diegotoledano95 Jul 21, 2026
bcf1a99
fix(mongodb): bump _v on UpdateItem native fast path
diegotoledano95 Jul 21, 2026
1ae58ce
fix(mongodb): capture pre-image on UpdateItem so GSI deltas apply
diegotoledano95 Jul 21, 2026
ac2f67a
fix(mongodb): retry transient write conflicts (folds D-M2, D-M3)
diegotoledano95 Jul 21, 2026
079ac1f
fix(mongodb): async GSI backfill on UpdateTable
diegotoledano95 Jul 21, 2026
004cf49
fix(mongodb): validate index-key types on write
diegotoledano95 Jul 21, 2026
fa37cd2
fix(mongodb): store binary sort keys as hex strings
diegotoledano95 Jul 21, 2026
1a44f97
fix(mongodb): don't drop items in Parallel Scan under key-hash skew
diegotoledano95 Jul 22, 2026
29a7869
fix(mongodb): reject non-primary read preferences
diegotoledano95 Jul 22, 2026
63e53d7
fix(mongodb): keep idempotency retention ≤10 min
diegotoledano95 Jul 22, 2026
3c87780
fix(mongodb): index stream_records(shard_id, sequence_number)
diegotoledano95 Jul 22, 2026
3385a4d
fix(mongodb): index GSI/LSI data collections on create
diegotoledano95 Jul 22, 2026
4c5fde1
fix(mongodb): match postgres stream_label format
diegotoledano95 Jul 22, 2026
188191c
fix(mongodb): stub out obsolete non-transactional write_stream_record
diegotoledano95 Jul 22, 2026
4028846
fix(mongodb): correct begins_with upper bound on string sort keys
diegotoledano95 Jul 22, 2026
62a53d6
fix(mongodb): lock in pushdown analyzer exclusions
diegotoledano95 Jul 22, 2026
fd086ba
feat(): add mongodb storage backend rfc
diegotoledano95 Jul 8, 2026
da09d7f
docs(rfc): update RFC-206 to match implementation
diegotoledano95 Jul 17, 2026
8844398
docs: rewrite RFC-206 and design doc to describe current backend
diegotoledano95 Jul 22, 2026
89e10f1
chore(mongodb): remove crate-wide allow(unused) and dead code
diegotoledano95 Jul 22, 2026
d05e273
fix(mongodb): replace broken WorkerStore impl with an explicit no-op
diegotoledano95 Jul 22, 2026
e75d524
fix(mongodb): propagate stale-index delete_one error
diegotoledano95 Jul 22, 2026
a44ba15
fix(mongodb): make init_stream_shards idempotent on E11000
diegotoledano95 Jul 22, 2026
58e92ca
fix(mongodb): sessionless fast paths for unconditional single-item wr…
diegotoledano95 Jul 22, 2026
2c65acb
test(mongodb): RFC-0003 §4 concurrency conformance
diegotoledano95 Jul 22, 2026
2d1ec20
fix(mongodb): surface single-item retry exhaustion as TransactionConf…
diegotoledano95 Jul 22, 2026
c0e3887
fix(mongodb): zeroize encryption key in MongoCredentialStore on drop
diegotoledano95 Jul 17, 2026
d03d9d6
fix(mongodb): warn at startup when MongoDB connection is not using TLS
diegotoledano95 Jul 17, 2026
782a85f
fix(mongodb): redact userinfo password before persisting connection s…
diegotoledano95 Jul 17, 2026
d8e62f5
fix(mongodb): fail closed when access key is_active flag is missing
diegotoledano95 Jul 17, 2026
4ace7ed
feat(devtools): add --backend flag to run-tests for mongo integration
diegotoledano95 Jul 23, 2026
263c96a
docs(mongodb): bump minimum MongoDB version to 7.0
diegotoledano95 Jul 23, 2026
1d2b228
feat(devtools): add run-mongodb-tests orchestrator
diegotoledano95 Jul 23, 2026
7f026cd
fix(mongodb): scope get_stream_records to the shards owning account
diegotoledano95 Jul 30, 2026
3eff680
chore(devtools): fix run-mongodb-tests server lifecycle to satisfy st…
diegotoledano95 Jul 30, 2026
b5e1a8b
fix(mongodb): mark Field vs Field comparisons as not pushable
diegotoledano95 Jul 30, 2026
5037e30
fix(mongodb): compute binary begins_with upper bound in hex-string space
diegotoledano95 Jul 30, 2026
c267a7f
fix(mongodb): implement transient table CREATING state
diegotoledano95 Jul 30, 2026
37ade14
chore(mongodb): adopt set_backend registration and adapt to post-#218…
diegotoledano95 Jul 30, 2026
267379c
chore(mongodb): populate TableKeyInfo secondary-index lists
diegotoledano95 Jul 30, 2026
2638d24
style(mongodb): satisfy cargo fmt check
diegotoledano95 Aug 4, 2026
1b48996
test(mongodb): cover restore reporting ACTIVE before the data copy co…
LeeroyHannigan Aug 4, 2026
254261a
fix(mongodb): set restored table ACTIVE only after the data copy comp…
diegotoledano95 Aug 4, 2026
b33abef
fix(mongodb): harden connection and credential handling
diegotoledano95 Aug 5, 2026
e764623
fix(mongodb): stop deriving Serialize on MongoStorageConfig
diegotoledano95 Aug 5, 2026
a8ff00b
fix(mongodb): scope restore backup lookup to the account
diegotoledano95 Aug 5, 2026
516245b
fix(devtools): isolate run-mongodb-tests container and output per run
diegotoledano95 Aug 5, 2026
5c0e7c5
test(rust): binary begins_with edges and field-vs-field conditions
diegotoledano95 Aug 5, 2026
895a160
ci(mongodb): add MongoDB integration workflow
diegotoledano95 Aug 5, 2026
1c0055e
fix(mongodb): warn when GSI backfill returns an empty, non-final batch
diegotoledano95 Aug 5, 2026
bdfe699
docs(mongodb): document f64-precision bound on inverted BETWEEN keys
diegotoledano95 Aug 5, 2026
fa59ff1
docs(mongodb): correct CI/test description and bump design doc to 7.0
diegotoledano95 Aug 5, 2026
71f1d64
test(rust): use a multi-byte all-0xFF begins_with prefix
diegotoledano95 Aug 5, 2026
53c0c49
fix(devtools): accept sqlite backend and don't abort on missing conne…
diegotoledano95 Aug 10, 2026
d873f65
chore(mongodb): adapt to in-tree SQLite backend
diegotoledano95 Aug 11, 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