KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > ejb > plugins > cmp > jdbc > SQLUtil


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.ejb.plugins.cmp.jdbc;
23
24 import java.sql.Connection JavaDoc;
25 import java.sql.DatabaseMetaData JavaDoc;
26 import javax.sql.DataSource JavaDoc;
27 import java.sql.SQLException JavaDoc;
28 import java.sql.Statement JavaDoc;
29 import java.sql.ResultSet JavaDoc;
30 import java.util.zip.CRC32 JavaDoc;
31 import java.util.ArrayList JavaDoc;
32
33 import org.jboss.deployment.DeploymentException;
34 import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCEntityBridge;
35 import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCFieldBridge;
36 import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCAbstractEntityBridge;
37 import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCAbstractCMRFieldBridge;
38 import org.jboss.logging.Logger;
39
40 import java.util.Vector JavaDoc;
41
42 /**
43  * SQLUtil helps with building sql statements.
44  *
45  * @author <a HREF="mailto:dain@daingroup.com">Dain Sundstrom</a>
46  * @author <a HREF="mailto:alex@jboss.org">Alex Loubyansky</a>
47  * @author <a HREF="joachim@cabsoft.be">Joachim Van der Auwera</a>
48  * @version $Revision: 58402 $
49  */

50 public final class SQLUtil
51 {
52    public static final String JavaDoc EMPTY_STRING = "";
53    public static final String JavaDoc INSERT_INTO = "INSERT INTO ";
54    public static final String JavaDoc VALUES = " VALUES ";
55    public static final String JavaDoc SELECT = "SELECT ";
56    public static final String JavaDoc DISTINCT = "DISTINCT ";
57    public static final String JavaDoc FROM = " FROM ";
58    public static final String JavaDoc WHERE = " WHERE ";
59    public static final String JavaDoc ORDERBY = " ORDER BY ";
60    public static final String JavaDoc DELETE_FROM = "DELETE FROM ";
61    public static final String JavaDoc AND = " AND ";
62    public static final String JavaDoc OR = " OR ";
63    public static final String JavaDoc NOT = " NOT ";
64    public static final String JavaDoc EXISTS = "EXISTS ";
65    public static final String JavaDoc COMMA = ", ";
66    public static final String JavaDoc LEFT_JOIN = " LEFT JOIN ";
67    public static final String JavaDoc LEFT_OUTER_JOIN = " LEFT OUTER JOIN ";
68    public static final String JavaDoc ON = " ON ";
69    public static final String JavaDoc NOT_EQUAL = "<>";
70    public static final String JavaDoc CREATE_TABLE = "CREATE TABLE ";
71    public static final String JavaDoc DROP_TABLE = "DROP TABLE ";
72    public static final String JavaDoc CREATE_INDEX = "CREATE INDEX ";
73    public static final String JavaDoc NULL = "NULL";
74    public static final String JavaDoc IS = " IS ";
75    public static final String JavaDoc IN = " IN ";
76    public static final String JavaDoc EMPTY = "EMPTY";
77    public static final String JavaDoc BETWEEN = " BETWEEN ";
78    public static final String JavaDoc LIKE = " LIKE ";
79    public static final String JavaDoc MEMBER_OF = " MEMBER OF ";
80    public static final String JavaDoc ESCAPE = " ESCAPE ";
81    public static final String JavaDoc CONCAT = "CONCAT";
82    public static final String JavaDoc SUBSTRING = "SUBSTRING";
83    public static final String JavaDoc LCASE = "LCASE";
84    public static final String JavaDoc UCASE = "UCASE";
85    public static final String JavaDoc LENGTH = "LENGTH";
86    public static final String JavaDoc LOCATE = "LOCATE";
87    public static final String JavaDoc ABS = "ABS";
88    public static final String JavaDoc MOD = "MOD";
89    public static final String JavaDoc SQRT = "SQRT";
90    public static final String JavaDoc COUNT = "COUNT";
91    public static final String JavaDoc MAX = "MAX";
92    public static final String JavaDoc MIN = "MIN";
93    public static final String JavaDoc AVG = "AVG";
94    public static final String JavaDoc SUM = "SUM";
95    public static final String JavaDoc ASC = " ASC";
96    public static final String JavaDoc DESC = " DESC";
97    public static final String JavaDoc OFFSET = " OFFSET ";
98    public static final String JavaDoc LIMIT = " LIMIT ";
99    public static final String JavaDoc UPDATE = "UPDATE ";
100    public static final String JavaDoc SET = " SET ";
101    public static final String JavaDoc TYPE = " TYPE ";
102    private static final String JavaDoc DOT = ".";
103
104    private static final String JavaDoc EQ_QUESTMARK = "=?";
105
106    private static final Vector JavaDoc rwords = new Vector JavaDoc();
107
108    public static String JavaDoc getTableNameWithoutSchema(String JavaDoc tableName)
109    {
110       final int dot = tableName.indexOf('.');
111       if(dot != -1)
112       {
113          char firstChar = tableName.charAt(0);
114          tableName = tableName.substring(dot + 1);
115          if(firstChar == '"' || firstChar == '\'')
116          {
117             tableName = firstChar + tableName;
118          }
119       }
120       return tableName;
121    }
122
123    public static String JavaDoc getSchema(String JavaDoc tableName)
124    {
125       String JavaDoc schema = null;
126       final int dot = tableName.indexOf('.');
127       if(dot != -1)
128       {
129          char firstChar = tableName.charAt(0);
130          final boolean quoted = firstChar == '"' || firstChar == '\'';
131          schema = tableName.substring(quoted ? 1 : 0, dot);
132       }
133       return schema;
134    }
135
136    public static String JavaDoc fixTableName(String JavaDoc tableName, DataSource JavaDoc dataSource)
137       throws DeploymentException
138    {
139       // don't fix the quited table name
140
char firstChar = tableName.charAt(0);
141       if(firstChar == '"' || firstChar == '\'')
142       {
143          return tableName;
144       }
145
146       // Separate schema name and table name
147
String JavaDoc strSchema = "";
148       int iIndex;
149       if((iIndex = tableName.indexOf('.')) != -1)
150       {
151          strSchema = tableName.substring(0, iIndex);
152          tableName = tableName.substring(iIndex + 1);
153       }
154
155       // check for SQL reserved word and escape it with prepending a "X"
156
// IMHO one should reject reserved words and throw a
157
// DeploymentException - pilhuhn
158
if(rwords != null)
159       {
160          for(int i = 0; i < rwords.size(); i++)
161          {
162             if(((String JavaDoc)rwords.elementAt(i)).equalsIgnoreCase(tableName))
163             {
164                tableName = "X" + tableName;
165                break;
166             }
167          }
168       }
169
170       Connection JavaDoc con = null;
171       try
172       {
173          con = dataSource.getConnection();
174          DatabaseMetaData JavaDoc dmd = con.getMetaData();
175
176          // fix length
177
int maxLength = dmd.getMaxTableNameLength();
178          if(maxLength > 0 && tableName.length() > maxLength)
179          {
180             CRC32 JavaDoc crc = new CRC32 JavaDoc();
181             crc.update(tableName.getBytes());
182             String JavaDoc nameCRC = Long.toString(crc.getValue(), 36);
183
184             tableName = tableName.substring(
185                0,
186                maxLength - nameCRC.length() - 2);
187             tableName += "_" + nameCRC;
188          }
189
190          // fix case
191
if(dmd.storesLowerCaseIdentifiers())
192          {
193             tableName = tableName.toLowerCase();
194          }
195          else if(dmd.storesUpperCaseIdentifiers())
196          {
197             tableName = tableName.toUpperCase();
198          }
199          // now put the schema name back on the table name
200
if(strSchema.length() > 0)
201          {
202             tableName = strSchema + "." + tableName;
203          }
204          return tableName;
205       }
206       catch(SQLException JavaDoc e)
207       {
208          // This should not happen. A J2EE compatiable JDBC driver is
209
// required fully support metadata.
210
throw new DeploymentException("Error while fixing table name", e);
211       }
212       finally
213       {
214          JDBCUtil.safeClose(con);
215       }
216    }
217
218    public static void addToRwords(String JavaDoc word)
219    {
220       if(!rwords.contains(word))
221          rwords.add(word);
222    }
223
224
225    public static String JavaDoc fixConstraintName(String JavaDoc name, DataSource JavaDoc dataSource)
226       throws DeploymentException
227    {
228       return fixTableName(name, dataSource).replace('.', '_');
229    }
230
231    // =======================================================================
232
// Create Table Columns Clause
233
// columnName0 sqlType0
234
// [, columnName1 sqlType0
235
// [, columnName2 sqlType0 [...]]]
236
// =======================================================================
237
public static String JavaDoc getCreateTableColumnsClause(JDBCFieldBridge[] fields)
238    {
239       StringBuffer JavaDoc buf = new StringBuffer JavaDoc(100);
240       boolean comma = false;
241       for(int i = 0; i < fields.length; ++i)
242       {
243          JDBCType type = getJDBCType(fields[i]);
244          if(type != null)
245          {
246             if(comma)
247                buf.append(COMMA);
248             else
249                comma = true;
250             buf.append(getCreateTableColumnsClause(type));
251          }
252       }
253       return buf.toString();
254    }
255
256    /**
257     * Returns columnName0 sqlType0
258     * [, columnName1 sqlType0
259     * [, columnName2 sqlType0 [...]]]
260     */

261    public static String JavaDoc getCreateTableColumnsClause(JDBCType type)
262    {
263       String JavaDoc[] columnNames = type.getColumnNames();
264       String JavaDoc[] sqlTypes = type.getSQLTypes();
265       boolean[] notNull = type.getNotNull();
266
267       StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
268       for(int i = 0; i < columnNames.length; i++)
269       {
270          if(i != 0)
271             buf.append(COMMA);
272          buf.append(columnNames[i]).append(' ').append(sqlTypes[i]);
273          if(notNull[i])
274             buf.append(NOT).append(NULL);
275       }
276       return buf.toString();
277    }
278
279    // =======================================================================
280
// Column Names Clause
281
// columnName0 [, columnName1 [AND columnName2 [...]]]
282
// =======================================================================
283

284    /**
285     * Returns columnName0 [, columnName1 [AND columnName2 [...]]]
286     */

287    public static StringBuffer JavaDoc getColumnNamesClause(JDBCFieldBridge[] fields, StringBuffer JavaDoc sb)
288    {
289       return getColumnNamesClause(fields, "", sb);
290    }
291
292    /**
293     * Returns columnName0 [, columnName1 [AND columnName2 [...]]]
294     */

295    public static StringBuffer JavaDoc getColumnNamesClause(JDBCFieldBridge[] fields,
296                                                    String JavaDoc identifier,
297                                                    StringBuffer JavaDoc buf)
298    {
299       boolean comma = false;
300       for(int i = 0; i < fields.length; ++i)
301       {
302          JDBCType type = getJDBCType(fields[i]);
303          if(type != null)
304          {
305             if(comma)
306                buf.append(COMMA);
307             else
308                comma = true;
309             getColumnNamesClause(type, identifier, buf);
310          }
311       }
312       return buf;
313    }
314
315    /**
316     * Returns columnName0 [, columnName1 [AND columnName2 [...]]]
317     */

318    public static StringBuffer JavaDoc getSearchableColumnNamesClause(JDBCFieldBridge[] fields,
319                                                              String JavaDoc identifier,
320                                                              StringBuffer JavaDoc buf)
321    {
322       boolean comma = false;
323       for(int i = 0; i < fields.length; ++i)
324       {
325          JDBCType type = getJDBCType(fields[i]);
326          if(type != null && type.isSearchable())
327          {
328             if(comma)
329                buf.append(COMMA);
330             else
331                comma = true;
332             getColumnNamesClause(type, identifier, buf);
333          }
334       }
335       return buf;
336    }
337
338    /**
339     * Returns columnName0 [, columnName1 [AND columnName2 [...]]]
340     */

341    public static StringBuffer JavaDoc getColumnNamesClause(JDBCEntityBridge.FieldIterator loadIter, StringBuffer JavaDoc sb)
342    {
343       if(loadIter.hasNext())
344          getColumnNamesClause(loadIter.next(), sb);
345       while(loadIter.hasNext())
346       {
347          sb.append(COMMA);
348          getColumnNamesClause(loadIter.next(), sb);
349       }
350       return sb;
351    }
352
353    /**
354     * Returns columnName0 [, columnName1 [, columnName2 [...]]]
355     */

356    public static StringBuffer JavaDoc getColumnNamesClause(JDBCFieldBridge field, StringBuffer JavaDoc sb)
357    {
358       return getColumnNamesClause(field.getJDBCType(), sb);
359    }
360
361    /**
362     * Returns identifier.columnName0
363     * [, identifier.columnName1
364     * [, identifier.columnName2 [...]]]
365     */

366    public static StringBuffer JavaDoc getColumnNamesClause(JDBCFieldBridge field, String JavaDoc identifier, StringBuffer JavaDoc sb)
367    {
368       return getColumnNamesClause(field.getJDBCType(), identifier, sb);
369    }
370
371    /**
372     * Returns identifier.columnName0
373     * [, identifier.columnName1
374     * [, identifier.columnName2 [...]]]
375     */

376    private static StringBuffer JavaDoc getColumnNamesClause(JDBCType type, String JavaDoc identifier, StringBuffer JavaDoc buf)
377    {
378       String JavaDoc[] columnNames = type.getColumnNames();
379       boolean hasIdentifier = identifier.length() > 0;
380       if(hasIdentifier)
381          buf.append(identifier).append(DOT);
382       buf.append(columnNames[0]);
383       int i = 1;
384       while(i < columnNames.length)
385       {
386          buf.append(COMMA);
387          if(hasIdentifier)
388             buf.append(identifier).append(DOT);
389          buf.append(columnNames[i++]);
390       }
391       return buf;
392    }
393
394    /**
395     * Returns ', columnName0 [, columnName1 [AND columnName2 [...]]]'
396     */

397    public static StringBuffer JavaDoc appendColumnNamesClause(JDBCAbstractEntityBridge entity, String JavaDoc eagerLoadGroup, StringBuffer JavaDoc sb)
398    {
399       return appendColumnNamesClause(entity, eagerLoadGroup, "", sb);
400    }
401
402    /**
403     * Returns ', columnName0 [, columnName1 [AND columnName2 [...]]]'
404     */

405    public static StringBuffer JavaDoc appendColumnNamesClause(JDBCAbstractEntityBridge entity,
406                                                       String JavaDoc eagerLoadGroup,
407                                                       String JavaDoc alias,
408                                                       StringBuffer JavaDoc sb)
409    {
410       return appendColumnNamesClause(entity.getTableFields(), entity.getLoadGroupMask(eagerLoadGroup), alias, sb);
411    }
412
413    /**
414     * Returns ', columnName0 [, columnName1 [AND columnName2 [...]]]'
415     */

416    public static StringBuffer JavaDoc appendColumnNamesClause(JDBCFieldBridge[] fields,
417                                                       boolean[] mask,
418                                                       String JavaDoc identifier,
419                                                       StringBuffer JavaDoc buf)
420    {
421       for(int i = 0; i < fields.length; ++i)
422       {
423          if(mask[i])
424          {
425             JDBCType type = getJDBCType(fields[i]);
426             if(type != null)
427             {
428                buf.append(COMMA);
429                getColumnNamesClause(type, identifier, buf);
430             }
431          }
432       }
433       return buf;
434    }
435
436    /**
437     * Returns ', columnName0 [, columnName1 [AND columnName2 [...]]]'
438     */

439    public static StringBuffer JavaDoc appendColumnNamesClause(JDBCFieldBridge[] fields,
440                                                       String JavaDoc identifier,
441                                                       StringBuffer JavaDoc buf)
442    {
443       for(int i = 0; i < fields.length; ++i)
444       {
445          JDBCType type = getJDBCType(fields[i]);
446          if(type != null)
447          {
448             buf.append(COMMA);
449             getColumnNamesClause(type, identifier, buf);
450          }
451       }
452       return buf;
453    }
454
455    /**
456     * Returns identifier.columnName0
457     * [, identifier.columnName1
458     * [, identifier.columnName2 [...]]]
459     */

460    private static StringBuffer JavaDoc getColumnNamesClause(JDBCType type, StringBuffer JavaDoc buf)
461    {
462       String JavaDoc[] columnNames = type.getColumnNames();
463       buf.append(columnNames[0]);
464       int i = 1;
465       while(i < columnNames.length)
466       {
467          buf.append(COMMA).append(columnNames[i++]);
468       }
469       return buf;
470    }
471
472    // =======================================================================
473
// Set Clause
474
// columnName0=? [, columnName1=? [, columnName2=? [...]]]
475
// =======================================================================
476

477    /**
478     * Returns columnName0=? [, columnName1=? [, columnName2=? [...]]]
479     */

480    public static StringBuffer JavaDoc getSetClause(JDBCEntityBridge.FieldIterator fieldsIter,
481                                            StringBuffer JavaDoc buf)
482    {
483       JDBCType type = getJDBCType(fieldsIter.next());
484       getSetClause(type, buf);
485       while(fieldsIter.hasNext())
486       {
487          type = getJDBCType(fieldsIter.next());
488          buf.append(COMMA);
489          getSetClause(type, buf);
490       }
491       return buf;
492    }
493
494    /**
495     * Returns columnName0=? [, columnName1=? [, columnName2=? [...]]]
496     */

497    private static StringBuffer JavaDoc getSetClause(JDBCType type, StringBuffer JavaDoc buf)
498    {
499       String JavaDoc[] columnNames = type.getColumnNames();
500       buf.append(columnNames[0]).append(EQ_QUESTMARK);
501       int i = 1;
502       while(i < columnNames.length)
503       {
504          buf.append(COMMA).append(columnNames[i++]).append(EQ_QUESTMARK);
505       }
506       return buf;
507    }
508
509    // =======================================================================
510
// Values Clause
511
// ? [, ? [, ? [...]]]
512
// =======================================================================
513

514    /**
515     * Returns ? [, ? [, ? [...]]]
516     */

517    public static StringBuffer JavaDoc getValuesClause(JDBCFieldBridge[] fields, StringBuffer JavaDoc buf)
518    {
519       boolean comma = false;
520       for(int i = 0; i < fields.length; ++i)
521       {
522          JDBCType type = getJDBCType(fields[i]);
523          if(type != null)
524          {
525             if(comma)
526                buf.append(COMMA);
527             else
528                comma = true;
529             getValuesClause(type, buf);
530          }
531       }
532       return buf;
533    }
534
535    /**
536     * Returns ? [, ? [, ? [...]]]
537     */

538    private static StringBuffer JavaDoc getValuesClause(JDBCType type, StringBuffer JavaDoc buf)
539    {
540       int columnCount = type.getColumnNames().length;
541       buf.append('?');
542       int i = 1;
543       while(i++ < columnCount)
544          buf.append(COMMA).append('?');
545       return buf;
546    }
547
548    // =======================================================================
549
// Where Clause
550
// columnName0=? [AND columnName1=? [AND columnName2=? [...]]]
551
// =======================================================================
552

553    /**
554     * Returns columnName0=? [AND columnName1=? [AND columnName2=? [...]]]
555     */

556    public static StringBuffer JavaDoc getWhereClause(JDBCFieldBridge[] fields, StringBuffer JavaDoc buf)
557    {
558       return getWhereClause(fields, "", buf);
559    }
560
561    /**
562     * Returns identifier.columnName0=?
563     * [AND identifier.columnName1=?
564     * [AND identifier.columnName2=? [...]]]
565     */

566    public static StringBuffer JavaDoc getWhereClause(JDBCFieldBridge[] fields, String JavaDoc identifier, StringBuffer JavaDoc buf)
567    {
568       boolean and = false;
569       for(int i = 0; i < fields.length; ++i)
570       {
571          JDBCType type = getJDBCType(fields[i]);
572          if(type != null)
573          {
574             if(and)
575                buf.append(AND);
576             else
577                and = true;
578             getWhereClause(type, identifier, buf);
579          }
580       }
581       return buf;
582    }
583
584    /**
585     * Returns columnName0=? [AND columnName1=? [AND columnName2=? [...]]]
586     */

587    public static StringBuffer JavaDoc getWhereClause(JDBCFieldBridge[] fields,
588                                              long mask,
589                                              StringBuffer JavaDoc buf)
590    {
591       return getWhereClause(fields, mask, "", buf);
592    }
593
594    /**
595     * Returns columnName0=? [AND columnName1=? [AND columnName2=? [...]]]
596     */

597    private static StringBuffer JavaDoc getWhereClause(JDBCFieldBridge[] fields,
598                                               long mask,
599                                               String JavaDoc identifier,
600                                               StringBuffer JavaDoc buf)
601    {
602       boolean and = false;
603       long fieldMask = 1;
604       for(int i = 0; i < fields.length; ++i)
605       {
606          if((fieldMask & mask) > 0)
607          {
608             JDBCType type = getJDBCType(fields[i]);
609             if(type != null)
610             {
611                if(and)
612                   buf.append(AND);
613                else
614                   and = true;
615                getWhereClause(type, identifier, buf);
616             }
617          }
618          fieldMask <<= 1;
619       }
620       return buf;
621    }
622
623    /**
624     * Returns columnName0=? [AND columnName1=? [AND columnName2=? [...]]]
625     */

626    public static StringBuffer JavaDoc getWhereClause(JDBCFieldBridge field, StringBuffer JavaDoc buf)
627    {
628       return getWhereClause(field.getJDBCType(), "", buf);
629    }
630
631    /**
632     * Returns identifier.columnName0=?
633     * [AND identifier.columnName1=?
634     * [AND identifier.columnName2=? [...]]]
635     */

636    public static StringBuffer JavaDoc getWhereClause(JDBCType type, String JavaDoc identifier, StringBuffer JavaDoc buf)
637    {
638       if(identifier.length() > 0)
639       {
640          identifier += '.';
641       }
642
643       String JavaDoc[] columnNames = type.getColumnNames();
644       buf.append(identifier).append(columnNames[0]).append(EQ_QUESTMARK);
645       int i = 1;
646       while(i < columnNames.length)
647       {
648          buf.append(AND).append(identifier).append(columnNames[i++]).append(EQ_QUESTMARK);
649       }
650       return buf;
651    }
652
653    /**
654     * Returns identifier.columnName0{comparison}?
655     * [AND identifier.columnName1{comparison}?
656     * [AND identifier.columnName2{comparison}? [...]]]
657     */

658    public static StringBuffer JavaDoc getWhereClause(JDBCType type, String JavaDoc identifier, String JavaDoc comparison, StringBuffer JavaDoc buf)
659    {
660       if(identifier.length() > 0)
661       {
662          identifier += '.';
663       }
664
665       String JavaDoc[] columnNames = type.getColumnNames();
666       buf.append(identifier).append(columnNames[0]).append(comparison).append('?');
667       int i = 1;
668       while(i < columnNames.length)
669       {
670          buf.append(AND).append(identifier).append(columnNames[i++]).append(comparison).append('?');
671       }
672       return buf;
673    }
674
675
676    // =======================================================================
677
// Is [Not] Null Clause
678
// columnName0 IS [NOT] NULL [AND columnName1 IS [NOT] NULL [...]]
679
// =======================================================================
680

681    /**
682     * Returns identifier.columnName0 IS [NOT] NULL
683     * [AND identifier.columnName1 IS [NOT] NULL
684     * [AND identifier.columnName2 IS [NOT] NULL [...]]]
685     */

686    public static StringBuffer JavaDoc getIsNullClause(boolean not,
687                                               JDBCFieldBridge[] fields,
688                                               String JavaDoc identifier,
689                                               StringBuffer JavaDoc buf)
690    {
691       boolean and = false;
692       for(int i = 0; i < fields.length; ++i)
693       {
694          JDBCType type = getJDBCType(fields[i]);
695          if(type != null)
696          {
697             if(and)
698                buf.append(AND);
699             else
700                and = true;
701             getIsNullClause(not, type, identifier, buf);
702          }
703       }
704       return buf;
705    }
706
707    /**
708     * Returns identifier.columnName0 IS [NOT] NULL
709     * [AND identifier.columnName1 IS [NOT] NULL
710     * [AND identifier.columnName2 IS [NOT] NULL [...]]]
711     */

712    public static StringBuffer JavaDoc getIsNullClause(boolean not,
713                                               JDBCFieldBridge field,
714                                               String JavaDoc identifier,
715                                               StringBuffer JavaDoc buf)
716    {
717       return getIsNullClause(not, field.getJDBCType(), identifier, buf);
718    }
719
720    /**
721     * Returns identifier.columnName0 IS [NOT] NULL
722     * [AND identifier.columnName1 IS [NOT] NULL
723     * [AND identifier.columnName2 IS [NOT] NULL [...]]]
724     */

725    private static StringBuffer JavaDoc getIsNullClause(boolean not,
726                                                JDBCType type,
727                                                String JavaDoc identifier,
728                                                StringBuffer JavaDoc buf)
729    {
730       if(identifier.length() > 0)
731       {
732          identifier += '.';
733       }
734
735       String JavaDoc[] columnNames = type.getColumnNames();
736
737       buf.append(identifier).append(columnNames[0]).append(IS);
738       (not ? buf.append(NOT) : buf).append(NULL);
739       int i = 1;
740       while(i < columnNames.length)
741       {
742          buf.append(AND).append(identifier).append(columnNames[i++]).append(IS);
743          (not ? buf.append(NOT) : buf).append(NULL);
744       }
745       return buf;
746    }
747
748    // =======================================================================
749
// Join Clause
750
// parent.pkColumnName0=child.fkColumnName0
751
// [AND parent.pkColumnName1=child.fkColumnName1
752
// [AND parent.pkColumnName2=child.fkColumnName2 [...]]]
753
// =======================================================================
754

755    public static StringBuffer JavaDoc getJoinClause(JDBCAbstractCMRFieldBridge cmrField,
756                                             String JavaDoc parentAlias,
757                                             String JavaDoc childAlias,
758                                             StringBuffer JavaDoc buf)
759    {
760       JDBCAbstractEntityBridge parentEntity = cmrField.getEntity();
761       JDBCAbstractEntityBridge childEntity = (JDBCAbstractEntityBridge)cmrField.getRelatedEntity();
762
763       JDBCFieldBridge parentField;
764       JDBCFieldBridge childField;
765
766       if(cmrField.hasForeignKey())
767       {
768          // parent has the foreign keys
769
JDBCFieldBridge[] parentFkFields = cmrField.getForeignKeyFields();
770          int i = 0;
771          while(i < parentFkFields.length)
772          {
773             parentField = parentFkFields[i++];
774             childField = (JDBCFieldBridge)childEntity.getFieldByName(parentField.getFieldName());
775             getJoinClause(parentField, parentAlias, childField, childAlias, buf);
776             if(i < parentFkFields.length)
777                buf.append(AND);
778          }
779       }
780       else
781       {
782          // child has the foreign keys
783
JDBCFieldBridge[] childFkFields = cmrField.getRelatedCMRField().getForeignKeyFields();
784          int i = 0;
785          while(i < childFkFields.length)
786          {
787             childField = childFkFields[i++];
788             parentField = (JDBCFieldBridge)parentEntity.getFieldByName(childField.getFieldName());
789
790             // add the sql
791
getJoinClause(parentField, parentAlias, childField, childAlias, buf);
792             if(i < childFkFields.length)
793             {
794                buf.append(AND);
795             }
796          }
797       }
798       return buf;
799    }
800
801    public static StringBuffer JavaDoc getRelationTableJoinClause(JDBCAbstractCMRFieldBridge cmrField,
802                                                          String JavaDoc parentAlias,
803                                                          String JavaDoc relationTableAlias,
804                                                          StringBuffer JavaDoc buf)
805    {
806       JDBCAbstractEntityBridge parentEntity = cmrField.getEntity();
807       JDBCFieldBridge parentField;
808       JDBCFieldBridge relationField;
809
810       // parent to relation table join
811
JDBCFieldBridge[] parentFields = cmrField.getTableKeyFields();
812       int i = 0;
813       while(i < parentFields.length)
814       {
815          relationField = parentFields[i++];
816          parentField = (JDBCFieldBridge)parentEntity.getFieldByName(relationField.getFieldName());
817          getJoinClause(parentField, parentAlias, relationField, relationTableAlias, buf);
818          if(i < parentFields.length)
819             buf.append(AND);
820       }
821       return buf;
822    }
823
824    /**
825     * Returns parent.pkColumnName0=child.fkColumnName0
826     * [AND parent.pkColumnName1=child.fkColumnName1
827     * [AND parent.pkColumnName2=child.fkColumnName2 [...]]]
828     */

829    private static StringBuffer JavaDoc getJoinClause(JDBCFieldBridge pkField,
830                                              String JavaDoc parent,
831                                              JDBCFieldBridge fkField,
832                                              String JavaDoc child,
833                                              StringBuffer JavaDoc buf)
834    {
835       return getJoinClause(pkField.getJDBCType(), parent, fkField.getJDBCType(), child, buf);
836    }
837
838    public static StringBuffer JavaDoc getJoinClause(JDBCFieldBridge[] pkFields,
839                                             String JavaDoc parent,
840                                             JDBCFieldBridge[] fkFields,
841                                             String JavaDoc child,
842                                             StringBuffer JavaDoc buf)
843    {
844       if(pkFields.length != fkFields.length)
845       {
846          throw new IllegalArgumentException JavaDoc(
847             "Error createing theta join clause:" +
848             " pkField.size()=" + pkFields.length +
849             " fkField.size()=" + fkFields.length);
850       }
851
852       boolean and = false;
853       for(int i = 0; i < pkFields.length; ++i)
854       {
855          // these types should not be null
856
JDBCType pkType = getJDBCType(pkFields[i]);
857          JDBCType fkType = getJDBCType(fkFields[i]);
858          if(and)
859             buf.append(AND);
860          else
861             and = true;
862          getJoinClause(pkType, parent, fkType, child, buf);
863       }
864       return buf;
865    }
866
867    /**
868     * Returns parent.pkColumnName0=child.fkColumnName0
869     * [AND parent.pkColumnName1=child.fkColumnName1
870     * [AND parent.pkColumnName2=child.fkColumnName2 [...]]]
871     */

872    private static StringBuffer JavaDoc getJoinClause(JDBCType pkType,
873                                              String JavaDoc parent,
874                                              JDBCType fkType,
875                                              String JavaDoc child,
876                                              StringBuffer JavaDoc buf)
877    {
878       if(parent.length() > 0)
879       {
880          parent += '.';
881       }
882       if(child.length() > 0)
883       {
884          child += '.';
885       }
886
887       String JavaDoc[] pkColumnNames = pkType.getColumnNames();
888       String JavaDoc[] fkColumnNames = fkType.getColumnNames();
889       if(pkColumnNames.length != fkColumnNames.length)
890       {
891          throw new IllegalArgumentException JavaDoc("PK and FK have different number of columns");
892       }
893
894       buf.append(parent).append(pkColumnNames[0]).append('=').append(child).append(fkColumnNames[0]);
895       int i = 1;
896       while(i < pkColumnNames.length)
897       {
898          buf.append(AND)
899             .append(parent)
900             .append(pkColumnNames[i])
901             .append('=')
902             .append(child)
903             .append(fkColumnNames[i++]);
904       }
905       return buf;
906    }
907
908    // =======================================================================
909
// Self Compare Where Clause
910
// fromIdentifier.pkColumnName0=toIdentifier.fkColumnName0
911
// [AND fromIdentifier.pkColumnName1=toIdentifier.fkColumnName1
912
// [AND fromIdentifier.pkColumnName2=toIdentifier.fkColumnName2 [...]]]
913
// =======================================================================
914

915    public static StringBuffer JavaDoc getSelfCompareWhereClause(JDBCFieldBridge[] fields,
916                                                         String JavaDoc fromIdentifier,
917                                                         String JavaDoc toIdentifier,
918                                                         StringBuffer JavaDoc buf)
919    {
920       boolean and = false;
921       for(int i = 0; i < fields.length; ++i)
922       {
923          JDBCType type = getJDBCType(fields[i]);
924          if(type != null)
925          {
926             if(and)
927                buf.append(AND);
928             else
929                and = true;
930             getSelfCompareWhereClause(type, fromIdentifier, toIdentifier, buf);
931          }
932       }
933       return buf;
934    }
935
936    private static StringBuffer JavaDoc getSelfCompareWhereClause(JDBCType type,
937                                                          String JavaDoc fromIdentifier,
938                                                          String JavaDoc toIdentifier,
939                                                          StringBuffer JavaDoc buf)
940    {
941       if(fromIdentifier.length() > 0)
942          fromIdentifier += '.';
943       if(toIdentifier.length() > 0)
944          toIdentifier += '.';
945
946       String JavaDoc[] columnNames = type.getColumnNames();
947
948       buf.append(fromIdentifier)
949          .append(columnNames[0])
950          .append('=')
951          .append(toIdentifier)
952          .append(columnNames[0]);
953       int i = 1;
954       while(i < columnNames.length)
955       {
956          buf.append(AND)
957             .append(fromIdentifier)
958             .append(columnNames[i])
959             .append('=')
960             .append(toIdentifier)
961             .append(columnNames[i++]);
962       }
963       return buf;
964    }
965
966    public static StringBuffer JavaDoc getSelfCompareWhereClause(JDBCFieldBridge fromField,
967                                                         JDBCFieldBridge toField,
968                                                         String JavaDoc fromIdentifier,
969                                                         String JavaDoc toIdentifier,
970                                                         String JavaDoc comparison,
971                                                         StringBuffer JavaDoc buf)
972    {
973       return getSelfCompareWhereClause(
974          fromField.getJDBCType(), toField.getJDBCType(), fromIdentifier, toIdentifier, comparison, buf
975       );
976    }
977
978    private static StringBuffer JavaDoc getSelfCompareWhereClause(JDBCType fromType,
979                                                          JDBCType toType,
980                                                          String JavaDoc fromIdentifier,
981                                                          String JavaDoc toIdentifier,
982                                                          String JavaDoc comparison,
983                                                          StringBuffer JavaDoc buf)
984    {
985       if(fromIdentifier.length() > 0)
986          fromIdentifier += '.';
987       if(toIdentifier.length() > 0)
988          toIdentifier += '.';
989
990       String JavaDoc[] fromColumnNames = fromType.getColumnNames();
991       String JavaDoc[] toColumnNames = toType.getColumnNames();
992
993       buf.append(fromIdentifier)
994          .append(fromColumnNames[0])
995          .append(comparison)
996          .append(toIdentifier)
997          .append(toColumnNames[0]);
998       int i = 1;
999       while(i < fromColumnNames.length)
1000      {
1001         buf.append(AND)
1002            .append(fromIdentifier)
1003            .append(fromColumnNames[i])
1004            .append(comparison)
1005            .append(toIdentifier)
1006            .append(toColumnNames[i++]);
1007      }
1008      return buf;
1009   }
1010
1011   public static boolean tableExists(String JavaDoc tableName, DataSource JavaDoc dataSource)
1012      throws DeploymentException
1013   {
1014      Connection JavaDoc con = null;
1015      ResultSet JavaDoc rs = null;
1016      try
1017      {
1018         con = dataSource.getConnection();
1019
1020         // (a j2ee spec compatible jdbc driver has to fully
1021
// implement the DatabaseMetaData)
1022
DatabaseMetaData JavaDoc dmd = con.getMetaData();
1023         String JavaDoc catalog = con.getCatalog();
1024         String JavaDoc schema = null;
1025         String JavaDoc quote = dmd.getIdentifierQuoteString();
1026         if(tableName.startsWith(quote))
1027         {
1028            if(tableName.endsWith(quote) == false)
1029            {
1030               throw new DeploymentException("Mismatched quote in table name: " + tableName);
1031            }
1032            int quoteLength = quote.length();
1033            tableName = tableName.substring(quoteLength, tableName.length() - quoteLength);
1034            if(dmd.storesLowerCaseQuotedIdentifiers())
1035               tableName = tableName.toLowerCase();
1036            else if(dmd.storesUpperCaseQuotedIdentifiers())
1037               tableName = tableName.toUpperCase();
1038         }
1039         else
1040         {
1041            if(dmd.storesLowerCaseIdentifiers())
1042               tableName = tableName.toLowerCase();
1043            else if(dmd.storesUpperCaseIdentifiers())
1044               tableName = tableName.toUpperCase();
1045         }
1046
1047         // Patch #927759: Split tablename into "schema" and "table" separated by '.'
1048
int dotIndex;
1049         if ((dotIndex = tableName.indexOf('.')) != -1)
1050         {
1051            // Yank out schema name ...
1052
schema = tableName.substring(0, dotIndex);
1053            tableName = tableName.substring(dotIndex + 1);
1054         }
1055
1056         rs = dmd.getTables(catalog, schema, tableName, null);
1057         return rs.next();
1058      }
1059      catch(SQLException JavaDoc e)
1060      {
1061         // This should not happen. A J2EE compatiable JDBC driver is
1062
// required fully support metadata.
1063
throw new DeploymentException("Error while checking if table aleady exists "+tableName, e);
1064      }
1065      finally
1066      {
1067         JDBCUtil.safeClose(rs);
1068         JDBCUtil.safeClose(con);
1069      }
1070   }
1071
1072   public static OldColumns getOldColumns(String JavaDoc tableName, DataSource JavaDoc dataSource)
1073      throws DeploymentException
1074   {
1075      Connection JavaDoc con = null;
1076      ResultSet JavaDoc rs = null;
1077      ArrayList JavaDoc columnNames = new ArrayList JavaDoc();
1078      ArrayList JavaDoc typeNames = new ArrayList JavaDoc();
1079      ArrayList JavaDoc columnSizes = new ArrayList JavaDoc();
1080      try
1081      {
1082         con = dataSource.getConnection();
1083
1084         // (a j2ee spec compatible jdbc driver has to fully
1085
// implement the DatabaseMetaData)
1086
DatabaseMetaData JavaDoc dmd = con.getMetaData();
1087         String JavaDoc catalog = con.getCatalog();
1088         String JavaDoc schema = null;
1089         String JavaDoc quote = dmd.getIdentifierQuoteString();
1090         if (tableName.startsWith(quote))
1091         {
1092            if (tableName.endsWith(quote) == false)
1093            {
1094               throw new DeploymentException("Mismatched quote in table name: " + tableName);
1095            }
1096            int quoteLength = quote.length();
1097            tableName = tableName.substring(quoteLength, tableName.length() - quoteLength);
1098            if (dmd.storesLowerCaseQuotedIdentifiers())
1099               tableName = tableName.toLowerCase();
1100            else if (dmd.storesUpperCaseQuotedIdentifiers())
1101               tableName = tableName.toUpperCase();
1102         }
1103         else
1104         {
1105            if (dmd.storesLowerCaseIdentifiers())
1106               tableName = tableName.toLowerCase();
1107            else if (dmd.storesUpperCaseIdentifiers())
1108               tableName = tableName.toUpperCase();
1109         }
1110
1111         // Patch #927759: Split tablename into "schema" and "table" separated by '.'
1112
int dotIndex;
1113         if ((dotIndex = tableName.indexOf('.')) != -1)
1114         {
1115            // Yank out schema name ...
1116
schema = tableName.substring(0, dotIndex);
1117            tableName = tableName.substring(dotIndex + 1);
1118         }
1119
1120         rs = dmd.getColumns(catalog, schema, tableName, null);
1121         while (rs.next())
1122         {
1123            String JavaDoc columnName = rs.getString("COLUMN_NAME");
1124            columnNames.add(columnName == null ? null : columnName.toUpperCase());
1125            typeNames.add(rs.getString("TYPE_NAME"));
1126            columnSizes.add(new Integer JavaDoc(rs.getInt("COLUMN_SIZE")));
1127         }
1128         return new OldColumns(columnNames, typeNames, columnSizes);
1129
1130      }
1131      catch (SQLException JavaDoc e)
1132      {
1133         // This should not happen. A J2EE compatiable JDBC driver is
1134
// required fully support metadata.
1135
throw new DeploymentException("Error while geting column names", e);
1136      }
1137      finally
1138      {
1139         JDBCUtil.safeClose(rs);
1140         JDBCUtil.safeClose(con);
1141      }
1142   }
1143
1144   public static OldIndexes getOldIndexes(String JavaDoc tableName, DataSource JavaDoc dataSource)
1145      throws DeploymentException
1146   {
1147      tableName = unquote(tableName, dataSource);
1148
1149      Connection JavaDoc con = null;
1150      ResultSet JavaDoc rs = null;
1151      ArrayList JavaDoc indexNames = new ArrayList JavaDoc();
1152      ArrayList JavaDoc columnNames = new ArrayList JavaDoc();
1153      ArrayList JavaDoc ascDesc = new ArrayList JavaDoc();
1154      try
1155      {
1156         con = dataSource.getConnection();
1157
1158         // (a j2ee spec compatible jdbc driver has to fully
1159
// implement the DatabaseMetaData)
1160
DatabaseMetaData JavaDoc dmd = con.getMetaData();
1161         String JavaDoc catalog = con.getCatalog();
1162         String JavaDoc schema = null;
1163         if (dmd.storesLowerCaseIdentifiers())
1164            tableName = tableName.toLowerCase();
1165         else if (dmd.storesUpperCaseIdentifiers())
1166            tableName = tableName.toUpperCase();
1167
1168         // Patch #927759: Split tablename into "schema" and "table" separated by '.'
1169
int dotIndex;
1170         if ((dotIndex = tableName.indexOf('.')) != -1)
1171         {
1172            // Yank out schema name ...
1173
schema = tableName.substring(0, dotIndex);
1174            tableName = tableName.substring(dotIndex + 1);
1175         }
1176
1177         rs = dmd.getIndexInfo(catalog, schema, tableName, false, false);
1178         while (rs.next())
1179         {
1180            indexNames.add(rs.getString("INDEX_NAME"));
1181            columnNames.add(rs.getString("COLUMN_NAME"));
1182            ascDesc.add(rs.getString("ASC_OR_DESC"));
1183         }
1184         return new OldIndexes(indexNames, columnNames, ascDesc);
1185
1186      }
1187      catch (SQLException JavaDoc e)
1188      {
1189         // This should not happen. A J2EE compatiable JDBC driver is
1190
// required fully support metadata.
1191
throw new DeploymentException("Error while geting column names", e);
1192      }
1193      finally
1194      {
1195         JDBCUtil.safeClose(rs);
1196         JDBCUtil.safeClose(con);
1197      }
1198   }
1199
1200   public static String JavaDoc unquote(String JavaDoc tableName, DataSource JavaDoc ds)
1201      throws DeploymentException
1202   {
1203      Connection JavaDoc con = null;
1204      try
1205      {
1206         con = ds.getConnection();
1207         String JavaDoc quote = con.getMetaData().getIdentifierQuoteString();
1208         if (tableName.startsWith(quote))
1209         {
1210            if (tableName.endsWith(quote) == false)
1211            {
1212               throw new DeploymentException("Mismatched quote in table name: " + tableName);
1213            }
1214            int quoteLength = quote.length();
1215            tableName = tableName.substring(quoteLength, tableName.length() - quoteLength);
1216         }
1217      }
1218      catch(SQLException JavaDoc e)
1219      {
1220         throw new DeploymentException("Failed to get datasource connection");
1221      }
1222      finally
1223      {
1224         JDBCUtil.safeClose(con);
1225      }
1226      return tableName;
1227   }
1228
1229   private static JDBCType getJDBCType(JDBCFieldBridge field)
1230   {
1231      JDBCType type = field.getJDBCType();
1232      if(type != null && type.getColumnNames().length > 0)
1233      {
1234         return type;
1235      }
1236      return null;
1237   }
1238
1239   public static void dropTable(DataSource JavaDoc dataSource,
1240                                String JavaDoc tableName)
1241      throws DeploymentException
1242   {
1243      Logger log = Logger.getLogger("CLEANER");
1244      String JavaDoc sql = "DROP TABLE " + tableName;
1245      try
1246      {
1247         Connection JavaDoc con = null;
1248         Statement JavaDoc statement = null;
1249         try
1250         {
1251            // execute sql
1252
con = dataSource.getConnection();
1253            statement = con.createStatement();
1254            statement.executeUpdate(sql);
1255         }
1256         finally
1257         {
1258            // make sure to close the connection and statement before
1259
// comitting the transaction or XA will break
1260
JDBCUtil.safeClose(statement);
1261            JDBCUtil.safeClose(con);
1262         }
1263        } catch (Exception JavaDoc e) {
1264            throw new DeploymentException("Error while droping table "+tableName, e);
1265        }
1266        log.info("Dropped table "+tableName+" succesfuly");
1267    }
1268
1269   /**
1270    * utility class to store the information returned by getOldColumns()
1271    */

1272   public static class OldColumns
1273   {
1274      private ArrayList JavaDoc columnNames;
1275      private ArrayList JavaDoc typeNames;
1276      private ArrayList JavaDoc columnSizes;
1277
1278      private OldColumns(ArrayList JavaDoc cn, ArrayList JavaDoc tn, ArrayList JavaDoc cs)
1279      {
1280         columnNames = cn;
1281         typeNames = tn;
1282         columnSizes = cs;
1283      }
1284
1285      public ArrayList JavaDoc getColumnNames()
1286      {
1287         return columnNames;
1288      }
1289
1290      public ArrayList JavaDoc getTypeNames()
1291      {
1292         return typeNames;
1293      }
1294
1295      public ArrayList JavaDoc getColumnSizes()
1296      {
1297         return columnSizes;
1298      }
1299   }
1300
1301   /**
1302    * utility class to store the information returned by getOldColumns()
1303    */

1304   public static class OldIndexes
1305   {
1306      private ArrayList JavaDoc indexNames;
1307      private ArrayList JavaDoc columnNames;
1308      private ArrayList JavaDoc columnAscDesc;
1309
1310      private OldIndexes(ArrayList JavaDoc in, ArrayList JavaDoc cn, ArrayList JavaDoc ad)
1311      {
1312         indexNames = in;
1313         columnNames = cn;
1314         columnAscDesc = ad;
1315      }
1316
1317      public ArrayList JavaDoc getColumnNames()
1318      {
1319         return columnNames;
1320      }
1321
1322      public ArrayList JavaDoc getIndexNames()
1323      {
1324         return indexNames;
1325      }
1326
1327      public ArrayList JavaDoc getColumnAscDesc()
1328      {
1329         return columnAscDesc;
1330      }
1331   }
1332
1333}
1334
Popular Tags