Пользовательские функции для Knex
Есть целый ряд операций, которые я выполняю постоянно, и я надеялся, что найдется способ "расширить" knex, чтобы иметь возможность их выполнять.
Я хотел бы что-то вроде:
oneExists
result = knex.count(id).from('table').where({'code': 25})
if (result.length === 0) return false
if (result.length === 1) return true
throw an error
Я хотел бы иметь возможность сделать что-то вроде
knex.oneExists.count('id').from('table').where({'code': 25}).
на данный момент я пишу код так:
KnexUtil.oneExists(knex.select('id').from('table').where({code: 25}))
который возвращает обещание
Я просмотрел кодовую базу knex и не уверен:
- как связать это (и буду ли я делать это в /lib/query/compiler.js)
- как просто сделать расширение для knex, так что мне не нужно изменять исходную кодовую базу
4 ответа
Это обсуждалось в https://github.com/tgriesser/knex/issues/1158
knex
не поддерживает это, но один хакерский способ сделать это состоит в том, чтобы обезопасить сборщик запросов knex с помощью вашей функции:
var knex = require('knex')({client: 'pg'});
knex.client.QueryBuilder.prototype.newFunc = function () {
console.log("New query builder function");
return this;
}
knex('table').newFunc().toString();
// outputs:
// New query builder function
// 'select * from "table"'
Начиная с v0.19.1, knex имеет встроенную возможность расширения QueryBuilder.
import Knex from 'knex'
Knex.QueryBuilder.extend('someFn', function (arg) {
console.log('Do Smth', arg)
return this
})
const knex = Knex({ client: 'pg' })
knex.select().from('table').someFn(0).toString()
Что вы можете. Я бы порекомендовал просто создать свой собственный плагин, что-то вроде следующего:
// my-plugin.js
'use strict';
module.exports = function (Bookshelf) {
Bookshelf.Model = Bookshelf.Model.extend({
foo: function ( bar ) {
if( bar )
console.log('Method foo was called on a model with the arguments:', arguments.join(', '));
}
});
Bookshelf.Collection = Bookshelf.Collection.extend({
foo: function ( bar ) {
if( bar )
console.log('Method foo was called on a collection with the arguments:', arguments.join(', '));
}
});
};
Затем в вашем основном файле приложения добавьте:
Bookshelf.plugin( require( './my-plugin' ) );
Плагины BookshelfJS в основном позволяют расширять модели и коллекции (и многое другое), что позволяет добавлять собственный метод или перезаписывать существующие (при этом сохраняя возможность вызывать оригинальный метод из вашего плагина)
Для лучшего понимания, вам может быть полезно взглянуть на некоторые существующие плагины BookshelfJS, некоторые уже поставляются с книжной полкой, внутри директории плагинов.
Другой плагин, который может быть полезен для лучшего понимания работы плагинов, - плагин Soft Delete. В этом плагине вы можете видеть, как некоторые методы BookshelfJS переопределяются как в моделях, так и в объектах коллекций, с помощью методов, которые выполняют исходную версию метода, а затем возвращают проанализированный / измененный результат ( строки №37- № 59 и строки №) 37- # 57), а также добавление совершенно новых методов ( Строки # 61- # 72)
Изменить: Очевидно, что это больше BookshelfJS, чем KnexJS, но я не видел никакого способа создания плагинов для KnexJS, так как это просто конструктор запросов, вся настоящая магия в ORM
При использовании TypeScript:
import { knex, Knex as KnexOriginal } from "knex";
declare module "knex" {
namespace Knex {
interface QueryBuilder {
customFunction<TRecord, TResult>(
value: number
): KnexOriginal.QueryBuilder<TRecord, TResult>;
}
}
}
knex.QueryBuilder.extend("customFunction", function (value: number) {
console.log("Custom Function:", value);
return this;
});
const pg = knex({ client: "pg" });
pg("table").select("*").customFunction(10).toString()
Ознакомьтесь с документацией о том, как расширить knex