2121
2222import java .util .ArrayList ;
2323import java .util .List ;
24+ import java .util .Optional ;
2425
2526import org .apache .cayenne .access .sqlbuilder .ExpressionNodeBuilder ;
2627import org .apache .cayenne .access .sqlbuilder .QuotingAppendable ;
2728import org .apache .cayenne .access .sqlbuilder .SelectBuilder ;
28- import org .apache .cayenne .access .sqlbuilder .sqltree .ColumnNode ;
29- import org .apache .cayenne .access .sqlbuilder .sqltree .EmptyNode ;
30- import org .apache .cayenne .access .sqlbuilder .sqltree .FunctionNode ;
31- import org .apache .cayenne .access .sqlbuilder .sqltree .InNode ;
32- import org .apache .cayenne .access .sqlbuilder .sqltree .LimitOffsetNode ;
33- import org .apache .cayenne .access .sqlbuilder .sqltree .Node ;
34- import org .apache .cayenne .access .sqlbuilder .sqltree .NodeType ;
35- import org .apache .cayenne .access .sqlbuilder .sqltree .OpExpressionNode ;
36- import org .apache .cayenne .access .sqlbuilder .sqltree .TextNode ;
37- import org .apache .cayenne .access .sqlbuilder .sqltree .ValueNode ;
38- import org .apache .cayenne .access .sqlbuilder .sqltree .TrimmingColumnNode ;
39- import org .apache .cayenne .access .translator .select .BaseSQLTreeProcessor ;
29+ import org .apache .cayenne .access .sqlbuilder .sqltree .*;
30+ import org .apache .cayenne .access .translator .select .TypeAwareSQLTreeProcessor ;
4031import org .apache .cayenne .util .ArrayUtil ;
32+ import org .apache .cayenne .value .GeoJson ;
33+ import org .apache .cayenne .value .Json ;
34+ import org .apache .cayenne .value .Wkt ;
4135
4236import static org .apache .cayenne .access .sqlbuilder .SQLBuilder .*;
4337
4438/**
4539 * @since 4.2
4640 */
47- public class OracleSQLTreeProcessor extends BaseSQLTreeProcessor {
41+ public class OracleSQLTreeProcessor extends TypeAwareSQLTreeProcessor {
4842
4943 private static final int ORACLE_IN_BATCH_SIZE = 1000 ;
5044
5145 private SelectBuilder selectBuilder ;
5246
5347 private Node root ;
5448
55- @ Override
56- protected void onResultNode (Node parent , Node child , int index ) {
57- for (int i =0 ; i <child .getChildrenCount (); i ++) {
58- child .replaceChild (i , aliased (child .getChild (i ), "c" + i ).build ());
59- }
49+ private static final OracleSQLTreeProcessor INSTANCE = new OracleSQLTreeProcessor ();
50+
51+ public static OracleSQLTreeProcessor getInstance () {
52+ return INSTANCE ;
6053 }
6154
62- @ Override
63- protected void onColumnNode (Node parent , ColumnNode child , int index ) {
64- replaceChild (parent , index , new TrimmingColumnNode (child ));
55+ protected OracleSQLTreeProcessor () {
56+ registerProcessor (NodeType .IN , (ChildProcessor <InNode >) this ::onInNode );
57+ registerProcessor (NodeType .LIMIT_OFFSET , (ChildProcessor <LimitOffsetNode >) this ::onLimitOffsetNode );
58+ registerProcessor (NodeType .FUNCTION , (ChildProcessor <FunctionNode >) this ::onFunctionNode );
59+
60+ registerColumnProcessor (Wkt .class , (parent , child , i )
61+ -> Optional .of (wrapInFunction (child , "ST_AsText" )));
62+ registerColumnProcessor (GeoJson .class , (parent , child , i )
63+ -> Optional .of (wrapInFunction (child , "ST_AsGeoJSON" )));
64+
65+ registerValueProcessor (Wkt .class , (parent , child , i )
66+ -> Optional .of (wrapInFunction (child , "ST_GeomFromText" )));
67+ registerValueProcessor (GeoJson .class , (parent , child , i )
68+ -> Optional .of (wrapInFunction (child , "ST_GeomFromGeoJSON" )));
69+ registerValueProcessor (Json .class , (parent , child , i )
70+ -> Optional .of (wrapInFunction (child , "ST_AsCLOB" )));
6571 }
6672
67- @ Override
68- protected void onLimitOffsetNode (Node parent , LimitOffsetNode child , int index ) {
73+ protected Optional <Node > onLimitOffsetNode (Node parent , LimitOffsetNode child , int index ) {
6974 if (child .getLimit () > 0 || child .getOffset () > 0 ) {
7075 int limit = child .getLimit ();
7176 int offset = child .getOffset ();
@@ -86,21 +91,21 @@ protected void onLimitOffsetNode(Node parent, LimitOffsetNode child, int index)
8691 .where (exp (text (" rnum" )).gt (value (offset )));
8792 }
8893 parent .replaceChild (index , new EmptyNode ());
94+ return Optional .of (new LimitOffsetNode (child .getLimit (), child .getOffset ()));
8995 }
9096
91- @ Override
92- protected void onInNode (Node parent , InNode child , int index ) {
97+ protected Optional <Node > onInNode (Node parent , InNode child , int index ) {
9398 boolean not = child .isNot ();
9499 Node arg = child .getChild (0 );
95100 Node childNode = child .getChild (1 );
96101 if (childNode .getType () != NodeType .VALUE ) {
97- return ;
102+ return Optional . of ( child ) ;
98103 }
99104
100105 ValueNode valueNode = (ValueNode )childNode ;
101106 Object value = valueNode .getValue ();
102107 if (!value .getClass ().isArray ()) {
103- return ;
108+ return Optional . of ( child ) ;
104109 }
105110
106111 List <Node > newChildren = new ArrayList <>();
@@ -153,6 +158,7 @@ protected void onInNode(Node parent, InNode child, int index) {
153158 }
154159 }
155160 parent .replaceChild (index , exp .build ());
161+ return Optional .of (child );
156162 }
157163
158164 private InNode newSliceNode (InNode child , Node arg , ValueNode valueNode , Object slice ) {
@@ -162,8 +168,7 @@ private InNode newSliceNode(InNode child, Node arg, ValueNode valueNode, Object
162168 return nextNode ;
163169 }
164170
165- @ Override
166- protected void onFunctionNode (Node parent , FunctionNode child , int index ) {
171+ protected Optional <Node > onFunctionNode (Node parent , FunctionNode child , int index ) {
167172 String functionName = child .getFunctionName ();
168173 Node functionReplacement = null ;
169174 switch (functionName ) {
@@ -173,7 +178,7 @@ protected void onFunctionNode(Node parent, FunctionNode child, int index) {
173178 functionReplacement .addChild (child .getChild (1 -i ));
174179 }
175180 parent .replaceChild (index , functionReplacement );
176- return ;
181+ return Optional . of ( child ) ;
177182
178183 case "DAY_OF_YEAR" :
179184 case "DAY_OF_WEEK" :
@@ -189,7 +194,7 @@ protected void onFunctionNode(Node parent, FunctionNode child, int index) {
189194 }
190195 functionReplacement .addChild (new TextNode (functionName ));
191196 parent .replaceChild (index , functionReplacement );
192- return ;
197+ return Optional . of ( child ) ;
193198
194199 case "SUBSTRING" :
195200 functionReplacement = new FunctionNode ("SUBSTR" , child .getAlias (), true );
@@ -227,9 +232,9 @@ public void appendChildrenSeparator(QuotingAppendable buffer, int childIdx) {
227232 if (functionReplacement != null ) {
228233 replaceChild (parent , index , functionReplacement );
229234 }
235+ return Optional .of (child );
230236 }
231237
232- @ Override
233238 public Node process (Node node ) {
234239 root = node ;
235240 super .process (node );
0 commit comments