fix(): handle empty q filters - allow to query deleted records from graph API - staled_at fixes (#11544)
* fix(): Allow to query deleted records from graph API * fix(): Allow to query deleted records from graph API * handle empty q value * update staled at sync * rename integration tests file * Create strong-houses-marry.md * try to fix flacky tests * fix pricing context * update changeset * update changeset * fix import * skip test for now --------- Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
cfffd55ae6
commit
065df75e7d
@@ -1,7 +1,6 @@
|
||||
import {
|
||||
CommonEvents,
|
||||
ContainerRegistrationKeys,
|
||||
groupBy,
|
||||
Modules,
|
||||
promiseAll,
|
||||
} from "@medusajs/framework/utils"
|
||||
@@ -41,10 +40,6 @@ export class DataSynchronizer {
|
||||
return this.#container.indexSyncService
|
||||
}
|
||||
|
||||
get #indexDataService(): ModulesSdkTypes.IMedusaInternalService<any> {
|
||||
return this.#container.indexDataService
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
get #indexRelationService(): ModulesSdkTypes.IMedusaInternalService<any> {
|
||||
return this.#container.indexRelationService
|
||||
@@ -103,48 +98,20 @@ export class DataSynchronizer {
|
||||
async removeEntities(entities: string[], staleOnly: boolean = false) {
|
||||
this.#isReadyOrThrow()
|
||||
|
||||
const staleCondition = staleOnly ? { staled_at: { $ne: null } } : {}
|
||||
const staleCondition = staleOnly ? "staled_at IS NOT NULL" : ""
|
||||
|
||||
const dataToDelete = await this.#indexDataService.list({
|
||||
...staleCondition,
|
||||
name: entities,
|
||||
})
|
||||
|
||||
const toDeleteByEntity = groupBy(dataToDelete, "name")
|
||||
|
||||
for (const entity of toDeleteByEntity.keys()) {
|
||||
const records = toDeleteByEntity.get(entity)
|
||||
const ids = records?.map(
|
||||
(record: { data: { id: string } }) => record.data.id
|
||||
for (const entity of entities) {
|
||||
await this.#container.manager.execute(
|
||||
`WITH deleted_data AS (
|
||||
DELETE FROM "index_data"
|
||||
WHERE "name" = ? ${staleCondition ? `AND ${staleCondition}` : ""}
|
||||
RETURNING id
|
||||
)
|
||||
DELETE FROM "index_relation"
|
||||
WHERE ("parent_name" = ? AND "parent_id" IN (SELECT id FROM deleted_data))
|
||||
OR ("child_name" = ? AND "child_id" IN (SELECT id FROM deleted_data))`,
|
||||
[entity, entity, entity]
|
||||
)
|
||||
if (!ids?.length) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (this.#schemaObjectRepresentation[entity]) {
|
||||
// Here we assume that some data have been deleted from from the source and we are cleaning since they are still staled in the index and we remove them from the index
|
||||
|
||||
// TODO: expand storage provider interface
|
||||
await (this.#storageProvider as any).onDelete({
|
||||
entity,
|
||||
data: ids,
|
||||
schemaEntityObjectRepresentation:
|
||||
this.#schemaObjectRepresentation[entity],
|
||||
})
|
||||
} else {
|
||||
// Here we assume that the entity is not indexed anymore as it is not part of the schema object representation and we are cleaning the index
|
||||
// TODO: Drop the partition somewhere
|
||||
await promiseAll([
|
||||
this.#container.manager.execute(
|
||||
`DELETE FROM "index_data" WHERE "name" = ?`,
|
||||
[entity]
|
||||
),
|
||||
this.#container.manager.execute(
|
||||
`DELETE FROM "index_relation" WHERE "parent_name" = ? OR "child_name" = ?`,
|
||||
[entity, entity]
|
||||
),
|
||||
])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,11 +2,13 @@ import {
|
||||
Context,
|
||||
Event,
|
||||
IndexTypes,
|
||||
QueryGraphFunction,
|
||||
RemoteQueryFunction,
|
||||
Subscriber,
|
||||
} from "@medusajs/framework/types"
|
||||
import {
|
||||
MikroOrmBaseRepository as BaseRepository,
|
||||
CommonEvents,
|
||||
ContainerRegistrationKeys,
|
||||
deepMerge,
|
||||
InjectManager,
|
||||
@@ -210,13 +212,20 @@ export class PostgresProvider implements IndexTypes.StorageProvider {
|
||||
}
|
||||
|
||||
const { fields, alias } = schemaEntityObjectRepresentation
|
||||
const { data: entityData } = await this.query_.graph({
|
||||
|
||||
const graphConfig: Parameters<QueryGraphFunction>[0] = {
|
||||
entity: alias,
|
||||
filters: {
|
||||
id: ids,
|
||||
},
|
||||
fields: [...new Set(["id", ...fields])],
|
||||
})
|
||||
}
|
||||
|
||||
if (action === CommonEvents.DELETED || action === CommonEvents.DETACHED) {
|
||||
graphConfig.withDeleted = true
|
||||
}
|
||||
|
||||
const { data: entityData } = await this.query_.graph(graphConfig)
|
||||
|
||||
const argument = {
|
||||
entity: schemaEntityObjectRepresentation.entity,
|
||||
|
||||
@@ -591,10 +591,14 @@ export class QueryBuilder {
|
||||
let textSearchQuery: string | null = null
|
||||
const searchQueryFilterProp = `${rootEntity}.q`
|
||||
|
||||
if (filter[searchQueryFilterProp]) {
|
||||
hasTextSearch = true
|
||||
textSearchQuery = filter[searchQueryFilterProp]
|
||||
delete filter[searchQueryFilterProp]
|
||||
if (searchQueryFilterProp in filter) {
|
||||
if (!filter[searchQueryFilterProp]) {
|
||||
delete filter[searchQueryFilterProp]
|
||||
} else {
|
||||
hasTextSearch = true
|
||||
textSearchQuery = filter[searchQueryFilterProp]
|
||||
delete filter[searchQueryFilterProp]
|
||||
}
|
||||
}
|
||||
|
||||
const joinParts = this.buildQueryParts(
|
||||
|
||||
Reference in New Issue
Block a user