1 21 package oracle.toplink.essentials.platform.database; 23 24 import java.io.*; 25 import java.sql.*; 26 import java.util.*; 27 import oracle.toplink.essentials.exceptions.*; 28 import oracle.toplink.essentials.expressions.*; 29 import oracle.toplink.essentials.internal.databaseaccess.*; 30 import oracle.toplink.essentials.internal.expressions.*; 31 import oracle.toplink.essentials.internal.helper.*; 32 import oracle.toplink.essentials.queryframework.*; 33 import oracle.toplink.essentials.sessions.SessionProfiler; 34 import oracle.toplink.essentials.internal.sessions.AbstractRecord; 35 import oracle.toplink.essentials.internal.sessions.AbstractSession; 36 37 46 public class SybasePlatform extends oracle.toplink.essentials.platform.database.DatabasePlatform { 47 protected Hashtable typeStrings; 52 53 protected Hashtable getTypeStrings() { 54 if (typeStrings == null) { 55 initializeTypeStrings(); 56 } 57 return typeStrings; 58 } 59 60 protected synchronized void initializeTypeStrings() { 61 if (typeStrings == null) { 62 typeStrings = new Hashtable(30); 63 typeStrings.put(new Integer (Types.ARRAY), "ARRAY"); 64 typeStrings.put(new Integer (Types.BIGINT), "BIGINT"); 65 typeStrings.put(new Integer (Types.BINARY), "BINARY"); 66 typeStrings.put(new Integer (Types.BIT), "BIT"); 67 typeStrings.put(new Integer (Types.BLOB), "BLOB"); 68 typeStrings.put(new Integer (Types.CHAR), "CHAR"); 69 typeStrings.put(new Integer (Types.CLOB), "CLOB"); 70 typeStrings.put(new Integer (Types.DATE), "DATE"); 71 typeStrings.put(new Integer (Types.DECIMAL), "DECIMAL"); 72 typeStrings.put(new Integer (Types.DOUBLE), "DOUBLE"); 73 typeStrings.put(new Integer (Types.FLOAT), "FLOAT"); 74 typeStrings.put(new Integer (Types.INTEGER), "INTEGER"); 75 typeStrings.put(new Integer (Types.JAVA_OBJECT), "JAVA_OBJECT"); 76 typeStrings.put(new Integer (Types.LONGVARBINARY), "LONGVARBINARY"); 77 typeStrings.put(new Integer (Types.LONGVARCHAR), "LONGVARCHAR"); 78 typeStrings.put(new Integer (Types.NULL), "NULL"); 79 typeStrings.put(new Integer (Types.NUMERIC), "NUMERIC"); 80 typeStrings.put(new Integer (Types.OTHER), "OTHER"); 81 typeStrings.put(new Integer (Types.REAL), "REAL"); 82 typeStrings.put(new Integer (Types.REF), "REF"); 83 typeStrings.put(new Integer (Types.SMALLINT), "SMALLINT"); 84 typeStrings.put(new Integer (Types.STRUCT), "STRUCT"); 85 typeStrings.put(new Integer (Types.TIME), "TIME"); 86 typeStrings.put(new Integer (Types.TIMESTAMP), "TIMESTAMP"); 87 typeStrings.put(new Integer (Types.TINYINT), "TINYINT"); 88 typeStrings.put(new Integer (Types.VARBINARY), "VARBINARY"); 89 typeStrings.put(new Integer (Types.VARCHAR), "VARCHAR"); 90 } 91 } 92 93 97 protected void appendByteArray(byte[] bytes, Writer writer) throws IOException { 98 if (usesNativeSQL() && (!usesByteArrayBinding())) { 99 writer.write("0x"); 100 Helper.writeHexString(bytes, writer); 101 } else { 102 super.appendByteArray(bytes, writer); 103 } 104 } 105 106 111 protected void appendDate(java.sql.Date date, Writer writer) throws IOException { 112 if (usesNativeSQL()) { 113 writer.write("'"); 114 writer.write(Helper.printDate(date)); 115 writer.write("'"); 116 } else { 117 super.appendDate(date, writer); 118 } 119 } 120 121 125 protected void appendSybaseTimestamp(java.sql.Timestamp timestamp, Writer writer) throws IOException { 126 writer.write("'"); 127 writer.write(Helper.printTimestampWithoutNanos(timestamp)); 128 writer.write(':'); 129 130 String nanoString = Integer.toString(timestamp.getNanos()); 133 int numberOfZeros = 0; 134 for (int num = Math.min(9 - nanoString.length(), 3); num > 0; num--) { 135 writer.write('0'); 136 numberOfZeros++; 137 } 138 if ((nanoString.length() + numberOfZeros) > 3) { 139 nanoString = nanoString.substring(0, (3 - numberOfZeros)); 140 } 141 writer.write(nanoString); 142 writer.write("'"); 143 } 144 145 150 protected void appendTime(java.sql.Time time, Writer writer) throws IOException { 151 if (usesNativeSQL()) { 152 writer.write("'"); 153 writer.write(Helper.printTime(time)); 154 writer.write("'"); 155 } else { 156 super.appendTime(time, writer); 157 } 158 } 159 160 165 protected void appendTimestamp(java.sql.Timestamp timestamp, Writer writer) throws IOException { 166 if (usesNativeSQL()) { 167 appendSybaseTimestamp(timestamp, writer); 168 } else { 169 super.appendTimestamp(timestamp, writer); 170 } 171 } 172 173 178 protected void appendCalendar(Calendar calendar, Writer writer) throws IOException { 179 if (usesNativeSQL()) { 180 appendSybaseCalendar(calendar, writer); 181 } else { 182 super.appendCalendar(calendar, writer); 183 } 184 } 185 186 190 protected void appendSybaseCalendar(Calendar calendar, Writer writer) throws IOException { 191 writer.write("'"); 192 writer.write(Helper.printCalendar(calendar)); 193 writer.write("'"); 194 } 195 196 200 public ExpressionOperator atan2Operator() { 201 return ExpressionOperator.simpleTwoArgumentFunction(ExpressionOperator.Atan2, "ATN2"); 202 } 203 204 protected Hashtable buildFieldTypes() { 205 Hashtable fieldTypeMapping; 206 207 fieldTypeMapping = new Hashtable(); 208 fieldTypeMapping.put(Boolean .class, new FieldTypeDefinition("BIT default 0", false, false)); 209 210 fieldTypeMapping.put(Integer .class, new FieldTypeDefinition("INTEGER", false)); 211 fieldTypeMapping.put(Long .class, new FieldTypeDefinition("NUMERIC", 19)); 212 fieldTypeMapping.put(Float .class, new FieldTypeDefinition("FLOAT(16)", false)); 213 fieldTypeMapping.put(Double .class, new FieldTypeDefinition("FLOAT(32)", false)); 214 fieldTypeMapping.put(Short .class, new FieldTypeDefinition("SMALLINT", false)); 215 fieldTypeMapping.put(Byte .class, new FieldTypeDefinition("SMALLINT", false)); 216 fieldTypeMapping.put(java.math.BigInteger .class, new FieldTypeDefinition("NUMERIC", 38)); 217 fieldTypeMapping.put(java.math.BigDecimal .class, new FieldTypeDefinition("NUMERIC", 38).setLimits(38, -19, 19)); 218 fieldTypeMapping.put(Number .class, new FieldTypeDefinition("NUMERIC", 38).setLimits(38, -19, 19)); 219 220 fieldTypeMapping.put(String .class, new FieldTypeDefinition("VARCHAR", 255)); 221 fieldTypeMapping.put(Character .class, new FieldTypeDefinition("CHAR", 1)); 222 223 fieldTypeMapping.put(Byte [].class, new FieldTypeDefinition("IMAGE", false)); 224 fieldTypeMapping.put(Character [].class, new FieldTypeDefinition("TEXT", false)); 225 fieldTypeMapping.put(byte[].class, new FieldTypeDefinition("IMAGE", false)); 226 fieldTypeMapping.put(char[].class, new FieldTypeDefinition("TEXT", false)); 227 fieldTypeMapping.put(java.sql.Blob .class, new FieldTypeDefinition("IMAGE", false)); 228 fieldTypeMapping.put(java.sql.Clob .class, new FieldTypeDefinition("TEXT", false)); 229 230 fieldTypeMapping.put(java.sql.Date .class, new FieldTypeDefinition("DATETIME", false)); 231 fieldTypeMapping.put(java.sql.Time .class, new FieldTypeDefinition("DATETIME", false)); 232 fieldTypeMapping.put(java.sql.Timestamp .class, new FieldTypeDefinition("DATETIME", false)); 233 234 return fieldTypeMapping; 235 } 236 237 241 public ValueReadQuery buildSelectQueryForNativeSequence() { 242 ValueReadQuery selectQuery = new ValueReadQuery(); 243 StringWriter writer = new StringWriter(); 244 writer.write("SELECT @@IDENTITY"); 245 selectQuery.setSQLString(writer.toString()); 246 return selectQuery; 247 } 248 249 256 public Object executeStoredProcedure(DatabaseCall dbCall, PreparedStatement statement, DatabaseAccessor accessor, AbstractSession session) throws SQLException { 257 Object result = null; 258 ResultSet resultSet = null; 259 if (!dbCall.getReturnsResultSet()) { 260 accessor.executeDirectNoSelect(statement, dbCall, session); 261 result = accessor.buildOutputRow((CallableStatement)statement, dbCall, session); 262 263 if (dbCall.areManyRowsReturned()) { 266 Vector tempResult = new Vector(); 267 ((Vector)tempResult).add(result); 268 result = tempResult; 269 } 270 } else { 271 session.startOperationProfile(SessionProfiler.STATEMENT_EXECUTE); 274 try { 275 resultSet = statement.executeQuery(); 276 } finally { 277 session.endOperationProfile(SessionProfiler.STATEMENT_EXECUTE); 278 } 279 dbCall.matchFieldOrder(resultSet, accessor, session); 280 281 if (dbCall.isCursorReturned()) { 283 dbCall.setStatement(statement); 284 dbCall.setResult(resultSet); 285 return dbCall; 286 } 287 result = processResultSet(resultSet, dbCall, statement, accessor, session); 288 289 if (dbCall.shouldBuildOutputRow()) { 290 AbstractRecord outputRow = accessor.buildOutputRow((CallableStatement)statement, dbCall, session); 291 dbCall.getQuery().setProperty("output", outputRow); 292 session.getEventManager().outputParametersDetected(outputRow, dbCall); 293 } 294 return result; 295 } 297 return result; 298 } 299 300 304 public String getBatchDelimiterString() { 305 return ""; 306 } 307 308 313 public String getCreationInOutputProcedureToken() { 314 return getInOutputProcedureToken(); 315 } 316 317 322 public String getCreationOutputProcedureToken() { 323 return getOutputProcedureToken(); 324 } 325 326 331 public String getInOutputProcedureToken() { 332 return "OUT"; 333 } 334 335 339 public String getJdbcTypeName(int jdbcType) { 340 return (String )getTypeStrings().get(new Integer (jdbcType)); 341 } 342 343 348 public int getMaxFieldNameSize() { 349 return 22; 350 } 351 352 358 public Vector getNativeTableInfo(String table, String creator, AbstractSession session) { 359 String query = "SELECT * FROM sysobjects WHERE table_type <> 'SYSTEM_TABLE'"; 361 if (table != null) { 362 if (table.indexOf('%') != -1) { 363 query = query + " AND table_name LIKE " + table; 364 } else { 365 query = query + " AND table_name = " + table; 366 } 367 } 368 if (creator != null) { 369 if (creator.indexOf('%') != -1) { 370 query = query + " AND table_owner LIKE " + creator; 371 } else { 372 query = query + " AND table_owner = " + creator; 373 } 374 } 375 return session.executeSelectingCall(new oracle.toplink.essentials.queryframework.SQLCall(query)); 376 } 377 378 383 public String getOutputProcedureToken() { 384 return "OUTPUT"; 385 } 386 387 391 public String getProcedureArgumentString() { 392 return "@"; 393 } 394 395 399 public String getProcedureCallHeader() { 400 return "EXECUTE "; 401 } 402 403 406 public String getStoredProcedureParameterPrefix() { 407 return "@"; 408 } 409 410 415 public String getStoredProcedureTerminationToken() { 416 return " go"; 417 } 418 419 424 public ValueReadQuery getTimestampQuery() { 425 if (timestampQuery == null) { 426 timestampQuery = new ValueReadQuery(); 427 timestampQuery.setSQLString("SELECT GETDATE()"); 428 } 429 return timestampQuery; 430 } 431 432 436 protected void initializePlatformOperators() { 437 super.initializePlatformOperators(); 438 addOperator(operatorOuterJoin()); 439 addOperator(ExpressionOperator.simpleFunction(ExpressionOperator.Today, "GETDATE")); 440 addOperator(ExpressionOperator.simpleFunction(ExpressionOperator.currentDate, "GETDATE")); 443 addOperator(ExpressionOperator.simpleFunction(ExpressionOperator.Length, "CHAR_LENGTH")); 444 addOperator(ExpressionOperator.sybaseLocateOperator()); 445 addOperator(ExpressionOperator.simpleThreeArgumentFunction(ExpressionOperator.Substring, "SUBSTRING")); 446 addOperator(ExpressionOperator.addDate()); 447 addOperator(ExpressionOperator.dateName()); 448 addOperator(ExpressionOperator.datePart()); 449 addOperator(ExpressionOperator.dateDifference()); 450 addOperator(ExpressionOperator.difference()); 451 addOperator(ExpressionOperator.charIndex()); 452 addOperator(ExpressionOperator.charLength()); 453 addOperator(ExpressionOperator.reverse()); 454 addOperator(ExpressionOperator.replicate()); 455 addOperator(ExpressionOperator.right()); 456 addOperator(ExpressionOperator.cot()); 457 addOperator(ExpressionOperator.sybaseAtan2Operator()); 458 addOperator(ExpressionOperator.sybaseAddMonthsOperator()); 459 addOperator(ExpressionOperator.sybaseInStringOperator()); 460 addOperator(ExpressionOperator.simpleTwoArgumentFunction(ExpressionOperator.Nvl, "ISNULL")); 462 addOperator(ExpressionOperator.sybaseToNumberOperator()); 464 addOperator(ExpressionOperator.sybaseToDateToStringOperator()); 465 addOperator(ExpressionOperator.sybaseToDateOperator()); 466 addOperator(ExpressionOperator.sybaseToCharOperator()); 467 addOperator(ExpressionOperator.simpleFunction(ExpressionOperator.Ceil, "CEILING")); 468 addOperator(modOperator()); 469 } 470 471 public boolean isSybase() { 472 return true; 473 } 474 475 481 public Hashtable maximumNumericValues() { 482 Hashtable values = new Hashtable(); 483 484 values.put(Integer .class, new Integer (Integer.MAX_VALUE)); 485 values.put(Long .class, new Long (Long.MAX_VALUE)); 486 values.put(Double .class, new Double ((double)Float.MAX_VALUE)); 487 values.put(Short .class, new Short (Short.MAX_VALUE)); 488 values.put(Byte .class, new Byte (Byte.MAX_VALUE)); 489 values.put(Float .class, new Float (Float.MAX_VALUE)); 490 values.put(java.math.BigInteger .class, new java.math.BigInteger ("99999999999999999999999999999999999999")); 491 values.put(java.math.BigDecimal .class, new java.math.BigDecimal ("9999999999999999999.9999999999999999999")); 492 return values; 493 } 494 495 501 public Hashtable minimumNumericValues() { 502 Hashtable values = new Hashtable(); 503 504 values.put(Integer .class, new Integer (Integer.MIN_VALUE)); 505 values.put(Long .class, new Long (Long.MIN_VALUE)); 506 values.put(Double .class, new Double ((double)1.4012984643247149E-44)); values.put(Short .class, new Short (Short.MIN_VALUE)); 508 values.put(Byte .class, new Byte (Byte.MIN_VALUE)); 509 values.put(Float .class, new Float (Float.MIN_VALUE)); 510 values.put(java.math.BigInteger .class, new java.math.BigInteger ("-99999999999999999999999999999999999999")); 511 values.put(java.math.BigDecimal .class, new java.math.BigDecimal ("-9999999999999999999.9999999999999999999")); 512 return values; 513 } 514 515 519 public ExpressionOperator modOperator() { 520 ExpressionOperator result = new ExpressionOperator(); 521 result.setSelector(ExpressionOperator.Mod); 522 Vector v = new Vector(); 523 v.addElement(" % "); 524 result.printsAs(v); 525 result.bePostfix(); 526 result.setNodeClass(oracle.toplink.essentials.internal.expressions.FunctionExpression.class); 527 return result; 528 } 529 530 534 protected ExpressionOperator operatorOuterJoin() { 535 ExpressionOperator result = new ExpressionOperator(); 536 result.setSelector(ExpressionOperator.EqualOuterJoin); 537 Vector v = new Vector(); 538 v.addElement(" =* "); 539 result.printsAs(v); 540 result.bePostfix(); 541 result.setNodeClass(RelationExpression.class); 542 return result; 543 } 544 545 549 public void printFieldIdentityClause(Writer writer) throws ValidationException { 550 try { 551 writer.write(" IDENTITY"); 552 } catch (IOException ioException) { 553 throw ValidationException.fileError(ioException); 554 } 555 } 556 557 561 public void printFieldNullClause(Writer writer) throws ValidationException { 562 try { 563 writer.write(" NULL"); 564 } catch (IOException ioException) { 565 throw ValidationException.fileError(ioException); 566 } 567 } 568 569 574 public void registerOutputParameter(CallableStatement statement, int index, int jdbcType) throws SQLException { 575 statement.registerOutParameter(index, jdbcType, (String )getTypeStrings().get(new Integer (jdbcType))); 576 } 577 578 582 public boolean requiresProcedureCallBrackets() { 583 return false; 584 } 585 586 590 public boolean requiresProcedureCallOuputToken() { 591 return true; 592 } 593 594 599 public boolean requiresTypeNameToRegisterOutputParameter() { 600 return true; 601 } 602 603 608 public boolean shouldPrintInOutputTokenBeforeType() { 609 return false; 610 } 611 612 616 public boolean shouldPrintOuterJoinInWhereClause() { 617 return false; 618 } 619 620 625 public boolean shouldPrintOutputTokenBeforeType() { 626 return false; 627 } 628 629 635 public boolean shouldNativeSequenceAcquireValueAfterInsert() { 636 return true; 637 } 638 639 643 public boolean shouldUseJDBCOuterJoinSyntax() { 644 return false; 645 } 646 647 652 public boolean supportsNativeSequenceNumbers() { 653 return true; 654 } 655 656 659 public boolean supportsLocalTempTables() { 660 return true; 661 } 662 663 666 protected String getCreateTempTableSqlPrefix() { 667 return "CREATE TABLE "; 668 } 669 670 673 public DatabaseTable getTempTableForTable(DatabaseTable table) { 674 return new DatabaseTable("#" + table.getName(), table.getTableQualifier()); 675 } 676 677 680 public void writeUpdateOriginalFromTempTableSql(Writer writer, DatabaseTable table, 681 Collection pkFields, 682 Collection assignedFields) throws IOException 683 { 684 writer.write("UPDATE "); 685 String tableName = table.getQualifiedName(); 686 writer.write(tableName); 687 String tempTableName = getTempTableForTable(table).getQualifiedName(); 688 writeAutoAssignmentSetClause(writer, null, tempTableName, assignedFields); 689 writer.write(" FROM "); 690 writer.write(tableName); 691 writer.write(", "); 692 writer.write(tempTableName); 693 writeAutoJoinWhereClause(writer, tableName, tempTableName, pkFields); 694 } 695 } 696 | Popular Tags |