View Javadoc

1   /*
2    * org.riverock.dbrevision - Database revision engine
3    * For more information about DbRevision, please visit project site
4    * http://www.riverock.org
5    *
6    * Copyright (C) 2006-2006, Riverock Software, All Rights Reserved.
7    *
8    * Riverock - The Open-source Java Development Community
9    * http://www.riverock.org
10   *
11   *
12   * This library is free software; you can redistribute it and/or
13   * modify it under the terms of the GNU Lesser General Public
14   * License as published by the Free Software Foundation; either
15   * version 2.1 of the License, or (at your option) any later version.
16   *
17   * This library is distributed in the hope that it will be useful,
18   * but WITHOUT ANY WARRANTY; without even the implied warranty of
19   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20   * Lesser General Public License for more details.
21   *
22   * You should have received a copy of the GNU Lesser General Public
23   * License along with this library; if not, write to the Free Software
24   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25   */
26  package org.riverock.dbrevision.db.impl;
27  
28  import java.io.ByteArrayOutputStream;
29  import java.io.InputStream;
30  import java.sql.Blob;
31  import java.sql.Connection;
32  import java.sql.DatabaseMetaData;
33  import java.sql.PreparedStatement;
34  import java.sql.ResultSet;
35  import java.sql.SQLException;
36  import java.sql.Statement;
37  import java.sql.Types;
38  import java.util.ArrayList;
39  import java.util.List;
40  
41  import org.apache.log4j.Logger;
42  
43  import org.riverock.dbrevision.annotation.schema.db.DbDataFieldData;
44  import org.riverock.dbrevision.annotation.schema.db.DbField;
45  import org.riverock.dbrevision.annotation.schema.db.DbForeignKey;
46  import org.riverock.dbrevision.annotation.schema.db.DbPrimaryKey;
47  import org.riverock.dbrevision.annotation.schema.db.DbPrimaryKeyColumn;
48  import org.riverock.dbrevision.annotation.schema.db.DbSequence;
49  import org.riverock.dbrevision.annotation.schema.db.DbTable;
50  import org.riverock.dbrevision.annotation.schema.db.DbView;
51  import org.riverock.dbrevision.db.Database;
52  import org.riverock.dbrevision.db.DatabaseManager;
53  import org.riverock.dbrevision.exception.DbRevisionException;
54  import org.riverock.dbrevision.utils.DbUtils;
55  import org.riverock.dbrevision.utils.Utils;
56  
57  /**
58   * IBM DB2 connection
59   * $Author: serg_main $
60   *
61   * $Id: DB2Database.java 1141 2006-12-14 14:43:29Z serg_main $
62   *
63   */
64  @SuppressWarnings({"UnusedAssignment"})
65  public class DB2Database extends Database {
66      private static Logger log = Logger.getLogger(DB2Database.class);
67  
68      /**
69       * get family for this adapter
70       * @return family
71       */
72      public Family getFamily() {
73          return Family.DB2;
74      }
75  
76      public void setBlobField(String tableName, String fieldName, byte[] bytes, String whereQuery, Object[] objects, int[] fieldTyped) {
77      }
78  
79      public DB2Database(Connection conn) {
80          super(conn);
81      }
82  
83      public int getMaxLengthStringField() {
84          return 2000;
85      }
86  
87      public boolean isBatchUpdate() {
88          return true;
89      }
90  
91      public boolean isNeedUpdateBracket() {
92          return false;
93      }
94  
95      public boolean isByteArrayInUtf8() {
96          return false;
97      }
98  
99      public boolean isSchemaSupports() {
100         return false;  //To change body of implemented methods use File | Settings | File Templates.
101     }
102 
103     public String getDefaultSchemaName(DatabaseMetaData databaseMetaData) {
104         return null;  //To change body of implemented methods use File | Settings | File Templates.
105     }
106 
107     public String getClobField(ResultSet rs, String nameField) {
108         return getClobField(rs, nameField, 20000);
109     }
110 
111     public byte[] getBlobField(ResultSet rs, String nameField, int maxLength) {
112         try {
113             Blob blob = rs.getBlob(nameField);
114             ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
115             int count;
116             byte buffer[] = new byte[1024];
117 
118             InputStream inputStream = blob.getBinaryStream();
119             while ((count = inputStream.read(buffer)) >= 0) {
120                 outputStream.write(buffer, 0, count);
121                 outputStream.flush();
122             }
123             outputStream.close();
124             return outputStream.toByteArray();
125         }
126         catch (Exception e) {
127             throw new DbRevisionException(e);
128         }
129     }
130 
131     public void createTable(DbTable table) {
132         if (table == null || table.getFields().isEmpty()) {
133             return;
134         }
135 
136         String sql = "create table \"" + table.getName() + "\" " +
137             "(";
138 
139         boolean isFirst = true;
140 
141         for (DbField field : table.getFields()) {
142             if (!isFirst)
143                 sql += ",";
144             else
145                 isFirst = !isFirst;
146 
147             sql += " \"" + field.getName() + "\"";
148             switch (field.getJavaType()) {
149 
150                 case Types.NUMERIC:
151                 case Types.DECIMAL:
152                     sql += " DECIMAL(" + (field.getSize()==null || field.getSize() > 31 ? 31 : field.getSize()) + ',' + field.getDecimalDigit() + ")";
153                     break;
154 
155                 case Types.INTEGER:
156                     sql += " INTEGER";
157                     break;
158 
159                 case Types.DOUBLE:
160                     sql += " DOUBLE";
161                     break;
162 
163                 case Types.CHAR:
164                     sql += " VARCHAR(1)";
165                     break;
166 
167                 case Types.VARCHAR:
168                     sql += " VARCHAR(" + field.getSize() + ")";
169                     break;
170 
171                 case Types.TIMESTAMP:
172                 case Types.DATE:
173                     sql += " TIMESTAMP";
174                     break;
175 
176                 case Types.LONGVARCHAR:
177                     sql += " VARCHAR(10)";
178                     break;
179 
180                 case Types.LONGVARBINARY:
181                     sql += " LONGVARBINARY";
182                     break;
183 
184                 default:
185                     field.setJavaStringType("unknown field type field - " + field.getName() + " javaType - " + field.getJavaType());
186                     System.out.println("unknown field type field - " + field.getName() + " javaType - " + field.getJavaType());
187             }
188 
189             if (field.getDefaultValue() != null) {
190                 String val = field.getDefaultValue().trim();
191 
192 //                if (!val.equalsIgnoreCase("null"))
193 //                    val = "'"+val+"'";
194                 if (DatabaseManager.checkDefaultTimestamp(val))
195                     val = "CURRENT TIMESTAMP";
196 
197                 sql += (" DEFAULT " + val);
198             }
199 
200             if (field.getNullable() == DatabaseMetaData.columnNoNulls) {
201                 sql += " NOT NULL ";
202             }
203         }
204 
205         if (table.getPrimaryKey() != null && table.getPrimaryKey().getColumns().size() > 0) {
206             DbPrimaryKey pk = table.getPrimaryKey();
207 
208             sql += ", CONSTRAINT " + pk.getPkName() + " PRIMARY KEY ( ";
209 
210             int seq = Integer.MIN_VALUE;
211             isFirst = true;
212             for (DbPrimaryKeyColumn primaryKeyColumnType : pk.getColumns()) {
213                 DbPrimaryKeyColumn column = primaryKeyColumnType;
214                 int seqTemp = Integer.MAX_VALUE;
215                 for (DbPrimaryKeyColumn columnTemp : pk.getColumns()) {
216                     if (seq < columnTemp.getKeySeq() && columnTemp.getKeySeq() < seqTemp) {
217                         seqTemp = columnTemp.getKeySeq();
218                         column = columnTemp;
219                     }
220                 }
221                 seq = column.getKeySeq();
222 
223                 if (!isFirst)
224                     sql += ",";
225                 else
226                     isFirst = !isFirst;
227 
228                 sql += column.getColumnName();
229             }
230             sql += " )";
231         }
232 
233         sql += " )";
234 
235         Statement ps = null;
236         try {
237             ps = this.getConnection().createStatement();
238             ps.executeUpdate(sql);
239             this.getConnection().commit();
240         }
241         catch (SQLException e) {
242             throw new DbRevisionException(e);
243         }
244         finally {
245             DbUtils.close(ps);
246             ps = null;
247         }
248 
249     }
250 
251     public void createForeignKey(DbTable view) {
252     }
253 
254     public void dropTable(DbTable table) {
255         if (table == null)
256             return;
257 
258         dropTable(table.getName());
259     }
260 
261     public void dropTable(String nameTable) {
262         if (nameTable == null || nameTable.trim().length() == 0)
263             return;
264 
265         String sql = "drop table " + nameTable;
266 
267         Statement ps = null;
268         try {
269             ps = this.getConnection().createStatement();
270             ps.executeUpdate(sql);
271         }
272         catch (SQLException e) {
273             throw new DbRevisionException(e);
274         }
275         finally {
276             DbUtils.close(ps);
277             ps = null;
278         }
279     }
280 
281     public void dropSequence(String nameSequence) {
282     }
283 
284     public void dropConstraint(DbForeignKey impPk) {
285         if (impPk == null) {
286             return;
287         }
288 
289         String sql = "ALTER TABLE " + impPk.getPkTableName() + " DROP CONSTRAINT " + impPk.getPkName();
290 
291         PreparedStatement ps = null;
292         try {
293             ps = this.getConnection().prepareStatement(sql);
294             ps.executeUpdate();
295         }
296         catch (SQLException e) {
297             throw new DbRevisionException(e);
298         }
299         finally {
300             DbUtils.close(ps);
301             ps = null;
302         }
303     }
304 
305     public void addColumn(DbTable table, DbField field) {
306     }
307 
308     public String getOnDeleteSetNull() {
309         return null;
310     }
311 
312     public String getDefaultTimestampValue() {
313         return "CURRENT TIMESTAMP";
314     }
315 
316     public List<DbView> getViewList(String schemaPattern, String tablePattern) {
317         return DatabaseManager.getViewList(getConnection(), schemaPattern, tablePattern);
318     }
319 
320     public List<DbSequence> getSequnceList(String schemaPattern) {
321         return new ArrayList<DbSequence>();
322     }
323 
324     public String getViewText(DbView view) {
325         return null;
326     }
327 
328     public void createView(DbView view) {
329         if (view == null ||
330             view.getName() == null || view.getName().length() == 0 ||
331             view.getText() == null || view.getText().length() == 0
332         )
333             return;
334 
335         String sql_ =
336             "CREATE VIEW " + view.getName() +
337             " AS " +
338             Utils.replaceStringArray(view.getText(),
339                 new String[][]{{"||", "+"}, {"\n", " "}}).trim();
340 
341         Statement ps = null;
342         try {
343             ps = this.getConnection().createStatement();
344             ps.execute(sql_);
345         }
346         catch (SQLException e) {
347             String errorString = "Error create view. Error code " + e.getErrorCode() + "\n" + sql_;
348             log.error(errorString, e);
349             throw new DbRevisionException(errorString, e);
350         }
351         finally {
352             DbUtils.close(ps);
353             ps = null;
354         }
355     }
356 
357     public void createSequence(DbSequence seq) {
358     }
359 
360     public void setLongVarbinary(PreparedStatement ps, int index, DbDataFieldData fieldData) {
361         try {
362             ps.setNull(index, Types.VARCHAR);
363         }
364         catch (SQLException e) {
365             throw new DbRevisionException(e);
366         }
367     }
368 
369     public void setLongVarchar(PreparedStatement ps, int index, DbDataFieldData fieldData) {
370         try {
371             ps.setString(index, "");
372         }
373         catch (SQLException e) {
374             throw new DbRevisionException(e);
375         }
376     }
377 
378     public String getClobField(ResultSet rs, String nameField, int maxLength) {
379         return null;
380     }
381 /*
382             CLOB clob = ((OracleResultSet) rs).getCLOB(nameField);
383 
384             if (clob == null)
385                 return null;
386 
387             return clob.getSubString(1, maxLength);
388         }
389 */
390 
391     public boolean testExceptionTableNotFound(Exception e) {
392         if (e instanceof SQLException) {
393             if (((SQLException) e).getErrorCode() == -204)
394                 return true;
395         }
396         return false;
397     }
398 
399     public boolean testExceptionIndexUniqueKey(Exception e, String index) {
400         if (e instanceof SQLException) {
401             if (((SQLException) e).getErrorCode() == -(org.hsqldb.Trace.VIOLATION_OF_UNIQUE_INDEX))
402                 return true;
403         }
404 /*
405         if ((e instanceof SQLException) &&
406                 ((e.toString().indexOf("ORA-00001") != -1) &&
407                 (e.toString().indexOf(index) != -1)))
408 
409             return true;
410 */
411         return false;
412     }
413 
414     public boolean testExceptionIndexUniqueKey(Exception e) {
415         return false;
416     }
417 
418     public boolean testExceptionTableExists(Exception e) {
419         if (e instanceof SQLException) {
420             if (((SQLException) e).getErrorCode() == -601)
421                 return true;
422         }
423         return false;
424     }
425 
426     public boolean testExceptionViewExists(Exception e) {
427         if (e instanceof SQLException) {
428             if (((SQLException) e).getErrorCode() == -601)
429                 return true;
430         }
431         return false;
432     }
433 
434     public boolean testExceptionSequenceExists(Exception e) {
435         return false;
436     }
437 
438     public boolean testExceptionConstraintExists(Exception e) {
439         if (e instanceof SQLException) {
440             if (((SQLException) e).getErrorCode() == -(org.hsqldb.Trace.CONSTRAINT_ALREADY_EXISTS))
441                 return true;
442         }
443         return false;
444     }
445 }