Skip to content

Commit

Permalink
wip: implement indices in withModuleSelection()
Browse files Browse the repository at this point in the history
  • Loading branch information
Yogu committed Sep 11, 2024
1 parent 5034311 commit 7c2691d
Show file tree
Hide file tree
Showing 5 changed files with 444 additions and 9 deletions.
273 changes: 273 additions & 0 deletions spec/project/select-modules-in-sources.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,279 @@ describe('selectModulesInProjectSource', () => {
}
`);
});

it('keeps indices that are fully covered by the modules', () => {
const result = run(
gql`
type Test
@rootEntity(
indices: [
{ fields: ["field1", "key"] }
{ fields: ["field1", "children.field1"], sparse: true }
]
)
@modules(in: "module1") {
key: String @key @modules(in: "module1")
field1: String @modules(in: "module1")
children: [Child] @modules(in: "module1")
}
type Child @childEntity @modules(in: "module1") {
field1: String @modules(in: "module1")
field2: String @modules(in: "module1")
}
`,
['module1'],
);
expect(result).to.equal(`
type Test
@rootEntity(
indices: [
{ fields: ["field1", "key"] }
{ fields: ["field1", "children.field1"], sparse: true }
]
)
@modules(in: ["module1"]) {
key: String @key @modules(in: ["module1"])
field1: String @modules(in: ["module1"])
children: [Child] @modules(in: ["module1"])
}
type Child @childEntity @modules(in: ["module1"]) {
field1: String @modules(in: ["module1"])
field2: String @modules(in: ["module1"])
}
`);
});

it('removes indices where none of the specified fields are included in the selected modules', () => {
const result = run(
gql`
type Test
@rootEntity(
indices: [
{ fields: ["field1", "key"] }
{ fields: ["field2", "children.field2"], sparse: true }
]
)
@modules(in: "module1") {
key: String @key @modules(in: "module1")
field1: String @modules(in: "module1")
field2: String @modules(in: "module2")
children: [Child] @modules(in: "module1")
}
type Child @childEntity @modules(in: "module1") {
field1: String @modules(in: "module1")
field2: String @modules(in: "module2")
}
`,
['module1'],
);
expect(result).to.equal(`
type Test
@rootEntity(
indices: [
{ fields: ["field1", "key"] }
]
)
@modules(in: ["module1"]) {
key: String @key @modules(in: ["module1"])
field1: String @modules(in: ["module1"])
children: [Child] @modules(in: ["module1"])
}
type Child @childEntity @modules(in: ["module1"]) {
field1: String @modules(in: ["module1"])
}
`);
});

it('removes the whole indices arg if all indices have been removed', () => {
const result = run(
gql`
type Test
@rootEntity(
indices: [
{ fields: ["field2"] }
{ fields: ["field2", "children.field2"], sparse: true }
]
)
@modules(in: "module1") {
key: String @key @modules(in: "module1")
field1: String @modules(in: "module1")
field2: String @modules(in: "module2")
children: [Child] @modules(in: "module1")
}
type Child @childEntity @modules(in: "module1") {
field1: String @modules(in: "module1")
field2: String @modules(in: "module2")
}
`,
['module1'],
);
expect(result).to.equal(`
type Test
@rootEntity
@modules(in: ["module1"]) {
key: String @key @modules(in: ["module1"])
field1: String @modules(in: ["module1"])
children: [Child] @modules(in: ["module1"])
}
type Child @childEntity @modules(in: ["module1"]) {
field1: String @modules(in: ["module1"])
}
`);
});

it('removes the whole indices arg if all indices have been removed (and there are other args)', () => {
const result = run(
gql`
type Test
@rootEntity(
flexSearch: true
indices: [
{ fields: ["field2"] }
{ fields: ["field2", "children.field2"], sparse: true }
]
)
@modules(in: "module1") {
key: String @key @modules(in: "module1")
field1: String @modules(in: "module1")
field2: String @modules(in: "module2")
children: [Child] @modules(in: "module1")
}
type Child @childEntity @modules(in: "module1") {
field1: String @modules(in: "module1")
field2: String @modules(in: "module2")
}
`,
['module1'],
);
expect(result).to.equal(`
type Test
@rootEntity(
flexSearch: true
)
@modules(in: ["module1"]) {
key: String @key @modules(in: ["module1"])
field1: String @modules(in: ["module1"])
children: [Child] @modules(in: ["module1"])
}
type Child @childEntity @modules(in: ["module1"]) {
field1: String @modules(in: ["module1"])
}
`);
});

it('removes unique indices that are partially covered by the modules', () => {
const result = run(
gql`
type Test
@rootEntity(
indices: [
{ fields: ["field1", "key"] }
{
fields: ["field1", "children.field1", "children.field2"]
unique: true
}
]
)
@modules(in: "module1") {
key: String @key @modules(in: "module1")
field1: String @modules(in: "module1")
children: [Child] @modules(in: "module1")
}
type Child @childEntity @modules(in: "module1") {
field1: String @modules(in: "module1")
field2: String @modules(in: "module2")
}
`,
['module1'],
);
expect(result).to.equal(`
type Test
@rootEntity(
indices: [
{ fields: ["field1", "key"] }
]
)
@modules(in: ["module1"]) {
key: String @key @modules(in: ["module1"])
field1: String @modules(in: ["module1"])
children: [Child] @modules(in: ["module1"])
}
type Child @childEntity @modules(in: ["module1"]) {
field1: String @modules(in: ["module1"])
}
`);
});

it('trims down indices that are partially covered by the modules', () => {
const result = run(
gql`
type Test
@rootEntity(
indices: [
{ fields: ["field1", "key"] }
{
fields: ["field1", "children.field1", "children.field2"]
sparse: true
}
]
)
@modules(in: "module1") {
key: String @key @modules(in: "module1")
field1: String @modules(in: "module1")
children: [Child] @modules(in: "module1")
}
type Child @childEntity @modules(in: "module1") {
field1: String @modules(in: "module1")
field2: String @modules(in: "module2")
}
`,
['module1'],
);
expect(result).to.equal(`
type Test
@rootEntity(
indices: [
{ fields: ["field1", "key"] }
{
fields: ["field1", "children.field1"]
sparse: true
}
]
)
@modules(in: ["module1"]) {
key: String @key @modules(in: ["module1"])
field1: String @modules(in: ["module1"])
children: [Child] @modules(in: ["module1"])
}
type Child @childEntity @modules(in: ["module1"]) {
field1: String @modules(in: ["module1"])
}
`);
});
});

describe('with removeModuleDeclarations = true', () => {
Expand Down
14 changes: 14 additions & 0 deletions src/model/compatibility-check/check-indices.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { EnumType, RootEntityType } from '../implementation';
import { ValidationContext, ValidationMessage } from '../validation';
import { getRequiredBySuffix } from './describe-module-specification';

export function checkIndices(
typeToCheck: RootEntityType,
baselineType: RootEntityType,
context: ValidationContext,
) {
// use index config instead of indices because there is a transformation step that changes
// indices and also adds new indices. It would be confusing report issues for these.
for (const index of baselineType.indexConfigs) {
}
}
2 changes: 2 additions & 0 deletions src/model/compatibility-check/check-root-entity-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { getRequiredBySuffix } from './describe-module-specification';
import { checkBusinessObject } from './check-business-object';
import { checkTtl } from './check-ttl';
import { checkFlexSearchOnType } from './check-flex-search-on-type';
import { checkIndices } from './check-indices';

export function checkRootEntityType(
typeToCheck: RootEntityType,
Expand All @@ -14,4 +15,5 @@ export function checkRootEntityType(
checkBusinessObject(typeToCheck, baselineType, context);
checkTtl(typeToCheck, baselineType, context);
checkFlexSearchOnType(typeToCheck, baselineType, context);
checkIndices(typeToCheck, baselineType, context);
}
5 changes: 4 additions & 1 deletion src/model/implementation/root-entity-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { compact } from '../../utils/utils';
import {
FlexSearchPerformanceParams,
FlexSearchPrimarySortClauseConfig,
IndexDefinitionConfig,
PermissionsConfig,
RootEntityTypeConfig,
TypeKind,
Expand Down Expand Up @@ -54,6 +55,7 @@ export class RootEntityType extends ObjectTypeBase {
readonly flexSearchPrimarySort: ReadonlyArray<FlexSearchPrimarySortClause>;
readonly flexSearchPrimarySortAstNode: ArgumentNode | undefined;
readonly flexSearchPerformanceParams: FlexSearchPerformanceParams;
readonly indexConfigs: ReadonlyArray<IndexDefinitionConfig>;

constructor(
private readonly input: RootEntityTypeConfig,
Expand All @@ -79,11 +81,12 @@ export class RootEntityType extends ObjectTypeBase {
this.flexSearchPrimarySort = [];
this.flexSearchPerformanceParams = {};
}
this.indexConfigs = input.indices ?? [];
}

@memorize()
get indices(): ReadonlyArray<Index> {
const indexConfigs = this.input.indices ? [...this.input.indices] : [];
const indexConfigs = [...this.indexConfigs];

// @key implies a unique index
// (do this to the inputs so that addIdentifyingSuffixIfNeeded is called on these, too)
Expand Down
Loading

0 comments on commit 7c2691d

Please sign in to comment.