@ocap/indexdb-memory 1.6.5 → 1.6.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.
- package/README.md +1 -1
- package/lib/db/base.js +476 -0
- package/lib/db/index.js +33 -0
- package/lib/table/transaction.js +2 -2
- package/package.json +12 -10
- package/lib/db.js +0 -160
package/README.md
CHANGED
package/lib/db/base.js
ADDED
@@ -0,0 +1,476 @@
|
|
1
|
+
/* eslint-disable newline-per-chained-call */
|
2
|
+
const { BN } = require('@ocap/util');
|
3
|
+
const { BaseIndexDB } = require('@ocap/indexdb');
|
4
|
+
const { formatPagination, formatNextPagination } = require('@ocap/indexdb/lib/util');
|
5
|
+
const { parseDateTime } = require('@ocap/indexdb/lib/util');
|
6
|
+
const { DEFAULT_TOKEN_DECIMAL } = require('@ocap/util/lib/constant');
|
7
|
+
const { toChecksumAddress } = require('@arcblock/did/lib/type');
|
8
|
+
|
9
|
+
const debug = require('debug')(require('../../package.json').name);
|
10
|
+
|
11
|
+
const MAX_REQUEST_FACTORY_ADDRESS_SIZE = 100;
|
12
|
+
|
13
|
+
class LocalBaseIndexDB extends BaseIndexDB {
|
14
|
+
listTransactions({
|
15
|
+
addressFilter = {},
|
16
|
+
paging = {},
|
17
|
+
timeFilter = {},
|
18
|
+
typeFilter = {},
|
19
|
+
assetFilter = {},
|
20
|
+
factoryFilter = {},
|
21
|
+
tokenFilter = {},
|
22
|
+
accountFilter = {},
|
23
|
+
validityFilter = {},
|
24
|
+
txFilter = {},
|
25
|
+
rollupFilter = {},
|
26
|
+
} = {}) {
|
27
|
+
const query = this.tx.collection.chain();
|
28
|
+
|
29
|
+
const { sender, receiver, direction = 'UNION' } = addressFilter;
|
30
|
+
const { types = [] } = typeFilter;
|
31
|
+
const { factories = [] } = factoryFilter;
|
32
|
+
const { assets = [] } = assetFilter;
|
33
|
+
const { tokens = [] } = tokenFilter;
|
34
|
+
const { accounts = [] } = accountFilter;
|
35
|
+
const { txs = [] } = txFilter;
|
36
|
+
const { rollups = [] } = rollupFilter;
|
37
|
+
let { startDateTime, endDateTime } = timeFilter;
|
38
|
+
startDateTime = parseDateTime(startDateTime);
|
39
|
+
endDateTime = parseDateTime(endDateTime);
|
40
|
+
|
41
|
+
const pagination = formatPagination({ paging, defaultSortField: 'time' });
|
42
|
+
debug('listTransactions', { sender, receiver, pagination, types, factories, assets, tokens, accounts, rollups });
|
43
|
+
|
44
|
+
if (sender && receiver) {
|
45
|
+
if (direction === 'MUTUAL') {
|
46
|
+
// 两人之间的所有往来
|
47
|
+
query.where((x) => {
|
48
|
+
if (x.sender === sender && x.receiver === receiver) {
|
49
|
+
return true;
|
50
|
+
}
|
51
|
+
if (x.sender === receiver && x.receiver === sender) {
|
52
|
+
return true;
|
53
|
+
}
|
54
|
+
|
55
|
+
return false;
|
56
|
+
});
|
57
|
+
} else if (direction === 'ONE_WAY') {
|
58
|
+
// 两人之间的单向交易
|
59
|
+
query.where((x) => x.sender === sender && x.receiver === receiver);
|
60
|
+
} else if (direction === 'UNION') {
|
61
|
+
// 查询某个人收发的交易
|
62
|
+
query.where((x) => x.sender === sender || x.receiver === receiver);
|
63
|
+
}
|
64
|
+
} else if (sender) {
|
65
|
+
// 某个人发的交易
|
66
|
+
query.where((x) => x.sender === sender);
|
67
|
+
} else if (receiver) {
|
68
|
+
// 某个人收的交易
|
69
|
+
query.where((x) => x.receiver === receiver);
|
70
|
+
}
|
71
|
+
|
72
|
+
if (types.length) {
|
73
|
+
query.where((x) => types.includes(x.type));
|
74
|
+
}
|
75
|
+
|
76
|
+
if (factories.length) {
|
77
|
+
query.where((x) => x.factories.some((f) => factories.includes(f)));
|
78
|
+
}
|
79
|
+
|
80
|
+
if (assets.length) {
|
81
|
+
query.where((x) => x.assets.some((f) => assets.includes(f)));
|
82
|
+
}
|
83
|
+
|
84
|
+
if (tokens.length) {
|
85
|
+
query.where((x) => x.tokens.some((f) => tokens.includes(f)));
|
86
|
+
}
|
87
|
+
|
88
|
+
if (accounts.length) {
|
89
|
+
query.where((x) => x.accounts.some((f) => accounts.includes(f)));
|
90
|
+
}
|
91
|
+
|
92
|
+
if (startDateTime && endDateTime) {
|
93
|
+
query.where((x) => x.time > startDateTime && x.time <= endDateTime);
|
94
|
+
} else if (startDateTime) {
|
95
|
+
query.where((x) => x.time > startDateTime);
|
96
|
+
} else if (endDateTime) {
|
97
|
+
query.where((x) => x.time <= endDateTime);
|
98
|
+
}
|
99
|
+
|
100
|
+
if (validityFilter.validity && validityFilter.validity === 'VALID') {
|
101
|
+
query.where((x) => x.valid === true);
|
102
|
+
}
|
103
|
+
if (validityFilter.validity && validityFilter.validity === 'INVALID') {
|
104
|
+
query.where((x) => x.valid === false);
|
105
|
+
}
|
106
|
+
|
107
|
+
if (txs.length) {
|
108
|
+
query.where((x) => txs.includes(x.hash));
|
109
|
+
}
|
110
|
+
|
111
|
+
if (rollups.length) {
|
112
|
+
query.where((x) => x.rollups.some((f) => rollups.includes(f)));
|
113
|
+
}
|
114
|
+
|
115
|
+
const transactions = query
|
116
|
+
.simplesort(pagination.order.field, paging.order.type === 'desc')
|
117
|
+
.offset(pagination.cursor)
|
118
|
+
.limit(pagination.size)
|
119
|
+
.data();
|
120
|
+
|
121
|
+
const total = query.count();
|
122
|
+
const nextPaging = {
|
123
|
+
cursor: pagination.cursor + transactions.length,
|
124
|
+
next: transactions.length >= pagination.size,
|
125
|
+
total,
|
126
|
+
};
|
127
|
+
|
128
|
+
return { transactions, paging: nextPaging };
|
129
|
+
}
|
130
|
+
|
131
|
+
async listAssets({ ownerAddress, factoryAddress, paging, timeFilter = {} } = {}) {
|
132
|
+
if (!ownerAddress && !factoryAddress) {
|
133
|
+
return { assets: [], account: null };
|
134
|
+
}
|
135
|
+
|
136
|
+
const pagination = formatPagination({ paging, defaultSortField: 'renaissanceTime' });
|
137
|
+
|
138
|
+
// eslint-disable-next-line prefer-const
|
139
|
+
let { startDateTime, endDateTime, field = 'renaissanceTime' } = timeFilter;
|
140
|
+
startDateTime = parseDateTime(startDateTime);
|
141
|
+
endDateTime = parseDateTime(endDateTime);
|
142
|
+
|
143
|
+
if (['genesisTime', 'renaissanceTime', 'consumedTime'].includes(field) === false) {
|
144
|
+
throw new Error('invalid field specified in timeFilter');
|
145
|
+
}
|
146
|
+
|
147
|
+
const query = this.asset.collection.chain();
|
148
|
+
if (ownerAddress) {
|
149
|
+
query.where((x) => x.owner === ownerAddress);
|
150
|
+
}
|
151
|
+
if (factoryAddress) {
|
152
|
+
query.where((x) => x.parent === factoryAddress);
|
153
|
+
}
|
154
|
+
if (startDateTime && endDateTime) {
|
155
|
+
query.where((x) => x[field] > startDateTime && x[field] <= endDateTime);
|
156
|
+
} else if (startDateTime) {
|
157
|
+
query.where((x) => x[field] > startDateTime);
|
158
|
+
} else if (endDateTime) {
|
159
|
+
query.where((x) => x[field] <= endDateTime);
|
160
|
+
}
|
161
|
+
|
162
|
+
debug('listAssets', { ownerAddress, factoryAddress, timeFilter, paging, pagination });
|
163
|
+
|
164
|
+
const assets = await query
|
165
|
+
.simplesort(pagination.order.field, pagination.order.type === 'desc')
|
166
|
+
.offset(pagination.cursor)
|
167
|
+
.limit(pagination.size)
|
168
|
+
.data();
|
169
|
+
|
170
|
+
const total = query.count();
|
171
|
+
|
172
|
+
const account = ownerAddress ? await this.account.get(ownerAddress) : null;
|
173
|
+
return { assets, account, paging: formatNextPagination(total, pagination) };
|
174
|
+
}
|
175
|
+
|
176
|
+
async listTopAccounts({ paging, tokenAddress } = {}) {
|
177
|
+
const query = this.account.collection.chain();
|
178
|
+
const pagination = formatPagination({
|
179
|
+
paging,
|
180
|
+
defaultSortField: 'balance',
|
181
|
+
supportedSortFields: ['genesisTime', 'renaissanceTime', 'balance', 'moniker'],
|
182
|
+
});
|
183
|
+
debug('listTopAccounts', { tokenAddress, paging, pagination });
|
184
|
+
|
185
|
+
query.where((x) => {
|
186
|
+
const owned = x.tokens.find((t) => t.address === tokenAddress);
|
187
|
+
return owned ? owned.balance > '0' : false;
|
188
|
+
});
|
189
|
+
|
190
|
+
if (pagination.order.field === 'balance') {
|
191
|
+
const descending = pagination.order.type === 'desc';
|
192
|
+
query.sort((a, b) => {
|
193
|
+
const tokenA = a.tokens.find((x) => x.address === tokenAddress);
|
194
|
+
const tokenB = b.tokens.find((x) => x.address === tokenAddress);
|
195
|
+
const balanceA = new BN(tokenA ? tokenA.balance : '0');
|
196
|
+
const balanceB = new BN(tokenB ? tokenB.balance : '0');
|
197
|
+
|
198
|
+
if (balanceB.gt(balanceA)) {
|
199
|
+
return descending ? 1 : -1;
|
200
|
+
}
|
201
|
+
|
202
|
+
if (balanceB.eq(balanceA)) {
|
203
|
+
return 0;
|
204
|
+
}
|
205
|
+
|
206
|
+
return descending ? -1 : 1;
|
207
|
+
});
|
208
|
+
} else {
|
209
|
+
query.simplesort(pagination.order.field, pagination.order.type);
|
210
|
+
}
|
211
|
+
|
212
|
+
const accounts = query.offset(pagination.cursor).limit(pagination.size).data();
|
213
|
+
const total = query.count();
|
214
|
+
|
215
|
+
accounts.forEach((account) => {
|
216
|
+
if (Array.isArray(account.tokens) && account.tokens.length) {
|
217
|
+
account.tokens = account.tokens.map((token) => {
|
218
|
+
token.decimal = typeof token.decimal === 'undefined' ? DEFAULT_TOKEN_DECIMAL : token.decimal;
|
219
|
+
return token;
|
220
|
+
});
|
221
|
+
}
|
222
|
+
});
|
223
|
+
|
224
|
+
return { accounts, paging: formatNextPagination(total, pagination) };
|
225
|
+
}
|
226
|
+
|
227
|
+
async listTokens({ issuerAddress, paging } = {}) {
|
228
|
+
const conditions = {};
|
229
|
+
if (issuerAddress) {
|
230
|
+
conditions.issuer = issuerAddress;
|
231
|
+
}
|
232
|
+
|
233
|
+
const pagination = formatPagination({
|
234
|
+
paging,
|
235
|
+
defaultSortField: 'renaissanceTime',
|
236
|
+
supportedSortFields: ['genesisTime', 'renaissanceTime', 'issuer', 'symbol', 'totalSupply'],
|
237
|
+
});
|
238
|
+
|
239
|
+
debug('listTokens', { issuerAddress, paging, conditions, pagination });
|
240
|
+
|
241
|
+
let tokens = this.token.collection
|
242
|
+
.chain()
|
243
|
+
.find(conditions)
|
244
|
+
.simplesort(pagination.order.field, pagination.order.type === 'desc')
|
245
|
+
.offset(pagination.cursor)
|
246
|
+
.limit(pagination.size)
|
247
|
+
.data();
|
248
|
+
|
249
|
+
tokens = tokens.map((token) => {
|
250
|
+
token.decimal = typeof token.decimal === 'undefined' ? DEFAULT_TOKEN_DECIMAL : token.decimal;
|
251
|
+
return token;
|
252
|
+
});
|
253
|
+
|
254
|
+
const total = this.token.count(Object.keys(conditions).length ? conditions : undefined);
|
255
|
+
|
256
|
+
return { tokens, paging: formatNextPagination(total, pagination) };
|
257
|
+
}
|
258
|
+
|
259
|
+
async listFactories({ ownerAddress, addressList, paging } = {}) {
|
260
|
+
const conditions = {};
|
261
|
+
if (ownerAddress) {
|
262
|
+
conditions.owner = ownerAddress;
|
263
|
+
}
|
264
|
+
|
265
|
+
if (Array.isArray(addressList) && addressList.length > 0) {
|
266
|
+
if (addressList.length > MAX_REQUEST_FACTORY_ADDRESS_SIZE) {
|
267
|
+
throw new Error(`The length of 'addressList' cannot exceed the length of ${MAX_REQUEST_FACTORY_ADDRESS_SIZE}`);
|
268
|
+
}
|
269
|
+
conditions.address = { $in: addressList };
|
270
|
+
}
|
271
|
+
|
272
|
+
const pagination = formatPagination({
|
273
|
+
paging,
|
274
|
+
defaultSortField: 'renaissanceTime',
|
275
|
+
supportedSortFields: ['genesisTime', 'renaissanceTime', 'owner', 'numMinted', 'limit', 'name'],
|
276
|
+
});
|
277
|
+
debug('listFactories', { ownerAddress, paging, conditions, pagination });
|
278
|
+
|
279
|
+
const factories = await this.factory.collection
|
280
|
+
.chain()
|
281
|
+
.find(conditions)
|
282
|
+
.simplesort(pagination.order.field, pagination.order.type === 'desc')
|
283
|
+
.offset(pagination.cursor)
|
284
|
+
.limit(pagination.size)
|
285
|
+
.data();
|
286
|
+
|
287
|
+
const total = this.factory.count(Object.keys(conditions).length ? conditions : undefined);
|
288
|
+
|
289
|
+
return { factories, paging: formatNextPagination(total, pagination) };
|
290
|
+
}
|
291
|
+
|
292
|
+
listStakes({ addressFilter = {}, paging = {}, timeFilter = {}, assetFilter = {} } = {}) {
|
293
|
+
const query = this.stake.collection.chain();
|
294
|
+
|
295
|
+
const { sender, receiver } = addressFilter;
|
296
|
+
const { assets = [] } = assetFilter;
|
297
|
+
let { startDateTime, endDateTime, field } = timeFilter;
|
298
|
+
startDateTime = parseDateTime(startDateTime);
|
299
|
+
endDateTime = parseDateTime(endDateTime);
|
300
|
+
field = ['genesisTime', 'renaissanceTime'].includes(field) ? field : 'renaissanceTime';
|
301
|
+
|
302
|
+
const pagination = formatPagination({
|
303
|
+
paging,
|
304
|
+
defaultSortField: 'renaissanceTime',
|
305
|
+
supportedSortFields: ['genesisTime', 'renaissanceTime'],
|
306
|
+
});
|
307
|
+
|
308
|
+
if (sender && receiver) {
|
309
|
+
query.where((x) => x.sender === sender && x.receiver === receiver);
|
310
|
+
} else if (sender) {
|
311
|
+
query.where((x) => x.sender === sender);
|
312
|
+
} else if (receiver) {
|
313
|
+
query.where((x) => x.receiver === receiver);
|
314
|
+
}
|
315
|
+
|
316
|
+
if (assets.length) {
|
317
|
+
query.where((x) => x.assets.some((f) => assets.includes(f)));
|
318
|
+
}
|
319
|
+
|
320
|
+
if (startDateTime && endDateTime) {
|
321
|
+
query.where((x) => x[field] > startDateTime && x[field] <= endDateTime);
|
322
|
+
} else if (startDateTime) {
|
323
|
+
query.where((x) => x[field] > startDateTime);
|
324
|
+
} else if (endDateTime) {
|
325
|
+
query.where((x) => x[field] <= endDateTime);
|
326
|
+
}
|
327
|
+
|
328
|
+
const stakes = query
|
329
|
+
.simplesort(pagination.order.field, paging.order.type === 'desc')
|
330
|
+
.offset(pagination.cursor)
|
331
|
+
.limit(pagination.size)
|
332
|
+
.data();
|
333
|
+
|
334
|
+
const total = query.count();
|
335
|
+
const nextPaging = {
|
336
|
+
cursor: pagination.cursor + stakes.length,
|
337
|
+
next: stakes.length >= pagination.size,
|
338
|
+
total,
|
339
|
+
};
|
340
|
+
|
341
|
+
return { stakes, paging: nextPaging };
|
342
|
+
}
|
343
|
+
|
344
|
+
async listRollups({ paging, tokenAddress = '', erc20TokenAddress = '', foreignTokenAddress = '' } = {}) {
|
345
|
+
const pagination = formatPagination({
|
346
|
+
paging,
|
347
|
+
defaultSortField: 'renaissanceTime',
|
348
|
+
supportedSortFields: ['genesisTime', 'renaissanceTime'],
|
349
|
+
});
|
350
|
+
|
351
|
+
const query = this.rollup.collection.chain();
|
352
|
+
if (tokenAddress) {
|
353
|
+
query.where((x) => x.tokenAddress === tokenAddress);
|
354
|
+
}
|
355
|
+
|
356
|
+
const foreignTokenAddr = foreignTokenAddress || erc20TokenAddress;
|
357
|
+
if (erc20TokenAddress) {
|
358
|
+
query.where((x) => x.foreignToken.contractAddress === toChecksumAddress(foreignTokenAddr));
|
359
|
+
}
|
360
|
+
|
361
|
+
debug('listRollups', { paging, pagination });
|
362
|
+
|
363
|
+
const rollups = query
|
364
|
+
.simplesort(pagination.order.field, pagination.order.type === 'desc')
|
365
|
+
.offset(pagination.cursor)
|
366
|
+
.limit(pagination.size)
|
367
|
+
.data();
|
368
|
+
|
369
|
+
const total = query.count();
|
370
|
+
|
371
|
+
return { rollups, paging: formatNextPagination(total, pagination) };
|
372
|
+
}
|
373
|
+
|
374
|
+
listRollupBlocks({
|
375
|
+
paging = {},
|
376
|
+
rollupAddress = '',
|
377
|
+
tokenAddress = '',
|
378
|
+
proposer = '',
|
379
|
+
height = '',
|
380
|
+
timeFilter = {},
|
381
|
+
txFilter = {},
|
382
|
+
validatorFilter = {},
|
383
|
+
} = {}) {
|
384
|
+
const query = this.rollupBlock.collection.chain();
|
385
|
+
|
386
|
+
const { txs = [] } = txFilter;
|
387
|
+
const { validators = [] } = validatorFilter;
|
388
|
+
let { startDateTime, endDateTime, field = 'genesisTime' } = timeFilter; // eslint-disable-line
|
389
|
+
startDateTime = parseDateTime(startDateTime);
|
390
|
+
endDateTime = parseDateTime(endDateTime);
|
391
|
+
|
392
|
+
const pagination = formatPagination({
|
393
|
+
paging,
|
394
|
+
defaultSortField: 'genesisTime',
|
395
|
+
supportedSortFields: ['genesisTime', 'renaissanceTime'],
|
396
|
+
});
|
397
|
+
|
398
|
+
if (rollupAddress) {
|
399
|
+
query.where((x) => x.rollup === rollupAddress);
|
400
|
+
}
|
401
|
+
|
402
|
+
if (Number(height) > 0) {
|
403
|
+
query.where((x) => Number(x.height) === Number(height));
|
404
|
+
}
|
405
|
+
|
406
|
+
if (proposer) {
|
407
|
+
query.where((x) => x.proposer === proposer);
|
408
|
+
}
|
409
|
+
|
410
|
+
if (tokenAddress) {
|
411
|
+
query.where((x) => x.tokenInfo.address === tokenAddress);
|
412
|
+
}
|
413
|
+
|
414
|
+
if (txs.length) {
|
415
|
+
query.where((x) => x.txs.some((f) => txs.includes(f)));
|
416
|
+
}
|
417
|
+
|
418
|
+
if (validators.length) {
|
419
|
+
query.where((x) => x.validators.some((f) => validators.includes(f)));
|
420
|
+
}
|
421
|
+
|
422
|
+
if (startDateTime && endDateTime) {
|
423
|
+
query.where((x) => x[field] > startDateTime && x[field] <= endDateTime);
|
424
|
+
} else if (startDateTime) {
|
425
|
+
query.where((x) => x[field] > startDateTime);
|
426
|
+
} else if (endDateTime) {
|
427
|
+
query.where((x) => x[field] <= endDateTime);
|
428
|
+
}
|
429
|
+
|
430
|
+
const blocks = query
|
431
|
+
.simplesort(pagination.order.field, paging.order.type === 'desc')
|
432
|
+
.offset(pagination.cursor)
|
433
|
+
.limit(pagination.size)
|
434
|
+
.data();
|
435
|
+
|
436
|
+
const total = query.count();
|
437
|
+
const nextPaging = {
|
438
|
+
cursor: pagination.cursor + blocks.length,
|
439
|
+
next: blocks.length >= pagination.size,
|
440
|
+
total,
|
441
|
+
};
|
442
|
+
|
443
|
+
return { blocks, paging: nextPaging };
|
444
|
+
}
|
445
|
+
|
446
|
+
listRollupValidators({ paging = {}, rollupAddress = '' } = {}) {
|
447
|
+
const query = this.rollupValidator.collection.chain();
|
448
|
+
|
449
|
+
const pagination = formatPagination({
|
450
|
+
paging,
|
451
|
+
defaultSortField: 'genesisTime',
|
452
|
+
supportedSortFields: ['joinTime', 'leaveTime', 'genesisTime', 'renaissanceTime'],
|
453
|
+
});
|
454
|
+
|
455
|
+
if (rollupAddress) {
|
456
|
+
query.where((x) => x.rollup === rollupAddress);
|
457
|
+
}
|
458
|
+
|
459
|
+
const validators = query
|
460
|
+
.simplesort(pagination.order.field, paging.order.type === 'desc')
|
461
|
+
.offset(pagination.cursor)
|
462
|
+
.limit(pagination.size)
|
463
|
+
.data();
|
464
|
+
|
465
|
+
const total = query.count();
|
466
|
+
const nextPaging = {
|
467
|
+
cursor: pagination.cursor + validators.length,
|
468
|
+
next: validators.length >= pagination.size,
|
469
|
+
total,
|
470
|
+
};
|
471
|
+
|
472
|
+
return { validators, paging: nextPaging };
|
473
|
+
}
|
474
|
+
}
|
475
|
+
|
476
|
+
module.exports = LocalBaseIndexDB;
|
package/lib/db/index.js
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
/* eslint-disable newline-per-chained-call */
|
2
|
+
const md5 = require('@ocap/util/lib/md5');
|
3
|
+
const BaseIndexDB = require('./base');
|
4
|
+
|
5
|
+
const Table = require('../table/base');
|
6
|
+
const Transaction = require('../table/transaction');
|
7
|
+
const { name, version } = require('../../package.json');
|
8
|
+
|
9
|
+
class MemoryIndexDB extends BaseIndexDB {
|
10
|
+
constructor() {
|
11
|
+
super();
|
12
|
+
|
13
|
+
this.name = name;
|
14
|
+
this.version = version;
|
15
|
+
|
16
|
+
this.md5 = md5;
|
17
|
+
|
18
|
+
this.account = new Table('account', 'address');
|
19
|
+
this.asset = new Table('asset', 'address');
|
20
|
+
this.delegation = new Table('delegation', 'address');
|
21
|
+
this.tx = new Transaction('tx', 'hash');
|
22
|
+
this.factory = new Table('factory', 'address');
|
23
|
+
this.token = new Table('token', 'address');
|
24
|
+
this.stake = new Table('stake', 'address');
|
25
|
+
this.rollup = new Table('rollup', 'address');
|
26
|
+
this.rollupBlock = new Table('rollupBlock', 'hash');
|
27
|
+
this.rollupValidator = new Table('rollupValidator', 'address');
|
28
|
+
|
29
|
+
this.attachReadyListeners();
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
module.exports = MemoryIndexDB;
|
package/lib/table/transaction.js
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
/* eslint-disable no-underscore-dangle */
|
2
|
-
const {
|
2
|
+
const { formatTxBeforeInsert } = require('@ocap/indexdb/lib/util');
|
3
3
|
const Base = require('./base');
|
4
4
|
|
5
5
|
class Transaction extends Base {
|
6
6
|
_insert(row) {
|
7
|
-
return super._insert(
|
7
|
+
return super._insert(formatTxBeforeInsert(row));
|
8
8
|
}
|
9
9
|
}
|
10
10
|
|
package/package.json
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
{
|
2
2
|
"name": "@ocap/indexdb-memory",
|
3
3
|
"description": "OCAP indexdb adapter that uses memory as backend, just for test purpose",
|
4
|
-
"version": "1.6.
|
4
|
+
"version": "1.6.10",
|
5
5
|
"author": "wangshijun <shijun@arcblock.io> (https://www.arcblock.io)",
|
6
6
|
"bugs": {
|
7
|
-
"url": "https://github.com/ArcBlock/
|
7
|
+
"url": "https://github.com/ArcBlock/asset-chain/issues",
|
8
8
|
"email": "shijun@arcblock.io"
|
9
9
|
},
|
10
10
|
"publishConfig": {
|
@@ -14,9 +14,9 @@
|
|
14
14
|
"wangshijun <shijun@arcblock.io> (https://www.arcblock.io)"
|
15
15
|
],
|
16
16
|
"devDependencies": {
|
17
|
-
"jest": "^
|
17
|
+
"jest": "^27.3.1"
|
18
18
|
},
|
19
|
-
"homepage": "https://github.com/ArcBlock/
|
19
|
+
"homepage": "https://github.com/ArcBlock/asset-chain/tree/master/indexdb/memory",
|
20
20
|
"keywords": [
|
21
21
|
"ocap",
|
22
22
|
"indexdb",
|
@@ -29,19 +29,21 @@
|
|
29
29
|
],
|
30
30
|
"repository": {
|
31
31
|
"type": "git",
|
32
|
-
"url": "https://github.com/ArcBlock/
|
32
|
+
"url": "https://github.com/ArcBlock/asset-chain/tree/master/indexdb/memory"
|
33
33
|
},
|
34
34
|
"scripts": {
|
35
35
|
"lint": "eslint tests lib",
|
36
36
|
"lint:fix": "eslint --fix tests lib",
|
37
|
-
"test": "
|
37
|
+
"test": "jest --forceExit --detectOpenHandles",
|
38
38
|
"coverage": "npm run test -- --coverage"
|
39
39
|
},
|
40
|
-
"gitHead": "
|
40
|
+
"gitHead": "ab272e8db3a15c6571cc7fae7cc3d3e0fdd4bdb1",
|
41
41
|
"dependencies": {
|
42
|
-
"@
|
43
|
-
"@ocap/
|
44
|
-
"
|
42
|
+
"@arcblock/did": "1.6.10",
|
43
|
+
"@ocap/indexdb": "1.6.10",
|
44
|
+
"@ocap/util": "1.6.10",
|
45
|
+
"debug": "^4.3.3",
|
46
|
+
"empty-value": "^1.0.1",
|
45
47
|
"lodash": "^4.17.21",
|
46
48
|
"lokijs": "^1.5.11"
|
47
49
|
}
|
package/lib/db.js
DELETED
@@ -1,160 +0,0 @@
|
|
1
|
-
/* eslint-disable newline-per-chained-call */
|
2
|
-
const md5 = require('@ocap/util/lib/md5');
|
3
|
-
const { BaseIndexDB } = require('@ocap/indexdb');
|
4
|
-
const formatPagination = require('@ocap/util/lib/format-pagination');
|
5
|
-
|
6
|
-
const Table = require('./table/base');
|
7
|
-
const Transaction = require('./table/transaction');
|
8
|
-
const { name, version } = require('../package.json');
|
9
|
-
|
10
|
-
class MemoryIndexDB extends BaseIndexDB {
|
11
|
-
constructor() {
|
12
|
-
super();
|
13
|
-
|
14
|
-
this.name = name;
|
15
|
-
this.version = version;
|
16
|
-
|
17
|
-
this.md5 = md5;
|
18
|
-
|
19
|
-
this.account = new Table('account', 'address');
|
20
|
-
this.asset = new Table('asset', 'address');
|
21
|
-
this.delegation = new Table('delegation', 'address');
|
22
|
-
this.tx = new Transaction('tx', 'hash');
|
23
|
-
|
24
|
-
this.account.onReady(() => this.markReady('account'));
|
25
|
-
this.asset.onReady(() => this.markReady('asset'));
|
26
|
-
this.delegation.onReady(() => this.markReady('delegation'));
|
27
|
-
this.tx.onReady(() => this.markReady('tx'));
|
28
|
-
}
|
29
|
-
|
30
|
-
listTransactions({ addressFilter = {}, paging = {}, timeFilter = {}, typeFilter = {} } = {}) {
|
31
|
-
const query = this.tx.collection.chain();
|
32
|
-
|
33
|
-
const { sender, receiver, direction = 'UNION' } = addressFilter;
|
34
|
-
const { types = [] } = typeFilter;
|
35
|
-
const { startDateTime, endDateTime } = timeFilter;
|
36
|
-
const pagination = formatPagination({ paging, defaultSortField: 'time' });
|
37
|
-
|
38
|
-
if (sender && receiver) {
|
39
|
-
if (direction === 'MUTUAL') {
|
40
|
-
// 两人之间的所有往来
|
41
|
-
query.where((x) => {
|
42
|
-
if (x.sender === sender && x.receiver === receiver) {
|
43
|
-
return true;
|
44
|
-
}
|
45
|
-
if (x.sender === receiver && x.receiver === sender) {
|
46
|
-
return true;
|
47
|
-
}
|
48
|
-
|
49
|
-
return false;
|
50
|
-
});
|
51
|
-
} else if (direction === 'ONE_WAY') {
|
52
|
-
// 两人之间的单向交易
|
53
|
-
query.where((x) => x.sender === sender && x.receiver === receiver);
|
54
|
-
} else if (direction === 'UNION') {
|
55
|
-
// 查询某个人收发的交易
|
56
|
-
query.where((x) => x.sender === sender || x.receiver === receiver);
|
57
|
-
}
|
58
|
-
} else if (sender) {
|
59
|
-
// 某个人发的交易
|
60
|
-
query.where((x) => x.sender === sender);
|
61
|
-
} else if (receiver) {
|
62
|
-
// 某个人收的交易
|
63
|
-
query.where((x) => x.receiver === receiver);
|
64
|
-
}
|
65
|
-
|
66
|
-
if (types.length) {
|
67
|
-
query.where((x) => typeFilter.types.includes(x.type));
|
68
|
-
}
|
69
|
-
|
70
|
-
if (startDateTime && endDateTime) {
|
71
|
-
query.where((x) => x.time > startDateTime && x.time <= endDateTime);
|
72
|
-
} else if (startDateTime) {
|
73
|
-
query.where((x) => x.time > startDateTime);
|
74
|
-
} else if (endDateTime) {
|
75
|
-
query.where((x) => x.time <= endDateTime);
|
76
|
-
}
|
77
|
-
|
78
|
-
const result = query
|
79
|
-
.simplesort(pagination.order.field, paging.order.type === 'desc')
|
80
|
-
.offset(pagination.cursor)
|
81
|
-
.limit(pagination.size)
|
82
|
-
.data();
|
83
|
-
|
84
|
-
const total = query.count();
|
85
|
-
|
86
|
-
result.paging = { cursor: pagination.cursor + result.length, next: result.length >= pagination.size, total };
|
87
|
-
return result;
|
88
|
-
}
|
89
|
-
|
90
|
-
async listAssets({ ownerAddress, paging } = {}) {
|
91
|
-
if (!ownerAddress) {
|
92
|
-
return {};
|
93
|
-
}
|
94
|
-
|
95
|
-
const pagination = formatPagination({ paging, defaultSortField: 'renaissanceTime' });
|
96
|
-
|
97
|
-
const assets = await this.asset.collection
|
98
|
-
.chain()
|
99
|
-
.find({ owner: ownerAddress })
|
100
|
-
.simplesort(pagination.order.field, pagination.order.type === 'desc')
|
101
|
-
.offset(pagination.cursor)
|
102
|
-
.limit(pagination.size)
|
103
|
-
.data();
|
104
|
-
|
105
|
-
const total = await this.asset.count({ owner: ownerAddress });
|
106
|
-
const account = await this.account.get(ownerAddress);
|
107
|
-
|
108
|
-
return {
|
109
|
-
assets,
|
110
|
-
account,
|
111
|
-
paging: { cursor: pagination.cursor + assets.length, next: assets.length >= pagination.size, total },
|
112
|
-
};
|
113
|
-
}
|
114
|
-
|
115
|
-
async listAssetTransactions({ address, paging } = {}) {
|
116
|
-
if (!address) {
|
117
|
-
return [];
|
118
|
-
}
|
119
|
-
|
120
|
-
const pagination = formatPagination({ paging, defaultSortField: 'time' });
|
121
|
-
|
122
|
-
const queryCondition = { assets: { $contains: address } };
|
123
|
-
const txs = await this.tx.collection
|
124
|
-
.chain()
|
125
|
-
.find(queryCondition)
|
126
|
-
.simplesort(pagination.order.field, pagination.order.type === 'desc')
|
127
|
-
.offset(pagination.cursor)
|
128
|
-
.limit(pagination.size)
|
129
|
-
.data();
|
130
|
-
|
131
|
-
const total = await this.tx.collection.count(queryCondition);
|
132
|
-
|
133
|
-
txs.paging = { cursor: pagination.cursor + txs.length, next: txs.length >= pagination.size, total };
|
134
|
-
|
135
|
-
return txs;
|
136
|
-
}
|
137
|
-
|
138
|
-
listTopAccounts({ paging } = {}) {
|
139
|
-
const params = formatPagination({ paging, defaultSortField: 'balance' });
|
140
|
-
|
141
|
-
const accounts = this.account.collection
|
142
|
-
.chain()
|
143
|
-
.find()
|
144
|
-
.simplesort(params.order.field, params.order.type === 'desc')
|
145
|
-
.offset(params.cursor)
|
146
|
-
.limit(params.size)
|
147
|
-
.data();
|
148
|
-
|
149
|
-
const total = this.account.count();
|
150
|
-
|
151
|
-
accounts.paging = { cursor: params.cursor + accounts.length, next: accounts.length >= params.size, total };
|
152
|
-
return accounts;
|
153
|
-
}
|
154
|
-
|
155
|
-
listBlocks() {
|
156
|
-
return [];
|
157
|
-
}
|
158
|
-
}
|
159
|
-
|
160
|
-
module.exports = MemoryIndexDB;
|