VOOZH about

URL: https://deepwiki.com/hypervel/components/5-database-and-orm

⇱ Database and ORM | hypervel/components | DeepWiki


Loading...
Last indexed: 7 March 2026 (96fbab)
Menu

Database and ORM

Purpose and Scope

This document covers Hypervel's enhanced Eloquent ORM implementation, which builds on Hyperf's database layer to provide Laravel-compatible model functionality. The system includes advanced features for attribute casting, custom collections, event management, and coroutine-safe operations.

For query builder and relationship implementations, see Eloquent Model Foundation. For attribute casting and type conversion, see Model Attributes and Type Casting. For collection handling, see Model Collections and Resources. For pivot table management, see Relationships and Pivot Models.

Overview

Hypervel's ORM layer extends Hyperf's Eloquent implementation with Laravel-compatible APIs and coroutine-safe enhancements. The system provides:

  • Event Suppression: Context-based event control via withoutEvents() for coroutine isolation
  • Custom Query Builders: Attribute-based builder class resolution
  • Enhanced Attribute Casting: Date factory integration and custom caster support
  • Custom Collections: Declarative collection classes via attributes
  • Pivot Model Events: Event firing for composite key pivot deletions
  • Broadcasting Integration: Model-level channel routing
  • Quiet Operations: Event-free CRUD operations with *Quietly() methods

Model Class Hierarchy


Sources: src/core/src/Database/Eloquent/Model.php1-307 src/core/src/Database/Eloquent/Relations/Pivot.php1-63 src/core/src/Database/Eloquent/Relations/MorphPivot.php1-69

Model Traits and Concerns

The model system uses a trait-based architecture to compose functionality:

TraitPurposeKey Methods
HasAttributesAttribute casting and date handlinggetCasts(), asDateTime(), asDate()
HasBootableTraitsTrait initializationbootTraits(), initializeTraits()
HasCallbacksModel lifecycle hooksfireModelEvent(), registerModelEvent()
HasCollectionCustom collection resolutionnewCollection(), resolveCollectionFromAttribute()
HasGlobalScopesGlobal query scopesaddGlobalScope(), withoutGlobalScope()
HasLocalScopesLocal query scopesscopeActive(), etc.
HasObserversModel observersobserve(), flushEventListeners()
HasRelationsEager loadingload(), loadMissing()
HasRelationshipsRelationship definitionshasMany(), belongsTo(), etc.
HasTimestampsTimestamp managementfreshTimestamp()
TransformsToResourceAPI resource conversiontoResource(), toResourceCollection()

Sources: src/core/src/Database/Eloquent/Model.php77-87

Event Suppression and Coroutine Isolation

withoutEvents() Context Management

The withoutEvents() method provides coroutine-safe event suppression using Hyperf's Context storage. This allows operations to execute without triggering model events while maintaining isolation between concurrent requests.


Sources: src/core/src/Database/Eloquent/Model.php186-214 tests/Database/Eloquent/EloquentModelWithoutEventsTest.php23-38

Context Key Format

Each model class uses a unique context key to isolate event suppression:

__database.model.without_events.{ModelClassName}

This allows different model classes to have independent event suppression states within the same coroutine.

Implementation Details:

Sources: src/core/src/Database/Eloquent/Model.php198-214 tests/Database/Eloquent/EloquentModelWithoutEventsTest.php90-113

Quiet Operation Methods

The model provides convenience methods for common operations without events:

MethodPurposeSource Line
saveQuietly()Save without firing eventssrc/core/src/Database/Eloquent/Model.php227-230
pushQuietly()Save with relationships, no eventssrc/core/src/Database/Eloquent/Model.php219-222
updateQuietly()Update attributes without eventssrc/core/src/Database/Eloquent/Model.php238-245
deleteQuietly()Delete without eventssrc/core/src/Database/Eloquent/Model.php271-274
incrementQuietly()Increment column without eventssrc/core/src/Database/Eloquent/Model.php251-256
decrementQuietly()Decrement column without eventssrc/core/src/Database/Eloquent/Model.php261-266
replicateQuietly()Clone model without eventssrc/core/src/Database/Eloquent/Model.php279-282

All quiet methods internally use withoutEvents() to suppress event dispatching.

Sources: src/core/src/Database/Eloquent/Model.php217-282

Custom Query Builders

UseEloquentBuilder Attribute

Models can declare custom query builder classes using the UseEloquentBuilder attribute. This enables type-safe, model-specific query methods.


Sources: src/core/src/Database/Eloquent/Model.php119-149

