Skip to content

feat(core): add em.clone() and qb.insertFrom() for server-side row cloning#7365

Merged
B4nan merged 8 commits intonextfrom
feat/clone-insert-from
Apr 18, 2026
Merged

feat(core): add em.clone() and qb.insertFrom() for server-side row cloning#7365
B4nan merged 8 commits intonextfrom
feat/clone-insert-from

Conversation

@B4nan
Copy link
Copy Markdown
Member

@B4nan B4nan commented Mar 21, 2026

Summary

  • Adds qb.insertFrom(sourceQb, options?) — generates INSERT INTO ... SELECT with 3-tier column derivation: metadata-driven, select-field-driven, or explicit
  • Adds em.clone(entity, where?, overrides?, options?) — convenience method returning a hydrated entity, delegates to driver.nativeClone()
  • Handles TPT inheritance (multi-table inserts), embedded properties, M:1 FK preservation, version property reset
  • Works across all SQL drivers (SQLite, PostgreSQL, MySQL, MariaDB, MSSQL); MongoDB uses find+insert fallback

Closes #5820

🤖 Generated with Claude Code

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 21, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.64%. Comparing base (8808779) to head (cb16ab5).
⚠️ Report is 21 commits behind head on next.

Additional details and impacted files
@@           Coverage Diff            @@
##             next    #7365    +/-   ##
========================================
  Coverage   99.64%   99.64%            
========================================
  Files         262      262            
  Lines       26080    26270   +190     
  Branches     7207     6806   -401     
========================================
+ Hits        25987    26177   +190     
  Misses         88       88            
  Partials        5        5            

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@B4nan B4nan changed the title feat(core): add em.clone() and qb.insertFrom() for server-side row cloning feat(core): add em.clone() and qb.insertFrom() for server-side row cloning Mar 21, 2026
@B4nan B4nan marked this pull request as ready for review March 21, 2026 19:28
@B4nan B4nan force-pushed the feat/clone-insert-from branch 2 times, most recently from 630ea02 to 9f172a7 Compare April 1, 2026 14:53
B4nan and others added 8 commits April 14, 2026 09:23
…w cloning

Adds support for cloning database rows via INSERT...SELECT, avoiding data
round-trips through the application. Two layers:

- `qb.insertFrom(sourceQb)` — low-level QB method with 3-tier column
  derivation (metadata → select fields → explicit)
- `em.clone(entity, where, overrides)` — high-level convenience that
  returns a hydrated entity

Handles TPT inheritance (multi-table inserts), embedded properties,
M:1 FK preservation, version property reset, and works across all SQL
drivers. MongoDB uses find+insert fallback.

Closes #5820

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add curly braces to single-line if statements (eslint curly rule)
- Use AnyQueryBuilder<Entity> for insertFrom() parameter type
- Fix MsSqlNativeQueryBuilder JSR return type issue

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use QueryBuilder<any> for insertFrom() param (avoids never/any variance)
- Fix MongoDriver.nativeClone to handle PK value as where filter
- Add MongoDB test suite for em.clone() coverage
- Fix test entity definitions (Opt type, options typing)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… tests, refactor TPT filter

- Add Product entity with persist:false and formula to test filter branches
- Add Article/Company QB insertFrom tests for M:N and embedded filter branches
- Refactor TPT filter to reuse getCloneableProps()
- 72 tests total, 91.5% patch coverage

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…er checks

- Remove unreachable generated/formula checks in getCloneableProps (caught by persist:false first)
- Remove unreachable throw in resolveInsertFromColumns (meta always set)
- Fix TPT version check to use tableMeta instead of leafMeta
- Add MsSqlNativeQueryBuilder unit test for insertSubQuery delegation
- Add DatabaseDriver.nativeClone throw test
- Add MongoDriver "entity not found" test

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove unreachable `inherited` checks from getCloneableProps (never true
  for non-TPT via meta.props, and TPT uses ownProps which skips the check)
- Refactor tier 2 column resolver to filter instead of return []
- Fix TPT version check to use tableMeta.versionProperty
- Remove STI test entities (not needed for coverage)

Remaining 2 uncovered lines are TPT version property reset — requires
TPT entity with version column which needs deeper schema support.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…eaky abstraction

- Extract `buildCloneFields()` and `mapCloneOverrides()` from duplicated
  loops in nativeCloneSimple/nativeCloneTPT
- Use `for...of` instead of indexed loops for fieldNames iteration
- Remove `options.select` dual-purpose in NativeQueryBuilder — store
  columns directly in `insertSubQuery.columns`
- Remove empty `if` block in MySQL INSERT IGNORE handling
- Strip narrating-the-obvious comments from EM, MongoDriver, SqlDriver
- Fix `this.metadata` → `em.metadata` in em.clone() for consistency
- Remove unnecessary spread copy of overrides (mapDataToFieldNames
  already copies internally)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@B4nan B4nan force-pushed the feat/clone-insert-from branch from 9f172a7 to cb16ab5 Compare April 14, 2026 07:23
@B4nan B4nan changed the base branch from master to next April 18, 2026 14:31
@B4nan B4nan merged commit fed9b4a into next Apr 18, 2026
22 checks passed
@B4nan B4nan deleted the feat/clone-insert-from branch April 18, 2026 14:36
B4nan added a commit that referenced this pull request Apr 19, 2026
…w cloning (#7365)

## Summary

- Adds `qb.insertFrom(sourceQb, options?)` — generates `INSERT INTO ...
SELECT` with 3-tier column derivation: metadata-driven,
select-field-driven, or explicit
- Adds `em.clone(entity, where?, overrides?, options?)` — convenience
method returning a hydrated entity, delegates to `driver.nativeClone()`
- Handles TPT inheritance (multi-table inserts), embedded properties,
M:1 FK preservation, version property reset
- Works across all SQL drivers (SQLite, PostgreSQL, MySQL, MariaDB,
MSSQL); MongoDB uses find+insert fallback

Closes #5820

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
B4nan added a commit that referenced this pull request Apr 20, 2026
…w cloning (#7365)

## Summary

- Adds `qb.insertFrom(sourceQb, options?)` — generates `INSERT INTO ...
SELECT` with 3-tier column derivation: metadata-driven,
select-field-driven, or explicit
- Adds `em.clone(entity, where?, overrides?, options?)` — convenience
method returning a hydrated entity, delegates to `driver.nativeClone()`
- Handles TPT inheritance (multi-table inserts), embedded properties,
M:1 FK preservation, version property reset
- Works across all SQL drivers (SQLite, PostgreSQL, MySQL, MariaDB,
MSSQL); MongoDB uses find+insert fallback

Closes #5820

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The possibility of cloning entities

1 participant