* 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>
114 lines
3.3 KiB
TypeScript
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("; "))
|
|
}
|