Last active
October 30, 2017 22:54
-
-
Save sarahbkim/55232ea24e4e97d1843e07a26231943e to your computer and use it in GitHub Desktop.
metaprogramming
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
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