如何使用函数扩展 pg-promise 接口
How to extend pg-promise interface with function
我有一个 node.js 模块 pg-promise
实例化如下。
const pgp = require('pg-promise')();
// Database connection details;
const cn = {
host: 'localhost', // 'localhost' is the default;
...
}
// Create db connection and verify it
var db = pgp(process.env.DATABASE_URL || cn);
db.one('Select version()')
.then(data => {
log.info('Connected: ', data);
})
.catch(error => {
log.error("Error connecting to db", error);
})
// extension methods
db.findById = function (table, id) {
log.debug('read ', table, id);
return db.one('Select * from ' + table + ' where id = ', id);
}
module.exports = db;
db对象是接口类型的一个实例pgPromise.IDatabase<{}, pg.Iclient>
我希望能够调用这个库提供的函数以及我自己的函数。:
const db = require('../db');
db.any('Select query..')
.then(data => { res.send(data); })
.catch(err => { log.error(err); });
db.findById('users',1)
.then(data => { res.send(data); })
.catch(err => { log.error(err); });
但是当我 运行 它时,我得到了错误
TypeError: db.findById is not a function
我也试过了,效果一样。
module.exports = db;
module.exports.findById = function()...;
我能想到的唯一解决方案是:
module.exports = {
db: db,
findById: function(){
...
}
}
但是现在很难在其他模块中使用它,因为我总是需要专门询问 db
属性.
pg-promise
似乎使用了一种烦人的模式,他们冻结每个对象并使每个 属性 只读,所以你将无法像你一样简单地手动添加属性尝试。该库支持 initOptions
extend
属性 中的扩展,如下所示:
const initOptions = {
extend(obj, dc) {
obj.findById = function() {
...
}
//add other extension methods or properties here
}
};
const pgp = require('pg-promise')(initOptions);
//now any databases created with pgp will contain those extension methods
或者,您可以在您的导出对象上定义一个代理,它遵从数据库或您自己的自定义函数:
const extension = {
findById: function() {
...
},
//other functions
};
module.exports = new Proxy(extension, { get(target, name) {
if(db[name] !== undefined) return db[name];
return target[name];
});
但是您应该更喜欢使用 initOptions
.
本机支持的方式来执行此操作
来自 pg-promise 的作者。
pg-promise 中的数据库协议是可扩展的,支持事件 extend,可让您在所有级别上扩展协议。您需要这种级别的自动化,因为当涉及到基本的 Tasks 和 Transactions 时,它们封装了分配的连接,协议变得动态,并且所以你需要一个特殊的规定来使协议扩展自动工作,这正是事件 extend 所做的。
为了更好地理解它,我写了 pg-promise-demo 来展示如何正确地做到这一点,以及一些其他大多数时候有用的高级内容。
我有一个 node.js 模块 pg-promise
实例化如下。
const pgp = require('pg-promise')();
// Database connection details;
const cn = {
host: 'localhost', // 'localhost' is the default;
...
}
// Create db connection and verify it
var db = pgp(process.env.DATABASE_URL || cn);
db.one('Select version()')
.then(data => {
log.info('Connected: ', data);
})
.catch(error => {
log.error("Error connecting to db", error);
})
// extension methods
db.findById = function (table, id) {
log.debug('read ', table, id);
return db.one('Select * from ' + table + ' where id = ', id);
}
module.exports = db;
db对象是接口类型的一个实例pgPromise.IDatabase<{}, pg.Iclient>
我希望能够调用这个库提供的函数以及我自己的函数。:
const db = require('../db');
db.any('Select query..')
.then(data => { res.send(data); })
.catch(err => { log.error(err); });
db.findById('users',1)
.then(data => { res.send(data); })
.catch(err => { log.error(err); });
但是当我 运行 它时,我得到了错误
TypeError: db.findById is not a function
我也试过了,效果一样。
module.exports = db;
module.exports.findById = function()...;
我能想到的唯一解决方案是:
module.exports = {
db: db,
findById: function(){
...
}
}
但是现在很难在其他模块中使用它,因为我总是需要专门询问 db
属性.
pg-promise
似乎使用了一种烦人的模式,他们冻结每个对象并使每个 属性 只读,所以你将无法像你一样简单地手动添加属性尝试。该库支持 initOptions
extend
属性 中的扩展,如下所示:
const initOptions = {
extend(obj, dc) {
obj.findById = function() {
...
}
//add other extension methods or properties here
}
};
const pgp = require('pg-promise')(initOptions);
//now any databases created with pgp will contain those extension methods
或者,您可以在您的导出对象上定义一个代理,它遵从数据库或您自己的自定义函数:
const extension = {
findById: function() {
...
},
//other functions
};
module.exports = new Proxy(extension, { get(target, name) {
if(db[name] !== undefined) return db[name];
return target[name];
});
但是您应该更喜欢使用 initOptions
.
来自 pg-promise 的作者。
pg-promise 中的数据库协议是可扩展的,支持事件 extend,可让您在所有级别上扩展协议。您需要这种级别的自动化,因为当涉及到基本的 Tasks 和 Transactions 时,它们封装了分配的连接,协议变得动态,并且所以你需要一个特殊的规定来使协议扩展自动工作,这正是事件 extend 所做的。
为了更好地理解它,我写了 pg-promise-demo 来展示如何正确地做到这一点,以及一些其他大多数时候有用的高级内容。