All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.ebean.platform.postgres.PostgresPlatform Maven / Gradle / Ivy

There is a newer version: 15.8.1
Show newest version
package io.ebean.platform.postgres;

import io.ebean.BackgroundExecutor;
import io.ebean.Query;
import io.ebean.annotation.PartitionMode;
import io.ebean.annotation.Platform;
import io.ebean.config.PlatformConfig;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebean.config.dbplatform.DbPlatformType;
import io.ebean.config.dbplatform.DbType;
import io.ebean.config.dbplatform.IdType;
import io.ebean.config.dbplatform.PlatformIdGenerator;
import io.ebean.config.dbplatform.SqlErrorCodes;
import io.ebean.util.SplitName;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

/**
 * Postgres 10+ platform.
 * 

* Defaults to use "generated by default as identity". */ public class PostgresPlatform extends DatabasePlatform { private static final String SKIP_LOCKED = " skip locked"; private static final String NO_WAIT = " nowait"; private static final String FOR_UPDATE = " for update"; private static final String FOR_NO_KEY_UPDATE = " for no key update"; private static final String FOR_SHARE = " for share"; private static final String FOR_KEY_SHARE = " for key share"; private boolean forUpdateNoKey; public PostgresPlatform() { super(); this.platform = Platform.POSTGRES; this.supportsNativeIlike = true; this.supportsDeleteTableAlias = true; this.selectCountWithAlias = true; this.blobDbType = Types.LONGVARBINARY; this.clobDbType = Types.VARCHAR; this.nativeUuidType = true; this.truncateTable = "truncate table %s cascade"; this.dbEncrypt = new PostgresDbEncrypt(); this.historySupport = new PostgresHistorySupport(); // Use Identity and getGeneratedKeys this.dbIdentity.setIdType(IdType.IDENTITY); this.dbIdentity.setSupportsGetGeneratedKeys(true); this.dbIdentity.setSupportsSequence(true); this.dbIdentity.setSupportsIdentity(true); this.dbDefaultValue.setNow("current_timestamp"); this.exceptionTranslator = new SqlErrorCodes() .addAcquireLock("55P03") .addDuplicateKey("23505") .addDataIntegrity("23000", "23502", "23503", "23514") .addSerializableConflict("40001") .build(); this.openQuote = "\""; this.closeQuote = "\""; DbPlatformType dbTypeText = new DbPlatformType("text", false); DbPlatformType dbBytea = new DbPlatformType("bytea", false); dbTypeMap.put(DbType.UUID, new DbPlatformType("uuid", false)); dbTypeMap.put(DbType.INET, new DbPlatformType("inet", false)); dbTypeMap.put(DbType.CIDR, new DbPlatformType("cidr", false)); dbTypeMap.put(DbType.HSTORE, new DbPlatformType("hstore", false)); dbTypeMap.put(DbType.JSON, new DbPlatformType("json", false)); dbTypeMap.put(DbType.JSONB, new DbPlatformType("jsonb", false)); dbTypeMap.put(DbType.INTEGER, new DbPlatformType("integer", false)); dbTypeMap.put(DbType.DOUBLE, new DbPlatformType("float")); dbTypeMap.put(DbType.TINYINT, new DbPlatformType("smallint")); dbTypeMap.put(DbType.TIMESTAMP, new DbPlatformType("timestamptz")); dbTypeMap.put(DbType.LOCALDATETIME, new DbPlatformType("timestamp")); dbTypeMap.put(DbType.BINARY, dbBytea); dbTypeMap.put(DbType.VARBINARY, dbBytea); dbTypeMap.put(DbType.BLOB, dbBytea); dbTypeMap.put(DbType.CLOB, dbTypeText); dbTypeMap.put(DbType.LONGVARBINARY, dbBytea); dbTypeMap.put(DbType.LONGVARCHAR, dbTypeText); } @Override public void configure(PlatformConfig config) { super.configure(config); forUpdateNoKey = config.isForUpdateNoKey(); } @Override protected void addGeoTypes(int srid) { dbTypeMap.put(DbType.POINT, geoType("point", srid)); dbTypeMap.put(DbType.POLYGON, geoType("polygon", srid)); dbTypeMap.put(DbType.LINESTRING, geoType("linestring", srid)); dbTypeMap.put(DbType.MULTIPOINT, geoType("multipoint", srid)); dbTypeMap.put(DbType.MULTILINESTRING, geoType("multilinestring", srid)); dbTypeMap.put(DbType.MULTIPOLYGON, geoType("multipolygon", srid)); } private DbPlatformType geoType(String type, int srid) { return new DbPlatformType("geometry(" + type + "," + srid + ")"); } /** * So we can generate varchar[], int[], uuid[] column definitions and use the associated scalar types. */ @Override public boolean isNativeArrayType() { return true; } /** * Create a Postgres specific sequence IdGenerator. */ @Override public PlatformIdGenerator createSequenceIdGenerator(BackgroundExecutor be, DataSource ds, int stepSize, String seqName) { return new PostgresSequenceIdGenerator(be, ds, seqName, sequenceBatchSize); } @Override protected String withForUpdate(String sql, Query.LockWait lockWait, Query.LockType lockType) { switch (lockWait) { case SKIPLOCKED: return sql + lock(lockType) + SKIP_LOCKED; case NOWAIT: return sql + lock(lockType) + NO_WAIT; default: return sql + lock(lockType); } } private String lock(Query.LockType lockType) { switch (lockType) { case UPDATE: return FOR_UPDATE; case NO_KEY_UPDATE: return FOR_NO_KEY_UPDATE; case SHARE: return FOR_SHARE; case KEY_SHARE: return FOR_KEY_SHARE; case DEFAULT: return forUpdateNoKey ? FOR_NO_KEY_UPDATE : FOR_UPDATE; } return FOR_UPDATE; } @Override public boolean tablePartitionsExist(Connection connection, String table) throws SQLException { try (PreparedStatement statement = connection.prepareStatement("select count(*) from pg_inherits i WHERE i.inhparent = ?::regclass")) { statement.setString(1, table); try (ResultSet resultSet = statement.executeQuery()) { return resultSet.next() && resultSet.getInt(1) > 0; } } } /** * Return SQL using built in partition helper functions to create some initial partitions. *

* Only use this if extra-ddl doesn't have some initial partitions defined (which it should). */ @Override public String tablePartitionInit(String tableName, PartitionMode mode) { // default partition required pg11 but this is only used for testing but bumped test docker container to pg14 by default String[] schemaTable = SplitName.split(tableName); String baseTable; String plusSchema; if (schemaTable[0] == null) { plusSchema = ""; baseTable = tableName; } else { // table in an explicit schema plusSchema = ",'" + schemaTable[0] + "'"; baseTable = schemaTable[1]; } return "create table " + tableName + "_default" + " partition of " + tableName + " default;\n" + "select partition('" + mode.name().toLowerCase() + "','" + baseTable + "',1" + plusSchema + ");"; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy