The JayData JavaScript Language Query API makes heavy use of language expressions as the means of intercepting storage agnostic developer intention and translating it to storage specific query actions. During the long journey while this JavaScript Language Query expression
1 2 3 4 |
$news.Articles .filter(function(article) { return article.Author.Profile.Age > 21 } ) .map(function(article) { return { Title: article.Title, AuthorName: article.Author.Name} }) .forEach( render ); |
gets converted into this sqLite statement
1 2 3 4 5 |
SELECT T0.Title, T1.Name FROM Articles T0 LEFT OUTER JOIN Persons T1 ON T0.Author__ID = T1.ID LEFT OUTER JOIN Profiles T2 ON T1.Profile__ID = T2.ID WHERE T2.Age > 21 |
we use the CodeParser class all the way to transform JavaScript code into a more meaningful form: code expressions. Code expressions are effectively many content in a tree or graph that can be traversed (visited) and transformed on our likes.
To create code expression from actual JavaScript functions or simple strings you need an instance of the code parser class.
1 2 3 4 5 6 7 8 |
<script src="/JayData.js" type="text/javascript"></script> <script type="text/javascript"> var codeParser = new $data.Expressions.CodeParser(); </script> </head> <body> |
Passing code as a string
Simple constant expression.
1 2 |
var expression = codeParser.createExpression("'hello world'"); console.log(expression.getJSON()); |
result:
1 2 3 4 5 6 |
{ "expressionType": "ConstantExpression", "nodeType": "constant", "type": "string", "value": "hello world" } |
1 |
var expression = new $data.Expressions.ConstantExpression("hello world"); |
A simple binary expression
1 2 |
var expression = codeParser.createExpression("'apple' > 'orange'"); console.log(expression.getJSON()); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
{ "expressionType": "SimpleBinaryExpression", "nodeType": "greaterThan", "type": "boolean", "left": { "expressionType": "ConstantExpression", "nodeType": "constant", "type": "string", "value": "apple" }, "right": { "expressionType": "ConstantExpression", "nodeType": "constant", "type": "string", "value": "orange" }, "operator": ">" } var left = $data.Expressions.ConstantExpression("apple"); var right = $data.Expressions.ConstantExpression("orange"); var gt = $data.Expressions.SimpleBinaryExpression(left, right, ExpressionTypes.greaterThen); |
A more complex expression
1 2 |
var expression = codeParser.createExpression("'apple'.indexOf(['a','p'].join('')) == 0"); console.log(expression.getJSON()); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
{ "expressionType": "SimpleBinaryExpression", "nodeType": "equal", "type": "boolean", "left": { "expressionType": "CallExpression", "nodeType": "call", "expression": { "expressionType": "ConstantExpression", "nodeType": "constant", "type": "string", "value": "apple" }, "member": { "expressionType": "ConstantExpression", "nodeType": "constant", "type": "string", "value": "indexOf" }, "args": [ { "expressionType": "CallExpression", "nodeType": "call", "expression": { "expressionType": "ArrayLiteralExpression", "nodeType": "arrayLiteral", "items": [ { "expressionType": "ConstantExpression", "nodeType": "constant", "type": "string", "value": "a" }, { "expressionType": "ConstantExpression", "nodeType": "constant", "type": "string", "value": "p" } ] }, "member": { "expressionType": "ConstantExpression", "nodeType": "constant", "type": "string", "value": "join" }, "args": [ { "expressionType": "ConstantExpression", "nodeType": "constant", "type": "string", "value": "" } ] } ] }, "right": { "expressionType": "ConstantExpression", "nodeType": "constant", "type": "number", "value": 0 }, "operator": "==" } |
Passing code as a function
A simple true predicate
1 2 3 4 |
codeParser.createExpression(<span class="kwrd">function</span>() { <span class="kwrd">return</span> <span class="kwrd">true</span>; }).getJSON(); <span class="str">{ "</span>expressionType<span class="str">": "</span>FunctionExpression<span class="str">", "</span>nodeType<span class="str">": "</span>Function<span class="str">", "</span>parameters<span class="str">": [], "</span>body<span class="str">": { "</span>expressionType<span class="str">": "</span>ConstantExpression<span class="str">", "</span>nodeType<span class="str">": "</span>constant<span class="str">", "</span>type<span class="str">": "</span>boolean<span class="str">", "</span>value<span class="str">": "</span><span class="kwrd">true</span>" } } |
A filter predicate
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
codeParser.createExpression(<span class="kwrd">function</span>(article) { <span class="kwrd">return</span> article.Title == <span class="kwrd">this</span>.title }).getJSON(); { <span class="str">"expressionType"</span>: <span class="str">"FunctionExpression"</span>, <span class="str">"nodeType"</span>: <span class="str">"Function"</span>, <span class="str">"parameters"</span>: [ { <span class="str">"expressionType"</span>: <span class="str">"ParameterExpression"</span>, <span class="str">"nodeType"</span>: <span class="str">"lambdaParameter"</span>, <span class="str">"type"</span>: <span class="str">"unknown"</span>, <span class="str">"name"</span>: <span class="str">"article"</span> } ], <span class="str">"body"</span>: { <span class="str">"expressionType"</span>: <span class="str">"SimpleBinaryExpression"</span>, <span class="str">"nodeType"</span>: <span class="str">"equal"</span>, <span class="str">"type"</span>: <span class="str">"boolean"</span>, <span class="str">"left"</span>: { <span class="str">"expressionType"</span>: <span class="str">"PropertyExpression"</span>, <span class="str">"nodeType"</span>: <span class="str">"memberAccess"</span>, <span class="str">"expression"</span>: { <span class="str">"expressionType"</span>: <span class="str">"ParameterExpression"</span>, <span class="str">"nodeType"</span>: <span class="str">"lambdaParameterReference"</span>, <span class="str">"type"</span>: <span class="str">"unknown"</span>, <span class="str">"name"</span>: <span class="str">"article"</span>, <span class="str">"paramIndex"</span>: 0 }, <span class="str">"member"</span>: { <span class="str">"expressionType"</span>: <span class="str">"ConstantExpression"</span>, <span class="str">"nodeType"</span>: <span class="str">"constant"</span>, <span class="str">"type"</span>: <span class="str">"string"</span>, <span class="str">"value"</span>: <span class="str">"Title"</span> } }, <span class="str">"right"</span>: { <span class="str">"expressionType"</span>: <span class="str">"PropertyExpression"</span>, <span class="str">"nodeType"</span>: <span class="str">"memberAccess"</span>, <span class="str">"expression"</span>: { <span class="str">"expressionType"</span>: <span class="str">"ThisExpression"</span>, <span class="str">"nodeType"</span>: <span class="str">"this"</span> }, <span class="str">"member"</span>: { <span class="str">"expressionType"</span>: <span class="str">"ConstantExpression"</span>, <span class="str">"nodeType"</span>: <span class="str">"constant"</span>, <span class="str">"type"</span>: <span class="str">"string"</span>, <span class="str">"value"</span>: <span class="str">"title"</span> } }, <span class="str">"operator"</span>: <span class="str">"=="</span> } } |
A projection expression
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
codeParser.createExpression(<span class="kwrd">function</span>(article) { <span class="kwrd">return</span> { Title: article.Title, Author: article.Author.Name } }).getJSON(); { <span class="str">"expressionType"</span>: <span class="str">"FunctionExpression"</span>, <span class="str">"nodeType"</span>: <span class="str">"Function"</span>, <span class="str">"parameters"</span>: [ { <span class="str">"expressionType"</span>: <span class="str">"ParameterExpression"</span>, <span class="str">"nodeType"</span>: <span class="str">"lambdaParameter"</span>, <span class="str">"type"</span>: <span class="str">"unknown"</span>, <span class="str">"name"</span>: <span class="str">"article"</span> } ], <span class="str">"body"</span>: { <span class="str">"expressionType"</span>: <span class="str">"ObjectLiteralExpression"</span>, <span class="str">"nodeType"</span>: <span class="str">"objectLiteral"</span>, <span class="str">"members"</span>: [ { <span class="str">"expressionType"</span>: <span class="str">"ObjectFieldExpression"</span>, <span class="str">"nodeType"</span>: <span class="str">"objectField"</span>, <span class="str">"fieldName"</span>: <span class="str">"Title"</span>, <span class="str">"expression"</span>: { <span class="str">"expressionType"</span>: <span class="str">"PropertyExpression"</span>, <span class="str">"nodeType"</span>: <span class="str">"memberAccess"</span>, <span class="str">"expression"</span>: { <span class="str">"expressionType"</span>: <span class="str">"ParameterExpression"</span>, <span class="str">"nodeType"</span>: <span class="str">"lambdaParameterReference"</span>, <span class="str">"type"</span>: <span class="str">"unknown"</span>, <span class="str">"name"</span>: <span class="str">"article"</span>, <span class="str">"paramIndex"</span>: 0 }, <span class="str">"member"</span>: { <span class="str">"expressionType"</span>: <span class="str">"ConstantExpression"</span>, <span class="str">"nodeType"</span>: <span class="str">"constant"</span>, <span class="str">"type"</span>: <span class="str">"string"</span>, <span class="str">"value"</span>: <span class="str">"Title"</span> } } }, { <span class="str">"expressionType"</span>: <span class="str">"ObjectFieldExpression"</span>, <span class="str">"nodeType"</span>: <span class="str">"objectField"</span>, <span class="str">"fieldName"</span>: <span class="str">"Author"</span>, <span class="str">"expression"</span>: { <span class="str">"expressionType"</span>: <span class="str">"PropertyExpression"</span>, <span class="str">"nodeType"</span>: <span class="str">"memberAccess"</span>, <span class="str">"expression"</span>: { <span class="str">"expressionType"</span>: <span class="str">"PropertyExpression"</span>, <span class="str">"nodeType"</span>: <span class="str">"memberAccess"</span>, <span class="str">"expression"</span>: { <span class="str">"expressionType"</span>: <span class="str">"ParameterExpression"</span>, <span class="str">"nodeType"</span>: <span class="str">"lambdaParameterReference"</span>, <span class="str">"type"</span>: <span class="str">"unknown"</span>, <span class="str">"name"</span>: <span class="str">"article"</span>, <span class="str">"paramIndex"</span>: 0 }, <span class="str">"member"</span>: { <span class="str">"expressionType"</span>: <span class="str">"ConstantExpression"</span>, <span class="str">"nodeType"</span>: <span class="str">"constant"</span>, <span class="str">"type"</span>: <span class="str">"string"</span>, <span class="str">"value"</span>: <span class="str">"Author"</span> } }, <span class="str">"member"</span>: { <span class="str">"expressionType"</span>: <span class="str">"ConstantExpression"</span>, <span class="str">"nodeType"</span>: <span class="str">"constant"</span>, <span class="str">"type"</span>: <span class="str">"string"</span>, <span class="str">"value"</span>: <span class="str">"Name"</span> } } } ] } } |