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.commons.lang.StringUtils;
42 import org.apache.log4j.Logger;
43
44 import org.riverock.dbrevision.annotation.schema.db.DbDataFieldData;
45 import org.riverock.dbrevision.annotation.schema.db.DbField;
46 import org.riverock.dbrevision.annotation.schema.db.DbForeignKey;
47 import org.riverock.dbrevision.annotation.schema.db.DbPrimaryKey;
48 import org.riverock.dbrevision.annotation.schema.db.DbPrimaryKeyColumn;
49 import org.riverock.dbrevision.annotation.schema.db.DbSequence;
50 import org.riverock.dbrevision.annotation.schema.db.DbTable;
51 import org.riverock.dbrevision.annotation.schema.db.DbView;
52 import org.riverock.dbrevision.db.Database;
53 import org.riverock.dbrevision.db.DatabaseManager;
54 import org.riverock.dbrevision.exception.DbRevisionException;
55 import org.riverock.dbrevision.utils.DbUtils;
56
57
58
59
60
61
62
63
64 @SuppressWarnings({"UnusedAssignment"})
65 public class HyperSonicDatabase extends Database {
66 private static Logger log = Logger.getLogger( HyperSonicDatabase.class );
67
68
69
70
71
72 public Family getFamily() {
73 return Family.HYPERSONIC;
74 }
75
76 public void setBlobField(String tableName, String fieldName, byte[] bytes, String whereQuery, Object[] objects, int[] fieldTyped) {
77 }
78
79 public HyperSonicDatabase(Connection conn) {
80 super(conn);
81 }
82
83 public int getMaxLengthStringField() {
84 return 1000000;
85 }
86
87 public boolean isBatchUpdate() {
88 return false;
89 }
90
91 public boolean isNeedUpdateBracket() {
92 return true;
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
105 return "PUBLIC";
106 }
107
108 public String getClobField(ResultSet rs, String nameField) {
109 return getClobField(rs, nameField, 20000);
110 }
111
112 public byte[] getBlobField(ResultSet rs, String nameField, int maxLength) {
113 try {
114 Blob blob = rs.getBlob(nameField);
115 ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
116 int count;
117 byte buffer[] = new byte[1024];
118
119 InputStream inputStream = blob.getBinaryStream();
120 while ((count = inputStream.read(buffer)) >= 0) {
121 outputStream.write(buffer, 0, count);
122 outputStream.flush();
123 }
124 outputStream.close();
125 return outputStream.toByteArray();
126 }
127 catch (Exception e) {
128 throw new DbRevisionException(e);
129 }
130 }
131
132 public void createTable(DbTable table) {
133 if (table == null || table.getFields().isEmpty()) {
134 return;
135 }
136
137 String sql = "create table \"" + table.getName() + "\"\n" +
138 "(";
139
140 try {
141 boolean isFirst = true;
142
143 for (DbField field : table.getFields()) {
144 if (!isFirst) {
145 sql += ",";
146 }
147 else {
148 isFirst = !isFirst;
149 }
150
151 sql += "\n" + field.getName() + "";
152 int fieldType = field.getJavaType();
153 switch (fieldType) {
154
155 case Types.NUMERIC:
156 case Types.DECIMAL:
157 sql += " DECIMAL";
158 break;
159
160 case Types.INTEGER:
161 sql += " INTEGER";
162 break;
163
164 case Types.DOUBLE:
165 sql += " DOUBLE";
166 break;
167
168 case Types.CHAR:
169 case Types.VARCHAR:
170 sql += " VARCHAR";
171 break;
172
173 case Types.DATE:
174 case Types.TIMESTAMP:
175 sql += " TIMESTAMP";
176 break;
177
178 case Types.LONGVARCHAR:
179
180 sql += " LONGVARCHAR";
181 break;
182
183 case Types.LONGVARBINARY:
184 case Types.BLOB:
185
186 sql += " LONGVARBINARY";
187 break;
188
189 case Types.CLOB:
190 sql += " LONGVARCHAR";
191 break;
192
193 default:
194 field.setJavaStringType("unknown field type field - " + field.getName() + " javaType - " + field.getJavaType());
195 System.out.println("unknown field type field - " + field.getName() + " javaType - " + field.getJavaType());
196 }
197
198 if (field.getDefaultValue() != null) {
199 String val = field.getDefaultValue().trim();
200
201 if (StringUtils.isNotBlank(val)) {
202 switch (fieldType) {
203 case Types.CHAR:
204 case Types.VARCHAR:
205 val = "'" + val + "'";
206 break;
207 case Types.TIMESTAMP:
208 case Types.DATE:
209 if (DatabaseManager.checkDefaultTimestamp(val)) {
210 val = "'CURRENT_TIMESTAMP'";
211 }
212
213 break;
214 default:
215 }
216 sql += (" DEFAULT " + val);
217 }
218 }
219
220 if (field.getNullable() == DatabaseMetaData.columnNoNulls) {
221 sql += " NOT NULL ";
222 }
223 }
224 if (table.getPrimaryKey() != null && table.getPrimaryKey().getColumns().size() > 0) {
225 DbPrimaryKey pk = table.getPrimaryKey();
226
227
228
229
230
231
232 sql += ",\nCONSTRAINT " + pk.getPkName() + " PRIMARY KEY (\n";
233
234 int seq = Integer.MIN_VALUE;
235 isFirst = true;
236 for (DbPrimaryKeyColumn column : pk.getColumns()) {
237 int seqTemp = Integer.MAX_VALUE;
238 for (DbPrimaryKeyColumn columnTemp : pk.getColumns()) {
239 if (seq < columnTemp.getKeySeq() && columnTemp.getKeySeq() < seqTemp) {
240 seqTemp = columnTemp.getKeySeq();
241 column = columnTemp;
242 }
243 }
244 seq = column.getKeySeq();
245
246 if (!isFirst) {
247 sql += ",";
248 }
249 else {
250 isFirst = !isFirst;
251 }
252
253 sql += column.getColumnName();
254 }
255 sql += "\n)";
256 }
257 sql += "\n)";
258
259 Statement ps = null;
260 try {
261 ps = this.getConnection().createStatement();
262 ps.execute(sql);
263 }
264 finally {
265 DbUtils.close(ps);
266 ps = null;
267 }
268 }
269 catch (Exception e) {
270 log.error("sql: " + sql);
271 throw new DbRevisionException(e);
272 }
273
274 }
275
276 public void createForeignKey(DbTable view) {
277 }
278
279 public void dropTable(DbTable table) {
280 dropTable(table.getName());
281 }
282
283 public void dropTable(String nameTable) {
284 if (nameTable == null) {
285 return;
286 }
287 String sql = "drop table \"" + nameTable + "\"\n";
288 PreparedStatement ps = null;
289 try {
290 ps = this.getConnection().prepareStatement(sql);
291 ps.executeUpdate();
292 }
293 catch (SQLException e) {
294 throw new DbRevisionException(e);
295 }
296 finally {
297 DbUtils.close(ps);
298 ps = null;
299 }
300 }
301
302 public void dropSequence(String nameSequence) {
303 }
304
305 public void dropConstraint(DbForeignKey impPk) {
306 if (impPk == null)
307 return;
308
309 String sql = "ALTER TABLE " + impPk.getPkTableName() + " DROP CONSTRAINT " + impPk.getPkName();
310
311 PreparedStatement ps = null;
312 try {
313 ps = this.getConnection().prepareStatement(sql);
314 ps.executeUpdate();
315 }
316 catch (SQLException e) {
317 throw new DbRevisionException(e);
318 }
319 finally {
320 DbUtils.close(ps);
321 ps = null;
322 }
323 }
324
325 public void addColumn(DbTable table, DbField field) {
326 String sql = "alter table \"" + table.getName() + "\" add column " + field.getName() + " ";
327
328 int fieldType = field.getJavaType();
329 switch (fieldType) {
330
331 case Types.NUMERIC:
332 case Types.DECIMAL:
333 sql += " DECIMAL";
334 break;
335
336 case Types.INTEGER:
337 sql += " INTEGER";
338 break;
339
340 case Types.DOUBLE:
341 sql += " DOUBLE";
342 break;
343
344 case Types.CHAR:
345 case Types.VARCHAR:
346 sql += " VARCHAR";
347 break;
348
349 case Types.TIMESTAMP:
350 case Types.DATE:
351 sql += " TIMESTAMP";
352 break;
353
354 case Types.LONGVARCHAR:
355
356 sql += " LONGVARCHAR";
357 break;
358
359 case Types.LONGVARBINARY:
360
361 sql += " LONGVARBINARY";
362 break;
363
364 default:
365 String errorString = "unknown field type field - " + field.getName() + " javaType - " + field.getJavaType();
366 log.error(errorString);
367 throw new DbRevisionException(errorString);
368 }
369
370 if (field.getDefaultValue() != null) {
371 String val = field.getDefaultValue().trim();
372
373 if (StringUtils.isNotBlank(val)) {
374 switch (fieldType) {
375 case Types.CHAR:
376 case Types.VARCHAR:
377 val = "'" + val + "'";
378 break;
379 case Types.TIMESTAMP:
380 case Types.DATE:
381
382
383
384 break;
385 default:
386 }
387 sql += (" DEFAULT " + val);
388 }
389 }
390
391 if (field.getNullable() == DatabaseMetaData.columnNoNulls) {
392 sql += " NOT NULL ";
393 }
394
395
396 if (log.isDebugEnabled())
397 log.debug("addColumn sql - \n" + sql);
398
399 PreparedStatement ps = null;
400 try {
401 ps = this.getConnection().prepareStatement(sql);
402 ps.executeUpdate();
403 }
404 catch (SQLException e) {
405 throw new DbRevisionException(e);
406 }
407 finally {
408 DbUtils.close(ps);
409 ps = null;
410 }
411 }
412
413 public String getOnDeleteSetNull() {
414 return "";
415 }
416
417 public String getDefaultTimestampValue() {
418 return "current_timestamp";
419 }
420
421 public List<DbView> getViewList(String schemaPattern, String tablePattern) {
422 return DatabaseManager.getViewList(getConnection(), schemaPattern, tablePattern);
423 }
424
425 public List<DbSequence> getSequnceList(String schemaPattern) {
426 return new ArrayList<DbSequence>();
427 }
428
429 public String getViewText(DbView view) {
430 return null;
431 }
432
433 public void createView(DbView view) {
434 if (view == null ||
435 view.getName() == null || view.getName().length() == 0 ||
436 view.getText() == null || view.getText().length() == 0
437 )
438 return;
439
440 String sql_ = "create VIEW " + view.getName() + " as " + view.getText();
441 PreparedStatement ps = null;
442 try {
443 ps = this.getConnection().prepareStatement(sql_);
444 ps.executeUpdate();
445 }
446 catch (SQLException e) {
447 throw new DbRevisionException(e);
448 } finally {
449 DbUtils.close(ps);
450 ps = null;
451 }
452 }
453
454 public void createSequence(DbSequence seq) {
455 }
456
457 public void setLongVarbinary(PreparedStatement ps, int index, DbDataFieldData fieldData) {
458 try {
459 ps.setNull(index, Types.LONGVARBINARY);
460 }
461 catch (SQLException e) {
462 throw new DbRevisionException(e);
463 }
464 }
465
466 public void setLongVarchar(PreparedStatement ps, int index, DbDataFieldData fieldData) {
467 try {
468 ps.setNull(index, Types.LONGVARCHAR);
469 }
470 catch (SQLException e) {
471 throw new DbRevisionException(e);
472 }
473 }
474
475 public String getClobField(ResultSet rs, String nameField, int maxLength) {
476 return null;
477 }
478
479
480
481
482
483
484
485
486
487
488 public boolean testExceptionTableNotFound(Exception e) {
489 if (e == null)
490 return false;
491
492 if (e instanceof SQLException) {
493 if (((SQLException) e).getErrorCode() == -(org.hsqldb.Trace.TABLE_NOT_FOUND))
494 return true;
495 }
496 return false;
497 }
498
499 public boolean testExceptionIndexUniqueKey(Exception e, String index) {
500 if (e == null)
501 return false;
502
503 if (e instanceof SQLException) {
504 if (((SQLException) e).getErrorCode() == -(org.hsqldb.Trace.VIOLATION_OF_UNIQUE_INDEX) &&
505 (e.toString().indexOf(index) != -1))
506 return true;
507 }
508 return false;
509 }
510
511 public boolean testExceptionIndexUniqueKey(Exception e) {
512 if (e == null)
513 return false;
514
515 if (e instanceof SQLException) {
516 if (((SQLException) e).getErrorCode() == -(org.hsqldb.Trace.VIOLATION_OF_UNIQUE_INDEX))
517 return true;
518 }
519 return false;
520 }
521
522 public boolean testExceptionTableExists(Exception e) {
523 if (e == null)
524 return false;
525
526 if (e instanceof SQLException) {
527 if (((SQLException) e).getErrorCode() == -(org.hsqldb.Trace.TABLE_ALREADY_EXISTS))
528 return true;
529 }
530 return false;
531 }
532
533 public boolean testExceptionViewExists(Exception e) {
534 if (e == null)
535 return false;
536
537 if (e instanceof SQLException) {
538 if (((SQLException) e).getErrorCode() == -(org.hsqldb.Trace.VIEW_ALREADY_EXISTS))
539 return true;
540 }
541 return false;
542 }
543
544 public boolean testExceptionSequenceExists(Exception e) {
545 return false;
546 }
547
548 public boolean testExceptionConstraintExists(Exception e) {
549 if (e == null)
550 return false;
551
552 if (e instanceof SQLException) {
553 if (((SQLException) e).getErrorCode() == -(org.hsqldb.Trace.CONSTRAINT_ALREADY_EXISTS))
554 return true;
555 }
556 return false;
557 }
558 }