const Loader = require('../vendor/Loader') const db_crud = require('./crud') module.exports = function modelScope(type, db_model, _props) { const props = Object.assign({ hasOne: {}, afterCreate: () => {}, }, _props) const crud = db_crud(db_model) const model = { type: type, db_model: db_model, crud: crud, index: (query) => { return new Promise( (resolve, reject) => { crud.index(query).then( (data) => { if (! props.hasOne) { resolve(data ? data.toJSON() : []) } else { let recs = data.toJSON() const loader = new Loader () loader.onReady( () => { console.log(type, 'ready') resolve(recs) }) console.log('hasOne') loader.register('hasOne') Object.keys(props.hasOne).forEach( (key,i) => { loader.register(key) console.log('register', key) const type = props.hasOne[key] const id_lookup = {} recs.forEach(r => { const id = r[key + '_id'] id_lookup[id] = id_lookup[id] || [] id_lookup[id].push(r) }) // console.log('\n\n%%%%%%%%%%%%%%%%%%%%%%%% index > hasOne ' + key + '\n\n\n') // console.log(recs.length, Object.keys(id_lookup).length) db_crud(type).show_ids(Object.keys(id_lookup)).then( (sub_recs) => { // console.log(key, 'sub_recs', sub_recs) const short_key = key.replace('_id','') sub_recs.toJSON().forEach(rec => { id_lookup[rec.id].forEach( parent_rec => parent_rec[short_key] = rec ) }) console.log('ready', key) loader.ready(key) }) }) loader.ready('hasOne') } }) // }).catch( () => res.sendStatus(500) ) }) }, show: (id) => { return new Promise( (resolve, reject) => { crud.show(id).then( (data) => { if (! props.hasOne) { resolve(data.toJSON()) } else { let rec = data.toJSON() const loader = new Loader () loader.onReady( () => { resolve(rec) }) loader.register('hasOne') Object.keys(props.hasOne).forEach( (key,i) => { loader.register(key) const type = props.hasOne[key] db_crud(type).show(rec[key + '_id']).then( (sub_rec) => { rec[key] = sub_rec loader.ready(key) }) }) loader.ready('hasOne') } }) // .catch( (err) => res.sendStatus(500) ) }) }, findOrCreate: (data) => { return new Promise( (resolve, reject) => { let query = Object.assign({}, data) query.limit = 1 crud.index(query).then( (recs) => { if (recs && recs.length) { const rec = recs.at(0) console.log('found rec', data.name) return resolve(rec) } console.log('creating rec', data.name) model.create(data).then( (rec) => { resolve(rec) }) }) }) }, create: (data) => { return new Promise( (resolve, reject) => { crud.create( model.sanitize(data) ).then( (data) => { console.log('yooooooo') resolve(data.toJSON()) props.afterCreate && props.afterCreate(data) }).catch( (e) => { console.error('error creating', e) reject() }) }) }, update: (id, data) => { console.log('update', id) return new Promise( (resolve, reject) => { crud.update(id, model.sanitize(data)).then( (data) => { resolve(data.toJSON()) }).catch( (e) => { console.error('error updating', e) reject() }) }) }, destroy: (id) => { return new Promise( (resolve, reject) => { crud.destroy(id).then( (data) => { res.json(data.toJSON()) })// .catch( () => res.sendStatus(500) ) }) }, sanitize: (data) => { var valid = {} console.log('yooooooo') Object.keys(data).forEach(key => { console.log('yooooooo2', key) if (props.hasOne[key]) { return } console.log('yooooooo3') valid[key] = data[key] }) console.log('yooooooo4') console.log(valid) return valid }, } return model }