Skip to content

Commit

Permalink
Fix store context (#2161)
Browse files Browse the repository at this point in the history
* Fix Store not working from changes in #2153

* Update changelog
  • Loading branch information
stwiname authored Nov 13, 2023
1 parent b15d83b commit 9846ee6
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 42 deletions.
5 changes: 3 additions & 2 deletions packages/node-core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Fixed
- Store not having access to blockheight and causing workers to fail on startup (#2161)

## [6.4.0] - 2023-11-10
### Added
- Base yargs config for all SDKs (#2144)
- Support block skipping on unavailable blocks (#2151)

### Fixed
- When using store get methods the `save` function would be missing
- When using store get methods the `save` function would be missing (#2153)
- Not indexing cleanly when all datasources have reached their end block

### Fixed
Expand Down
21 changes: 11 additions & 10 deletions packages/node-core/src/indexer/store.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export class StoreService {

// Should be updated each block
private _blockHeight?: number;
private operationStack?: StoreOperations;
private _operationStack?: StoreOperations;

constructor(
private sequelize: Sequelize,
Expand All @@ -125,7 +125,15 @@ export class StoreService {
return this._metaDataRepo;
}

private get blockHeight(): number {
private set operationStack(os: StoreOperations | undefined) {
this._operationStack = os;
}

get operationStack(): StoreOperations | undefined {
return this._operationStack;
}

get blockHeight(): number {
assert(this._blockHeight, new Error('StoreService.setBlockHeight has not been called'));
return this._blockHeight;
}
Expand Down Expand Up @@ -749,14 +757,7 @@ group by
}

getStore(): Store {
return new Store(
this.config,
this.storeCache,
this.blockHeight,
this.isIndexed.bind(this),
this.isIndexedHistorical.bind(this),
this.operationStack
);
return new Store(this.config, this.storeCache, this);
}
}

Expand Down
55 changes: 25 additions & 30 deletions packages/node-core/src/indexer/store/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,24 @@ type Options = {
limit?: number;
};

/* A context is provided to allow it to be updated by the owner of the class instance */
type Context = {
blockHeight: number;
operationStack?: StoreOperations;
isIndexed: (entity: string, field: string) => boolean;
isIndexedHistorical: (entity: string, field: string) => boolean;
};

export class Store implements IStore {
/* These need to explicily be private using JS style private properties in order to not leak these in the sandbox */
#config: NodeConfig;
#storeCache: StoreCacheService;
#blockHeight: number;
#isIndexed: (entity: string, field: string) => boolean;
#isIndexedHistorical: (entity: string, field: string) => boolean;
#operationStack?: StoreOperations;

constructor(
config: NodeConfig,
storeCache: StoreCacheService,
blockHeight: number,
isIndexed: (entity: string, field: string) => boolean,
isIndexedHistorical: (entity: string, field: string) => boolean,
operationStack?: StoreOperations
) {
#context: Context;

constructor(config: NodeConfig, storeCache: StoreCacheService, context: Context) {
this.#config = config;
this.#storeCache = storeCache;
this.#blockHeight = blockHeight;
this.#isIndexed = isIndexed;
this.#isIndexedHistorical = isIndexedHistorical;
this.#operationStack = operationStack;
this.#context = context;
}

#queryLimitCheck(storeMethod: string, entity: string, options?: Options) {
Expand Down Expand Up @@ -68,7 +63,7 @@ export class Store implements IStore {
options: Options = {}
): Promise<T[]> {
try {
const indexed = this.#isIndexed(entity, String(field));
const indexed = this.#context.isIndexed(entity, String(field));
assert(indexed, `to query by field ${String(field)}, an index must be created on model ${entity}`);
this.#queryLimitCheck('getByField', entity, options);

Expand All @@ -91,7 +86,7 @@ export class Store implements IStore {
// Check that the fields are indexed
filter.forEach((f) => {
assert(
this.#isIndexed(entity, String(f[0])),
this.#context.isIndexed(entity, String(f[0])),
`to query by field ${String(f[0])}, an index must be created on model ${entity}`
);
});
Expand All @@ -113,7 +108,7 @@ export class Store implements IStore {

async getOneByField<T extends Entity>(entity: string, field: keyof T, value: T[keyof T]): Promise<T | undefined> {
try {
const indexed = this.#isIndexedHistorical(entity, field as string);
const indexed = this.#context.isIndexedHistorical(entity, field as string);
assert(indexed, `to query by field ${String(field)}, a unique index must be created on model ${entity}`);
const raw = await this.#storeCache.getModel<T>(entity).getOneByField(field, value);

Expand All @@ -126,20 +121,20 @@ export class Store implements IStore {
// eslint-disable-next-line @typescript-eslint/require-await
async set(entity: string, _id: string, data: Entity): Promise<void> {
try {
this.#storeCache.getModel(entity).set(_id, data, this.#blockHeight);
this.#storeCache.getModel(entity).set(_id, data, this.#context.blockHeight);

this.#operationStack?.put(OperationType.Set, entity, data);
this.#context.operationStack?.put(OperationType.Set, entity, data);
} catch (e) {
throw new Error(`Failed to set Entity ${entity} with _id ${_id}: ${e}`);
}
}
// eslint-disable-next-line @typescript-eslint/require-await
async bulkCreate(entity: string, data: Entity[]): Promise<void> {
try {
this.#storeCache.getModel(entity).bulkCreate(data, this.#blockHeight);
this.#storeCache.getModel(entity).bulkCreate(data, this.#context.blockHeight);

for (const item of data) {
this.#operationStack?.put(OperationType.Set, entity, item);
this.#context.operationStack?.put(OperationType.Set, entity, item);
}
} catch (e) {
throw new Error(`Failed to bulkCreate Entity ${entity}: ${e}`);
Expand All @@ -149,9 +144,9 @@ export class Store implements IStore {
// eslint-disable-next-line @typescript-eslint/require-await
async bulkUpdate(entity: string, data: Entity[], fields?: string[]): Promise<void> {
try {
this.#storeCache.getModel(entity).bulkUpdate(data, this.#blockHeight, fields);
this.#storeCache.getModel(entity).bulkUpdate(data, this.#context.blockHeight, fields);
for (const item of data) {
this.#operationStack?.put(OperationType.Set, entity, item);
this.#context.operationStack?.put(OperationType.Set, entity, item);
}
} catch (e) {
throw new Error(`Failed to bulkCreate Entity ${entity}: ${e}`);
Expand All @@ -160,20 +155,20 @@ export class Store implements IStore {
// eslint-disable-next-line @typescript-eslint/require-await
async remove(entity: string, id: string): Promise<void> {
try {
this.#storeCache.getModel(entity).remove(id, this.#blockHeight);
this.#storeCache.getModel(entity).remove(id, this.#context.blockHeight);

this.#operationStack?.put(OperationType.Remove, entity, id);
this.#context.operationStack?.put(OperationType.Remove, entity, id);
} catch (e) {
throw new Error(`Failed to remove Entity ${entity} with id ${id}: ${e}`);
}
}
// eslint-disable-next-line @typescript-eslint/require-await
async bulkRemove(entity: string, ids: string[]): Promise<void> {
try {
this.#storeCache.getModel(entity).bulkRemove(ids, this.#blockHeight);
this.#storeCache.getModel(entity).bulkRemove(ids, this.#context.blockHeight);

for (const id of ids) {
this.#operationStack?.put(OperationType.Remove, entity, id);
this.#context.operationStack?.put(OperationType.Remove, entity, id);
}
} catch (e) {
throw new Error(`Failed to bulkRemove Entity ${entity}: ${e}`);
Expand Down

0 comments on commit 9846ee6

Please sign in to comment.