#1640 - For Postgres support mapping InetAddress to INET db column (#1641)

* #1640 - For Postgres support mapping InetAddress to INET db column

* #1640 - For Postgres support mapping InetAddress to INET db column

Support for Inet and Cdir types + offlineMigrationGeneration + PlatformConfig.databaseInetAddressVarchar for turning off InetAddress mapping on Postgres
This commit is contained in:
Rob Bygrave
2019-02-21 22:14:21 +13:00
committed by GitHub
parent 03a42f7f6e
commit 5975694538
15 changed files with 374 additions and 27 deletions
@@ -47,6 +47,11 @@ public class PlatformConfig {
*/
private DbUuid dbUuid = DbUuid.AUTO_VARCHAR;
/**
* Set to true to force InetAddress to map to Varchar (for Postgres rather than INET)
*/
private boolean databaseInetAddressVarchar;
/**
* Modify the default mapping of standard types such as default precision for DECIMAL etc.
*/
@@ -181,6 +186,20 @@ public class PlatformConfig {
this.idType = idType;
}
/**
* Return true if InetAddress should map to varchar column (rather than Postgres INET).
*/
public boolean isDatabaseInetAddressVarchar() {
return databaseInetAddressVarchar;
}
/**
* Set to true to force InetAddress to map to varchar column.
*/
public void setDatabaseInetAddressVarchar(boolean databaseInetAddressVarchar) {
this.databaseInetAddressVarchar = databaseInetAddressVarchar;
}
/**
* Add a custom type mapping.
* <p>
@@ -235,6 +254,7 @@ public class PlatformConfig {
databaseSequenceBatchSize = p.getInt("databaseSequenceBatchSize", databaseSequenceBatchSize);
databaseBooleanTrue = p.get("databaseBooleanTrue", databaseBooleanTrue);
databaseBooleanFalse = p.get("databaseBooleanFalse", databaseBooleanFalse);
databaseInetAddressVarchar = p.getBoolean("databaseInetAddressVarchar", databaseInetAddressVarchar);
DbUuid dbUuid = p.getEnum(DbUuid.class, "dbuuid", null);
if (dbUuid != null) {
@@ -27,6 +27,9 @@ public class DbPlatformTypeMapping {
private static final DbPlatformType BOOLEAN_LOGICAL = new BooleanLogicalType();
private static final DbPlatformType INET_NATIVE = new DbPlatformType("inet", false);
private static final DbPlatformType INET_VARCHAR = new DbPlatformType("varchar", 50);
private static final DbPlatformType UUID_NATIVE = new DbPlatformType("uuid", false);
@SuppressWarnings("unused")
private static final DbPlatformType UUID_PLACEHOLDER = new DbPlatformType("uuidPlaceholder");
@@ -106,6 +109,7 @@ public class DbPlatformTypeMapping {
put(DbType.JSONBLOB, new DbPlatformType("jsonblob"));
put(DbType.JSONVARCHAR, new DbPlatformType("jsonvarchar", 1000));
put(DbType.UUID, UUID_NATIVE);
put(DbType.INET, INET_NATIVE);
} else {
put(DbType.VARCHAR, new DbPlatformType("varchar", 255));
@@ -121,6 +125,7 @@ public class DbPlatformTypeMapping {
put(DbType.JSONVARCHAR, JSON_VARCHAR_PLACEHOLDER);
// default to native UUID and override on platform configure()
put(DbType.UUID, UUID_NATIVE);
put(DbType.INET, INET_VARCHAR);
}
}
@@ -35,6 +35,8 @@ public enum DbType {
ARRAY(Types.ARRAY),
UUID(ExtraDbTypes.UUID),
INET(ExtraDbTypes.INET),
CDIR(ExtraDbTypes.CDIR),
POINT(ExtraDbTypes.POINT),
POLYGON(ExtraDbTypes.POLYGON),
@@ -40,6 +40,9 @@ public interface ExtraDbTypes {
*/
int JSONBlob = 5005;
int INET = 5020;
int CDIR = 5021;
/**
* Geo Point
*/
@@ -60,6 +60,7 @@ public class PostgresPlatform extends DatabasePlatform {
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.HSTORE, new DbPlatformType("hstore", false));
dbTypeMap.put(DbType.JSON, new DbPlatformType("json", false));
dbTypeMap.put(DbType.JSONB, new DbPlatformType("jsonb", false));
@@ -334,6 +334,24 @@ public final class ConvertInetAddresses {
return ip.getHostAddress();
}
/**
* Return the host address without the square brackets around IPv6 addresses.
*/
public static String toHostAddress(InetAddress ip) {
return ip.getHostAddress();
}
/**
* Parse the IPv4 or IPv6 address without quare brackets around IPv6 addresses.
*/
public static InetAddress fromHost(String hostAddr) {
if (hostAddr.startsWith("[")) {
// IPv6 address
hostAddr = hostAddr.substring(1, hostAddr.length() - 1);
}
return forString(hostAddr);
}
/**
* Returns an InetAddress representing the literal IPv4 or IPv6 host
* portion of a URL, encoded in the format specified by RFC 3986 section 3.2.2.
@@ -14,6 +14,8 @@ import io.ebean.config.ScalarTypeConverter;
import io.ebean.config.ServerConfig;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebean.config.dbplatform.DbPlatformType;
import io.ebean.types.Cdir;
import io.ebean.types.Inet;
import io.ebean.util.AnnotationUtil;
import io.ebeaninternal.api.ExtraTypeFactory;
import io.ebeaninternal.dbmigration.DbOffline;
@@ -128,7 +130,6 @@ public final class DefaultTypeManager implements TypeManager {
private final ScalarType<?> dateType = new ScalarTypeDate();
private final ScalarType<?> inetAddressType = new ScalarTypeInetAddress();
private final ScalarType<?> urlType = new ScalarTypeURL();
private final ScalarType<?> uriType = new ScalarTypeURI();
private final ScalarType<?> localeType = new ScalarTypeLocale();
@@ -975,8 +976,21 @@ public final class DefaultTypeManager implements TypeManager {
addType(UUID.class, uuidType);
}
if (offlineMigrationGeneration || (postgres && !config.getPlatformConfig().isDatabaseInetAddressVarchar())) {
addType(InetAddress.class, new ScalarTypeInetAddressPostgres());
} else {
addType(InetAddress.class, new ScalarTypeInetAddress());
}
if (offlineMigrationGeneration || postgres) {
addType(Cdir.class, new ScalarTypeCdir.Postgres());
addType(Inet.class, new ScalarTypeInet.Postgres());
} else {
addType(Cdir.class, new ScalarTypeCdir.Varchar());
addType(Inet.class, new ScalarTypeInet.Varchar());
}
addType(File.class, fileType);
addType(InetAddress.class, inetAddressType);
addType(Locale.class, localeType);
addType(Currency.class, currencyType);
addType(TimeZone.class, timeZoneType);
@@ -16,6 +16,12 @@ public class PostgresHelper {
*/
public static final String JSONB_TYPE = "jsonb";
public static final String INET_TYPE = "inet";
public static Object asInet(String value) throws SQLException {
return asObject(INET_TYPE, value);
}
/**
* Construct and return Postgres specific PG object.
*/
@@ -0,0 +1,71 @@
package io.ebeaninternal.server.type;
import io.ebean.config.dbplatform.ExtraDbTypes;
import io.ebean.types.Cdir;
import java.sql.SQLException;
import java.sql.Types;
/**
* ScalarType for Cdir to Varchar or Postgres CDIR.
*/
public abstract class ScalarTypeCdir extends ScalarTypeBaseVarchar<Cdir> {
ScalarTypeCdir() {
super(Cdir.class, false, ExtraDbTypes.INET);
}
@Override
public abstract void bind(DataBind b, Cdir value) throws SQLException;
@Override
public Cdir convertFromDbString(String dbValue) {
return parse(dbValue);
}
@Override
public String convertToDbString(Cdir beanValue) {
return formatValue(beanValue);
}
@Override
public String formatValue(Cdir value) {
return value.getAddress();
}
@Override
public Cdir parse(String value) {
return new Cdir(value);
}
/**
* Cdir to Varchar.
*/
public static class Varchar extends ScalarTypeCdir {
@Override
public void bind(DataBind b, Cdir value) throws SQLException {
if (value == null) {
b.setNull(Types.VARCHAR);
} else {
b.setString(convertToDbString(value));
}
}
}
/**
* Cdir to Postgres CDIR.
*/
public static class Postgres extends ScalarTypeCdir {
@Override
public void bind(DataBind b, Cdir value) throws SQLException {
if (value == null) {
b.setNull(Types.OTHER);
} else {
String strValue = convertToDbString(value);
b.setObject(PostgresHelper.asInet(strValue));
}
}
}
}
@@ -0,0 +1,71 @@
package io.ebeaninternal.server.type;
import io.ebean.config.dbplatform.ExtraDbTypes;
import io.ebean.types.Inet;
import java.sql.SQLException;
import java.sql.Types;
/**
* ScalarType for Inet to Varchar or Postgres INET.
*/
public abstract class ScalarTypeInet extends ScalarTypeBaseVarchar<Inet> {
ScalarTypeInet() {
super(Inet.class, false, ExtraDbTypes.INET);
}
@Override
public abstract void bind(DataBind b, Inet value) throws SQLException;
@Override
public Inet convertFromDbString(String dbValue) {
return parse(dbValue);
}
@Override
public String convertToDbString(Inet beanValue) {
return formatValue(beanValue);
}
@Override
public String formatValue(Inet value) {
return value.getAddress();
}
@Override
public Inet parse(String value) {
return new Inet(value);
}
/**
* Inet to Varchar.
*/
public static class Varchar extends ScalarTypeInet {
@Override
public void bind(DataBind b, Inet value) throws SQLException {
if (value == null) {
b.setNull(Types.VARCHAR);
} else {
b.setString(convertToDbString(value));
}
}
}
/**
* Inet to Postgres INET.
*/
public static class Postgres extends ScalarTypeInet {
@Override
public void bind(DataBind b, Inet value) throws SQLException {
if (value == null) {
b.setNull(Types.OTHER);
} else {
String strValue = convertToDbString(value);
b.setObject(PostgresHelper.asInet(strValue));
}
}
}
}
@@ -0,0 +1,57 @@
package io.ebeaninternal.server.type;
import io.ebean.config.dbplatform.ExtraDbTypes;
import io.ebean.text.TextException;
import java.net.InetAddress;
import java.sql.SQLException;
import java.sql.Types;
/**
* ScalarType for InetAddress to Postgres INET.
*/
public class ScalarTypeInetAddressPostgres extends ScalarTypeBaseVarchar<InetAddress> {
public ScalarTypeInetAddressPostgres() {
super(InetAddress.class, false, ExtraDbTypes.INET);
}
@Override
public void bind(DataBind b, InetAddress value) throws SQLException {
if (value == null) {
b.setNull(Types.OTHER);
} else {
String strValue = convertToDbString(value);
b.setObject(PostgresHelper.asInet(strValue));
}
}
@Override
public InetAddress convertFromDbString(String dbValue) {
try {
return parse(dbValue);
} catch (IllegalArgumentException e) {
throw new RuntimeException("Error with InetAddresses [" + dbValue + "] " + e);
}
}
@Override
public String convertToDbString(InetAddress beanValue) {
return formatValue(beanValue);
}
@Override
public String formatValue(InetAddress v) {
return ConvertInetAddresses.toHostAddress(v);
}
@Override
public InetAddress parse(String value) {
try {
return ConvertInetAddresses.fromHost(value);
} catch (IllegalArgumentException e) {
throw new TextException("Error with InetAddresses [{}]", value, e);
}
}
}