@nocobase/database 1.4.0-alpha.20241024151311 → 1.4.0-alpha.20241027230531

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.
@@ -132,6 +132,8 @@ export declare class Collection<TModelAttributes extends {} = any, TCreationAttr
132
132
  tableNameAsString(options?: {
133
133
  ignorePublicSchema: boolean;
134
134
  }): any;
135
+ getRealTableName(quoted?: boolean): any;
136
+ getRealFieldName(name: string, quoted?: boolean): string;
135
137
  getTableNameWithSchemaAsString(): string;
136
138
  quotedTableName(): any;
137
139
  collectionSchema(): string;
package/lib/collection.js CHANGED
@@ -51,11 +51,11 @@ module.exports = __toCommonJS(collection_exports);
51
51
  var import_deepmerge = __toESM(require("deepmerge"));
52
52
  var import_events = require("events");
53
53
  var import_lodash = __toESM(require("lodash"));
54
+ var import_safe_json_stringify = __toESM(require("safe-json-stringify"));
54
55
  var import_sequelize = require("sequelize");
55
56
  var import_model = require("./model");
56
57
  var import_repository = require("./repository");
57
58
  var import_utils = require("./utils");
58
- var import_safe_json_stringify = __toESM(require("safe-json-stringify"));
59
59
  function EnsureAtomicity(target, propertyKey, descriptor) {
60
60
  const originalMethod = descriptor.value;
61
61
  descriptor.value = function(...args) {
@@ -101,6 +101,7 @@ const _Collection = class _Collection extends import_events.EventEmitter {
101
101
  this.bindFieldEventListener();
102
102
  this.modelInit();
103
103
  this.db.modelCollection.set(this.model, this);
104
+ this.db.modelNameCollectionMap.set(this.model.name, this);
104
105
  this.db.tableNameCollectionMap.set(this.getTableNameWithSchemaAsString(), this);
105
106
  if (!options.inherits) {
106
107
  this.setFields(options.fields);
@@ -179,8 +180,46 @@ const _Collection = class _Collection extends import_events.EventEmitter {
179
180
  } else if (model) {
180
181
  M = model;
181
182
  }
183
+ const collection = this;
182
184
  this.model = class extends M {
183
185
  };
186
+ Object.defineProperty(this.model, "primaryKeyAttribute", {
187
+ get: function() {
188
+ const singleFilterTargetKey = (() => {
189
+ if (!collection.options.filterTargetKey) {
190
+ return null;
191
+ }
192
+ if (Array.isArray(collection.options.filterTargetKey) && collection.options.filterTargetKey.length === 1) {
193
+ return collection.options.filterTargetKey[0];
194
+ }
195
+ return collection.options.filterTargetKey;
196
+ })();
197
+ if (!this._primaryKeyAttribute && singleFilterTargetKey && collection.getField(singleFilterTargetKey)) {
198
+ return singleFilterTargetKey;
199
+ }
200
+ return this._primaryKeyAttribute;
201
+ }.bind(this.model),
202
+ set(value) {
203
+ this._primaryKeyAttribute = value;
204
+ }
205
+ });
206
+ Object.defineProperty(this.model, "primaryKeyAttributes", {
207
+ get: function() {
208
+ if (Array.isArray(this._primaryKeyAttributes) && this._primaryKeyAttributes.length) {
209
+ return this._primaryKeyAttributes;
210
+ }
211
+ if (collection.options.filterTargetKey) {
212
+ const fields = import_lodash.default.castArray(collection.options.filterTargetKey);
213
+ if (fields.every((field) => collection.getField(field))) {
214
+ return fields;
215
+ }
216
+ }
217
+ return this._primaryKeyAttributes;
218
+ }.bind(this.model),
219
+ set(value) {
220
+ this._primaryKeyAttributes = value;
221
+ }
222
+ });
184
223
  this.model.init(null, this.sequelizeModelOptions());
185
224
  this.model.options.modelName = this.options.name;
186
225
  if (!autoGenId) {
@@ -597,6 +636,14 @@ const _Collection = class _Collection extends import_events.EventEmitter {
597
636
  }
598
637
  return `${schema}.${tableName}`;
599
638
  }
639
+ getRealTableName(quoted = false) {
640
+ const realname = this.tableNameAsString();
641
+ return !quoted ? realname : this.db.sequelize.getQueryInterface().quoteIdentifiers(realname);
642
+ }
643
+ getRealFieldName(name, quoted = false) {
644
+ const realname = this.model.getAttributes()[name].field;
645
+ return !quoted ? name : this.db.sequelize.getQueryInterface().quoteIdentifier(realname);
646
+ }
600
647
  getTableNameWithSchemaAsString() {
601
648
  const tableName = this.model.tableName;
602
649
  if (this.collectionSchema() && this.db.inDialect("postgres")) {
@@ -630,12 +677,13 @@ const _Collection = class _Collection extends import_events.EventEmitter {
630
677
  }
631
678
  sequelizeModelOptions() {
632
679
  const { name } = this.options;
633
- return {
680
+ const attr = {
634
681
  ...import_lodash.default.omit(this.options, ["name", "fields", "model", "targetKey"]),
635
682
  modelName: name,
636
683
  sequelize: this.context.database.sequelize,
637
684
  tableName: this.tableName()
638
685
  };
686
+ return attr;
639
687
  }
640
688
  bindFieldEventListener() {
641
689
  this.on("field.afterAdd", (field) => {
package/lib/database.d.ts CHANGED
@@ -80,6 +80,7 @@ export declare class Database extends EventEmitter implements AsyncEmitter {
80
80
  collections: Map<string, Collection<any, any>>;
81
81
  pendingFields: Map<string, FieldTypes.RelationField[]>;
82
82
  modelCollection: Map<ModelStatic<any>, Collection<any, any>>;
83
+ modelNameCollectionMap: Map<string, Collection<any, any>>;
83
84
  tableNameCollectionMap: Map<string, Collection<any, any>>;
84
85
  context: any;
85
86
  queryInterface: QueryInterface;
@@ -132,6 +133,7 @@ export declare class Database extends EventEmitter implements AsyncEmitter {
132
133
  collection<Attributes = any, CreateAttributes = Attributes>(options: CollectionOptions): Collection<Attributes, CreateAttributes>;
133
134
  getTablePrefix(): string;
134
135
  getFieldByPath(path: string): any;
136
+ getCollectionByModelName(name: string): Collection<any, any>;
135
137
  /**
136
138
  * get exists collection by its name
137
139
  * @param name
package/lib/database.js CHANGED
@@ -90,6 +90,7 @@ const _Database = class _Database extends import_events.EventEmitter {
90
90
  collections = /* @__PURE__ */ new Map();
91
91
  pendingFields = /* @__PURE__ */ new Map();
92
92
  modelCollection = /* @__PURE__ */ new Map();
93
+ modelNameCollectionMap = /* @__PURE__ */ new Map();
93
94
  tableNameCollectionMap = /* @__PURE__ */ new Map();
94
95
  context = {};
95
96
  queryInterface;
@@ -430,6 +431,9 @@ const _Database = class _Database extends import_events.EventEmitter {
430
431
  }
431
432
  return field;
432
433
  }
434
+ getCollectionByModelName(name) {
435
+ return this.modelNameCollectionMap.get(name);
436
+ }
433
437
  /**
434
438
  * get exists collection by its name
435
439
  * @param name
@@ -32,7 +32,7 @@ __export(referential_integrity_check_exports, {
32
32
  module.exports = __toCommonJS(referential_integrity_check_exports);
33
33
  async function referentialIntegrityCheck(options) {
34
34
  const { referencedInstance, db, transaction } = options;
35
- const collection = db.modelCollection.get(referencedInstance.constructor);
35
+ const collection = db.getCollectionByModelName(referencedInstance.constructor.name);
36
36
  const collectionName = collection.name;
37
37
  const references = db.referenceMap.getReferences(collectionName);
38
38
  if (!references) {
@@ -38,6 +38,11 @@ function escapeLike(value) {
38
38
  __name(escapeLike, "escapeLike");
39
39
  var string_default = {
40
40
  $includes(value, ctx) {
41
+ if (value === null) {
42
+ return {
43
+ [import_sequelize.Op.is]: null
44
+ };
45
+ }
41
46
  if (Array.isArray(value)) {
42
47
  const conditions = value.map((item) => ({
43
48
  [(0, import_utils.isPg)(ctx) ? import_sequelize.Op.iLike : import_sequelize.Op.like]: `%${escapeLike(item)}%`
@@ -51,6 +56,11 @@ var string_default = {
51
56
  };
52
57
  },
53
58
  $notIncludes(value, ctx) {
59
+ if (value === null) {
60
+ return {
61
+ [import_sequelize.Op.not]: null
62
+ };
63
+ }
54
64
  if (Array.isArray(value)) {
55
65
  const conditions = value.map((item) => ({
56
66
  [(0, import_utils.isPg)(ctx) ? import_sequelize.Op.notILike : import_sequelize.Op.notLike]: `%${escapeLike(item)}%`
@@ -323,7 +323,7 @@ async function updateMultipleAssociation(model, key, value, options = {}) {
323
323
  } else if (item.sequelize) {
324
324
  setItems.push(item);
325
325
  } else if (typeof item === "object") {
326
- const targetKey2 = association.targetKey || "id";
326
+ const targetKey2 = association.targetKey || association.options.targetKey || "id";
327
327
  if (item[targetKey2]) {
328
328
  const attributes = {
329
329
  [targetKey2]: item[targetKey2]
@@ -337,9 +337,9 @@ async function updateMultipleAssociation(model, key, value, options = {}) {
337
337
  await model[setAccessor](setItems, { transaction, context, individualHooks: true });
338
338
  const newItems = [];
339
339
  const pk = association.target.primaryKeyAttribute;
340
- const tmpKey = (_a = association["options"]) == null ? void 0 : _a["targetKey"];
341
340
  let targetKey = pk;
342
341
  const db = model.constructor["database"];
342
+ const tmpKey = (_a = association["options"]) == null ? void 0 : _a["targetKey"];
343
343
  if (tmpKey !== pk) {
344
344
  const targetKeyFieldOptions = (_b = db.getFieldByPath(`${association.target.name}.${tmpKey}`)) == null ? void 0 : _b.options;
345
345
  if (targetKeyFieldOptions == null ? void 0 : targetKeyFieldOptions.unique) {
@@ -405,7 +405,8 @@ async function updateMultipleAssociation(model, key, value, options = {}) {
405
405
  }
406
406
  }
407
407
  for (const newItem of newItems) {
408
- const existIndexInSetItems = setItems.findIndex((setItem) => setItem[targetKey] === newItem[targetKey]);
408
+ const findTargetKey = association.targetKey || association.options.targetKey || targetKey;
409
+ const existIndexInSetItems = setItems.findIndex((setItem) => setItem[findTargetKey] === newItem[findTargetKey]);
409
410
  if (existIndexInSetItems !== -1) {
410
411
  setItems[existIndexInSetItems] = newItem;
411
412
  } else {
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@nocobase/database",
3
- "version": "1.4.0-alpha.20241024151311",
3
+ "version": "1.4.0-alpha.20241027230531",
4
4
  "description": "",
5
5
  "main": "./lib/index.js",
6
6
  "types": "./lib/index.d.ts",
7
7
  "license": "AGPL-3.0",
8
8
  "dependencies": {
9
- "@nocobase/logger": "1.4.0-alpha.20241024151311",
10
- "@nocobase/utils": "1.4.0-alpha.20241024151311",
9
+ "@nocobase/logger": "1.4.0-alpha.20241027230531",
10
+ "@nocobase/utils": "1.4.0-alpha.20241027230531",
11
11
  "async-mutex": "^0.3.2",
12
12
  "chalk": "^4.1.1",
13
13
  "cron-parser": "4.4.0",
@@ -38,5 +38,5 @@
38
38
  "url": "git+https://github.com/nocobase/nocobase.git",
39
39
  "directory": "packages/database"
40
40
  },
41
- "gitHead": "3a8d759b6d14b87dd6c2929a028bc19bccbdfe45"
41
+ "gitHead": "6f363bf299af23580d68c8b0659e4d31d70f4687"
42
42
  }