package com.j256.ormlite.db; import java.util.List; import com.j256.ormlite.field.FieldType; /** * Postgres database type information used to create the tables, etc.. * * @author graywatson */ public class PostgresDatabaseType extends BaseDatabaseType { private final static String DATABASE_URL_PORTION = "postgresql"; private final static String DRIVER_CLASS_NAME = "org.postgresql.Driver"; private final static String DATABASE_NAME = "Postgres"; @Override public boolean isDatabaseUrlThisType(String url, String dbTypePart) { return DATABASE_URL_PORTION.equals(dbTypePart); } @Override protected String[] getDriverClassNames() { return new String[] { DRIVER_CLASS_NAME }; } @Override public String getDatabaseName() { return DATABASE_NAME; } @Override protected void appendUuidNativeType(StringBuilder sb, FieldType fieldType, int fieldWidth) { sb.append("UUID"); } @Override protected void appendByteType(StringBuilder sb, FieldType fieldType, int fieldWidth) { sb.append("SMALLINT"); } @Override protected void appendByteArrayType(StringBuilder sb, FieldType fieldType, int fieldWidth) { sb.append("BYTEA"); } @Override protected void appendSerializableType(StringBuilder sb, FieldType fieldType, int fieldWidth) { sb.append("BYTEA"); } @Override protected void configureGeneratedIdSequence(StringBuilder sb, FieldType fieldType, List<String> statementsBefore, List<String> additionalArgs, List<String> queriesAfter) { String sequenceName = fieldType.getGeneratedIdSequence(); // needs to match dropColumnArg() StringBuilder seqSb = new StringBuilder(64); seqSb.append("CREATE SEQUENCE "); // when it is created, it needs to be escaped specially appendEscapedEntityName(seqSb, sequenceName); statementsBefore.add(seqSb.toString()); sb.append("DEFAULT NEXTVAL("); // postgres needed this special escaping for NEXTVAL('"sequence-name"') sb.append('\'').append('\"').append(sequenceName).append('\"').append('\''); sb.append(") "); // could also be the type serial for auto-generated sequences // 8.2 also have the returning insert statement configureId(sb, fieldType, statementsBefore, additionalArgs, queriesAfter); } @Override public void dropColumnArg(FieldType fieldType, List<String> statementsBefore, List<String> statementsAfter) { if (fieldType.isGeneratedIdSequence()) { StringBuilder sb = new StringBuilder(64); sb.append("DROP SEQUENCE "); appendEscapedEntityName(sb, fieldType.getGeneratedIdSequence()); statementsAfter.add(sb.toString()); } } @Override public void appendEscapedEntityName(StringBuilder sb, String name) { // this handles table names like schema.table which have to be quoted like "schema"."table" boolean first = true; for (String namePart : name.split("\\.")) { if (first) { first = false; } else { sb.append('.'); } sb.append('\"').append(namePart).append('\"'); } } @Override public boolean isIdSequenceNeeded() { return true; } @Override public boolean isSelectSequenceBeforeInsert() { return true; } @Override public void appendSelectNextValFromSequence(StringBuilder sb, String sequenceName) { sb.append("SELECT NEXTVAL("); // this is word and not entity unfortunately appendEscapedWord(sb, sequenceName); sb.append(')'); } @Override public boolean isTruncateSupported() { return true; } @Override public boolean isCreateIfNotExistsSupported() { int major = driver.getMajorVersion(); if (major > 9 || (major == 9 && driver.getMinorVersion() >= 1)) { return true; } else { return super.isCreateIfNotExistsSupported(); } } }