perf(storage): add bulk plugin-storage upserts - #1098
Conversation
f2a006d to
5851d0a
Compare
Greptile SummaryThis PR adds a
Confidence Score: 5/5Safe to merge; the change is well-scoped and all policy-enforcement paths are covered by the new tests. Policy validation (both create and update) is enforced at the ORM layer before any adapter call. Empty-target and empty-update guards exist at both ORM and adapter levels. The native PG/SQLite path uses correct excluded.column references and parameter-aware batching. The ORM fallback for adapters without native upsertMany is logically sound. Cross-tenant write rejection and invalid-shape rejection are both tested. No correctness gaps were found in the changed paths. No files require special attention. test-config.ts bypasses the ORM fallback when calling upsertMany on the lazy test DB, but this is benign since the memory adapter always provides the method. Important Files Changed
Reviews (2): Last reviewed commit: "fix(fumadb): validate bulk upsert confli..." | Re-trigger Greptile |
## Summary - Mirror the upstream bulk-upsert validation hardening from UsefulSoftwareCo#1098. - Reject empty `upsertMany` conflict targets at the public FumaDB query boundary. - Add adapter-level empty-target guards for Drizzle and memory adapters. - Add a table-policy regression test for invalid bulk upsert target/update shapes. ## Validation - `bunx vitest run src/query/table-policy.test.ts` from `packages/core/fumadb` - `bunx oxlint --no-ignore --deny-warnings src/query/orm/index.ts src/adapters/drizzle/query.ts src/adapters/memory/index.ts src/query/table-policy.test.ts` from `packages/core/fumadb` - `git diff --check` ## Notes `bun run --cwd packages/core/fumadb typecheck` is currently blocked in this checkout by the existing missing `@libsql/client` import in `src/adapters/drizzle/runtime-ensure.test.ts`. Root oxlint intentionally ignores `packages/core/fumadb/`, so the file-level lint was run from the package with `--no-ignore`.
## Summary - Mirror the upstream bulk-upsert validation hardening from UsefulSoftwareCo#1098. - Reject empty `upsertMany` conflict targets at the public FumaDB query boundary. - Add adapter-level empty-target guards for Drizzle and memory adapters. - Add a table-policy regression test for invalid bulk upsert target/update shapes. ## Validation - `bunx vitest run src/query/table-policy.test.ts` from `packages/core/fumadb` - `bunx oxlint --no-ignore --deny-warnings src/query/orm/index.ts src/adapters/drizzle/query.ts src/adapters/memory/index.ts src/query/table-policy.test.ts` from `packages/core/fumadb` - `git diff --check` ## Notes `bun run --cwd packages/core/fumadb typecheck` is currently blocked in this checkout by the existing missing `@libsql/client` import in `src/adapters/drizzle/runtime-ensure.test.ts`. Root oxlint intentionally ignores `packages/core/fumadb/`, so the file-level lint was run from the package with `--no-ignore`.
788dd67 to
d34c58b
Compare
Add collection-level bulk methods to the OpenAPI store test stub so it satisfies the expanded PluginStorageCollectionFacade interface.
6da0c26 to
aa9c25e
Compare
The collection-level putMany/removeMany the branch added duplicate no production consumer; both call sites use the facade. Drop them and keep the branch to its real contribution, the atomic upsert implementation. Add a case proving a mid-batch failure leaves pre-existing rows intact, and make the fault injector unconditional so removing the transaction fails the test on the data rather than silently disarming it.
…sact generic bulk upserts
Summary
Add policy-safe bulk upserts to FumaDB and route plugin-storage batch writes through conflict upserts instead of delete-then-create loops.
API
AbstractQueryand the ORM adapter gain single-row and bulk upserts.batch()API.Proven consumers
The fork uses bulk writes for semantic-search indexing and OpenAPI operation replacement. This is an independent storage optimization, not a prerequisite for execution history.
Validation
PluginStorage.putMany.JSON aggregation, keyset pagination, and semantic-search behavior remain separate changes.