sedentary-pg 0.0.15 → 0.0.19
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 +45 -2
- package/index.d.ts +4 -4
- package/index.js +6 -6
- package/lib/adsrc.d.ts +1 -0
- package/lib/adsrc.js +7 -0
- package/lib/adsrc.ts +3 -0
- package/lib/pgdb.js +71 -45
- package/lib/pgdb.ts +57 -46
- package/package.json +15 -9
package/README.md
CHANGED
|
@@ -29,6 +29,49 @@
|
|
|
29
29
|
|
|
30
30
|
# under development
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
# Description
|
|
33
33
|
|
|
34
|
-
https://
|
|
34
|
+
The **PostgreSQL** specilized package of [Sedentary](https://www.npmjs.com/package/sedentary).
|
|
35
|
+
|
|
36
|
+
# Installation
|
|
37
|
+
|
|
38
|
+
With [npm](https://www.npmjs.com/package/sedentary-pg):
|
|
39
|
+
|
|
40
|
+
```sh
|
|
41
|
+
$ npm install --save sedentary-pg
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
# Documentation
|
|
45
|
+
|
|
46
|
+
The full documentation is on [sedentary.readthedocs.io](https://sedentary.readthedocs.io/).
|
|
47
|
+
|
|
48
|
+
# Compatibility
|
|
49
|
+
|
|
50
|
+
Requires:
|
|
51
|
+
|
|
52
|
+
- Node.js: **v12**
|
|
53
|
+
- TypeScript: **v4.1** (or none if used in a JavaScript project).
|
|
54
|
+
|
|
55
|
+
The package is tested under [all version combinations](https://app.travis-ci.com/github/iccicci/sedentary-pg)
|
|
56
|
+
of **Node.js** currently supported accordingly to [Node.js Release](https://github.com/nodejs/Release#readme) and of
|
|
57
|
+
**PostgreSQL** currently supported accordingly to
|
|
58
|
+
[PostgreSQL Versioning](https://www.postgresql.org/support/versioning/).
|
|
59
|
+
|
|
60
|
+
To work with the package under Windows, be sure to configure `bash.exe` as your _script-shell_.
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
> npm config set script-shell bash.exe
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
# Licence
|
|
67
|
+
|
|
68
|
+
[MIT Licence](https://github.com/iccicci/sedentary-pg/blob/master/LICENSE)
|
|
69
|
+
|
|
70
|
+
# Bugs
|
|
71
|
+
|
|
72
|
+
Do not hesitate to report any bug or inconsistency [@github](https://github.com/iccicci/sedentary-pg/issues).
|
|
73
|
+
|
|
74
|
+
# Donating
|
|
75
|
+
|
|
76
|
+
If you find useful this package, please consider the opportunity to donate some satoshis to this bitcoin address:
|
|
77
|
+
**1Md9WFAHrXTb3yPBwQWmUfv2RmzrtbHioB**
|
package/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EntryBase, ForeignKeyOptions, Natural, SedentaryOptions, Sedentary, Type } from "sedentary";
|
|
2
2
|
import { PoolConfig } from "pg";
|
|
3
|
-
export { AttributeDefinition, AttributeOptions, AttributesDefinition,
|
|
4
|
-
export { ModelOptions, Natural, SedentaryOptions, Type, TypeDefinition } from "sedentary";
|
|
3
|
+
export { AttributeDefinition, AttributeOptions, AttributesDefinition, EntryBase, ForeignKeyActions, ForeignKeyOptions } from "sedentary";
|
|
4
|
+
export { IndexAttributes, IndexDefinition, IndexOptions, IndexesDefinition, ModelOptions, Natural, SedentaryOptions, Type, TypeDefinition } from "sedentary";
|
|
5
5
|
export declare class SedentaryPG extends Sedentary {
|
|
6
6
|
constructor(connection: PoolConfig, options?: SedentaryOptions);
|
|
7
|
-
FKEY<N extends Natural, E extends
|
|
7
|
+
FKEY<N extends Natural, E extends EntryBase>(attribute: Type<N, E>, options?: ForeignKeyOptions): Type<N, E>;
|
|
8
8
|
}
|
|
9
9
|
export declare const Package: typeof SedentaryPG;
|
package/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Package = exports.SedentaryPG = exports.Type = exports.
|
|
3
|
+
exports.Package = exports.SedentaryPG = exports.Type = exports.EntryBase = void 0;
|
|
4
4
|
const sedentary_1 = require("sedentary");
|
|
5
5
|
const pgdb_1 = require("./lib/pgdb");
|
|
6
6
|
var sedentary_2 = require("sedentary");
|
|
7
|
-
Object.defineProperty(exports, "
|
|
7
|
+
Object.defineProperty(exports, "EntryBase", { enumerable: true, get: function () { return sedentary_2.EntryBase; } });
|
|
8
8
|
var sedentary_3 = require("sedentary");
|
|
9
9
|
Object.defineProperty(exports, "Type", { enumerable: true, get: function () { return sedentary_3.Type; } });
|
|
10
10
|
class SedentaryPG extends sedentary_1.Sedentary {
|
|
@@ -14,11 +14,11 @@ class SedentaryPG extends sedentary_1.Sedentary {
|
|
|
14
14
|
throw new Error("SedentaryPG.constructor: 'connection' argument: Wrong type, expected 'Object'");
|
|
15
15
|
this.db = new pgdb_1.PGDB(connection, this.log);
|
|
16
16
|
}
|
|
17
|
-
FKEY(attribute) {
|
|
18
|
-
const { attributeName,
|
|
17
|
+
FKEY(attribute, options) {
|
|
18
|
+
const { attributeName, modelName, unique } = attribute;
|
|
19
19
|
if (!unique)
|
|
20
|
-
throw new Error(`Sedentary.FKEY: '${
|
|
21
|
-
return super.FKEY(attribute);
|
|
20
|
+
throw new Error(`Sedentary.FKEY: '${modelName}' model: '${attributeName}' attribute: is not unique: can't be used as FKEY target`);
|
|
21
|
+
return super.FKEY(attribute, options);
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
exports.SedentaryPG = SedentaryPG;
|
package/lib/adsrc.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function adsrc(version: number): "pg_get_expr(pg_attrdef.adbin, pg_attrdef.adrelid) AS adsrc" | "adsrc";
|
package/lib/adsrc.js
ADDED
package/lib/adsrc.ts
ADDED
package/lib/pgdb.js
CHANGED
|
@@ -7,6 +7,7 @@ exports.PGDB = void 0;
|
|
|
7
7
|
const pg_1 = require("pg");
|
|
8
8
|
const pg_format_1 = __importDefault(require("pg-format"));
|
|
9
9
|
const db_1 = require("sedentary/lib/db");
|
|
10
|
+
const adsrc_1 = require("./adsrc");
|
|
10
11
|
const needDrop = [
|
|
11
12
|
["DATETIME", "int2"],
|
|
12
13
|
["DATETIME", "int4"],
|
|
@@ -20,6 +21,7 @@ const needUsing = [
|
|
|
20
21
|
["INT8", "varchar"]
|
|
21
22
|
];
|
|
22
23
|
const types = { int2: "SMALLINT", int4: "INTEGER", int8: "BIGINT", varchar: "VARCHAR" };
|
|
24
|
+
const actions = { cascade: "c", "no action": "a", restrict: "r", "set default": "d", "set null": "n" };
|
|
23
25
|
class PGDB extends db_1.DB {
|
|
24
26
|
constructor(connection, log) {
|
|
25
27
|
super(log);
|
|
@@ -32,23 +34,33 @@ class PGDB extends db_1.DB {
|
|
|
32
34
|
}
|
|
33
35
|
async dropConstraints(table) {
|
|
34
36
|
const indexes = [];
|
|
35
|
-
const res = await this.client.query("SELECT
|
|
37
|
+
const res = await this.client.query("SELECT confdeltype, confupdtype, conindid, conname, contype FROM pg_constraint WHERE conrelid = $1 ORDER BY conname", [table.oid]);
|
|
36
38
|
for (const row of res.rows) {
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
+
const arr = table.constraints.filter(_ => _.constraintName === row.conname && _.type === row.contype);
|
|
40
|
+
let drop = false;
|
|
41
|
+
if (arr.length === 0)
|
|
42
|
+
drop = true;
|
|
43
|
+
else if (row.contype === "u")
|
|
44
|
+
indexes.push(row.conindid);
|
|
45
|
+
else {
|
|
46
|
+
const { options } = arr[0].attribute.foreignKey;
|
|
47
|
+
if (actions[options.onDelete] !== row.confdeltype || actions[options.onUpdate] !== row.confupdtype)
|
|
48
|
+
drop = true;
|
|
49
|
+
}
|
|
50
|
+
if (drop) {
|
|
39
51
|
const statement = `ALTER TABLE ${table.tableName} DROP CONSTRAINT ${row.conname} CASCADE`;
|
|
40
|
-
this.
|
|
41
|
-
|
|
52
|
+
this.syncLog(statement);
|
|
53
|
+
if (this.sync)
|
|
54
|
+
await this.client.query(statement);
|
|
42
55
|
}
|
|
43
|
-
else
|
|
44
|
-
indexes.push(row.conindid);
|
|
45
56
|
}
|
|
46
57
|
return indexes;
|
|
47
58
|
}
|
|
48
59
|
async dropField(tableName, fieldName) {
|
|
49
60
|
const statement = `ALTER TABLE ${tableName} DROP COLUMN ${fieldName}`;
|
|
50
|
-
this.
|
|
51
|
-
|
|
61
|
+
this.syncLog(statement);
|
|
62
|
+
if (this.sync)
|
|
63
|
+
await this.client.query(statement);
|
|
52
64
|
}
|
|
53
65
|
async dropFields(table) {
|
|
54
66
|
const res = await this.client.query("SELECT attname FROM pg_attribute WHERE attrelid = $1 AND attnum > 0 AND attisdropped = false AND attinhcount = 0", [table.oid]);
|
|
@@ -79,8 +91,9 @@ class PGDB extends db_1.DB {
|
|
|
79
91
|
}
|
|
80
92
|
for (const index of Object.keys(iobject).sort()) {
|
|
81
93
|
const statement = `DROP INDEX ${index}`;
|
|
82
|
-
this.
|
|
83
|
-
|
|
94
|
+
this.syncLog(statement);
|
|
95
|
+
if (this.sync)
|
|
96
|
+
await this.client.query(statement);
|
|
84
97
|
}
|
|
85
98
|
}
|
|
86
99
|
async end() {
|
|
@@ -123,17 +136,18 @@ class PGDB extends db_1.DB {
|
|
|
123
136
|
]);
|
|
124
137
|
if (!res.rowCount) {
|
|
125
138
|
let query;
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
query = `UNIQUE(${attribute.fieldName})`;
|
|
132
|
-
break;
|
|
139
|
+
if (type === "f") {
|
|
140
|
+
const { fieldName, options, tableName } = attribute.foreignKey;
|
|
141
|
+
const onDelete = options.onDelete !== "no action" ? ` ON DELETE ${options.onDelete.toUpperCase()}` : "";
|
|
142
|
+
const onUpdate = options.onUpdate !== "no action" ? ` ON UPDATE ${options.onUpdate.toUpperCase()}` : "";
|
|
143
|
+
query = `FOREIGN KEY (${attribute.fieldName}) REFERENCES ${tableName}(${fieldName})${onDelete}${onUpdate}`;
|
|
133
144
|
}
|
|
145
|
+
else
|
|
146
|
+
query = `UNIQUE(${attribute.fieldName})`;
|
|
134
147
|
const statement = `ALTER TABLE ${table.tableName} ADD CONSTRAINT ${constraintName} ${query}`;
|
|
135
|
-
this.
|
|
136
|
-
|
|
148
|
+
this.syncLog(statement);
|
|
149
|
+
if (this.sync)
|
|
150
|
+
await this.client.query(statement);
|
|
137
151
|
}
|
|
138
152
|
}
|
|
139
153
|
}
|
|
@@ -143,34 +157,39 @@ class PGDB extends db_1.DB {
|
|
|
143
157
|
const { fieldName, notNull, size } = attribute;
|
|
144
158
|
const defaultValue = attribute.defaultValue === undefined ? undefined : (0, pg_format_1.default)("%L", attribute.defaultValue);
|
|
145
159
|
const [base, type] = this.fieldType(attribute);
|
|
146
|
-
const
|
|
147
|
-
const res = await this.client.query(`SELECT attnotnull, atttypmod, typname, ${adsrc} FROM pg_type, pg_attribute LEFT JOIN pg_attrdef ON adrelid = attrelid AND adnum = attnum WHERE
|
|
160
|
+
const where = "attrelid = $1 AND attnum > 0 AND atttypid = pg_type.oid AND attislocal = 't' AND attname = $2";
|
|
161
|
+
const res = await this.client.query(`SELECT attnotnull, atttypmod, typname, ${(0, adsrc_1.adsrc)(this.version)} FROM pg_type, pg_attribute LEFT JOIN pg_attrdef ON adrelid = attrelid AND adnum = attnum WHERE ${where}`, [oid, fieldName]);
|
|
148
162
|
const addField = async () => {
|
|
149
163
|
const statement = `ALTER TABLE ${tableName} ADD COLUMN ${fieldName} ${type}`;
|
|
150
|
-
this.
|
|
151
|
-
|
|
164
|
+
this.syncLog(statement);
|
|
165
|
+
if (this.sync)
|
|
166
|
+
await this.client.query(statement);
|
|
152
167
|
};
|
|
153
168
|
const dropDefault = async () => {
|
|
154
169
|
const statement = `ALTER TABLE ${tableName} ALTER COLUMN ${fieldName} DROP DEFAULT`;
|
|
155
|
-
this.
|
|
156
|
-
|
|
170
|
+
this.syncLog(statement);
|
|
171
|
+
if (this.sync)
|
|
172
|
+
await this.client.query(statement);
|
|
157
173
|
};
|
|
158
174
|
const setNotNull = async (isNull) => {
|
|
159
175
|
if (isNull === notNull)
|
|
160
176
|
return;
|
|
161
177
|
const statement = `ALTER TABLE ${tableName} ALTER COLUMN ${fieldName} ${notNull ? "SET" : "DROP"} NOT NULL`;
|
|
162
|
-
this.
|
|
163
|
-
|
|
178
|
+
this.syncLog(statement);
|
|
179
|
+
if (this.sync)
|
|
180
|
+
await this.client.query(statement);
|
|
164
181
|
};
|
|
165
182
|
const setDefault = async (isNull) => {
|
|
166
183
|
if (defaultValue !== undefined) {
|
|
167
184
|
let statement = `ALTER TABLE ${tableName} ALTER COLUMN ${fieldName} SET DEFAULT ${defaultValue}`;
|
|
168
|
-
this.
|
|
169
|
-
|
|
185
|
+
this.syncLog(statement);
|
|
186
|
+
if (this.sync)
|
|
187
|
+
await this.client.query(statement);
|
|
170
188
|
if (isNull) {
|
|
171
189
|
statement = `UPDATE ${tableName} SET ${fieldName} = ${defaultValue} WHERE ${fieldName} IS NULL`;
|
|
172
|
-
this.
|
|
173
|
-
this.
|
|
190
|
+
this.syncLog(statement);
|
|
191
|
+
if (this.sync)
|
|
192
|
+
this.client.query(statement);
|
|
174
193
|
}
|
|
175
194
|
}
|
|
176
195
|
await setNotNull(isNull);
|
|
@@ -192,8 +211,9 @@ class PGDB extends db_1.DB {
|
|
|
192
211
|
dropDefault();
|
|
193
212
|
const using = needUsing.filter(([type, name]) => attribute.type === type && typname === name).length ? " USING " + fieldName + "::" + type : "";
|
|
194
213
|
const statement = `ALTER TABLE ${tableName} ALTER COLUMN ${fieldName} TYPE ${type}${using}`;
|
|
195
|
-
this.
|
|
196
|
-
|
|
214
|
+
this.syncLog(statement);
|
|
215
|
+
if (this.sync)
|
|
216
|
+
await this.client.query(statement);
|
|
197
217
|
await setDefault(attnotnull);
|
|
198
218
|
}
|
|
199
219
|
}
|
|
@@ -213,8 +233,9 @@ class PGDB extends db_1.DB {
|
|
|
213
233
|
const { fields, indexName, type, unique } = index;
|
|
214
234
|
if (!this.indexes.includes(indexName)) {
|
|
215
235
|
const statement = `CREATE${unique ? " UNIQUE" : ""} INDEX ${indexName} ON ${tableName} USING ${type} (${fields.join(", ")})`;
|
|
216
|
-
this.
|
|
217
|
-
|
|
236
|
+
this.syncLog(statement);
|
|
237
|
+
if (this.sync)
|
|
238
|
+
await this.client.query(statement);
|
|
218
239
|
}
|
|
219
240
|
}
|
|
220
241
|
}
|
|
@@ -222,10 +243,12 @@ class PGDB extends db_1.DB {
|
|
|
222
243
|
if (!table.autoIncrementOwn)
|
|
223
244
|
return;
|
|
224
245
|
const statement = `ALTER SEQUENCE ${table.tableName}_id_seq OWNED BY ${table.tableName}.id`;
|
|
225
|
-
this.
|
|
226
|
-
|
|
246
|
+
this.syncLog(statement);
|
|
247
|
+
if (this.sync)
|
|
248
|
+
await this.client.query(statement);
|
|
227
249
|
}
|
|
228
250
|
async syncTable(table) {
|
|
251
|
+
var _a;
|
|
229
252
|
if (table.autoIncrement) {
|
|
230
253
|
await (async () => {
|
|
231
254
|
try {
|
|
@@ -236,8 +259,9 @@ class PGDB extends db_1.DB {
|
|
|
236
259
|
return;
|
|
237
260
|
if (e.code === "42P01") {
|
|
238
261
|
const statement = `CREATE SEQUENCE ${table.tableName}_id_seq`;
|
|
239
|
-
this.
|
|
240
|
-
|
|
262
|
+
this.syncLog(statement);
|
|
263
|
+
if (this.sync)
|
|
264
|
+
await this.client.query(statement);
|
|
241
265
|
table.autoIncrementOwn = true;
|
|
242
266
|
return;
|
|
243
267
|
}
|
|
@@ -263,8 +287,9 @@ class PGDB extends db_1.DB {
|
|
|
263
287
|
if (drop) {
|
|
264
288
|
const statement = `DROP TABLE ${table.tableName} CASCADE`;
|
|
265
289
|
create = true;
|
|
266
|
-
this.
|
|
267
|
-
|
|
290
|
+
this.syncLog(statement);
|
|
291
|
+
if (this.sync)
|
|
292
|
+
await this.client.query(statement);
|
|
268
293
|
}
|
|
269
294
|
}
|
|
270
295
|
else
|
|
@@ -272,10 +297,11 @@ class PGDB extends db_1.DB {
|
|
|
272
297
|
if (create) {
|
|
273
298
|
const parent = table.parent ? ` INHERITS (${table.parent.tableName})` : "";
|
|
274
299
|
const statement = `CREATE TABLE ${table.tableName} ()${parent}`;
|
|
275
|
-
this.
|
|
276
|
-
|
|
300
|
+
this.syncLog(statement);
|
|
301
|
+
if (this.sync)
|
|
302
|
+
await this.client.query(statement);
|
|
277
303
|
const resTable = await this.client.query("SELECT oid FROM pg_class WHERE relname = $1", [table.tableName]);
|
|
278
|
-
table.oid = resTable.rows[0].oid;
|
|
304
|
+
table.oid = (_a = resTable.rows[0]) === null || _a === void 0 ? void 0 : _a.oid;
|
|
279
305
|
}
|
|
280
306
|
}
|
|
281
307
|
}
|
package/lib/pgdb.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Pool, PoolClient, PoolConfig } from "pg";
|
|
2
2
|
import format from "pg-format";
|
|
3
|
-
import { Attribute, DB, Index, Natural, Table } from "sedentary/lib/db";
|
|
3
|
+
import { Attribute, DB, Index, Natural, ForeignKeyActions, Table } from "sedentary/lib/db";
|
|
4
|
+
import { adsrc } from "./adsrc";
|
|
4
5
|
|
|
5
6
|
const needDrop = [
|
|
6
7
|
["DATETIME", "int2"],
|
|
@@ -16,6 +17,8 @@ const needUsing = [
|
|
|
16
17
|
];
|
|
17
18
|
const types = { int2: "SMALLINT", int4: "INTEGER", int8: "BIGINT", varchar: "VARCHAR" };
|
|
18
19
|
|
|
20
|
+
const actions: { [k in ForeignKeyActions]: string } = { cascade: "c", "no action": "a", restrict: "r", "set default": "d", "set null": "n" };
|
|
21
|
+
|
|
19
22
|
export class PGDB extends DB {
|
|
20
23
|
private client: PoolClient;
|
|
21
24
|
private indexes: string[];
|
|
@@ -38,17 +41,26 @@ export class PGDB extends DB {
|
|
|
38
41
|
|
|
39
42
|
async dropConstraints(table: Table): Promise<number[]> {
|
|
40
43
|
const indexes: number[] = [];
|
|
41
|
-
const res = await this.client.query("SELECT
|
|
44
|
+
const res = await this.client.query("SELECT confdeltype, confupdtype, conindid, conname, contype FROM pg_constraint WHERE conrelid = $1 ORDER BY conname", [table.oid]);
|
|
42
45
|
|
|
43
46
|
for(const row of res.rows) {
|
|
44
|
-
const
|
|
47
|
+
const arr = table.constraints.filter(_ => _.constraintName === row.conname && _.type === row.contype);
|
|
48
|
+
let drop = false;
|
|
49
|
+
|
|
50
|
+
if(arr.length === 0) drop = true;
|
|
51
|
+
else if(row.contype === "u") indexes.push(row.conindid);
|
|
52
|
+
else {
|
|
53
|
+
const { options } = arr[0].attribute.foreignKey;
|
|
45
54
|
|
|
46
|
-
|
|
55
|
+
if(actions[options.onDelete] !== row.confdeltype || actions[options.onUpdate] !== row.confupdtype) drop = true;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if(drop) {
|
|
47
59
|
const statement = `ALTER TABLE ${table.tableName} DROP CONSTRAINT ${row.conname} CASCADE`;
|
|
48
60
|
|
|
49
|
-
this.
|
|
50
|
-
await this.client.query(statement);
|
|
51
|
-
}
|
|
61
|
+
this.syncLog(statement);
|
|
62
|
+
if(this.sync) await this.client.query(statement);
|
|
63
|
+
}
|
|
52
64
|
}
|
|
53
65
|
|
|
54
66
|
return indexes;
|
|
@@ -57,8 +69,8 @@ export class PGDB extends DB {
|
|
|
57
69
|
async dropField(tableName: string, fieldName: string): Promise<void> {
|
|
58
70
|
const statement = `ALTER TABLE ${tableName} DROP COLUMN ${fieldName}`;
|
|
59
71
|
|
|
60
|
-
this.
|
|
61
|
-
await this.client.query(statement);
|
|
72
|
+
this.syncLog(statement);
|
|
73
|
+
if(this.sync) await this.client.query(statement);
|
|
62
74
|
}
|
|
63
75
|
|
|
64
76
|
async dropFields(table: Table): Promise<void> {
|
|
@@ -97,8 +109,8 @@ export class PGDB extends DB {
|
|
|
97
109
|
for(const index of Object.keys(iobject).sort()) {
|
|
98
110
|
const statement = `DROP INDEX ${index}`;
|
|
99
111
|
|
|
100
|
-
this.
|
|
101
|
-
await this.client.query(statement);
|
|
112
|
+
this.syncLog(statement);
|
|
113
|
+
if(this.sync) await this.client.query(statement);
|
|
102
114
|
}
|
|
103
115
|
}
|
|
104
116
|
|
|
@@ -151,19 +163,18 @@ export class PGDB extends DB {
|
|
|
151
163
|
if(! res.rowCount) {
|
|
152
164
|
let query: string;
|
|
153
165
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
query = `
|
|
160
|
-
|
|
161
|
-
}
|
|
166
|
+
if(type === "f") {
|
|
167
|
+
const { fieldName, options, tableName } = attribute.foreignKey;
|
|
168
|
+
const onDelete = options.onDelete !== "no action" ? ` ON DELETE ${options.onDelete.toUpperCase()}` : "";
|
|
169
|
+
const onUpdate = options.onUpdate !== "no action" ? ` ON UPDATE ${options.onUpdate.toUpperCase()}` : "";
|
|
170
|
+
|
|
171
|
+
query = `FOREIGN KEY (${attribute.fieldName}) REFERENCES ${tableName}(${fieldName})${onDelete}${onUpdate}`;
|
|
172
|
+
} else query = `UNIQUE(${attribute.fieldName})`;
|
|
162
173
|
|
|
163
174
|
const statement = `ALTER TABLE ${table.tableName} ADD CONSTRAINT ${constraintName} ${query}`;
|
|
164
175
|
|
|
165
|
-
this.
|
|
166
|
-
await this.client.query(statement);
|
|
176
|
+
this.syncLog(statement);
|
|
177
|
+
if(this.sync) await this.client.query(statement);
|
|
167
178
|
}
|
|
168
179
|
}
|
|
169
180
|
}
|
|
@@ -175,25 +186,25 @@ export class PGDB extends DB {
|
|
|
175
186
|
const { fieldName, notNull, size } = attribute;
|
|
176
187
|
const defaultValue = attribute.defaultValue === undefined ? undefined : format("%L", attribute.defaultValue);
|
|
177
188
|
const [base, type] = this.fieldType(attribute);
|
|
178
|
-
const
|
|
189
|
+
const where = "attrelid = $1 AND attnum > 0 AND atttypid = pg_type.oid AND attislocal = 't' AND attname = $2";
|
|
179
190
|
|
|
180
191
|
const res = await this.client.query(
|
|
181
|
-
`SELECT attnotnull, atttypmod, typname, ${adsrc} FROM pg_type, pg_attribute LEFT JOIN pg_attrdef ON adrelid = attrelid AND adnum = attnum WHERE
|
|
192
|
+
`SELECT attnotnull, atttypmod, typname, ${adsrc(this.version)} FROM pg_type, pg_attribute LEFT JOIN pg_attrdef ON adrelid = attrelid AND adnum = attnum WHERE ${where}`,
|
|
182
193
|
[oid, fieldName]
|
|
183
194
|
);
|
|
184
195
|
|
|
185
196
|
const addField = async () => {
|
|
186
197
|
const statement = `ALTER TABLE ${tableName} ADD COLUMN ${fieldName} ${type}`;
|
|
187
198
|
|
|
188
|
-
this.
|
|
189
|
-
await this.client.query(statement);
|
|
199
|
+
this.syncLog(statement);
|
|
200
|
+
if(this.sync) await this.client.query(statement);
|
|
190
201
|
};
|
|
191
202
|
|
|
192
203
|
const dropDefault = async () => {
|
|
193
204
|
const statement = `ALTER TABLE ${tableName} ALTER COLUMN ${fieldName} DROP DEFAULT`;
|
|
194
205
|
|
|
195
|
-
this.
|
|
196
|
-
await this.client.query(statement);
|
|
206
|
+
this.syncLog(statement);
|
|
207
|
+
if(this.sync) await this.client.query(statement);
|
|
197
208
|
};
|
|
198
209
|
|
|
199
210
|
const setNotNull = async (isNull: boolean) => {
|
|
@@ -201,22 +212,22 @@ export class PGDB extends DB {
|
|
|
201
212
|
|
|
202
213
|
const statement = `ALTER TABLE ${tableName} ALTER COLUMN ${fieldName} ${notNull ? "SET" : "DROP"} NOT NULL`;
|
|
203
214
|
|
|
204
|
-
this.
|
|
205
|
-
await this.client.query(statement);
|
|
215
|
+
this.syncLog(statement);
|
|
216
|
+
if(this.sync) await this.client.query(statement);
|
|
206
217
|
};
|
|
207
218
|
|
|
208
219
|
const setDefault = async (isNull: boolean) => {
|
|
209
220
|
if(defaultValue !== undefined) {
|
|
210
221
|
let statement = `ALTER TABLE ${tableName} ALTER COLUMN ${fieldName} SET DEFAULT ${defaultValue}`;
|
|
211
222
|
|
|
212
|
-
this.
|
|
213
|
-
await this.client.query(statement);
|
|
223
|
+
this.syncLog(statement);
|
|
224
|
+
if(this.sync) await this.client.query(statement);
|
|
214
225
|
|
|
215
226
|
if(isNull) {
|
|
216
227
|
statement = `UPDATE ${tableName} SET ${fieldName} = ${defaultValue} WHERE ${fieldName} IS NULL`;
|
|
217
228
|
|
|
218
|
-
this.
|
|
219
|
-
this.client.query(statement);
|
|
229
|
+
this.syncLog(statement);
|
|
230
|
+
if(this.sync) this.client.query(statement);
|
|
220
231
|
}
|
|
221
232
|
}
|
|
222
233
|
|
|
@@ -240,8 +251,8 @@ export class PGDB extends DB {
|
|
|
240
251
|
const using = needUsing.filter(([type, name]) => attribute.type === type && typname === name).length ? " USING " + fieldName + "::" + type : "";
|
|
241
252
|
const statement = `ALTER TABLE ${tableName} ALTER COLUMN ${fieldName} TYPE ${type}${using}`;
|
|
242
253
|
|
|
243
|
-
this.
|
|
244
|
-
await this.client.query(statement);
|
|
254
|
+
this.syncLog(statement);
|
|
255
|
+
if(this.sync) await this.client.query(statement);
|
|
245
256
|
await setDefault(attnotnull);
|
|
246
257
|
}
|
|
247
258
|
} else if(defaultValue === undefined) {
|
|
@@ -261,8 +272,8 @@ export class PGDB extends DB {
|
|
|
261
272
|
if(! this.indexes.includes(indexName)) {
|
|
262
273
|
const statement = `CREATE${unique ? " UNIQUE" : ""} INDEX ${indexName} ON ${tableName} USING ${type} (${fields.join(", ")})`;
|
|
263
274
|
|
|
264
|
-
this.
|
|
265
|
-
await this.client.query(statement);
|
|
275
|
+
this.syncLog(statement);
|
|
276
|
+
if(this.sync) await this.client.query(statement);
|
|
266
277
|
}
|
|
267
278
|
}
|
|
268
279
|
}
|
|
@@ -272,8 +283,8 @@ export class PGDB extends DB {
|
|
|
272
283
|
|
|
273
284
|
const statement = `ALTER SEQUENCE ${table.tableName}_id_seq OWNED BY ${table.tableName}.id`;
|
|
274
285
|
|
|
275
|
-
this.
|
|
276
|
-
await this.client.query(statement);
|
|
286
|
+
this.syncLog(statement);
|
|
287
|
+
if(this.sync) await this.client.query(statement);
|
|
277
288
|
}
|
|
278
289
|
|
|
279
290
|
async syncTable(table: Table): Promise<void> {
|
|
@@ -286,8 +297,8 @@ export class PGDB extends DB {
|
|
|
286
297
|
if(e.code === "42P01") {
|
|
287
298
|
const statement = `CREATE SEQUENCE ${table.tableName}_id_seq`;
|
|
288
299
|
|
|
289
|
-
this.
|
|
290
|
-
await this.client.query(statement);
|
|
300
|
+
this.syncLog(statement);
|
|
301
|
+
if(this.sync) await this.client.query(statement);
|
|
291
302
|
table.autoIncrementOwn = true;
|
|
292
303
|
|
|
293
304
|
return;
|
|
@@ -318,8 +329,8 @@ export class PGDB extends DB {
|
|
|
318
329
|
const statement = `DROP TABLE ${table.tableName} CASCADE`;
|
|
319
330
|
|
|
320
331
|
create = true;
|
|
321
|
-
this.
|
|
322
|
-
await this.client.query(statement);
|
|
332
|
+
this.syncLog(statement);
|
|
333
|
+
if(this.sync) await this.client.query(statement);
|
|
323
334
|
}
|
|
324
335
|
} else create = true;
|
|
325
336
|
|
|
@@ -327,12 +338,12 @@ export class PGDB extends DB {
|
|
|
327
338
|
const parent = table.parent ? ` INHERITS (${table.parent.tableName})` : "";
|
|
328
339
|
const statement = `CREATE TABLE ${table.tableName} ()${parent}`;
|
|
329
340
|
|
|
330
|
-
this.
|
|
331
|
-
await this.client.query(statement);
|
|
341
|
+
this.syncLog(statement);
|
|
342
|
+
if(this.sync) await this.client.query(statement);
|
|
332
343
|
|
|
333
344
|
const resTable = await this.client.query("SELECT oid FROM pg_class WHERE relname = $1", [table.tableName]);
|
|
334
345
|
|
|
335
|
-
table.oid = resTable.rows[0]
|
|
346
|
+
table.oid = resTable.rows[0]?.oid;
|
|
336
347
|
}
|
|
337
348
|
}
|
|
338
349
|
}
|
package/package.json
CHANGED
|
@@ -2,25 +2,26 @@
|
|
|
2
2
|
"author": "Daniele Ricci <daniele.icc@gmail.com> (https://github.com/iccicci)",
|
|
3
3
|
"bugs": "https://github.com/iccicci/sedentary-pg/issues",
|
|
4
4
|
"dependencies": {
|
|
5
|
-
"@types/pg": "8.6.
|
|
5
|
+
"@types/pg": "8.6.2",
|
|
6
6
|
"@types/pg-format": "1.0.2",
|
|
7
7
|
"pg": "8.7.1",
|
|
8
8
|
"pg-format": "1.0.4",
|
|
9
|
-
"sedentary": "0.0.
|
|
9
|
+
"sedentary": "0.0.19"
|
|
10
10
|
},
|
|
11
11
|
"description": "The ORM which never needs to migrate - PostgreSQL",
|
|
12
12
|
"devDependencies": {
|
|
13
13
|
"@types/mocha": "9.0.0",
|
|
14
|
-
"@types/node": "
|
|
14
|
+
"@types/node": "17.0.0",
|
|
15
15
|
"@types/yamljs": "0.2.31",
|
|
16
|
-
"@typescript-eslint/eslint-plugin": "5.
|
|
17
|
-
"@typescript-eslint/parser": "5.
|
|
18
|
-
"eslint": "8.
|
|
16
|
+
"@typescript-eslint/eslint-plugin": "5.7.0",
|
|
17
|
+
"@typescript-eslint/parser": "5.7.0",
|
|
18
|
+
"eslint": "8.5.0",
|
|
19
19
|
"mocha": "9.1.3",
|
|
20
20
|
"nyc": "15.1.0",
|
|
21
|
-
"prettier": "2.5.
|
|
21
|
+
"prettier": "2.5.1",
|
|
22
22
|
"ts-node": "10.4.0",
|
|
23
|
-
"
|
|
23
|
+
"tsd": "0.19.0",
|
|
24
|
+
"typescript": "4.5.4",
|
|
24
25
|
"yamljs": "0.3.0"
|
|
25
26
|
},
|
|
26
27
|
"engines": {
|
|
@@ -61,6 +62,11 @@
|
|
|
61
62
|
"tsc": "tsc --declaration",
|
|
62
63
|
"version": "node -r ts-node/register utils.ts version"
|
|
63
64
|
},
|
|
65
|
+
"tsd": {
|
|
66
|
+
"compilerOptions": {
|
|
67
|
+
"strict": false
|
|
68
|
+
}
|
|
69
|
+
},
|
|
64
70
|
"types": "index.d.ts",
|
|
65
|
-
"version": "0.0.
|
|
71
|
+
"version": "0.0.19"
|
|
66
72
|
}
|