1 21 package oracle.toplink.essentials.platform.database; 23 24 import java.io.*; 25 import java.util.*; 26 import java.math.BigDecimal ; 27 import java.math.BigInteger ; 28 import java.sql.PreparedStatement ; 29 import java.sql.SQLException ; 30 import oracle.toplink.essentials.exceptions.ValidationException; 31 import oracle.toplink.essentials.expressions.ExpressionOperator; 32 import oracle.toplink.essentials.descriptors.ClassDescriptor; 33 import oracle.toplink.essentials.internal.databaseaccess.FieldTypeDefinition; 34 import oracle.toplink.essentials.internal.expressions.FunctionExpression; 35 import oracle.toplink.essentials.internal.expressions.RelationExpression; 36 import oracle.toplink.essentials.internal.sessions.AbstractSession; 37 import oracle.toplink.essentials.internal.helper.*; 38 import oracle.toplink.essentials.queryframework.ValueReadQuery; 39 import oracle.toplink.essentials.tools.schemaframework.FieldDefinition; 40 import oracle.toplink.essentials.sequencing.Sequence; 41 import oracle.toplink.essentials.sequencing.DefaultSequence; 42 import oracle.toplink.essentials.sequencing.NativeSequence; 43 import oracle.toplink.essentials.sessions.DatabaseSession; 44 45 57 public class PostgreSQLPlatform extends DatabasePlatform { 58 59 public PostgreSQLPlatform() { 60 super(); 61 } 62 63 76 protected void appendBoolean(Boolean bool, Writer writer) throws IOException { 77 if (bool.booleanValue()) { 78 writer.write("\'1\'"); 79 } else { 80 writer.write("\'0\'"); 81 } 82 } 83 84 88 protected void initializePlatformOperators() { 89 super.initializePlatformOperators(); 90 addOperator(ExpressionOperator.simpleLogicalNoParens(ExpressionOperator.Concat, "||")); 91 addOperator(ExpressionOperator.simpleTwoArgumentFunction(ExpressionOperator.Nvl, "NULLIF")); 92 addOperator(operatorLocate()); 93 } 94 95 96 101 public ValueReadQuery getTimestampQuery() { 102 if (timestampQuery == null) { 103 timestampQuery = new ValueReadQuery(); 104 timestampQuery.setSQLString("SELECT NOW()"); 105 } 106 return timestampQuery; 107 108 } 109 110 111 115 public String getInOutputProcedureToken() { 116 return "OUT"; 117 } 118 119 123 public boolean shouldPrintOutputTokenAtStart() { 124 return false; 126 } 127 128 132 public boolean isPostgreSQL() { 133 return true; 134 } 135 136 139 protected String getCreateTempTableSqlSuffix() { 140 return " ON COMMIT PRESERVE ROWS"; 142 } 143 144 public boolean supportsNativeSequenceNumbers() { 145 return true; 146 } 147 148 154 public boolean shouldNativeSequenceAcquireValueAfterInsert() { 155 return true; 156 } 157 158 159 163 public ValueReadQuery buildSelectQueryForNativeSequence(String seqName, Integer size) { 164 ValueReadQuery selectQuery = new ValueReadQuery(); 165 selectQuery.setSQLString("select currval(\'" + seqName + "\')"); 166 return selectQuery; 167 } 168 169 170 173 protected String getCreateTempTableSqlBodyForTable(DatabaseTable table) { 174 return null; 178 } 179 180 184 public void printFieldIdentityClause(Writer writer) throws ValidationException { 185 try { 186 writer.write(" SERIAL"); 187 } catch (IOException ioException) { 188 throw ValidationException.fileError(ioException); 189 } 190 } 191 192 protected Hashtable buildFieldTypes() { 193 Hashtable fieldTypeMapping = new Hashtable(); 194 195 fieldTypeMapping.put(Boolean .class, new FieldTypeDefinition("BOOLEAN", false)); 196 197 fieldTypeMapping.put(Integer .class, new FieldTypeDefinition("INTEGER", false)); 198 fieldTypeMapping.put(Long .class, new FieldTypeDefinition("BIGINT", false)); 199 fieldTypeMapping.put(Float .class, new FieldTypeDefinition("FLOAT")); 200 fieldTypeMapping.put(Double .class, new FieldTypeDefinition("FLOAT", false)); 201 fieldTypeMapping.put(Short .class, new FieldTypeDefinition("SMALLINT", false)); 202 fieldTypeMapping.put(Byte .class, new FieldTypeDefinition("SMALLINT", false)); 203 fieldTypeMapping.put(java.math.BigInteger .class, new FieldTypeDefinition("BIGINT", false)); 204 fieldTypeMapping.put(java.math.BigDecimal .class, new FieldTypeDefinition("DECIMAL",38)); 205 fieldTypeMapping.put(Number .class, new FieldTypeDefinition("DECIMAL",38)); 206 207 fieldTypeMapping.put(String .class, new FieldTypeDefinition("VARCHAR", 255)); 208 fieldTypeMapping.put(Character .class, new FieldTypeDefinition("CHAR", 1)); 209 210 fieldTypeMapping.put(Byte [].class, new FieldTypeDefinition("BYTEA")); 211 fieldTypeMapping.put(Character [].class, new FieldTypeDefinition("TEXT")); 212 fieldTypeMapping.put(byte[].class, new FieldTypeDefinition("BYTEA")); 213 fieldTypeMapping.put(char[].class, new FieldTypeDefinition("TEXT")); 214 fieldTypeMapping.put(java.sql.Blob .class, new FieldTypeDefinition("BYTEA")); 215 fieldTypeMapping.put(java.sql.Clob .class, new FieldTypeDefinition("TEXT")); 216 217 fieldTypeMapping.put(java.sql.Date .class, new FieldTypeDefinition("DATE", false)); 218 fieldTypeMapping.put(java.sql.Time .class, new FieldTypeDefinition("TIME", false)); 219 fieldTypeMapping.put(java.sql.Timestamp .class, new FieldTypeDefinition("TIMESTAMP", false)); 220 221 return fieldTypeMapping; 222 } 223 224 228 protected ExpressionOperator operatorLocate() { 229 ExpressionOperator result = new ExpressionOperator(); 230 result.setSelector(ExpressionOperator.Locate); 231 Vector v = new Vector(3); 232 v.addElement("STRPOS("); 233 v.addElement(", "); 234 v.addElement(")"); 235 result.printsAs(v); 236 result.bePrefix(); 237 result.setNodeClass(RelationExpression.class); 238 return result; 239 } 240 241 242 245 public boolean supportsGlobalTempTables() { 246 return true; 247 } 248 249 252 protected String getCreateTempTableSqlPrefix() { 253 return "CREATE GLOBAL TEMPORARY TABLE "; 254 } 255 256 261 public int getMaxFieldNameSize() { 262 return 63; 267 } 268 269 274 public String getProcedureBeginString() { 275 return "AS $$ BEGIN "; 276 } 277 278 282 public String getProcedureEndString() { 283 return "; END ; $$ LANGUAGE plpgsql;"; 284 } 285 286 290 public String getProcedureCallHeader() { 291 return "EXECUTE "; 292 } 293 294 298 public String getAssignmentString() { 299 return ":= "; 300 } 301 302 public void printFieldTypeSize(Writer writer, FieldDefinition field, 303 FieldTypeDefinition fieldType, AbstractSession session, String qualifiedFieldName) throws IOException { 304 if(!shouldAcquireSequenceValueAfterInsert(session, qualifiedFieldName)) { 305 writer.write(fieldType.getName()); 306 if ((fieldType.isSizeAllowed()) && ((field.getSize() != 0) || (fieldType.isSizeRequired()))) { 307 writer.write("("); 308 if (field.getSize() == 0) { 309 writer.write(new Integer (fieldType.getDefaultSize()).toString()); 310 } else { 311 writer.write(new Integer (field.getSize()).toString()); 312 } 313 if (field.getSubSize() != 0) { 314 writer.write(","); 315 writer.write(new Integer (field.getSubSize()).toString()); 316 } else if (fieldType.getDefaultSubSize() != 0) { 317 writer.write(","); 318 writer.write(new Integer (fieldType.getDefaultSubSize()).toString()); 319 } 320 writer.write(")"); 321 } 322 } 323 } 324 325 public void printFieldUnique(Writer writer, boolean isUnique, 326 AbstractSession session, String qualifiedFieldName) throws IOException { 327 if(!shouldAcquireSequenceValueAfterInsert(session, qualifiedFieldName)) { 328 if (isUnique) { 329 if (supportsPrimaryKeyConstraint()) { 330 writer.write(" UNIQUE"); 331 } 332 } 333 } 334 } 335 336 339 public boolean shouldUseJDBCOuterJoinSyntax() { 340 return false; 341 } 342 343 349 protected void setPrimitiveParameterValue(final PreparedStatement statement, final int index, 350 final Object parameter) throws SQLException { 351 if (parameter instanceof Number ) { 352 Number number = (Number ) parameter; 353 if (number instanceof Integer ) { 354 statement.setInt(index, number.intValue()); 355 } else if (number instanceof Long ) { 356 statement.setLong(index, number.longValue()); 357 } else if (number instanceof Short ) { 358 statement.setShort(index, number.shortValue()); 359 } else if (number instanceof Byte ) { 360 statement.setByte(index, number.byteValue()); 361 } else if (number instanceof Double ) { 362 statement.setDouble(index, number.doubleValue()); 363 } else if (number instanceof Float ) { 364 statement.setFloat(index, number.floatValue()); 365 } else if (number instanceof BigDecimal ) { 366 statement.setBigDecimal(index, (BigDecimal ) number); 367 } else if (number instanceof BigInteger ) { 368 statement.setBigDecimal(index, new BigDecimal ((BigInteger ) number)); 369 } else { 370 statement.setObject(index, parameter); 371 } 372 } else if (parameter instanceof String ) { 373 statement.setString(index, (String )parameter); 374 } else if (parameter instanceof Boolean ) { 375 statement.setBoolean(index, ((Boolean ) parameter).booleanValue()); 376 } else { 377 statement.setObject(index, parameter); 378 } 379 } 380 381 protected String getDBSequenceName(String tableName, String pkFieldName) { 382 StringBuffer seqName = new StringBuffer (tableName); 383 seqName.append("_").append(pkFieldName).append("_seq"); 384 return seqName.toString(); 385 } 386 387 400 public void platformSpecificSequencingInitialization(DatabaseSession session) { 401 Boolean isDefaultSequenceNative = null; 402 403 Iterator iterator = session.getProject().getDescriptors().values().iterator(); 405 Sequence sequence; 406 407 while (iterator.hasNext()) { 408 ClassDescriptor descriptor = (ClassDescriptor)iterator.next(); 409 410 if (descriptor.usesSequenceNumbers()) { 412 String currSequenceName = descriptor.getSequenceNumberName(); 413 sequence = (Sequence)getSequences().get(currSequenceName); 414 415 boolean shouldVerifySequenceName; 416 417 boolean usesDefaultSequence = sequence == null || sequence instanceof DefaultSequence; 418 if(usesDefaultSequence) { 419 if(isDefaultSequenceNative == null) { 421 isDefaultSequenceNative = new Boolean (getDefaultSequence() instanceof NativeSequence); 422 } 423 shouldVerifySequenceName = isDefaultSequenceNative.booleanValue(); 424 } else { 425 shouldVerifySequenceName = sequence instanceof NativeSequence; 426 } 427 428 if(shouldVerifySequenceName) { 429 DatabaseTable tbl = (DatabaseTable)descriptor.getTables().firstElement(); 430 String tableName = tbl.getQualifiedName(); 431 String pkFieldName = descriptor.getSequenceNumberField().getName(); 432 String seqName = getDBSequenceName(tableName, pkFieldName); 433 if(!currSequenceName.equals(seqName)) { 434 descriptor.setSequenceNumberName(seqName); 435 if(sequence != null) { 436 removeSequence(currSequenceName); 437 sequence.setName(seqName); 438 addSequence(sequence); 439 } 440 } 441 } 442 } 443 } 444 } 445 446 } 447 | Popular Tags |