@zhin.js/database 1.0.45 → 1.0.47
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/package.json +7 -4
- package/CHANGELOG.md +0 -293
- package/src/base/database.ts +0 -272
- package/src/base/dialect.ts +0 -89
- package/src/base/index.ts +0 -6
- package/src/base/model.ts +0 -329
- package/src/base/query-classes.ts +0 -625
- package/src/base/thenable.ts +0 -55
- package/src/base/transaction.ts +0 -213
- package/src/dialects/memory.ts +0 -882
- package/src/dialects/mongodb.ts +0 -535
- package/src/dialects/mysql.ts +0 -286
- package/src/dialects/pg.ts +0 -284
- package/src/dialects/redis.ts +0 -600
- package/src/dialects/sqlite.ts +0 -317
- package/src/index.ts +0 -19
- package/src/migration.ts +0 -547
- package/src/registry.ts +0 -59
- package/src/type/document/database.ts +0 -284
- package/src/type/document/model.ts +0 -87
- package/src/type/keyvalue/database.ts +0 -262
- package/src/type/keyvalue/model.ts +0 -339
- package/src/type/related/database.ts +0 -674
- package/src/type/related/model.ts +0 -884
- package/src/types.ts +0 -918
- package/tests/database.test.ts +0 -1750
- package/tests/dialects.test.ts +0 -147
- package/tests/migration.test.ts +0 -73
- package/tsconfig.json +0 -24
|
@@ -1,284 +0,0 @@
|
|
|
1
|
-
import { Database, Dialect } from '../../base/index.js';
|
|
2
|
-
import { DocumentModel } from './model.js';
|
|
3
|
-
import {
|
|
4
|
-
QueryParams,
|
|
5
|
-
BuildQueryResult,
|
|
6
|
-
DocumentQueryResult,
|
|
7
|
-
CreateQueryParams,
|
|
8
|
-
SelectQueryParams,
|
|
9
|
-
InsertQueryParams,
|
|
10
|
-
UpdateQueryParams,
|
|
11
|
-
DeleteQueryParams,
|
|
12
|
-
AlterQueryParams,
|
|
13
|
-
DropTableQueryParams,
|
|
14
|
-
DropIndexQueryParams
|
|
15
|
-
} from '../../types.js';
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* 文档型数据库类
|
|
19
|
-
* 支持集合、文档的文档型数据模型
|
|
20
|
-
*/
|
|
21
|
-
export class DocumentDatabase<
|
|
22
|
-
D = any,
|
|
23
|
-
S extends Record<string, object> = Record<string, object>
|
|
24
|
-
> extends Database<D, S, DocumentQueryResult> {
|
|
25
|
-
|
|
26
|
-
constructor(
|
|
27
|
-
dialect: Dialect<D, S, DocumentQueryResult>,
|
|
28
|
-
definitions?: Database.DefinitionObj<S>,
|
|
29
|
-
) {
|
|
30
|
-
super(dialect, definitions);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
protected async initialize(): Promise<void> {
|
|
34
|
-
for (const tableName of this.definitions.keys()) {
|
|
35
|
-
this.models.set(tableName, new DocumentModel(this, tableName));
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* 构建查询(重写基类方法)
|
|
41
|
-
*/
|
|
42
|
-
buildQuery<T extends keyof S>(params: QueryParams<S, T>): BuildQueryResult<DocumentQueryResult> {
|
|
43
|
-
switch (params.type) {
|
|
44
|
-
case 'create':
|
|
45
|
-
return this.buildCreateQuery(params as CreateQueryParams<S, T>);
|
|
46
|
-
case 'select':
|
|
47
|
-
return this.buildSelectQuery(params as SelectQueryParams<S, T>);
|
|
48
|
-
case 'insert':
|
|
49
|
-
return this.buildInsertQuery(params as InsertQueryParams<S, T>);
|
|
50
|
-
case 'update':
|
|
51
|
-
return this.buildUpdateQuery(params as UpdateQueryParams<S, T>);
|
|
52
|
-
case 'delete':
|
|
53
|
-
return this.buildDeleteQuery(params as DeleteQueryParams<S, T>);
|
|
54
|
-
case 'alter':
|
|
55
|
-
return this.buildAlterQuery(params as AlterQueryParams<S, T>);
|
|
56
|
-
case 'drop_table':
|
|
57
|
-
return this.buildDropTableQuery(params as DropTableQueryParams<S, T>);
|
|
58
|
-
case 'drop_index':
|
|
59
|
-
return this.buildDropIndexQuery(params as DropIndexQueryParams<S, T>);
|
|
60
|
-
default:
|
|
61
|
-
throw new Error(`Unsupported query type: ${(params as any).type}`);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* 构建创建集合查询
|
|
67
|
-
*/
|
|
68
|
-
protected buildCreateQuery<T extends keyof S>(params: CreateQueryParams<S, T>): BuildQueryResult<DocumentQueryResult> {
|
|
69
|
-
return {
|
|
70
|
-
query: {
|
|
71
|
-
collection: params.tableName as string,
|
|
72
|
-
filter: {},
|
|
73
|
-
projection: {}
|
|
74
|
-
},
|
|
75
|
-
params: []
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* 构建查询文档查询
|
|
81
|
-
*/
|
|
82
|
-
protected buildSelectQuery<T extends keyof S>(params: SelectQueryParams<S, T>): BuildQueryResult<DocumentQueryResult> {
|
|
83
|
-
const filter: Record<string, any> = {};
|
|
84
|
-
|
|
85
|
-
// 转换条件为文档查询格式
|
|
86
|
-
if (params.conditions) {
|
|
87
|
-
this.convertConditionToFilter(params.conditions, filter);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const query: DocumentQueryResult = {
|
|
91
|
-
collection: params.tableName as string,
|
|
92
|
-
filter
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
if (params.orderings) {
|
|
96
|
-
query.sort = {};
|
|
97
|
-
for (const order of params.orderings) {
|
|
98
|
-
query.sort[order.field as string] = order.direction === 'ASC' ? 1 : -1;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
if (params.limitCount) {
|
|
103
|
-
query.limit = params.limitCount;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
if (params.offsetCount) {
|
|
107
|
-
query.skip = params.offsetCount;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
if (params.fields && params.fields.length > 0) {
|
|
111
|
-
query.projection = {};
|
|
112
|
-
for (const field of params.fields) {
|
|
113
|
-
query.projection[field as string] = 1;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
return {
|
|
118
|
-
query,
|
|
119
|
-
params: []
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* 构建插入文档查询
|
|
125
|
-
*/
|
|
126
|
-
protected buildInsertQuery<T extends keyof S>(params: InsertQueryParams<S, T>): BuildQueryResult<DocumentQueryResult> {
|
|
127
|
-
return {
|
|
128
|
-
query: {
|
|
129
|
-
collection: params.tableName as string,
|
|
130
|
-
filter: {},
|
|
131
|
-
projection: {}
|
|
132
|
-
},
|
|
133
|
-
params: [params.data]
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* 构建更新文档查询
|
|
139
|
-
*/
|
|
140
|
-
protected buildUpdateQuery<T extends keyof S>(params: UpdateQueryParams<S, T>): BuildQueryResult<DocumentQueryResult> {
|
|
141
|
-
const filter: Record<string, any> = {};
|
|
142
|
-
|
|
143
|
-
if (params.conditions) {
|
|
144
|
-
this.convertConditionToFilter(params.conditions, filter);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
return {
|
|
148
|
-
query: {
|
|
149
|
-
collection: params.tableName as string,
|
|
150
|
-
filter,
|
|
151
|
-
projection: {}
|
|
152
|
-
},
|
|
153
|
-
params: [params.update]
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* 构建删除文档查询
|
|
159
|
-
*/
|
|
160
|
-
protected buildDeleteQuery<T extends keyof S>(params: DeleteQueryParams<S, T>): BuildQueryResult<DocumentQueryResult> {
|
|
161
|
-
const filter: Record<string, any> = {};
|
|
162
|
-
|
|
163
|
-
if (params.conditions) {
|
|
164
|
-
this.convertConditionToFilter(params.conditions, filter);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
return {
|
|
168
|
-
query: {
|
|
169
|
-
collection: params.tableName as string,
|
|
170
|
-
filter,
|
|
171
|
-
projection: {}
|
|
172
|
-
},
|
|
173
|
-
params: []
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* 构建修改集合查询
|
|
179
|
-
*/
|
|
180
|
-
protected buildAlterQuery<T extends keyof S>(params: AlterQueryParams<S, T>): BuildQueryResult<DocumentQueryResult> {
|
|
181
|
-
return {
|
|
182
|
-
query: {
|
|
183
|
-
collection: params.tableName as string,
|
|
184
|
-
filter: {},
|
|
185
|
-
projection: {}
|
|
186
|
-
},
|
|
187
|
-
params: [params.alterations]
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* 构建删除集合查询
|
|
193
|
-
*/
|
|
194
|
-
protected buildDropTableQuery<T extends keyof S>(params: DropTableQueryParams<S, T>): BuildQueryResult<DocumentQueryResult> {
|
|
195
|
-
return {
|
|
196
|
-
query: {
|
|
197
|
-
collection: params.tableName as string,
|
|
198
|
-
filter: {},
|
|
199
|
-
projection: {}
|
|
200
|
-
},
|
|
201
|
-
params: []
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* 构建删除索引查询
|
|
207
|
-
*/
|
|
208
|
-
protected buildDropIndexQuery<T extends keyof S>(params: DropIndexQueryParams<S, T>): BuildQueryResult<DocumentQueryResult> {
|
|
209
|
-
return {
|
|
210
|
-
query: {
|
|
211
|
-
collection: params.tableName as string,
|
|
212
|
-
filter: {},
|
|
213
|
-
projection: {}
|
|
214
|
-
},
|
|
215
|
-
params: [params.indexName]
|
|
216
|
-
};
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* 转换条件为文档查询格式
|
|
221
|
-
*/
|
|
222
|
-
private convertConditionToFilter(condition: any, filter: Record<string, any>): void {
|
|
223
|
-
if (typeof condition !== 'object' || condition === null) {
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
for (const [key, value] of Object.entries(condition)) {
|
|
228
|
-
if (key.startsWith('$')) {
|
|
229
|
-
// 逻辑操作符
|
|
230
|
-
if (key === '$and' && Array.isArray(value)) {
|
|
231
|
-
filter.$and = value.map(cond => {
|
|
232
|
-
const subFilter: Record<string, any> = {};
|
|
233
|
-
this.convertConditionToFilter(cond, subFilter);
|
|
234
|
-
return subFilter;
|
|
235
|
-
});
|
|
236
|
-
} else if (key === '$or' && Array.isArray(value)) {
|
|
237
|
-
filter.$or = value.map(cond => {
|
|
238
|
-
const subFilter: Record<string, any> = {};
|
|
239
|
-
this.convertConditionToFilter(cond, subFilter);
|
|
240
|
-
return subFilter;
|
|
241
|
-
});
|
|
242
|
-
} else if (key === '$not') {
|
|
243
|
-
const subFilter: Record<string, any> = {};
|
|
244
|
-
this.convertConditionToFilter(value, subFilter);
|
|
245
|
-
filter.$not = subFilter;
|
|
246
|
-
}
|
|
247
|
-
} else if (typeof value === 'object' && value !== null) {
|
|
248
|
-
// 比较操作符
|
|
249
|
-
const fieldFilter: Record<string, any> = {};
|
|
250
|
-
for (const [op, opValue] of Object.entries(value)) {
|
|
251
|
-
if (op.startsWith('$')) {
|
|
252
|
-
fieldFilter[op] = opValue;
|
|
253
|
-
} else {
|
|
254
|
-
fieldFilter.$eq = value;
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
filter[key] = Object.keys(fieldFilter).length > 0 ? fieldFilter : value;
|
|
258
|
-
} else {
|
|
259
|
-
// 简单相等
|
|
260
|
-
filter[key] = { $eq: value };
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
/**
|
|
266
|
-
* 获取模型
|
|
267
|
-
*/
|
|
268
|
-
model<T extends keyof S>(name: T): DocumentModel<D, S, T> {
|
|
269
|
-
let model = this.models.get(name) as DocumentModel<D, S, T> | undefined;
|
|
270
|
-
if (!model) {
|
|
271
|
-
model = new DocumentModel<D, S, T>(this, name);
|
|
272
|
-
this.models.set(name, model as any);
|
|
273
|
-
}
|
|
274
|
-
return model as DocumentModel<D, S, T>;
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
/**
|
|
278
|
-
* 获取所有模型名称
|
|
279
|
-
*/
|
|
280
|
-
getModelNames(): string[] {
|
|
281
|
-
return Object.keys(this.definitions || {});
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { Model} from '../../base/index.js';
|
|
2
|
-
import { DocumentDatabase } from './database.js';
|
|
3
|
-
import { DocumentQueryResult, Condition } from '../../types.js';
|
|
4
|
-
import { randomUUID } from 'crypto';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* 文档型模型类
|
|
8
|
-
* 继承自 Model,提供文档型数据库特有的操作
|
|
9
|
-
*/
|
|
10
|
-
export class DocumentModel<D=any, S extends Record<string, object> = Record<string, object>, T extends keyof S = keyof S> extends Model<D, S, DocumentQueryResult, T> {
|
|
11
|
-
constructor(
|
|
12
|
-
database: DocumentDatabase<D, S>,
|
|
13
|
-
name: T
|
|
14
|
-
) {
|
|
15
|
-
super(database, name);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* 创建文档
|
|
20
|
-
*/
|
|
21
|
-
async create(document: S[T]): Promise<S[T] & { _id: string }>;
|
|
22
|
-
async create(documents: S[T][]): Promise<(S[T] & { _id: string })[]>;
|
|
23
|
-
async create(documents: S[T] | S[T][]): Promise<(S[T] & { _id: string }) | (S[T] & { _id: string })[]> {
|
|
24
|
-
const isArray = Array.isArray(documents);
|
|
25
|
-
const docs = isArray ? documents : [documents];
|
|
26
|
-
|
|
27
|
-
const results = [];
|
|
28
|
-
for (const doc of docs) {
|
|
29
|
-
const _id = this.generateId();
|
|
30
|
-
const docWithId = { ...doc, _id };
|
|
31
|
-
|
|
32
|
-
await this.dialect.query(
|
|
33
|
-
{
|
|
34
|
-
operation: 'insertOne',
|
|
35
|
-
filter: {},
|
|
36
|
-
projection: {},
|
|
37
|
-
collection: this.name as string,
|
|
38
|
-
},
|
|
39
|
-
[docWithId]
|
|
40
|
-
);
|
|
41
|
-
results.push(docWithId);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return isArray ? results : results[0];
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* 查找单个文档
|
|
49
|
-
*/
|
|
50
|
-
async selectOne<K extends keyof S[T]>(...fields: Array<K>): Promise<(Pick<S[T], K> & { _id: string }) | null> {
|
|
51
|
-
const results = await this.select(...fields).limit(1);
|
|
52
|
-
return results.length > 0 ? results[0] as (Pick<S[T], K> & { _id: string }) : null;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* 根据ID查找文档
|
|
57
|
-
*/
|
|
58
|
-
async selectById(id: string){
|
|
59
|
-
return this.select('_id' as any).where({
|
|
60
|
-
_id: id,
|
|
61
|
-
} as Condition<S[T]>).limit(1).then((results: any) => results[0] || null);
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* 根据ID更新文档
|
|
65
|
-
*/
|
|
66
|
-
async updateById(id: string, update: Partial<S[T]>): Promise<number> {
|
|
67
|
-
return this.update(update).where({
|
|
68
|
-
_id: id,
|
|
69
|
-
} as Condition<S[T]>)
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* 根据ID删除文档
|
|
74
|
-
*/
|
|
75
|
-
async deleteById(id: string): Promise<S[T][] | number> {
|
|
76
|
-
return this.delete({
|
|
77
|
-
_id: id,
|
|
78
|
-
} as Condition<S[T]>) as Promise<S[T][] | number>;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* 生成文档ID
|
|
83
|
-
*/
|
|
84
|
-
private generateId(): string {
|
|
85
|
-
return randomUUID();
|
|
86
|
-
}
|
|
87
|
-
}
|
|
@@ -1,262 +0,0 @@
|
|
|
1
|
-
import { Database, Dialect } from '../../base/index.js';
|
|
2
|
-
import { KeyValueModel } from './model.js';
|
|
3
|
-
import {
|
|
4
|
-
QueryParams,
|
|
5
|
-
BuildQueryResult,
|
|
6
|
-
KeyValueQueryResult,
|
|
7
|
-
KeyValueOperationResult,
|
|
8
|
-
CreateQueryParams,
|
|
9
|
-
SelectQueryParams,
|
|
10
|
-
InsertQueryParams,
|
|
11
|
-
UpdateQueryParams,
|
|
12
|
-
DeleteQueryParams,
|
|
13
|
-
AlterQueryParams,
|
|
14
|
-
DropTableQueryParams,
|
|
15
|
-
DropIndexQueryParams
|
|
16
|
-
} from '../../types.js';
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* 键值数据库类
|
|
20
|
-
* 支持简单的键值对存储
|
|
21
|
-
*/
|
|
22
|
-
export class KeyValueDatabase<
|
|
23
|
-
D=any,
|
|
24
|
-
S extends Record<string, object> = Record<string, object>
|
|
25
|
-
> extends Database<D, S, KeyValueQueryResult> {
|
|
26
|
-
|
|
27
|
-
constructor(
|
|
28
|
-
dialect: Dialect<D, S, KeyValueQueryResult>,
|
|
29
|
-
definitions?: Database.DefinitionObj<S>,
|
|
30
|
-
) {
|
|
31
|
-
super(dialect, definitions);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
protected async initialize(): Promise<void> {
|
|
35
|
-
for (const tableName of this.definitions.keys()) {
|
|
36
|
-
this.models.set(tableName, new KeyValueModel(this, tableName));
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* 构建查询(重写基类方法)
|
|
42
|
-
*/
|
|
43
|
-
buildQuery<T extends keyof S>(params: QueryParams<S, T>): BuildQueryResult<KeyValueQueryResult> {
|
|
44
|
-
switch (params.type) {
|
|
45
|
-
case 'create':
|
|
46
|
-
return this.buildCreateQuery(params as CreateQueryParams<S, T>);
|
|
47
|
-
case 'select':
|
|
48
|
-
return this.buildSelectQuery(params as SelectQueryParams<S, T>);
|
|
49
|
-
case 'insert':
|
|
50
|
-
return this.buildInsertQuery(params as InsertQueryParams<S, T>);
|
|
51
|
-
case 'update':
|
|
52
|
-
return this.buildUpdateQuery(params as UpdateQueryParams<S, T>);
|
|
53
|
-
case 'delete':
|
|
54
|
-
return this.buildDeleteQuery(params as DeleteQueryParams<S, T>);
|
|
55
|
-
case 'alter':
|
|
56
|
-
return this.buildAlterQuery(params as AlterQueryParams<S, T>);
|
|
57
|
-
case 'drop_table':
|
|
58
|
-
return this.buildDropTableQuery(params as DropTableQueryParams<S, T>);
|
|
59
|
-
case 'drop_index':
|
|
60
|
-
return this.buildDropIndexQuery(params as DropIndexQueryParams<S, T>);
|
|
61
|
-
default:
|
|
62
|
-
throw new Error(`Unsupported query type: ${(params as any).type}`);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* 构建创建桶查询
|
|
68
|
-
*/
|
|
69
|
-
protected buildCreateQuery<T extends keyof S>(params: CreateQueryParams<S, T>): BuildQueryResult<KeyValueQueryResult> {
|
|
70
|
-
return {
|
|
71
|
-
query: {
|
|
72
|
-
bucket: params.tableName as string,
|
|
73
|
-
operation: 'keys'
|
|
74
|
-
},
|
|
75
|
-
params: []
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* 构建查询键值查询
|
|
81
|
-
*/
|
|
82
|
-
protected buildSelectQuery<T extends keyof S>(params: SelectQueryParams<S, T>): BuildQueryResult<KeyValueQueryResult> {
|
|
83
|
-
// 键值数据库的查询通常是获取所有键或特定键
|
|
84
|
-
const query: KeyValueQueryResult = {
|
|
85
|
-
bucket: params.tableName as string,
|
|
86
|
-
operation: 'keys'
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
// 如果有条件,尝试提取键名
|
|
90
|
-
if (params.conditions) {
|
|
91
|
-
const key = this.extractKeyFromCondition(params.conditions);
|
|
92
|
-
if (key) {
|
|
93
|
-
query.operation = 'get';
|
|
94
|
-
query.key = key;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return {
|
|
99
|
-
query,
|
|
100
|
-
params: []
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* 构建插入键值查询
|
|
106
|
-
*/
|
|
107
|
-
protected buildInsertQuery<T extends keyof S>(params: InsertQueryParams<S, T>): BuildQueryResult<KeyValueQueryResult> {
|
|
108
|
-
const key = this.extractKeyFromData(params.data);
|
|
109
|
-
|
|
110
|
-
return {
|
|
111
|
-
query: {
|
|
112
|
-
bucket: params.tableName as string,
|
|
113
|
-
operation: 'set',
|
|
114
|
-
key: key || 'default',
|
|
115
|
-
value: params.data
|
|
116
|
-
},
|
|
117
|
-
params: [params.data]
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* 构建更新键值查询
|
|
123
|
-
*/
|
|
124
|
-
protected buildUpdateQuery<T extends keyof S>(params: UpdateQueryParams<S, T>): BuildQueryResult<KeyValueQueryResult> {
|
|
125
|
-
const key = this.extractKeyFromCondition(params.conditions);
|
|
126
|
-
|
|
127
|
-
return {
|
|
128
|
-
query: {
|
|
129
|
-
bucket: params.tableName as string,
|
|
130
|
-
operation: 'set',
|
|
131
|
-
key: key || 'default',
|
|
132
|
-
value: params.update
|
|
133
|
-
},
|
|
134
|
-
params: [params.update]
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* 构建删除键值查询
|
|
140
|
-
*/
|
|
141
|
-
protected buildDeleteQuery<T extends keyof S>(params: DeleteQueryParams<S, T>): BuildQueryResult<KeyValueQueryResult> {
|
|
142
|
-
const key = this.extractKeyFromCondition(params.conditions);
|
|
143
|
-
|
|
144
|
-
return {
|
|
145
|
-
query: {
|
|
146
|
-
bucket: params.tableName as string,
|
|
147
|
-
operation: 'delete',
|
|
148
|
-
key: key || 'default'
|
|
149
|
-
},
|
|
150
|
-
params: []
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* 构建修改桶查询
|
|
156
|
-
*/
|
|
157
|
-
protected buildAlterQuery<T extends keyof S>(params: AlterQueryParams<S, T>): BuildQueryResult<KeyValueQueryResult> {
|
|
158
|
-
return {
|
|
159
|
-
query: {
|
|
160
|
-
bucket: params.tableName as string,
|
|
161
|
-
operation: 'keys'
|
|
162
|
-
},
|
|
163
|
-
params: [params.alterations]
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* 构建删除桶查询
|
|
169
|
-
*/
|
|
170
|
-
protected buildDropTableQuery<T extends keyof S>(params: DropTableQueryParams<S, T>): BuildQueryResult<KeyValueQueryResult> {
|
|
171
|
-
return {
|
|
172
|
-
query: {
|
|
173
|
-
bucket: params.tableName as string,
|
|
174
|
-
operation: 'clear'
|
|
175
|
-
},
|
|
176
|
-
params: []
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* 构建删除索引查询
|
|
182
|
-
*/
|
|
183
|
-
protected buildDropIndexQuery<T extends keyof S>(params: DropIndexQueryParams<S, T>): BuildQueryResult<KeyValueQueryResult> {
|
|
184
|
-
return {
|
|
185
|
-
query: {
|
|
186
|
-
bucket: params.tableName as string,
|
|
187
|
-
operation: 'keys'
|
|
188
|
-
},
|
|
189
|
-
params: [params.indexName]
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* 从条件中提取键名
|
|
195
|
-
*/
|
|
196
|
-
private extractKeyFromCondition(condition: any): string | null {
|
|
197
|
-
if (typeof condition !== 'object' || condition === null) {
|
|
198
|
-
return null;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
// 查找 key 字段
|
|
202
|
-
if ('key' in condition) {
|
|
203
|
-
return condition.key;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// 查找 id 字段
|
|
207
|
-
if ('id' in condition) {
|
|
208
|
-
return condition.id;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
// 递归查找
|
|
212
|
-
for (const value of Object.values(condition)) {
|
|
213
|
-
if (typeof value === 'object' && value !== null) {
|
|
214
|
-
const result = this.extractKeyFromCondition(value);
|
|
215
|
-
if (result) return result;
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
return null;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* 从数据中提取键名
|
|
224
|
-
*/
|
|
225
|
-
private extractKeyFromData(data: any): string | null {
|
|
226
|
-
if (typeof data !== 'object' || data === null) {
|
|
227
|
-
return null;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
// 查找 key 字段
|
|
231
|
-
if ('key' in data) {
|
|
232
|
-
return data.key;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
// 查找 id 字段
|
|
236
|
-
if ('id' in data) {
|
|
237
|
-
return data.id;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
return null;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
/**
|
|
244
|
-
* 获取模型
|
|
245
|
-
*/
|
|
246
|
-
model<T extends keyof S>(name: T): KeyValueModel<D, S, T> {
|
|
247
|
-
let model = this.models.get(name) as KeyValueModel<D, S, T> | undefined;
|
|
248
|
-
if (!model) {
|
|
249
|
-
model = new KeyValueModel<D, S, T>(this, name);
|
|
250
|
-
this.models.set(name, model as any);
|
|
251
|
-
}
|
|
252
|
-
return model as KeyValueModel<D, S, T>;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* 获取所有模型名称
|
|
257
|
-
*/
|
|
258
|
-
getModelNames(): string[] {
|
|
259
|
-
return Object.keys(this.definitions || {});
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|