oak-db 3.3.9 → 3.3.10

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.
@@ -1,36 +1,37 @@
1
- import { EntityDict, OperateOption, OperationResult, TxnOption, StorageSchema, SelectOption, AggregationResult } from 'oak-domain/lib/types';
2
- import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
3
- import { CascadeStore } from 'oak-domain/lib/store/CascadeStore';
4
- import { MySQLConfiguration } from './types/Configuration';
5
- import { MySqlConnector } from './connector';
6
- import { MySqlTranslator, MySqlSelectOption, MysqlOperateOption } from './translator';
7
- import { AsyncContext, AsyncRowStore } from 'oak-domain/lib/store/AsyncRowStore';
8
- import { SyncContext } from 'oak-domain/lib/store/SyncRowStore';
9
- import { CreateEntityOption } from '../types/Translator';
10
- export declare class MysqlStore<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>> extends CascadeStore<ED> implements AsyncRowStore<ED, Cxt> {
11
- protected countAbjointRow<T extends keyof ED, OP extends SelectOption, Cxt extends SyncContext<ED>>(entity: T, selection: Pick<ED[T]['Selection'], 'filter' | 'count'>, context: Cxt, option: OP): number;
12
- protected aggregateAbjointRowSync<T extends keyof ED, OP extends SelectOption, Cxt extends SyncContext<ED>>(entity: T, aggregation: ED[T]['Aggregation'], context: Cxt, option: OP): AggregationResult<ED[T]['Schema']>;
13
- protected selectAbjointRow<T extends keyof ED, OP extends SelectOption>(entity: T, selection: ED[T]['Selection'], context: SyncContext<ED>, option: OP): Partial<ED[T]['Schema']>[];
14
- protected updateAbjointRow<T extends keyof ED, OP extends OperateOption>(entity: T, operation: ED[T]['Operation'], context: SyncContext<ED>, option: OP): number;
15
- exec(script: string, txnId?: string): Promise<void>;
16
- connector: MySqlConnector;
17
- translator: MySqlTranslator<ED>;
18
- constructor(storageSchema: StorageSchema<ED>, configuration: MySQLConfiguration);
19
- protected aggregateAbjointRowAsync<T extends keyof ED, OP extends SelectOption, Cxt extends AsyncContext<ED>>(entity: T, aggregation: ED[T]['Aggregation'], context: Cxt, option: OP): Promise<AggregationResult<ED[T]['Schema']>>;
20
- aggregate<T extends keyof ED, OP extends SelectOption>(entity: T, aggregation: ED[T]['Aggregation'], context: Cxt, option: OP): Promise<AggregationResult<ED[T]['Schema']>>;
21
- protected supportManyToOneJoin(): boolean;
22
- protected supportMultipleCreate(): boolean;
23
- private formResult;
24
- protected selectAbjointRowAsync<T extends keyof ED>(entity: T, selection: ED[T]['Selection'], context: AsyncContext<ED>, option?: MySqlSelectOption): Promise<Partial<ED[T]['Schema']>[]>;
25
- protected updateAbjointRowAsync<T extends keyof ED>(entity: T, operation: ED[T]['Operation'], context: AsyncContext<ED>, option?: MysqlOperateOption): Promise<number>;
26
- operate<T extends keyof ED>(entity: T, operation: ED[T]['Operation'], context: Cxt, option: OperateOption): Promise<OperationResult<ED>>;
27
- select<T extends keyof ED>(entity: T, selection: ED[T]['Selection'], context: Cxt, option: SelectOption): Promise<Partial<ED[T]['Schema']>[]>;
28
- protected countAbjointRowAsync<T extends keyof ED>(entity: T, selection: Pick<ED[T]['Selection'], 'filter' | 'count'>, context: AsyncContext<ED>, option: SelectOption): Promise<number>;
29
- count<T extends keyof ED>(entity: T, selection: Pick<ED[T]['Selection'], 'filter' | 'count'>, context: Cxt, option: SelectOption): Promise<number>;
30
- begin(option?: TxnOption): Promise<string>;
31
- commit(txnId: string): Promise<void>;
32
- rollback(txnId: string): Promise<void>;
33
- connect(): void;
34
- disconnect(): Promise<void>;
35
- initialize(option: CreateEntityOption): Promise<void>;
36
- }
1
+ import { EntityDict, OperateOption, OperationResult, TxnOption, StorageSchema, SelectOption, AggregationResult } from 'oak-domain/lib/types';
2
+ import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
3
+ import { CascadeStore } from 'oak-domain/lib/store/CascadeStore';
4
+ import { MySQLConfiguration } from './types/Configuration';
5
+ import { MySqlConnector } from './connector';
6
+ import { MySqlTranslator, MySqlSelectOption, MysqlOperateOption } from './translator';
7
+ import { AsyncContext, AsyncRowStore } from 'oak-domain/lib/store/AsyncRowStore';
8
+ import { SyncContext } from 'oak-domain/lib/store/SyncRowStore';
9
+ import { CreateEntityOption } from '../types/Translator';
10
+ export declare class MysqlStore<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>> extends CascadeStore<ED> implements AsyncRowStore<ED, Cxt> {
11
+ protected countAbjointRow<T extends keyof ED, OP extends SelectOption, Cxt extends SyncContext<ED>>(entity: T, selection: Pick<ED[T]['Selection'], 'filter' | 'count'>, context: Cxt, option: OP): number;
12
+ protected aggregateAbjointRowSync<T extends keyof ED, OP extends SelectOption, Cxt extends SyncContext<ED>>(entity: T, aggregation: ED[T]['Aggregation'], context: Cxt, option: OP): AggregationResult<ED[T]['Schema']>;
13
+ protected selectAbjointRow<T extends keyof ED, OP extends SelectOption>(entity: T, selection: ED[T]['Selection'], context: SyncContext<ED>, option: OP): Partial<ED[T]['Schema']>[];
14
+ protected updateAbjointRow<T extends keyof ED, OP extends OperateOption>(entity: T, operation: ED[T]['Operation'], context: SyncContext<ED>, option: OP): number;
15
+ exec(script: string, txnId?: string): Promise<void>;
16
+ connector: MySqlConnector;
17
+ translator: MySqlTranslator<ED>;
18
+ constructor(storageSchema: StorageSchema<ED>, configuration: MySQLConfiguration);
19
+ checkRelationAsync<T extends keyof ED, Cxt extends AsyncContext<ED>>(entity: T, operation: Omit<ED[T]['Operation'] | ED[T]['Selection'], 'id'>, context: Cxt): Promise<void>;
20
+ protected aggregateAbjointRowAsync<T extends keyof ED, OP extends SelectOption, Cxt extends AsyncContext<ED>>(entity: T, aggregation: ED[T]['Aggregation'], context: Cxt, option: OP): Promise<AggregationResult<ED[T]['Schema']>>;
21
+ aggregate<T extends keyof ED, OP extends SelectOption>(entity: T, aggregation: ED[T]['Aggregation'], context: Cxt, option: OP): Promise<AggregationResult<ED[T]['Schema']>>;
22
+ protected supportManyToOneJoin(): boolean;
23
+ protected supportMultipleCreate(): boolean;
24
+ private formResult;
25
+ protected selectAbjointRowAsync<T extends keyof ED>(entity: T, selection: ED[T]['Selection'], context: AsyncContext<ED>, option?: MySqlSelectOption): Promise<Partial<ED[T]['Schema']>[]>;
26
+ protected updateAbjointRowAsync<T extends keyof ED>(entity: T, operation: ED[T]['Operation'], context: AsyncContext<ED>, option?: MysqlOperateOption): Promise<number>;
27
+ operate<T extends keyof ED>(entity: T, operation: ED[T]['Operation'], context: Cxt, option: OperateOption): Promise<OperationResult<ED>>;
28
+ select<T extends keyof ED>(entity: T, selection: ED[T]['Selection'], context: Cxt, option: SelectOption): Promise<Partial<ED[T]['Schema']>[]>;
29
+ protected countAbjointRowAsync<T extends keyof ED>(entity: T, selection: Pick<ED[T]['Selection'], 'filter' | 'count'>, context: AsyncContext<ED>, option: SelectOption): Promise<number>;
30
+ count<T extends keyof ED>(entity: T, selection: Pick<ED[T]['Selection'], 'filter' | 'count'>, context: Cxt, option: SelectOption): Promise<number>;
31
+ begin(option?: TxnOption): Promise<string>;
32
+ commit(txnId: string): Promise<void>;
33
+ rollback(txnId: string): Promise<void>;
34
+ connect(): void;
35
+ disconnect(): Promise<void>;
36
+ initialize(option: CreateEntityOption): Promise<void>;
37
+ }
@@ -1,305 +1,308 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MysqlStore = void 0;
4
- const tslib_1 = require("tslib");
5
- const CascadeStore_1 = require("oak-domain/lib/store/CascadeStore");
6
- const connector_1 = require("./connector");
7
- const translator_1 = require("./translator");
8
- const lodash_1 = require("lodash");
9
- const assert_1 = tslib_1.__importDefault(require("assert"));
10
- const relation_1 = require("oak-domain/lib/store/relation");
11
- function convertGeoTextToObject(geoText) {
12
- if (geoText.startsWith('POINT')) {
13
- const coord = geoText.match((/(\d|\.)+(?=\)|\s)/g));
14
- (0, assert_1.default)(coord.length === 2);
15
- return {
16
- type: 'point',
17
- coordinate: coord.map(ele => parseFloat(ele)),
18
- };
19
- }
20
- else {
21
- throw new Error('only support Point now');
22
- }
23
- }
24
- class MysqlStore extends CascadeStore_1.CascadeStore {
25
- countAbjointRow(entity, selection, context, option) {
26
- throw new Error('MySQL store不支持同步取数据,不应该跑到这儿');
27
- }
28
- aggregateAbjointRowSync(entity, aggregation, context, option) {
29
- throw new Error('MySQL store不支持同步取数据,不应该跑到这儿');
30
- }
31
- selectAbjointRow(entity, selection, context, option) {
32
- throw new Error('MySQL store不支持同步取数据,不应该跑到这儿');
33
- }
34
- updateAbjointRow(entity, operation, context, option) {
35
- throw new Error('MySQL store不支持同步更新数据,不应该跑到这儿');
36
- }
37
- async exec(script, txnId) {
38
- await this.connector.exec(script, txnId);
39
- }
40
- connector;
41
- translator;
42
- constructor(storageSchema, configuration) {
43
- super(storageSchema);
44
- this.connector = new connector_1.MySqlConnector(configuration);
45
- this.translator = new translator_1.MySqlTranslator(storageSchema);
46
- }
47
- async aggregateAbjointRowAsync(entity, aggregation, context, option) {
48
- const sql = this.translator.translateAggregate(entity, aggregation, option);
49
- const result = await this.connector.exec(sql, context.getCurrentTxnId());
50
- return this.formResult(entity, result[0]);
51
- }
52
- aggregate(entity, aggregation, context, option) {
53
- return this.aggregateAsync(entity, aggregation, context, option);
54
- }
55
- supportManyToOneJoin() {
56
- return true;
57
- }
58
- supportMultipleCreate() {
59
- return true;
60
- }
61
- formResult(entity, result) {
62
- const schema = this.getSchema();
63
- /* function resolveObject(r: Record<string, any>, path: string, value: any) {
64
- const i = path.indexOf(".");
65
- const bs = path.indexOf('[');
66
- const be = path.indexOf(']');
67
- if (i === -1 && bs === -1) {
68
- r[i] = value;
69
- }
70
- else if (i === -1) {
71
-
72
- }
73
- else if (bs === -1) {
74
- const attrHead = path.slice(0, i);
75
- const attrTail = path.slice(i + 1);
76
- if (!r[attrHead]) {
77
- r[attrHead] = {};
78
- }
79
- resolveObject(r[attrHead], attrTail, value);
80
- }
81
- } */
82
- function resolveAttribute(entity2, r, attr, value) {
83
- const { attributes, view } = schema[entity2];
84
- if (!view) {
85
- const i = attr.indexOf(".");
86
- if (i !== -1) {
87
- const attrHead = attr.slice(0, i);
88
- const attrTail = attr.slice(i + 1);
89
- const rel = (0, relation_1.judgeRelation)(schema, entity2, attrHead);
90
- if (rel === 1) {
91
- (0, lodash_1.set)(r, attr, value);
92
- }
93
- else {
94
- if (!r[attrHead]) {
95
- r[attrHead] = {};
96
- }
97
- if (rel === 0) {
98
- resolveAttribute(entity2, r[attrHead], attrTail, value);
99
- }
100
- else if (rel === 2) {
101
- resolveAttribute(attrHead, r[attrHead], attrTail, value);
102
- }
103
- else {
104
- (0, assert_1.default)(typeof rel === 'string');
105
- resolveAttribute(rel, r[attrHead], attrTail, value);
106
- }
107
- }
108
- }
109
- else if (attributes[attr]) {
110
- const { type } = attributes[attr];
111
- switch (type) {
112
- case 'date':
113
- case 'time': {
114
- if (value instanceof Date) {
115
- r[attr] = value.valueOf();
116
- }
117
- else {
118
- r[attr] = value;
119
- }
120
- break;
121
- }
122
- case 'geometry': {
123
- if (typeof value === 'string') {
124
- r[attr] = convertGeoTextToObject(value);
125
- }
126
- else {
127
- r[attr] = value;
128
- }
129
- break;
130
- }
131
- case 'object':
132
- case 'array': {
133
- if (typeof value === 'string') {
134
- r[attr] = JSON.parse(value.replace(/[\r]/g, '\\r').replace(/[\n]/g, '\\n'));
135
- }
136
- else {
137
- r[attr] = value;
138
- }
139
- break;
140
- }
141
- case 'function': {
142
- if (typeof value === 'string') {
143
- // 函数的执行环境需要的参数只有创建函数者知悉,只能由上层再创建Function
144
- r[attr] = `return ${Buffer.from(value, 'base64').toString()}`;
145
- }
146
- else {
147
- r[attr] = value;
148
- }
149
- break;
150
- }
151
- case 'bool':
152
- case 'boolean': {
153
- if (value === 0) {
154
- r[attr] = false;
155
- }
156
- else if (value === 1) {
157
- r[attr] = true;
158
- }
159
- else {
160
- r[attr] = value;
161
- }
162
- break;
163
- }
164
- case 'decimal': {
165
- // mysql内部取回decimal是字符串
166
- if (typeof value === 'string') {
167
- r[attr] = parseFloat(value);
168
- }
169
- else {
170
- (0, assert_1.default)(value === null || typeof value === 'number');
171
- r[attr] = value;
172
- }
173
- break;
174
- }
175
- default: {
176
- r[attr] = value;
177
- }
178
- }
179
- }
180
- else {
181
- r[attr] = value;
182
- }
183
- }
184
- else {
185
- (0, lodash_1.assign)(r, {
186
- [attr]: value,
187
- });
188
- }
189
- }
190
- function removeNullObjects(r, e) {
191
- // assert(r.id && typeof r.id === 'string', `对象${<string>e}取数据时发现id为非法值${r.id},rowId是${r.id}`)
192
- for (let attr in r) {
193
- const rel = (0, relation_1.judgeRelation)(schema, e, attr);
194
- if (rel === 2) {
195
- // 边界,如果是toModi的对象,这里的外键确实有可能为空
196
- // assert(schema[e].toModi || r.entity !== attr || r.entityId === r[attr].id, `对象${<string>e}取数据时,发现entityId与连接的对象的主键不一致,rowId是${r.id},其entityId值为${r.entityId},连接的对象的主键为${r[attr].id}`);
197
- if (r[attr].id === null) {
198
- (0, assert_1.default)(schema[e].toModi || r.entity !== attr);
199
- delete r[attr];
200
- continue;
201
- }
202
- // assert(r.entity === attr, `对象${<string>e}取数据时,发现entity值与连接的外键对象不一致,rowId是${r.id},其entity值为${r.entity},连接的对象为${attr}`);
203
- removeNullObjects(r[attr], attr);
204
- }
205
- else if (typeof rel === 'string') {
206
- // 边界,如果是toModi的对象,这里的外键确实有可能为空
207
- // assert(schema[e].toModi || r[`${attr}Id`] === r[attr].id, `对象${<string>e}取数据时,发现其外键与连接的对象的主键不一致,rowId是${r.id},其${attr}Id值为${r[`${attr}Id`]},连接的对象的主键为${r[attr].id}`);
208
- if (r[attr].id === null) {
209
- (0, assert_1.default)(schema[e].toModi || r[`${attr}Id`] === null);
210
- delete r[attr];
211
- continue;
212
- }
213
- removeNullObjects(r[attr], rel);
214
- }
215
- }
216
- }
217
- function formSingleRow(r) {
218
- let result2 = {};
219
- for (let attr in r) {
220
- const value = r[attr];
221
- resolveAttribute(entity, result2, attr, value);
222
- }
223
- removeNullObjects(result2, entity);
224
- return result2;
225
- }
226
- if (result instanceof Array) {
227
- return result.map(r => formSingleRow(r));
228
- }
229
- return formSingleRow(result);
230
- }
231
- async selectAbjointRowAsync(entity, selection, context, option) {
232
- const sql = this.translator.translateSelect(entity, selection, option);
233
- const result = await this.connector.exec(sql, context.getCurrentTxnId());
234
- return this.formResult(entity, result[0]);
235
- }
236
- async updateAbjointRowAsync(entity, operation, context, option) {
237
- const { translator, connector } = this;
238
- const { action } = operation;
239
- const txn = context.getCurrentTxnId();
240
- switch (action) {
241
- case 'create': {
242
- const { data } = operation;
243
- const sql = translator.translateInsert(entity, data instanceof Array ? data : [data]);
244
- const result = await connector.exec(sql, txn);
245
- return result[0].affectedRows;
246
- }
247
- case 'remove': {
248
- const sql = translator.translateRemove(entity, operation, option);
249
- const result = await connector.exec(sql, txn);
250
- // todo 这里对sorter和indexfrom/count的支持不完整
251
- return result[0].changedRows;
252
- }
253
- default: {
254
- (0, assert_1.default)(!['select', 'download', 'stat'].includes(action));
255
- const sql = translator.translateUpdate(entity, operation, option);
256
- const result = await connector.exec(sql, txn);
257
- // todo 这里对sorter和indexfrom/count的支持不完整
258
- return result[0].changedRows;
259
- }
260
- }
261
- }
262
- async operate(entity, operation, context, option) {
263
- const { action } = operation;
264
- (0, assert_1.default)(!['select', 'download', 'stat'].includes(action), '现在不支持使用select operation');
265
- return await super.operateAsync(entity, operation, context, option);
266
- }
267
- async select(entity, selection, context, option) {
268
- const result = await super.selectAsync(entity, selection, context, option);
269
- return result;
270
- }
271
- async countAbjointRowAsync(entity, selection, context, option) {
272
- const sql = this.translator.translateCount(entity, selection, option);
273
- const result = await this.connector.exec(sql, context.getCurrentTxnId());
274
- return result[0][0].cnt;
275
- }
276
- async count(entity, selection, context, option) {
277
- return this.countAsync(entity, selection, context, option);
278
- }
279
- async begin(option) {
280
- const txn = await this.connector.startTransaction(option);
281
- return txn;
282
- }
283
- async commit(txnId) {
284
- await this.connector.commitTransaction(txnId);
285
- }
286
- async rollback(txnId) {
287
- await this.connector.rollbackTransaction(txnId);
288
- }
289
- connect() {
290
- this.connector.connect();
291
- }
292
- async disconnect() {
293
- await this.connector.disconnect();
294
- }
295
- async initialize(option) {
296
- const schema = this.getSchema();
297
- for (const entity in schema) {
298
- const sqls = this.translator.translateCreateEntity(entity, option);
299
- for (const sql of sqls) {
300
- await this.connector.exec(sql);
301
- }
302
- }
303
- }
304
- }
305
- exports.MysqlStore = MysqlStore;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MysqlStore = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const CascadeStore_1 = require("oak-domain/lib/store/CascadeStore");
6
+ const connector_1 = require("./connector");
7
+ const translator_1 = require("./translator");
8
+ const lodash_1 = require("lodash");
9
+ const assert_1 = tslib_1.__importDefault(require("assert"));
10
+ const relation_1 = require("oak-domain/lib/store/relation");
11
+ function convertGeoTextToObject(geoText) {
12
+ if (geoText.startsWith('POINT')) {
13
+ const coord = geoText.match((/(\d|\.)+(?=\)|\s)/g));
14
+ (0, assert_1.default)(coord.length === 2);
15
+ return {
16
+ type: 'point',
17
+ coordinate: coord.map(ele => parseFloat(ele)),
18
+ };
19
+ }
20
+ else {
21
+ throw new Error('only support Point now');
22
+ }
23
+ }
24
+ class MysqlStore extends CascadeStore_1.CascadeStore {
25
+ countAbjointRow(entity, selection, context, option) {
26
+ throw new Error('MySQL store不支持同步取数据,不应该跑到这儿');
27
+ }
28
+ aggregateAbjointRowSync(entity, aggregation, context, option) {
29
+ throw new Error('MySQL store不支持同步取数据,不应该跑到这儿');
30
+ }
31
+ selectAbjointRow(entity, selection, context, option) {
32
+ throw new Error('MySQL store不支持同步取数据,不应该跑到这儿');
33
+ }
34
+ updateAbjointRow(entity, operation, context, option) {
35
+ throw new Error('MySQL store不支持同步更新数据,不应该跑到这儿');
36
+ }
37
+ async exec(script, txnId) {
38
+ await this.connector.exec(script, txnId);
39
+ }
40
+ connector;
41
+ translator;
42
+ constructor(storageSchema, configuration) {
43
+ super(storageSchema);
44
+ this.connector = new connector_1.MySqlConnector(configuration);
45
+ this.translator = new translator_1.MySqlTranslator(storageSchema);
46
+ }
47
+ checkRelationAsync(entity, operation, context) {
48
+ throw new Error('Method not implemented.');
49
+ }
50
+ async aggregateAbjointRowAsync(entity, aggregation, context, option) {
51
+ const sql = this.translator.translateAggregate(entity, aggregation, option);
52
+ const result = await this.connector.exec(sql, context.getCurrentTxnId());
53
+ return this.formResult(entity, result[0]);
54
+ }
55
+ aggregate(entity, aggregation, context, option) {
56
+ return this.aggregateAsync(entity, aggregation, context, option);
57
+ }
58
+ supportManyToOneJoin() {
59
+ return true;
60
+ }
61
+ supportMultipleCreate() {
62
+ return true;
63
+ }
64
+ formResult(entity, result) {
65
+ const schema = this.getSchema();
66
+ /* function resolveObject(r: Record<string, any>, path: string, value: any) {
67
+ const i = path.indexOf(".");
68
+ const bs = path.indexOf('[');
69
+ const be = path.indexOf(']');
70
+ if (i === -1 && bs === -1) {
71
+ r[i] = value;
72
+ }
73
+ else if (i === -1) {
74
+
75
+ }
76
+ else if (bs === -1) {
77
+ const attrHead = path.slice(0, i);
78
+ const attrTail = path.slice(i + 1);
79
+ if (!r[attrHead]) {
80
+ r[attrHead] = {};
81
+ }
82
+ resolveObject(r[attrHead], attrTail, value);
83
+ }
84
+ } */
85
+ function resolveAttribute(entity2, r, attr, value) {
86
+ const { attributes, view } = schema[entity2];
87
+ if (!view) {
88
+ const i = attr.indexOf(".");
89
+ if (i !== -1) {
90
+ const attrHead = attr.slice(0, i);
91
+ const attrTail = attr.slice(i + 1);
92
+ const rel = (0, relation_1.judgeRelation)(schema, entity2, attrHead);
93
+ if (rel === 1) {
94
+ (0, lodash_1.set)(r, attr, value);
95
+ }
96
+ else {
97
+ if (!r[attrHead]) {
98
+ r[attrHead] = {};
99
+ }
100
+ if (rel === 0) {
101
+ resolveAttribute(entity2, r[attrHead], attrTail, value);
102
+ }
103
+ else if (rel === 2) {
104
+ resolveAttribute(attrHead, r[attrHead], attrTail, value);
105
+ }
106
+ else {
107
+ (0, assert_1.default)(typeof rel === 'string');
108
+ resolveAttribute(rel, r[attrHead], attrTail, value);
109
+ }
110
+ }
111
+ }
112
+ else if (attributes[attr]) {
113
+ const { type } = attributes[attr];
114
+ switch (type) {
115
+ case 'date':
116
+ case 'time': {
117
+ if (value instanceof Date) {
118
+ r[attr] = value.valueOf();
119
+ }
120
+ else {
121
+ r[attr] = value;
122
+ }
123
+ break;
124
+ }
125
+ case 'geometry': {
126
+ if (typeof value === 'string') {
127
+ r[attr] = convertGeoTextToObject(value);
128
+ }
129
+ else {
130
+ r[attr] = value;
131
+ }
132
+ break;
133
+ }
134
+ case 'object':
135
+ case 'array': {
136
+ if (typeof value === 'string') {
137
+ r[attr] = JSON.parse(value.replace(/[\r]/g, '\\r').replace(/[\n]/g, '\\n'));
138
+ }
139
+ else {
140
+ r[attr] = value;
141
+ }
142
+ break;
143
+ }
144
+ case 'function': {
145
+ if (typeof value === 'string') {
146
+ // 函数的执行环境需要的参数只有创建函数者知悉,只能由上层再创建Function
147
+ r[attr] = `return ${Buffer.from(value, 'base64').toString()}`;
148
+ }
149
+ else {
150
+ r[attr] = value;
151
+ }
152
+ break;
153
+ }
154
+ case 'bool':
155
+ case 'boolean': {
156
+ if (value === 0) {
157
+ r[attr] = false;
158
+ }
159
+ else if (value === 1) {
160
+ r[attr] = true;
161
+ }
162
+ else {
163
+ r[attr] = value;
164
+ }
165
+ break;
166
+ }
167
+ case 'decimal': {
168
+ // mysql内部取回decimal是字符串
169
+ if (typeof value === 'string') {
170
+ r[attr] = parseFloat(value);
171
+ }
172
+ else {
173
+ (0, assert_1.default)(value === null || typeof value === 'number');
174
+ r[attr] = value;
175
+ }
176
+ break;
177
+ }
178
+ default: {
179
+ r[attr] = value;
180
+ }
181
+ }
182
+ }
183
+ else {
184
+ r[attr] = value;
185
+ }
186
+ }
187
+ else {
188
+ (0, lodash_1.assign)(r, {
189
+ [attr]: value,
190
+ });
191
+ }
192
+ }
193
+ function removeNullObjects(r, e) {
194
+ // assert(r.id && typeof r.id === 'string', `对象${<string>e}取数据时发现id为非法值${r.id},rowId是${r.id}`)
195
+ for (let attr in r) {
196
+ const rel = (0, relation_1.judgeRelation)(schema, e, attr);
197
+ if (rel === 2) {
198
+ // 边界,如果是toModi的对象,这里的外键确实有可能为空
199
+ // assert(schema[e].toModi || r.entity !== attr || r.entityId === r[attr].id, `对象${<string>e}取数据时,发现entityId与连接的对象的主键不一致,rowId是${r.id},其entityId值为${r.entityId},连接的对象的主键为${r[attr].id}`);
200
+ if (r[attr].id === null) {
201
+ (0, assert_1.default)(schema[e].toModi || r.entity !== attr);
202
+ delete r[attr];
203
+ continue;
204
+ }
205
+ // assert(r.entity === attr, `对象${<string>e}取数据时,发现entity值与连接的外键对象不一致,rowId是${r.id},其entity值为${r.entity},连接的对象为${attr}`);
206
+ removeNullObjects(r[attr], attr);
207
+ }
208
+ else if (typeof rel === 'string') {
209
+ // 边界,如果是toModi的对象,这里的外键确实有可能为空
210
+ // assert(schema[e].toModi || r[`${attr}Id`] === r[attr].id, `对象${<string>e}取数据时,发现其外键与连接的对象的主键不一致,rowId是${r.id},其${attr}Id值为${r[`${attr}Id`]},连接的对象的主键为${r[attr].id}`);
211
+ if (r[attr].id === null) {
212
+ (0, assert_1.default)(schema[e].toModi || r[`${attr}Id`] === null);
213
+ delete r[attr];
214
+ continue;
215
+ }
216
+ removeNullObjects(r[attr], rel);
217
+ }
218
+ }
219
+ }
220
+ function formSingleRow(r) {
221
+ let result2 = {};
222
+ for (let attr in r) {
223
+ const value = r[attr];
224
+ resolveAttribute(entity, result2, attr, value);
225
+ }
226
+ removeNullObjects(result2, entity);
227
+ return result2;
228
+ }
229
+ if (result instanceof Array) {
230
+ return result.map(r => formSingleRow(r));
231
+ }
232
+ return formSingleRow(result);
233
+ }
234
+ async selectAbjointRowAsync(entity, selection, context, option) {
235
+ const sql = this.translator.translateSelect(entity, selection, option);
236
+ const result = await this.connector.exec(sql, context.getCurrentTxnId());
237
+ return this.formResult(entity, result[0]);
238
+ }
239
+ async updateAbjointRowAsync(entity, operation, context, option) {
240
+ const { translator, connector } = this;
241
+ const { action } = operation;
242
+ const txn = context.getCurrentTxnId();
243
+ switch (action) {
244
+ case 'create': {
245
+ const { data } = operation;
246
+ const sql = translator.translateInsert(entity, data instanceof Array ? data : [data]);
247
+ const result = await connector.exec(sql, txn);
248
+ return result[0].affectedRows;
249
+ }
250
+ case 'remove': {
251
+ const sql = translator.translateRemove(entity, operation, option);
252
+ const result = await connector.exec(sql, txn);
253
+ // todo 这里对sorter和indexfrom/count的支持不完整
254
+ return result[0].changedRows;
255
+ }
256
+ default: {
257
+ (0, assert_1.default)(!['select', 'download', 'stat'].includes(action));
258
+ const sql = translator.translateUpdate(entity, operation, option);
259
+ const result = await connector.exec(sql, txn);
260
+ // todo 这里对sorter和indexfrom/count的支持不完整
261
+ return result[0].changedRows;
262
+ }
263
+ }
264
+ }
265
+ async operate(entity, operation, context, option) {
266
+ const { action } = operation;
267
+ (0, assert_1.default)(!['select', 'download', 'stat'].includes(action), '现在不支持使用select operation');
268
+ return await super.operateAsync(entity, operation, context, option);
269
+ }
270
+ async select(entity, selection, context, option) {
271
+ const result = await super.selectAsync(entity, selection, context, option);
272
+ return result;
273
+ }
274
+ async countAbjointRowAsync(entity, selection, context, option) {
275
+ const sql = this.translator.translateCount(entity, selection, option);
276
+ const result = await this.connector.exec(sql, context.getCurrentTxnId());
277
+ return result[0][0].cnt;
278
+ }
279
+ async count(entity, selection, context, option) {
280
+ return this.countAsync(entity, selection, context, option);
281
+ }
282
+ async begin(option) {
283
+ const txn = await this.connector.startTransaction(option);
284
+ return txn;
285
+ }
286
+ async commit(txnId) {
287
+ await this.connector.commitTransaction(txnId);
288
+ }
289
+ async rollback(txnId) {
290
+ await this.connector.rollbackTransaction(txnId);
291
+ }
292
+ connect() {
293
+ this.connector.connect();
294
+ }
295
+ async disconnect() {
296
+ await this.connector.disconnect();
297
+ }
298
+ async initialize(option) {
299
+ const schema = this.getSchema();
300
+ for (const entity in schema) {
301
+ const sqls = this.translator.translateCreateEntity(entity, option);
302
+ for (const sql of sqls) {
303
+ await this.connector.exec(sql);
304
+ }
305
+ }
306
+ }
307
+ }
308
+ exports.MysqlStore = MysqlStore;
@@ -635,7 +635,7 @@ class SqlTranslator {
635
635
  */
636
636
  const joinFilter = {
637
637
  $expr83: {
638
- [['all', 'not all'].includes(predicate) ? '$ne' : '$eq']: [
638
+ '$eq': [
639
639
  {
640
640
  '#attr': fk,
641
641
  },
@@ -655,7 +655,9 @@ class SqlTranslator {
655
655
  data: {
656
656
  id: 1,
657
657
  },
658
- filter: (0, filter_1.combineFilters)(subEntity, this.schema, [joinFilter, filter2[attr]]),
658
+ filter: (0, filter_1.combineFilters)(subEntity, this.schema, [joinFilter, {
659
+ $not: filter2[attr],
660
+ }]),
659
661
  indexFrom: 0,
660
662
  count: 1,
661
663
  }, currentNumber, filterRefAlias, option);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oak-db",
3
- "version": "3.3.9",
3
+ "version": "3.3.10",
4
4
  "description": "oak-db",
5
5
  "main": "lib/index",
6
6
  "author": {