UNPKG

tabel

Version:

A simple orm for PostgreSQL which works with simple javascript objects and arrays

140 lines (111 loc) 3.54 kB
const {assign} = require('lodash'); const isUsableObject = require('isusableobject'); const Relation = require('./Relation'); class BelongsTo extends Relation { constructor(ownerTable, toTable, foreignKey, otherKey) { super(ownerTable); assign(this, {fromTable: ownerTable.fork(), toTable, foreignKey, otherKey}); } initRelation(fromModels=[]) { return fromModels.map((model) => assign(model, {[this.relationName]: null})); } getRelated(...args) { if (args.length === 0) { if (this.activeModel !== null) { return this.getRelated([this.activeModel]).then(([relatedModel]) => relatedModel); } else { return Promise.resolve(null); } } const [fromModels] = args; if (fromModels.length === 0) { return Promise.resolve([]); } else { const foreignKeys = fromModels.filter((m) => !!m).map((m) => m[this.foreignKey]); return this.constraints.apply(this.toTable.fork()) .whereIn(this.otherKey, foreignKeys) .all() ; } } matchModels(fromModels=[], relatedModels=[]) { const keyDict = relatedModels.reduce( (dict, m) => assign(dict, {[m[this.otherKey]]: m}), {} ); return fromModels.map((m) => assign(m, { [this.relationName]: isUsableObject(keyDict[m[this.foreignKey]]) ? keyDict[m[this.foreignKey]] : null })); } associate(...args) { if (args.length === 0) { throw new Error('bad method call'); } if (args.length === 1) { return this.associate(this.activeModel, ...args); } const [fromModel, toModel] = args; return this.fromTable.whereKey(fromModel).update({ [this.foreignKey]: toModel[this.otherKey] }); } dissociate(...args) { if (args.length === 0) { return this.dissociate(this.activeModel); } const [fromModel] = args; return this.fromTable.whereKey(fromModel).update({ [this.foreignKey]: null }); } update(...args) { if (args.length === 0) { throw new Error('bad method call'); } if (args.length === 1) { return this.update(this.activeModel, ...args); } const [fromModel, values] = args; return this.constraints.apply(this.toTable.fork()) .where(this.otherKey, fromModel[this.foreignKey]) .update(values); } del(...args) { if (args.length === 0) { return this.del(this.activeModel); } const [fromModel] = args; return this.constraints.apply(this.toTable.fork()) .where(this.otherKey, fromModel[this.foreignKey]) .del(); } join(joiner=(() => {}), label=null) { label = this.jointLabel(label, {}); const {fromTable, toTable, foreignKey, otherKey} = this; if (this.ownerTable.scopeTrack.hasJoint(label)) { return this.ownerTable; } else { return this.ownerTable.joint((q) => { q.join(toTable.tableName(), (j) => { j.on(fromTable.c(foreignKey), '=', toTable.c(otherKey)); joiner(j); }); }, label); } } leftJoin(joiner=(() => {}), label=null) { label = this.jointLabel(label, {isLeftJoin: true}); const {fromTable, toTable, foreignKey, otherKey} = this; if (this.ownerTable.scopeTrack.hasJoint(label)) { return this.ownerTable; } else { return this.ownerTable.joint((q) => { q.leftJoin(toTable.tableName(), (j) => { j.on(fromTable.c(foreignKey), '=', toTable.c(otherKey)); joiner(j); }); }, label); } } } module.exports = BelongsTo;