@stormzx/sqlbuilder
Version:
A simple sql builder.
134 lines (106 loc) • 3.42 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Builder = void 0;
exports.setSupportFragment = setSupportFragment;
var _lodash = _interopRequireDefault(require("lodash"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
class Builder {
#fragments = new Map();
/**
* Fragments may has same method.
* define a property for current fragment.
*/
#currentFragment = null;
hasFragment(type) {
return this.#fragments.has(type);
}
setFragment(type, fragment) {
this.#currentFragment = fragment;
if (this.#fragments.has(type)) {
this.#fragments.set(type, _lodash.default.flattenDeep([this.#fragments.get(type), fragment]));
} else {
this.#fragments.set(type, fragment);
}
}
getFragment(type) {
let fragment = this.#fragments.get(type);
if (_lodash.default.isArray(fragment)) {
return fragment.at(-1);
}
return fragment;
}
get currentFragment() {
return this.#currentFragment;
}
set currentFragment(Fragment) {
this.#currentFragment = Fragment;
}
toSQL(count = false) {
let fragments = _lodash.default.sortBy([...this.#fragments.values()], f => f.priority ?? f[0].priority);
fragments = _lodash.default.flattenDeep(fragments);
if (count) {
let inner = (0, _lodash.default)(fragments).map('countSql').join(' ');
return `select count(*) count from (${inner}) as t`;
} else {
return (0, _lodash.default)(fragments).map('sql').join(' ');
}
} // mysql2 query(sql) need be a stringg or {sql: string}
get sql() {
return this.toSQL(false);
}
}
exports.Builder = Builder;
function setSupportFragment(Builder, ...Fragments) {
let target = Builder.prototype;
let methods = (0, _lodash.default)(Fragments).flattenDeep().map(F => {
return _lodash.default.map(getMemberMethods(F), (descriptor, method) => {
return {
fragment: F,
type: F.type,
method,
descriptor
};
});
}).flatten().groupBy('method').value();
_lodash.default.map(methods, methods => {
let method = methods[0].method;
if (methods.length > 1) {
// 检查到哪个fragment了
Reflect.defineProperty(target, method, { ...methods[0].descriptor,
value: function (...args) {
let fragment = this.currentFragment;
fragment[method](...arguments);
return this;
}
});
} else {
let desc = methods[0].descriptor;
let type = methods[0].type;
let method = methods[0].method;
let Fragment = methods[0].fragment;
Reflect.defineProperty(target, method, { ...desc,
value: function () {
if (!this.hasFragment(type)) {
this.setFragment(type, new Fragment(this));
}
this.getFragment(type)[method](...arguments);
return this;
}
});
}
});
}
/**
* get methods of Fragment.
*/
function getMemberMethods(Class) {
let descriptors = Object.getOwnPropertyDescriptors(Class.prototype);
while (/^class/.test(Object.toString.call(Class = Class.__proto__))) {
descriptors = { ...(Object.getOwnPropertyDescriptors(Class.prototype) || {}),
...descriptors
};
}
return (0, _lodash.default)(descriptors).omit('constructor').omitBy(v => !_lodash.default.isFunction(v.value)).value();
}