UNPKG

@zenweb/tenant

Version:

Zenweb Tenant module

67 lines (66 loc) 2.18 kB
import { $getContext } from '@zenweb/core'; import modMySQL from '@zenweb/mysql'; export * from './types.js'; /** * 当前上下文取得的租户信息 */ const TENANT = Symbol.for('zenweb@tenant'); /** * 生成租户数据库配置信息 */ export function makeTenantMySQLOption(option) { // 重组配置 const pools = {}; // 对应的服务器是否有从库 const haveSlaves = {}; for (const [server, poolConfig] of Object.entries(option.pools)) { pools[`${server}_MASTER`] = poolConfig.MASTER; if (poolConfig.SLAVES && poolConfig.SLAVES.length > 0) { haveSlaves[server] = true; let i = 1; for (const slave of poolConfig.SLAVES) { pools[`${server}_SLAVE${i}`] = slave; i++; } } else { haveSlaves[server] = false; } } return { cluster: option.cluster, pools, bindQuery: option.bindQuery, // 所属数据库服务器切换 async getPoolConnectionBefore(opt) { const ctx = $getContext(); if (!ctx[TENANT]) { ctx[TENANT] = await option.tenantGetter(ctx); } return { // 将原有选择规则增加前缀 // 判断是否有从库,如果没有强制走主库 pattern: ctx[TENANT].server + '_' + ((haveSlaves[ctx[TENANT].server] && opt?.pattern) || 'MASTER'), selector: opt?.selector, }; }, // 所属数据库切换 (复用连接池) getPoolConnectionAfter(conn) { return new Promise((resolve, reject) => { const ctx = $getContext(); conn.query('USE `' + ctx[TENANT].database + '`', err => { if (err) reject(err); else resolve(); }); }); }, }; } export default function setup(option) { return function tenant(setup) { setup.debug('option: %o', option); setup.core.setup(modMySQL(makeTenantMySQLOption(option))); }; }