KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > versant > core > jdbc > ProjectionQueryDecoder


1
2 /*
3  * Copyright (c) 1998 - 2005 Versant Corporation
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  * Versant Corporation - initial API and implementation
11  */

12 package com.versant.core.jdbc;
13
14 import com.versant.core.jdo.query.*;
15 import com.versant.core.metadata.MDStatics;
16 import com.versant.core.metadata.FieldMetaData;
17 import com.versant.core.metadata.MDStaticUtils;
18 import com.versant.core.common.BindingSupportImpl;
19 import com.versant.core.jdbc.sql.SqlDriver;
20 import com.versant.core.util.IntArray;
21
22 /**
23  * This is a class that knows how to decode a result or projection query.
24  */

25 public class ProjectionQueryDecoder {
26     private static final int[] EMPTY_INT_ARRAY = new int[0];
27
28     public static final int TYPE_THIS = 1;
29     public static final int TYPE_AGGRETATE = 2;
30     public static final int TYPE_FIELD = 3;
31     public static final int TYPE_EXP = 4;
32     public static final int TYPE_VAR = 5;
33
34     private int[] typeMap;
35     private Object JavaDoc[] fmdMap;
36     private int[] typeCodeMap;
37     private int[] refIndexes;
38     private int firstThisColumn = -1;
39     private boolean containsOnlyThis;
40     private boolean containsThis;
41     private boolean aggregateOnly = true;
42     private boolean containsAggregate;
43     private SqlDriver driver;
44
45
46     public ProjectionQueryDecoder(ResultNode resultNode, SqlDriver driver) {
47         int size = resultNode.getResultSize();
48         typeMap = new int[size];
49         fmdMap = new Object JavaDoc[size];
50         typeCodeMap = new int[size];
51         refIndexes = new int[size];
52         this.driver = driver;
53         calculateTypes(size, resultNode);
54     }
55
56
57     private void calculateTypes(int size, ResultNode resultNode) {
58         int counter = 0;
59         IntArray refIndexArray = new IntArray();
60         for (Node n = resultNode.childList; n != null; n = n.next) {
61             if (n instanceof ReservedFieldNode) {
62                 typeCodeMap[counter] = MDStatics.OID;
63                 typeMap[counter] = TYPE_THIS;
64                 containsThis = true;
65                 aggregateOnly = false;
66                 if (firstThisColumn == -1) {
67                     firstThisColumn = counter;
68                 }
69             } else if (n instanceof AggregateNode) {
70                 typeMap[counter] = TYPE_AGGRETATE;
71                 containsAggregate = true;
72                 typeCodeMap[counter] = getTypeCode((AggregateNode)n, driver);
73             } else if (n instanceof AddNode || n instanceof MultiplyNode) {
74                 typeMap[counter] = TYPE_EXP;
75                 typeCodeMap[counter] = getTypeCode(n.childList);
76             } else {
77                 typeMap[counter] = TYPE_FIELD;
78                 if (n instanceof FieldNode) {
79                     fmdMap[counter] = ((FieldNode)n).fmd;
80                     typeCodeMap[counter] = ((FieldMetaData)fmdMap[counter]).typeCode;
81                 } else if (n instanceof FieldNavNode) {
82                     fmdMap[counter] = ((FieldNavNode)n).getResultFmd();
83                     typeCodeMap[counter] = ((FieldMetaData)fmdMap[counter]).typeCode;
84                 } else if (n instanceof VarNodeIF) {
85                     typeMap[counter] = TYPE_VAR;
86                     typeCodeMap[counter] = MDStatics.OID;
87                     fmdMap[counter] = ((VarNodeIF)n).getVarNode().getCmd();
88                 } else {
89                     throw BindingSupportImpl.getInstance().internal("");
90                 }
91
92                 //calculate if ref field.
93
if (typeMap[counter] == TYPE_FIELD
94                         && (((FieldMetaData)fmdMap[counter]).category == MDStatics.CATEGORY_REF
95                         || ((FieldMetaData)fmdMap[counter]).category == MDStatics.CATEGORY_POLYREF)) {
96                     refIndexArray.add(counter);
97                     typeCodeMap[counter] = MDStatics.OID;
98                 }
99                 aggregateOnly = false;
100             }
101             counter++;
102         }
103
104         if (size == 1 && containsThis == true) {
105             containsOnlyThis = true;
106         }
107
108         if (refIndexArray.size() == 0) {
109             refIndexes = EMPTY_INT_ARRAY;
110         } else {
111             refIndexes = refIndexArray.toArray();
112         }
113     }
114
115     private int getTypeCode(AggregateNode node, SqlDriver driver) {
116         int type = node.getType();
117         if (type == AggregateNode.TYPE_COUNT
118                 || node instanceof AggregateCountStarNode) {
119
120             return MDStatics.LONGW;
121
122
123         }
124         return driver.getAggregateTypeCode(type, getTypeCode(node.childList));
125     }
126
127     public boolean containsThis() {
128         return containsThis;
129     }
130
131     public boolean containsAggregate() {
132         return containsAggregate;
133     }
134
135     public boolean aggregateOnly() {
136         return aggregateOnly;
137     }
138
139     public int[] getResultTypeArray() {
140         return typeMap;
141     }
142
143     public Object JavaDoc[] getFmdArray() {
144         return fmdMap;
145     }
146
147     public int[] getTypeCodes() {
148         return typeCodeMap;
149     }
150
151     /**
152      * The index of the first occur. of 'this' in the projection.
153      */

154     public int getFirstThisIndex() {
155         return firstThisColumn;
156     }
157
158     /**
159      * Array containing the index pos of ref fields.
160      * return null if no ref fields.
161      */

162     public int[] getRefIndexArray() {
163         return refIndexes;
164     }
165
166     /**
167      * If this is a result that only contains 'this' and no other
168      * fields in the projection.
169      */

170     public boolean isContainsThisOnly() {
171         return containsOnlyThis;
172     }
173
174     /**
175      * The wrapper typecode of the exp. If the field eval to a primitive then the
176      * wrapper for that type is returned.
177      */

178     public static int getTypeCode(Node fn) {
179         if (fn instanceof AddNode || fn instanceof MultiplyNode) {
180             return getTypeCode(fn.childList);
181         }
182
183
184         int typeCode = MDStatics.BYTEW;
185
186
187         for (Node n = fn; n != null; n = n.next) {
188
189             int tmpCode = MDStaticUtils.primToNumberMapping[getTypeCodeImp(n)];
190
191
192             if (tmpCode > typeCode) {
193                 typeCode = tmpCode;
194             }
195         }
196         return typeCode;
197     }
198
199     public static int getTypeCodeImp(Node n) {
200         if (n instanceof FieldNode) {
201             return ((FieldNode)n).fmd.typeCode;
202         } else if (n instanceof FieldNavNode) {
203             return getTypeCodeImp(n.childList);
204         } else {
205             throw BindingSupportImpl.getInstance().internal("Expecting either a fieldNode or a FieldNavNode.");
206         }
207     }
208 }
209
Popular Tags