001: /* $Id: FromNode.java,v 1.12 2005/04/01 01:35:26 ahimanikya Exp $
002: * =======================================================================
003: * Copyright (c) 2003-2004 Axion Development Team. All rights reserved.
004: *
005: * Redistribution and use in source and binary forms, with or without
006: * modification, are permitted provided that the following conditions
007: * are met:
008: *
009: * 1. Redistributions of source code must retain the above
010: * copyright notice, this list of conditions and the following
011: * disclaimer.
012: *
013: * 2. Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in
015: * the documentation and/or other materials provided with the
016: * distribution.
017: *
018: * 3. The names "Tigris", "Axion", nor the names of its contributors may
019: * not be used to endorse or promote products derived from this
020: * software without specific prior written permission.
021: *
022: * 4. Products derived from this software may not be called "Axion", nor
023: * may "Tigris" or "Axion" appear in their names without specific prior
024: * written permission.
025: *
026: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
027: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
028: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
029: * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
030: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
031: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
032: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
033: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
034: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
035: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
036: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
037: * =======================================================================
038: */
039: package org.axiondb;
040:
041: /**
042: * A binary tree of tables (or "table like" objects) being selected from. Each element in
043: * the tree is either a FromNode or a TableIdentifier or a sub-query.
044: *
045: * @version $Revision: 1.12 $ $Date: 2005/04/01 01:35:26 $
046: * @author Amrish Lal
047: */
048: public class FromNode {
049:
050: /** Inner join. */
051: public static final int TYPE_INNER = 1;
052:
053: /** Left outer join */
054: public static final int TYPE_LEFT = 2;
055:
056: /** Right outer join */
057: public static final int TYPE_RIGHT = 3;
058:
059: /** No Join */
060: public static final int TYPE_SINGLE = 0;
061:
062: public FromNode() {
063: }
064:
065: /**
066: * get the join condition
067: *
068: * @return join condition.
069: */
070: public Selectable getCondition() {
071: return _condition;
072: }
073:
074: /**
075: * Get the Left input
076: *
077: * @return Object of type {@link FromNode}or {@link TableIdentifier}
078: */
079: public Object getLeft() {
080: return _left;
081: }
082:
083: /**
084: * get the right input
085: *
086: * @return Object of type {@link FromNode}or {@link TableIdentifier}
087: */
088: public Object getRight() {
089: return _right;
090: }
091:
092: /**
093: * Number of tables in this FromNode and its children.
094: *
095: * @return table count.
096: */
097: public int getTableCount() {
098: return getTableCount(getLeft()) + getTableCount(getRight());
099: }
100:
101: /**
102: * get the type of the join
103: *
104: * @return integer indicating type (UNDEFINED, LEFT OUTER, RIGHT OUTER, INNER)
105: */
106: public int getType() {
107: return _type;
108: }
109:
110: public boolean hasCondition() {
111: return null != getCondition();
112: }
113:
114: public boolean hasLeft() {
115: return null != getLeft();
116: }
117:
118: public boolean hasRight() {
119: return null != getRight();
120: }
121:
122: public boolean isInnerJoin() {
123: return getType() == FromNode.TYPE_INNER;
124: }
125:
126: public boolean isLeftJoin() {
127: return getType() == FromNode.TYPE_LEFT;
128: }
129:
130: public boolean isRightJoin() {
131: return getType() == FromNode.TYPE_RIGHT;
132: }
133:
134: /**
135: * Set the join condition
136: *
137: * @param type condition Join condition.
138: */
139: public void setCondition(Selectable condition) {
140: _condition = condition;
141: }
142:
143: public void setLeft(FromNode join) {
144: _left = join;
145: }
146:
147: public void setLeft(Object table) {
148: _left = table;
149: }
150:
151: public void setRight(FromNode join) {
152: _right = join;
153: }
154:
155: public void setRight(Object table) {
156: _right = table;
157: }
158:
159: /**
160: * Set the type of join.
161: *
162: * @param type integer value representing join type (INNER, LEFT OUTER, RIGHT OUTER)
163: */
164: public void setType(int type) {
165: _type = type;
166: }
167:
168: public String toString() {
169: return toString("");
170: }
171:
172: /**
173: * Array of tables in this FromNode or its children. Array is devleoped by preorder
174: * traversal of the FromNode tree.
175: *
176: * @return Array of {@link TableIdentifier}
177: */
178: public TableIdentifier[] toTableArray() {
179: TableIdentifier[] tables = new TableIdentifier[getTableCount()];
180: toTableArray(tables, 0);
181: return (tables);
182: }
183:
184: private String toString(String prefix) {
185: String result = "\n";
186: result += prefix + "Type : " + typeToString(getType()) + "\n";
187: if (_left instanceof TableIdentifier) {
188: TableIdentifier table = (TableIdentifier) _left;
189: result += prefix + "Left : " + " TableIdentifier "
190: + table.toString() + "\n";
191: }
192: if (_left instanceof FromNode) {
193: FromNode node = (FromNode) _left;
194: result += prefix + "Left : " + " FromNode "
195: + node.toString(prefix + "\t") + "\n";
196: }
197:
198: if (_right instanceof TableIdentifier) {
199: TableIdentifier table = (TableIdentifier) _right;
200: result += prefix + "Right: " + " TableIdentifier "
201: + table.toString() + "\n";
202: }
203:
204: if (_right instanceof FromNode) {
205: FromNode node = (FromNode) _right;
206: result += prefix + "Right: " + " FromNode "
207: + node.toString(prefix + "\t") + "\n";
208: }
209: return (result);
210: }
211:
212: private int toTableArray(TableIdentifier[] tables, int pos) {
213: pos = toTableArray(tables, pos, getLeft());
214: pos = toTableArray(tables, pos, getRight());
215: return pos;
216: }
217:
218: public static String typeToString(int type) {
219: switch (type) {
220: case TYPE_SINGLE:
221: return "single";
222: case TYPE_INNER:
223: return "inner";
224: case TYPE_LEFT:
225: return "left-outer";
226: case TYPE_RIGHT:
227: return "right-outer";
228: default:
229: return "unknown?";
230: }
231: }
232:
233: private static int getTableCount(Object child) {
234: if (null == child) {
235: return 0;
236: } else if (child instanceof TableIdentifier) {
237: return 1;
238: } else {
239: return ((FromNode) child).getTableCount();
240: }
241: }
242:
243: private static int toTableArray(TableIdentifier[] tables, int pos,
244: Object child) {
245: if (null == child) {
246: return pos;
247: } else if (child instanceof TableIdentifier) {
248: tables[pos] = ((TableIdentifier) child);
249: return pos + 1;
250: } else {
251: return ((FromNode) child).toTableArray(tables, pos);
252: }
253: }
254:
255: /** Join condition */
256: private Selectable _condition = null;
257:
258: /** Left input table identifier or FromNode. */
259: private Object _left = null;
260:
261: /** Right input table identifier or FromNode. */
262: private Object _right = null;
263:
264: /** Join type */
265: private int _type = TYPE_SINGLE;
266: }
|