Builder Resolution Flow

The builder resolution process:

  1. Check static cache $resolvedBuilderClasses[ModelClass] src/core/src/Database/Eloquent/Model.php121-122
  2. If not cached, call resolveCustomBuilderClass() src/core/src/Database/Eloquent/Model.php138-149
  3. Use reflection to find UseEloquentBuilder attribute src/core/src/Database/Eloquent/Model.php140-141
  4. Return attribute's builder class or false if not found src/core/src/Database/Eloquent/Model.php143-148
  5. Cache result for subsequent calls src/core/src/Database/Eloquent/Model.php121-122
  6. Instantiate builder with query instance src/core/src/Database/Eloquent/Model.php124-130

Sources: src/core/src/Database/Eloquent/Model.php119-149

Broadcasting Integration

Models implement the HasBroadcastChannel interface to provide automatic channel routing for WebSocket broadcasting.

Channel Naming

The model generates two types of channel identifiers:

MethodPurposeFormatExample
broadcastChannelRoute()Route definition patternNamespace.Class.{camelParam}App.Models.User.{user}
broadcastChannel()Instance-specific channelNamespace.Class.{keyValue}App.Models.User.123

Implementation:


Sources: src/core/src/Database/Eloquent/Model.php151-159

Attribute Casting System

Cast Resolution and Caching

The casting system supports multiple cast types with efficient caching:


Sources: src/core/src/Database/Eloquent/Concerns/HasAttributes.php16-72

Cast Type Support

The system supports multiple cast types:

Cast TypeResolutionExample
SimpleBuilt-in PHP types'active' => 'bool'
ParameterizedClass with constructor args'data' => 'encrypted:aes-256'
CastableClass implementing CastableCustom cast classes
ObjectDirect caster instancePre-configured caster

Cast String Parsing:

When a cast type contains parameters (e.g., encrypted:aes-256):

  1. Split on : to separate class and arguments src/core/src/Database/Eloquent/Concerns/HasAttributes.php40-44
  2. Split arguments on , for multiple parameters src/core/src/Database/Eloquent/Concerns/HasAttributes.php44
  3. Pass arguments to caster constructor src/core/src/Database/Eloquent/Concerns/HasAttributes.php55

Sources: src/core/src/Database/Eloquent/Concerns/HasAttributes.php30-72

Date Factory Integration

The HasAttributes trait integrates with the Date facade to respect application-wide date class configuration:


Sources: src/core/src/Database/Eloquent/Concerns/HasAttributes.php84-142 tests/Core/Database/Eloquent/Concerns/DateFactoryTest.php1-352

Date Conversion Methods

MethodPurposeTime ComponentSource
asDateTime()Full datetime parsingPreserves timesrc/core/src/Database/Eloquent/Concerns/HasAttributes.php101-142
asDate()Date-only parsingSets to 00:00:00src/core/src/Database/Eloquent/Concerns/HasAttributes.php90-93

Both methods delegate to the Date facade, ensuring consistent use of the configured date class (e.g., Carbon or CarbonImmutable).

Date Value Type Handling:

  1. CarbonInterface: Wrap in configured class via Date::instance() src/core/src/Database/Eloquent/Concerns/HasAttributes.php106-108
  2. DateTimeInterface: Parse formatted string via Date::parse() src/core/src/Database/Eloquent/Concerns/HasAttributes.php113-118
  3. Numeric: Create from timestamp via Date::createFromTimestamp() src/core/src/Database/Eloquent/Concerns/HasAttributes.php123-125
  4. Y-m-d format: Use Carbon's format parser then wrap src/core/src/Database/Eloquent/Concerns/HasAttributes.php130-132
  5. Other strings: Parse via configured format or fallback src/core/src/Database/Eloquent/Concerns/HasAttributes.php134-141

Sources: src/core/src/Database/Eloquent/Concerns/HasAttributes.php84-142

Collection System

Collection Class Resolution

Models can specify custom collection classes through two mechanisms with attribute taking precedence:


Sources: src/core/src/Database/Eloquent/Concerns/HasCollection.php1-60

Collection Resolution Priority

The resolution follows this priority:

  1. Static Cache: Check $resolvedCollectionClasses[ModelClass] src/core/src/Database/Eloquent/Concerns/HasCollection.php37
  2. CollectedBy Attribute: Use reflection to find attribute src/core/src/Database/Eloquent/Concerns/HasCollection.php47-58
  3. $collectionClass Property: Fall back to property value src/core/src/Database/Eloquent/Concerns/HasCollection.php37
  4. Default: Use Collection::class src/core/src/Database/Eloquent/Model.php97

Cache Implementation:


Sources: src/core/src/Database/Eloquent/Concerns/HasCollection.php35-40 tests/Core/Database/Eloquent/Concerns/HasCollectionTest.php138-147

Eloquent Collection Features

The Hypervel\Database\Eloquent\Collection class extends Hyperf's base collection with:

FeatureMethodReturn TypePurpose
Resource TransformationtoResource()JsonResourceConvert to API resource
Resource CollectiontoResourceCollection()ResourceCollectionConvert to resource collection
Flexible Findfind($key)`ModelCollection`
Base CollectiontoBase()SupportCollectionConvert to non-Eloquent collection

Type-Safe Map Operation:

The map() method intelligently returns an Eloquent collection if all items are models, otherwise returns a base collection src/core/src/Database/Eloquent/Collection.php129-136:


Sources: src/core/src/Database/Eloquent/Collection.php1-145

Pivot Model Enhancements

Event-Aware Pivot Deletion

Both Pivot and MorphPivot classes override the delete() method to fire events even for composite key pivots:


Sources: src/core/src/Database/Eloquent/Relations/Pivot.php41-62 src/core/src/Database/Eloquent/Relations/MorphPivot.php42-68

Pivot vs MorphPivot Deletion

The key difference between Pivot and MorphPivot deletion:

ClassAdditional ConstraintSource
PivotNonesrc/core/src/Database/Eloquent/Relations/Pivot.php55
MorphPivotAdds WHERE morph_type = ?src/core/src/Database/Eloquent/Relations/MorphPivot.php59

MorphPivot Query Construction:


Sources: src/core/src/Database/Eloquent/Relations/MorphPivot.php56-61

Pivot Model Traits

Both Pivot and MorphPivot include the same enhanced trait set as the base Model class:


This ensures pivot models have the same capabilities as regular models, including:

Sources: src/core/src/Database/Eloquent/Relations/Pivot.php18-24 src/core/src/Database/Eloquent/Relations/MorphPivot.php19-24 tests/Core/Database/Eloquent/Relations/PivotCollectionTest.php1-257

Timestamp Management

Date Facade Integration

The HasTimestamps trait overrides Hyperf's timestamp generation to use the Date facade:


This ensures all timestamp fields respect the application's configured date class (e.g., CarbonImmutable).

Sources: src/core/src/Database/Eloquent/Concerns/HasTimestamps.php1-28

Timestamp Application Points

The freshTimestamp() method is called automatically when:

  • Creating new models (sets created_at and updated_at)
  • Updating existing models (updates updated_at)
  • Using touch() to update timestamps manually

Global Date Class Configuration:


Sources: tests/Core/Database/Eloquent/Concerns/DateFactoryTest.php110-129 tests/Core/Database/Eloquent/Concerns/DateFactoryTest.php250-269

Route Model Binding

UrlRoutable Implementation

The Model class implements the UrlRoutable interface to enable automatic route model binding:


This allows models to be automatically resolved from route parameters:


Custom Route Keys:

Override getRouteKeyName() in your model to use a different column:


Sources: src/core/src/Database/Eloquent/Model.php108-111

Summary

The Hypervel Database and ORM system provides:

  1. Coroutine-Safe Event Management: Context-based event suppression with withoutEvents() and quiet operation methods
  2. Custom Query Builders: Attribute-based builder resolution via UseEloquentBuilder
  3. Advanced Attribute Casting: Date factory integration, custom casters, and parameterized casts
  4. Flexible Collection System: Declarative collection classes via CollectedBy attribute with property fallback
  5. Enhanced Pivot Models: Event firing for composite key deletions with morph type constraints
  6. Broadcasting Integration: Automatic channel routing via HasBroadcastChannel interface
  7. Route Model Binding: Laravel-compatible UrlRoutable implementation

The system maintains full compatibility with Hyperf's coroutine architecture while providing Laravel-familiar APIs and enhanced functionality.

Sources: src/core/src/Database/Eloquent/Model.php1-307 src/core/src/Database/Eloquent/Relations/Pivot.php1-63 src/core/src/Database/Eloquent/Relations/MorphPivot.php1-69 src/core/src/Database/Eloquent/Collection.php1-145 src/core/src/Database/Eloquent/Concerns/HasAttributes.php1-143 src/core/src/Database/Eloquent/Concerns/HasCollection.php1-60 src/core/src/Database/Eloquent/Concerns/HasTimestamps.php1-28