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}