A simple compiler to tokenize, parse and generate SQL code, allowing edit dynamically the query.
Here is a simple usage. We'll use compile the following query:
import Compiler from 'sql-compiler';
/** 1. Parse string SQL to Abstract Syntax Tree */
const { value: ast } = Compiler.parser(
Compiler.tokenizer(
`SELECT
'Leonardo' as name,
'Dicaprio' as lastname
FROM
dual l`
)
);
/** 2. Manipulate the SQL, add new column. */
ast.value.columns.push({
type: 'NUMERIC',
value: '20',
alias: 'age',
});
/** 3. Generate the manipulated SQL. */
const code = Compiler.codeGenerator(ast);
console.log(code);
// STDOUT: SELECT 'Leonardo' AS name, 'Dicaprio' AS lastname, 20 AS age FROM dual l
SELECT
'Leonardo' as name,
'Dicaprio' as lastname
FROM
dual l
Split the SQL commands, reserved words, strings, concatenation
[
'SELECT',
'',
"'UUID'",
'||',
'chr(01)',
'',
"'CLIENT'",
'||',
'chr(01)',
'',
"'VERSION'",
'||',
'chr(01)',
'',
'FROM',
'clients',
];
Parse the tokens of previous step in abstract schema representation.
{
"type": "SELECT",
"value": {
"columns": [
{ "type": "STRING", "value": "Leonardo", "alias": "name" },
{ "type": "STRING", "value": "Dicaprio", "alias": "lastname" }
],
"from": { "type": "IDENTIFIER", "value": "dual", "alias": "l" }
}
}
Manipulate the tree representation of the last step (e.g. Add new column to the select)
{
"type": "SELECT",
"value": {
"columns": [
{ "type": "STRING", "value": "Leonardo", "alias": "name" },
{ "type": "STRING", "value": "Dicaprio", "alias": "lastname" },
{ "type": "NUMERIC", "value": "20", "alias": "age" }
],
"from": { "type": "IDENTIFIER", "value": "dual", "alias": "l" }
}
}
Generate the updated SQL code, using as reference the released tree of elements.
SELECT 'Leonardo' AS name, 'Dicaprio' AS lastname, 20 AS age FROM dual l