-
-
Save joepie91/92c99eefad2fb66f4228119669eb0b3a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"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