@tachybase/database 1.6.13 → 1.6.14

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/lib/database.js CHANGED
@@ -541,14 +541,23 @@ const _Database = class _Database extends import_node_events.EventEmitter {
541
541
  if (isMySQL) {
542
542
  await this.sequelize.query("SET FOREIGN_KEY_CHECKS = 0", null);
543
543
  }
544
- if (this.options.schema && this.inDialect("postgres")) {
545
- await this.sequelize.query(`CREATE SCHEMA IF NOT EXISTS "${this.options.schema}"`, null);
544
+ const isSQLite = this.inDialect("sqlite");
545
+ if (isSQLite) {
546
+ await this.sequelize.query("PRAGMA foreign_keys = OFF");
546
547
  }
547
- const result = await this.sequelize.sync(options);
548
- if (isMySQL) {
549
- await this.sequelize.query("SET FOREIGN_KEY_CHECKS = 1", null);
548
+ try {
549
+ if (this.options.schema && this.inDialect("postgres")) {
550
+ await this.sequelize.query(`CREATE SCHEMA IF NOT EXISTS "${this.options.schema}"`, null);
551
+ }
552
+ return await this.sequelize.sync(options);
553
+ } finally {
554
+ if (isMySQL) {
555
+ await this.sequelize.query("SET FOREIGN_KEY_CHECKS = 1", null);
556
+ }
557
+ if (isSQLite) {
558
+ await this.sequelize.query("PRAGMA foreign_keys = ON");
559
+ }
550
560
  }
551
- return result;
552
561
  }
553
562
  async clean(options) {
554
563
  const { drop, ...others } = options || {};
@@ -55,58 +55,60 @@ const _SortField = class _SortField extends import_field.Field {
55
55
  }
56
56
  }, "onScopeChange");
57
57
  this.initRecordsSortValue = /* @__PURE__ */ __name(async ({ transaction }) => {
58
- const orderField = (() => {
59
- const model = this.collection.model;
60
- if (model.primaryKeyAttribute) {
61
- return model.primaryKeyAttribute;
62
- }
63
- if (model.rawAttributes["createdAt"]) {
64
- return model.rawAttributes["createdAt"].field;
65
- }
66
- throw new Error(`can not find order key for collection ${this.collection.name}`);
67
- })();
68
- const needInit = /* @__PURE__ */ __name(async (scopeKey2 = null, scopeValue = null) => {
69
- const filter = {};
70
- if (scopeKey2 && scopeValue) {
71
- filter[scopeKey2] = scopeValue;
72
- }
73
- const totalCount = await this.collection.repository.count({
74
- filter,
75
- transaction
76
- });
77
- const emptyCount = await this.collection.repository.count({
78
- filter: {
79
- [this.name]: null,
80
- ...filter
81
- },
82
- transaction
83
- });
84
- return emptyCount === totalCount && emptyCount > 0;
85
- }, "needInit");
86
- const doInit = /* @__PURE__ */ __name(async (scopeKey2 = null, scopeValue = null) => {
87
- const queryInterface = this.collection.db.sequelize.getQueryInterface();
88
- if (scopeKey2) {
89
- const scopeAttribute = this.collection.model.rawAttributes[scopeKey2];
90
- if (!scopeAttribute) {
91
- throw new Error(`can not find scope field ${scopeKey2} for collection ${this.collection.name}`);
58
+ try {
59
+ const orderField = (() => {
60
+ const model = this.collection.model;
61
+ if (model.primaryKeyAttribute) {
62
+ return model.primaryKeyAttribute;
92
63
  }
93
- scopeKey2 = scopeAttribute.field;
94
- }
95
- const quotedOrderField = queryInterface.quoteIdentifier(orderField);
96
- const sortColumnName = queryInterface.quoteIdentifier(this.collection.model.rawAttributes[this.name].field);
97
- let sql;
98
- const whereClause = scopeKey2 && scopeValue ? (() => {
99
- const filteredScopeValue = scopeValue.filter((v) => v !== null);
100
- if (filteredScopeValue.length === 0) {
101
- return "";
64
+ if (model.rawAttributes["createdAt"]) {
65
+ return model.rawAttributes["createdAt"].field;
66
+ }
67
+ throw new Error(`can not find order key for collection ${this.collection.name}`);
68
+ })();
69
+ const needInit = /* @__PURE__ */ __name(async (scopeKey2 = null, scopeValue = null) => {
70
+ const filter = {};
71
+ if (scopeKey2 != null && scopeValue != null) {
72
+ filter[scopeKey2] = scopeValue;
102
73
  }
103
- const initialClause = `
104
- WHERE ${queryInterface.quoteIdentifier(scopeKey2)} IN (${filteredScopeValue.map((v) => `'${v}'`).join(", ")})`;
105
- const nullCheck = scopeValue.includes(null) ? ` OR ${queryInterface.quoteIdentifier(scopeKey2)} IS NULL` : "";
106
- return initialClause + nullCheck;
107
- })() : "";
108
- if (this.collection.db.inDialect("postgres")) {
109
- sql = `
74
+ const totalCount = await this.collection.repository.count({
75
+ filter,
76
+ transaction
77
+ });
78
+ const emptyCount = await this.collection.repository.count({
79
+ filter: {
80
+ [this.name]: null,
81
+ ...filter
82
+ },
83
+ transaction
84
+ });
85
+ return emptyCount === totalCount && emptyCount > 0;
86
+ }, "needInit");
87
+ const doInit = /* @__PURE__ */ __name(async (scopeKey2 = null, scopeValue = null) => {
88
+ const queryInterface = this.collection.db.sequelize.getQueryInterface();
89
+ const escape = this.collection.db.sequelize.escape.bind(this.collection.db.sequelize);
90
+ if (scopeKey2) {
91
+ const scopeAttribute = this.collection.model.rawAttributes[scopeKey2];
92
+ if (!scopeAttribute) {
93
+ throw new Error(`can not find scope field ${scopeKey2} for collection ${this.collection.name}`);
94
+ }
95
+ scopeKey2 = scopeAttribute.field;
96
+ }
97
+ const quotedOrderField = queryInterface.quoteIdentifier(orderField);
98
+ const sortColumnName = queryInterface.quoteIdentifier(this.collection.model.rawAttributes[this.name].field);
99
+ let sql;
100
+ const whereClause = scopeKey2 != null && scopeValue != null ? (() => {
101
+ const filteredScopeValue = scopeValue.filter((v) => v !== null);
102
+ if (filteredScopeValue.length === 0) {
103
+ return "";
104
+ }
105
+ const initialClause = `
106
+ WHERE ${queryInterface.quoteIdentifier(scopeKey2)} IN (${filteredScopeValue.map((v) => escape(v)).join(", ")})`;
107
+ const nullCheck = scopeValue.includes(null) ? ` OR ${queryInterface.quoteIdentifier(scopeKey2)} IS NULL` : "";
108
+ return initialClause + nullCheck;
109
+ })() : "";
110
+ if (this.collection.db.inDialect("postgres")) {
111
+ sql = `
110
112
  UPDATE ${this.collection.quotedTableName()}
111
113
  SET ${sortColumnName} = ordered_table.new_sequence_number
112
114
  FROM (
@@ -116,8 +118,17 @@ const _SortField = class _SortField extends import_field.Field {
116
118
  ) AS ordered_table
117
119
  WHERE ${this.collection.quotedTableName()}.${quotedOrderField} = ordered_table.${quotedOrderField};
118
120
  `;
119
- } else if (this.collection.db.inDialect("sqlite")) {
120
- sql = `
121
+ } else if (this.collection.db.inDialect("sqlite")) {
122
+ const outerWhere = scopeKey2 && scopeValue ? (() => {
123
+ const filtered = scopeValue.filter((v) => v !== null);
124
+ if (filtered.length === 0) return "";
125
+ let clause = `WHERE ${queryInterface.quoteIdentifier(scopeKey2)} IN (${filtered.map((v) => escape(v)).join(", ")})`;
126
+ if (scopeValue.includes(null)) {
127
+ clause += ` OR ${queryInterface.quoteIdentifier(scopeKey2)} IS NULL`;
128
+ }
129
+ return clause;
130
+ })() : "";
131
+ sql = `
121
132
  UPDATE ${this.collection.quotedTableName()}
122
133
  SET ${sortColumnName} = (
123
134
  SELECT new_sequence_number
@@ -127,10 +138,11 @@ const _SortField = class _SortField extends import_field.Field {
127
138
  ${whereClause}
128
139
  ) AS ordered_table
129
140
  WHERE ${this.collection.quotedTableName()}.${quotedOrderField} = ordered_table.${quotedOrderField}
130
- );
141
+ )
142
+ ${outerWhere};
131
143
  `;
132
- } else if (this.collection.db.inDialect("mysql") || this.collection.db.inDialect("mariadb")) {
133
- sql = `
144
+ } else if (this.collection.db.inDialect("mysql") || this.collection.db.inDialect("mariadb")) {
145
+ sql = `
134
146
  UPDATE ${this.collection.quotedTableName()}
135
147
  JOIN (
136
148
  SELECT *, ROW_NUMBER() OVER (${scopeKey2 ? `PARTITION BY ${queryInterface.quoteIdentifier(scopeKey2)}` : ""} ORDER BY ${quotedOrderField}) AS new_sequence_number
@@ -139,30 +151,39 @@ const _SortField = class _SortField extends import_field.Field {
139
151
  ) AS ordered_table ON ${this.collection.quotedTableName()}.${quotedOrderField} = ordered_table.${quotedOrderField}
140
152
  SET ${this.collection.quotedTableName()}.${sortColumnName} = ordered_table.new_sequence_number;
141
153
  `;
142
- }
143
- await this.collection.db.sequelize.query(sql, {
144
- transaction
145
- });
146
- }, "doInit");
147
- const scopeKey = this.options.scopeKey;
148
- if (scopeKey) {
149
- const groups = await this.collection.repository.find({
150
- attributes: [scopeKey],
151
- group: [scopeKey],
152
- raw: true,
153
- transaction
154
- });
155
- const needInitGroups = [];
156
- for (const group of groups) {
157
- if (await needInit(scopeKey, group[scopeKey])) {
158
- needInitGroups.push(group[scopeKey]);
159
154
  }
155
+ await this.collection.db.sequelize.query(sql, {
156
+ transaction
157
+ });
158
+ }, "doInit");
159
+ const scopeKey = this.options.scopeKey;
160
+ if (scopeKey) {
161
+ const groups = await this.collection.repository.find({
162
+ attributes: [scopeKey],
163
+ group: [scopeKey],
164
+ raw: true,
165
+ transaction
166
+ });
167
+ const needInitGroups = [];
168
+ for (const group of groups) {
169
+ if (await needInit(scopeKey, group[scopeKey])) {
170
+ needInitGroups.push(group[scopeKey]);
171
+ }
172
+ }
173
+ if (needInitGroups.length > 0) {
174
+ await doInit(scopeKey, needInitGroups);
175
+ }
176
+ } else if (await needInit()) {
177
+ await doInit();
160
178
  }
161
- if (needInitGroups.length > 0) {
162
- await doInit(scopeKey, needInitGroups);
179
+ } catch (err) {
180
+ const msg = err instanceof Error ? err.message : String(err);
181
+ const isMissingTable = /no such table|relation .* does not exist|Table .* doesn't exist|No description found|SQLITE_ERROR/i.test(
182
+ msg
183
+ );
184
+ if (!isMissingTable) {
185
+ throw err;
163
186
  }
164
- } else if (await needInit()) {
165
- await doInit();
166
187
  }
167
188
  }, "initRecordsSortValue");
168
189
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tachybase/database",
3
- "version": "1.6.13",
3
+ "version": "1.6.14",
4
4
  "description": "",
5
5
  "homepage": "https://github.com/tegojs/tego#readme",
6
6
  "bugs": {
@@ -31,9 +31,9 @@
31
31
  "semver": "7.7.2",
32
32
  "sequelize": "^6.37.7",
33
33
  "umzug": "^3.8.2",
34
- "@tachybase/logger": "1.6.13",
35
- "@tachybase/utils": "1.6.13",
36
- "@tachybase/globals": "1.6.13"
34
+ "@tachybase/globals": "1.6.14",
35
+ "@tachybase/logger": "1.6.14",
36
+ "@tachybase/utils": "1.6.14"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@types/flat": "^5.0.5",