@entity-access/entity-access 1.0.288 → 1.0.289

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.
Files changed (48) hide show
  1. package/dist/decorators/CheckConstraint.d.ts +4 -0
  2. package/dist/decorators/CheckConstraint.d.ts.map +1 -0
  3. package/dist/decorators/CheckConstraint.js +8 -0
  4. package/dist/decorators/CheckConstraint.js.map +1 -0
  5. package/dist/decorators/ICheckConstraint.d.ts +5 -0
  6. package/dist/decorators/ICheckConstraint.d.ts.map +1 -0
  7. package/dist/decorators/ICheckConstraint.js +3 -0
  8. package/dist/decorators/ICheckConstraint.js.map +1 -0
  9. package/dist/entity-query/EntityType.d.ts +2 -0
  10. package/dist/entity-query/EntityType.d.ts.map +1 -1
  11. package/dist/entity-query/EntityType.js +1 -0
  12. package/dist/entity-query/EntityType.js.map +1 -1
  13. package/dist/migrations/Migrations.d.ts +2 -0
  14. package/dist/migrations/Migrations.d.ts.map +1 -1
  15. package/dist/migrations/Migrations.js +8 -0
  16. package/dist/migrations/Migrations.js.map +1 -1
  17. package/dist/migrations/postgres/PostgresAutomaticMigrations.d.ts +3 -0
  18. package/dist/migrations/postgres/PostgresAutomaticMigrations.d.ts.map +1 -1
  19. package/dist/migrations/postgres/PostgresAutomaticMigrations.js +34 -9
  20. package/dist/migrations/postgres/PostgresAutomaticMigrations.js.map +1 -1
  21. package/dist/migrations/sql-server/SqlServerAutomaticMigrations.d.ts +3 -0
  22. package/dist/migrations/sql-server/SqlServerAutomaticMigrations.d.ts.map +1 -1
  23. package/dist/migrations/sql-server/SqlServerAutomaticMigrations.js +33 -9
  24. package/dist/migrations/sql-server/SqlServerAutomaticMigrations.js.map +1 -1
  25. package/dist/model/EntityModel.d.ts.map +1 -1
  26. package/dist/model/EntityModel.js +1 -0
  27. package/dist/model/EntityModel.js.map +1 -1
  28. package/dist/model/EntitySource.js +1 -1
  29. package/dist/model/EntitySource.js.map +1 -1
  30. package/dist/tests/db-tests/tests/check-constraint-test.d.ts +3 -0
  31. package/dist/tests/db-tests/tests/check-constraint-test.d.ts.map +1 -0
  32. package/dist/tests/db-tests/tests/check-constraint-test.js +28 -0
  33. package/dist/tests/db-tests/tests/check-constraint-test.js.map +1 -0
  34. package/dist/tests/model/ShoppingContext.d.ts.map +1 -1
  35. package/dist/tests/model/ShoppingContext.js +6 -1
  36. package/dist/tests/model/ShoppingContext.js.map +1 -1
  37. package/dist/tsconfig.tsbuildinfo +1 -1
  38. package/package.json +1 -1
  39. package/src/decorators/CheckConstraint.ts +10 -0
  40. package/src/decorators/ICheckConstraint.ts +4 -0
  41. package/src/entity-query/EntityType.ts +3 -0
  42. package/src/migrations/Migrations.ts +11 -0
  43. package/src/migrations/postgres/PostgresAutomaticMigrations.ts +43 -9
  44. package/src/migrations/sql-server/SqlServerAutomaticMigrations.ts +43 -10
  45. package/src/model/EntityModel.ts +1 -0
  46. package/src/model/EntitySource.ts +1 -1
  47. package/src/tests/db-tests/tests/check-constraint-test.ts +35 -0
  48. package/src/tests/model/ShoppingContext.ts +5 -0
@@ -1,4 +1,5 @@
1
1
  /* eslint-disable no-console */
2
+ import ICheckConstraint from "../../decorators/ICheckConstraint.js";
2
3
  import { IColumn } from "../../decorators/IColumn.js";
3
4
  import { IForeignKeyConstraint } from "../../decorators/IForeignKeyConstraint.js";
4
5
  import { IIndex } from "../../decorators/IIndex.js";
@@ -131,31 +132,41 @@ export default class PostgresAutomaticMigrations extends PostgresMigrations {
131
132
  await driver.executeQuery(query);
132
133
  }
133
134
 
134
- async migrateForeignKey(context: EntityContext, constraint: IForeignKeyConstraint) {
135
- const { type } = constraint;
136
- const name = type.schema
137
- ? type.schema + "." + type.name
138
- : type.name;
135
+ async constraintExists(context: EntityContext, name: string, schema: string) {
139
136
 
140
137
  let text = `SELECT * FROM information_schema.referential_constraints
141
138
  WHERE lower(constraint_name)=lower($1)
142
139
  `;
143
140
 
144
- const values = [constraint.name];
141
+ const values = [name];
145
142
 
146
- if(type.schema) {
143
+ if(schema) {
147
144
  text += " and constraint_schema = $2";
148
- values.push(type.schema);
145
+ values.push(schema);
149
146
  }
150
147
 
151
148
  const driver = context.connection;
152
149
 
153
150
  const r = await driver.executeQuery({ text, values });
154
151
  if (r.rows?.length) {
152
+ return true;
153
+ }
154
+ return false;
155
+ }
156
+
157
+ async migrateForeignKey(context: EntityContext, constraint: IForeignKeyConstraint) {
158
+ const { type } = constraint;
159
+ const name = type.schema
160
+ ? type.schema + "." + type.name
161
+ : type.name;
162
+
163
+ if (await this.constraintExists(context, constraint.name, type.schema)) {
155
164
  return;
156
165
  }
157
166
 
158
- text = `ALTER TABLE ${name} ADD CONSTRAINT ${constraint.name}
167
+ const driver = context.connection;
168
+
169
+ let text = `ALTER TABLE ${name} ADD CONSTRAINT ${constraint.name}
159
170
  foreign key (${constraint.column.columnName})
160
171
  references ${constraint.refColumns[0].entityType.name}(
161
172
  ${constraint.refColumns.map((x) => x.columnName).join(",")}
@@ -186,5 +197,28 @@ export default class PostgresAutomaticMigrations extends PostgresMigrations {
186
197
 
187
198
  }
188
199
 
200
+ async migrateCheckConstraint(context: EntityContext, constraint: ICheckConstraint<any>, type: EntityType) {
201
+ if (await this.constraintExists(context, constraint.name, type.schema)) {
202
+ return;
203
+ }
204
+
205
+ const name = type.schema
206
+ ? type.schema + "." + type.name
207
+ : type.name;
208
+
209
+
210
+ const driver = context.connection;
211
+
212
+ const text = `ALTER TABLE ${name} ADD CONSTRAINT ${constraint.name} CHECK (${constraint.filter})`;
213
+
214
+ try {
215
+ await driver.executeQuery(text);
216
+ } catch (error) {
217
+ // we will simply ignore this
218
+ console.warn(`Failed adding constraint ${constraint.name}`);
219
+ console.warn(error);
220
+ }
221
+ }
222
+
189
223
 
190
224
  }
@@ -1,3 +1,4 @@
1
+ import ICheckConstraint from "../../decorators/ICheckConstraint.js";
1
2
  import { IColumn } from "../../decorators/IColumn.js";
2
3
  import { IForeignKeyConstraint } from "../../decorators/IForeignKeyConstraint.js";
3
4
  import { IIndex } from "../../decorators/IIndex.js";
@@ -137,30 +138,39 @@ export default class SqlServerAutomaticMigrations extends SqlServerMigrations {
137
138
  await driver.executeQuery(query);
138
139
  }
139
140
 
140
- async migrateForeignKey(context: EntityContext, constraint: IForeignKeyConstraint) {
141
- const { type } = constraint;
142
- const name = type.schema
143
- ? type.schema + "." + type.name
144
- : type.name;
145
-
141
+ async constraintExists(context: EntityContext, name: string, schema: string, type: EntityType) {
146
142
  let text = `SELECT COUNT(*)
147
143
  FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
148
144
  WHERE TABLE_NAME='${type.name}'
149
- AND CONSTRAINT_NAME='${constraint.name}'
145
+ AND CONSTRAINT_NAME='${name}'
150
146
  AND CONSTRAINT_TYPE='FOREIGN KEY'`;
151
147
 
152
- if(type.schema) {
153
- text += ` and schema_name = ${type.schema}`;
148
+ if(schema) {
149
+ text += ` and schema_name = ${schema}`;
154
150
  }
155
151
 
156
152
  const driver = context.connection;
157
153
 
158
154
  const r = await driver.executeQuery(text);
159
155
  if (r.rows?.length) {
156
+ return true;
157
+ }
158
+
159
+ }
160
+
161
+ async migrateForeignKey(context: EntityContext, constraint: IForeignKeyConstraint) {
162
+ const { type } = constraint;
163
+ const name = type.schema
164
+ ? type.schema + "." + type.name
165
+ : type.name;
166
+
167
+ if (await this.constraintExists(context, name, type.schema, type)) {
160
168
  return;
161
169
  }
162
170
 
163
- text = `ALTER TABLE ${name} ADD CONSTRAINT ${constraint.name}
171
+ const driver = context.connection;
172
+
173
+ let text = `ALTER TABLE ${name} ADD CONSTRAINT ${constraint.name}
164
174
  foreign key (${constraint.column.columnName})
165
175
  references ${constraint.refColumns[0].entityType.name}(
166
176
  ${constraint.refColumns.map((x) => x.columnName).join(",")}
@@ -190,4 +200,27 @@ export default class SqlServerAutomaticMigrations extends SqlServerMigrations {
190
200
  }
191
201
  }
192
202
 
203
+ async migrateCheckConstraint(context: EntityContext, constraint: ICheckConstraint<any>, type: EntityType) {
204
+ if (await this.constraintExists(context, constraint.name, type.schema, type)) {
205
+ return;
206
+ }
207
+
208
+ const name = type.schema
209
+ ? type.schema + "." + type.name
210
+ : type.name;
211
+
212
+
213
+ const driver = context.connection;
214
+
215
+ const text = `ALTER TABLE ${name} ADD CONSTRAINT ${constraint.name} CHECK (${constraint.filter})`;
216
+
217
+ try {
218
+ await driver.executeQuery(text);
219
+ } catch (error) {
220
+ // we will simply ignore this
221
+ console.warn(`Failed adding constraint ${constraint.name}`);
222
+ console.warn(error);
223
+ }
224
+ }
225
+
193
226
  }
@@ -27,6 +27,7 @@ const getOrCreateModel = (map: Map<any, EntityType>, type: IClassOf<any>, naming
27
27
  t.addColumn(column);
28
28
  }
29
29
  t.indexes.push(... original.indexes.map((i) => ({ ... i, columns: [ ... i.columns.map((c) => ( { ... c}))] })));
30
+ t.checkConstraints.push(... original.checkConstraints.map((i) => ({ ... i})));
30
31
  // sort keys...
31
32
  if (t.keys.length > 1) {
32
33
  t.keys.sort((a, b) => a.order - b.order);
@@ -155,7 +155,7 @@ export class EntitySource<T = any> {
155
155
  }
156
156
  return returnEntity;
157
157
  } catch (error) {
158
- if (retry) {
158
+ if (retry > 0) {
159
159
  await sleep(300);
160
160
  return await this.saveDirect({ keys, mode, changes, updateAfterSelect } as any, retry -1);
161
161
  }
@@ -0,0 +1,35 @@
1
+ import assert from "assert";
2
+ import { Sql } from "../../../index.js";
3
+ import { TestConfig } from "../../TestConfig.js";
4
+ import { createContext } from "../../model/createContext.js";
5
+
6
+ export default async function(this: TestConfig) {
7
+
8
+ if (!this.db) {
9
+ return;
10
+ }
11
+
12
+ const context = await createContext(this.driver);
13
+
14
+ const first = await context.products.all().first();
15
+
16
+ first.name = "First product";
17
+
18
+ try {
19
+
20
+ // try direct save...
21
+ await context.productPrices.saveDirect({
22
+ mode: "insert",
23
+ changes: {
24
+ productID: first.productID,
25
+ active: true,
26
+ amount: -1,
27
+ startDate: new Date(),
28
+ }
29
+ });
30
+ } catch (error) {
31
+ // expcted...
32
+ return;
33
+ }
34
+ assert.fail();
35
+ }
@@ -7,6 +7,7 @@ import DateTime from "../../types/DateTime.js";
7
7
  import { UserFile } from "./UseFile.js";
8
8
  import Sql from "../../sql/Sql.js";
9
9
  import MultiForeignKeys from "../../decorators/ForeignKey.js";
10
+ import CheckConstraint from "../../decorators/CheckConstraint.js";
10
11
 
11
12
  export const statusPublished = "published";
12
13
 
@@ -285,6 +286,10 @@ export class ProductCategory {
285
286
  }
286
287
 
287
288
  @Table("ProductPrices")
289
+ @CheckConstraint({
290
+ name: "CX_ProductPrices_PositivePrice",
291
+ filter: (x) => x.amount > 0
292
+ })
288
293
  export class ProductPrice {
289
294
 
290
295
  @Column({ key: true, generated: "identity", dataType: "BigInt"})