@fxjs/db-driver
Version:
[](https://www.npmjs.org/package/@fxjs/db-driver) [](https://travis-ci.org/fxjs-modules/db-driver) [ • 7.16 kB
JavaScript
/// <reference types="fib-pool" />
Object.defineProperty(exports, "__esModule", { value: true });
exports.SQLDriver = exports.Driver = void 0;
const url = require("url");
const assert = require("assert");
const coroutine = require("coroutine");
const Utils = require("../utils");
function setReactivePool(driver) {
let pool = false;
Object.defineProperty(driver.extend_config, 'pool', {
set(nextVal) {
if (typeof nextVal === 'string')
nextVal = Utils.castQueryStringToBoolean(nextVal);
if (nextVal) {
pool = Utils.parsePoolConfig(nextVal);
pool.maxsize = Utils.forceInteger(pool.maxsize, 100);
pool.timeout = Utils.forceInteger(pool.timeout, 1000);
Utils.mountPoolToDriver(driver, pool);
}
else {
pool = false;
}
},
get() { return pool; }
});
}
// function getDriver (name: 'mongodb'): typeof import('./driver-mongodb').default
function getDriver(name) {
switch (name) {
case 'mysql':
return require('./driver-mysql').default;
case 'postgresql':
case 'postgres':
case 'pg':
case 'psql':
return require('./driver-postgresql').default;
case 'sqlite':
return require('./driver-sqlite').default;
case 'redis':
return require('./driver-redis').default;
// case 'mongodb':
// return require('./driver-mongodb').default
default:
if (name) {
const type = Utils.filterDriverType(url.parse(name).protocol);
if (type !== 'unknown')
return getDriver(type);
}
// throw new Error(`[feature] driver type ${name} is not supported`)
return Driver;
}
}
class Driver {
constructor(options) {
this.extend_config = {
pool: false,
debug: false
};
// options would be replaced, `Utils.parseConnectionString` return a fresh object
options = Utils.parseConnectionString(options);
Object.defineProperty(this, 'config', { get() { return options; } });
assert.ok(!!this.config.protocol, '[driver.config] invalid protocol');
// some db has no host
switch (options.protocol) {
default: break;
case 'mysql:':
case 'mssql:':
case 'postgresql:':
assert.ok(!!this.config.host || !!this.config.hostname, '[driver.config] host or hostname required');
break;
}
this.type = Utils.filterDriverType(this.config.protocol);
const extend_config = {};
Object.defineProperty(this, 'extend_config', { get() { return extend_config; } });
setReactivePool(this);
extend_config.pool = options.query.pool;
extend_config.debug = Utils.castQueryStringToBoolean(options.query.debug);
Object.defineProperty(this, 'uid', { value: Utils.driverUUid(), writable: false, configurable: false });
}
static create(input) {
const driver = Driver.getDriver(typeof input === 'object' ? input.protocol : input);
return new driver(input);
}
/**
* @descritpin there's a bug in fibjs <= 0.35.x, only string type `field` would be
* used by `url.format`
*/
static formatUrl(input) {
let protocol = input.protocol;
// some user would like add // after valid protocol like `http:`, `mysql:`
if (protocol === null || protocol === void 0 ? void 0 : protocol.endsWith('//'))
protocol = protocol.slice(0, -2);
return url.format(Object.assign(Object.assign(Object.assign({}, input), { protocol }), !!input.port && { port: input.port + '' }));
}
get uri() {
const isSQLite = this.config.protocol === 'sqlite:';
return Driver.formatUrl(Object.assign(Object.assign(Object.assign({}, this.config), this.type === 'psql' && { protocol: 'psql:' }), { slashes: isSQLite ? false : this.config.slashes, query: isSQLite ? {} : this.config.query }));
}
get isPool() {
return !!this.extend_config.pool;
}
get isSql() {
const p = this.config.protocol || '';
return ((p === 'mysql:')
|| (p === 'mssql:')
|| (p === 'psql:')
|| (p.startsWith('sqlite:')));
}
get isNoSql() {
const p = this.config.protocol || '';
return ((p === 'mongodb:'));
}
get isCommand() {
const p = this.config.protocol || '';
return ((p === 'mongodb:')
|| (p === 'redis:'));
}
/**
* @description switch to another database, pointless for some databases such as sqlite
* @param targetDb
*/
switchDb(targetDb) {
this.currentDb = targetDb;
}
;
/**
* @description re open db connection
*/
reopen() {
try {
this.close();
}
catch (error) { }
return this.open();
}
/**
* @description open db connection
*/
open() {
return this.connection = this.getConnection();
}
/**
* @description close db connection
*/
close() { }
/**
* @description some db connection has `ping` method
*/
ping() { }
/**
* @description get connection instance but don't change internal status
*/
getConnection() { return null; }
connectionPool(callback) {
if (this.isPool)
return this.pool((conn) => callback(conn));
return callback(this.getConnection());
}
useTrans(callback) {
return this.connectionPool((conn) => {
if (typeof conn.trans === 'function') {
const waitor = {
ev: new (coroutine.Event)(),
result: undefined
};
conn.trans(() => {
waitor.result = callback(conn);
waitor.ev.set();
});
waitor.ev.wait();
return waitor.result;
}
else {
return callback(conn);
}
});
}
}
exports.Driver = Driver;
Driver.getDriver = getDriver;
class SQLDriver extends Driver {
constructor(opts) {
super(opts);
this.currentDb = null;
const options = Utils.parseConnectionString(opts);
this.extend_config.debug_sql = Utils.castQueryStringToBoolean(options.query.debug_sql);
}
/**
* @override
*/
dbExists(dbname) { return false; }
;
/**
* @override
*/
begin() { }
/**
* @override
*/
commit() { }
/**
* @override
*/
trans(cb) { return true; }
/**
* @override
*/
rollback() { }
/**
* @override
*/
execute(sql) { return; }
}
exports.SQLDriver = SQLDriver;