1 56 57 package org.objectstyle.cayenne.dba.oracle; 58 59 import java.sql.Connection ; 60 import java.sql.ResultSet ; 61 import java.sql.SQLException ; 62 import java.sql.Statement ; 63 import java.util.ArrayList ; 64 import java.util.Collections ; 65 import java.util.Iterator ; 66 import java.util.List ; 67 68 import org.objectstyle.cayenne.CayenneRuntimeException; 69 import org.objectstyle.cayenne.access.DataNode; 70 import org.objectstyle.cayenne.access.QueryLogger; 71 import org.objectstyle.cayenne.dba.JdbcPkGenerator; 72 import org.objectstyle.cayenne.map.DbEntity; 73 import org.objectstyle.cayenne.map.DbKeyGenerator; 74 75 93 public class OraclePkGenerator extends JdbcPkGenerator { 94 private static final String _SEQUENCE_PREFIX = "pk_"; 95 96 public void createAutoPk(DataNode node, List dbEntities) throws Exception { 97 List sequences = getExistingSequences(node); 98 99 Iterator it = dbEntities.iterator(); 101 while (it.hasNext()) { 102 DbEntity ent = (DbEntity) it.next(); 103 if (!sequences.contains(sequenceName(ent))) { 104 runUpdate(node, createSequenceString(ent)); 105 } 106 } 107 } 108 109 public List createAutoPkStatements(List dbEntities) { 110 List list = new ArrayList (); 111 Iterator it = dbEntities.iterator(); 112 while (it.hasNext()) { 113 DbEntity ent = (DbEntity) it.next(); 114 list.add(createSequenceString(ent)); 115 } 116 117 return list; 118 } 119 120 public void dropAutoPk(DataNode node, List dbEntities) throws Exception { 121 List sequences = getExistingSequences(node); 122 123 Iterator it = dbEntities.iterator(); 125 while (it.hasNext()) { 126 DbEntity ent = (DbEntity) it.next(); 127 if (sequences.contains(stripSchemaName(sequenceName(ent)))) { 128 runUpdate(node, dropSequenceString(ent)); 129 } 130 } 131 } 132 133 public List dropAutoPkStatements(List dbEntities) { 134 List list = new ArrayList (); 135 Iterator it = dbEntities.iterator(); 136 while (it.hasNext()) { 137 DbEntity ent = (DbEntity) it.next(); 138 list.add(dropSequenceString(ent)); 139 } 140 141 return list; 142 } 143 144 protected String createSequenceString(DbEntity ent) { 145 StringBuffer buf = new StringBuffer (); 146 buf 147 .append("CREATE SEQUENCE ") 148 .append(sequenceName(ent)) 149 .append(" START WITH 200") 150 .append(" INCREMENT BY ") 151 .append(pkCacheSize(ent)); 152 return buf.toString(); 153 } 154 155 159 protected String dropSequenceString(DbEntity ent) { 160 StringBuffer buf = new StringBuffer (); 161 buf.append("DROP SEQUENCE ").append(sequenceName(ent)); 162 return buf.toString(); 163 } 164 165 173 protected int pkFromDatabase(DataNode node, DbEntity ent) throws Exception { 174 175 DbKeyGenerator pkGenerator = ent.getPrimaryKeyGenerator(); 176 String pkGeneratingSequenceName; 177 if (pkGenerator != null 178 && DbKeyGenerator.ORACLE_TYPE.equals(pkGenerator.getGeneratorType()) 179 && pkGenerator.getGeneratorName() != null) 180 pkGeneratingSequenceName = pkGenerator.getGeneratorName(); 181 else 182 pkGeneratingSequenceName = sequenceName(ent); 183 184 Connection con = node.getDataSource().getConnection(); 185 try { 186 Statement st = con.createStatement(); 187 try { 188 String sql = "SELECT " + pkGeneratingSequenceName + ".nextval FROM DUAL"; 189 QueryLogger.logQuery( 190 QueryLogger.DEFAULT_LOG_LEVEL, 191 sql, 192 Collections.EMPTY_LIST); 193 ResultSet rs = st.executeQuery(sql); 194 try { 195 if (!rs.next()) { 197 throw new CayenneRuntimeException( 198 "Error generating pk for DbEntity " + ent.getName()); 199 } 200 return rs.getInt(1); 201 } 202 finally { 203 rs.close(); 204 } 205 } 206 finally { 207 st.close(); 208 } 209 } 210 finally { 211 con.close(); 212 } 213 } 214 215 protected int pkCacheSize(DbEntity entity) { 216 DbKeyGenerator keyGenerator = entity.getPrimaryKeyGenerator(); 218 if (keyGenerator != null 219 && DbKeyGenerator.ORACLE_TYPE.equals(keyGenerator.getGeneratorType()) 220 && keyGenerator.getGeneratorName() != null) { 221 222 Integer size = keyGenerator.getKeyCacheSize(); 223 return (size != null && size.intValue() >= 1) 224 ? size.intValue() 225 : super.getPkCacheSize(); 226 } 227 else { 228 return super.getPkCacheSize(); 229 } 230 } 231 232 233 protected String sequenceName(DbEntity entity) { 234 235 DbKeyGenerator keyGenerator = entity.getPrimaryKeyGenerator(); 237 if (keyGenerator != null 238 && DbKeyGenerator.ORACLE_TYPE.equals(keyGenerator.getGeneratorType()) 239 && keyGenerator.getGeneratorName() != null) { 240 241 return keyGenerator.getGeneratorName().toLowerCase(); 242 } 243 else { 244 String entName = entity.getName(); 245 String seqName = _SEQUENCE_PREFIX + entName.toLowerCase(); 246 247 if (entity.getSchema() != null && entity.getSchema().length() > 0) { 248 seqName = entity.getSchema() + "." + seqName; 249 } 250 return seqName; 251 } 252 } 253 254 protected String stripSchemaName(String sequenceName) { 255 int ind = sequenceName.indexOf('.'); 256 return (ind >= 0) ? sequenceName.substring(ind + 1) : sequenceName; 257 } 258 259 263 protected List getExistingSequences(DataNode node) throws SQLException { 264 265 Connection con = node.getDataSource().getConnection(); 267 268 try { 269 Statement sel = con.createStatement(); 270 try { 271 String sql = "SELECT LOWER(SEQUENCE_NAME) FROM ALL_SEQUENCES"; 272 QueryLogger.logQuery( 273 QueryLogger.DEFAULT_LOG_LEVEL, 274 sql, 275 Collections.EMPTY_LIST); 276 ResultSet rs = sel.executeQuery(sql); 277 try { 278 List sequenceList = new ArrayList (); 279 while (rs.next()) { 280 sequenceList.add(rs.getString(1)); 281 } 282 return sequenceList; 283 } 284 finally { 285 rs.close(); 286 } 287 } 288 finally { 289 sel.close(); 290 } 291 } 292 finally { 293 con.close(); 294 } 295 } 296 } 297 | Popular Tags |