UNPKG

orange-orm

Version:

Object Relational Mapper

247 lines (213 loc) 8.12 kB
const newColumn = require('./table/column/newColumn'); const column = require('./table/column'); const join = require('./table/join'); const hasMany = require('./table/hasMany'); const hasOne = require('./table/hasOne'); const getMany = require('./table/getMany'); const count = require('./table/count'); const getManyDto = require('./table/getManyDto'); const getById = require('./table/getById'); const tryGetById = require('./table/tryGetById'); const tryGetFirst = require('./table/tryGetFirstFromDb'); const newCache = require('./table/newRowCache'); const newContext = require('./newObject'); const insert = require('./table/insert'); const _delete = require('./table/delete'); const cascadeDelete = require('./table/cascadeDelete'); const patchTable = require('./patchTable'); const newEmitEvent = require('./emitEvent'); const hostLocal = require('./hostLocal'); const getSessionSingleton = require('./table/getSessionSingleton'); const isJsonUpdateSupported = require('./table/isJsonUpdateSupported'); // const getTSDefinition = require('./getTSDefinition'); //todo: unused ? const where = require('./table/where'); const aggregate = require('./table/aggregate'); const groupBy = require('./table/groupBy'); function _new(tableName) { var table = newContext(); table._dbName = tableName; table._primaryColumns = []; table._aliases = new Set(); table._columns = []; table._columnDiscriminators = []; table._formulaDiscriminators = []; table._relations = {}; table._cache = newCache(table); table._emitChanged = newEmitEvent(); table.primaryColumn = function(columnName) { var columnDef = newColumn(table, columnName); columnDef.isPrimary = true; table._primaryColumns.push(columnDef); return column(columnDef, table); }; table.column = function(columnName) { var columnDef = newColumn(table, columnName); return column(columnDef, table); }; table.join = function(relatedTable) { return join(table, relatedTable); }; table.hasMany = function(joinRelation) { return hasMany(joinRelation); }; table.hasOne = function(joinRelation) { return hasOne(joinRelation); }; table.count = function(context, ...rest) { const args = [context, table, ...rest]; return Promise.resolve().then(() => count.apply(null, args)); }; table.getMany = function(context, ...rest) { const args = [context, table, ...rest]; return Promise.resolve().then(() => getMany.apply(null, args)); }; table.getManyDto = function(context, ...rest) { const args = [context, table, ...rest]; return Promise.resolve().then(() => getManyDto.apply(null, args)); }; table.aggregate = function(context, ...rest) { const args = [context, table, ...rest]; return groupBy.apply(null, args); }; table.distinct = function(context, ...rest) { const args = [context, table, ...rest, { distinct: true }]; return groupBy.apply(null, args); }; table.getMany.exclusive = function(context, ...rest) { const args = [context, table, ...rest]; return Promise.resolve().then(() => getMany.exclusive.apply(null, args)); }; table.tryGetFirst = function(context, ...rest) { const args = [context, table, ...rest]; return Promise.resolve().then(() => tryGetFirst.apply(null, args)); }; table.tryGetFirst.exclusive = function(context, ...rest) { const args = [context, table, ...rest]; return Promise.resolve().then(() => tryGetFirst.exclusive.apply(null, args)); }; table.getOne = table.tryGetFirst; table.getOne.exclusive = table.tryGetFirst.exclusive; table.getById = function(context, ...rest) { const args = [context, table, ...rest]; return Promise.resolve().then(() => getById.apply(null, args)); }; table.getById.exclusive = function(context, ...rest) { const args = [context, table, ...rest]; return Promise.resolve().then(() => getById.exclusive.apply(null, args)); }; table.tryGetById = function(context, ...rest) { const args = [context, table, ...rest]; return Promise.resolve().then(() => tryGetById.apply(null, args)); }; table.tryGetById.exclusive = function(context, ...rest) { const args = [context, table, ...rest]; return Promise.resolve().then(() => tryGetById.exclusive.apply(null, args)); }; table.columnDiscriminators = function() { for (var i = 0; i < arguments.length; i++) { table._columnDiscriminators.push(arguments[i]); } return table; }; table.formulaDiscriminators = function() { for (var i = 0; i < arguments.length; i++) { table._formulaDiscriminators.push(arguments[i]); } return table; }; table.insert = function(context, ...rest) { const concurrency = undefined; let args = [context, {table, concurrency}, ...rest]; return insert.apply(null, args); }; table.insertWithConcurrency = function(context, options, ...rows) { let args = [context, {table, options}].concat([].slice.call(rows)); return insert.apply(null, args); }; table.updateWithConcurrency = function(context, options, row, property, value, oldValue, patchInfo) { options = options || {}; const columnOptions = inferColumnOptions(options, property); const concurrency = columnOptions.concurrency || 'optimistic'; const column = table[property]; if (patchInfo && column && column.tsType === 'JSONColumn' && Array.isArray(patchInfo.path) && patchInfo.path.length > 1) { const engine = getSessionSingleton(context, 'engine'); if (isJsonUpdateSupported(engine)) { const jsonPath = patchInfo.path.slice(1); const jsonUpdateState = row._jsonUpdateState || {}; const columnState = jsonUpdateState[property] || { patches: [] }; columnState.patches.push({ path: jsonPath, op: patchInfo.op, value: patchInfo.value, oldValue: patchInfo.oldValue }); jsonUpdateState[property] = columnState; row._jsonUpdateState = jsonUpdateState; if (concurrency !== 'overwrite') { const state = row._concurrencyState || { columns: {} }; const columnConcurrency = state.columns[property] || {}; columnConcurrency.concurrency = concurrency; columnConcurrency.paths = columnConcurrency.paths || []; columnConcurrency.paths.push({ path: jsonPath, oldValue: patchInfo.oldValue }); delete columnConcurrency.oldValue; state.columns[property] = columnConcurrency; row._concurrencyState = state; } } else if (concurrency !== 'overwrite') { const state = row._concurrencyState || { columns: {} }; const fullOldValue = Object.prototype.hasOwnProperty.call(patchInfo, 'fullOldValue') ? patchInfo.fullOldValue : oldValue; state.columns[property] = { oldValue: fullOldValue, concurrency }; row._concurrencyState = state; } } else if (concurrency !== 'overwrite') { const state = row._concurrencyState || { columns: {} }; state.columns[property] = { oldValue, concurrency }; row._concurrencyState = state; } row[property] = value; }; table.delete = function(context, ...rest) { const args = [context, table, ...rest]; return _delete.apply(null, args); }; table.cascadeDelete = function(context, ...rest) { const args = [context, table, ...rest]; return cascadeDelete.apply(null, args); }; table.deleteCascade = table.cascadeDelete; table.exclusive = function() { table._exclusive = true; return table; }; table.patch = function(context, ...rest) { const args = [context, table, ...rest]; return patchTable.apply(null, args); }; // table.subscribeChanged = table._emitChanged.add; //legacy // table.unsubscribeChanged = table._emitChanged.remove; //legacy table.hostLocal = function(options) { return hostLocal({table, ...options}); }; // table.ts = function(name) { //unused ? // return getTSDefinition(table, {name}); // }; table.where = where(table); table._aggregate = aggregate(table); return table; } function inferColumnOptions(defaults, property) { const parent = {}; if (!defaults) return parent; if ('readonly' in defaults) parent.readonly = defaults.readonly; if ('concurrency' in defaults) parent.concurrency = defaults.concurrency; return { ...parent, ...(defaults[property] || {}) }; } module.exports = _new;