@venizia/ignis-docs 0.1.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 +83 -67
- 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 +31 -17
- 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 +98 -0
- 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 -607
- 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/datasources.md +13 -20
- package/content/guides/core-concepts/persistent/index.md +2 -4
- package/content/guides/core-concepts/persistent/models.md +1 -1
- package/content/guides/core-concepts/persistent/postgres-drivers.md +59 -25
- package/content/guides/core-concepts/persistent/search-meilisearch.md +3 -1
- package/content/guides/core-concepts/persistent/search-typesense.md +7 -5
- 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/building-a-crud-api.md +9 -13
- package/content/guides/tutorials/ecommerce-api.md +10 -15
- package/content/guides/tutorials/realtime-chat.md +7 -7
- 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 +85 -447
- 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 +51 -5
- 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,223 +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
|
|
13
|
+
The smallest real datasource: a `pg.Pool` wrapped in a class, wired to node-postgres via `@datasource`.
|
|
35
14
|
|
|
36
15
|
```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`
|
|
106
|
-
|
|
107
|
-
```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 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: a driver is resolved from 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. The protected `useDriver({ driver, schema? })` assigns `this.driver` **and** builds `this.connector` in one step. `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
|
-
- Call `this.getSchema()` to get the auto-discovered schema
|
|
206
|
-
- Create a `Pool` instance and assign it to `this.client` (required for transaction support)
|
|
207
|
-
- Create the Drizzle connector from that client and the schema
|
|
208
|
-
|
|
209
|
-
### Example Implementations
|
|
210
|
-
|
|
211
|
-
#### Pattern 1: Auto-Discovery (Recommended)
|
|
212
|
-
|
|
213
|
-
Simplest approach - schema is auto-discovered from repositories:
|
|
214
|
-
|
|
215
|
-
```typescript
|
|
216
|
-
// src/datasources/postgres.datasource.ts
|
|
217
|
-
import { BasePostgresDataSource, datasource } from '@venizia/ignis';
|
|
218
|
-
import { applicationEnvironment, int, ValueOrPromise } from '@venizia/ignis-helpers';
|
|
219
|
-
import { drizzle } from 'drizzle-orm/node-postgres';
|
|
220
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';
|
|
221
20
|
|
|
222
21
|
interface IDataSourceConfigs {
|
|
223
22
|
host: string;
|
|
@@ -225,303 +24,142 @@ interface IDataSourceConfigs {
|
|
|
225
24
|
database: string;
|
|
226
25
|
user: string;
|
|
227
26
|
password: string;
|
|
228
|
-
ssl: boolean;
|
|
229
27
|
}
|
|
230
28
|
|
|
231
|
-
|
|
232
|
-
* PostgresDataSource with auto-discovery support.
|
|
233
|
-
*
|
|
234
|
-
* How it works:
|
|
235
|
-
* 1. @repository decorator binds model to datasource
|
|
236
|
-
* 2. When configure() is called, getSchema() auto-discovers all bound models
|
|
237
|
-
* 3. Drizzle is initialized with the auto-discovered schema
|
|
238
|
-
*/
|
|
239
|
-
@datasource({ driver: 'node-postgres' })
|
|
29
|
+
@datasource({ driver: NodePostgresDriver })
|
|
240
30
|
export class PostgresDataSource extends BasePostgresDataSource<IDataSourceConfigs> {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
constructor() {
|
|
244
|
-
super({
|
|
245
|
-
name: PostgresDataSource.name,
|
|
246
|
-
config: {
|
|
247
|
-
host: applicationEnvironment.get<string>('APP_ENV_POSTGRES_HOST'),
|
|
248
|
-
port: int(applicationEnvironment.get<string>('APP_ENV_POSTGRES_PORT')),
|
|
249
|
-
database: applicationEnvironment.get<string>('APP_ENV_POSTGRES_DATABASE'),
|
|
250
|
-
user: applicationEnvironment.get<string>('APP_ENV_POSTGRES_USERNAME'),
|
|
251
|
-
password: applicationEnvironment.get<string>('APP_ENV_POSTGRES_PASSWORD'),
|
|
252
|
-
ssl: false,
|
|
253
|
-
},
|
|
254
|
-
// NO schema property - auto-discovered from @repository bindings!
|
|
255
|
-
});
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
override configure(): ValueOrPromise<void> {
|
|
259
|
-
// getSchema() auto-discovers models from @repository bindings
|
|
260
|
-
const schema = this.getSchema();
|
|
261
|
-
|
|
262
|
-
const dataSourceSchema = Object.keys(schema);
|
|
263
|
-
this.logger.debug(
|
|
264
|
-
'[configure] Auto-discovered schema | Schema + Relations (%s): %o',
|
|
265
|
-
dataSourceSchema.length,
|
|
266
|
-
dataSourceSchema,
|
|
267
|
-
);
|
|
268
|
-
|
|
269
|
-
// The client slot is what beginTransaction() resolves its driver from
|
|
31
|
+
override configure(): void {
|
|
270
32
|
this.client = new Pool(this.settings);
|
|
271
|
-
this.connector = drizzle({ client: this.client, schema });
|
|
272
33
|
}
|
|
273
34
|
|
|
274
|
-
override getConnectionString():
|
|
35
|
+
override getConnectionString(): string {
|
|
275
36
|
const { host, port, user, password, database } = this.settings;
|
|
276
|
-
return
|
|
37
|
+
return `postgresql://${user}:${password}@${host}:${port}/${database}`;
|
|
277
38
|
}
|
|
278
39
|
}
|
|
279
40
|
```
|
|
280
41
|
|
|
281
|
-
|
|
42
|
+
A `@repository` binds a model to `PostgresDataSource`, and the schema is auto-discovered from that binding - no manual schema wiring.
|
|
282
43
|
|
|
283
|
-
|
|
284
|
-
@repository({ model: User, dataSource: PostgresDataSource })
|
|
285
|
-
export class UserRepository extends DefaultCRUDRepository<typeof User.schema> {}
|
|
44
|
+
## How it works
|
|
286
45
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
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.
|
|
290
51
|
|
|
291
|
-
|
|
52
|
+
## Common tasks
|
|
292
53
|
|
|
293
|
-
|
|
54
|
+
### Configure connection settings
|
|
294
55
|
|
|
295
|
-
|
|
56
|
+
Pass connection settings through the constructor's `config` option. `configure()` reads them back off `this.settings`.
|
|
296
57
|
|
|
297
58
|
```typescript
|
|
298
|
-
import {
|
|
299
|
-
|
|
300
|
-
Configuration, configurationTable, configurationRelations,
|
|
301
|
-
} from '@/models/entities';
|
|
59
|
+
import { Pool } from 'pg';
|
|
60
|
+
import { applicationEnvironment, int } from '@venizia/ignis-helpers';
|
|
302
61
|
|
|
303
|
-
@datasource({ driver: 'node-postgres' })
|
|
304
62
|
export class PostgresDataSource extends BasePostgresDataSource<IDataSourceConfigs> {
|
|
305
63
|
constructor() {
|
|
306
64
|
super({
|
|
307
65
|
name: PostgresDataSource.name,
|
|
308
66
|
config: {
|
|
309
|
-
host:
|
|
310
|
-
port:
|
|
311
|
-
database:
|
|
312
|
-
user:
|
|
313
|
-
password:
|
|
314
|
-
},
|
|
315
|
-
// Manually provide schema using spread syntax
|
|
316
|
-
schema: {
|
|
317
|
-
[User.TABLE_NAME]: userTable,
|
|
318
|
-
[Configuration.TABLE_NAME]: configurationTable,
|
|
319
|
-
...userRelations.relations,
|
|
320
|
-
...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'),
|
|
321
72
|
},
|
|
322
73
|
});
|
|
323
74
|
}
|
|
324
75
|
|
|
325
|
-
override configure():
|
|
326
|
-
// When schema is manually provided, getSchema() returns it directly
|
|
76
|
+
override configure(): void {
|
|
327
77
|
this.client = new Pool(this.settings);
|
|
328
|
-
this.connector = drizzle({ client: this.client, schema: this.getSchema() });
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
override getConnectionString(): ValueOrPromise<string> {
|
|
332
|
-
// ...
|
|
333
78
|
}
|
|
334
79
|
}
|
|
335
80
|
```
|
|
336
81
|
|
|
337
|
-
|
|
338
|
-
> Your `configure()` must leave the datasource with a way to reach the database: either assign the raw client to `this.client`, or wire a driver with `this.useDriver({ driver })`. `beginTransaction()` resolves a driver lazily from whichever you provided. With neither, it throws `No driver and no client`.
|
|
82
|
+
### Choose a driver
|
|
339
83
|
|
|
340
|
-
|
|
84
|
+
| Driver | Package | When to use |
|
|
85
|
+
|---|---|---|
|
|
86
|
+
| `NodePostgresDriver` | `pg` | Long-standing default |
|
|
87
|
+
| `PostgresJsDriver` | `postgres` | Required for Supabase's transaction pooler; faster elsewhere |
|
|
341
88
|
|
|
342
|
-
|
|
89
|
+
Swapping drivers only changes which class `@datasource` names and how `configure()` builds the client:
|
|
343
90
|
|
|
344
91
|
```typescript
|
|
345
|
-
@
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
| Method | Return Type | Description |
|
|
361
|
-
|--------|-------------|-------------|
|
|
362
|
-
| `configure(opts?)` | `ValueOrPromise<void>` | Initialize the client and Drizzle connector. Must set `this.client` (or call `this.useDriver()`) and `this.connector`. |
|
|
363
|
-
| `getConnectionString()` | `ValueOrPromise<string>` | Return the database connection string. |
|
|
364
|
-
|
|
365
|
-
### Helper Methods
|
|
366
|
-
|
|
367
|
-
| Method | Description |
|
|
368
|
-
|--------|-------------|
|
|
369
|
-
| `getSchema()` | Returns the schema (auto-discovers via `discoverSchema()` if not manually provided) |
|
|
370
|
-
| `getSettings()` | Returns connection settings |
|
|
371
|
-
| `getConnector()` | Returns the Drizzle connector |
|
|
372
|
-
| `hasDiscoverableModels()` | Returns `true` if there are models registered for this datasource via `@repository` |
|
|
373
|
-
|
|
374
|
-
### Protected Methods
|
|
375
|
-
|
|
376
|
-
| Method | Description |
|
|
377
|
-
|--------|-------------|
|
|
378
|
-
| `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. |
|
|
379
|
-
|
|
380
|
-
## Connector Types
|
|
381
|
-
|
|
382
|
-
**File:** `packages/core/src/connectors/postgres/datasources/common/types.ts`
|
|
383
|
-
|
|
384
|
-
| Type | Description |
|
|
385
|
-
|------|-------------|
|
|
386
|
-
| `TRelationalConnector<Schema>` | Canonical connector type - a Drizzle `PgDatabase` that **every** pg driver (`node-postgres`, `postgres-js`) satisfies. Use this in new code. |
|
|
387
|
-
| `TNodePostgresConnector<Schema>` | **`@deprecated`** compat alias for `TRelationalConnector<Schema>` |
|
|
388
|
-
| `TNodePostgresTransactionConnector<Schema>` | **`@deprecated`** compat alias - was the `PoolClient`-specific transaction connector; now aliases `TRelationalConnector<Schema>` |
|
|
389
|
-
| `TAnyConnector<Schema>` | Alias of `TRelationalConnector<Schema>` |
|
|
390
|
-
| `TAnyDataSourceSchema` | `Record<string, any>` - base type for all schema objects (defined in `src/base/datasources/common/types.ts`, shared across engines) |
|
|
391
|
-
|
|
392
|
-
### `DataSourceDrivers`
|
|
393
|
-
|
|
394
|
-
Static class for driver validation (defined in `src/base/datasources/common/types.ts`, shared across engines):
|
|
395
|
-
|
|
396
|
-
```typescript
|
|
397
|
-
DataSourceDrivers.NODE_POSTGRES // 'node-postgres'
|
|
398
|
-
DataSourceDrivers.POSTGRES_JS // 'postgres-js'
|
|
399
|
-
DataSourceDrivers.TYPESENSE // 'typesense'
|
|
400
|
-
DataSourceDrivers.MEILISEARCH // 'meilisearch'
|
|
401
|
-
DataSourceDrivers.isValid('node-postgres') // true
|
|
402
|
-
```
|
|
403
|
-
|
|
404
|
-
## Transaction Support
|
|
405
|
-
|
|
406
|
-
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).
|
|
407
|
-
|
|
408
|
-
### How It Works
|
|
409
|
-
|
|
410
|
-
`BasePostgresDataSource.beginTransaction()` does the following:
|
|
411
|
-
|
|
412
|
-
1. Resolves a driver from `this.client` (or the one `useDriver()` wired) and acquires a connection from it
|
|
413
|
-
2. Executes `BEGIN TRANSACTION ISOLATION LEVEL <level>` on the client
|
|
414
|
-
3. Creates a separate Drizzle connector scoped to that client
|
|
415
|
-
4. Returns an `IDatabaseTransaction` object with `commit()`, `rollback()`, and the scoped `connector`
|
|
416
|
-
|
|
417
|
-
When `commit()` or `rollback()` succeeds, the client is released back to the pool.
|
|
418
|
-
|
|
419
|
-
> [!WARNING] `commit()`/`rollback()` throw on failure
|
|
420
|
-
> 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).
|
|
421
|
-
|
|
422
|
-
### Neutral vs. PostgreSQL Transaction Types
|
|
423
|
-
|
|
424
|
-
`src/base` declares the engine-neutral shape; the PostgreSQL connector narrows it with connection details.
|
|
425
|
-
|
|
426
|
-
```typescript
|
|
427
|
-
// packages/core/src/base/datasources/common/types.ts - engine-neutral
|
|
428
|
-
interface ITransaction<_Schema = unknown> {
|
|
429
|
-
isActive: boolean;
|
|
430
|
-
commit(): Promise<void>;
|
|
431
|
-
rollback(): Promise<void>;
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
// packages/core/src/connectors/postgres/datasources/common/types.ts - PostgreSQL
|
|
435
|
-
interface IDatabaseTransaction<Schema extends TAnyDataSourceSchema = TAnyDataSourceSchema>
|
|
436
|
-
extends ITransaction<Schema> {
|
|
437
|
-
connector: TRelationalConnector<Schema>;
|
|
438
|
-
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
|
+
}
|
|
439
107
|
}
|
|
440
108
|
```
|
|
441
109
|
|
|
442
|
-
|
|
443
|
-
|------|-------------|
|
|
444
|
-
| `ITransaction<Schema>` | Engine-neutral contract - `isActive`, `commit()`, `rollback()`. No connector field. |
|
|
445
|
-
| `IDatabaseTransaction<Schema>` | PostgreSQL transaction object - extends `ITransaction` with `connector` and `isolationLevel` |
|
|
446
|
-
| `IDatabaseTransactionOptions` | Options for starting a PostgreSQL transaction (`isolationLevel`); extends the neutral `ITransactionOptions` |
|
|
447
|
-
| `IDatabaseExtraOptions` | Extends the neutral `IExtraOptions`, narrowing `transaction?: IDatabaseTransaction` |
|
|
448
|
-
| `TIsolationLevel` | Union type: `'READ COMMITTED'` \| `'REPEATABLE READ'` \| `'SERIALIZABLE'` |
|
|
449
|
-
| `IsolationLevels` | Static class with isolation level constants and validation |
|
|
450
|
-
|
|
451
|
-
> [!NOTE]
|
|
452
|
-
> `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.
|
|
453
111
|
|
|
454
|
-
###
|
|
112
|
+
### Run a transaction
|
|
455
113
|
|
|
456
|
-
|
|
114
|
+
`beginTransaction()` acquires a connection, issues `BEGIN`, and returns a handle with a scoped `connector`, `commit()`, and `rollback()`.
|
|
457
115
|
|
|
458
116
|
```typescript
|
|
459
|
-
import { IsolationLevels } from '@venizia/ignis';
|
|
117
|
+
import { IsolationLevels } from '@venizia/ignis/postgres';
|
|
118
|
+
import { userTable } from '@/schemas';
|
|
460
119
|
|
|
461
|
-
|
|
462
|
-
IsolationLevels.
|
|
463
|
-
IsolationLevels.REPEATABLE_READ // Consistent reads within transaction
|
|
464
|
-
IsolationLevels.SERIALIZABLE // Strictest isolation
|
|
465
|
-
|
|
466
|
-
// Validation
|
|
467
|
-
IsolationLevels.isValid('READ COMMITTED'); // true
|
|
468
|
-
IsolationLevels.isValid('INVALID'); // false
|
|
469
|
-
```
|
|
470
|
-
|
|
471
|
-
> [!NOTE]
|
|
472
|
-
> The default isolation level is `READ COMMITTED` when no `isolationLevel` option is provided.
|
|
473
|
-
|
|
474
|
-
### Usage Example
|
|
475
|
-
|
|
476
|
-
```typescript
|
|
477
|
-
// Start transaction from datasource or repository
|
|
478
|
-
const tx = await dataSource.beginTransaction({
|
|
479
|
-
isolationLevel: IsolationLevels.SERIALIZABLE
|
|
120
|
+
const transaction = await postgresDataSource.beginTransaction({
|
|
121
|
+
isolationLevel: IsolationLevels.SERIALIZABLE,
|
|
480
122
|
});
|
|
481
123
|
|
|
482
124
|
try {
|
|
483
|
-
|
|
484
|
-
await
|
|
485
|
-
await tx.connector.insert(profileTable).values({ userId: '...', bio: 'Hello' });
|
|
486
|
-
|
|
487
|
-
await tx.commit();
|
|
125
|
+
await transaction.connector.insert(userTable).values({ name: 'Alice' });
|
|
126
|
+
await transaction.commit();
|
|
488
127
|
} catch (error) {
|
|
489
|
-
// rollback() throws if ROLLBACK itself fails - nest it so it never replaces the original cause
|
|
490
128
|
try {
|
|
491
|
-
await
|
|
129
|
+
await transaction.rollback();
|
|
492
130
|
} catch (rollbackError) {
|
|
493
|
-
|
|
131
|
+
console.error('Rollback failed | %s', rollbackError);
|
|
494
132
|
}
|
|
495
133
|
throw error;
|
|
496
134
|
}
|
|
497
135
|
```
|
|
498
136
|
|
|
499
|
-
|
|
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
|
|
500
141
|
|
|
501
|
-
|
|
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.
|
|
502
143
|
|
|
503
|
-
|
|
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
|
+
```
|
|
504
151
|
|
|
505
|
-
-
|
|
506
|
-
- [Connectors](./connectors) - Base-vs-connectors architecture, dual-door exports, aliases
|
|
507
|
-
- [DataSources Guide](/guides/core-concepts/persistent/datasources) - Creating DataSources tutorial
|
|
508
|
-
- [Repositories](/guides/core-concepts/persistent/repositories) - Using DataSources for database access
|
|
509
|
-
- [Models](/guides/core-concepts/persistent/models) - Entity schemas loaded by DataSource
|
|
510
|
-
- [Transactions](/guides/core-concepts/persistent/transactions) - Multi-operation database transactions
|
|
511
|
-
- [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.
|
|
512
153
|
|
|
513
|
-
|
|
514
|
-
- [Repositories API](/references/base/repositories/) - Data access layer
|
|
515
|
-
- [Environment Variables](/references/configuration/environment-variables) - Configuration management
|
|
154
|
+
## See also
|
|
516
155
|
|
|
517
|
-
-
|
|
518
|
-
|
|
519
|
-
|
|
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
|
|
520
161
|
|
|
521
|
-
|
|
522
|
-
- [Performance Optimization](/best-practices/performance-optimization) - Connection pool tuning
|
|
523
|
-
- [Security Guidelines](/best-practices/security-guidelines) - Database credential management
|
|
162
|
+
**Files:**
|
|
524
163
|
|
|
525
|
-
-
|
|
526
|
-
|
|
527
|
-
- [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`
|