001: /**
002: * com.mckoi.database.sql.FromTableSubQuerySource 21 Jul 2001
003: *
004: * Mckoi SQL Database ( http://www.mckoi.com/database )
005: * Copyright (C) 2000, 2001, 2002 Diehl and Associates, Inc.
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * Version 2 as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License Version 2 for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * Version 2 along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
019: *
020: * Change Log:
021: *
022: *
023: */package com.mckoi.database.interpret;
024:
025: import com.mckoi.database.*;
026:
027: /**
028: * An implementation of FromTableInterface that wraps around a
029: * TableSelectExpression object as a sub-query source.
030: *
031: * @author Tobias Downer
032: */
033:
034: public class FromTableSubQuerySource implements FromTableInterface {
035:
036: /**
037: * The wrapped object.
038: */
039: private TableSelectExpression table_expression;
040:
041: /**
042: * The fully prepared TableExpressionFromSet object that is used to
043: * qualify variables in the table.
044: */
045: private TableExpressionFromSet from_set;
046:
047: /**
048: * The TableName that this source is generated to (aliased name). If null,
049: * we inherit from the root set.
050: */
051: private TableName end_table_name;
052:
053: /**
054: * A unique name given to this source that is used to reference it in a
055: * TableSet.
056: */
057: private String unique_key;
058:
059: /**
060: * The list of all variable names in the resultant source.
061: */
062: private Variable[] vars;
063:
064: /**
065: * Set to true if this should do case insensitive resolutions.
066: */
067: private boolean case_insensitive = false;
068:
069: /**
070: * Constructs the source.
071: */
072: public FromTableSubQuerySource(DatabaseConnection connection,
073: String unique_key, TableSelectExpression table_expression,
074: TableExpressionFromSet from_set,
075: TableName aliased_table_name) {
076: this .unique_key = unique_key;
077: this .table_expression = table_expression;
078: this .from_set = from_set;
079: this .end_table_name = aliased_table_name;
080: // Is the database case insensitive?
081: this .case_insensitive = connection.isInCaseInsensitiveMode();
082: }
083:
084: /**
085: * Returns the TableSelectExpression for this sub-query.
086: */
087: TableSelectExpression getTableExpression() {
088: return table_expression;
089: }
090:
091: /**
092: * Returns the TableExpressionFromSet for this sub-query.
093: */
094: TableExpressionFromSet getFromSet() {
095: return from_set;
096: }
097:
098: /**
099: * Returns the aliased table name of this sub-query or null if it is left
100: * as-is.
101: */
102: TableName getAliasedName() {
103: return end_table_name;
104: }
105:
106: /**
107: * Makes sure the 'vars' list is created correctly.
108: */
109: private void ensureVarList() {
110: if (vars == null) {
111: vars = from_set.generateResolvedVariableList();
112: // for (int i = 0; i < vars.length; ++i) {
113: // System.out.println("+ " + vars[i]);
114: // }
115: // System.out.println("0000");
116: // Are the variables aliased to a table name?
117: if (end_table_name != null) {
118: for (int i = 0; i < vars.length; ++i) {
119: vars[i].setTableName(end_table_name);
120: }
121: }
122: }
123: }
124:
125: /**
126: * Returns the unique name of this source.
127: */
128: public String getUniqueKey() {
129: return unique_key;
130: }
131:
132: /**
133: * Toggle the case sensitivity flag.
134: */
135: public void setCaseInsensitive(boolean status) {
136: case_insensitive = status;
137: }
138:
139: private boolean stringCompare(String str1, String str2) {
140: if (!case_insensitive) {
141: return str1.equals(str2);
142: }
143: return str1.equalsIgnoreCase(str2);
144: }
145:
146: /**
147: * If the given Variable matches the reference then this method returns
148: * true.
149: */
150: private boolean matchesVar(Variable v, String catalog,
151: String schema, String table, String column) {
152: TableName tn = v.getTableName();
153: String cn = v.getName();
154:
155: if (column == null) {
156: return true;
157: }
158: if (!stringCompare(cn, column)) {
159: return false;
160: }
161:
162: if (table == null) {
163: return true;
164: }
165: if (tn == null) {
166: return false;
167: }
168: String tname = tn.getName();
169: if (tname != null && !stringCompare(tname, table)) {
170: return false;
171: }
172:
173: if (schema == null) {
174: return true;
175: }
176: String sname = tn.getSchema();
177: if (sname != null && !stringCompare(sname, schema)) {
178: return false;
179: }
180:
181: // Currently we ignore catalog
182: return true;
183:
184: }
185:
186: // ---------- Implemented from FromTableInterface ----------
187:
188: public String getUniqueName() {
189: return getUniqueKey();
190: }
191:
192: public boolean matchesReference(String catalog, String schema,
193: String table) {
194: if (schema == null && table == null) {
195: return true;
196: }
197: if (end_table_name != null) {
198: String ts = end_table_name.getSchema();
199: String tt = end_table_name.getName();
200: if (schema == null) {
201: if (stringCompare(tt, table)) {
202: return true;
203: }
204: } else {
205: if (stringCompare(tt, table)
206: && stringCompare(ts, schema)) {
207: return true;
208: }
209: }
210: }
211: // No way to determine if there is a match
212: return false;
213: }
214:
215: public int resolveColumnCount(String catalog, String schema,
216: String table, String column) {
217: ensureVarList();
218:
219: if (catalog == null && schema == null && table == null
220: && column == null) {
221: // Return the column count
222: return vars.length;
223: }
224:
225: int matched_count = 0;
226: for (int i = 0; i < vars.length; ++i) {
227: Variable v = vars[i];
228: if (matchesVar(v, catalog, schema, table, column)) {
229: ++matched_count;
230: }
231: }
232:
233: return matched_count;
234:
235: }
236:
237: public Variable resolveColumn(String catalog, String schema,
238: String table, String column) {
239: ensureVarList();
240:
241: // System.out.println("resolveColumn: " + catalog + ", " + schema + ", " +
242: // table + ", " + column);
243:
244: for (int i = 0; i < vars.length; ++i) {
245: Variable v = vars[i];
246: if (matchesVar(v, catalog, schema, table, column)) {
247: // System.out.println("Result: " + v);
248: return v;
249: }
250: }
251:
252: throw new Error("Couldn't resolve to a column.");
253: }
254:
255: public Variable[] allColumns() {
256: ensureVarList();
257: return vars;
258: }
259:
260: }
|