Skip to content

Commit

Permalink
Fix codegen and runtime issues relating to the dbType directive
Browse files Browse the repository at this point in the history
  • Loading branch information
stwiname committed Feb 4, 2025
1 parent 9a16361 commit b2935fc
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 8 deletions.
3 changes: 2 additions & 1 deletion packages/cli/src/template/model.ts.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export class <%= props.className %> implements CompatEntity {
}
}
<% } else { %>static async getBy<%=helper.upperFirst(field.name) %>(<%=field.name %>: <%=field.type %>, options: GetOptions<Compat<%=props.className %>Props>): Promise<<%=props.className %>[]> {
// Inputs must be cast as the store interface has not been updated to support alternative ID types
const records = await store.getByField<Compat<%=props.className %>Props>('<%=props.entityName %>', '<%=field.name %>', <%=field.name %>, options);
return records.map(record => this.create(record as unknown as <%= props.className %>Props));
}
Expand All @@ -80,7 +81,7 @@ export class <%= props.className %> implements CompatEntity {
* ⚠️ This function will first search cache data followed by DB data. Please consider this when using order and offset options.⚠️
* */
static async getByFields(filter: FieldsExpression<<%= props.className %>Props>[], options: GetOptions<<%= props.className %>Props>): Promise<<%=props.className %>[]> {
const records = await store.getByFields<<%=props.className %>Props>('<%=props.entityName %>', filter, options);
const records = await store.getByFields<Compat<%=props.className %>Props>('<%=props.entityName %>', filter as unknown as FieldsExpression<Compat<%=props.className %>Props>[], options as unknown as GetOptions<Compat<%=props.className %>Props>);
return records.map(record => this.create(record as unknown as <%= props.className %>Props));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors
// SPDX-License-Identifier: GPL-3.0

import {Entity} from '@subql/types-core';
import {DataTypes, Sequelize} from '@subql/x-sequelize';
import _ from 'lodash';
import {NodeConfig} from '../../../configure';
Expand Down Expand Up @@ -117,4 +118,46 @@ describe('Model provider consistency test', () => {
expect(cacheResult3).toEqual(result3);
});
});

describe('alternative id types', () => {
it('can store an entity with a numeric ID type', async () => {
const modelFactory = sequelize.define(
'testModel2',
{
id: {
type: DataTypes.INTEGER,
primaryKey: true,
},
field1: DataTypes.INTEGER,
},
{timestamps: false, schema: schema}
);
const model2 = await modelFactory.sync();

let i = 0;

const plainModel = new PlainModel(model2 as any, false);
const cacheModel = new CachedModel(model2 as any, false, new NodeConfig({} as any), () => i++);

const numericData = {
id: 1,
field1: 1,
} as unknown as Entity;

await plainModel.set(numericData.id.toString(), numericData, 1);
await cacheModel.set(numericData.id.toString(), numericData, 1);

const result = await plainModel.get(numericData.id, undefined as any);
expect(result).toEqual(numericData);

const cacheResult = await cacheModel.get(numericData.id);
expect(cacheResult).toEqual(numericData);

const [getByResult] = await plainModel.getByFields([['field1', '=', 1] as any], {limit: 1}, undefined as any);
expect(getByResult).toEqual(numericData);

const [getByCachedResult] = await cacheModel.getByFields([['field1', '=', 1] as any], {limit: 1});
expect(getByCachedResult).toEqual(numericData);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,6 @@ export class PlainModel<T extends BaseEntity = BaseEntity> implements IModel<T>
}

async set(id: string, data: T, blockHeight: number, tx?: Transaction): Promise<void> {
if (id !== data.id) {
throw new Error(`Id doesnt match with data`);
}

await this.bulkUpdate([data], blockHeight, undefined, tx);
}

Expand Down
7 changes: 5 additions & 2 deletions packages/utils/src/graphql/entities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,8 +247,11 @@ export function getAllEntitiesRelations(_schema: GraphQLSchema | string | null):
const t = getTypeByScalarName(dbType);

// Allowlist of types that can be used.
if (!t || !['BigInt', 'Float', 'ID', 'Int', 'String'].includes(t.name)) {
throw new Error(`${dbType} is not a defined scalar type, please use another type in the dbType directive`);
const allowedTypes = ['BigInt', 'Float', 'ID', 'Int', 'String'];
if (!t || !allowedTypes.includes(t.name)) {
throw new Error(
`${dbType} is not a defined scalar type, please use another type in the dbType directive.\n Available types: ${allowedTypes.join(', ')}`
);
}

const f = newModel.fields.find((f) => f.name === 'id');
Expand Down
2 changes: 1 addition & 1 deletion packages/utils/src/graphql/graphql.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ describe('utils that handle schema.graphql', () => {
for (const type of ['JSON', 'Date', 'Bytes', 'Boolean', 'StarterEntity']) {
const schema = makeSchema(type);
expect(() => getAllEntitiesRelations(schema)).toThrow(
`${type} is not a defined scalar type, please use another type in the dbType directive`
`${type} is not a defined scalar type, please use another type in the dbType directive.\nAvailable types: BigInt, Float, ID, Int, String`
);
}
});
Expand Down

0 comments on commit b2935fc

Please sign in to comment.