Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/rxm.git
README.md
# Overview
-Relational eXpression Map (**rxm**) is a terse database query language that
-decouples structured document formats from SQL statements.
+Relational eXpression Map (**rxm**) is a database- and output-agnostic query
+language for generating structured documents.
# Requirements
run.sh
#!/bin/bash
-java -Drxm_beautify=true -jar build/libs/rxm.jar $1
-#java -jar build/libs/rxm.jar $1
+java -Dbeautify=true -jar build/libs/rxm.jar $1
source/grammar/Query.g
expression : exprEquality | exprLogicalAnd ;
-exprLogicalAnd: exprLogicalOr (T_LOGIC_AND exprLogicalOr)* ;
-exprLogicalOr : exprRelational (T_LOGIC_OR exprRelational)* ;
+exprLogicalAnd: exprLogicalOr (exprAnd exprLogicalOr)* ;
+exprLogicalOr : exprRelational (exprOr exprRelational)* ;
exprRelational: exprEquality | exprCompRel ;
exprEquality : exprParen | exprCompEqual ;
exprParen : T_EXPR_OPEN expression T_EXPR_CLOSE ;
+
+exprAnd : T_LOGIC_AND ;
+exprOr : T_LOGIC_OR ;
exprCompRel : tableColumn (T_LT | T_GT | T_LTE | T_GTE) exprValue ;
-exprCompEqual : tableColumn (T_EQ | T_INEQ) exprValueOrSet ;
+exprCompEqual : tableColumn (T_EQ | T_INEQ) (exprValue | exprSet) ;
exprValue : exprParameter | literal ;
-exprValueOrSet: exprValue | exprSet ;
-exprSet : T_EXPR_SET_OPEN exprList T_EXPR_SET_CLOSE ;
-exprList : exprValue (T_COMMA exprValue)* ;
exprParameter : T_EXPR_PARAMETER T_ID ;
literal : T_NULL | T_STRING | T_FLOAT ;
+
+exprSet : T_EXPR_SET_OPEN exprList T_EXPR_SET_CLOSE ;
+exprList : exprValue (T_COMMA exprValue)* ;
source/java/com/whitemagicsoftware/rxm/QueryBuilder.java
import com.whitemagicsoftware.rxm.tree.xml.SelectClauseTree;
import com.whitemagicsoftware.rxm.tree.xml.JoinClauseList;
-import com.whitemagicsoftware.rxm.tree.xml.WhereClauseList;
+import com.whitemagicsoftware.rxm.tree.xml.WhereClause;
import org.antlr.v4.runtime.ANTLRInputStream;
private Tree<Payload> joinClauseList;
- /** List of where clause expressions (tree used as flat hierarchy). */
- private Tree<Payload> whereClauseList;
+ private WhereClause whereClause = new WhereClause();
/**
}
+ @Override
public synchronized void enterWhere( QueryParser.WhereContext ctx ) {
- addWhereClause( ctx );
+ getWhereClause().enterWhere( ctx );
+ }
+
+ @Override
+ public void exitExprOr( QueryParser.ExprOrContext ctx ) {
+ getWhereClause().exitExprOr( ctx );
+ }
+
+ @Override
+ public void exitExprAnd( QueryParser.ExprAndContext ctx ) {
+ getWhereClause().exitExprAnd( ctx );
+ }
+
+ @Override
+ public synchronized void enterExprParen( QueryParser.ExprParenContext ctx ) {
+ getWhereClause().enterExprParen( ctx );
+ }
+
+ @Override
+ public synchronized void exitExprParen( QueryParser.ExprParenContext ctx ) {
+ getWhereClause().exitExprParen( ctx );
+ }
+
+ @Override
+ public synchronized void enterExprCompRel(
+ QueryParser.ExprCompRelContext ctx ) {
+ getWhereClause().enterExprCompRel( ctx );
+ }
+
+ @Override
+ public synchronized void enterExprCompEqual(
+ QueryParser.ExprCompEqualContext ctx ) {
+ getWhereClause().enterExprCompEqual( ctx );
}
String from = getFromClause();
String join = getJoinClause();
- String where = getWhereClause();
- System.out.printf( "%s%s%s%s",
- select, from, join, where );
+ String where = getWhereClause().toString();
+
+ System.out.printf( "%s%s%s%s", select, from, join, where );
}
*/
private String getFromClause() {
- return "FROM person person";
+ return "FROM person person ";
}
*
* @return The WHERE portion of a SQL statement.
- */
- private String getWhereClause() {
- return getWhereClauseList().toString();
- }
-
- /**
- * Adds a new leaf, representing a JOIN clause, to the from clause list.
- *
- * @param ctx The INNER/OUTER JOIN expression to add to the list.
*/
- private void addWhereClause( ParserRuleContext ctx ) {
- getWhereClauseList().addLeaf( createWhereClauseList( ctx ) );
+ private WhereClause getWhereClause() {
+ return this.whereClause;
}
private Tree<Payload> createJoinClauseList( ParserRuleContext ctx ) {
return new JoinClauseList<Payload>( new Payload( ctx ) );
- }
-
- /**
- * Changes where the next mapped items will be attached.
- */
- private void setWhereClauseList( Tree<Payload> whereClauseList ) {
- this.whereClauseList = whereClauseList;
- }
-
- /**
- * Lazily-initializes the from clause list.
- *
- * @return The list that will contain the query's FROM clause.
- */
- private Tree<Payload> getWhereClauseList() {
- Tree<Payload> list = this.whereClauseList;
-
- if( list == null ) {
- setWhereClauseList( list = createWhereClauseList( null ) );
- }
-
- return list;
- }
-
- /**
- * Creates a new WhereClauseList instance containing the given parser
- * rule context. The resulting tree should only have leaves added
- * to the root, never branching beyond a flat hierarchy (one-level deep).
- *
- * @return A new WhereClauseList instance, never null, containing a payload
- * with the parser rule context.
- */
- private Tree<Payload> createWhereClauseList( ParserRuleContext ctx ) {
- return new WhereClauseList<Payload>( new Payload( ctx ) );
}
}
source/java/com/whitemagicsoftware/rxm/tree/TransformationTree.java
*/
protected boolean beautify() {
- return Boolean.getBoolean( "rxm_beautify" );
+ // Returns the System property value.
+ return Boolean.getBoolean( "beautify" );
}
* Used by subclasses to beautify the leading SQL clause (e.g., SELECT,
* FROM, WHERE).
+ *
+ * @param spaces The number of spaces to include in the result.
+ * @return A non-null string with 'spaces' amount of space.
*/
protected String getWhitespace( int spaces ) {
return beautify() ? getNewline() + getIndent( spaces ) : " ";
}
/**
* Helper method.
+ *
+ * @return A non-null string with the default amount of space.
*/
protected String getWhitespace() {
source/java/com/whitemagicsoftware/rxm/tree/xml/WhereClause.java
+package com.whitemagicsoftware.rxm.tree.xml;
+
+import com.whitemagicsoftware.rxm.grammar.QueryBaseListener;
+import com.whitemagicsoftware.rxm.grammar.QueryParser;
+
+import org.antlr.v4.runtime.tree.TerminalNode;
+
+/**
+ */
+public class WhereClause {
+ private StringBuilder buffer = new StringBuilder( 2048 );
+
+ /**
+ */
+ public WhereClause() {
+ }
+
+ /**
+ * Appends "<code>WHERE </code>" to the output.
+ *
+ * @param ctx The WHERE expression context (unused).
+ */
+ public void enterWhere( QueryParser.WhereContext ctx ) {
+ append( "WHERE " );
+ }
+
+ /**
+ * Appends "<code> AND </code>" to the output.
+ *
+ * @param ctx The AND expression context (unused).
+ */
+ public void exitExprAnd( QueryParser.ExprAndContext ctx ) {
+ append( " AND " );
+ }
+
+ /**
+ * Appends "<code> OR </code>" to the output.
+ *
+ * @param ctx The OR expression context (unused).
+ */
+ public void exitExprOr( QueryParser.ExprOrContext ctx ) {
+ append( " OR " );
+ }
+
+ /**
+ * Appends "<code>(</code>" to the output.
+ *
+ * @param ctx The parenthesis expression context (unused).
+ */
+ public void enterExprParen( QueryParser.ExprParenContext ctx ) {
+ append( "(" );
+ }
+
+ /**
+ * Appends "<code>)</code>" to the output.
+ *
+ * @param ctx The parenthesis expression context (unused).
+ */
+ public void exitExprParen( QueryParser.ExprParenContext ctx ) {
+ append( ")" );
+ }
+
+ /**
+ * Transforms an <b>rxm</b> equality comparator into ANSI SQL.
+ * Note: There is probably a cleaner way to implement this monstrosity.
+ *
+ * @param ctx The equality comparison context.
+ */
+ public void enterExprCompEqual( QueryParser.ExprCompEqualContext ctx ) {
+ QueryParser.TableColumnContext tableColumn = ctx.tableColumn();
+ QueryParser.ExprSetContext set = ctx.exprSet();
+ QueryParser.ExprValueContext value = ctx.exprValue();
+
+ // If the terminal node is null, then the equality is T_INEQ.
+ TerminalNode equal = ctx.getToken( QueryParser.T_EQ, 0 );
+
+ String entity = tableColumn.getText();
+ String result = "";
+
+ if( set == null ) {
+ // Presume = or <> by default (could change to IS or IS NOT).
+ String comparator = ctx.getChild(1).getText();
+
+ QueryParser.LiteralContext literal = value.literal();
+
+ if( literal == null ) {
+ result = ctx.getText();
+ }
+ else {
+ // Default is to presume the value literal is not the 'null' token.
+ String rhs = literal.getText();
+
+ // If the "null" literal terminal node is not null, then null has
+ // been found and so the value must be switched to NULL and the
+ // comparators likewise revised.
+ if( literal.T_NULL() != null ) {
+ rhs = "NULL";
+ comparator = " IS " + (equal == null ? "NOT " : "");
+ }
+
+ result = String.format( "%s%s%s", entity, comparator, rhs );
+ }
+ }
+ else {
+ result = String.format( "%s %sIN (%s)",
+ entity,
+ equal == null ? "NOT " : "",
+ set.exprList().getText() );
+ }
+
+ append( result );
+ }
+
+ /**
+ * Appends a relational expression (less than, greater than, etc.) to the
+ * output.
+ *
+ * @param ctx The relational expression context.
+ */
+ public void enterExprCompRel( QueryParser.ExprCompRelContext ctx ) {
+ append( ctx.getText() );
+ }
+
+ /**
+ * Appends a given string to the buffer.
+ *
+ * @param s The string to append.
+ */
+ private void append( String s ) {
+ getBuffer().append( s );
+ }
+
+ /**
+ * Returns the buffer used for building the transformed output.
+ *
+ * @return A non-null string builder, possibly empty.
+ */
+ private StringBuilder getBuffer() {
+ return this.buffer;
+ }
+
+ /**
+ * Returns the buffer converted to a string. This is the result of
+ * the transformed output and should only be called when the parsing
+ * of the <b>rxm</b> source is complete.
+ *
+ * @return A non-null string, possibly empty.
+ */
+ public String toString() {
+ return getBuffer().toString();
+ }
+}
+
source/java/com/whitemagicsoftware/rxm/tree/xml/WhereClauseList.java
-package com.whitemagicsoftware.rxm.tree.xml;
-
-import com.whitemagicsoftware.rxm.tree.Payload;
-
-import org.antlr.v4.runtime.Token;
-
-/**
- * <p>
- * Stores a list of Payload instances. This is instantiated by the parser
- * to create a transformation list capable of generating SQL/XML WHERE
- * expressions. The payload dynamically determines the set of wrapper classes
- * using the package for name of class.
- * </p>
- * <p>
- * The tree is being re-used as a list. (A list is simply a tree with
- * one branch and many siblings.)
- * </p>
- */
-public class WhereClauseList<T extends Payload> extends JoinClauseList<T> {
- /**
- * Constructs a list capable of transforming itself into a SQL/XML
- * FROM clause.
- *
- * @param payload The data associated with this list (must not be null).
- */
- public WhereClauseList( T payload ) {
- super( payload );
- }
-
- public String toString() {
- String w = getWhitespace(0);
- return getBranches().size() > 0 ?
- String.format( "%sWHERE%s%s", w, getWhitespace(), super.toString() ) :
- "";
- }
-}
-
source/java/com/whitemagicsoftware/rxm/tree/xml/WhereContext.java
@Override
public Token getStart() {
- QueryParser.ExpressionContext expression = expression();
-
- return new Token( expression.getText() );
+ return new Token( "" );
}

Added delegation methods to create the ANSI SQL WHERE clause.

Author Dave Jarvis <email>
Date 2015-03-16 18:54:37 GMT-0700
Commit 390c452899a460e886ae3dd606e1f3b31c02d9e2
Parent 50e194b
Delta 215 lines added, 104 lines removed, 111-line increase