001package com.avaje.ebean.config.dbplatform;
002
003import com.avaje.ebean.BackgroundExecutor;
004import com.avaje.ebean.config.ServerConfig;
005import com.avaje.ebean.dbmigration.ddlgeneration.DdlHandler;
006import com.avaje.ebean.dbmigration.ddlgeneration.platform.PostgresDdl;
007
008import javax.sql.DataSource;
009import java.sql.Types;
010import java.util.Properties;
011
012/**
013 * Postgres v9 specific platform.
014 * <p>
015 * Uses serial types and getGeneratedKeys.
016 * </p>
017 */
018public class PostgresPlatform extends DatabasePlatform {
019
020  public PostgresPlatform() {
021    super();
022    this.name = "postgres";
023    this.supportsNativeIlike = true;
024    this.likeClause = "like ? escape''";
025    this.selectCountWithAlias = true;
026    this.blobDbType = Types.LONGVARBINARY;
027    this.clobDbType = Types.VARCHAR;
028    this.nativeUuidType = true;
029
030    this.dbEncrypt = new PostgresDbEncrypt();
031    this.historySupport = new PostgresHistorySupport();
032    this.platformDdl = new PostgresDdl(this);
033
034    // Use Identity and getGeneratedKeys
035    this.dbIdentity.setIdType(IdType.IDENTITY);
036    this.dbIdentity.setSupportsGetGeneratedKeys(true);
037    this.dbIdentity.setSupportsSequence(true);
038
039    //this.columnAliasPrefix = "as c";
040
041    this.openQuote = "\"";
042    this.closeQuote = "\"";
043
044    DbType dbTypeText = new DbType("text");
045    DbType dbBytea = new DbType("bytea", false);
046
047    dbTypeMap.put(DbType.HSTORE, new DbType("hstore", false));
048    dbTypeMap.put(DbType.JSON, new DbType("json", false));
049    dbTypeMap.put(DbType.JSONB, new DbType("jsonb", false));
050
051    dbTypeMap.put(Types.INTEGER, new DbType("integer", false));
052    dbTypeMap.put(Types.DOUBLE, new DbType("float"));
053    dbTypeMap.put(Types.TINYINT, new DbType("smallint"));
054    dbTypeMap.put(Types.DECIMAL, new DbType("decimal", 38));
055    dbTypeMap.put(Types.TIMESTAMP, new DbType("timestamptz"));
056
057    dbTypeMap.put(Types.BINARY, dbBytea);
058    dbTypeMap.put(Types.VARBINARY, dbBytea);
059
060    dbTypeMap.put(Types.BLOB, dbBytea);
061    dbTypeMap.put(Types.CLOB, dbTypeText);
062    dbTypeMap.put(Types.LONGVARBINARY, dbBytea);
063    dbTypeMap.put(Types.LONGVARCHAR, dbTypeText);
064  }
065
066  @Override
067  public void configure(ServerConfig serverConfig) {
068    super.configure(serverConfig);
069    Properties properties = serverConfig.getProperties();
070    if (properties != null) {
071      String tsType = properties.getProperty("ebean.postgres.timestamp");
072      if (tsType != null) {
073        // set timestamp type to "timestamp" without time zone
074        dbTypeMap.put(Types.TIMESTAMP, new DbType(tsType));
075      }
076    }
077  }
078
079  /**
080   * Return a DdlHandler instance for generating DDL for the specific platform.
081   */
082  public DdlHandler createDdlHandler(ServerConfig serverConfig) {
083    return this.platformDdl.createDdlHandler(serverConfig);
084  }
085
086  /**
087   * Create a Postgres specific sequence IdGenerator.
088   */
089  @Override
090  public PlatformIdGenerator createSequenceIdGenerator(BackgroundExecutor be, DataSource ds, String seqName, int batchSize) {
091
092    return new PostgresSequenceIdGenerator(be, ds, seqName, batchSize);
093  }
094
095  @Override
096  protected String withForUpdate(String sql) {
097    return sql + " for update";
098  }
099}