Skip to content

Instantly share code, notes, and snippets.

@joepie91

joepie91/.js Secret

Created April 1, 2020 21:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joepie91/692e12c595e64917ed7221dd4e1499c1 to your computer and use it in GitHub Desktop.
Save joepie91/692e12c595e64917ed7221dd4e1499c1 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: belongsTo({
column: "primary_category_id",
query: [ withOwner() ]
}),
categories: through([
has({ column: "projects_categories.project_id", query: [
// Optional extra clauses for the query on the pivot table, eg. for filtering entries
where({ adminApproved: true })
]}),
"category_id"
]),
// all user groups for a given project ID -> all memberships for the given user group IDs -> for each membership, the record referenced by the given user_id
users: through([ "user_groups.project_id", "membership.user_group_id", "user_id" ]),
// ... expands to ...
users: through([
has({ column: remoteColumn({ table: "user_groups", column: "project_id" }) }),
has({ column: remoteColumn({ table: "memberships", column: "user_group_id" }) }),
belongsTo({ column: column("user_id") }),
]),
owner: "owner_id",
// ... expands to
owner: belongsTo({ column: "owner_id" }),
releases: "releases.project_id",
// ... expands to ...
releases: has({ column: "releases.project_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