Skip to content

Instantly share code, notes, and snippets.

@alexandrebodin
Last active October 4, 2017 20:17
Show Gist options
  • Save alexandrebodin/93a8e4263aa1a20c92c4d2922782ffe7 to your computer and use it in GitHub Desktop.
Save alexandrebodin/93a8e4263aa1a20c92c4d2922782ffe7 to your computer and use it in GitHub Desktop.
addEntity to knex query with simplicity and clean code
var R = require('ramda');
var knex = require('knex')({
client: 'pg',
connection: {
host: 'localhost',
port: '35432',
database: 'vamos',
password: 'vamos',
user: 'vamos',
}
});
const withEntity = (qb, table, fk, alias = table) => qb.leftJoin(table, fk, `${table}.id`).select(knex.raw(`to_json(${table}) ${alias}`))
const queryWrapper = (query, resolver) => {
let mappings = {};
return {
query,
addContact(...path) {
if (mappings.contact) throw new Error('addContact called twice');
mappings.contact = path.length > 0 ? R.flatten(path) : ['contact'];
query.modify(withEntity, 'contact', 'beuz.contact_id')
return this;
},
addCompany(...path) {
if (mappings.company) throw new Error('addCompany called twice');
mappings.company = path.length > 0 ? R.flatten(path) : ['company'];
query.modify(withEntity, 'company', 'contact.company_id')
return this;
},
then(...args) {
return query
.map(row => {
const keys = Object.keys(mappings);
return keys.reduce((acc, key) => R.assocPath(mappings[key], row[key], acc), R.omit(keys, row));
})
.map(resolver)
.then(...args);
}
}
}
const contactR = contact => ({
id: contact.id,
firstname: contact.firstname,
lastname: contact.lastname,
company: contact.company
});
const resolver = beuz => ({
id: beuz.id,
contact: contactR(beuz.contact),
})
const db = {
getBeuz(filters, sqlParams) {
return queryWrapper(knex('beuz').select('beuz.id').where('beuz.id', 1), resolver);
},
}
const a = db.getBeuz({}, {})
.addContact()
.addCompany(['contact', 'company'])
.then(res => {
console.log(res);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment