be even more safe in db
This commit is contained in:
parent
89c3c2d58d
commit
700eb32f5a
@ -34,14 +34,23 @@ export class Store<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class Index<S,T> {
|
||||
indexName: string;
|
||||
storeName: string;
|
||||
|
||||
constructor(s: Store<T>, indexName: string) {
|
||||
this.storeName = s.name;
|
||||
this.indexName = indexName;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stream that can be filtered, reduced or joined
|
||||
* with indices.
|
||||
*/
|
||||
export interface QueryStream<T> {
|
||||
indexJoin<S>(storeName: string,
|
||||
indexName: string,
|
||||
keyFn: (obj: any) => any): QueryStream<[T, S]>;
|
||||
indexJoin<S,I>(index: Index<I,S>,
|
||||
keyFn: (obj: T) => I): QueryStream<[T, S]>;
|
||||
filter(f: (x: any) => boolean): QueryStream<T>;
|
||||
reduce<S>(f: (v: T, acc: S) => S, start?: S): Promise<S>;
|
||||
flatMap(f: (x: T) => T[]): QueryStream<T>;
|
||||
@ -83,11 +92,10 @@ abstract class QueryStreamBase<T> implements QueryStream<T> {
|
||||
return new QueryStreamFlatMap(this, f);
|
||||
}
|
||||
|
||||
indexJoin<S>(storeName: string,
|
||||
indexName: string,
|
||||
key: any): QueryStream<[T, S]> {
|
||||
this.root.addStoreAccess(storeName, false);
|
||||
return new QueryStreamIndexJoin(this, storeName, indexName, key);
|
||||
indexJoin<S,I>(index: Index<I,S>,
|
||||
keyFn: (obj: T) => I): QueryStream<[T, S]> {
|
||||
this.root.addStoreAccess(index.storeName, false);
|
||||
return new QueryStreamIndexJoin(this, index.storeName, index.indexName, keyFn);
|
||||
}
|
||||
|
||||
filter(f: (x: any) => boolean): QueryStream<T> {
|
||||
@ -191,7 +199,8 @@ class QueryStreamIndexJoin<T, S> extends QueryStreamBase<[T, S]> {
|
||||
key: any;
|
||||
indexName: string;
|
||||
|
||||
constructor(s: QueryStreamBase<T>, storeName: string, indexName: string, key: any) {
|
||||
constructor(s: QueryStreamBase<T>, storeName: string, indexName: string,
|
||||
key: any) {
|
||||
super(s.root);
|
||||
this.s = s;
|
||||
this.storeName = storeName;
|
||||
@ -287,10 +296,17 @@ export class QueryRoot {
|
||||
this.db = db;
|
||||
}
|
||||
|
||||
iter<T>(store: Store<T>,
|
||||
{only = <string | undefined>undefined, indexName = <string | undefined>undefined} = {}): QueryStream<T> {
|
||||
iter<T>(store: Store<T>): QueryStream<T> {
|
||||
this.stores.add(store.name);
|
||||
return new IterQueryStream(this, store.name, { only, indexName });
|
||||
return new IterQueryStream(this, store.name, {});
|
||||
}
|
||||
|
||||
iterIndex<S,T>(index: Index<S,T>, only?: S): QueryStream<T> {
|
||||
this.stores.add(index.storeName);
|
||||
return new IterQueryStream(this, index.storeName, {
|
||||
only,
|
||||
indexName: index.indexName
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -30,7 +30,7 @@ import {
|
||||
WireInfo, RefreshSession, ReserveRecord, CoinPaySig
|
||||
} from "./types";
|
||||
import {HttpResponse, RequestException} from "./http";
|
||||
import {QueryRoot, Store} from "./query";
|
||||
import {QueryRoot, Store, Index} from "./query";
|
||||
import {Checkable} from "./checkable";
|
||||
import {canonicalizeBaseUrl} from "./helpers";
|
||||
import {ReserveCreationInfo, Amounts} from "./types";
|
||||
@ -306,12 +306,36 @@ function getWithdrawDenomList(amountAvailable: AmountJson,
|
||||
|
||||
|
||||
namespace Stores {
|
||||
export let exchanges: Store<IExchangeInfo> = new Store<IExchangeInfo>("exchanges");
|
||||
class ExchangeStore extends Store<IExchangeInfo> {
|
||||
constructor() {
|
||||
super("exchanges");
|
||||
}
|
||||
pubKeyIndex = new Index<string,IExchangeInfo>(this, "pubKey");
|
||||
}
|
||||
|
||||
class CoinsStore extends Store<Coin> {
|
||||
constructor() {
|
||||
super("coins");
|
||||
}
|
||||
|
||||
exchangeBaseUrlIndex = new Index<string,Coin>(this, "exchangeBaseUrl");
|
||||
}
|
||||
|
||||
class HistoryStore extends Store<HistoryRecord> {
|
||||
constructor() {
|
||||
super("history");
|
||||
}
|
||||
|
||||
timestampIndex = new Index<number,HistoryRecord>(this, "timestamp");
|
||||
}
|
||||
|
||||
|
||||
export let exchanges: ExchangeStore = new ExchangeStore();
|
||||
export let transactions: Store<Transaction> = new Store<Transaction>("transactions");
|
||||
export let reserves: Store<ReserveRecord> = new Store<ReserveRecord>("reserves");
|
||||
export let coins: Store<Coin> = new Store<Coin>("coins");
|
||||
export let coins: CoinsStore = new CoinsStore();
|
||||
export let refresh: Store<RefreshSession> = new Store<RefreshSession>("refresh");
|
||||
export let history: Store<HistoryRecord> = new Store<HistoryRecord>("history");
|
||||
export let history: HistoryStore = new HistoryStore();
|
||||
export let precoins: Store<PreCoin> = new Store<PreCoin>("precoins");
|
||||
}
|
||||
|
||||
@ -463,9 +487,8 @@ export class Wallet {
|
||||
console.log("Checking for merchant's exchange", JSON.stringify(info));
|
||||
return [
|
||||
this.q()
|
||||
.iter(Stores.exchanges, {indexName: "pubKey", only: info.master_pub})
|
||||
.indexJoin("coins",
|
||||
"exchangeBaseUrl",
|
||||
.iterIndex(Stores.exchanges.pubKeyIndex, info.master_pub)
|
||||
.indexJoin(Stores.coins.exchangeBaseUrlIndex,
|
||||
(exchange) => exchange.baseUrl)
|
||||
.reduce((x) => storeExchangeCoin(x, info.url))
|
||||
];
|
||||
@ -997,8 +1020,7 @@ export class Wallet {
|
||||
private async suspendCoins(exchangeInfo: IExchangeInfo): Promise<void> {
|
||||
let suspendedCoins = await (
|
||||
this.q()
|
||||
.iter(Stores.coins,
|
||||
{indexName: "exchangeBaseUrl", only: exchangeInfo.baseUrl})
|
||||
.iterIndex(Stores.coins.exchangeBaseUrlIndex, exchangeInfo.baseUrl)
|
||||
.reduce((coin: Coin, suspendedCoins: Coin[]) => {
|
||||
if (!exchangeInfo.active_denoms.find((c) => c.denom_pub == coin.denomPub)) {
|
||||
return Array.prototype.concat(suspendedCoins, [coin]);
|
||||
@ -1375,7 +1397,7 @@ export class Wallet {
|
||||
|
||||
let history = await (
|
||||
this.q()
|
||||
.iter(Stores.history, {indexName: "timestamp"})
|
||||
.iterIndex(Stores.history.timestampIndex)
|
||||
.reduce(collect, []));
|
||||
|
||||
return {history};
|
||||
|
Loading…
Reference in New Issue
Block a user