@venizia/ignis-docs 0.2.0 → 0.2.1-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -14
- package/content/best-practices/api-usage-examples.md +39 -19
- package/content/best-practices/architectural-patterns.md +22 -11
- package/content/best-practices/architecture-decisions.md +29 -16
- package/content/best-practices/code-style-standards/advanced-patterns.md +43 -31
- package/content/best-practices/code-style-standards/constants-configuration.md +19 -4
- package/content/best-practices/code-style-standards/control-flow.md +33 -1
- package/content/best-practices/code-style-standards/documentation.md +28 -8
- package/content/best-practices/code-style-standards/function-patterns.md +15 -4
- package/content/best-practices/code-style-standards/index.md +7 -2
- package/content/best-practices/code-style-standards/naming-conventions.md +26 -2
- package/content/best-practices/code-style-standards/route-definitions.md +9 -5
- package/content/best-practices/code-style-standards/tooling.md +14 -1
- package/content/best-practices/code-style-standards/type-safety.md +39 -6
- package/content/best-practices/common-pitfalls.md +59 -35
- package/content/best-practices/contribution-workflow.md +6 -2
- package/content/best-practices/data-modeling.md +78 -62
- package/content/best-practices/deployment-strategies.md +56 -19
- package/content/best-practices/error-handling.md +182 -93
- package/content/best-practices/index.md +6 -0
- package/content/best-practices/performance-optimization.md +26 -13
- package/content/best-practices/security-guidelines.md +35 -9
- package/content/best-practices/testing-strategies.md +7 -2
- package/content/best-practices/troubleshooting-tips.md +27 -17
- package/content/extensions/components/api-reference.md +107 -322
- package/content/extensions/components/authentication/api.md +454 -603
- package/content/extensions/components/authentication/errors.md +121 -498
- package/content/extensions/components/authentication/index.md +88 -801
- package/content/extensions/components/authentication/usage.md +207 -956
- package/content/extensions/components/authorization/api.md +736 -656
- package/content/extensions/components/authorization/errors.md +168 -206
- package/content/extensions/components/authorization/index.md +82 -797
- package/content/extensions/components/authorization/usage.md +194 -527
- package/content/extensions/components/health-check.md +71 -243
- package/content/extensions/components/mail/api.md +504 -287
- package/content/extensions/components/mail/errors.md +73 -61
- package/content/extensions/components/mail/index.md +96 -467
- package/content/extensions/components/mail/usage.md +130 -172
- package/content/extensions/components/request-tracker.md +66 -173
- package/content/extensions/components/socket-io/api.md +195 -13
- package/content/extensions/components/socket-io/errors.md +3 -3
- package/content/extensions/components/socket-io/index.md +50 -337
- package/content/extensions/components/socket-io/usage.md +143 -26
- package/content/extensions/components/static-asset/api.md +410 -142
- package/content/extensions/components/static-asset/errors.md +110 -53
- package/content/extensions/components/static-asset/index.md +79 -608
- package/content/extensions/components/static-asset/usage.md +180 -300
- package/content/extensions/components/websocket/api.md +275 -399
- package/content/extensions/components/websocket/errors.md +47 -56
- package/content/extensions/components/websocket/index.md +74 -407
- package/content/extensions/components/websocket/usage.md +110 -341
- package/content/extensions/helpers/cron/index.md +51 -160
- package/content/extensions/helpers/crypto/index.md +62 -483
- package/content/extensions/helpers/crypto/reference.md +456 -0
- package/content/extensions/helpers/env/index.md +60 -178
- package/content/extensions/helpers/error/index.md +221 -207
- package/content/extensions/helpers/inversion/index.md +65 -556
- package/content/extensions/helpers/inversion/reference.md +522 -0
- package/content/extensions/helpers/kafka/admin.md +20 -1
- package/content/extensions/helpers/kafka/compile-binary.md +41 -35
- package/content/extensions/helpers/kafka/consumer.md +54 -20
- package/content/extensions/helpers/kafka/examples.md +21 -16
- package/content/extensions/helpers/kafka/index.md +80 -610
- package/content/extensions/helpers/kafka/producer.md +134 -5
- package/content/extensions/helpers/kafka/schema-registry.md +45 -70
- package/content/extensions/helpers/logger/hf-logger.md +193 -0
- package/content/extensions/helpers/logger/index.md +64 -563
- package/content/extensions/helpers/logger/pino.md +85 -0
- package/content/extensions/helpers/logger/reference.md +746 -0
- package/content/extensions/helpers/network/api.md +241 -195
- package/content/extensions/helpers/network/index.md +72 -530
- package/content/extensions/helpers/queue/index.md +72 -900
- package/content/extensions/helpers/queue/reference.md +467 -0
- package/content/extensions/helpers/redis/index.md +73 -645
- package/content/extensions/helpers/redis/reference.md +727 -0
- package/content/extensions/helpers/secrets/index.md +66 -0
- package/content/extensions/helpers/socket-io/api.md +305 -203
- package/content/extensions/helpers/socket-io/index.md +66 -432
- package/content/extensions/helpers/storage/api.md +564 -462
- package/content/extensions/helpers/storage/index.md +77 -573
- package/content/extensions/helpers/types/index.md +66 -499
- package/content/extensions/helpers/types/reference.md +650 -0
- package/content/extensions/helpers/uid/index.md +58 -227
- package/content/extensions/helpers/websocket/api.md +329 -216
- package/content/extensions/helpers/websocket/index.md +65 -503
- package/content/extensions/helpers/worker-thread/index.md +58 -396
- package/content/extensions/helpers/worker-thread/reference.md +428 -0
- package/content/guides/core-concepts/persistent/models.md +1 -1
- package/content/guides/core-concepts/persistent/search-typesense.md +3 -3
- package/content/guides/core-concepts/persistent/transactions.md +1 -1
- package/content/guides/core-concepts/secrets-vault.md +177 -0
- package/content/guides/core-concepts/services.md +1 -1
- package/content/guides/migrations/redis-helpers-migration.md +1 -1
- package/content/guides/migrations/unified-connectors-migration.md +2 -2
- package/content/guides/tutorials/ecommerce-api.md +3 -8
- package/content/references/base/application.md +1 -1
- package/content/references/base/connectors.md +79 -136
- package/content/references/base/datasources-reference.md +599 -0
- package/content/references/base/datasources.md +84 -444
- package/content/references/base/dependency-injection.md +17 -39
- package/content/references/base/filter-system/application-usage.md +69 -121
- package/content/references/base/filter-system/array-operators.md +12 -0
- package/content/references/base/filter-system/comparison-operators.md +12 -0
- package/content/references/base/filter-system/default-filter.md +136 -348
- package/content/references/base/filter-system/fields-order-pagination.md +38 -16
- package/content/references/base/filter-system/index.md +106 -257
- package/content/references/base/filter-system/json-filtering.md +12 -2
- package/content/references/base/filter-system/list-operators.md +16 -2
- package/content/references/base/filter-system/logical-operators.md +13 -0
- package/content/references/base/filter-system/null-operators.md +13 -0
- package/content/references/base/filter-system/pattern-matching.md +12 -0
- package/content/references/base/filter-system/quick-reference.md +11 -2
- package/content/references/base/filter-system/range-operators.md +12 -0
- package/content/references/base/filter-system/tips.md +70 -133
- package/content/references/base/filter-system/use-cases.md +156 -233
- package/content/references/base/middlewares.md +35 -21
- package/content/references/base/models-reference.md +886 -0
- package/content/references/base/models.md +80 -1452
- package/content/references/base/repositories/advanced.md +156 -192
- package/content/references/base/repositories/index.md +77 -650
- package/content/references/base/repositories/mixins.md +22 -18
- package/content/references/base/repositories/relations.md +123 -171
- package/content/references/base/repositories/soft-deletable.md +58 -56
- package/content/references/base/secrets.md +263 -0
- package/content/references/base/services.md +2 -2
- package/content/references/configuration/environment-variables.md +48 -4
- package/content/references/configuration/index.md +49 -31
- package/content/references/quick-reference.md +3 -16
- package/content/references/utilities/crypto.md +35 -76
- package/content/references/utilities/date.md +33 -73
- package/content/references/utilities/index.md +1 -1
- package/content/references/utilities/jsx-reference.md +298 -0
- package/content/references/utilities/jsx.md +82 -525
- package/content/references/utilities/module.md +29 -62
- package/content/references/utilities/parse.md +34 -64
- package/content/references/utilities/performance.md +33 -58
- package/content/references/utilities/promise.md +28 -62
- package/content/references/utilities/request.md +57 -218
- package/content/references/utilities/schema.md +43 -137
- package/content/references/utilities/statuses-reference.md +361 -0
- package/content/references/utilities/statuses.md +63 -667
- package/package.json +8 -8
|
@@ -1,222 +1,22 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: DataSources
|
|
3
|
-
description:
|
|
2
|
+
title: DataSources
|
|
3
|
+
description: Manage the connection to a database or search engine with a DataSource class
|
|
4
4
|
difficulty: intermediate
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
#
|
|
7
|
+
# DataSources
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
A datasource owns the connection to a database (or search engine).
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
> IGNIS splits datasources into an **engine-neutral root** (`src/base/datasources/`) and **per-engine connectors** (`src/connectors/{postgres,typesense}/datasources/`). `AbstractDataSource` has no SQL, no Drizzle, and no `pool` - those live only in the PostgreSQL connector. See [Connectors](./connectors) for the full base-vs-connectors architecture, dual-door exports, and how to add a new engine. This page documents the neutral contract plus the PostgreSQL connector in depth; see [Search & Typesense](/guides/core-concepts/persistent/search-typesense) for the other engine.
|
|
11
|
+
## In one example
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
## Quick Reference
|
|
17
|
-
|
|
18
|
-
| Class/Interface | Purpose | Key Members |
|
|
19
|
-
|-----------------|---------|-------------|
|
|
20
|
-
| **IDataSource** | Engine-neutral contract for all datasources | `name`, `settings`, `schema`, `getSchema()`, `getSettings()`, `configure()` |
|
|
21
|
-
| **AbstractDataSource** | Engine-neutral base implementation with logging | Extends `BaseHelper`, `getCapabilities()` defaults to `{ transactions: false }`, `beginTransaction()` defaults to `throwNotSupported(...)` |
|
|
22
|
-
| **AbstractPostgresDataSource** | PostgreSQL-aware abstraction | Adds `connector`, `client`, `driver`, abstract `getConnectionString()`/`beginTransaction()` |
|
|
23
|
-
| **BasePostgresDataSource** | Concrete class to extend for PostgreSQL | Auto-discovery, real transaction support, constructor with config. Canonical name - `BaseDataSource` is a compatibility alias re-exporting the same class |
|
|
24
|
-
| **ITransaction** | Engine-neutral transaction contract | `isActive`, `commit()`, `rollback()` (no connector field) |
|
|
25
|
-
| **IDatabaseTransaction** | PostgreSQL transaction object | Extends `ITransaction`, adds `connector`, `isolationLevel` |
|
|
26
|
-
| **IsolationLevels** | Isolation level constants (PostgreSQL) | `READ_COMMITTED`, `REPEATABLE_READ`, `SERIALIZABLE` |
|
|
27
|
-
|
|
28
|
-
## `IDataSource` Interface
|
|
29
|
-
|
|
30
|
-
Engine-neutral contract implemented by every datasource in the framework, regardless of engine.
|
|
31
|
-
|
|
32
|
-
**File:** `packages/core/src/base/datasources/common/types.ts`
|
|
33
|
-
|
|
34
|
-
### Type Parameters
|
|
35
|
-
|
|
36
|
-
```typescript
|
|
37
|
-
interface IDataSource<
|
|
38
|
-
Settings extends object = {},
|
|
39
|
-
Schema extends TAnyDataSourceSchema = TAnyDataSourceSchema,
|
|
40
|
-
ConfigurableOptions extends object = {},
|
|
41
|
-
> extends IConfigurable<ConfigurableOptions>
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
| Type Parameter | Default | Description |
|
|
45
|
-
|----------------|---------|-------------|
|
|
46
|
-
| `Settings` | `{}` | Connection configuration type (host, port, etc.) |
|
|
47
|
-
| `Schema` | `TAnyDataSourceSchema` | Combined schema type (shape depends on the connector - Drizzle tables for PostgreSQL, collection definitions for typesense) |
|
|
48
|
-
| `ConfigurableOptions` | `{}` | Options passed to `configure()` |
|
|
49
|
-
|
|
50
|
-
### Properties & Methods
|
|
51
|
-
|
|
52
|
-
| Member | Type | Description |
|
|
53
|
-
|--------|------|-------------|
|
|
54
|
-
| `name` | `string` | Datasource name |
|
|
55
|
-
| `settings` | `Settings` | Configuration object |
|
|
56
|
-
| `schema` | `Schema` | Combined schema (auto-discovered or manual) |
|
|
57
|
-
| `getSchema()` | `Schema` | Returns combined schema |
|
|
58
|
-
| `getSettings()` | `Settings` | Returns connection settings |
|
|
59
|
-
| `configure(opts?)` | `ValueOrPromise<void>` | Initializes the underlying connection (from `IConfigurable`) |
|
|
60
|
-
|
|
61
|
-
> [!NOTE]
|
|
62
|
-
> `getCapabilities()` and `beginTransaction()` are not part of the `IDataSource` interface - they are declared on `AbstractDataSource` (below), which every connector extends.
|
|
63
|
-
|
|
64
|
-
## `AbstractDataSource` (Engine-Neutral Root)
|
|
65
|
-
|
|
66
|
-
**File:** `packages/core/src/base/datasources/abstract.ts`
|
|
67
|
-
|
|
68
|
-
Top-level abstract class implemented by every engine. Extends `BaseHelper` for scoped logging. Contains **no SQL, no Drizzle, and no connection-pool members** - those are added by each connector.
|
|
69
|
-
|
|
70
|
-
```typescript
|
|
71
|
-
abstract class AbstractDataSource<
|
|
72
|
-
Settings extends object = {},
|
|
73
|
-
Schema extends TAnyDataSourceSchema = TAnyDataSourceSchema,
|
|
74
|
-
ConfigurableOptions extends object = {},
|
|
75
|
-
> extends BaseHelper implements IDataSource<Settings, Schema, ConfigurableOptions>
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
**Properties:**
|
|
79
|
-
|
|
80
|
-
| Property | Type | Visibility | Description |
|
|
81
|
-
|----------|------|------------|-------------|
|
|
82
|
-
| `name` | `string` | public | Datasource identifier |
|
|
83
|
-
| `settings` | `Settings` | public | Connection configuration |
|
|
84
|
-
| `schema` | `Schema` | public | Combined schema |
|
|
85
|
-
|
|
86
|
-
**Abstract methods** (must be implemented by connectors):
|
|
87
|
-
|
|
88
|
-
| Method | Return Type | Description |
|
|
89
|
-
|--------|-------------|-------------|
|
|
90
|
-
| `configure(opts?)` | `ValueOrPromise<void>` | Initialize the underlying connection |
|
|
91
|
-
| `getConnectionString()` | `ValueOrPromise<string>` | Return the connection URL |
|
|
92
|
-
|
|
93
|
-
**Concrete methods (defaults, overridable by connectors):**
|
|
94
|
-
|
|
95
|
-
| Method | Return Type | Default Behavior |
|
|
96
|
-
|--------|-------------|-------------------|
|
|
97
|
-
| `getSettings()` | `Settings` | Returns `this.settings` |
|
|
98
|
-
| `getSchema()` | `Schema` | Returns `this.schema` (throws if not initialized) |
|
|
99
|
-
| `getCapabilities()` | `IDataSourceCapabilities` | Returns `{ transactions: false }` |
|
|
100
|
-
| `beginTransaction(opts?)` | `Promise<ITransaction>` | Calls `throwNotSupported({ scope: this.constructor.name, feature: 'Transactions', logger: this.logger })` - throws HTTP 501 with `messageCode: 'core.not_supported'` |
|
|
101
|
-
|
|
102
|
-
> [!NOTE] NotSupported convention
|
|
103
|
-
> Every capability an engine doesn't implement - transactions, row-level locking - uses the same `throwNotSupported` utility (`packages/core/src/utilities/error.utility.ts`), producing a consistent `501 Not Implemented` with `messageCode: 'core.not_supported'`. This is how the typesense connector signals "not applicable to this engine" instead of silently no-op-ing.
|
|
104
|
-
|
|
105
|
-
### `IDataSourceCapabilities`
|
|
13
|
+
The smallest real datasource: a `pg.Pool` wrapped in a class, wired to node-postgres via `@datasource`.
|
|
106
14
|
|
|
107
15
|
```typescript
|
|
108
|
-
interface IDataSourceCapabilities {
|
|
109
|
-
transactions: boolean;
|
|
110
|
-
}
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
Only `BasePostgresDataSource` overrides `getCapabilities()` to return `{ transactions: true }`. The typesense datasources inherit the neutral default.
|
|
114
|
-
|
|
115
|
-
## PostgreSQL Connector: `AbstractPostgresDataSource` & `BasePostgresDataSource`
|
|
116
|
-
|
|
117
|
-
**Files:** `packages/core/src/connectors/postgres/datasources/abstract.ts`, `packages/core/src/connectors/postgres/datasources/base.ts`
|
|
118
|
-
|
|
119
|
-
### `AbstractPostgresDataSource`
|
|
120
|
-
|
|
121
|
-
Extends `AbstractDataSource` with PostgreSQL/Drizzle-specific members.
|
|
122
|
-
|
|
123
|
-
```typescript
|
|
124
|
-
abstract class AbstractPostgresDataSource<
|
|
125
|
-
Settings extends object = {},
|
|
126
|
-
Schema extends TAnyDataSourceSchema = TAnyDataSourceSchema,
|
|
127
|
-
ConfigurableOptions extends object = {},
|
|
128
|
-
> extends AbstractDataSource<Settings, Schema, ConfigurableOptions>
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
**Additional properties:**
|
|
132
|
-
|
|
133
|
-
| Property | Type | Visibility | Description |
|
|
134
|
-
|----------|------|------------|-------------|
|
|
135
|
-
| `connector` | `TRelationalConnector<Schema>` | public | Drizzle ORM instance (any Drizzle pg driver satisfies this - see the driver seam below) |
|
|
136
|
-
| `driver` | `IRelationalDriver` | protected | The connection driver (`node-postgres` or `postgres-js`); built lazily by `wireDriverFromMetadata()` from the class named in `@datasource({ driver })`, or explicitly by `useDriver()` |
|
|
137
|
-
| `client` | `Client` (`Pool` by default) | protected | The raw driver client `configure()` built - a `pg.Pool`, or a postgres-js `Sql`. Assigning it alone is enough: `wireDriverFromMetadata()` instantiates the `@datasource({ driver })` class over it on first use. Absent once `useDriver()` wired a driver instead |
|
|
138
|
-
|
|
139
|
-
> [!NOTE] Driver seam
|
|
140
|
-
> `AbstractRelationalDataSource`/`BaseRelationalDataSource` (exported as `AbstractPostgresDataSource`/`BasePostgresDataSource`) now take a fourth generic - `<Settings, Schema, ConfigurableOptions, Client = Pool>` - so a `postgres-js` datasource can declare `Client = Sql` and keep `getClient()` honest. `@datasource({ driver })` names the driver **class** (`NodePostgresDriver` or `PostgresJsDriver`), never a string - a driver-name string cannot carry `pg`/`postgres` into the app's bundle, only a real class reference can. `configure()` only needs to assign `this.client`; the protected `wireDriverFromMetadata()` (called internally by `getConnector()`/`resolveDriver()`) instantiates the named class over it and builds `this.connector`, lazily and idempotently. The protected `useDriver({ driver, schema? })` stays available for a custom or third-party driver - it assigns `this.driver` **and** builds `this.connector` in one step, bypassing `@datasource({ driver })` entirely. `pg` and `postgres` are both optional peer dependencies; concrete drivers live at `@venizia/ignis/postgres/node-postgres` and `@venizia/ignis/postgres/postgres-js`, and Supabase support at `@venizia/ignis/postgres/supabase`. See [Postgres Drivers & Supabase](/guides/core-concepts/persistent/postgres-drivers).
|
|
141
|
-
|
|
142
|
-
**Additional abstract method:**
|
|
143
|
-
|
|
144
|
-
| Method | Return Type | Description |
|
|
145
|
-
|--------|-------------|-------------|
|
|
146
|
-
| `beginTransaction(opts?)` | `Promise<IDatabaseTransaction<Schema>>` | Start a new PostgreSQL transaction |
|
|
147
|
-
|
|
148
|
-
### `BasePostgresDataSource` (canonical name; `BaseDataSource` is a compatibility alias)
|
|
149
|
-
|
|
150
|
-
Extends `AbstractPostgresDataSource` with a constructor, **schema auto-discovery**, and a real `beginTransaction()` implementation backed by the connection pool.
|
|
151
|
-
|
|
152
|
-
```typescript
|
|
153
|
-
abstract class BasePostgresDataSource<
|
|
154
|
-
Settings extends object = {},
|
|
155
|
-
Schema extends TAnyDataSourceSchema = TAnyDataSourceSchema,
|
|
156
|
-
ConfigurableOptions extends object = {},
|
|
157
|
-
> extends AbstractPostgresDataSource<Settings, Schema, ConfigurableOptions>
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
> [!TIP] Naming
|
|
161
|
-
> `BasePostgresDataSource` is the canonical, engine-carrying name - prefer it in new code. `import { BaseDataSource } from '@venizia/ignis'` (or `@venizia/ignis/postgres`) still resolves to the exact same class via a re-export in `connectors/postgres/datasources/index.ts` (`export { BasePostgresDataSource as BaseDataSource } from './base-datasource'`), so existing code is unaffected.
|
|
162
|
-
|
|
163
|
-
#### Key Features
|
|
164
|
-
|
|
165
|
-
| Feature | Description |
|
|
166
|
-
|---------|--------------|
|
|
167
|
-
| **Schema Auto-Discovery** | Schema is automatically built from registered `@repository` decorators |
|
|
168
|
-
| **Manual Override** | You can manually provide schema in constructor for full control |
|
|
169
|
-
| **Built-in Transaction Support** | `beginTransaction()` acquires its connection from the resolved driver; overrides `getCapabilities()` to return `{ transactions: true }` |
|
|
170
|
-
|
|
171
|
-
> [!TIP]
|
|
172
|
-
> Set `autoDiscovery` to `false` in the `@datasource` decorator to disable automatic schema discovery. This is useful when you want to manually provide the schema.
|
|
173
|
-
|
|
174
|
-
### Constructor Options
|
|
175
|
-
|
|
176
|
-
```typescript
|
|
177
|
-
constructor(opts: {
|
|
178
|
-
name: string; // DataSource name (usually class name)
|
|
179
|
-
config: Settings; // Database connection settings
|
|
180
|
-
schema?: Schema; // Optional - auto-discovered if not provided
|
|
181
|
-
})
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
### Schema Auto-Discovery
|
|
185
|
-
|
|
186
|
-
When you use `@repository({ model: YourModel, dataSource: YourDataSource })`, the framework automatically:
|
|
187
|
-
|
|
188
|
-
1. Registers the model-datasource binding in the MetadataRegistry
|
|
189
|
-
2. When `getSchema()` is called, discovers all models bound to this datasource
|
|
190
|
-
3. Builds the combined schema (tables + relations) automatically
|
|
191
|
-
|
|
192
|
-
**This means you no longer need to manually merge tables and relations in the DataSource constructor!**
|
|
193
|
-
|
|
194
|
-
### Configuration Flow
|
|
195
|
-
|
|
196
|
-
1. **Your DataSource's `constructor` is called**:
|
|
197
|
-
- You call `super()` with `name` and `config`
|
|
198
|
-
- Schema is auto-discovered from `@repository` bindings (or manually provided via `schema`)
|
|
199
|
-
|
|
200
|
-
2. **`Application.registerDataSources()` is called during startup**:
|
|
201
|
-
- The application gets your `DataSource` instance from the DI container
|
|
202
|
-
- It calls the `configure()` method on your instance
|
|
203
|
-
|
|
204
|
-
3. **Your `configure()` method runs**:
|
|
205
|
-
- Create a `Pool` instance and assign it to `this.client` - that is the whole method
|
|
206
|
-
- `getConnector()`/`beginTransaction()` lazily instantiate the class named in `@datasource({ driver })` over `this.client` and build the Drizzle connector from it - your `configure()` never touches `this.connector` directly
|
|
207
|
-
|
|
208
|
-
### Example Implementations
|
|
209
|
-
|
|
210
|
-
#### Pattern 1: Auto-Discovery (Recommended)
|
|
211
|
-
|
|
212
|
-
Simplest approach - schema is auto-discovered from repositories:
|
|
213
|
-
|
|
214
|
-
```typescript
|
|
215
|
-
// src/datasources/postgres.datasource.ts
|
|
216
|
-
import { BasePostgresDataSource, datasource } from '@venizia/ignis';
|
|
217
|
-
import { NodePostgresDriver } from '@venizia/ignis/postgres/node-postgres';
|
|
218
|
-
import { applicationEnvironment, int, ValueOrPromise } from '@venizia/ignis-helpers';
|
|
219
16
|
import { Pool } from 'pg';
|
|
17
|
+
import { datasource } from '@venizia/ignis';
|
|
18
|
+
import { BasePostgresDataSource } from '@venizia/ignis/postgres';
|
|
19
|
+
import { NodePostgresDriver } from '@venizia/ignis/postgres/node-postgres';
|
|
220
20
|
|
|
221
21
|
interface IDataSourceConfigs {
|
|
222
22
|
host: string;
|
|
@@ -224,302 +24,142 @@ interface IDataSourceConfigs {
|
|
|
224
24
|
database: string;
|
|
225
25
|
user: string;
|
|
226
26
|
password: string;
|
|
227
|
-
ssl: boolean;
|
|
228
27
|
}
|
|
229
28
|
|
|
230
|
-
/**
|
|
231
|
-
* PostgresDataSource with auto-discovery support.
|
|
232
|
-
*
|
|
233
|
-
* How it works:
|
|
234
|
-
* 1. @repository decorator binds model to datasource
|
|
235
|
-
* 2. getSchema() auto-discovers all bound models when the driver/connector are wired
|
|
236
|
-
* 3. Naming NodePostgresDriver in @datasource is what wires the driver and Drizzle connector
|
|
237
|
-
*/
|
|
238
29
|
@datasource({ driver: NodePostgresDriver })
|
|
239
30
|
export class PostgresDataSource extends BasePostgresDataSource<IDataSourceConfigs> {
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
constructor() {
|
|
243
|
-
super({
|
|
244
|
-
name: PostgresDataSource.name,
|
|
245
|
-
config: {
|
|
246
|
-
host: applicationEnvironment.get<string>('APP_ENV_POSTGRES_HOST'),
|
|
247
|
-
port: int(applicationEnvironment.get<string>('APP_ENV_POSTGRES_PORT')),
|
|
248
|
-
database: applicationEnvironment.get<string>('APP_ENV_POSTGRES_DATABASE'),
|
|
249
|
-
user: applicationEnvironment.get<string>('APP_ENV_POSTGRES_USERNAME'),
|
|
250
|
-
password: applicationEnvironment.get<string>('APP_ENV_POSTGRES_PASSWORD'),
|
|
251
|
-
ssl: false,
|
|
252
|
-
},
|
|
253
|
-
// NO schema property - auto-discovered from @repository bindings!
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
override configure(): ValueOrPromise<void> {
|
|
258
|
-
const schema = Object.keys(this.getSchema());
|
|
259
|
-
this.logger.debug(
|
|
260
|
-
'[configure] Auto-discovered schema | Schema + Relations (%s): %o',
|
|
261
|
-
schema.length,
|
|
262
|
-
schema,
|
|
263
|
-
);
|
|
264
|
-
|
|
265
|
-
// That is all - the base class wires the driver + connector from @datasource({ driver }).
|
|
31
|
+
override configure(): void {
|
|
266
32
|
this.client = new Pool(this.settings);
|
|
267
33
|
}
|
|
268
34
|
|
|
269
|
-
override getConnectionString():
|
|
35
|
+
override getConnectionString(): string {
|
|
270
36
|
const { host, port, user, password, database } = this.settings;
|
|
271
|
-
return
|
|
37
|
+
return `postgresql://${user}:${password}@${host}:${port}/${database}`;
|
|
272
38
|
}
|
|
273
39
|
}
|
|
274
40
|
```
|
|
275
41
|
|
|
276
|
-
|
|
42
|
+
A `@repository` binds a model to `PostgresDataSource`, and the schema is auto-discovered from that binding - no manual schema wiring.
|
|
277
43
|
|
|
278
|
-
|
|
279
|
-
@repository({ model: User, dataSource: PostgresDataSource })
|
|
280
|
-
export class UserRepository extends DefaultCRUDRepository<typeof User.schema> {}
|
|
44
|
+
## How it works
|
|
281
45
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
46
|
+
- **Driver is a class, not a string.** `@datasource({ driver })` names `NodePostgresDriver` or `PostgresJsDriver` as a class reference - never a driver-name string. Only a real class reference carries `pg`/`postgres` into the application's bundle, so both stay genuinely optional peer dependencies.
|
|
47
|
+
- **`configure()` has exactly one job.** Build the raw client and assign it to `this.client` (a `pg.Pool` for node-postgres, or a postgres-js `Sql`). It never touches `this.connector` directly.
|
|
48
|
+
- **The driver wires lazily.** The first time `getConnector()` or `beginTransaction()` is called, the base class reads the class named in `@datasource({ driver })`, instantiates it over `this.client`, and builds `this.connector` from it.
|
|
49
|
+
- **Base vs. connector split.** IGNIS splits datasources into an engine-neutral root (`AbstractDataSource` - no SQL, no Drizzle, no pool) and per-engine connectors (`BasePostgresDataSource` for PostgreSQL, a parallel class for typesense). See [Connectors](/references/base/connectors) for the full architecture.
|
|
50
|
+
- **Naming.** The PostgreSQL connector's canonical class is `BaseRelationalDataSource`; `BasePostgresDataSource` and `BaseDataSource` are compatibility aliases re-exporting the same class.
|
|
285
51
|
|
|
286
|
-
|
|
52
|
+
## Common tasks
|
|
287
53
|
|
|
288
|
-
|
|
54
|
+
### Configure connection settings
|
|
289
55
|
|
|
290
|
-
|
|
56
|
+
Pass connection settings through the constructor's `config` option. `configure()` reads them back off `this.settings`.
|
|
291
57
|
|
|
292
58
|
```typescript
|
|
293
|
-
import {
|
|
294
|
-
import {
|
|
295
|
-
User, userTable, userRelations,
|
|
296
|
-
Configuration, configurationTable, configurationRelations,
|
|
297
|
-
} from '@/models/entities';
|
|
59
|
+
import { Pool } from 'pg';
|
|
60
|
+
import { applicationEnvironment, int } from '@venizia/ignis-helpers';
|
|
298
61
|
|
|
299
|
-
@datasource({ driver: NodePostgresDriver })
|
|
300
62
|
export class PostgresDataSource extends BasePostgresDataSource<IDataSourceConfigs> {
|
|
301
63
|
constructor() {
|
|
302
64
|
super({
|
|
303
65
|
name: PostgresDataSource.name,
|
|
304
66
|
config: {
|
|
305
|
-
host:
|
|
306
|
-
port:
|
|
307
|
-
database:
|
|
308
|
-
user:
|
|
309
|
-
password:
|
|
310
|
-
},
|
|
311
|
-
// Manually provide schema using spread syntax
|
|
312
|
-
schema: {
|
|
313
|
-
[User.TABLE_NAME]: userTable,
|
|
314
|
-
[Configuration.TABLE_NAME]: configurationTable,
|
|
315
|
-
...userRelations.relations,
|
|
316
|
-
...configurationRelations.relations,
|
|
67
|
+
host: applicationEnvironment.get<string>('APP_ENV_POSTGRES_HOST'),
|
|
68
|
+
port: int(applicationEnvironment.get<string>('APP_ENV_POSTGRES_PORT')),
|
|
69
|
+
database: applicationEnvironment.get<string>('APP_ENV_POSTGRES_DATABASE'),
|
|
70
|
+
user: applicationEnvironment.get<string>('APP_ENV_POSTGRES_USERNAME'),
|
|
71
|
+
password: applicationEnvironment.get<string>('APP_ENV_POSTGRES_PASSWORD'),
|
|
317
72
|
},
|
|
318
73
|
});
|
|
319
74
|
}
|
|
320
75
|
|
|
321
|
-
override configure():
|
|
322
|
-
// Manually-provided schema is used as-is by the connector the base class builds from this.client
|
|
76
|
+
override configure(): void {
|
|
323
77
|
this.client = new Pool(this.settings);
|
|
324
78
|
}
|
|
325
|
-
|
|
326
|
-
override getConnectionString(): ValueOrPromise<string> {
|
|
327
|
-
// ...
|
|
328
|
-
}
|
|
329
79
|
}
|
|
330
80
|
```
|
|
331
81
|
|
|
332
|
-
|
|
333
|
-
> Your `configure()` must leave the datasource with a way to reach the database: either assign the raw client to `this.client` (paired with naming the driver class in `@datasource({ driver })`), or wire a driver directly with `this.useDriver({ driver })` for a custom or third-party driver. `getConnector()`/`beginTransaction()` resolve the driver lazily from whichever you provided. With neither, it throws `No driver and no client`.
|
|
82
|
+
### Choose a driver
|
|
334
83
|
|
|
335
|
-
|
|
84
|
+
| Driver | Package | When to use |
|
|
85
|
+
|---|---|---|
|
|
86
|
+
| `NodePostgresDriver` | `pg` | Long-standing default |
|
|
87
|
+
| `PostgresJsDriver` | `postgres` | Required for Supabase's transaction pooler; faster elsewhere |
|
|
336
88
|
|
|
337
|
-
|
|
89
|
+
Swapping drivers only changes which class `@datasource` names and how `configure()` builds the client:
|
|
338
90
|
|
|
339
91
|
```typescript
|
|
340
|
-
@
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
| Method | Return Type | Description |
|
|
356
|
-
|--------|-------------|-------------|
|
|
357
|
-
| `configure(opts?)` | `ValueOrPromise<void>` | Initialize the client. Must set `this.client` (the base class wires the driver and Drizzle connector from `@datasource({ driver })`), or call `this.useDriver()` directly for a custom driver. |
|
|
358
|
-
| `getConnectionString()` | `ValueOrPromise<string>` | Return the database connection string. |
|
|
359
|
-
|
|
360
|
-
### Helper Methods
|
|
361
|
-
|
|
362
|
-
| Method | Description |
|
|
363
|
-
|--------|-------------|
|
|
364
|
-
| `getSchema()` | Returns the schema (auto-discovers via `discoverSchema()` if not manually provided) |
|
|
365
|
-
| `getSettings()` | Returns connection settings |
|
|
366
|
-
| `getConnector()` | Returns the Drizzle connector |
|
|
367
|
-
| `hasDiscoverableModels()` | Returns `true` if there are models registered for this datasource via `@repository` |
|
|
368
|
-
|
|
369
|
-
### Protected Methods
|
|
370
|
-
|
|
371
|
-
| Method | Description |
|
|
372
|
-
|--------|-------------|
|
|
373
|
-
| `discoverSchema()` | Queries the `MetadataRegistry` for all `@repository` bindings targeting this datasource, then calls `registry.buildSchema()` to merge tables and relations into a single schema object. |
|
|
374
|
-
|
|
375
|
-
## Connector Types
|
|
376
|
-
|
|
377
|
-
**File:** `packages/core/src/connectors/postgres/datasources/common/types.ts`
|
|
378
|
-
|
|
379
|
-
| Type | Description |
|
|
380
|
-
|------|-------------|
|
|
381
|
-
| `TRelationalConnector<Schema>` | Canonical connector type - a Drizzle `PgDatabase` that **every** pg driver (`node-postgres`, `postgres-js`) satisfies. Use this in new code. |
|
|
382
|
-
| `TNodePostgresConnector<Schema>` | **`@deprecated`** compat alias for `TRelationalConnector<Schema>` |
|
|
383
|
-
| `TNodePostgresTransactionConnector<Schema>` | **`@deprecated`** compat alias - was the `PoolClient`-specific transaction connector; now aliases `TRelationalConnector<Schema>` |
|
|
384
|
-
| `TAnyConnector<Schema>` | Alias of `TRelationalConnector<Schema>` |
|
|
385
|
-
| `TAnyDataSourceSchema` | `Record<string, any>` - base type for all schema objects (defined in `src/base/datasources/common/types.ts`, shared across engines) |
|
|
386
|
-
|
|
387
|
-
### `DataSourceDrivers`
|
|
388
|
-
|
|
389
|
-
Static class for driver validation (defined in `src/base/datasources/common/types.ts`, shared across engines):
|
|
390
|
-
|
|
391
|
-
```typescript
|
|
392
|
-
DataSourceDrivers.NODE_POSTGRES // 'node-postgres'
|
|
393
|
-
DataSourceDrivers.POSTGRES_JS // 'postgres-js'
|
|
394
|
-
DataSourceDrivers.TYPESENSE // 'typesense'
|
|
395
|
-
DataSourceDrivers.MEILISEARCH // 'meilisearch'
|
|
396
|
-
DataSourceDrivers.isValid('node-postgres') // true
|
|
397
|
-
```
|
|
398
|
-
|
|
399
|
-
> [!NOTE]
|
|
400
|
-
> `NODE_POSTGRES`/`POSTGRES_JS` remain valid `TDataSourceDriver` string values, but `@datasource({ driver })` on a **relational** datasource no longer accepts them - it takes the `NodePostgresDriver`/`PostgresJsDriver` class instead (see [Postgres Drivers & Supabase](/guides/core-concepts/persistent/postgres-drivers)). Search connectors (`TYPESENSE`, `MEILISEARCH`) still take the driver-name string form.
|
|
401
|
-
|
|
402
|
-
## Transaction Support
|
|
403
|
-
|
|
404
|
-
Only engines that declare `getCapabilities().transactions === true` implement real transactions - currently just the PostgreSQL connector. Calling `beginTransaction()` on the typesense connector throws `NotSupported` (HTTP 501).
|
|
405
|
-
|
|
406
|
-
### How It Works
|
|
407
|
-
|
|
408
|
-
`BasePostgresDataSource.beginTransaction()` does the following:
|
|
409
|
-
|
|
410
|
-
1. Resolves a driver from `this.client` (or the one `useDriver()` wired) and acquires a connection from it
|
|
411
|
-
2. Executes `BEGIN TRANSACTION ISOLATION LEVEL <level>` on the client
|
|
412
|
-
3. Creates a separate Drizzle connector scoped to that client
|
|
413
|
-
4. Returns an `IDatabaseTransaction` object with `commit()`, `rollback()`, and the scoped `connector`
|
|
414
|
-
|
|
415
|
-
When `commit()` or `rollback()` succeeds, the client is released back to the pool.
|
|
416
|
-
|
|
417
|
-
> [!WARNING] `commit()`/`rollback()` throw on failure
|
|
418
|
-
> A failed `COMMIT` or `ROLLBACK` **throws** (a failed `COMMIT` no longer resolves as success), and the poisoned connection is **destroyed** rather than returned to the pool - under the `node-postgres` driver, which can discard a connection; `postgres-js` has no destroy semantics and pools it anyway. A failed `BEGIN` also destroys the acquired connection rather than leaking it. Because `rollback()` can throw and is normally called from a `catch`, nest it in its own `try...catch` so the rollback error does not replace the original cause. See [Transactions](/guides/core-concepts/persistent/transactions) and [Postgres Drivers & Supabase](/guides/core-concepts/persistent/postgres-drivers).
|
|
419
|
-
|
|
420
|
-
### Neutral vs. PostgreSQL Transaction Types
|
|
421
|
-
|
|
422
|
-
`src/base` declares the engine-neutral shape; the PostgreSQL connector narrows it with connection details.
|
|
423
|
-
|
|
424
|
-
```typescript
|
|
425
|
-
// packages/core/src/base/datasources/common/types.ts - engine-neutral
|
|
426
|
-
interface ITransaction<_Schema = unknown> {
|
|
427
|
-
isActive: boolean;
|
|
428
|
-
commit(): Promise<void>;
|
|
429
|
-
rollback(): Promise<void>;
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
// packages/core/src/connectors/postgres/datasources/common/types.ts - PostgreSQL
|
|
433
|
-
interface IDatabaseTransaction<Schema extends TAnyDataSourceSchema = TAnyDataSourceSchema>
|
|
434
|
-
extends ITransaction<Schema> {
|
|
435
|
-
connector: TRelationalConnector<Schema>;
|
|
436
|
-
isolationLevel: TIsolationLevel;
|
|
92
|
+
import { PostgresJsDriver } from '@venizia/ignis/postgres/postgres-js';
|
|
93
|
+
import postgres from 'postgres';
|
|
94
|
+
import type { Sql } from 'postgres';
|
|
95
|
+
import * as schema from '@/schemas';
|
|
96
|
+
|
|
97
|
+
@datasource({ driver: PostgresJsDriver })
|
|
98
|
+
export class PostgresDataSource extends BasePostgresDataSource<
|
|
99
|
+
IDataSourceConfigs,
|
|
100
|
+
typeof schema,
|
|
101
|
+
{},
|
|
102
|
+
Sql
|
|
103
|
+
> {
|
|
104
|
+
override configure(): void {
|
|
105
|
+
this.client = postgres(this.getConnectionString());
|
|
106
|
+
}
|
|
437
107
|
}
|
|
438
108
|
```
|
|
439
109
|
|
|
440
|
-
|
|
441
|
-
|------|-------------|
|
|
442
|
-
| `ITransaction<Schema>` | Engine-neutral contract - `isActive`, `commit()`, `rollback()`. No connector field. |
|
|
443
|
-
| `IDatabaseTransaction<Schema>` | PostgreSQL transaction object - extends `ITransaction` with `connector` and `isolationLevel` |
|
|
444
|
-
| `IDatabaseTransactionOptions` | Options for starting a PostgreSQL transaction (`isolationLevel`); extends the neutral `ITransactionOptions` |
|
|
445
|
-
| `IDatabaseExtraOptions` | Extends the neutral `IExtraOptions`, narrowing `transaction?: IDatabaseTransaction` |
|
|
446
|
-
| `TIsolationLevel` | Union type: `'READ COMMITTED'` \| `'REPEATABLE READ'` \| `'SERIALIZABLE'` |
|
|
447
|
-
| `IsolationLevels` | Static class with isolation level constants and validation |
|
|
448
|
-
|
|
449
|
-
> [!NOTE]
|
|
450
|
-
> `AbstractRepository`, `PersistableRepository`, and every other engine-neutral repository type parameter is named `TOptions`/`IExtraOptions` in `src/base`. The PostgreSQL connector's `PostgresBaseRepository` narrows `ExtraOptions` to default to `IDatabaseExtraOptions`, so repository code written against a `PostgresBaseRepository` subclass sees `IDatabaseTransaction` (with `connector`/`isolationLevel`) rather than the bare neutral `ITransaction`.
|
|
110
|
+
See [Postgres Drivers & Supabase](/guides/core-concepts/persistent/postgres-drivers) for the full comparison, client-validation behavior, and Supabase presets.
|
|
451
111
|
|
|
452
|
-
###
|
|
112
|
+
### Run a transaction
|
|
453
113
|
|
|
454
|
-
|
|
114
|
+
`beginTransaction()` acquires a connection, issues `BEGIN`, and returns a handle with a scoped `connector`, `commit()`, and `rollback()`.
|
|
455
115
|
|
|
456
116
|
```typescript
|
|
457
|
-
import { IsolationLevels } from '@venizia/ignis';
|
|
117
|
+
import { IsolationLevels } from '@venizia/ignis/postgres';
|
|
118
|
+
import { userTable } from '@/schemas';
|
|
458
119
|
|
|
459
|
-
|
|
460
|
-
IsolationLevels.
|
|
461
|
-
IsolationLevels.REPEATABLE_READ // Consistent reads within transaction
|
|
462
|
-
IsolationLevels.SERIALIZABLE // Strictest isolation
|
|
463
|
-
|
|
464
|
-
// Validation
|
|
465
|
-
IsolationLevels.isValid('READ COMMITTED'); // true
|
|
466
|
-
IsolationLevels.isValid('INVALID'); // false
|
|
467
|
-
```
|
|
468
|
-
|
|
469
|
-
> [!NOTE]
|
|
470
|
-
> The default isolation level is `READ COMMITTED` when no `isolationLevel` option is provided.
|
|
471
|
-
|
|
472
|
-
### Usage Example
|
|
473
|
-
|
|
474
|
-
```typescript
|
|
475
|
-
// Start transaction from datasource or repository
|
|
476
|
-
const tx = await dataSource.beginTransaction({
|
|
477
|
-
isolationLevel: IsolationLevels.SERIALIZABLE
|
|
120
|
+
const transaction = await postgresDataSource.beginTransaction({
|
|
121
|
+
isolationLevel: IsolationLevels.SERIALIZABLE,
|
|
478
122
|
});
|
|
479
123
|
|
|
480
124
|
try {
|
|
481
|
-
|
|
482
|
-
await
|
|
483
|
-
await tx.connector.insert(profileTable).values({ userId: '...', bio: 'Hello' });
|
|
484
|
-
|
|
485
|
-
await tx.commit();
|
|
125
|
+
await transaction.connector.insert(userTable).values({ name: 'Alice' });
|
|
126
|
+
await transaction.commit();
|
|
486
127
|
} catch (error) {
|
|
487
|
-
// rollback() throws if ROLLBACK itself fails - nest it so it never replaces the original cause
|
|
488
128
|
try {
|
|
489
|
-
await
|
|
129
|
+
await transaction.rollback();
|
|
490
130
|
} catch (rollbackError) {
|
|
491
|
-
|
|
131
|
+
console.error('Rollback failed | %s', rollbackError);
|
|
492
132
|
}
|
|
493
133
|
throw error;
|
|
494
134
|
}
|
|
495
135
|
```
|
|
496
136
|
|
|
497
|
-
|
|
137
|
+
- **`rollback()` throws on failure.** Nest it in its own `try...catch` so a rollback failure never replaces the original error.
|
|
138
|
+
- **Prefer the repository API.** Most repository code should call `repository.beginTransaction()` instead of going through the datasource directly. See [Transactions](/guides/core-concepts/persistent/transactions).
|
|
139
|
+
|
|
140
|
+
### Share one datasource across repositories
|
|
498
141
|
|
|
499
|
-
|
|
142
|
+
One `PostgresDataSource` instance is shared by every repository bound to it - `@repository` auto-injects the datasource, and `getSchema()` merges the tables and relations of every model bound to it.
|
|
500
143
|
|
|
501
|
-
|
|
144
|
+
```typescript
|
|
145
|
+
@repository({ model: User, dataSource: PostgresDataSource })
|
|
146
|
+
export class UserRepository extends DefaultCRUDRepository<typeof User.schema> {}
|
|
147
|
+
|
|
148
|
+
@repository({ model: Configuration, dataSource: PostgresDataSource })
|
|
149
|
+
export class ConfigurationRepository extends DefaultCRUDRepository<typeof Configuration.schema> {}
|
|
150
|
+
```
|
|
502
151
|
|
|
503
|
-
-
|
|
504
|
-
- [Connectors](./connectors) - Base-vs-connectors architecture, dual-door exports, aliases
|
|
505
|
-
- [DataSources Guide](/guides/core-concepts/persistent/datasources) - Creating DataSources tutorial
|
|
506
|
-
- [Repositories](/guides/core-concepts/persistent/repositories) - Using DataSources for database access
|
|
507
|
-
- [Models](/guides/core-concepts/persistent/models) - Entity schemas loaded by DataSource
|
|
508
|
-
- [Transactions](/guides/core-concepts/persistent/transactions) - Multi-operation database transactions
|
|
509
|
-
- [Search & Typesense](/guides/core-concepts/persistent/search-typesense) - The typesense connector
|
|
152
|
+
`PostgresDataSource.schema` automatically includes both `User` and `Configuration`, plus their relations - one pooled connection, no per-repository connection setup.
|
|
510
153
|
|
|
511
|
-
|
|
512
|
-
- [Repositories API](/references/base/repositories/) - Data access layer
|
|
513
|
-
- [Environment Variables](/references/configuration/environment-variables) - Configuration management
|
|
154
|
+
## See also
|
|
514
155
|
|
|
515
|
-
-
|
|
516
|
-
|
|
517
|
-
|
|
156
|
+
- [Full reference](/references/base/datasources-reference) - every `IDataSource` member, `BasePostgresDataSource` internals, and transaction edge cases
|
|
157
|
+
- [Tutorial](/guides/core-concepts/persistent/datasources) - creating datasources step by step
|
|
158
|
+
- [Connectors](/references/base/connectors) - the base-vs-connector architecture
|
|
159
|
+
- [Repositories](/references/base/repositories/) - the layer that queries through a datasource
|
|
160
|
+
- [Models](/references/base/models) - the schema a datasource discovers from `@repository` bindings
|
|
518
161
|
|
|
519
|
-
|
|
520
|
-
- [Performance Optimization](/best-practices/performance-optimization) - Connection pool tuning
|
|
521
|
-
- [Security Guidelines](/best-practices/security-guidelines) - Database credential management
|
|
162
|
+
**Files:**
|
|
522
163
|
|
|
523
|
-
-
|
|
524
|
-
|
|
525
|
-
- [Building a CRUD API](/guides/tutorials/building-a-crud-api) - DataSource configuration
|
|
164
|
+
- [`packages/core/src/base/datasources/abstract.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/core/src/base/datasources/abstract.ts) - neutral `AbstractDataSource`
|
|
165
|
+
- [`packages/core/src/connectors/postgres/datasources/base.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/core/src/connectors/postgres/datasources/base.ts) - PostgreSQL `BasePostgresDataSource`
|