Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Allow to extend knex query builder #3334

Merged
merged 9 commits into from Jul 23, 2019
@@ -1,5 +1,6 @@
const Raw = require('./raw');
const Client = require('./client');
const QueryBuilder = require('./query/builder');

const makeKnex = require('./util/make-knex');
const parseConnection = require('./util/parse-connection');
@@ -56,6 +57,7 @@ function Knex(config) {

// Expose Client on the main Knex namespace.
Knex.Client = Client;
Knex.QueryBuilder = QueryBuilder;

/* eslint no-console:0 */

@@ -43,6 +43,7 @@ function Builder(client) {
this._notFlag = false;
this._asColumnFlag = false;
}

inherits(Builder, EventEmitter);

const validateWithArgs = function(alias, statement, method) {
@@ -1219,4 +1220,8 @@ Builder.prototype.del = Builder.prototype.delete;
require('../interface')(Builder);
helpers.addQueryContext(Builder);

Builder.extend = function(methodName, fn) {
assign(Builder.prototype, { [methodName]: fn });
};

module.exports = Builder;
@@ -468,4 +468,30 @@ describe('knex', () => {
});
});
});

describe('extend query builder', () => {
let connection;
beforeEach(() => {
connection = new sqlite3.Database(':memory:');
});

afterEach(() => {
connection.close();
});

it('should extend default queryBuilder', (done) => {
Knex.QueryBuilder.extend('customSelect', function(value) {

This comment has been minimized.

Copy link
@kibertoad

kibertoad Jul 7, 2019

Collaborator

This leaks extended querybuilder outside of thus test, I think. Would be good to delete custom metode in after() block.

This comment has been minimized.

Copy link
@felixmosh

felixmosh Jul 7, 2019

Author Contributor

So you suggest to add remove method as well? cause with the current api, it always adds the method for the entire app.

This comment has been minimized.

Copy link
@kibertoad

kibertoad Jul 7, 2019

Collaborator

wouldn't simple delete Knex.Querybuilder.prototype.customMethod work? I don't think we should expose deletion method via API.

This comment has been minimized.

Copy link
@felixmosh

felixmosh Jul 7, 2019

Author Contributor

It will work, I will update my PR soon

return this.select(this.client.raw(`${value} as value`));
});

const knex = Knex({ client: 'sqlite3' });
knex
.connection(connection)
.customSelect(42)
.then((result) => {
expect(result[0].value).to.equal(42);
done();
});
});
});
});
@@ -353,6 +353,10 @@ interface Knex<TRecord extends {} = any, TResult = any[]>
seed: Knex.Seeder;
fn: Knex.FunctionHelper;
ref: Knex.RefBuilder;

QueryBuilder: {
extend(methodName: string, fn: Function): void;
};
}

declare function Knex<TRecord = any, TResult = unknown[]>(
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.