Created
December 2, 2021 14:47
-
-
Save molda/068ec2643b7f25790280a122239a68d2 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
/* | |
USAGE: | |
// bellow query is the same as | |
// SELECT appid FROM tbl_user_app WHERE userid IN (SELECT id FROM tbl_user WHERE email='$0'); | |
var ql = '{tbl_user(email)=>(id)|tbl_user_app(id>userid)=>[appid]}'; | |
var obj = parse(ql); | |
var data = { email: '[email protected]' }; | |
query(obj, data, function(err, result){ | |
console.log('RESULT', err, result); | |
}); | |
*/ | |
function parse(str) { | |
if (!str || str[0] !== '{') | |
return; | |
if (str.indexOf(';') > -1) | |
return console.log('Interpreter error: Illegal character ";"'); | |
str = str.substring(1, str.length - 1); | |
var cmd = str.split('|'); | |
if (!cmd || !cmd.length) | |
return; | |
var queries = []; | |
cmd.forEach(function(c, cmdindex){ | |
var pos = c.indexOf('=>'); | |
var obj = { map: {}, outmap: {} }; | |
if (pos < 0) { | |
obj.table = c; | |
} else { | |
obj.table = c.substring(0, pos); | |
obj.select = c.substring(pos + 2); | |
} | |
var index = obj.table.indexOf('('); | |
if (index > -1) { | |
var fields = obj.table.substring(index + 1, obj.table.length - 1); | |
obj.table = obj.table.substring(0, index); | |
if (fields[0] === '(') { | |
fields = fields.substring(1, fields.indexOf(')')); | |
} | |
fields = fields.split(',').trim(); | |
fields.forEach(function(f, i){ | |
if (f.indexOf('>') > -1) { | |
f = f.split('>'); | |
fields[i] = f[0]; | |
obj.map[f[0]] = f[1]; | |
} | |
}); | |
obj.queryfields = fields; | |
} | |
if (obj.select) { | |
if (obj.select[0] === '(') { | |
obj.select = obj.select.substring(1, obj.select.indexOf(')')); | |
} else if (obj.select[0] === '[') { | |
obj.select = obj.select.substring(1, obj.select.indexOf(']')); | |
obj.multi = true; | |
} | |
var tmp = []; | |
var split = obj.select.split(','); | |
split.forEach(function(f, i){ | |
f = f.split('>'); | |
if (f[1]) | |
obj.outmap[f[0]] = f[1]; | |
obj.value = f[1] || f[0]; | |
f = f[0]; | |
var index = f.indexOf('.'); | |
if (index > -1) | |
f = f.substring(0, index); | |
tmp.push(f); | |
}); | |
obj.select = tmp.join(','); | |
if (tmp.length !== 1 || cmdindex !== cmd.length - 1) | |
obj.value = false; | |
} | |
var query = 'SELECT {0} FROM {1}'.format(obj.select || '*', obj.table); | |
var qf = obj.queryfields; | |
if (qf && qf.length) { | |
query += ' WHERE '; | |
qf.forEach(function(f, index){ | |
if (index) | |
query += ' AND '; | |
query += '{0} = {{1}}'.format(obj.map[f] ? obj.map[f] : f, f); | |
}); | |
} | |
query += ';'; | |
if (!qf && !obj.multi) | |
qf = ['id']; | |
queries.push({ query: query, params: qf, multi: obj.multi, value: obj.value, map: Object.keys(obj.outmap).length ? obj.outmap : false }); | |
}); | |
return queries; | |
}; | |
function query(arr, data, callback) { | |
var queue = []; | |
var db = DBMS(); | |
var result; | |
data = [data]; | |
arr.forEach(function(q, index){ | |
queue.push(function(next){ | |
var paramsOk = true; | |
var data2 = data[index]; | |
q.params.forEach(function(p){ | |
var d = data2[p]; | |
if (d === undefined || d === null) | |
return (paramsOk = false); | |
var td = typeof(d); | |
if (td === 'string') | |
data2[p] = '\'' + d + '\''; | |
if (td === 'boolean') | |
data2[p] = d ? 'TRUE' : 'FALSE'; | |
}); | |
if (!paramsOk) | |
return callback('Data missing params'); | |
var q2 = q.query.arg(data2); | |
console.log('q2', q2); | |
db.query(q2).callback(function(err, response){ | |
if (err || !response) | |
return callback(err || response); | |
if (!q.multi) { | |
response = response[0]; | |
if (q.map) | |
response = remap(response, q.map); | |
// last query returns value rather then object with a key/value when only single prop is to be returned | |
if (q.value && arr.length === index + 1) { | |
if (q.value.indexOf('.') > -1) | |
response = U.get(response, q.value); | |
else | |
response = response[q.value]; | |
} | |
} else { | |
response.forEach(function(r, i){ | |
if (q.map) | |
response[i] = remap(r, q.map); | |
if (q.value && arr.length === index + 1) | |
response[i] = response[i][q.value]; | |
}); | |
} | |
data[index + 1] = response; | |
next(); | |
}); | |
}); | |
}); | |
queue.async(function(){ | |
callback(null, data[arr.length]); | |
}); | |
}; | |
function remap(obj, map) { | |
var tmp = {}; | |
Object.keys(map).forEach(function(key){ | |
tmp[map[key]] = key.indexOf('.') > -1 ? U.get(obj, key) : obj[key]; | |
}); | |
return tmp; | |
}; | |
ON('ready', function(){ | |
if (!global.DBMS) | |
throw new Error('Interpreter requires DBMS module!'); | |
}); | |
exports.query = query; | |
exports.parse = parse; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment