14 KiB
Pairity Specifications
Status: IMPLEMENTATION
Architecture
Pairity is a partitioned‑model PHP ORM (DTO/DAO) that separates data representation (DTO) from persistence logic (DAO). It includes a Query Builder, relation management, raw SQL helpers, and a user friendly migration system.
-
Current DB Support:
- MySQL/MariaDB
- PostgreSQL
- SQLite
- SQL Server
- Oracle
-
Table Definitions
- Create YAML file to create new table.
- file names are used as table names.
relationskey in the YAML file can be used to define relationships.validationkey in the YAML file can be used to define validation rules.indexeskey in the YAML file can be used to define indexes.primarykey can define composite primary keys.prefixcan define table-specific prefixes.tenancykey to enable automatic tenant scoping.inheritancekey to define Single Table (STI) or Class Table (CTI) inheritance.morphkey to define polymorphic relationship targets.encryptedflag on columns for transparent AES-256 encryption.auditablekey to enable automatic change tracking/auditing.timestampskey in the YAML file can be used to enable timestamps.softDeleteskey in the YAML file can be used to enable soft deletes.
- Support for Database Views (mapping DTOs to SQL views).
- Update YAML file to modify existing tables.
- Run
pairity migrateto apply changes. - Run
pairity make:modelto generate DTO and DAO classes from YAML files.
- Create YAML file to create new table.
-
Schema Builder:
- Fluent PHP API for programmatic table creation and alteration.
- Acts as the underlying engine for YAML-driven migrations.
- Support for Schema Blueprints (PHP-based schema snapshots).
- Support for Schema Snapshotting (
make:yaml:snapshot) for baseline deployments. - Support for Dry Run previews via
migrate:dryrun.
-
Auditing & Change Tracking
- Built-in auditing system that automatically tracks changes to DTOs.
- Enabled via
auditable: truein YAML schema. - Records previous and current values, event type, and timestamps.
- Integration with
AuditListenerandAuditorservice.
-
Event Dispatcher & Lifecycle Hooks
- Robust event system for model lifecycle:
retrieved,creating,created,updating,updated,saving,saved,deleting,deleted. - Supports halting operations (e.g., validation) via "before" events.
- Wildcard listener support (e.g.,
pairity.model.*).
- Robust event system for model lifecycle:
-
Models:
- DTOs / Data Transfer Objects:
- immutable by default.
- Supports accessors and mutators.
- Supports validation.
- Supports casting (including native PHP Enums, Custom Cast Types, and Encrypted Attributes).
- Supports relations (including Lazy Loading via Ghost Objects and Polymorphism).
- Supports serialization (
toArray,toJson). - Supports hidden/exposed attributes for serialization.
- Supports Virtual/Computed Properties.
- Supports Inheritance Mapping (STI/CTI).
- Managed via Identity Map.
- Performance boosted by Pre-Generated Hydrators.
- DAOs / Data Access Objects:
- Provide CRUD and Mass Operations (Insert, Update, Delete).
- Support for Upserts (Insert or Update).
- Support for relations (including Polymorphic relations).
- Support for dynamic helpers.
- Support for Scopes (including Global Scopes, Soft Deletes, Automatic Multi-Tenancy, and Polymorphic Scopes).
- Support for Unit of Work (with Automatic Auditing).
- Support for Event System.
- Support for Migrations.
- Support for Schema Builder.
- Returns DTO, Pairity Collection, or Pairity Paginator.
- DTOs / Data Transfer Objects:
-
Query Builder:
- Supports raw SQL.
- Supports joins.
- Supports eager loading (Nested, Constrained, and Polymorphic).
- Supports pagination (Offset and Cursor).
- Supports Concurrency Control (Shared and Exclusive Locks).
- Supports Query Result Caching.
- Supports Async/Parallel Query Execution.
- Supports scopes.
- Supports casts.
- Supports custom helpers.
- Supports Read/Write Splitting.
- Supports Query Logging & Profiling.
- Supports Set Operations (Unions, Intersect, Except).
- Supports Driver-Specific Hints & Options.
- DOES NOT support NoSQL.
-
Framework Integration:
- Connection Management:
- Multi-database support with named connections.
- Explicit transaction control (
beginTransaction,commit,rollBack). - Support for Savepoints (nested transactions).
- Support for Connection Heartbeats and health checks via
db:check:health. - Support for Database Interceptors (Middleware).
- Seeding & Factories: Built-in support for dummy data and test state generation.
- Localization (i18n):
- Environment-driven language selection (
PAIRITY_LOCALE). - Localized exception messages and CLI output.
- Environment-driven language selection (
- Metadata Caching: Caching of hydrated schema to avoid repeated YAML parsing.
- Service Provider: Standardized entry point for framework integration.
- Connection Management:
Namespace
Pairity\
Package
getphred/pairity
Core Concepts
1. Partitioned Model (DTO/DAO Separation)
Pairity strictly separates data state from persistence logic.
- DTO (Data Transfer Object): Pure, immutable (by default) data carriers representing a single record. They are responsible for data integrity, casting, and validation, but have no knowledge of the database.
- DAO (Data Access Object): The persistence engine for a model. DAOs handle all database communication (CRUD, queries) and act as factories that produce DTOs.
2. YAML-Driven Schema
The database schema is defined in YAML files, which serve as the single source of truth. These files are used to:
- Generate and execute migrations.
- Generate DTO and DAO class code to ensure type safety and consistency.
3. Unified Query Builder
A fluent PHP interface for constructing SQL queries that works across all supported relational databases. It abstracts driver-specific syntax while allowing raw SQL for complex, non-portable optimizations.
4. Unit of Work
The Unit of Work tracks all changes made to DTOs during a business transaction. It coordinates the writing out of these changes and resolves concurrency issues, ensuring that the database remains in a consistent state.
5. Event-Driven Architecture
A robust event system that allows developers to hook into the lifecycle of DTOs and DAOs (e.g., beforeSave, afterUpdate, onDelete). This facilitates decoupled logic for auditing, cache invalidation, and complex validation.
6. CLI Tool (pairity)
The pairity CLI is a first-class citizen of the framework, providing essential developer tools for schema management, code generation, and maintenance. It includes specialized commands for schema evolution (migrate:dryrun), availability (db:check:health), and state synchronization (db:check:sync).
7. Identity Map
To maintain data consistency, Pairity uses an Identity Map to track all instantiated DTOs within a single request cycle. This ensures that fetching the same record multiple times returns the same object instance.
8. Connection Management
A centralized DatabaseManager handles multiple PDO connections, allowing the ORM to communicate with different databases or read/write replicas seamlessly.
9. Metadata Caching
To optimize performance, Pairity caches the processed YAML schema and table metadata using a PSR-16 cache. This minimizes filesystem I/O and YAML parsing during runtime.
10. Data Seeding & Factories
Pairity provides a robust system for seeding the database with initial data and generating complex DTO states via Factories, facilitating both development and testing.
11. Query Logging & Profiling
A centralized logging mechanism to capture all executed SQL queries, their execution time, and bound parameters. This is essential for debugging, performance optimization, and security audits.
12. Standardized Pagination
Pairity provides a dedicated Paginator object for paginated results. This object encapsulates the DTO collection along with metadata like total records, current page, and navigation helpers, ensuring a consistent API response.
13. Structured Exception Hierarchy
Pairity uses a custom exception hierarchy to provide clear, actionable error feedback. This avoids leaking raw database driver exceptions and allows developers to handle specific scenarios (e.g., RecordNotFoundException, QueryException) gracefully.
14. Localization (i18n)
To support global development, Pairity includes a localization layer. Exception messages and CLI output are translated based on the environment configuration (PAIRITY_LOCALE), facilitating better accessibility and debugging for developers across different regions.
15. DTO Serialization & Transformation
Pairity DTOs provide built-in support for transformation into array or JSON formats, making them ideal for use in modern APIs. This includes the ability to define "hidden" fields (e.g., sensitive data) that are excluded by default, and "exposed" fields that are included during serialization.
16. Concurrency Control (Locking)
To handle high-concurrency environments, Pairity provides both Optimistic and Pessimistic locking.
- Optimistic Locking: Automatic versioning via a
versioncolumn. - Pessimistic Locking: Support for Shared (Read) and Exclusive (Write) locks via the Query Builder (
sharedLock(),lockForUpdate()).
17. Multi-Tenancy & Data Isolation
Pairity supports enterprise-grade multi-tenancy through automatic scoping. By defining a tenant identifier in the YAML schema, the ORM automatically injects the necessary filters into all queries and inserts, ensuring strict data isolation between tenants with zero developer overhead.
18. Performance Optimization (Hydrators & Ghost Objects)
To achieve maximum performance, Pairity employs advanced optimization techniques:
- Pre-Generated Hydrators: Code-generated classes specialized for populating DTOs, bypassing slow reflection-based instantiation.
- Lazy Loading via Ghost Objects: Utilizing the Proxy pattern to instantiate DTOs for relations that only trigger a database query when a property is accessed.
19. Custom Extension & Interceptors
Developers can extend the ORM's core behavior through:
- Custom Cast Types: Defining reusable casting logic for unique data types (e.g., encryption, spatial data).
- Database Interceptors (Middleware): Hooking into the
DatabaseManagerto intercept and modify raw PDO calls for auditing, security, or custom logging. - Virtual Properties: Defining computed DTO attributes in YAML that behave as first-class fields.
20. Data Migrations & Procedural Transforms
Beyond schema changes, Pairity supports procedural data migrations. These are PHP-based scripts used to transform or move data using the ORM's business logic, ensuring complex data transitions are handled safely within the application's domain layer.
21. Polymorphic Relationships
Pairity allows a model to belong to more than one other type of model on a single association. This is implemented via morphTo, morphOne, and morphMany, allowing for flexible data structures like shared comment or attachment systems.
22. Table Inheritance Mapping
To support domain-driven design, Pairity provides two primary inheritance patterns:
- Single Table Inheritance (STI): Mapping multiple DTO types to a single database table using a discriminator column.
- Class Table Inheritance (CTI): Mapping a class hierarchy across multiple tables, with a base table for common attributes and specialized tables for extended data.
23. Auditing & Change Tracking
Pairity includes a built-in auditing system that automatically tracks changes to DTOs. When enabled in the YAML schema, the ORM records the previous and current values of attributes, the timestamp, and the user responsible for the change, facilitating compliance and security auditing.
24. Async & Parallel Query Execution
For high-performance applications using PHP Fibers or asynchronous runtimes (e.g., Swoole, RoadRunner), Pairity supports dispatching multiple independent queries in parallel. This maximizes database throughput and reduces total response time for data-heavy operations.
25. Attribute Encryption
Pairity provides native support for transparent attribute encryption. Sensitive data (PII) can be marked as encrypted in the YAML schema, and the ORM will automatically handle AES-256 encryption/decryption before storage and after retrieval, ensuring data-at-rest security.
26. Seed Squashing
To facilitate rapid environment setup, Pairity supports squashing individual seed files into a single, optimized baseline seed. This reduces the overhead of executing hundreds of separate seeder classes and provides a clean starting point for new development or staging environments.
CLI Actions
List of actions that the pairity tool can perform:
db:check:health: Verify database connection health and heartbeat.db:check:sync: Verify synchronization of manual migration files and seed files (excludes YAML to DB direct).db:seed: Seed the database with records.db:seed:squash: Squash all individual seed files into a single baseline seed for new environments.make:factory: Create a new Factory class for a model.make:migration: Create a manual migration file for custom SQL or data changes.make:model: Generate DTO and DAO classes from YAML schema definitions.make:seeder: Create a new Seeder class.make:yaml:fromdb: Reverse-engineer an existing database to generate YAML schema files.make:yaml:snapshot: Export the current YAML source of truth into a single SQL or PHP baseline snapshot.migrate: Apply pending schema changes defined in YAML files.migrate:dryrun: Preview all changes that would be run withmigrate(YAML to DB direct only).migrate:rollback: Roll back the last database migration.migration:data: Execute procedural PHP data migrations.