1 19 20 package org.apache.cayenne.dba.oracle; 21 22 import java.lang.reflect.Field ; 23 import java.lang.reflect.Method ; 24 import java.sql.PreparedStatement ; 25 import java.sql.Types ; 26 import java.util.Iterator ; 27 import java.util.List ; 28 29 import org.apache.cayenne.CayenneRuntimeException; 30 import org.apache.cayenne.access.DataNode; 31 import org.apache.cayenne.access.trans.QualifierTranslator; 32 import org.apache.cayenne.access.trans.QueryAssembler; 33 import org.apache.cayenne.access.trans.TrimmingQualifierTranslator; 34 import org.apache.cayenne.access.types.ByteArrayType; 35 import org.apache.cayenne.access.types.ByteType; 36 import org.apache.cayenne.access.types.CharType; 37 import org.apache.cayenne.access.types.DefaultType; 38 import org.apache.cayenne.access.types.ExtendedTypeMap; 39 import org.apache.cayenne.access.types.ShortType; 40 import org.apache.cayenne.dba.JdbcAdapter; 41 import org.apache.cayenne.dba.PkGenerator; 42 import org.apache.cayenne.map.DbAttribute; 43 import org.apache.cayenne.map.DbEntity; 44 import org.apache.cayenne.query.BatchQuery; 45 import org.apache.cayenne.query.InsertBatchQuery; 46 import org.apache.cayenne.query.Query; 47 import org.apache.cayenne.query.SQLAction; 48 import org.apache.cayenne.query.UpdateBatchQuery; 49 50 69 public class OracleAdapter extends JdbcAdapter { 70 71 public static final String ORACLE_FLOAT = "FLOAT"; 72 public static final String ORACLE_BLOB = "BLOB"; 73 public static final String ORACLE_CLOB = "CLOB"; 74 75 public static final String TRIM_FUNCTION = "RTRIM"; 76 public static final String NEW_CLOB_FUNCTION = "EMPTY_CLOB()"; 77 public static final String NEW_BLOB_FUNCTION = "EMPTY_BLOB()"; 78 79 protected static boolean initDone; 80 protected static int oracleCursorType = Integer.MAX_VALUE; 81 protected static Method outputStreamFromBlobMethod; 82 protected static Method writerFromClobMethod; 83 protected static boolean supportsOracleLOB; 84 85 static { 86 initDriverInformation(); 90 } 91 92 protected static void initDriverInformation() { 93 initDone = true; 94 95 try { 97 Class oraTypes = Class.forName("oracle.jdbc.driver.OracleTypes"); 98 Field cursorField = oraTypes.getField("CURSOR"); 99 oracleCursorType = cursorField.getInt(null); 100 101 outputStreamFromBlobMethod = Class.forName("oracle.sql.BLOB").getMethod( 102 "getBinaryOutputStream", 103 new Class [0]); 104 105 writerFromClobMethod = Class.forName("oracle.sql.CLOB").getMethod( 106 "getCharacterOutputStream", 107 new Class [0]); 108 supportsOracleLOB = true; 109 110 } 111 catch (Throwable th) { 112 } 114 } 115 116 public static Method getOutputStreamFromBlobMethod() { 117 return outputStreamFromBlobMethod; 118 } 119 120 public static boolean isSupportsOracleLOB() { 122 return supportsOracleLOB; 123 } 124 125 131 static boolean updatesLOBColumns(BatchQuery query) { 132 boolean isInsert = query instanceof InsertBatchQuery; 133 boolean isUpdate = query instanceof UpdateBatchQuery; 134 135 if (!isInsert && !isUpdate) { 136 return false; 137 } 138 139 List updatedAttributes = (isInsert) 140 ? query.getDbAttributes() 141 : ((UpdateBatchQuery) query).getUpdatedAttributes(); 142 143 Iterator it = updatedAttributes.iterator(); 144 while (it.hasNext()) { 145 int type = ((DbAttribute) it.next()).getType(); 146 if (type == Types.CLOB || type == Types.BLOB) { 147 return true; 148 } 149 } 150 151 return false; 152 } 153 154 public static Method getWriterFromClobMethod() { 155 return writerFromClobMethod; 156 } 157 158 165 public static int getOracleCursorType() { 166 167 if (oracleCursorType == Integer.MAX_VALUE) { 168 throw new CayenneRuntimeException( 169 "No information exists about oracle types. " 170 + "Check that Oracle JDBC driver is available to the application."); 171 } 172 173 return oracleCursorType; 174 } 175 176 public OracleAdapter() { 177 setSupportsBatchUpdates(true); 179 } 180 181 185 protected void configureExtendedTypes(ExtendedTypeMap map) { 186 super.configureExtendedTypes(map); 187 188 map.registerType(new CharType(true, true)); 190 191 map.registerType(new ByteArrayType(true, true)); 193 194 map.registerType(new OracleUtilDateType()); 196 197 map.registerType(new ShortType(true)); 199 map.registerType(new ByteType(true)); 200 201 map.registerType(new OracleIntegerType()); 207 map.registerType(new OracleDoubleType()); 208 } 209 210 214 protected PkGenerator createPkGenerator() { 215 return new OraclePkGenerator(); 216 } 217 218 222 public String dropTable(DbEntity ent) { 223 return "DROP TABLE " + ent.getFullyQualifiedName() + " CASCADE CONSTRAINTS"; 224 } 225 226 230 public DbAttribute buildAttribute( 231 String name, 232 String typeName, 233 int type, 234 int size, 235 int scale, 236 boolean allowNulls) { 237 238 DbAttribute attr = super.buildAttribute( 239 name, 240 typeName, 241 type, 242 size, 243 scale, 244 allowNulls); 245 246 if (type == Types.DECIMAL && scale <= 0) { 247 attr.setType(Types.INTEGER); 248 attr.setScale(-1); 249 } 250 else if (type == Types.OTHER) { 251 if (ORACLE_FLOAT.equals(typeName)) { 254 attr.setType(Types.FLOAT); 255 } 256 else if (ORACLE_BLOB.equals(typeName)) { 257 attr.setType(Types.BLOB); 258 } 259 else if (ORACLE_CLOB.equals(typeName)) { 260 attr.setType(Types.CLOB); 261 } 262 } 263 else if (type == Types.DATE) { 264 if ("DATE".equals(typeName)) { 266 attr.setType(Types.TIMESTAMP); 267 } 268 } 269 270 return attr; 271 } 272 273 276 public QualifierTranslator getQualifierTranslator(QueryAssembler queryAssembler) { 277 return new TrimmingQualifierTranslator( 278 queryAssembler, 279 OracleAdapter.TRIM_FUNCTION); 280 } 281 282 287 public SQLAction getAction(Query query, DataNode node) { 288 return query.createSQLAction(new OracleActionBuilder(this, node 289 .getEntityResolver())); 290 } 291 292 295 final class OracleIntegerType extends DefaultType { 296 297 public OracleIntegerType() { 298 super(Integer .class.getName()); 299 } 300 301 public void setJdbcObject( 302 PreparedStatement st, 303 Object val, 304 int pos, 305 int type, 306 int precision) throws Exception { 307 308 if (val != null) { 309 st.setInt(pos, ((Number ) val).intValue()); 310 } 311 else { 312 super.setJdbcObject(st, val, pos, type, precision); 313 } 314 } 315 } 316 317 320 final class OracleDoubleType extends DefaultType { 321 322 public OracleDoubleType() { 323 super(Double .class.getName()); 324 } 325 326 public void setJdbcObject( 327 PreparedStatement st, 328 Object val, 329 int pos, 330 int type, 331 int precision) throws Exception { 332 333 if (val != null) { 334 st.setDouble(pos, ((Number ) val).doubleValue()); 335 } 336 else { 337 super.setJdbcObject(st, val, pos, type, precision); 338 } 339 } 340 } 341 } 342 | Popular Tags |