001package io.ebean.config.dbplatform.oracle;
002
003import io.ebean.BackgroundExecutor;
004import io.ebean.Query;
005import io.ebean.annotation.Platform;
006import io.ebean.config.dbplatform.BasicSqlAnsiLimiter;
007import io.ebean.config.dbplatform.DatabasePlatform;
008import io.ebean.config.dbplatform.DbPlatformType;
009import io.ebean.config.dbplatform.DbType;
010import io.ebean.config.dbplatform.IdType;
011import io.ebean.config.dbplatform.PlatformIdGenerator;
012import io.ebean.config.dbplatform.SqlErrorCodes;
013
014import javax.sql.DataSource;
015import java.sql.Types;
016
017/**
018 * Oracle specific platform.
019 */
020public class OraclePlatform extends DatabasePlatform {
021
022  public OraclePlatform() {
023    super();
024    this.platform = Platform.ORACLE;
025    this.supportsDeleteTableAlias = true;
026    this.maxTableNameLength = 30;
027    this.maxConstraintNameLength = 30;
028    this.dbEncrypt = new OracleDbEncrypt();
029    this.sqlLimiter = new OracleAnsiSqlRowsLimiter();
030    this.basicSqlLimiter = new BasicSqlAnsiLimiter();
031    this.historySupport = new OracleDbHistorySupport();
032    this.truncateTable = "truncate table %s cascade";
033    dbIdentity.setIdType(IdType.IDENTITY);
034    dbIdentity.setSupportsSequence(true);
035    dbIdentity.setSupportsIdentity(true);
036    dbIdentity.setSupportsGetGeneratedKeys(true);
037
038    this.dbDefaultValue.setFalse("0");
039    this.dbDefaultValue.setTrue("1");
040    this.dbDefaultValue.setNow("current_timestamp");
041
042    this.treatEmptyStringsAsNull = true;
043    this.likeClauseRaw = "like ?";
044
045    this.exceptionTranslator =
046      new SqlErrorCodes()
047        //.addAcquireLock("")
048        .addDuplicateKey("1")
049        .addDataIntegrity("2291")
050        .addSerializableConflict("72000")
051        .build();
052
053    this.openQuote = "\"";
054    this.closeQuote = "\"";
055
056    booleanDbType = Types.INTEGER;
057    dbTypeMap.put(DbType.BOOLEAN, new DbPlatformType("number(1)"));
058
059    dbTypeMap.put(DbType.INTEGER, new DbPlatformType("number", 10));
060    dbTypeMap.put(DbType.BIGINT, new DbPlatformType("number", 19));
061    dbTypeMap.put(DbType.REAL, new DbPlatformType("number", 19, 4));
062    dbTypeMap.put(DbType.DOUBLE, new DbPlatformType("number", 19, 4));
063    dbTypeMap.put(DbType.SMALLINT, new DbPlatformType("number", 5));
064    dbTypeMap.put(DbType.TINYINT, new DbPlatformType("number", 3));
065    dbTypeMap.put(DbType.DECIMAL, new DbPlatformType("number", 16, 3));
066    dbTypeMap.put(DbType.VARCHAR, new DbPlatformType("varchar2", 255));
067
068    dbTypeMap.put(DbType.LONGVARBINARY, new DbPlatformType("blob"));
069    dbTypeMap.put(DbType.LONGVARCHAR, new DbPlatformType("clob"));
070    dbTypeMap.put(DbType.VARBINARY, new DbPlatformType("raw", 255));
071    dbTypeMap.put(DbType.BINARY, new DbPlatformType("raw", 255));
072
073    dbTypeMap.put(DbType.TIME, new DbPlatformType("timestamp"));
074  }
075
076  @Override
077  public PlatformIdGenerator createSequenceIdGenerator(BackgroundExecutor be, DataSource ds, int stepSize, String seqName) {
078    return new OracleSequenceIdGenerator(be, ds, seqName, sequenceBatchSize);
079  }
080
081  @Override
082  protected String withForUpdate(String sql, Query.LockWait lockWait, Query.LockType lockType) {
083    switch (lockWait) {
084      case SKIPLOCKED:
085        return sql + " for update skip locked";
086      case NOWAIT:
087        return sql + " for update nowait";
088      default:
089        return sql + " for update";
090    }
091  }
092
093}