123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649 |
- const {InnerState} = require('../inner-state');
- const {assert} = require('../assert');
- const {TableName} = require('./table-name');
- const {Column} = require('./column');
- const npm = {
- os: require('os'),
- utils: require('../utils'),
- formatting: require('../formatting')
- };
- class ColumnSet extends InnerState {
- constructor(columns, opt) {
- super();
- if (!columns || typeof columns !== 'object') {
- throw new TypeError('Invalid parameter \'columns\' specified.');
- }
- opt = assert(opt, ['table', 'inherit']);
- if (!npm.utils.isNull(opt.table)) {
- this.table = (opt.table instanceof TableName) ? opt.table : new TableName(opt.table);
- }
-
-
- if (Array.isArray(columns)) {
- const colNames = {};
- this.columns = columns.map(c => {
- const col = (c instanceof Column) ? c : new Column(c);
- if (col.name in colNames) {
- throw new Error(`Duplicate column name "${col.name}".`);
- }
- colNames[col.name] = true;
- return col;
- });
- } else {
- if (columns instanceof Column) {
- this.columns = [columns];
- } else {
- this.columns = [];
- for (const name in columns) {
- if (opt.inherit || Object.prototype.hasOwnProperty.call(columns, name)) {
- this.columns.push(new Column(name));
- }
- }
- }
- }
- Object.freeze(this.columns);
- Object.freeze(this);
- this.extendState({
- names: undefined,
- variables: undefined,
- updates: undefined,
- isSimple: true
- });
- for (let i = 0; i < this.columns.length; i++) {
- const c = this.columns[i];
-
-
- if (c.prop || c.init || 'def' in c) {
- this._inner.isSimple = false;
- break;
- }
- }
- }
-
- get names() {
- const _i = this._inner;
- if (!_i.names) {
- _i.names = this.columns.map(c => c.escapedName).join();
- }
- return _i.names;
- }
-
- get variables() {
- const _i = this._inner;
- if (!_i.variables) {
- _i.variables = this.columns.map(c => c.variable + c.castText).join();
- }
- return _i.variables;
- }
- }
- ColumnSet.prototype.assign = function (options) {
- const _i = this._inner;
- const hasPrefix = options && options.prefix && typeof options.prefix === 'string';
- if (_i.updates && !hasPrefix) {
- return _i.updates;
- }
- let dynamic = hasPrefix;
- const hasSource = options && options.source && typeof options.source === 'object';
- let list = this.columns.filter(c => {
- if (c.cnd) {
- return false;
- }
- if (c.skip) {
- dynamic = true;
- if (hasSource) {
- const a = colDesc(c, options.source);
- if (c.skip.call(options.source, a)) {
- return false;
- }
- }
- }
- return true;
- });
- const prefix = hasPrefix ? npm.formatting.as.alias(options.prefix) + '.' : '';
- list = list.map(c => prefix + c.escapedName + '=' + c.variable + c.castText).join();
- if (!dynamic) {
- _i.updates = list;
- }
- return list;
- };
- ColumnSet.prototype.assignColumns = function (options) {
- options = assert(options, ['from', 'to', 'skip']);
- const skip = (typeof options.skip === 'string' && [options.skip]) || ((Array.isArray(options.skip) || typeof options.skip === 'function') && options.skip);
- const from = (typeof options.from === 'string' && options.from && (npm.formatting.as.alias(options.from) + '.')) || '';
- const to = (typeof options.to === 'string' && options.to && (npm.formatting.as.alias(options.to) + '.')) || '';
- const iterator = typeof skip === 'function' ? c => !skip.call(c, c) : c => skip.indexOf(c.name) === -1;
- const cols = skip ? this.columns.filter(iterator) : this.columns;
- return cols.map(c => to + c.escapedName + '=' + from + c.escapedName).join();
- };
- ColumnSet.prototype.extend = function (columns) {
- let cs = columns;
- if (!(cs instanceof ColumnSet)) {
- cs = new ColumnSet(columns);
- }
-
- return new ColumnSet(this.columns.concat(cs.columns), {table: this.table});
- };
- ColumnSet.prototype.merge = function (columns) {
- let cs = columns;
- if (!(cs instanceof ColumnSet)) {
- cs = new ColumnSet(columns);
- }
- const colNames = {}, cols = [];
- this.columns.forEach((c, idx) => {
- cols.push(c);
- colNames[c.name] = idx;
- });
- cs.columns.forEach(c => {
- if (c.name in colNames) {
- cols[colNames[c.name]] = c;
- } else {
- cols.push(c);
- }
- });
- return new ColumnSet(cols, {table: this.table});
- };
- ColumnSet.prototype.prepare = function (source) {
- if (this._inner.isSimple) {
- return source;
- }
- const target = {};
- this.columns.forEach(c => {
- const a = colDesc(c, source);
- if (c.init) {
- target[a.name] = c.init.call(source, a);
- } else {
- if (a.exists || 'def' in c) {
- target[a.name] = a.value;
- }
- }
- });
- return target;
- };
- function colDesc(column, source) {
- const a = {
- source,
- name: column.prop || column.name
- };
- a.exists = a.name in source;
- if (a.exists) {
- a.value = source[a.name];
- } else {
- a.value = 'def' in column ? column.def : undefined;
- }
- return a;
- }
- ColumnSet.prototype.toString = function (level) {
- level = level > 0 ? parseInt(level) : 0;
- const gap0 = npm.utils.messageGap(level),
- gap1 = npm.utils.messageGap(level + 1),
- lines = [
- 'ColumnSet {'
- ];
- if (this.table) {
- lines.push(gap1 + 'table: ' + this.table);
- }
- if (this.columns.length) {
- lines.push(gap1 + 'columns: [');
- this.columns.forEach(c => {
- lines.push(c.toString(2));
- });
- lines.push(gap1 + ']');
- } else {
- lines.push(gap1 + 'columns: []');
- }
- lines.push(gap0 + '}');
- return lines.join(npm.os.EOL);
- };
- npm.utils.addInspection(ColumnSet, function () {
- return this.toString();
- });
- module.exports = {ColumnSet};
|