22
33import com .fasterxml .jackson .databind .JsonNode ;
44import io .github .mnesimiyilmaz .sql4json .condition .ConditionProcessor ;
5- import io .github .mnesimiyilmaz .sql4json .condition .CriteriaNode ;
65import io .github .mnesimiyilmaz .sql4json .definitions .JsonColumnWithNonAggFunctionDefinion ;
76import io .github .mnesimiyilmaz .sql4json .definitions .OrderByColumnDefinion ;
87import io .github .mnesimiyilmaz .sql4json .definitions .SelectColumnDefinition ;
9- import io .github .mnesimiyilmaz .sql4json .grouping .GroupByInput ;
10- import io .github .mnesimiyilmaz .sql4json .grouping .GroupByProcessor ;
11- import io .github .mnesimiyilmaz .sql4json .sorting .SortProcessor ;
12- import io .github .mnesimiyilmaz .sql4json .utils .FieldKey ;
13- import io .github .mnesimiyilmaz .sql4json .utils .JsonUtils ;
8+ import io .github .mnesimiyilmaz .sql4json .generated .SQL4JsonParser ;
9+ import io .github .mnesimiyilmaz .sql4json .processor .SQLBuilder ;
10+ import io .github .mnesimiyilmaz .sql4json .processor .SQLProcessor ;
1411import io .github .mnesimiyilmaz .sql4json .generated .SQL4JsonBaseListener ;
12+ import org .antlr .v4 .runtime .tree .ParseTree ;
1513
1614import java .util .*;
17- import java .util .function .Function ;
18- import java .util .stream .Collectors ;
1915
2016/**
2117 * @author mnesimiyilmaz
2218 */
2319class SQL4JsonListenerImpl extends SQL4JsonBaseListener {
2420
2521 private final List <SelectColumnDefinition > selectedColumns ;
26-
27- private JsonNode dataNode ;
28- private List <Map <FieldKey , Object >> flattenedData ;
29- private CriteriaNode whereClause ;
30- private List <JsonColumnWithNonAggFunctionDefinion > groupByColumns ;
31- private CriteriaNode havingClause ;
32- private List <OrderByColumnDefinion > orderByColumns ;
22+ private final JsonNode dataNode ;
23+ private final SQLProcessor sqlProcessor ;
24+ private String rootPath ;
3325
3426 public SQL4JsonListenerImpl (JsonNode jsonNode ) {
3527 this .dataNode = jsonNode ;
28+ this .sqlProcessor = new SQLProcessor ();
3629 this .selectedColumns = new ArrayList <>();
3730 }
3831
3932 @ Override
4033 public void enterRootNode (io .github .mnesimiyilmaz .sql4json .generated .SQL4JsonParser .RootNodeContext ctx ) {
41- String rootPath = ctx .getText ();
42- if (rootPath .equalsIgnoreCase ("$r" )) {
43- rootPath = "" ;
44- } else {
45- rootPath = rootPath .substring (3 );
34+ String path = ctx .getText ();
35+ if (path .startsWith ("$r" )){
36+ this .rootPath = path .equalsIgnoreCase ("$r" ) ? "" : path .substring (3 );
4637 }
47- this . dataNode = JsonUtils . peelJsonNode ( dataNode , rootPath );
48- this . flattenedData = JsonUtils . convertJsonToFlattenedListOfKeyValue ( dataNode );
38+ getBuilder ( ctx ). setSelectedColumns ( new ArrayList <>( selectedColumns ) );
39+ selectedColumns . clear ( );
4940 }
5041
5142 @ Override
@@ -62,88 +53,39 @@ public void enterSelectedColumns(io.github.mnesimiyilmaz.sql4json.generated.SQL4
6253
6354 @ Override
6455 public void enterWhereConditions (io .github .mnesimiyilmaz .sql4json .generated .SQL4JsonParser .WhereConditionsContext ctx ) {
65- this . whereClause = new ConditionProcessor (ctx .conditions ()).process ();
56+ getBuilder ( ctx ). setWhereClause ( new ConditionProcessor (ctx .conditions ()).process () );
6657 }
6758
6859 @ Override
6960 public void enterHavingConditions (io .github .mnesimiyilmaz .sql4json .generated .SQL4JsonParser .HavingConditionsContext ctx ) {
70- this . havingClause = new ConditionProcessor (ctx .conditions ()).process ();
61+ getBuilder ( ctx ). setHavingClause ( new ConditionProcessor (ctx .conditions ()).process () );
7162 }
7263
7364 @ Override
7465 public void enterGroupByColumn (io .github .mnesimiyilmaz .sql4json .generated .SQL4JsonParser .GroupByColumnContext ctx ) {
75- if (this .groupByColumns == null ) {
76- this .groupByColumns = new ArrayList <>();
77- }
78- this .groupByColumns .add (new JsonColumnWithNonAggFunctionDefinion (ctx .jsonColumnWithNonAggFunction ()));
66+ getBuilder (ctx ).addGroupByColumn (new JsonColumnWithNonAggFunctionDefinion (ctx .jsonColumnWithNonAggFunction ()));
7967 }
8068
8169 @ Override
8270 public void enterOrderByColumn (io .github .mnesimiyilmaz .sql4json .generated .SQL4JsonParser .OrderByColumnContext ctx ) {
83- if (this .orderByColumns == null ) {
84- this .orderByColumns = new ArrayList <>();
85- }
86- this .orderByColumns .add (new OrderByColumnDefinion (ctx ));
71+ getBuilder (ctx ).addOrderByColumn (new OrderByColumnDefinion (ctx ));
8772 }
8873
89- public JsonNode getResult () {
90- if (whereClause != null ) {
91- this .flattenedData .removeIf (x -> !whereClause .test (x ));
92- }
93- if (groupByColumns != null ) {
94- this .flattenedData = new GroupByProcessor (new GroupByInput (
95- flattenedData , selectedColumns , groupByColumns , havingClause )).process ();
96- }
97- if (orderByColumns != null ) {
98- flattenedData .sort (new SortProcessor (flattenedData , orderByColumns ).buildComparator ());
99- }
100- if (groupByColumns == null && !selectedColumns .get (0 ).isAsterisk ()) {
101- flattenedData = flattenedData .stream ().map (this ::getSelectedRowData ).collect (Collectors .toList ());
102- }
103- return JsonUtils .convertStructuredMapToJsonNode (
104- flattenedData .stream ().map (JsonUtils ::convertFlatMapToStructuredMap ).collect (Collectors .toList ()));
74+ public JsonNode getResult (){
75+ return sqlProcessor .process (dataNode , rootPath );
10576 }
10677
107- private Map <FieldKey , Object > getSelectedRowData (Map <FieldKey , Object > row ) {
108- Map <FieldKey , Object > result = new HashMap <>();
109- for (SelectColumnDefinition selectedColumn : selectedColumns ) {
110- FieldKey fieldKey = FieldKey .of (selectedColumn .getColumnDefinition ().getColumnDefinition ().getColumnName ());
111- if (isObjectField (row , fieldKey .getKey ())) {
112- result .putAll (getObjectFieldValues (row , fieldKey .getKey (), selectedColumn .getAlias ()));
113- } else {
114- Object value = row .get (fieldKey );
115- Optional <Function <Object , Object >> decorator = selectedColumn .getColumnDefinition ().getColumnDefinition ().getValueDecorator ();
116- if (decorator .isPresent ()) {
117- value = decorator .get ().apply (value );
118- }
119- if (selectedColumn .getAlias () != null ) {
120- result .put (FieldKey .of (selectedColumn .getAlias ()), value );
121- } else {
122- result .put (fieldKey , value );
123- }
124- }
125- }
126- return result ;
78+ private SQLBuilder getBuilder (ParseTree tree ){
79+ return sqlProcessor .getBuilder (sql4JsonContextNameOf (tree ));
12780 }
12881
129- private boolean isObjectField (Map <FieldKey , Object > row , String selectPath ) {
130- return row .keySet ().stream ().filter (x -> x .getKey ().startsWith (selectPath )).count () > 1L ;
131- }
82+ private static String sql4JsonContextNameOf (ParseTree tree ){
83+ ParseTree parent = tree .getParent ();
13284
133- private Map <FieldKey , Object > getObjectFieldValues (Map <FieldKey , Object > row , String selectPath , String alias ) {
134- if (alias == null ) {
135- return row .entrySet ().stream ()
136- .filter (x -> x .getKey ().getKey ().startsWith (selectPath ))
137- .collect (HashMap ::new , (m , v ) -> m .put (v .getKey (), v .getValue ()), HashMap ::putAll );
138- } else {
139- Map <FieldKey , Object > result = new HashMap <>();
140- for (Map .Entry <FieldKey , Object > entry : row .entrySet ()) {
141- if (entry .getKey ().getKey ().startsWith (selectPath )) {
142- result .put (FieldKey .of (alias + entry .getKey ().getKey ().substring (selectPath .length ())), entry .getValue ());
143- }
144- }
145- return result ;
85+ while (!(parent instanceof SQL4JsonParser .Sql4jsonContext )){
86+ parent = parent .getParent ();
14687 }
88+ return parent .toString ();
14789 }
14890
14991}
0 commit comments