Core Architecture
Core Architecture
Relevant source files
The following files were used as context for generating this wiki page:
The @primebrick/dal-pg library is structured into four distinct layers that transform high-level TypeScript entity definitions into optimized, parameterized PostgreSQL queries. This architecture prioritizes type safety, performance for bulk operations, and strict SQL injection prevention.
Module Structure
The codebase is organized into functional modules that handle specific stages of the data lifecycle:
| Module | Purpose | Key Components |
|---|---|---|
| Meta | Entity definitions and type mapping | @Entity, getEntityPersistenceMeta, jsValueToPgParam |
| Query | DSL and SQL generation | Filter, Sort, buildSelectQuery, createStream |
| Repository | CRUD and Data Access Logic | Repository.find, Repository.addMany, Repository.update |
| DAL | Connection and Pool Management | Dal gateway, withClient, getDal |
Code
Sources: docs/ai/dal-architecture.md:5-29, src/index.ts:17-145
Data Flow: From Entity to SQL
The transition from "Natural Language Space" (TypeScript classes) to "Code Entity Space" (SQL execution) follows a structured pipeline:
- Metadata Extraction: Decorators like
@Entityand@Columnregister class properties in aWeakMap. The system usesReflect.getMetadata("design:type")to infer PostgreSQL types (e.g.,Datebecomestimestamptz). - Query Composition: Consumers use the Query DSL (
field('name').eq('value')) to build abstract filter trees. - SQL Building: The
buildSelectQueryfunction consumes the metadata and DSL to produce aSqlQueryobject containing a parameterized string and values. - Execution: The
Repositorysends the query to theDalgateway, which manages thepg.Pooland executes the command.
Mapping: TypeScript to PostgreSQL
The following diagram bridges the gap between TypeScript definitions and the underlying database schema managed by the DAL.
Code
Sources: docs/ai/dal-architecture.md:31-66, src/meta/entity-meta.ts:17-45
Subsystem Interconnections
Entity Metadata System
The metadata system is the source of truth for all operations. It defines how property names map to snake_case columns and which fields are used for soft-deletion or auditing. For details, see Entity Metadata System.
Type Coercion
This layer ensures that JavaScript types (like Date or BigInt) are correctly formatted for the node-pg driver and that values returning from the wire are hydrated back into the expected JS format.
For details, see Type Coercion: JS ↔ PostgreSQL.
Query DSL and SQL Builder
The DAL provides a functional DSL to avoid raw string manipulation. This system handles complex joins, projections, and filtering while enforcing strict identifier validation via assertValidIdentPart.
For details, see Query DSL and SQL Builder.
Repository and Bulk Strategies
The Repository class implements different strategies based on the operation scale. While single writes use standard INSERT/UPDATE, bulk updates utilize a TEMP TABLE strategy to maintain atomicity and performance.
For details, see Repository: CRUD and Finders and Streaming Large Result Sets.
SQL Execution Pipeline
This diagram illustrates how a call to repository.find() moves through the system.
Code
Sources: docs/ai/dal-architecture.md:67-110, src/query/query-builder.ts:77-83