Files
medusa-store/packages/modules/index/src/utils/create-partitions.ts
Carlos R. L. Rodrigues b868a4ef4d feat(index): add filterable fields to link definition (#11898)
* feat(index): add filterable fields to link definition

* rm comment

* break recursion

* validate read only links

* validate filterable

* gql schema array

* link parents

* isInverse

* push id when not present

* Fix ciruclar relationships and add tests to ensure proper behaviour (part 1)

* log and fallback to entity.alias

* cleanup and fixes

* cleanup and fixes

* cleanup and fixes

* fix get attributes

* gql type

* unit test

* array inference

* rm only

* package.json

* pacvkage.json

* fix link retrieval on duplicated entity type and aliases + tests

* link parents as array

* Match only parent entity

* rm comment

* remove hard coded schema

* extend types

* unit test

* test

* types

* pagination type

* type

* fix integration tests

* Improve performance of in selection

* use @@ to filter property

* escape jsonPath

* add Event Bus by default

* changeset

* rm postgres analyze

* estimate count

* new query

* parent aliases

* inner query w/ filter and sort relations

* address comments

---------

Co-authored-by: adrien2p <adrien.deperetti@gmail.com>
Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>
2025-04-29 12:10:31 +02:00

114 lines
3.3 KiB
TypeScript

import { IndexTypes } from "@medusajs/framework/types"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { schemaObjectRepresentationPropertiesToOmit } from "@types"
export async function createPartitions(
schemaObjectRepresentation: IndexTypes.SchemaObjectRepresentation,
manager: SqlEntityManager
): Promise<void> {
const activeSchema = manager.config.get("schema")
? `"${manager.config.get("schema")}".`
: ""
const createdPartitions: Set<string> = new Set()
const partitions = Object.keys(schemaObjectRepresentation)
.filter(
(key) =>
!schemaObjectRepresentationPropertiesToOmit.includes(key) &&
schemaObjectRepresentation[key].listeners.length > 0
)
.map((key) => {
const cName = key.toLowerCase()
if (createdPartitions.has(cName)) {
return []
}
createdPartitions.add(cName)
const part: string[] = []
part.push(
`CREATE TABLE IF NOT EXISTS ${activeSchema}cat_${cName} PARTITION OF ${activeSchema}index_data FOR VALUES IN ('${key}')`
)
for (const parent of schemaObjectRepresentation[key].parents) {
if (parent.isInverse) {
continue
}
const pName = `cat_pivot_${parent.ref.entity}${key}`.toLowerCase()
if (createdPartitions.has(pName)) {
continue
}
createdPartitions.add(pName)
part.push(
`CREATE TABLE IF NOT EXISTS ${activeSchema}${pName} PARTITION OF ${activeSchema}index_relation FOR VALUES IN ('${parent.ref.entity}-${key}')`
)
}
return part
})
.flat()
if (!partitions.length) {
return
}
await manager.execute(partitions.join("; "))
// Create indexes for each partition
const indexCreationCommands = Object.keys(schemaObjectRepresentation)
.filter(
(key) =>
!schemaObjectRepresentationPropertiesToOmit.includes(key) &&
schemaObjectRepresentation[key].listeners.length > 0
)
.map((key) => {
const cName = key.toLowerCase()
const part: string[] = []
part.push(
`CREATE INDEX CONCURRENTLY IF NOT EXISTS "IDX_cat_${cName}_data_gin" ON ${activeSchema}cat_${cName} USING GIN ("data" jsonb_path_ops)`
)
part.push(
`CREATE INDEX CONCURRENTLY IF NOT EXISTS "IDX_cat_${cName}_id" ON ${activeSchema}cat_${cName} ("id")`
)
for (const parent of schemaObjectRepresentation[key].parents) {
if (parent.isInverse) {
continue
}
const pName = `cat_pivot_${parent.ref.entity}${key}`.toLowerCase()
part.push(
`CREATE INDEX CONCURRENTLY IF NOT EXISTS "IDX_${pName}_child_id" ON ${activeSchema}${pName} ("child_id")`
)
}
return part
})
.flat()
for (const cmd of indexCreationCommands) {
try {
await manager.execute(cmd)
} catch (error) {
console.error(`Failed to create index: ${error.message}`)
}
}
// Create count estimate function
partitions.push(`
CREATE OR REPLACE FUNCTION count_estimate(query text) RETURNS bigint AS $$
DECLARE
plan jsonb;
BEGIN
EXECUTE 'EXPLAIN (FORMAT JSON) ' || query INTO plan;
RETURN (plan->0->'Plan'->>'Plan Rows')::bigint;
END;
$$ LANGUAGE plpgsql;
`)
await manager.execute(partitions.join("; "))
}