/sqltraverse

Traverses Codeschool SQL AST

Primary LanguageJavaScriptOtherNOASSERTION

Overview | Features | Installation | Credits | Issues


Overview

SQLTraverse is AST (abstract syntax tree) walker. This allows you to move through the AST generated by the Codeschool sqlite-parser in a structured manner. If you've ever used Estraverse before it works in the exact same way (in fact we use Estraverse under the hood).

⬆️

Features

The following code will do a simple walk of the AST passed to it. We can take actions either when we enter the node or when we leave the node.

sqltraverse.traverse(ast, {
    enter: function (node, parent) {
        if (node.type == 'statement' || node.type == 'assignment')
            return sqltraverse.VisitorOption.Skip;
    },
    leave: function (node, parent) {
        if (node.type == 'literal')
          console.log(node.value);
    }
});

We can use this.skip, this.remove and this.break functions instead of using Skip, Remove and Break.

sqltraverse.traverse(ast, {
    enter: function (node) {
        this.break();
    }
});

And sqltraverse provides sqltraverse.replace function. When returning node from enter/leave, current node is replaced with it.

result = sqltraverse.replace(tree, {
    enter: function (node) {
        // Replace it with replaced.
        if (node.type === 'literal')
            return replaced;
    }
});

By passing visitor.keys mapping, we can extend sqltraverse traversing functionality.

// This tree contains a user-defined `TestExpression` node.
var tree = {
    type: 'TestExpression',

    // This 'argument' is the property containing the other **node**.
    argument: {
        type: 'literal',
        value: 20
    },

    // This 'extended' is the property not containing the other **node**.
    extended: true
};
sqltraverse.traverse(tree, {
    enter: function (node) { },

    // Extending the existing traversing rules.
    keys: {
        // TargetNodeName: [ 'keys', 'containing', 'the', 'other', '**node**' ]
        TestExpression: ['argument']
    }
});

By passing visitor.fallback option, we can control the behavior when encountering unknown nodes.

// This tree contains a user-defined `TestExpression` node.
var tree = {
    type: 'TestExpression',

    // This 'argument' is the property containing the other **node**.
    argument: {
        type: 'literal',
        value: 20
    },

    // This 'extended' is the property not containing the other **node**.
    extended: true
};
sqltraverse.traverse(tree, {
    enter: function (node) { },

    // Iterating the child **nodes** of unknown nodes.
    fallback: 'iteration'
});

When visitor.fallback is a function, we can determine which keys to visit on each node.

// This tree contains a user-defined `TestExpression` node.
var tree = {
    type: 'TestExpression',

    // This 'argument' is the property containing the other **node**.
    argument: {
        type: 'literal',
        value: 20
    },

    // This 'extended' is the property not containing the other **node**.
    extended: true
};
sqltraverse.traverse(tree, {
    enter: function (node) { },

    // Skip the `argument` property of each node
    fallback: function(node) {
        return Object.keys(node).filter(function(key) {
            return key !== 'argument';
        });
    }
});

⬆️

Installation

⬆️

Using this project

⬆️

Credits

jdrew1303

Copyright (c) 2016

Issues

  • Tests, tests and more tests.
  • Documentation currently under construction (The examples need to be worked through for SQL instead of JavaScript).
  • AST is currently in a state of flux for some node types. We also probably need a builder for these nodes (another project).
  • You need to pass in ast.statement and not just the raw ast given back from the parser. (This is an issue with the base node not having a type.)

⬆️