1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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
59
60
61
62
63
64 @SuppressWarnings({"UnusedAssignment"})
65 public class DB2Database extends Database {
66 private static Logger log = Logger.getLogger(DB2Database.class);
67
68
69
70
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;
101 }
102
103 public String getDefaultSchemaName(DatabaseMetaData databaseMetaData) {
104 return null;
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
193
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
383
384
385
386
387
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
406
407
408
409
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 }