Last active
November 8, 2017 14:53
-
-
Save Aracturat/4077e70292ffa995b37da78a35a1410b to your computer and use it in GitHub Desktop.
Function To SQL
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
import * as ts from 'typescript'; | |
class Test { | |
public ParamString: string; | |
public ParamInt: number; | |
public ParamString2: string; | |
} | |
class Collection<T> { | |
private selectQuery: (t: T) => any; | |
private whereQuery: (t: T) => boolean; | |
private orderByQuery: (t: T) => any; | |
public where(query: (t: T) => boolean): Collection<T> { | |
this.whereQuery = query; | |
return this; | |
} | |
public orderBy(query: (t: T) => any): Collection<T> { | |
this.orderByQuery = query; | |
return this; | |
} | |
public select(query: (t: T) => any): Collection<T> { | |
this.selectQuery = query; | |
return this; | |
} | |
public getSql(): string { | |
var selectString = this.queryToSql(this.selectQuery); | |
var whereString = this.queryToSql(this.whereQuery); | |
var orderByString = this.queryToSql(this.orderByQuery); | |
var ret = "SELECT\n" + selectString + "\nFROM Table e\n"; | |
if (whereString.length > 0) { | |
ret += "WHERE " + whereString +"\n"; | |
} | |
if (orderByString.length > 0) { | |
ret += "ORDER BY " + orderByString; | |
} | |
return ret; | |
} | |
private queryToSql(query: (t: T) => boolean): string { | |
if (query) { | |
let src = ts.createSourceFile("test.ts", query.toString(), ts.ScriptTarget.ES2016, false); | |
var expr = <ts.ExpressionStatement> src.statements[0]; | |
var arrFunc = <ts.ArrowFunction> expr.expression; | |
return this.toSql(arrFunc.body); | |
} | |
return ""; | |
} | |
private toSql(expr: ts.Node): string { | |
switch(expr.kind) { | |
case ts.SyntaxKind.PropertyAccessExpression: | |
var paExpr = <ts.PropertyAccessExpression> expr; | |
var idObject = <ts.Identifier> paExpr.expression; | |
return idObject.text + "." + paExpr.name.text; | |
case ts.SyntaxKind.ParenthesizedExpression: | |
var parExpr = <ts.ParenthesizedExpression> expr; | |
if (parExpr.expression.kind != ts.SyntaxKind.ObjectLiteralExpression) { | |
return "(" + this.toSql(parExpr.expression) + ")"; | |
} | |
else { | |
return this.toSql(parExpr.expression); | |
} | |
case ts.SyntaxKind.BinaryExpression: | |
var bExpr = <ts.BinaryExpression> expr; | |
var op = ""; | |
switch (bExpr.operatorToken.kind) { | |
case ts.SyntaxKind.EqualsEqualsToken: | |
op = "="; | |
break; | |
case ts.SyntaxKind.GreaterThanToken: | |
op = ">"; | |
break; | |
case ts.SyntaxKind.GreaterThanEqualsToken: | |
op = ">="; | |
break; | |
case ts.SyntaxKind.LessThanToken: | |
op = "<"; | |
break; | |
case ts.SyntaxKind.LessThanEqualsToken: | |
op = "<="; | |
break; | |
case ts.SyntaxKind.AmpersandAmpersandToken: | |
op = "and"; | |
break; | |
case ts.SyntaxKind.BarBarToken: | |
op = "or"; | |
break; | |
default: | |
op = "[UndefinedOperator]"; | |
} | |
return this.toSql(bExpr.left) + " " + op + " " + this.toSql(bExpr.right); | |
case ts.SyntaxKind.NumericLiteral: | |
var nlExpr = <ts.NumericLiteral> expr; | |
return nlExpr.text; | |
case ts.SyntaxKind.StringLiteral: | |
var slExpr = <ts.StringLiteral> expr; | |
return "'" + slExpr.text + "'"; | |
case ts.SyntaxKind.CallExpression: | |
var cExpr = <ts.CallExpression> expr; | |
if (cExpr.expression.kind == ts.SyntaxKind.PropertyAccessExpression) { | |
var cpaExpr = <ts.PropertyAccessExpression> cExpr.expression; | |
var funcName = ""; | |
var args = ""; | |
switch (cpaExpr.name.text) { | |
case "toUpperCase": | |
funcName = "UPPER"; | |
break; | |
case "toLowerCase": | |
funcName = "LOWER"; | |
break; | |
case "substring": | |
funcName = "SUBSTRING" | |
args = ", " + cExpr.arguments.map(e => this.toSql(e)).join(", "); | |
break; | |
default: | |
funcName = "[UndefinedFunction]"; | |
break; | |
} | |
return funcName + "(" + this.toSql(cpaExpr.expression) + args + ")"; | |
} | |
case ts.SyntaxKind.ObjectLiteralExpression: | |
var olExpr = <ts.ObjectLiteralExpression> expr; | |
return olExpr.properties.map(pr => { | |
switch (pr.kind) { | |
case ts.SyntaxKind.PropertyAssignment: | |
var prAs = <ts.PropertyAssignment> pr; | |
var prNameObject = <ts.Identifier> prAs.name; | |
return this.toSql(prAs.initializer) + " as " + prNameObject.text; | |
default: | |
return "[undefined]"; | |
} | |
}).join(",\n"); | |
default: | |
debugger; | |
return "[undefined]"; | |
} | |
} | |
} | |
/* | |
return | |
SELECT | |
e.ParamInt as IntParam, | |
UPPER(e.ParamString) as StringParam | |
FROM Table e | |
WHERE (LOWER(UPPER(e.ParamString)) = SUBSTRING(LOWER('3'), 0, 10) or e.ParamInt >= 4) and e.ParamString2 <= '2' | |
ORDER BY e.ParamInt | |
*/ | |
var result = new Collection<Test>() | |
.where(e => (e.ParamString.toUpperCase().toLowerCase() == "3".toLowerCase().substring(0, 10) || e.ParamInt >= 4) && e.ParamString2 <= "2") | |
.orderBy(e => e.ParamInt) | |
.select(e => <any> { | |
IntParam: e.ParamInt, | |
StringParam: e.ParamString.toUpperCase() | |
}) | |
.getSql(); | |
console.log(result); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment