Skip to content

Export QueryRunner to extend ModelQueryBuilder #1102

@will-apresenta

Description

@will-apresenta

Package version

21.6.0

Describe the bug

I'm creating a Cache layer over model queries, so i need to extend ModelQueryBuilder but to do that, i will need access to QueryRunner.

Additionally, it would be very usefull if the method was broken on another 3 methods (get query result, convert rows to models and preload relations).

Cache provider example:

       ModelQueryBuilder.macro('convertRowsToModels', async function (this: ModelQueryBuilder, rows: any[]) {
            return rows.reduce((models: any, row: any) => {
                if (isObject(row)) {
                    const modelInstance = this.model.$createFromAdapterResult(row, this.sideloaded, this.clientOptions)
                    /**
                     * Transform row when row transformer is defined
                     */
                    if (this.rowTransformerCallback) {
                        this.rowTransformerCallback(modelInstance!)
                    }
                    models.push(modelInstance)
                }
                return models
            }, [])
        })

        ModelQueryBuilder.macro('execQueryModel', async function (this: ModelQueryBuilder) {
            this.applyWhere()
            const isWriteQuery = ['update', 'del', 'insert'].includes((this.knexQuery as any)['_method'])
            const queryData = Object.assign(this.getQueryData(), this.customReporterData)
            const rows = await new QueryRunner(this.client, this.debugQueries, queryData).run(this.knexQuery)
            /**
             * Return the rows as it is when query is a write query
             */
            if (isWriteQuery || !this.wrapResultsToModelInstances) {
                return Array.isArray(rows) ? rows : [rows]
            }
            /**
             * Convert fetched results to an array of model instances
             */
            return this.convertRowsToModels(rows)
        })


        ModelQueryBuilder.macro('execQuery', async function (this: ModelQueryBuilder) {
            const isWriteQuery = ['update', 'del', 'insert'].includes((this.knexQuery as any)['_method'])
            let modelInstances

            if (isCachable(this.model)) {
                // make cache tratatives, like clear cache if isWriteQuery
                // check if cache already exists or make retrieve from DB
            } else {
                modelInstances = await this.execQueryModel()
            }

            /**
             * Preload for model instances
             */
            await this.preloader.sideload(this.sideloaded).debug(this.debugQueries).processAllForMany(modelInstances, this.client)
            return modelInstances
        })

Reproduction repo

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions