@spinajs/orm-postgres 2.0.528

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 ADDED
@@ -0,0 +1,64 @@
1
+ # @spinajs/orm-postgres
2
+
3
+ PostgreSQL driver for the SpinaJS ORM.
4
+
5
+ ## Usage
6
+
7
+ ```ts
8
+ import { Configuration } from '@spinajs/configuration';
9
+
10
+ // connection configuration
11
+ {
12
+ db: {
13
+ Connections: [
14
+ {
15
+ Driver: 'orm-driver-postgres',
16
+ Name: 'default',
17
+ Host: 'localhost',
18
+ Port: 5432,
19
+ User: 'postgres',
20
+ Password: 'postgres',
21
+ Database: 'app',
22
+ Options: {
23
+ // optional: pins search_path for every pooled connection; also the schema
24
+ // tableInfo() reads from. Defaults to `public`.
25
+ Schema: 'public',
26
+ },
27
+ },
28
+ ],
29
+ },
30
+ }
31
+ ```
32
+
33
+ ## Dialect notes — differences from the shared `@spinajs/orm-sql` (MySQL-flavoured) layer
34
+
35
+ | Feature | MySQL / shared layer | This driver |
36
+ | --- | --- | --- |
37
+ | Identifier quoting | `` `backticks` `` | `"double quotes"` |
38
+ | Bound parameters | `?` | rewritten to `$1..$n` at execution |
39
+ | Generated keys | `LAST_INSERT_ID()` | `RETURNING` rows (`insertReturning: true`) |
40
+ | Auto increment | `AUTO_INCREMENT`, NULL in VALUES assigns the key | `GENERATED BY DEFAULT AS IDENTITY`, `DEFAULT` in VALUES assigns the key |
41
+ | Upsert | `ON DUPLICATE KEY UPDATE c = VALUES(c)` | `ON CONFLICT (cols) DO UPDATE SET c = EXCLUDED.c` |
42
+ | Insert-or-ignore | `INSERT IGNORE` | `ON CONFLICT DO NOTHING` |
43
+ | Offset without limit | `LIMIT 18446744073709551615` | bare `OFFSET` |
44
+ | `ENUM` / `SET` columns | native types | `TEXT` (+ `CHECK (col IN (...))` for enum) |
45
+ | `DATETIME` / `DOUBLE` / `BLOB` / `JSON` | native names | `TIMESTAMP` / `DOUBLE PRECISION` / `BYTEA` / `JSONB` |
46
+ | `UNSIGNED`, per-column `CHARACTER SET`, inline `COMMENT` | supported | dropped (no postgres spelling) |
47
+ | `MODIFY column` | one clause restates the column | `ALTER COLUMN ... TYPE / SET / DROP` actions, MODIFY semantics kept (omitted NOT NULL / DEFAULT is dropped) |
48
+ | `CREATE DATABASE IF NOT EXISTS` | supported | refused — postgres has no such clause |
49
+ | `CREATE EVENT`, table history triggers, `CREATE TABLE ... LIKE` | MySQL syntax | unregistered — fail with a DI error naming the abstraction |
50
+ | `DECIMAL` / `NUMERIC` / `BIGINT` in responses | driver-dependent | strings (node-postgres refuses to lose precision above 2^53); `ResponseSchemaTypes` says so |
51
+
52
+ Transactions run on a dedicated pooled client with full savepoint support; all four
53
+ standard isolation levels are accepted (`READ UNCOMMITTED` behaves as `READ COMMITTED`,
54
+ postgres' documented, standard-permitted upgrade).
55
+
56
+ ## Running integration tests
57
+
58
+ The integration suite expects the docker fixture from the repository root:
59
+
60
+ ```
61
+ docker compose --profile test up -d postgres
62
+ ```
63
+
64
+ It listens on port `15432` by default; override with `ORM_TEST_POSTGRES_PORT`.
@@ -0,0 +1,122 @@
1
+ import { Container, IContainer } from '@spinajs/di';
2
+ import { Log } from '@spinajs/log';
3
+ import { ICompilerOutput, OnDuplicateQueryBuilder, InsertQueryBuilder, TableExistsCompiler, TableExistsQueryBuilder, LimitQueryCompiler, LimitBuilder, CreateDatabaseCompiler, CreateDatabaseQueryBuilder, IdentifierQuoter } from '@spinajs/orm';
4
+ import { SqlInsertQueryCompiler, SqlColumnQueryCompiler, SqlAlterColumnQueryCompiler, SqlOnDuplicateQueryCompiler, SqlDefaultValueBuilder } from '@spinajs/orm-sql';
5
+ export declare class PostgresTableExistsCompiler implements TableExistsCompiler {
6
+ protected builder: TableExistsQueryBuilder;
7
+ constructor(builder: TableExistsQueryBuilder);
8
+ compile(): ICompilerOutput;
9
+ }
10
+ /**
11
+ * LIMIT / OFFSET the postgres way. The shared compiler emits MySQL's
12
+ * `LIMIT 18446744073709551615` for an offset without a limit — a literal larger than
13
+ * BIGINT, which postgres rejects outright. Postgres accepts a bare OFFSET, so the
14
+ * workaround is simply dropped.
15
+ */
16
+ export declare class PostgresLimitQueryCompiler extends LimitQueryCompiler {
17
+ protected _builder: LimitBuilder<unknown>;
18
+ constructor(builder: LimitBuilder<unknown>);
19
+ compile(): ICompilerOutput;
20
+ }
21
+ /**
22
+ * Upsert, spelled `ON CONFLICT (...) DO UPDATE`. MySQL's `ON DUPLICATE KEY UPDATE` and its
23
+ * `VALUES(col)` reference are both rejected by postgres; the row that failed to insert is
24
+ * reachable as `EXCLUDED` instead, which — like VALUES(col) — applies each conflicting
25
+ * row's own values in a multi row upsert and needs no bindings.
26
+ */
27
+ export declare class PostgresOnDuplicateQueryCompiler extends SqlOnDuplicateQueryCompiler {
28
+ constructor(builder: OnDuplicateQueryBuilder);
29
+ compile(): {
30
+ bindings: any[];
31
+ expression: string;
32
+ };
33
+ }
34
+ export declare class PostgresInsertQueryCompiler extends SqlInsertQueryCompiler {
35
+ constructor(container: IContainer, builder: InsertQueryBuilder);
36
+ compile(): {
37
+ bindings: any[];
38
+ expression: string;
39
+ };
40
+ /**
41
+ * An identity column rejects an explicit NULL — postgres wants the DEFAULT keyword where
42
+ * MySQL and SQLite read NULL as "assign the key".
43
+ */
44
+ protected autoIncrementPlaceholder(): string;
45
+ /**
46
+ * `INSERT IGNORE` is MySQL; the postgres spelling of "silently skip the conflicting row"
47
+ * is `ON CONFLICT DO NOTHING`, which comes AFTER the values. Skipped when an upsert
48
+ * clause is present — the ON CONFLICT compiler emits its own conflict handling and two
49
+ * such clauses are invalid SQL.
50
+ */
51
+ protected ignore(): string;
52
+ /**
53
+ * RETURNING on a plain INSERT. Skipped when an upsert clause is present — the ON CONFLICT
54
+ * compiler emits its own RETURNING and two would be invalid SQL.
55
+ */
56
+ protected returning(): string;
57
+ protected into(): string;
58
+ }
59
+ /**
60
+ * Column DDL in the postgres dialect. Differences from the shared (MySQL) compiler, each
61
+ * with the postgres answer:
62
+ *
63
+ * - AUTO_INCREMENT does not exist: an integer-family column renders as
64
+ * `GENERATED BY DEFAULT AS IDENTITY` ( BY DEFAULT, not ALWAYS, because the ORM's batch
65
+ * insert path may supply an explicit key for some rows of a batch ).
66
+ * - ENUM and SET are not inline types: both render as TEXT, an enum additionally carrying
67
+ * a CHECK constraint over its members. SET stays plain TEXT because the shared
68
+ * SqlSetConverter stores a comma-joined string and the LIKE-based InSet statement reads
69
+ * it back.
70
+ * - UNSIGNED, CHARACTER SET and inline COMMENT have no postgres spelling and are dropped;
71
+ * COLLATE is kept ( postgres collations are identifiers, so it is quoted ).
72
+ * - MySQL type names map to their postgres equivalents ( DATETIME → TIMESTAMP,
73
+ * DOUBLE → DOUBLE PRECISION, BLOB → BYTEA, JSON → JSONB ).
74
+ */
75
+ export declare class PostgresColumnQueryCompiler extends SqlColumnQueryCompiler {
76
+ compile(): ICompilerOutput;
77
+ /**
78
+ * The `DEFAULT ...` fragment of the column body, or '' when none is set — public because
79
+ * the ALTER COLUMN compiler rebuilds it into `ALTER COLUMN x SET DEFAULT ...`.
80
+ */
81
+ defaultExpression(): string;
82
+ /**
83
+ * The bare type, without constraints — public because the ALTER COLUMN compiler needs
84
+ * exactly this piece for `ALTER COLUMN x TYPE t`.
85
+ */
86
+ typeExpression(): string;
87
+ }
88
+ /**
89
+ * ALTER COLUMN, postgres style.
90
+ *
91
+ * MySQL's MODIFY restates the whole column in one clause; postgres alters each attribute
92
+ * with its own action, and — matching MODIFY's semantics, where any omitted attribute is
93
+ * dropped — an absent NOT NULL / DEFAULT drops the constraint rather than leaving it.
94
+ * The actions are comma-joined, so the parent compiler's `ALTER TABLE t ` prefix yields
95
+ * one valid multi-action statement.
96
+ */
97
+ export declare class PostgresAlterColumnQueryCompiler extends SqlAlterColumnQueryCompiler {
98
+ protected Log: Log;
99
+ protected _columnDefinition(): ICompilerOutput;
100
+ protected _add(definition: string): string | null;
101
+ protected _modify(_definition: string): string | null;
102
+ }
103
+ /**
104
+ * Postgres spells database DDL its own way: encoding is `ENCODING`, not CHARACTER SET,
105
+ * and CREATE DATABASE has no IF NOT EXISTS at all — existence has to be checked by the
106
+ * caller, so the flag is refused rather than silently dropped.
107
+ */
108
+ export declare class PostgresCreateDatabaseQueryCompiler extends CreateDatabaseCompiler {
109
+ protected container: Container;
110
+ protected builder: CreateDatabaseQueryBuilder;
111
+ Quoter: IdentifierQuoter;
112
+ constructor(container: Container, builder: CreateDatabaseQueryBuilder);
113
+ compile(): ICompilerOutput;
114
+ }
115
+ /**
116
+ * `CURRENT_DATE()` — with the parentheses the shared builder emits — is a syntax error in
117
+ * postgres: both CURRENT_DATE and CURRENT_TIMESTAMP are niladic keywords there.
118
+ */
119
+ export declare class PostgresDefaultValueBuilder<T> extends SqlDefaultValueBuilder<T> {
120
+ date(): T;
121
+ }
122
+ //# sourceMappingURL=compilers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compilers.d.ts","sourceRoot":"","sources":["../../src/compilers.ts"],"names":[],"mappings":"AACA,OAAO,EAAuB,SAAS,EAAE,UAAU,EAAc,MAAM,aAAa,CAAC;AAErF,OAAO,EAAU,GAAG,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAY,uBAAuB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,uBAAuB,EAAgB,kBAAkB,EAAE,YAAY,EAAE,sBAAsB,EAAE,0BAA0B,EAAE,gBAAgB,EAA2C,MAAM,cAAc,CAAC;AACnT,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,2BAA2B,EAAE,2BAA2B,EAAE,sBAAsB,EAA0C,MAAM,kBAAkB,CAAC;AAG5M,qBACa,2BAA4B,YAAW,mBAAmB;IACzD,SAAS,CAAC,OAAO,EAAE,uBAAuB;IAAtD,YAAsB,OAAO,EAAE,uBAAuB,EAIrD;IAEM,OAAO,IAAI,eAAe,CAgBhC;CACF;AAED;;;;;GAKG;AACH,qBACa,0BAA2B,SAAQ,kBAAkB;IAChE,SAAS,CAAC,QAAQ,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;IAE1C,YAAY,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC,EAQzC;IAEM,OAAO,IAAI,eAAe,CAmBhC;CACF;AAED;;;;;GAKG;AACH,qBACa,gCAAiC,SAAQ,2BAA2B;IAC/E,YAAY,OAAO,EAAE,uBAAuB,EAE3C;IAEM,OAAO;;;MAgCb;CACF;AAED,qBAEa,2BAA4B,SAAQ,sBAAsB;IACrE,YAAY,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,kBAAkB,EAE7D;IAEM,OAAO;QASV,QAAQ;QACR,UAAU;MAEb;IAED;;;OAGG;IACH,SAAS,CAAC,wBAAwB,IAAI,MAAM,CAE3C;IAED;;;;;OAKG;IACH,SAAS,CAAC,MAAM,IAAI,MAAM,CAEzB;IAED;;;OAGG;IACH,SAAS,CAAC,SAAS,WAOlB;IAED,SAAS,CAAC,IAAI,WAGb;CACF;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBACa,2BAA4B,SAAQ,sBAAsB;IAC9D,OAAO,IAAI,eAAe,CAkChC;IAED;;;OAGG;IACI,iBAAiB,IAAI,MAAM,CAEjC;IAED;;;OAGG;IACI,cAAc,IAAI,MAAM,CAiD9B;CACF;AAED;;;;;;;;GAQG;AACH,qBAEa,gCAAiC,SAAQ,2BAA2B;IAE/E,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC;IAEnB,SAAS,CAAC,iBAAiB,IAAI,eAAe,CAE7C;IAED,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOhD;IAED,SAAS,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAYpD;CACF;AAED;;;;GAIG;AACH,qBAEa,mCAAoC,SAAQ,sBAAsB;IAIjE,SAAS,CAAC,SAAS,EAAE,SAAS;IAAE,SAAS,CAAC,OAAO,EAAE,0BAA0B;IAFlF,MAAM,EAAE,gBAAgB,CAAC;IAEhC,YAAsB,SAAS,EAAE,SAAS,EAAY,OAAO,EAAE,0BAA0B,EAExF;IAEM,OAAO,IAAI,eAAe,CAYhC;CACF;AAMD;;;GAGG;AACH,qBACa,2BAA2B,CAAC,CAAC,CAAE,SAAQ,sBAAsB,CAAC,CAAC,CAAC;IACpE,IAAI,IAAI,CAAC,CAGf;CACF"}
@@ -0,0 +1,391 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.PostgresDefaultValueBuilder = exports.PostgresCreateDatabaseQueryCompiler = exports.PostgresAlterColumnQueryCompiler = exports.PostgresColumnQueryCompiler = exports.PostgresInsertQueryCompiler = exports.PostgresOnDuplicateQueryCompiler = exports.PostgresLimitQueryCompiler = exports.PostgresTableExistsCompiler = void 0;
16
+ /* eslint-disable security/detect-object-injection */
17
+ const di_1 = require("@spinajs/di");
18
+ const exceptions_1 = require("@spinajs/exceptions");
19
+ const log_1 = require("@spinajs/log");
20
+ const orm_1 = require("@spinajs/orm");
21
+ const orm_sql_1 = require("@spinajs/orm-sql");
22
+ const lodash_1 = __importDefault(require("lodash"));
23
+ let PostgresTableExistsCompiler = class PostgresTableExistsCompiler {
24
+ constructor(builder) {
25
+ this.builder = builder;
26
+ if (builder === null) {
27
+ throw new Error('table exists query builder cannot be null');
28
+ }
29
+ }
30
+ compile() {
31
+ // `Database` on this builder plays the role a schema plays in postgres: one server
32
+ // database holds many schemas, and a connection cannot ask about another database at
33
+ // all. Unqualified checks go against current_schema() — the head of search_path —
34
+ // which is where an unqualified CREATE TABLE would land the table.
35
+ if (this.builder.Database) {
36
+ return {
37
+ bindings: [this.builder.Table, this.builder.Database],
38
+ expression: `SELECT table_name FROM information_schema.tables WHERE table_name = ? AND table_schema = ? LIMIT 1`,
39
+ };
40
+ }
41
+ return {
42
+ bindings: [this.builder.Table],
43
+ expression: `SELECT table_name FROM information_schema.tables WHERE table_name = ? AND table_schema = current_schema() LIMIT 1`,
44
+ };
45
+ }
46
+ };
47
+ exports.PostgresTableExistsCompiler = PostgresTableExistsCompiler;
48
+ exports.PostgresTableExistsCompiler = PostgresTableExistsCompiler = __decorate([
49
+ (0, di_1.NewInstance)(),
50
+ __metadata("design:paramtypes", [orm_1.TableExistsQueryBuilder])
51
+ ], PostgresTableExistsCompiler);
52
+ /**
53
+ * LIMIT / OFFSET the postgres way. The shared compiler emits MySQL's
54
+ * `LIMIT 18446744073709551615` for an offset without a limit — a literal larger than
55
+ * BIGINT, which postgres rejects outright. Postgres accepts a bare OFFSET, so the
56
+ * workaround is simply dropped.
57
+ */
58
+ let PostgresLimitQueryCompiler = class PostgresLimitQueryCompiler extends orm_1.LimitQueryCompiler {
59
+ constructor(builder) {
60
+ super();
61
+ if (!builder) {
62
+ throw new Error('builder cannot be null or undefined');
63
+ }
64
+ this._builder = builder;
65
+ }
66
+ compile() {
67
+ const limits = this._builder.getLimits();
68
+ const bindings = [];
69
+ let stmt = '';
70
+ if ((limits.limit ?? 0) > 0) {
71
+ stmt += ` LIMIT ?`;
72
+ bindings.push(limits.limit);
73
+ }
74
+ if ((limits.offset ?? 0) > 0) {
75
+ stmt += ` OFFSET ?`;
76
+ bindings.push(limits.offset);
77
+ }
78
+ return {
79
+ bindings,
80
+ expression: stmt,
81
+ };
82
+ }
83
+ };
84
+ exports.PostgresLimitQueryCompiler = PostgresLimitQueryCompiler;
85
+ exports.PostgresLimitQueryCompiler = PostgresLimitQueryCompiler = __decorate([
86
+ (0, di_1.NewInstance)(),
87
+ __metadata("design:paramtypes", [orm_1.LimitBuilder])
88
+ ], PostgresLimitQueryCompiler);
89
+ /**
90
+ * Upsert, spelled `ON CONFLICT (...) DO UPDATE`. MySQL's `ON DUPLICATE KEY UPDATE` and its
91
+ * `VALUES(col)` reference are both rejected by postgres; the row that failed to insert is
92
+ * reachable as `EXCLUDED` instead, which — like VALUES(col) — applies each conflicting
93
+ * row's own values in a multi row upsert and needs no bindings.
94
+ */
95
+ let PostgresOnDuplicateQueryCompiler = class PostgresOnDuplicateQueryCompiler extends orm_sql_1.SqlOnDuplicateQueryCompiler {
96
+ constructor(builder) {
97
+ super(builder);
98
+ }
99
+ compile() {
100
+ if (this._builder.getColumn().length === 0) {
101
+ throw new orm_1.OrmException(`no unique or primary key columns defined in table ${this._builder.getParent().Table}`);
102
+ }
103
+ const conflictTarget = this._builder
104
+ .getColumn()
105
+ .map((c) => this.Quoter.quote(c))
106
+ .join(',');
107
+ const columns = this._builder
108
+ .getColumnsToUpdate()
109
+ .map((c) => {
110
+ if (lodash_1.default.isString(c)) {
111
+ return `${this.Quoter.quote(c)} = EXCLUDED.${this.Quoter.quote(c)}`;
112
+ }
113
+ else {
114
+ return c.Query;
115
+ }
116
+ })
117
+ .join(',');
118
+ const bindings = lodash_1.default.flatMap(this._builder.getColumnsToUpdate(), (c) => {
119
+ return lodash_1.default.isString(c) ? [] : c.Bindings ?? [];
120
+ });
121
+ const returning = this._builder.getReturning();
122
+ const returningExpression = returning.length === 0 ? '' : ` RETURNING ${returning[0] === '*' ? '*' : returning.map((c) => this.Quoter.quote(c)).join(',')}`;
123
+ return {
124
+ bindings,
125
+ expression: `ON CONFLICT (${conflictTarget}) DO UPDATE SET ${columns}${returningExpression}`,
126
+ };
127
+ }
128
+ };
129
+ exports.PostgresOnDuplicateQueryCompiler = PostgresOnDuplicateQueryCompiler;
130
+ exports.PostgresOnDuplicateQueryCompiler = PostgresOnDuplicateQueryCompiler = __decorate([
131
+ (0, di_1.NewInstance)(),
132
+ __metadata("design:paramtypes", [orm_1.OnDuplicateQueryBuilder])
133
+ ], PostgresOnDuplicateQueryCompiler);
134
+ let PostgresInsertQueryCompiler = class PostgresInsertQueryCompiler extends orm_sql_1.SqlInsertQueryCompiler {
135
+ constructor(container, builder) {
136
+ super(container, builder);
137
+ }
138
+ compile() {
139
+ const into = this.into();
140
+ const columns = this.columns();
141
+ const values = this.values();
142
+ const upsort = this.upsort();
143
+ const ignore = this.ignore();
144
+ const returning = this.returning();
145
+ return {
146
+ bindings: values.bindings.concat(upsort.bindings),
147
+ expression: `${into} ${columns} ${values.data}${ignore} ${upsort.expression}${returning}`.trim(),
148
+ };
149
+ }
150
+ /**
151
+ * An identity column rejects an explicit NULL — postgres wants the DEFAULT keyword where
152
+ * MySQL and SQLite read NULL as "assign the key".
153
+ */
154
+ autoIncrementPlaceholder() {
155
+ return 'DEFAULT';
156
+ }
157
+ /**
158
+ * `INSERT IGNORE` is MySQL; the postgres spelling of "silently skip the conflicting row"
159
+ * is `ON CONFLICT DO NOTHING`, which comes AFTER the values. Skipped when an upsert
160
+ * clause is present — the ON CONFLICT compiler emits its own conflict handling and two
161
+ * such clauses are invalid SQL.
162
+ */
163
+ ignore() {
164
+ return this._builder.Ignore && !this._builder.Update ? ' ON CONFLICT DO NOTHING' : '';
165
+ }
166
+ /**
167
+ * RETURNING on a plain INSERT. Skipped when an upsert clause is present — the ON CONFLICT
168
+ * compiler emits its own RETURNING and two would be invalid SQL.
169
+ */
170
+ returning() {
171
+ if (this._builder.Update || this._builder.Returning.length === 0) {
172
+ return '';
173
+ }
174
+ const cols = this._builder.Returning[0] === '*' ? ['*'] : this._builder.Returning.map((c) => this.Quoter.quote(c));
175
+ return ` RETURNING ${cols.join(',')}`;
176
+ }
177
+ into() {
178
+ // no INSERT IGNORE here — see ignore() above
179
+ return `INSERT INTO ${this._container.resolve(orm_1.TableAliasCompiler).compile(this._builder)}`;
180
+ }
181
+ };
182
+ exports.PostgresInsertQueryCompiler = PostgresInsertQueryCompiler;
183
+ exports.PostgresInsertQueryCompiler = PostgresInsertQueryCompiler = __decorate([
184
+ (0, di_1.NewInstance)(),
185
+ (0, di_1.Inject)(di_1.Container),
186
+ __metadata("design:paramtypes", [Object, orm_1.InsertQueryBuilder])
187
+ ], PostgresInsertQueryCompiler);
188
+ /**
189
+ * Column DDL in the postgres dialect. Differences from the shared (MySQL) compiler, each
190
+ * with the postgres answer:
191
+ *
192
+ * - AUTO_INCREMENT does not exist: an integer-family column renders as
193
+ * `GENERATED BY DEFAULT AS IDENTITY` ( BY DEFAULT, not ALWAYS, because the ORM's batch
194
+ * insert path may supply an explicit key for some rows of a batch ).
195
+ * - ENUM and SET are not inline types: both render as TEXT, an enum additionally carrying
196
+ * a CHECK constraint over its members. SET stays plain TEXT because the shared
197
+ * SqlSetConverter stores a comma-joined string and the LIKE-based InSet statement reads
198
+ * it back.
199
+ * - UNSIGNED, CHARACTER SET and inline COMMENT have no postgres spelling and are dropped;
200
+ * COLLATE is kept ( postgres collations are identifiers, so it is quoted ).
201
+ * - MySQL type names map to their postgres equivalents ( DATETIME → TIMESTAMP,
202
+ * DOUBLE → DOUBLE PRECISION, BLOB → BYTEA, JSON → JSONB ).
203
+ */
204
+ let PostgresColumnQueryCompiler = class PostgresColumnQueryCompiler extends orm_sql_1.SqlColumnQueryCompiler {
205
+ compile() {
206
+ const _stmt = [];
207
+ _stmt.push(this.Quoter.quote(this.builder.Name));
208
+ _stmt.push(this.typeExpression());
209
+ if (this.builder.AutoIncrement) {
210
+ if (!['int', 'smallint', 'tinyint', 'mediumint', 'bigint'].includes(this.builder.Type)) {
211
+ throw new orm_1.OrmException(`postgres cannot auto-increment column ${this.builder.Name}: identity requires an integer type, got ${this.builder.Type}`);
212
+ }
213
+ _stmt.push('GENERATED BY DEFAULT AS IDENTITY');
214
+ }
215
+ if (this.builder.Collation) {
216
+ _stmt.push(`COLLATE ${this.Quoter.quote(this.builder.Collation)}`);
217
+ }
218
+ if (this.builder.NotNull) {
219
+ _stmt.push('NOT NULL');
220
+ }
221
+ if (this.builder.Default) {
222
+ _stmt.push(this._defaultCompiler());
223
+ }
224
+ if (this.builder.Type === 'enum') {
225
+ const members = this.builder.Args[0].map((a) => `'${(0, orm_sql_1.escapeStringLiteral)(a)}'`).join(',');
226
+ _stmt.push(`CHECK (${this.Quoter.quote(this.builder.Name)} IN (${members}))`);
227
+ }
228
+ if (this.builder.Unique) {
229
+ _stmt.push('UNIQUE');
230
+ }
231
+ return {
232
+ bindings: [],
233
+ expression: _stmt.filter((x) => !lodash_1.default.isEmpty(x)).join(' '),
234
+ };
235
+ }
236
+ /**
237
+ * The `DEFAULT ...` fragment of the column body, or '' when none is set — public because
238
+ * the ALTER COLUMN compiler rebuilds it into `ALTER COLUMN x SET DEFAULT ...`.
239
+ */
240
+ defaultExpression() {
241
+ return this._defaultCompiler();
242
+ }
243
+ /**
244
+ * The bare type, without constraints — public because the ALTER COLUMN compiler needs
245
+ * exactly this piece for `ALTER COLUMN x TYPE t`.
246
+ */
247
+ typeExpression() {
248
+ switch (this.builder.Type) {
249
+ case 'string':
250
+ return `VARCHAR(${this.builder.Args[0] ? this.builder.Args[0] : 255})`;
251
+ case 'text':
252
+ case 'tinytext':
253
+ case 'mediumtext':
254
+ case 'longtext':
255
+ case 'set':
256
+ case 'enum':
257
+ return 'TEXT';
258
+ case 'boolean':
259
+ return 'BOOLEAN';
260
+ case 'float':
261
+ return 'REAL';
262
+ case 'double':
263
+ return 'DOUBLE PRECISION';
264
+ case 'decimal': {
265
+ const precision = this.builder.Args[0] ? this.builder.Args[0] : 8;
266
+ const scale = this.builder.Args[1] ? this.builder.Args[1] : 2;
267
+ return `NUMERIC(${precision},${scale})`;
268
+ }
269
+ case 'tinyint':
270
+ case 'smallint':
271
+ return 'SMALLINT';
272
+ case 'int':
273
+ case 'mediumint':
274
+ return 'INTEGER';
275
+ case 'bigint':
276
+ return 'BIGINT';
277
+ case 'binary':
278
+ case 'tinyblob':
279
+ case 'mediumblob':
280
+ case 'longblob':
281
+ return 'BYTEA';
282
+ case 'bit':
283
+ return 'BIT';
284
+ case 'date':
285
+ return 'DATE';
286
+ case 'time':
287
+ return 'TIME';
288
+ case 'dateTime':
289
+ case 'timestamp':
290
+ return 'TIMESTAMP';
291
+ case 'json':
292
+ return 'JSONB';
293
+ default:
294
+ throw new orm_1.OrmException(`type ${this.builder.Type} is not supported by the postgres driver`);
295
+ }
296
+ }
297
+ };
298
+ exports.PostgresColumnQueryCompiler = PostgresColumnQueryCompiler;
299
+ exports.PostgresColumnQueryCompiler = PostgresColumnQueryCompiler = __decorate([
300
+ (0, di_1.NewInstance)()
301
+ ], PostgresColumnQueryCompiler);
302
+ /**
303
+ * ALTER COLUMN, postgres style.
304
+ *
305
+ * MySQL's MODIFY restates the whole column in one clause; postgres alters each attribute
306
+ * with its own action, and — matching MODIFY's semantics, where any omitted attribute is
307
+ * dropped — an absent NOT NULL / DEFAULT drops the constraint rather than leaving it.
308
+ * The actions are comma-joined, so the parent compiler's `ALTER TABLE t ` prefix yields
309
+ * one valid multi-action statement.
310
+ */
311
+ let PostgresAlterColumnQueryCompiler = class PostgresAlterColumnQueryCompiler extends orm_sql_1.SqlAlterColumnQueryCompiler {
312
+ _columnDefinition() {
313
+ return this.container.resolve(orm_1.ColumnQueryCompiler, [this.builder]).compile();
314
+ }
315
+ _add(definition) {
316
+ if (this.builder.AfterColumn) {
317
+ // AFTER is MySQL-only; postgres appends columns at the end and offers no placement
318
+ this.Log.warn(`postgres cannot place column '${this.builder.Name}' AFTER '${this.builder.AfterColumn}' - the column is appended at the end of the table`);
319
+ }
320
+ return `ADD COLUMN ${definition}`;
321
+ }
322
+ _modify(_definition) {
323
+ const column = this.Quoter.quote(this.builder.Name);
324
+ const compiler = this.container.resolve(orm_1.ColumnQueryCompiler, [this.builder]);
325
+ const actions = [`ALTER COLUMN ${column} TYPE ${compiler.typeExpression()}`];
326
+ actions.push(this.builder.NotNull ? `ALTER COLUMN ${column} SET NOT NULL` : `ALTER COLUMN ${column} DROP NOT NULL`);
327
+ const defaultExpression = compiler.defaultExpression();
328
+ actions.push(defaultExpression ? `ALTER COLUMN ${column} SET ${defaultExpression}` : `ALTER COLUMN ${column} DROP DEFAULT`);
329
+ return actions.join(', ');
330
+ }
331
+ };
332
+ exports.PostgresAlterColumnQueryCompiler = PostgresAlterColumnQueryCompiler;
333
+ __decorate([
334
+ (0, log_1.Logger)('ORM'),
335
+ __metadata("design:type", log_1.Log)
336
+ ], PostgresAlterColumnQueryCompiler.prototype, "Log", void 0);
337
+ exports.PostgresAlterColumnQueryCompiler = PostgresAlterColumnQueryCompiler = __decorate([
338
+ (0, di_1.NewInstance)(),
339
+ (0, di_1.Inject)(di_1.Container)
340
+ ], PostgresAlterColumnQueryCompiler);
341
+ /**
342
+ * Postgres spells database DDL its own way: encoding is `ENCODING`, not CHARACTER SET,
343
+ * and CREATE DATABASE has no IF NOT EXISTS at all — existence has to be checked by the
344
+ * caller, so the flag is refused rather than silently dropped.
345
+ */
346
+ let PostgresCreateDatabaseQueryCompiler = class PostgresCreateDatabaseQueryCompiler extends orm_1.CreateDatabaseCompiler {
347
+ constructor(container, builder) {
348
+ super();
349
+ this.container = container;
350
+ this.builder = builder;
351
+ }
352
+ compile() {
353
+ if (this.builder.Exists) {
354
+ throw new exceptions_1.NotSupported('postgres does not support CREATE DATABASE IF NOT EXISTS - check pg_database yourself before creating');
355
+ }
356
+ const encoding = this.builder.Charset ? ` ENCODING '${(0, orm_sql_1.assertCharsetName)(this.builder.Charset, 'encoding')}'` : '';
357
+ const collation = this.builder.Collation ? ` LC_COLLATE '${(0, orm_sql_1.escapeStringLiteral)(this.builder.Collation)}'` : '';
358
+ return {
359
+ bindings: [],
360
+ expression: `CREATE DATABASE ${this.Quoter.quote(this.builder.Name)}${encoding}${collation}`,
361
+ };
362
+ }
363
+ };
364
+ exports.PostgresCreateDatabaseQueryCompiler = PostgresCreateDatabaseQueryCompiler;
365
+ __decorate([
366
+ (0, di_1.Autoinject)(orm_1.IdentifierQuoter),
367
+ __metadata("design:type", orm_1.IdentifierQuoter)
368
+ ], PostgresCreateDatabaseQueryCompiler.prototype, "Quoter", void 0);
369
+ exports.PostgresCreateDatabaseQueryCompiler = PostgresCreateDatabaseQueryCompiler = __decorate([
370
+ (0, di_1.NewInstance)(),
371
+ (0, di_1.Inject)(di_1.Container),
372
+ __metadata("design:paramtypes", [di_1.Container, orm_1.CreateDatabaseQueryBuilder])
373
+ ], PostgresCreateDatabaseQueryCompiler);
374
+ // No PostgresDropDatabaseQueryCompiler: `DROP DATABASE IF EXISTS "x"` is exactly what the
375
+ // shared SqlDropDatabaseQueryCompiler emits once this driver's quoter is injected, so the
376
+ // driver claims the shared compiler instead of duplicating it.
377
+ /**
378
+ * `CURRENT_DATE()` — with the parentheses the shared builder emits — is a syntax error in
379
+ * postgres: both CURRENT_DATE and CURRENT_TIMESTAMP are niladic keywords there.
380
+ */
381
+ let PostgresDefaultValueBuilder = class PostgresDefaultValueBuilder extends orm_sql_1.SqlDefaultValueBuilder {
382
+ date() {
383
+ this.Query = orm_1.RawQuery.create('CURRENT_DATE');
384
+ return this.Owner;
385
+ }
386
+ };
387
+ exports.PostgresDefaultValueBuilder = PostgresDefaultValueBuilder;
388
+ exports.PostgresDefaultValueBuilder = PostgresDefaultValueBuilder = __decorate([
389
+ (0, di_1.NewInstance)()
390
+ ], PostgresDefaultValueBuilder);
391
+ //# sourceMappingURL=compilers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compilers.js","sourceRoot":"","sources":["../../src/compilers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ import { QueryContext, OrmDriver, IColumnDescriptor, ServerResponseMapper, ISupportedFeature, IsolationLevel, ITransactionContext, ITransactionOptions, IPoolMetrics } from '@spinajs/orm';
2
+ import { SqlDriver } from '@spinajs/orm-sql';
3
+ import pg from 'pg';
4
+ export * from './compilers.js';
5
+ export * from './statements.js';
6
+ export interface IPostgresTransactionContext extends ITransactionContext {
7
+ connection: pg.PoolClient;
8
+ }
9
+ /**
10
+ * Rewrites the `?` placeholders every compiler emits into the `$1..$n` positional
11
+ * parameters the pg protocol requires. Same brute-force walk the MSSQL driver does for
12
+ * its `@p` parameters — the compilers bind every user value, so a literal `?` does not
13
+ * appear in generated SQL outside of a placeholder position.
14
+ */
15
+ export declare function toPositionalParameters(stmt: string): string;
16
+ export declare class PostgresServerResponseMapper extends ServerResponseMapper {
17
+ read(data: any, pkNames?: string[]): {
18
+ RowsAffected: any;
19
+ LastInsertId: any;
20
+ Returning: any;
21
+ };
22
+ }
23
+ export declare class PostgresOrmDriver extends SqlDriver {
24
+ protected Pool: pg.Pool;
25
+ /**
26
+ * Postgres parses all four standard levels; READ UNCOMMITTED is accepted and behaves as
27
+ * READ COMMITTED, which is the standard-permitted upgrade, so it is not refused here.
28
+ */
29
+ readonly SupportedIsolationLevels: IsolationLevel[];
30
+ /**
31
+ * pg hands NUMERIC/DECIMAL and BIGINT back as STRINGS: both can exceed 2^53, where a
32
+ * float loses exactly the precision those types exist to keep, so node-postgres refuses
33
+ * to guess. No converter along the way changes that, so the RESPONSE schema has to say
34
+ * the same thing as the runtime. Reads only — on the request side these stay numbers.
35
+ */
36
+ readonly ResponseSchemaTypes: Readonly<Record<string, unknown>>;
37
+ executeOnDb(stmt: string, params: any[], context: QueryContext): Promise<any>;
38
+ protected isRetryableError(err: unknown): boolean;
39
+ protected _executeOnDbOnce(stmt: string, params: any[], context: QueryContext): Promise<any>;
40
+ supportedFeatures(): ISupportedFeature;
41
+ resolve(): void;
42
+ /** pg.Pool publishes its bookkeeping — no private-field spelunking needed here. */
43
+ poolMetrics(): IPoolMetrics;
44
+ ping(): Promise<boolean>;
45
+ connect(): Promise<OrmDriver>;
46
+ disconnect(): Promise<OrmDriver>;
47
+ tableInfo(name: string, schema?: string): Promise<IColumnDescriptor[]>;
48
+ /**
49
+ * Pulls the pooled client out of a transaction context. The base class only ever hands
50
+ * us contexts this driver's own `_begin` produced.
51
+ */
52
+ private txConnection;
53
+ protected _begin(options?: ITransactionOptions): Promise<ITransactionContext>;
54
+ protected _commit(ctx: ITransactionContext): Promise<void>;
55
+ protected _rollback(ctx: ITransactionContext): Promise<void>;
56
+ protected _savepoint(ctx: ITransactionContext, name: string): Promise<void>;
57
+ protected _releaseSavepoint(ctx: ITransactionContext, name: string): Promise<void>;
58
+ protected _rollbackToSavepoint(ctx: ITransactionContext, name: string): Promise<void>;
59
+ protected _dispose(ctx: ITransactionContext): Promise<void>;
60
+ }
61
+ //# sourceMappingURL=index.d.ts.map