Skip to content

Instantly share code, notes, and snippets.

@joepie91

joepie91/.js Secret

Created March 29, 2020 23:04
Show Gist options
  • Save joepie91/92c99eefad2fb66f4228119669eb0b3a to your computer and use it in GitHub Desktop.
Save joepie91/92c99eefad2fb66f4228119669eb0b3a to your computer and use it in GitHub Desktop.
"use strict";
const util = require("util");
let { select, onlyColumns, where, withRelations, withDerived, column, through, inValues, sql, postProcess } = require("../operations");
function withOwner() {
return withRelations({ owner: "owner_id" });
}
// TODO: Allow specifying placeholders that can be filled in later, for truly reusable query builders (so that eg. query planning only needs to be done once, this could even use prepared statements under the hood)
let query = select("projects", [
onlyColumns([ "id", "name" ]),
where({
active: true,
visible: true,
primary_category_id: inValues([ 2, 3, 5, 7, 8 ])
}),
// FIXME: where pivot table entry exists for category in that list
withRelations({
primaryCategory: [
column("primary_category_id"),
withOwner()
],
categories: [
through({
table: "projects_categories",
localSide: "project_id",
remoteSide: "category_id",
query: [ // Optional extra clauses for the query on the pivot table, eg. for filtering entries
where({ adminApproved: true })
]
}),
withOwner()
],
owner: "owner_id"
}),
withDerived({
capitalizedName: sql("UPPER(name)"),
teamCount: sql("moderator_count + admin_count"),
nameDistance: (project) => wordDistanceAlgorithm(project.name, "someReferenceName") // NOTE: This could have returned a Promise!
}),
mapCase({ from: "snake", to: "camel" })
]);
console.log(util.inspect(query, { depth: null, colors: true }));
// FIXME: Pre-processing (eg. inverse case-mapping for inserted objects or WHERE clauses) - maybe pre-processing that subscribes to particular operations? Something along the lines of axios interceptors perhaps
// FIXME: `either`/`all` for OR/AND representation respectively?
// FIXME: I guess `withDerived` could be implemented externally, as something that (depending on value type) either a) adds a column selector or b) adds a post-processing hook
// FIXME: Aggregrates (GROUP BY)
// return db.execute(query);
/* Hypothetical `mapCase` implementation */
function mapObjectCase(object, from, to) {
return mapObject(object, (key, value) => {
return [
caseMapper(key, from, to),
value
];
});
}
function mapCase({ from, to }) {
return postProcess((results) => {
// NOTE: This could have returned a Promise!
return results.map((result) => mapObjectCase(result, from, to));
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment