Skip to content

feat: add ORM relationships, collections, and query specifications#28

Merged
markshust merged 6 commits intodevelopfrom
feature/orm-relationships
Apr 15, 2026
Merged

feat: add ORM relationships, collections, and query specifications#28
markshust merged 6 commits intodevelopfrom
feature/orm-relationships

Conversation

@markshust
Copy link
Copy Markdown
Collaborator

@markshust markshust commented Apr 14, 2026

Summary

  • Added relationship attributes (#[HasOne], #[HasMany], #[BelongsTo], #[BelongsToMany]) for declaring entity relationships via PHP attributes
  • Added explicit eager loading via with() on Repository and RepositoryQueryBuilder — no lazy loading, no proxies, no N+1 by design
  • Added nested eager loading with dot notation ('comments.author')
  • Added first-class pivot entities for many-to-many relationships (real Entity classes, not magic pivot accessors)
  • Added EntityCollection — typed, chainable collection with filter, map, sort, group, chunk, pluck
  • Added QuerySpecification interface and matching() for composable, named query logic (replaces Eloquent scopes)
  • Changed findAll()/findBy() return types from array to EntityCollection
  • Added relationship validation with loud, helpful error messages following Marko's error philosophy
  • Updated docs guides and package reference with new relationship, collection, and specification documentation

Test plan

  • All 565 database package tests passing (1791 assertions)
  • EntityCollection — 26 tests covering construction, filtering, sorting, grouping, chunking
  • Relationship attributes — 18 tests covering all 4 attribute types
  • RelationshipMetadata — 17 tests covering value object and type enum
  • EntityMetadataFactory — 26 tests covering relationship parsing
  • QuerySpecification — 10 tests covering interface, matching, composition
  • RelationshipLoader — 16 tests covering BelongsTo, HasOne, HasMany batch loading
  • BelongsToMany loading — 11 tests covering pivot entity resolution
  • Nested eager loading — 10 tests covering dot notation and multi-level loading
  • Repository with() — 16 tests covering eager loading integration and validation
  • RepositoryQueryBuilder — 11 tests covering with() and matching() on query builder
  • Return type migration — 9 tests covering EntityCollection return types
  • Relationship validation — 13 tests covering error messages for misconfigurations
  • Standards enforcement pass completed
  • Documentation updated (guides, package reference, README)

Closes #24

🤖 Generated with Claude Code

@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Apr 14, 2026
@markshust markshust force-pushed the feature/orm-relationships branch from 7fe6c89 to 0c52237 Compare April 14, 2026 18:53
markshust and others added 4 commits April 14, 2026 19:07
…ecifications to database package

Extends the Data Mapper database layer with explicit relationship loading,
typed entity collections, and composable query specifications — no lazy
loading, no proxies, no magic.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Production mode must be opt-in (MARKO_ENV=production) rather than the
silent default. When no env var is set, show full error details to align
with the loud errors principle.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The RepositoryInterface return types changed from array to
EntityCollection, so test stubs implementing the interface need
to match.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The awk-based sync script failed on multiline variables, leaving
dropdowns empty after each sync. Replaced with portable shell
loop that works on both macOS and Linux. Populated both templates
with all 71 packages. Also defaults error handler to development
mode when no MARKO_ENV is set (loud errors by default).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@markshust markshust force-pushed the feature/orm-relationships branch from 0c52237 to da19791 Compare April 14, 2026 23:08
markshust and others added 2 commits April 14, 2026 19:20
…er rebase

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
EntityMetadataFactory now validates EntityCollection (not just array) for
HasMany/BelongsToMany properties. RelationshipLoader wraps loaded entities
in EntityCollection when the target property is typed as such.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@markshust markshust merged commit 6e4a185 into develop Apr 15, 2026
@markshust markshust deleted the feature/orm-relationships branch April 15, 2026 14:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add ORM supporthttps://github.com/propelorm/Propel2

1 participant