Last active
August 10, 2022 12:32
-
-
Save kopiro/4f75505a0c89269cf83ec5eacf6bae76 to your computer and use it in GitHub Desktop.
Functional SQL: https://www.codewars.com/kata/545434090294935e7d0010ab
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
/* | |
Solution of: https://www.codewars.com/kata/545434090294935e7d0010ab | |
*/ | |
var query = function () { | |
var self = {}; | |
var tables = []; | |
var selector = null; | |
var whereClauses = []; | |
var havingClauses = []; | |
var order = []; | |
var group = []; | |
var selectorAll = function (row) { | |
return row; | |
}; | |
self.select = function (e) { | |
if (selector != null) throw new Error("Duplicate SELECT"); | |
selector = e || false; | |
return self; | |
}; | |
self.from = function () { | |
if (tables.length > 0) throw new Error("Duplicate FROM"); | |
tables = Array.from(arguments); | |
return self; | |
}; | |
self.where = function () { | |
whereClauses.push(Array.from(arguments)); | |
return self; | |
}; | |
self.having = function () { | |
havingClauses.push(Array.from(arguments)); | |
return self; | |
}; | |
self.orderBy = function () { | |
if (order.length > 0) throw new Error("Duplicate ORDERBY"); | |
order = Array.from(arguments); | |
return self; | |
}; | |
self.groupBy = function () { | |
if (group.length > 0) throw new Error("Duplicate GROUPBY"); | |
group = Array.from(arguments); | |
return self; | |
}; | |
self.execute = function () { | |
var tmpdata = []; | |
var gdata = []; | |
var data = []; | |
var t = 0; | |
// JOIN | |
if (tables.length > 1) { | |
tables.forEach(function () { | |
data.push([]); | |
}); | |
tables[0].forEach(function (row, i) { | |
for (t = 0; t < tables.length; t++) { | |
data[t].push(tables[t][i]); | |
} | |
}); | |
tmpdata = []; | |
(function traverseTable(D, t) { | |
if (D.length === 0) { | |
tmpdata.push(t.slice(0)); | |
} else { | |
for (var i = 0; i < D[0].length; i++) { | |
t.push(D[0][i]); | |
traverseTable(D.slice(1), t); | |
t.splice(-1, 1); | |
} | |
} | |
})(data, []); | |
data = []; | |
tmpdata.forEach(function (row, i) { | |
if ( | |
whereClauses.every(function (orWhereClauses) { | |
return orWhereClauses.some(function (whereClause) { | |
return whereClause(row); | |
}); | |
}) | |
) { | |
data.push(row); | |
} | |
}); | |
} else if (tables.length === 1) { | |
tables[0].forEach(function (row, i) { | |
if ( | |
whereClauses.every(function (orWhereClauses) { | |
return orWhereClauses.some(function (whereClause) { | |
return whereClause(row); | |
}); | |
}) | |
) { | |
data.push(row); | |
} | |
}); | |
} else { | |
data = []; | |
} | |
// Group | |
if (group.length > 0) { | |
var T = {}; | |
data.forEach(function (row) { | |
var t = T; | |
group.forEach(function (groupCallback) { | |
var k = groupCallback(row); | |
t[k] = t[k] || {}; | |
t = t[k]; | |
}); | |
t._data = t._data || []; | |
t._data.push(row); | |
}); | |
(function traverse(node, R) { | |
if (node._data != null) { | |
node._data.forEach(function (e) { | |
R.push(e); | |
}); | |
} else { | |
for (var k in node) { | |
k = /\d+/.test(k) ? Number(k) : k; | |
var row = [k, []]; | |
traverse(node[k], row[1]); | |
R.push(row); | |
} | |
} | |
})(T, gdata); | |
gdata.forEach(function (grow) { | |
if ( | |
havingClauses.every(function (orHavingClauses) { | |
return orHavingClauses.some(function (havingClause) { | |
return havingClause(grow); | |
}); | |
}) | |
) { | |
tmpdata.push(grow); | |
} | |
}); | |
data = tmpdata; | |
} | |
order.forEach(function (orderCallback) { | |
data = data.sort(orderCallback); | |
}); | |
return data.map(selector || selectorAll); | |
}; | |
return self; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment