KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > mckoi > database > interpret > ColumnChecker


1 /**
2  * com.mckoi.database.interpret.ColumnChecker 09 Sep 2001
3  *
4  * Mckoi SQL Database ( http://www.mckoi.com/database )
5  * Copyright (C) 2000, 2001, 2002 Diehl and Associates, Inc.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * Version 2 as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License Version 2 for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * Version 2 along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  *
20  * Change Log:
21  *
22  *
23  */

24
25 package com.mckoi.database.interpret;
26
27 import com.mckoi.database.*;
28 import java.util.ArrayList JavaDoc;
29 import java.util.List JavaDoc;
30
31 /**
32  * A class that abstracts the checking of information in a table. This is
33  * abstracted because the behaviour is shared between ALTER and CREATE
34  * statement.
35  *
36  * @author Tobias Downer
37  */

38
39 abstract class ColumnChecker {
40
41   /**
42    * Given a column name string, this will strip off the preceeding table
43    * name if there is one specified. For example, 'Customer.id' would
44    * become 'id'. This also checks that the table specification is in the
45    * given table domain. For example,
46    * stripTableName("Customer", "Customer.id") would not throw an error but
47    * stripTableName("Order", "Customer.di") would.
48    */

49   static String JavaDoc stripTableName(String JavaDoc table_domain, String JavaDoc column) {
50     if (column.indexOf('.') != -1) {
51       String JavaDoc st = table_domain + ".";
52       if (!column.startsWith(st)) {
53         throw new StatementException("Column '" + column +
54           "' is not within the expected table domain '" + table_domain + "'");
55       }
56       column = column.substring(st.length());
57     }
58     return column;
59   }
60
61   /**
62    * Calls the 'stripTableName' method on all elements in the given list.
63    */

64   static ArrayList JavaDoc stripColumnList(String JavaDoc table_domain,
65                                    ArrayList JavaDoc column_list) {
66     if (column_list != null) {
67       int size = column_list.size();
68       for (int i = 0; i < size; ++i) {
69         String JavaDoc res = stripTableName(table_domain, (String JavaDoc) column_list.get(i));
70         column_list.set(i, res);
71       }
72     }
73     return column_list;
74   }
75
76   /**
77    * Returns the resolved column name if the column exists within the table
78    * being checked under, or null if it doesn't. Throws an error if the
79    * column name is abiguous.
80    */

81   abstract String JavaDoc resolveColumnName(String JavaDoc col_name) throws DatabaseException;
82
83   /**
84    * Resolves all the variables in the expression throwing a DatabaseException
85    * if any errors found. This checks that all variables point to a column
86    * in the table being created.
87    */

88   void checkExpression(Expression expression) throws DatabaseException {
89
90     if (expression != null) {
91       List JavaDoc list = expression.allVariables();
92       for (int i = 0; i < list.size(); ++i) {
93         Variable v = (Variable) list.get(i);
94         String JavaDoc orig_col = v.getName();
95         String JavaDoc resolved_column = resolveColumnName(orig_col);
96         if (resolved_column == null) {
97           throw new DatabaseException("Column '" + orig_col +
98                                       "' not found in the table.");
99         }
100         // Resolve the column name
101
if (!orig_col.equals(resolved_column)) {
102           v.setColumnName(resolved_column);
103         }
104
105       }
106
107       // Don't allow select statements because they don't convert to a
108
// text string that we can encode into the DataTableDef file.
109
if (expression.hasSubQuery()) {
110         throw new DatabaseException("Sub-queries not permitted in " +
111                                     "the check constraint expression.");
112       }
113     }
114
115   }
116
117   /**
118    * Checks all the columns in the list and throws an exception if any
119    * column names are not found in the columns in this create. Additionally
120    * sets the entry with the correct column resolved to.
121    */

122   void checkColumnList(ArrayList JavaDoc list) throws DatabaseException {
123     if (list != null) {
124       for (int i = 0; i < list.size(); ++i) {
125         String JavaDoc col = (String JavaDoc) list.get(i);
126         String JavaDoc resolved_col = resolveColumnName(col);
127         if (resolved_col == null) {
128           throw new DatabaseException(
129                                "Column '" + col + "' not found the table.");
130         }
131         list.set(i, resolved_col);
132       }
133     }
134   }
135
136
137   // ---------- Statics ----------
138

139   /**
140    * Given a DatabaseConnection and a TableName object, this returns an
141    * implementation of ColumnChecker that is able to check that the column
142    * name exists in the table, and that the reference is not ambigious.
143    */

144   static ColumnChecker standardColumnChecker(
145                              DatabaseConnection database, TableName tname) {
146     final DataTableDef table_def = database.getTable(tname).getDataTableDef();
147     final boolean ignores_case = database.isInCaseInsensitiveMode();
148
149     // Implement the checker
150
return new ColumnChecker() {
151       String JavaDoc resolveColumnName(String JavaDoc col_name) throws DatabaseException {
152         // We need to do case sensitive and case insensitive resolution,
153
String JavaDoc found_col = null;
154         for (int n = 0; n < table_def.columnCount(); ++n) {
155           DataTableColumnDef col =
156                                 (DataTableColumnDef) table_def.columnAt(n);
157           if (!ignores_case) {
158             if (col.getName().equals(col_name)) {
159               return col_name;
160             }
161           }
162           else {
163             if (col.getName().equalsIgnoreCase(col_name)) {
164               if (found_col != null) {
165                 throw new DatabaseException("Ambiguous column name '" +
166                                             col_name + "'");
167               }
168               found_col = col.getName();
169             }
170           }
171         }
172         return found_col;
173       }
174     };
175   }
176
177 }
178
Popular Tags