Skip to content

Instantly share code, notes, and snippets.

@sarahbkim
Last active October 30, 2017 22:54
Show Gist options
  • Save sarahbkim/55232ea24e4e97d1843e07a26231943e to your computer and use it in GitHub Desktop.
Save sarahbkim/55232ea24e4e97d1843e07a26231943e to your computer and use it in GitHub Desktop.
metaprogramming
const schema = [
{ klass: 'Places', validvalues: [ 'Chain', 'Category' ], validOperators: [ '$and', '$or' ] },
{ klass: 'Chain', validvalues: [], validOperators: ['$in', '$nin'] },
{ klass: 'Category', validvalues: [], validOperators: ['$in', '$nin'] }
]
function generateSubqueries(klass, validvalues) {
validvalues.forEach((subquery) => {
klass.prototype[`add${subquery}`] = function(operator, value) {
const klass = new this[subquery](operator, value)
this.value.push(klass)
}
klass.prototype[`add${subquery}`] = function(operator, value) {
const klass = new this[subquery](operator, value)
console.log("This should be deleted!!!", klass)
}
})
}
function makeFqueryClass(klassName, validOperators = [], validvalues= []) {
function valueToQuery(value) {
if (value.constructor.name === 'Fquery') {
return this.value.query()
}
if (value.constructor.name === 'Array') {
return value.map((op) => {
return op.query()
})
}
return value
}
function valueToJSON(value) {
if (value.constructor.name === 'Fquery') {
return value.toJSON()
}
if (value.constructor.name === 'Array') {
return value.map((op) => {
return op.toJSON()
})
}
return value
}
class FqueryKlass {
constructor(operator, value) {
// this.constructor.validate({ operator, value })
this.operator = operator
this.value = value || []
}
static klass() {
return klassName
}
static validvalues() {
return validvalues || []
}
static validOperators() {
return validOperators || []
}
static validate({ operator, value }) {
if (validOperators.length > 0 && validOperators.indexOf(operator) < 0) {
throw new Error(`Invalid operator, must be one of ${validOperators}`)
}
}
query() {
return {
[this.constructor.klass().toLowerCase()]: {
[this.operator]: valueToQuery(this.value)
}
}
}
toJSON() {
return {
klass: this.constructor.klass(),
operator: this.operator,
value: valueToJSON(this.value)
}
}
}
return FqueryKlass
}
class FqueryModule {
constructor(schemas = []) {
schemas.forEach((schema) => {
const { klass, validOperators, validvalues } = schema
this[klass] = makeFqueryClass(klass, validOperators)
generateSubqueries(this[klass], validvalues)
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment