mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-11-12 22:41:35 +00:00
Merge branch 'master' into wip/h2database-v2
This commit is contained in:
113 files changed
+1589
-372
No files matched your search
@@ -3,8 +3,8 @@ name: JDK 18-ea
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
# schedule:
|
schedule:
|
||||||
# - cron: '30 6 * * *'
|
- cron: '30 6 * * 1,3,5'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
|
|
||||||
name: MariaDB 10.6
|
name: MariaDB 10.6
|
||||||
|
|
||||||
on: [workflow_dispatch]
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
schedule:
|
||||||
|
- cron: '10 7 * * 1,4'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
|
|
||||||
name: SqlServer 2017 latest
|
name: SqlServer 2017 latest
|
||||||
|
|
||||||
on: [workflow_dispatch]
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
schedule:
|
||||||
|
- cron: '10 7 * * 2,5'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
|||||||
+2
-2
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ebean-parent</artifactId>
|
<artifactId>ebean-parent</artifactId>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<name>ebean api</name>
|
<name>ebean api</name>
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.avaje</groupId>
|
<groupId>io.avaje</groupId>
|
||||||
<artifactId>avaje-config</artifactId>
|
<artifactId>avaje-config</artifactId>
|
||||||
<version>1.5</version>
|
<version>1.7</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
|
|||||||
@@ -66,6 +66,8 @@ public class PlatformConfig {
|
|||||||
|
|
||||||
private boolean caseSensitiveCollation = true;
|
private boolean caseSensitiveCollation = true;
|
||||||
|
|
||||||
|
private boolean useMigrationStoredProcedures = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modify the default mapping of standard types such as default precision for DECIMAL etc.
|
* Modify the default mapping of standard types such as default precision for DECIMAL etc.
|
||||||
*/
|
*/
|
||||||
@@ -90,6 +92,7 @@ public class PlatformConfig {
|
|||||||
this.geometrySRID = platformConfig.geometrySRID;
|
this.geometrySRID = platformConfig.geometrySRID;
|
||||||
this.dbUuid = platformConfig.dbUuid;
|
this.dbUuid = platformConfig.dbUuid;
|
||||||
this.caseSensitiveCollation = platformConfig.caseSensitiveCollation;
|
this.caseSensitiveCollation = platformConfig.caseSensitiveCollation;
|
||||||
|
this.useMigrationStoredProcedures = platformConfig.useMigrationStoredProcedures;
|
||||||
this.allQuotedIdentifiers = platformConfig.allQuotedIdentifiers;
|
this.allQuotedIdentifiers = platformConfig.allQuotedIdentifiers;
|
||||||
this.databaseInetAddressVarchar = platformConfig.databaseInetAddressVarchar;
|
this.databaseInetAddressVarchar = platformConfig.databaseInetAddressVarchar;
|
||||||
this.customDbTypeMappings = platformConfig.customDbTypeMappings;
|
this.customDbTypeMappings = platformConfig.customDbTypeMappings;
|
||||||
@@ -142,6 +145,20 @@ public class PlatformConfig {
|
|||||||
this.caseSensitiveCollation = caseSensitiveCollation;
|
this.caseSensitiveCollation = caseSensitiveCollation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if force use of helper stored procedures for migrations.
|
||||||
|
*/
|
||||||
|
public boolean isUseMigrationStoredProcedures() {
|
||||||
|
return useMigrationStoredProcedures;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set true to force use of helper stored procedures for migrations.
|
||||||
|
*/
|
||||||
|
public void setUseMigrationStoredProcedures(boolean useMigrationStoredProcedures) {
|
||||||
|
this.useMigrationStoredProcedures = useMigrationStoredProcedures;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if Postgres FOR UPDATE should use the NO KEY option.
|
* Return true if Postgres FOR UPDATE should use the NO KEY option.
|
||||||
*/
|
*/
|
||||||
@@ -317,6 +334,7 @@ public class PlatformConfig {
|
|||||||
databaseBooleanFalse = p.get("databaseBooleanFalse", databaseBooleanFalse);
|
databaseBooleanFalse = p.get("databaseBooleanFalse", databaseBooleanFalse);
|
||||||
databaseInetAddressVarchar = p.getBoolean("databaseInetAddressVarchar", databaseInetAddressVarchar);
|
databaseInetAddressVarchar = p.getBoolean("databaseInetAddressVarchar", databaseInetAddressVarchar);
|
||||||
caseSensitiveCollation = p.getBoolean("caseSensitiveCollation", caseSensitiveCollation);
|
caseSensitiveCollation = p.getBoolean("caseSensitiveCollation", caseSensitiveCollation);
|
||||||
|
useMigrationStoredProcedures = p.getBoolean("useMigrationStoredProcedures", useMigrationStoredProcedures);
|
||||||
|
|
||||||
DbUuid dbUuid = p.getEnum(DbUuid.class, "dbuuid", null);
|
DbUuid dbUuid = p.getEnum(DbUuid.class, "dbuuid", null);
|
||||||
if (dbUuid != null) {
|
if (dbUuid != null) {
|
||||||
|
|||||||
@@ -7,13 +7,10 @@ public class BasicSqlAnsiLimiter implements BasicSqlLimiter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String limit(String dbSql, int firstRow, int maxRows) {
|
public String limit(String dbSql, int firstRow, int maxRows) {
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder(50 + dbSql.length());
|
StringBuilder sb = new StringBuilder(50 + dbSql.length());
|
||||||
|
|
||||||
sb.append(dbSql);
|
sb.append(dbSql);
|
||||||
if (firstRow > 0) {
|
if (firstRow > 0) {
|
||||||
sb.append(" ").append("offset");
|
sb.append(" offset ").append(firstRow).append(" rows");
|
||||||
sb.append(" ").append(firstRow).append(" rows");
|
|
||||||
}
|
}
|
||||||
if (maxRows > 0) {
|
if (maxRows > 0) {
|
||||||
sb.append(" fetch next ").append(maxRows).append(" rows only");
|
sb.append(" fetch next ").append(maxRows).append(" rows only");
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ public class DatabasePlatform {
|
|||||||
|
|
||||||
protected boolean supportsSavepointId = true;
|
protected boolean supportsSavepointId = true;
|
||||||
|
|
||||||
|
protected boolean useMigrationStoredProcedures = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The behaviour used when ending a read only transaction at read committed isolation level.
|
* The behaviour used when ending a read only transaction at read committed isolation level.
|
||||||
*/
|
*/
|
||||||
@@ -237,6 +239,7 @@ public class DatabasePlatform {
|
|||||||
public void configure(PlatformConfig config) {
|
public void configure(PlatformConfig config) {
|
||||||
this.sequenceBatchSize = config.getDatabaseSequenceBatchSize();
|
this.sequenceBatchSize = config.getDatabaseSequenceBatchSize();
|
||||||
this.caseSensitiveCollation = config.isCaseSensitiveCollation();
|
this.caseSensitiveCollation = config.isCaseSensitiveCollation();
|
||||||
|
this.useMigrationStoredProcedures = config.isUseMigrationStoredProcedures();
|
||||||
configureIdType(config.getIdType());
|
configureIdType(config.getIdType());
|
||||||
configure(config, config.isAllQuotedIdentifiers());
|
configure(config, config.isAllQuotedIdentifiers());
|
||||||
}
|
}
|
||||||
@@ -343,6 +346,13 @@ public class DatabasePlatform {
|
|||||||
return supportsSavepointId;
|
return supportsSavepointId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if migrations should use stored procedures.
|
||||||
|
*/
|
||||||
|
public boolean isUseMigrationStoredProcedures() {
|
||||||
|
return useMigrationStoredProcedures;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if the platform supports LIMIT with sql update.
|
* Return true if the platform supports LIMIT with sql update.
|
||||||
*/
|
*/
|
||||||
@@ -573,6 +583,10 @@ public class DatabasePlatform {
|
|||||||
this.supportsResultSetConcurrencyModeUpdatable = supportsResultSetConcurrencyModeUpdatable;
|
this.supportsResultSetConcurrencyModeUpdatable = supportsResultSetConcurrencyModeUpdatable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setUseMigrationStoredProcedures(final boolean useMigrationStoredProcedures) {
|
||||||
|
this.useMigrationStoredProcedures = useMigrationStoredProcedures;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Normally not needed - overridden in CockroachPlatform.
|
* Normally not needed - overridden in CockroachPlatform.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
package io.ebean.config.dbplatform.mariadb;
|
package io.ebean.config.dbplatform.mariadb;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import io.ebean.BackgroundExecutor;
|
||||||
import io.ebean.annotation.Platform;
|
import io.ebean.annotation.Platform;
|
||||||
|
import io.ebean.config.dbplatform.PlatformIdGenerator;
|
||||||
import io.ebean.config.dbplatform.mysql.BaseMySqlPlatform;
|
import io.ebean.config.dbplatform.mysql.BaseMySqlPlatform;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -11,6 +15,14 @@ public class MariaDbPlatform extends BaseMySqlPlatform {
|
|||||||
public MariaDbPlatform() {
|
public MariaDbPlatform() {
|
||||||
super();
|
super();
|
||||||
this.platform = Platform.MARIADB;
|
this.platform = Platform.MARIADB;
|
||||||
|
this.sequenceBatchMode = false;
|
||||||
this.historySupport = new MariaDbHistorySupport();
|
this.historySupport = new MariaDbHistorySupport();
|
||||||
|
this.dbIdentity.setSupportsSequence(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformIdGenerator createSequenceIdGenerator(BackgroundExecutor be, DataSource ds, int stepSize, String seqName) {
|
||||||
|
return new MariaDbSequence(be, ds, seqName, stepSize);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package io.ebean.config.dbplatform.mariadb;
|
||||||
|
|
||||||
|
import io.ebean.BackgroundExecutor;
|
||||||
|
import io.ebean.config.dbplatform.SequenceStepIdGenerator;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
public class MariaDbSequence extends SequenceStepIdGenerator {
|
||||||
|
|
||||||
|
private final String nextSql;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct where batchSize is the sequence step size.
|
||||||
|
*/
|
||||||
|
public MariaDbSequence(BackgroundExecutor be, DataSource ds, String seqName, int stepSize) {
|
||||||
|
super(be, ds, seqName, stepSize);
|
||||||
|
this.nextSql = "select next value for " + seqName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSql(int batchSize) {
|
||||||
|
return nextSql;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ public class Oracle11Platform extends OraclePlatform {
|
|||||||
public Oracle11Platform() {
|
public Oracle11Platform() {
|
||||||
super();
|
super();
|
||||||
this.platform = Platform.ORACLE11;
|
this.platform = Platform.ORACLE11;
|
||||||
|
this.columnAliasPrefix = "c";
|
||||||
this.sqlLimiter = new OracleRownumSqlLimiter();
|
this.sqlLimiter = new OracleRownumSqlLimiter();
|
||||||
this.basicSqlLimiter = new OracleRownumBasicLimiter();
|
this.basicSqlLimiter = new OracleRownumBasicLimiter();
|
||||||
dbIdentity.setIdType(IdType.SEQUENCE);
|
dbIdentity.setIdType(IdType.SEQUENCE);
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package io.ebean.config.dbplatform.oracle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Oracle 12 platform using column alias.
|
||||||
|
*/
|
||||||
|
public class Oracle12Platform extends OraclePlatform {
|
||||||
|
|
||||||
|
public Oracle12Platform() {
|
||||||
|
super();
|
||||||
|
//this.platform = Platform.ORACLE12;
|
||||||
|
this.columnAliasPrefix = "c";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,7 +22,6 @@ public class OraclePlatform extends DatabasePlatform {
|
|||||||
public OraclePlatform() {
|
public OraclePlatform() {
|
||||||
super();
|
super();
|
||||||
this.platform = Platform.ORACLE;
|
this.platform = Platform.ORACLE;
|
||||||
this.columnAliasPrefix = "c";
|
|
||||||
this.supportsDeleteTableAlias = true;
|
this.supportsDeleteTableAlias = true;
|
||||||
this.maxTableNameLength = 30;
|
this.maxTableNameLength = 30;
|
||||||
this.maxConstraintNameLength = 30;
|
this.maxConstraintNameLength = 30;
|
||||||
@@ -35,11 +34,9 @@ public class OraclePlatform extends DatabasePlatform {
|
|||||||
dbIdentity.setSupportsSequence(true);
|
dbIdentity.setSupportsSequence(true);
|
||||||
dbIdentity.setSupportsIdentity(true);
|
dbIdentity.setSupportsIdentity(true);
|
||||||
dbIdentity.setSupportsGetGeneratedKeys(true);
|
dbIdentity.setSupportsGetGeneratedKeys(true);
|
||||||
|
|
||||||
this.dbDefaultValue.setFalse("0");
|
this.dbDefaultValue.setFalse("0");
|
||||||
this.dbDefaultValue.setTrue("1");
|
this.dbDefaultValue.setTrue("1");
|
||||||
this.dbDefaultValue.setNow("current_timestamp");
|
this.dbDefaultValue.setNow("current_timestamp");
|
||||||
|
|
||||||
this.treatEmptyStringsAsNull = true;
|
this.treatEmptyStringsAsNull = true;
|
||||||
this.likeClauseRaw = "like ?";
|
this.likeClauseRaw = "like ?";
|
||||||
|
|
||||||
@@ -56,7 +53,6 @@ public class OraclePlatform extends DatabasePlatform {
|
|||||||
|
|
||||||
booleanDbType = Types.INTEGER;
|
booleanDbType = Types.INTEGER;
|
||||||
dbTypeMap.put(DbType.BOOLEAN, new DbPlatformType("number(1)"));
|
dbTypeMap.put(DbType.BOOLEAN, new DbPlatformType("number(1)"));
|
||||||
|
|
||||||
dbTypeMap.put(DbType.INTEGER, new DbPlatformType("number", 10));
|
dbTypeMap.put(DbType.INTEGER, new DbPlatformType("number", 10));
|
||||||
dbTypeMap.put(DbType.BIGINT, new DbPlatformType("number", 19));
|
dbTypeMap.put(DbType.BIGINT, new DbPlatformType("number", 19));
|
||||||
dbTypeMap.put(DbType.REAL, new DbPlatformType("number", 19, 4));
|
dbTypeMap.put(DbType.REAL, new DbPlatformType("number", 19, 4));
|
||||||
@@ -65,12 +61,10 @@ public class OraclePlatform extends DatabasePlatform {
|
|||||||
dbTypeMap.put(DbType.TINYINT, new DbPlatformType("number", 3));
|
dbTypeMap.put(DbType.TINYINT, new DbPlatformType("number", 3));
|
||||||
dbTypeMap.put(DbType.DECIMAL, new DbPlatformType("number", 16, 3));
|
dbTypeMap.put(DbType.DECIMAL, new DbPlatformType("number", 16, 3));
|
||||||
dbTypeMap.put(DbType.VARCHAR, new DbPlatformType("varchar2", 255));
|
dbTypeMap.put(DbType.VARCHAR, new DbPlatformType("varchar2", 255));
|
||||||
|
|
||||||
dbTypeMap.put(DbType.LONGVARBINARY, new DbPlatformType("blob"));
|
dbTypeMap.put(DbType.LONGVARBINARY, new DbPlatformType("blob"));
|
||||||
dbTypeMap.put(DbType.LONGVARCHAR, new DbPlatformType("clob"));
|
dbTypeMap.put(DbType.LONGVARCHAR, new DbPlatformType("clob"));
|
||||||
dbTypeMap.put(DbType.VARBINARY, new DbPlatformType("raw", 255));
|
dbTypeMap.put(DbType.VARBINARY, new DbPlatformType("raw", 255));
|
||||||
dbTypeMap.put(DbType.BINARY, new DbPlatformType("raw", 255));
|
dbTypeMap.put(DbType.BINARY, new DbPlatformType("raw", 255));
|
||||||
|
|
||||||
dbTypeMap.put(DbType.TIME, new DbPlatformType("timestamp"));
|
dbTypeMap.put(DbType.TIME, new DbPlatformType("timestamp"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
@@ -119,4 +119,9 @@ abstract class SqlServerBasePlatform extends DatabasePlatform {
|
|||||||
// for update are hints on from clause of base table
|
// for update are hints on from clause of base table
|
||||||
return sql;
|
return sql;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isUseMigrationStoredProcedures() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
package io.ebean.plugin;
|
|
||||||
|
|
||||||
import io.ebean.bean.EntityBean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Errorhandler to handle load errors and may be recover correct value.
|
|
||||||
*
|
|
||||||
* @author Roland Praml, FOCONIS AG
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface LoadErrorHandler {
|
|
||||||
void handleLoadError(EntityBean bean, Property prop, String fullName, Exception e);
|
|
||||||
}
|
|
||||||
@@ -18,7 +18,7 @@ import java.util.Locale;
|
|||||||
* try {
|
* try {
|
||||||
* File f = new File("src/test/resources/test1.csv");
|
* File f = new File("src/test/resources/test1.csv");
|
||||||
*
|
*
|
||||||
* FileReader reader = new FileReader(f);
|
* FileReader reader = new FileReader(f, encoding);
|
||||||
*
|
*
|
||||||
* CsvReader<Customer> csvReader = DB.createCsvReader(Customer.class);
|
* CsvReader<Customer> csvReader = DB.createCsvReader(Customer.class);
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -71,6 +71,20 @@ public class AnnotationUtil {
|
|||||||
return typeGet(clazz, annotation) != null;
|
return typeGet(clazz, annotation) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if an element is annotated with an annotation of given type searching meta-annotations.
|
||||||
|
*/
|
||||||
|
public static boolean metaHas(AnnotatedElement element, Class<?> annotationType) {
|
||||||
|
return !metaFindAll(element, annotationType).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find all the annotations of a given type searching meta-annotations.
|
||||||
|
*/
|
||||||
|
public static Set<Annotation> metaFindAll(AnnotatedElement element, Class<?> annotationType) {
|
||||||
|
return metaFindAllFor(element, Collections.singleton(annotationType));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find all the annotations for the filter searching meta-annotations.
|
* Find all the annotations for the filter searching meta-annotations.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package io.ebean.util;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utilities for IO. It uses UTF-8 as encoding when reading/writing and uses
|
||||||
|
* buffered IO for better performance.
|
||||||
|
*/
|
||||||
|
public class IOUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read from stream as UTF-8.
|
||||||
|
*/
|
||||||
|
public static BufferedReader newReader(InputStream is) {
|
||||||
|
return new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read from file as UTF-8.
|
||||||
|
*/
|
||||||
|
public static BufferedReader newReader(File file) throws FileNotFoundException {
|
||||||
|
return newReader(new FileInputStream(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write to stream as UTF-8
|
||||||
|
*/
|
||||||
|
public static BufferedWriter newWriter(OutputStream os) {
|
||||||
|
return new BufferedWriter(new OutputStreamWriter(os, StandardCharsets.UTF_8));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write to file as UTF-8
|
||||||
|
*/
|
||||||
|
public static BufferedWriter newWriter(File file) throws FileNotFoundException {
|
||||||
|
return newWriter(new FileOutputStream(file));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ebean-parent</artifactId>
|
<artifactId>ebean-parent</artifactId>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<!-- <parent>-->
|
<!-- <parent>-->
|
||||||
<!-- <groupId>org.avaje</groupId>-->
|
<!-- <groupId>org.avaje</groupId>-->
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-core</artifactId>
|
<artifactId>ebean-core</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|||||||
+15
-15
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ebean-parent</artifactId>
|
<artifactId>ebean-parent</artifactId>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<name>ebean bom</name>
|
<name>ebean bom</name>
|
||||||
@@ -71,88 +71,88 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean</artifactId>
|
<artifactId>ebean</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-api</artifactId>
|
<artifactId>ebean-api</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-core</artifactId>
|
<artifactId>ebean-core</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-core-type</artifactId>
|
<artifactId>ebean-core-type</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-ddl-generator</artifactId>
|
<artifactId>ebean-ddl-generator</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-externalmapping-api</artifactId>
|
<artifactId>ebean-externalmapping-api</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-externalmapping-xml</artifactId>
|
<artifactId>ebean-externalmapping-xml</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-autotune</artifactId>
|
<artifactId>ebean-autotune</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-querybean</artifactId>
|
<artifactId>ebean-querybean</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>querybean-generator</artifactId>
|
<artifactId>querybean-generator</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>kotlin-querybean-generator</artifactId>
|
<artifactId>kotlin-querybean-generator</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-test</artifactId>
|
<artifactId>ebean-test</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-postgis</artifactId>
|
<artifactId>ebean-postgis</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-redis</artifactId>
|
<artifactId>ebean-redis</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ebean-parent</artifactId>
|
<artifactId>ebean-parent</artifactId>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>ebean-core-type</artifactId>
|
<artifactId>ebean-core-type</artifactId>
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-api</artifactId>
|
<artifactId>ebean-api</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
+4
-4
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ebean-parent</artifactId>
|
<artifactId>ebean-parent</artifactId>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>ebean-core</artifactId>
|
<artifactId>ebean-core</artifactId>
|
||||||
@@ -41,19 +41,19 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-api</artifactId>
|
<artifactId>ebean-api</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-core-type</artifactId>
|
<artifactId>ebean-core-type</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-externalmapping-api</artifactId>
|
<artifactId>ebean-externalmapping-api</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
@@ -3,13 +3,13 @@ package io.ebeaninternal.server.core;
|
|||||||
import io.ebean.ScriptRunner;
|
import io.ebean.ScriptRunner;
|
||||||
import io.ebean.ddlrunner.DdlRunner;
|
import io.ebean.ddlrunner.DdlRunner;
|
||||||
import io.ebean.ddlrunner.ScriptTransform;
|
import io.ebean.ddlrunner.ScriptTransform;
|
||||||
|
import io.ebean.util.IOUtils;
|
||||||
import io.ebeaninternal.api.SpiEbeanServer;
|
import io.ebeaninternal.api.SpiEbeanServer;
|
||||||
import io.ebeaninternal.util.UrlHelper;
|
import io.ebeaninternal.util.UrlHelper;
|
||||||
|
|
||||||
import javax.persistence.PersistenceException;
|
import javax.persistence.PersistenceException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.LineNumberReader;
|
import java.io.LineNumberReader;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
@@ -66,8 +66,9 @@ final class DScriptRunner implements ScriptRunner {
|
|||||||
throw new IllegalArgumentException("resource is null?");
|
throw new IllegalArgumentException("resource is null?");
|
||||||
}
|
}
|
||||||
|
|
||||||
try (InputStream inputStream = UrlHelper.openNoCache(resource)) {
|
try (InputStream inputStream = UrlHelper.openNoCache(resource);
|
||||||
return readContent(new InputStreamReader(inputStream));
|
Reader reader = IOUtils.newReader(inputStream)) {
|
||||||
|
return readContent(reader);
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new PersistenceException("Failed to read script content", e);
|
throw new PersistenceException("Failed to read script content", e);
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import io.ebean.config.dbplatform.mysql.MySql55Platform;
|
|||||||
import io.ebean.config.dbplatform.mysql.MySqlPlatform;
|
import io.ebean.config.dbplatform.mysql.MySqlPlatform;
|
||||||
import io.ebean.config.dbplatform.nuodb.NuoDbPlatform;
|
import io.ebean.config.dbplatform.nuodb.NuoDbPlatform;
|
||||||
import io.ebean.config.dbplatform.oracle.Oracle11Platform;
|
import io.ebean.config.dbplatform.oracle.Oracle11Platform;
|
||||||
|
import io.ebean.config.dbplatform.oracle.Oracle12Platform;
|
||||||
import io.ebean.config.dbplatform.oracle.OraclePlatform;
|
import io.ebean.config.dbplatform.oracle.OraclePlatform;
|
||||||
import io.ebean.config.dbplatform.postgres.Postgres9Platform;
|
import io.ebean.config.dbplatform.postgres.Postgres9Platform;
|
||||||
import io.ebean.config.dbplatform.postgres.PostgresPlatform;
|
import io.ebean.config.dbplatform.postgres.PostgresPlatform;
|
||||||
@@ -25,11 +26,7 @@ import io.ebeaninternal.api.DbOffline;
|
|||||||
|
|
||||||
import javax.persistence.PersistenceException;
|
import javax.persistence.PersistenceException;
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
import java.sql.Connection;
|
import java.sql.*;
|
||||||
import java.sql.DatabaseMetaData;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a DatabasePlatform from the configuration.
|
* Create a DatabasePlatform from the configuration.
|
||||||
@@ -87,6 +84,9 @@ public class DatabasePlatformFactory {
|
|||||||
if (dbName.equals("oracle11") || dbName.equals("oracle10") || dbName.equals("oracle9")) {
|
if (dbName.equals("oracle11") || dbName.equals("oracle10") || dbName.equals("oracle9")) {
|
||||||
return new Oracle11Platform();
|
return new Oracle11Platform();
|
||||||
}
|
}
|
||||||
|
if (dbName.equals("oracle12")) {
|
||||||
|
return new Oracle12Platform();
|
||||||
|
}
|
||||||
if (dbName.equals("oracle")) {
|
if (dbName.equals("oracle")) {
|
||||||
return new OraclePlatform();
|
return new OraclePlatform();
|
||||||
}
|
}
|
||||||
@@ -173,7 +173,13 @@ public class DatabasePlatformFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private DatabasePlatform oracleVersion(int majorVersion) {
|
private DatabasePlatform oracleVersion(int majorVersion) {
|
||||||
return majorVersion < 12 ? new Oracle11Platform() : new OraclePlatform();
|
if (majorVersion < 12) {
|
||||||
|
return new Oracle11Platform();
|
||||||
|
}
|
||||||
|
if (majorVersion < 13) {
|
||||||
|
return new Oracle12Platform();
|
||||||
|
}
|
||||||
|
return new OraclePlatform();
|
||||||
}
|
}
|
||||||
|
|
||||||
private DatabasePlatform mysqlVersion(int majorVersion, int minorVersion) {
|
private DatabasePlatform mysqlVersion(int majorVersion, int minorVersion) {
|
||||||
|
|||||||
@@ -226,7 +226,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void addBeanToCollectionWithCreate(EntityBean parentBean, EntityBean detailBean, boolean withCheck) {
|
public void addBeanToCollectionWithCreate(EntityBean parentBean, EntityBean detailBean, boolean withCheck) {
|
||||||
BeanCollection<?> bc = (BeanCollection<?>) super.getValue(parentBean);
|
BeanCollection<?> bc = beanCollection(parentBean);
|
||||||
if (bc == null) {
|
if (bc == null) {
|
||||||
bc = help.createEmpty(parentBean);
|
bc = help.createEmpty(parentBean);
|
||||||
setValue(parentBean, bc);
|
setValue(parentBean, bc);
|
||||||
@@ -234,6 +234,15 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
|
|||||||
help.add(bc, detailBean, withCheck);
|
help.add(bc, detailBean, withCheck);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private BeanCollection<?> beanCollection(EntityBean parentBean) {
|
||||||
|
try {
|
||||||
|
return (BeanCollection<?>) super.getValue(parentBean);
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
// fetching element collection, ok for now
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if this is considered 'empty' from a save perspective.
|
* Return true if this is considered 'empty' from a save perspective.
|
||||||
*/
|
*/
|
||||||
|
|||||||
+1
-6
@@ -10,23 +10,18 @@ public final class DbExpressionHandlerFactory {
|
|||||||
* Create and return the appropriate platform specific handing of expressions.
|
* Create and return the appropriate platform specific handing of expressions.
|
||||||
*/
|
*/
|
||||||
public static DbExpressionHandler from(DatabasePlatform databasePlatform) {
|
public static DbExpressionHandler from(DatabasePlatform databasePlatform) {
|
||||||
Platform platform = databasePlatform.getPlatform();
|
Platform platform = databasePlatform.getPlatform().base();
|
||||||
switch (platform) {
|
switch (platform) {
|
||||||
case H2:
|
case H2:
|
||||||
return new H2DbExpression();
|
return new H2DbExpression();
|
||||||
case POSTGRES:
|
case POSTGRES:
|
||||||
case POSTGRES9:
|
|
||||||
return new PostgresDbExpression();
|
return new PostgresDbExpression();
|
||||||
case MARIADB:
|
case MARIADB:
|
||||||
return new MariaDbExpression();
|
return new MariaDbExpression();
|
||||||
case MYSQL55:
|
|
||||||
case MYSQL:
|
case MYSQL:
|
||||||
return new MySqlDbExpression();
|
return new MySqlDbExpression();
|
||||||
case ORACLE:
|
case ORACLE:
|
||||||
case ORACLE11:
|
|
||||||
return new OracleDbExpression();
|
return new OracleDbExpression();
|
||||||
case SQLSERVER16:
|
|
||||||
case SQLSERVER17:
|
|
||||||
case SQLSERVER:
|
case SQLSERVER:
|
||||||
return new SqlServerDbExpression();
|
return new SqlServerDbExpression();
|
||||||
case HANA:
|
case HANA:
|
||||||
|
|||||||
@@ -333,6 +333,13 @@ public final class DefaultPersister implements Persister {
|
|||||||
* Recursively delete the bean. This calls back to the EbeanServer.
|
* Recursively delete the bean. This calls back to the EbeanServer.
|
||||||
*/
|
*/
|
||||||
private int deleteRecurse(EntityBean detailBean, Transaction t, DeleteMode deleteMode) {
|
private int deleteRecurse(EntityBean detailBean, Transaction t, DeleteMode deleteMode) {
|
||||||
|
return deleteRequest(createDeleteCascade(detailBean, t, deleteMode.persistType()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete without being a cascade.
|
||||||
|
*/
|
||||||
|
private int delete(EntityBean detailBean, Transaction t, DeleteMode deleteMode) {
|
||||||
return deleteRequest(createDeleteRequest(detailBean, t, deleteMode.persistType()));
|
return deleteRequest(createDeleteRequest(detailBean, t, deleteMode.persistType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -560,7 +567,7 @@ public final class DefaultPersister implements Persister {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deleteList(List<?> beanList, SpiTransaction t, DeleteMode deleteMode, boolean children) {
|
private void deleteCascade(List<?> beanList, SpiTransaction t, DeleteMode deleteMode, boolean children) {
|
||||||
if (children) {
|
if (children) {
|
||||||
t.depth(-1);
|
t.depth(-1);
|
||||||
t.checkBatchEscalationOnCollection();
|
t.checkBatchEscalationOnCollection();
|
||||||
@@ -604,7 +611,7 @@ public final class DefaultPersister implements Persister {
|
|||||||
for (Object id : ids) {
|
for (Object id : ids) {
|
||||||
EntityBean bean = descriptor.createEntityBean();
|
EntityBean bean = descriptor.createEntityBean();
|
||||||
descriptor.convertSetId(id, bean);
|
descriptor.convertSetId(id, bean);
|
||||||
int rowCount = deleteRecurse(bean, transaction, deleteMode);
|
int rowCount = delete(bean, transaction, deleteMode);
|
||||||
if (rowCount == -1) {
|
if (rowCount == -1) {
|
||||||
total = -1;
|
total = -1;
|
||||||
} else if (total != -1) {
|
} else if (total != -1) {
|
||||||
@@ -656,7 +663,7 @@ public final class DefaultPersister implements Persister {
|
|||||||
t.logSummary("-- DeleteById of " + descriptor.name() + " ids[" + idList + "] requires fetch of foreign key values");
|
t.logSummary("-- DeleteById of " + descriptor.name() + " ids[" + idList + "] requires fetch of foreign key values");
|
||||||
}
|
}
|
||||||
List<?> beanList = server.findList(q, t);
|
List<?> beanList = server.findList(q, t);
|
||||||
deleteList(beanList, t, deleteMode, false);
|
deleteCascade(beanList, t, deleteMode, false);
|
||||||
return beanList.size();
|
return beanList.size();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -994,6 +1001,8 @@ public final class DefaultPersister implements Persister {
|
|||||||
executeSqlUpdate(sqlDelete, t);
|
executeSqlUpdate(sqlDelete, t);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
// TODO: Review first checking if many property is loaded and using the loaded beans
|
||||||
|
// ... and only using findIdsByParentId() when the many property isn't loaded
|
||||||
// Delete recurse using the Id values of the children
|
// Delete recurse using the Id values of the children
|
||||||
Object parentId = desc.getId(parentBean);
|
Object parentId = desc.getId(parentBean);
|
||||||
List<Object> idsByParentId = many.findIdsByParentId(parentId, null, t, excludeDetailIds, deleteMode.isHard());
|
List<Object> idsByParentId = many.findIdsByParentId(parentId, null, t, excludeDetailIds, deleteMode.isHard());
|
||||||
@@ -1017,7 +1026,7 @@ public final class DefaultPersister implements Persister {
|
|||||||
for (Object id : childIds) {
|
for (Object id : childIds) {
|
||||||
refList.add(targetDesc.createReference(id, null));
|
refList.add(targetDesc.createReference(id, null));
|
||||||
}
|
}
|
||||||
deleteList(refList, t, deleteMode, true);
|
deleteCascade(refList, t, deleteMode, true);
|
||||||
} else {
|
} else {
|
||||||
// perform delete by statement if possible
|
// perform delete by statement if possible
|
||||||
delete(targetDesc, null, childIds, t, deleteMode);
|
delete(targetDesc, null, childIds, t, deleteMode);
|
||||||
@@ -1157,6 +1166,10 @@ public final class DefaultPersister implements Persister {
|
|||||||
return createDeleteRequest(bean, t, type, Flags.ZERO);
|
return createDeleteRequest(bean, t, type, Flags.ZERO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private <T> PersistRequestBean<T> createDeleteCascade(EntityBean bean, Transaction t, Type type) {
|
||||||
|
return createDeleteRequest(bean, t, type, Flags.RECURSE);
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked"})
|
@SuppressWarnings({"unchecked"})
|
||||||
private <T> PersistRequestBean<T> createDeleteRequest(Object bean, Transaction t, PersistRequest.Type type, int flags) {
|
private <T> PersistRequestBean<T> createDeleteRequest(Object bean, Transaction t, PersistRequest.Type type, int flags) {
|
||||||
BeanManager<T> mgr = beanManager(bean.getClass());
|
BeanManager<T> mgr = beanManager(bean.getClass());
|
||||||
@@ -1167,7 +1180,7 @@ public final class DefaultPersister implements Persister {
|
|||||||
type = Type.DELETE_SOFT;
|
type = Type.DELETE_SOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
PersistRequestBean<T> request = new PersistRequestBean<>(server, (T)bean, null, mgr, (SpiTransaction) t, persistExecute, type, flags);
|
PersistRequestBean<T> request = new PersistRequestBean<>(server, (T) bean, null, mgr, (SpiTransaction) t, persistExecute, type, flags);
|
||||||
request.initForSoftDelete();
|
request.initForSoftDelete();
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
@@ -1186,7 +1199,7 @@ public final class DefaultPersister implements Persister {
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private <T> BeanManager<T> beanManager(Class<?> cls) {
|
private <T> BeanManager<T> beanManager(Class<?> cls) {
|
||||||
BeanManager<T> mgr = (BeanManager<T>)beanDescriptorManager.beanManager(cls);
|
BeanManager<T> mgr = (BeanManager<T>) beanDescriptorManager.beanManager(cls);
|
||||||
if (mgr == null) {
|
if (mgr == null) {
|
||||||
throw new PersistenceException(errNotRegistered(cls));
|
throw new PersistenceException(errNotRegistered(cls));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,11 +13,8 @@ import io.ebeaninternal.server.persist.dmlbind.BindableList;
|
|||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
import static io.ebean.annotation.Platform.MARIADB;
|
|
||||||
import static io.ebean.annotation.Platform.MYSQL;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Meta data for insert handler. The meta data is for a particular bean type. It
|
* Metadata for insert handler. The metadata is for a particular bean type. It
|
||||||
* is considered immutable and is thread safe.
|
* is considered immutable and is thread safe.
|
||||||
*/
|
*/
|
||||||
final class InsertMeta {
|
final class InsertMeta {
|
||||||
@@ -153,31 +150,25 @@ final class InsertMeta {
|
|||||||
private String genSql(boolean nullId, String table, boolean draftTable) {
|
private String genSql(boolean nullId, String table, boolean draftTable) {
|
||||||
GenerateDmlRequest request = new GenerateDmlRequest();
|
GenerateDmlRequest request = new GenerateDmlRequest();
|
||||||
request.setInsertSetMode();
|
request.setInsertSetMode();
|
||||||
|
|
||||||
request.append("insert into ").append(table);
|
request.append("insert into ").append(table);
|
||||||
if (nullId && noColumnsForInsert(draftTable)) {
|
if (nullId && noColumnsForInsert(draftTable)) {
|
||||||
return request.append(defaultValues()).toString();
|
return request.append(defaultValues()).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
request.append(" (");
|
request.append(" (");
|
||||||
if (!nullId) {
|
if (!nullId) {
|
||||||
id.dmlAppend(request);
|
id.dmlAppend(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shadowFKey != null) {
|
if (shadowFKey != null) {
|
||||||
shadowFKey.dmlAppend(request);
|
shadowFKey.dmlAppend(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (discriminator != null) {
|
if (discriminator != null) {
|
||||||
discriminator.dmlAppend(request);
|
discriminator.dmlAppend(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (draftTable) {
|
if (draftTable) {
|
||||||
all.dmlAppend(request);
|
all.dmlAppend(request);
|
||||||
} else {
|
} else {
|
||||||
allExcludeDraftOnly.dmlAppend(request);
|
allExcludeDraftOnly.dmlAppend(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
request.append(") values (");
|
request.append(") values (");
|
||||||
request.append(request.getInsertBindBuffer());
|
request.append(request.getInsertBindBuffer());
|
||||||
request.append(")");
|
request.append(")");
|
||||||
@@ -185,7 +176,14 @@ final class InsertMeta {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String defaultValues() {
|
private String defaultValues() {
|
||||||
return platform.base() == MYSQL || platform.base() == MARIADB ? " values (default)" : " default values";
|
switch (platform.base()) {
|
||||||
|
case MYSQL:
|
||||||
|
case MARIADB:
|
||||||
|
case ORACLE:
|
||||||
|
return " values (default)";
|
||||||
|
default:
|
||||||
|
return " default values";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+3
-1
@@ -4,11 +4,13 @@ import io.ebean.ProfileLocation;
|
|||||||
import io.ebean.config.ProfilingConfig;
|
import io.ebean.config.ProfilingConfig;
|
||||||
import io.ebean.plugin.Plugin;
|
import io.ebean.plugin.Plugin;
|
||||||
import io.ebean.plugin.SpiServer;
|
import io.ebean.plugin.SpiServer;
|
||||||
|
import io.ebean.util.IOUtils;
|
||||||
import io.ebeaninternal.api.CoreLog;
|
import io.ebeaninternal.api.CoreLog;
|
||||||
import io.ebeaninternal.api.SpiProfileHandler;
|
import io.ebeaninternal.api.SpiProfileHandler;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.time.format.DateTimeFormatterBuilder;
|
import java.time.format.DateTimeFormatterBuilder;
|
||||||
@@ -123,7 +125,7 @@ public final class DefaultProfileHandler implements SpiProfileHandler, Plugin {
|
|||||||
try {
|
try {
|
||||||
String now = DTF.format(LocalDateTime.now());
|
String now = DTF.format(LocalDateTime.now());
|
||||||
File file = new File(dir, "txprofile-" + now + ".tprofile");
|
File file = new File(dir, "txprofile-" + now + ".tprofile");
|
||||||
out = new BufferedWriter(new FileWriter(file));
|
out = IOUtils.newWriter(file);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error("Not expected", e);
|
log.error("Not expected", e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ public final class DefaultTypeManager implements TypeManager {
|
|||||||
List<? extends ScalarType<?>> types = plugin.createTypes(config, objectMapper);
|
List<? extends ScalarType<?>> types = plugin.createTypes(config, objectMapper);
|
||||||
for (ScalarType<?> type : types) {
|
for (ScalarType<?> type : types) {
|
||||||
log.debug("adding ScalarType {}", type.getClass());
|
log.debug("adding ScalarType {}", type.getClass());
|
||||||
addCustomType(type);
|
add(type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -211,25 +211,6 @@ public final class DefaultTypeManager implements TypeManager {
|
|||||||
logAdd(scalarType);
|
logAdd(scalarType);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Register the ScalarType for an enum. This is special in the sense that an Enum
|
|
||||||
* can have many classes if it uses method overrides and we need to register all
|
|
||||||
* the variations/classes for the enum.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
|
||||||
@Override
|
|
||||||
public void addEnumType(ScalarType<?> scalarType, Class<? extends Enum> enumClass) {
|
|
||||||
Set<Class<?>> mappedClasses = new HashSet<>();
|
|
||||||
mappedClasses.add(enumClass);
|
|
||||||
for (Object value : EnumSet.allOf(enumClass).toArray()) {
|
|
||||||
mappedClasses.add(value.getClass());
|
|
||||||
}
|
|
||||||
for (Class<?> cls : mappedClasses) {
|
|
||||||
typeMap.put(cls, scalarType);
|
|
||||||
}
|
|
||||||
logAdd(scalarType);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void logAdd(ScalarType<?> scalarType) {
|
private void logAdd(ScalarType<?> scalarType) {
|
||||||
if (log.isTraceEnabled()) {
|
if (log.isTraceEnabled()) {
|
||||||
String msg = "ScalarType register [" + scalarType.getClass().getName() + "]";
|
String msg = "ScalarType register [" + scalarType.getClass().getName() + "]";
|
||||||
@@ -275,16 +256,43 @@ public final class DefaultTypeManager implements TypeManager {
|
|||||||
"ScalarType of Joda LocalTime not defined. You need to set DatabaseConfig.jodaLocalTimeMode to"
|
"ScalarType of Joda LocalTime not defined. You need to set DatabaseConfig.jodaLocalTimeMode to"
|
||||||
+ " either 'normal' or 'utc'. UTC is the old mode using UTC timezone but local time zone is now preferred as 'normal' mode.");
|
+ " either 'normal' or 'utc'. UTC is the old mode using UTC timezone but local time zone is now preferred as 'normal' mode.");
|
||||||
}
|
}
|
||||||
found = checkInterfaceTypes(type);
|
found = checkInheritedTypes(type);
|
||||||
}
|
}
|
||||||
return found;
|
return found != ScalarTypeNotFound.INSTANCE ? found : null; // Do not return ScalarTypeNotFound, otherwise checks will fail
|
||||||
}
|
}
|
||||||
|
|
||||||
private ScalarType<?> checkInterfaceTypes(Class<?> type) {
|
/**
|
||||||
if (java.nio.file.Path.class.isAssignableFrom(type)) {
|
* Checks the typeMap for inherited types.
|
||||||
return typeMap.get(java.nio.file.Path.class);
|
*
|
||||||
|
* If e.g. <code>type</code> is a <code>GregorianCalendar</code>, then this method
|
||||||
|
* will check the class hierarchy and will probably return a
|
||||||
|
* <code>ScalarTypeCalendar</code> To speed up a second lookup, it will write
|
||||||
|
* back the found scalarType to typeMap.
|
||||||
|
*
|
||||||
|
* @param type the for which to search for a <code>ScalarType</code>
|
||||||
|
* @return either a valid <code>ScalarType</code> if one could be found or {@link ScalarTypeNotFound#INSTANCE} if not
|
||||||
|
*/
|
||||||
|
private ScalarType<?> checkInheritedTypes(Class<?> type) {
|
||||||
|
// first step loop through inheritance chain
|
||||||
|
Class<?> parent = type;
|
||||||
|
while (parent != null && parent != Object.class) {
|
||||||
|
ScalarType<?> found = typeMap.get(parent);
|
||||||
|
if (found != null && found != ScalarTypeNotFound.INSTANCE) {
|
||||||
|
typeMap.put(type, found); // store type for next lookup
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
// second step - loop through interfaces of this type
|
||||||
|
for (Class<?> iface: parent.getInterfaces()) {
|
||||||
|
found = checkInheritedTypes(iface);
|
||||||
|
if (found != null && found != ScalarTypeNotFound.INSTANCE) {
|
||||||
|
typeMap.put(type, found); // store type for next lookup
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parent = parent.getSuperclass();
|
||||||
}
|
}
|
||||||
return null;
|
typeMap.put(type, ScalarTypeNotFound.INSTANCE);
|
||||||
|
return ScalarTypeNotFound.INSTANCE; // no success
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -389,7 +397,7 @@ public final class DefaultTypeManager implements TypeManager {
|
|||||||
|
|
||||||
private DocPropertyType getDocType(Type genericType) {
|
private DocPropertyType getDocType(Type genericType) {
|
||||||
if (genericType instanceof Class<?>) {
|
if (genericType instanceof Class<?>) {
|
||||||
ScalarType<?> found = typeMap.get(genericType);
|
ScalarType<?> found = getScalarType((Class<?>)genericType);
|
||||||
if (found != null) {
|
if (found != null) {
|
||||||
return found.getDocType();
|
return found.getDocType();
|
||||||
}
|
}
|
||||||
@@ -447,7 +455,7 @@ public final class DefaultTypeManager implements TypeManager {
|
|||||||
return scalarType;
|
return scalarType;
|
||||||
}
|
}
|
||||||
|
|
||||||
scalarType = typeMap.get(type);
|
scalarType = getScalarType(type);
|
||||||
if (scalarType != null) {
|
if (scalarType != null) {
|
||||||
if (jdbcType == 0 || scalarType.getJdbcType() == jdbcType) {
|
if (jdbcType == 0 || scalarType.getJdbcType() == jdbcType) {
|
||||||
// matching type
|
// matching type
|
||||||
@@ -565,7 +573,7 @@ public final class DefaultTypeManager implements TypeManager {
|
|||||||
// use JPA normal Enum type (without mapping)
|
// use JPA normal Enum type (without mapping)
|
||||||
scalarEnum = createEnumScalarTypePerSpec(enumType, type);
|
scalarEnum = createEnumScalarTypePerSpec(enumType, type);
|
||||||
}
|
}
|
||||||
addEnumType(scalarEnum, enumType);
|
add(scalarEnum);
|
||||||
return scalarEnum;
|
return scalarEnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -655,16 +663,13 @@ public final class DefaultTypeManager implements TypeManager {
|
|||||||
scalarType = cls.getDeclaredConstructor().newInstance();
|
scalarType = cls.getDeclaredConstructor().newInstance();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addCustomType(scalarType);
|
add(scalarType);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Error loading ScalarType [" + cls.getName() + "]", e);
|
log.error("Error loading ScalarType [" + cls.getName() + "]", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addCustomType(ScalarType<?> scalarType) {
|
|
||||||
add(scalarType);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Object initObjectMapper(DatabaseConfig config) {
|
private Object initObjectMapper(DatabaseConfig config) {
|
||||||
Object objectMapper = config.getObjectMapper();
|
Object objectMapper = config.getObjectMapper();
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import io.ebean.core.type.DataReader;
|
|||||||
import io.ebean.core.type.DocPropertyType;
|
import io.ebean.core.type.DocPropertyType;
|
||||||
import io.ebean.text.TextException;
|
import io.ebean.text.TextException;
|
||||||
import io.ebean.text.json.EJson;
|
import io.ebean.text.json.EJson;
|
||||||
|
import io.ebean.util.IOUtils;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
@@ -75,14 +76,14 @@ abstract class ScalarTypeJsonMap extends ScalarTypeBase<Map> {
|
|||||||
try {
|
try {
|
||||||
if (keepSource) {
|
if (keepSource) {
|
||||||
StringWriter jsonBuffer = new StringWriter();
|
StringWriter jsonBuffer = new StringWriter();
|
||||||
try (InputStreamReader streamReader = new InputStreamReader(is, StandardCharsets.UTF_8)) {
|
try (Reader streamReader = IOUtils.newReader(is)) {
|
||||||
transferTo(streamReader, jsonBuffer);
|
transferTo(streamReader, jsonBuffer);
|
||||||
}
|
}
|
||||||
String rawJson = jsonBuffer.toString();
|
String rawJson = jsonBuffer.toString();
|
||||||
reader.pushJson(rawJson);
|
reader.pushJson(rawJson);
|
||||||
return parse(rawJson);
|
return parse(rawJson);
|
||||||
} else {
|
} else {
|
||||||
try (InputStreamReader streamReader = new InputStreamReader(is, StandardCharsets.UTF_8)) {
|
try (Reader streamReader = IOUtils.newReader(is)) {
|
||||||
return parse(streamReader);
|
return parse(streamReader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,12 +8,12 @@ import io.ebean.core.type.DataBinder;
|
|||||||
import io.ebean.core.type.DataReader;
|
import io.ebean.core.type.DataReader;
|
||||||
import io.ebean.core.type.DocPropertyType;
|
import io.ebean.core.type.DocPropertyType;
|
||||||
import io.ebean.text.TextException;
|
import io.ebean.text.TextException;
|
||||||
|
import io.ebean.util.IOUtils;
|
||||||
|
|
||||||
import java.io.DataInput;
|
import java.io.DataInput;
|
||||||
import java.io.DataOutput;
|
import java.io.DataOutput;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
@@ -68,7 +68,7 @@ abstract class ScalarTypeJsonNode extends ScalarTypeBase<JsonNode> {
|
|||||||
if (is == null) {
|
if (is == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try (InputStreamReader reader = new InputStreamReader(is)) {
|
try (Reader reader = IOUtils.newReader(is)) {
|
||||||
return parse(reader);
|
return parse(reader);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new SQLException("Error reading Blob stream from DB", e);
|
throw new SQLException("Error reading Blob stream from DB", e);
|
||||||
|
|||||||
@@ -0,0 +1,140 @@
|
|||||||
|
package io.ebeaninternal.server.type;
|
||||||
|
|
||||||
|
import java.io.DataInput;
|
||||||
|
import java.io.DataOutput;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonGenerator;
|
||||||
|
import com.fasterxml.jackson.core.JsonParser;
|
||||||
|
|
||||||
|
import io.ebean.core.type.DataBinder;
|
||||||
|
import io.ebean.core.type.DataReader;
|
||||||
|
import io.ebean.core.type.DocPropertyType;
|
||||||
|
import io.ebean.core.type.ScalarType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class is required as "null" key in ConcurrentHashMap.
|
||||||
|
* @author Roland Praml, FOCONIS AG
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class ScalarTypeNotFound implements ScalarType<Void> {
|
||||||
|
|
||||||
|
public static final ScalarTypeNotFound INSTANCE = new ScalarTypeNotFound();
|
||||||
|
private ScalarTypeNotFound() { }
|
||||||
|
@Override
|
||||||
|
public boolean isBinaryType() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isMutable() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDirty(Object value) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLength() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isJdbcNative() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getJdbcType() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<Void> getType() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void read(DataReader reader) throws SQLException {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void loadIgnore(DataReader reader) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bind(DataBinder binder, Void value) throws SQLException {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object toJdbcType(Object value) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void toBeanType(Object value) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String formatValue(Void value) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String format(Object value) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void parse(String value) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DocPropertyType getDocType() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDateTimeCapable() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long asVersion(Void value) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void convertFromMillis(long dateTime) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void readData(DataInput dataInput) throws IOException {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeData(DataOutput dataOutput, Void v) throws IOException {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void jsonRead(JsonParser parser) throws IOException {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void jsonWrite(JsonGenerator writer, Void value) throws IOException {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -32,7 +32,7 @@ public final class SimpleAesEncryptor implements Encryptor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private IvParameterSpec getIvParameterSpec(String initialVector) {
|
private IvParameterSpec getIvParameterSpec(String initialVector) {
|
||||||
return new IvParameterSpec(initialVector.getBytes());
|
return new IvParameterSpec(initialVector.getBytes(StandardCharsets.UTF_8));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -17,12 +17,6 @@ public interface TypeManager {
|
|||||||
*/
|
*/
|
||||||
void add(ScalarType<?> scalarType);
|
void add(ScalarType<?> scalarType);
|
||||||
|
|
||||||
/**
|
|
||||||
* Register a ScalarType for an Enum with can have multiple classes.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("rawtypes")
|
|
||||||
void addEnumType(ScalarType<?> type, Class<? extends Enum> myEnumClass);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the scalar type for the given logical type.
|
* Return the scalar type for the given logical type.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ebean-parent</artifactId>
|
<artifactId>ebean-parent</artifactId>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<name>ebean ddl generation</name>
|
<name>ebean ddl generation</name>
|
||||||
@@ -22,20 +22,20 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-migration</artifactId>
|
<artifactId>ebean-migration</artifactId>
|
||||||
<version>12.12.1</version>
|
<version>12.13.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-core-type</artifactId>
|
<artifactId>ebean-core-type</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-core</artifactId>
|
<artifactId>ebean-core</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import io.ebean.config.DatabaseConfig;
|
|||||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||||
import io.ebean.ddlrunner.DdlRunner;
|
import io.ebean.ddlrunner.DdlRunner;
|
||||||
import io.ebean.ddlrunner.ScriptTransform;
|
import io.ebean.ddlrunner.ScriptTransform;
|
||||||
|
import io.ebean.util.IOUtils;
|
||||||
import io.ebean.util.JdbcClose;
|
import io.ebean.util.JdbcClose;
|
||||||
import io.ebeaninternal.api.SpiDdlGenerator;
|
import io.ebeaninternal.api.SpiDdlGenerator;
|
||||||
import io.ebeaninternal.api.SpiEbeanServer;
|
import io.ebeaninternal.api.SpiEbeanServer;
|
||||||
@@ -17,13 +18,11 @@ import org.slf4j.LoggerFactory;
|
|||||||
|
|
||||||
import javax.persistence.PersistenceException;
|
import javax.persistence.PersistenceException;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.LineNumberReader;
|
import java.io.LineNumberReader;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
|
import java.io.Writer;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
@@ -50,6 +49,7 @@ public class DdlGenerator implements SpiDdlGenerator {
|
|||||||
private final ScriptTransform scriptTransform;
|
private final ScriptTransform scriptTransform;
|
||||||
private final Platform platform;
|
private final Platform platform;
|
||||||
private final String platformName;
|
private final String platformName;
|
||||||
|
private final boolean useMigrationStoredProcedures;
|
||||||
|
|
||||||
private CurrentModel currentModel;
|
private CurrentModel currentModel;
|
||||||
private String dropAllContent;
|
private String dropAllContent;
|
||||||
@@ -71,9 +71,11 @@ public class DdlGenerator implements SpiDdlGenerator {
|
|||||||
log.warn("DDL can't be run on startup with TenantMode " + config.getTenantMode());
|
log.warn("DDL can't be run on startup with TenantMode " + config.getTenantMode());
|
||||||
this.runDdl = false;
|
this.runDdl = false;
|
||||||
this.ddlAutoCommit = false;
|
this.ddlAutoCommit = false;
|
||||||
|
this.useMigrationStoredProcedures = false;
|
||||||
} else {
|
} else {
|
||||||
this.runDdl = config.isDdlRun();
|
this.runDdl = config.isDdlRun();
|
||||||
this.ddlAutoCommit = databasePlatform.isDdlAutoCommit();
|
this.ddlAutoCommit = databasePlatform.isDdlAutoCommit();
|
||||||
|
this.useMigrationStoredProcedures = config.getDatabasePlatform().isUseMigrationStoredProcedures();
|
||||||
}
|
}
|
||||||
this.scriptTransform = createScriptTransform(config);
|
this.scriptTransform = createScriptTransform(config);
|
||||||
this.baseDir = initBaseDir();
|
this.baseDir = initBaseDir();
|
||||||
@@ -187,7 +189,7 @@ public class DdlGenerator implements SpiDdlGenerator {
|
|||||||
|
|
||||||
protected void runDropSql(Connection connection) throws IOException {
|
protected void runDropSql(Connection connection) throws IOException {
|
||||||
if (!createOnly) {
|
if (!createOnly) {
|
||||||
if (extraDdl && jaxbPresent) {
|
if (extraDdl && jaxbPresent && useMigrationStoredProcedures) {
|
||||||
String extraApply = ExtraDdlXmlReader.buildExtra(platform, true);
|
String extraApply = ExtraDdlXmlReader.buildExtra(platform, true);
|
||||||
if (extraApply != null) {
|
if (extraApply != null) {
|
||||||
runScript(connection, false, extraApply, "extra-ddl");
|
runScript(connection, false, extraApply, "extra-ddl");
|
||||||
@@ -268,7 +270,7 @@ public class DdlGenerator implements SpiDdlGenerator {
|
|||||||
if (is == null) {
|
if (is == null) {
|
||||||
log.warn("sql script {} was not found as a resource", sqlScript);
|
log.warn("sql script {} was not found as a resource", sqlScript);
|
||||||
} else {
|
} else {
|
||||||
String content = readContent(new InputStreamReader(is));
|
String content = readContent(IOUtils.newReader(is)); // 'is' is closed
|
||||||
runScript(connection, false, content, sqlScript);
|
runScript(connection, false, content, sqlScript);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -337,7 +339,7 @@ public class DdlGenerator implements SpiDdlGenerator {
|
|||||||
|
|
||||||
protected void writeFile(String fileName, String fileContent) throws IOException {
|
protected void writeFile(String fileName, String fileContent) throws IOException {
|
||||||
File f = new File(baseDir, fileName);
|
File f = new File(baseDir, fileName);
|
||||||
try (FileWriter fw = new FileWriter(f)) {
|
try (Writer fw = IOUtils.newWriter(f)) {
|
||||||
fw.write(fileContent);
|
fw.write(fileContent);
|
||||||
fw.flush();
|
fw.flush();
|
||||||
}
|
}
|
||||||
@@ -348,7 +350,9 @@ public class DdlGenerator implements SpiDdlGenerator {
|
|||||||
if (!f.exists()) {
|
if (!f.exists()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return readContent(new FileReader(f));
|
try (Reader reader = IOUtils.newReader(f)) {
|
||||||
|
return readContent(reader);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String readContent(Reader reader) throws IOException {
|
protected String readContent(Reader reader) throws IOException {
|
||||||
|
|||||||
+25
-17
@@ -1,8 +1,22 @@
|
|||||||
package io.ebeaninternal.dbmigration;
|
package io.ebeaninternal.dbmigration;
|
||||||
|
|
||||||
|
import static io.ebeaninternal.api.PlatformMatch.matchPlatform;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.StringJoiner;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import io.ebean.DB;
|
import io.ebean.DB;
|
||||||
import io.ebean.Database;
|
import io.ebean.Database;
|
||||||
import io.ebean.annotation.Platform;
|
import io.ebean.annotation.Platform;
|
||||||
|
import io.ebean.config.ClassLoadConfig;
|
||||||
import io.ebean.config.DatabaseConfig;
|
import io.ebean.config.DatabaseConfig;
|
||||||
import io.ebean.config.DbConstraintNaming;
|
import io.ebean.config.DbConstraintNaming;
|
||||||
import io.ebean.config.PlatformConfig;
|
import io.ebean.config.PlatformConfig;
|
||||||
@@ -27,6 +41,8 @@ import io.ebean.config.dbplatform.sqlite.SQLitePlatform;
|
|||||||
import io.ebean.config.dbplatform.sqlserver.SqlServer16Platform;
|
import io.ebean.config.dbplatform.sqlserver.SqlServer16Platform;
|
||||||
import io.ebean.config.dbplatform.sqlserver.SqlServer17Platform;
|
import io.ebean.config.dbplatform.sqlserver.SqlServer17Platform;
|
||||||
import io.ebean.dbmigration.DbMigration;
|
import io.ebean.dbmigration.DbMigration;
|
||||||
|
import io.ebean.util.IOUtils;
|
||||||
|
import io.ebean.util.StringHelper;
|
||||||
import io.ebeaninternal.api.DbOffline;
|
import io.ebeaninternal.api.DbOffline;
|
||||||
import io.ebeaninternal.api.SpiEbeanServer;
|
import io.ebeaninternal.api.SpiEbeanServer;
|
||||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlOptions;
|
import io.ebeaninternal.dbmigration.ddlgeneration.DdlOptions;
|
||||||
@@ -42,17 +58,6 @@ import io.ebeaninternal.dbmigration.model.PlatformDdlWriter;
|
|||||||
import io.ebeaninternal.extraddl.model.DdlScript;
|
import io.ebeaninternal.extraddl.model.DdlScript;
|
||||||
import io.ebeaninternal.extraddl.model.ExtraDdl;
|
import io.ebeaninternal.extraddl.model.ExtraDdl;
|
||||||
import io.ebeaninternal.extraddl.model.ExtraDdlXmlReader;
|
import io.ebeaninternal.extraddl.model.ExtraDdlXmlReader;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import static io.ebeaninternal.api.PlatformMatch.matchPlatform;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates DB Migration xml and sql scripts.
|
* Generates DB Migration xml and sql scripts.
|
||||||
@@ -392,19 +397,22 @@ public class DefaultDbMigration implements DbMigration {
|
|||||||
private void generateExtraDdl(File migrationDir, DatabasePlatform dbPlatform, boolean tablePartitioning) throws IOException {
|
private void generateExtraDdl(File migrationDir, DatabasePlatform dbPlatform, boolean tablePartitioning) throws IOException {
|
||||||
if (dbPlatform != null) {
|
if (dbPlatform != null) {
|
||||||
if (tablePartitioning && includeBuiltInPartitioning) {
|
if (tablePartitioning && includeBuiltInPartitioning) {
|
||||||
generateExtraDdlFor(migrationDir, dbPlatform, ExtraDdlXmlReader.readBuiltinTablePartitioning());
|
generateExtraDdlFor(migrationDir, dbPlatform, ExtraDdlXmlReader.readBuiltinTablePartitioning(), false);
|
||||||
}
|
}
|
||||||
generateExtraDdlFor(migrationDir, dbPlatform, ExtraDdlXmlReader.readBuiltin());
|
// skip built-in migration stored procedures based on isUseMigrationStoredProcedures
|
||||||
generateExtraDdlFor(migrationDir, dbPlatform, ExtraDdlXmlReader.read());
|
generateExtraDdlFor(migrationDir, dbPlatform, ExtraDdlXmlReader.readBuiltin(), true);
|
||||||
|
generateExtraDdlFor(migrationDir, dbPlatform, ExtraDdlXmlReader.read(), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateExtraDdlFor(File migrationDir, DatabasePlatform dbPlatform, ExtraDdl extraDdl) throws IOException {
|
private void generateExtraDdlFor(File migrationDir, DatabasePlatform dbPlatform, ExtraDdl extraDdl, boolean checkSkip) throws IOException {
|
||||||
if (extraDdl != null) {
|
if (extraDdl != null) {
|
||||||
List<DdlScript> ddlScript = extraDdl.getDdlScript();
|
List<DdlScript> ddlScript = extraDdl.getDdlScript();
|
||||||
for (DdlScript script : ddlScript) {
|
for (DdlScript script : ddlScript) {
|
||||||
if (!script.isDrop() && matchPlatform(dbPlatform.getPlatform(), script.getPlatforms())) {
|
if (!script.isDrop() && matchPlatform(dbPlatform.getPlatform(), script.getPlatforms())) {
|
||||||
writeExtraDdl(migrationDir, script);
|
if (!checkSkip || dbPlatform.isUseMigrationStoredProcedures()) {
|
||||||
|
writeExtraDdl(migrationDir, script);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -417,7 +425,7 @@ public class DefaultDbMigration implements DbMigration {
|
|||||||
String fullName = repeatableMigrationName(script.isInit(), script.getName());
|
String fullName = repeatableMigrationName(script.isInit(), script.getName());
|
||||||
logger.debug("writing repeatable script {}", fullName);
|
logger.debug("writing repeatable script {}", fullName);
|
||||||
File file = new File(migrationDir, fullName);
|
File file = new File(migrationDir, fullName);
|
||||||
try (FileWriter writer = new FileWriter(file)) {
|
try (Writer writer = IOUtils.newWriter(file)) {
|
||||||
writer.write(script.getValue());
|
writer.write(script.getValue());
|
||||||
writer.flush();
|
writer.flush();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,11 @@ package io.ebeaninternal.dbmigration;
|
|||||||
|
|
||||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||||
import io.ebean.migration.MigrationVersion;
|
import io.ebean.migration.MigrationVersion;
|
||||||
|
import io.ebean.util.IOUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.Writer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -50,17 +51,17 @@ class IndexMigration {
|
|||||||
|
|
||||||
private void generateIndex() throws IOException {
|
private void generateIndex() throws IOException {
|
||||||
Collections.sort(all);
|
Collections.sort(all);
|
||||||
FileWriter writer = new FileWriter(indexFile);
|
try (Writer writer = IOUtils.newWriter(indexFile)) {
|
||||||
for (Entry entry : all) {
|
for (Entry entry : all) {
|
||||||
writeChecksumPadded(writer, entry.checksum);
|
writeChecksumPadded(writer, entry.checksum);
|
||||||
writer.write(entry.fileName);
|
writer.write(entry.fileName);
|
||||||
|
writer.write(eol);
|
||||||
|
}
|
||||||
writer.write(eol);
|
writer.write(eol);
|
||||||
}
|
}
|
||||||
writer.write(eol);
|
|
||||||
writer.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeChecksumPadded(FileWriter writer, int checksum) throws IOException {
|
private void writeChecksumPadded(Writer writer, int checksum) throws IOException {
|
||||||
final String asStr = String.valueOf(checksum);
|
final String asStr = String.valueOf(checksum);
|
||||||
writer.write(asStr);
|
writer.write(asStr);
|
||||||
writer.write(',');
|
writer.write(',');
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import java.io.*;
|
|||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.zip.CRC32;
|
import java.util.zip.CRC32;
|
||||||
|
|
||||||
|
import io.ebean.util.IOUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the checksum for the given file content.
|
* Calculates the checksum for the given file content.
|
||||||
*/
|
*/
|
||||||
@@ -13,9 +15,8 @@ class MChecksum {
|
|||||||
* Returns the checksum of the file. Agnostic of encoding and new line character.
|
* Returns the checksum of the file. Agnostic of encoding and new line character.
|
||||||
*/
|
*/
|
||||||
static int calculate(File file) {
|
static int calculate(File file) {
|
||||||
try {
|
try (BufferedReader bufferedReader = IOUtils.newReader(file)) {
|
||||||
final CRC32 crc32 = new CRC32();
|
final CRC32 crc32 = new CRC32();
|
||||||
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
|
|
||||||
String line;
|
String line;
|
||||||
while ((line = bufferedReader.readLine()) != null) {
|
while ((line = bufferedReader.readLine()) != null) {
|
||||||
final byte[] lineBytes = line.getBytes(StandardCharsets.UTF_8);
|
final byte[] lineBytes = line.getBytes(StandardCharsets.UTF_8);
|
||||||
|
|||||||
+12
@@ -18,12 +18,15 @@ public class MySqlDdl extends PlatformDdl {
|
|||||||
// this flag is for compatibility. Use it with care.
|
// this flag is for compatibility. Use it with care.
|
||||||
private static final boolean USE_CHECK_CONSTRAINT = Boolean.getBoolean("ebean.mysql.useCheckConstraint");
|
private static final boolean USE_CHECK_CONSTRAINT = Boolean.getBoolean("ebean.mysql.useCheckConstraint");
|
||||||
|
|
||||||
|
private final boolean useMigrationStoredProcedures;
|
||||||
|
|
||||||
public MySqlDdl(DatabasePlatform platform) {
|
public MySqlDdl(DatabasePlatform platform) {
|
||||||
super(platform);
|
super(platform);
|
||||||
this.alterColumn = "modify";
|
this.alterColumn = "modify";
|
||||||
this.dropUniqueConstraint = "drop index";
|
this.dropUniqueConstraint = "drop index";
|
||||||
this.historyDdl = new MySqlHistoryDdl();
|
this.historyDdl = new MySqlHistoryDdl();
|
||||||
this.inlineComments = true;
|
this.inlineComments = true;
|
||||||
|
this.useMigrationStoredProcedures = platform.isUseMigrationStoredProcedures();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -34,6 +37,15 @@ public class MySqlDdl extends PlatformDdl {
|
|||||||
return "drop index " + maxConstraintName(indexName) + " on " + tableName;
|
return "drop index " + maxConstraintName(indexName) + " on " + tableName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void alterTableDropColumn(final DdlBuffer buffer, final String tableName, final String columnName) throws IOException {
|
||||||
|
if (this.useMigrationStoredProcedures) {
|
||||||
|
buffer.append("CALL usp_ebean_drop_column('").append(tableName).append("', '").append(columnName).append("')").endOfStatement();
|
||||||
|
} else {
|
||||||
|
super.alterTableDropColumn(buffer, tableName, columnName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the drop foreign key clause.
|
* Return the drop foreign key clause.
|
||||||
*/
|
*/
|
||||||
|
|||||||
+3
-2
@@ -1,14 +1,15 @@
|
|||||||
package io.ebeaninternal.dbmigration.migrationreader;
|
package io.ebeaninternal.dbmigration.migrationreader;
|
||||||
|
|
||||||
|
|
||||||
|
import io.ebean.util.IOUtils;
|
||||||
import io.ebeaninternal.dbmigration.migration.Migration;
|
import io.ebeaninternal.dbmigration.migration.Migration;
|
||||||
|
|
||||||
import javax.xml.bind.JAXBContext;
|
import javax.xml.bind.JAXBContext;
|
||||||
import javax.xml.bind.JAXBException;
|
import javax.xml.bind.JAXBException;
|
||||||
import javax.xml.bind.Marshaller;
|
import javax.xml.bind.Marshaller;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.Writer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple writer for output of the Migration/ChangeSet as an XML document.
|
* Simple writer for output of the Migration/ChangeSet as an XML document.
|
||||||
@@ -26,7 +27,7 @@ public class MigrationXmlWriter {
|
|||||||
*/
|
*/
|
||||||
public void write(Migration migration, File file) {
|
public void write(Migration migration, File file) {
|
||||||
|
|
||||||
try (FileWriter writer = new FileWriter(file)) {
|
try (Writer writer = IOUtils.newWriter(file)) {
|
||||||
|
|
||||||
writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n");
|
writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n");
|
||||||
if (comment != null) {
|
if (comment != null) {
|
||||||
|
|||||||
+4
-4
@@ -2,6 +2,7 @@ package io.ebeaninternal.dbmigration.model;
|
|||||||
|
|
||||||
import io.ebean.config.DatabaseConfig;
|
import io.ebean.config.DatabaseConfig;
|
||||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||||
|
import io.ebean.util.IOUtils;
|
||||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlHandler;
|
import io.ebeaninternal.dbmigration.ddlgeneration.DdlHandler;
|
||||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||||
@@ -14,7 +15,6 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -70,16 +70,16 @@ public class PlatformDdlWriter {
|
|||||||
*/
|
*/
|
||||||
protected void writePlatformDdl(DdlWrite write, File resourcePath, String fullVersion) throws IOException {
|
protected void writePlatformDdl(DdlWrite write, File resourcePath, String fullVersion) throws IOException {
|
||||||
if (!write.isApplyEmpty()) {
|
if (!write.isApplyEmpty()) {
|
||||||
try (FileWriter applyWriter = createWriter(resourcePath, fullVersion, ".sql")) {
|
try (Writer applyWriter = createWriter(resourcePath, fullVersion, ".sql")) {
|
||||||
writeApplyDdl(applyWriter, write);
|
writeApplyDdl(applyWriter, write);
|
||||||
applyWriter.flush();
|
applyWriter.flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected FileWriter createWriter(File path, String fullVersion, String suffix) throws IOException {
|
protected Writer createWriter(File path, String fullVersion, String suffix) throws IOException {
|
||||||
File applyFile = new File(path, fullVersion + suffix);
|
File applyFile = new File(path, fullVersion + suffix);
|
||||||
return new FileWriter(applyFile);
|
return IOUtils.newWriter(applyFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+83
@@ -112,5 +112,88 @@ BEGIN
|
|||||||
END
|
END
|
||||||
GO
|
GO
|
||||||
</ddl-script>
|
</ddl-script>
|
||||||
|
<ddl-script name="create procs" platforms="mysql" init="true">-- Inital script to create stored procedures etc for mysql platform
|
||||||
|
DROP PROCEDURE IF EXISTS usp_ebean_drop_foreign_keys;
|
||||||
|
|
||||||
|
delimiter $$
|
||||||
|
--
|
||||||
|
-- PROCEDURE: usp_ebean_drop_foreign_keys TABLE, COLUMN
|
||||||
|
-- deletes all constraints and foreign keys referring to TABLE.COLUMN
|
||||||
|
--
|
||||||
|
CREATE PROCEDURE usp_ebean_drop_foreign_keys(IN p_table_name VARCHAR(255), IN p_column_name VARCHAR(255))
|
||||||
|
BEGIN
|
||||||
|
DECLARE done INT DEFAULT FALSE;
|
||||||
|
DECLARE c_fk_name CHAR(255);
|
||||||
|
DECLARE curs CURSOR FOR SELECT CONSTRAINT_NAME from information_schema.KEY_COLUMN_USAGE
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE() and TABLE_NAME = p_table_name and COLUMN_NAME = p_column_name
|
||||||
|
AND REFERENCED_TABLE_NAME IS NOT NULL;
|
||||||
|
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
|
||||||
|
|
||||||
|
OPEN curs;
|
||||||
|
|
||||||
|
read_loop: LOOP
|
||||||
|
FETCH curs INTO c_fk_name;
|
||||||
|
IF done THEN
|
||||||
|
LEAVE read_loop;
|
||||||
|
END IF;
|
||||||
|
SET @sql = CONCAT('ALTER TABLE ', p_table_name, ' DROP FOREIGN KEY ', c_fk_name);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
CLOSE curs;
|
||||||
|
END
|
||||||
|
$$
|
||||||
|
|
||||||
|
DROP PROCEDURE IF EXISTS usp_ebean_drop_column;
|
||||||
|
|
||||||
|
delimiter $$
|
||||||
|
--
|
||||||
|
-- PROCEDURE: usp_ebean_drop_column TABLE, COLUMN
|
||||||
|
-- deletes the column and ensures that all indices and constraints are dropped first
|
||||||
|
--
|
||||||
|
CREATE PROCEDURE usp_ebean_drop_column(IN p_table_name VARCHAR(255), IN p_column_name VARCHAR(255))
|
||||||
|
BEGIN
|
||||||
|
CALL usp_ebean_drop_foreign_keys(p_table_name, p_column_name);
|
||||||
|
SET @sql = CONCAT('ALTER TABLE ', p_table_name, ' DROP COLUMN ', p_column_name);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
END
|
||||||
|
$$
|
||||||
|
</ddl-script>
|
||||||
|
|
||||||
|
<ddl-script name="create procs" platforms="hana" init="true">-- Inital script to create stored procedures etc for the hana platform
|
||||||
|
delimiter $$
|
||||||
|
--
|
||||||
|
-- PROCEDURE: usp_ebean_drop_foreign_keys TABLE, COLUMN
|
||||||
|
-- deletes all constraints and foreign keys referring to TABLE.COLUMN
|
||||||
|
--
|
||||||
|
CREATE OR REPLACE PROCEDURE usp_ebean_drop_foreign_keys(IN table_name NVARCHAR(256), IN column_name NVARCHAR(256))
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
DECLARE foreign_key_names TABLE(CONSTRAINT_NAME NVARCHAR(256), TABLE_NAME NVARCHAR(256));
|
||||||
|
DECLARE i INT;
|
||||||
|
|
||||||
|
foreign_key_names = SELECT CONSTRAINT_NAME, TABLE_NAME FROM SYS.REFERENTIAL_CONSTRAINTS WHERE SCHEMA_NAME=CURRENT_SCHEMA AND TABLE_NAME=UPPER(:table_name) AND COLUMN_NAME=UPPER(:column_name);
|
||||||
|
|
||||||
|
FOR I IN 1 .. RECORD_COUNT(:foreign_key_names) DO
|
||||||
|
EXEC 'ALTER TABLE "' || ESCAPE_DOUBLE_QUOTES(:foreign_key_names.TABLE_NAME[i]) || '" DROP CONSTRAINT "' || ESCAPE_DOUBLE_QUOTES(:foreign_key_names.CONSTRAINT_NAME[i]) || '"';
|
||||||
|
END FOR;
|
||||||
|
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
|
||||||
|
delimiter $$
|
||||||
|
--
|
||||||
|
-- PROCEDURE: usp_ebean_drop_column TABLE, COLUMN
|
||||||
|
-- deletes the column and ensures that all indices and constraints are dropped first
|
||||||
|
--
|
||||||
|
CREATE OR REPLACE PROCEDURE usp_ebean_drop_column(IN table_name NVARCHAR(256), IN column_name NVARCHAR(256))
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
CALL usp_ebean_drop_foreign_keys(table_name, column_name);
|
||||||
|
EXEC 'ALTER TABLE "' || UPPER(ESCAPE_DOUBLE_QUOTES(table_name)) || '" DROP ("' || UPPER(ESCAPE_DOUBLE_QUOTES(column_name)) || '")';
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
</ddl-script>
|
||||||
</extra-ddl>
|
</extra-ddl>
|
||||||
@@ -7,7 +7,7 @@ import java.io.File;
|
|||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
public class MChecksumTest {
|
public class MChecksumTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void calculate() {
|
public void calculate() {
|
||||||
File file = new File("src/test/resources/dbmigration/index/1.0__hello.sql");
|
File file = new File("src/test/resources/dbmigration/index/1.0__hello.sql");
|
||||||
@@ -15,4 +15,12 @@ public class MChecksumTest {
|
|||||||
|
|
||||||
assertThat(MChecksum.calculate(file)).isEqualTo(907060870);
|
assertThat(MChecksum.calculate(file)).isEqualTo(907060870);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void calculateWithSpecialChars() {
|
||||||
|
File file = new File("src/test/resources/dbmigration/index-special-chars/1.0__hello.sql");
|
||||||
|
assertThat(file).exists();
|
||||||
|
|
||||||
|
assertThat(MChecksum.calculate(file)).isEqualTo(1859426839);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+85
@@ -0,0 +1,85 @@
|
|||||||
|
package io.ebeaninternal.dbmigration;
|
||||||
|
|
||||||
|
import io.ebean.Database;
|
||||||
|
import io.ebean.DatabaseFactory;
|
||||||
|
import io.ebean.annotation.Platform;
|
||||||
|
import io.ebean.config.DatabaseConfig;
|
||||||
|
import io.ebean.config.PlatformConfig;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to test the alternative drop behaviour using stored procedures for MySql databases .
|
||||||
|
*
|
||||||
|
* @author Jonas Pöhler, FOCONIS AG
|
||||||
|
*/
|
||||||
|
public class MysqlGenerateMigrationTest {
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void resetPendingDropsProperty() {
|
||||||
|
System.clearProperty("ddl.migration.pendingDropsFor");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMysqlStoredProcedures() throws Exception {
|
||||||
|
DefaultDbMigration migration = new DefaultDbMigration();
|
||||||
|
migration.setIncludeIndex(true);
|
||||||
|
// We use src/test/resources as output directory (so we see in GIT if files will change)
|
||||||
|
migration.setPathToResources("src/test/resources");
|
||||||
|
|
||||||
|
migration.addPlatform(Platform.MYSQL, "mysql");
|
||||||
|
|
||||||
|
final PlatformConfig platformConfig = new PlatformConfig();
|
||||||
|
platformConfig.setUseMigrationStoredProcedures(true);
|
||||||
|
|
||||||
|
DatabaseConfig config = new DatabaseConfig();
|
||||||
|
config.setName("migrationtest");
|
||||||
|
config.loadFromProperties();
|
||||||
|
config.setPlatformConfig(platformConfig);
|
||||||
|
config.setRegister(false);
|
||||||
|
config.setDefaultServer(false);
|
||||||
|
config.getProperties().put("ebean.migration.migrationPath", "db/migration/mysql");
|
||||||
|
|
||||||
|
config.setPackages(Arrays.asList("misc.migration.mysql_v1_0"));
|
||||||
|
Database server = DatabaseFactory.create(config);
|
||||||
|
migration.setServer(server);
|
||||||
|
migration.setMigrationPath("mysql/procedures");
|
||||||
|
|
||||||
|
// First, we clean up the output-directory
|
||||||
|
assertThat(migration.migrationDirectory().getAbsolutePath()).contains("procedures");
|
||||||
|
Files.walk(migration.migrationDirectory().toPath())
|
||||||
|
.filter(Files::isRegularFile)
|
||||||
|
.map(Path::toFile).forEach(File::delete);
|
||||||
|
|
||||||
|
// then we generate migration scripts for v1_0
|
||||||
|
assertThat(migration.generateMigration()).isEqualTo("1.0__initial");
|
||||||
|
|
||||||
|
config.setPackages(Arrays.asList("misc.migration.mysql_v1_1"));
|
||||||
|
server.shutdown();
|
||||||
|
server = DatabaseFactory.create(config);
|
||||||
|
migration.setServer(server);
|
||||||
|
migration.setMigrationPath("mysql/procedures");
|
||||||
|
assertThat(migration.generateMigration()).isEqualTo("1.1");
|
||||||
|
|
||||||
|
System.setProperty("ddl.migration.pendingDropsFor", "1.1");
|
||||||
|
assertThat(migration.generateMigration()).isEqualTo("1.2__dropsFor_1.1");
|
||||||
|
|
||||||
|
final Path sqlFile = migration.migrationDirectory().toPath()
|
||||||
|
.resolve("mysql/1.2__dropsFor_1.1.sql");
|
||||||
|
|
||||||
|
assertThat(sqlFile).isNotEmptyFile();
|
||||||
|
assertThat(Files.readAllLines(sqlFile, StandardCharsets.UTF_8))
|
||||||
|
.contains("CALL usp_ebean_drop_column('migtest_e_basic', 'status2');")
|
||||||
|
.contains("CALL usp_ebean_drop_column('migtest_e_basic', 'description');");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-3
@@ -1,5 +1,6 @@
|
|||||||
package io.ebeaninternal.dbmigration.ddlgeneration;
|
package io.ebeaninternal.dbmigration.ddlgeneration;
|
||||||
|
|
||||||
|
import io.ebean.util.IOUtils;
|
||||||
import io.ebeaninternal.dbmigration.migration.AddColumn;
|
import io.ebeaninternal.dbmigration.migration.AddColumn;
|
||||||
import io.ebeaninternal.dbmigration.migration.ChangeSet;
|
import io.ebeaninternal.dbmigration.migration.ChangeSet;
|
||||||
import io.ebeaninternal.dbmigration.migration.CreateTable;
|
import io.ebeaninternal.dbmigration.migration.CreateTable;
|
||||||
@@ -9,8 +10,8 @@ import io.ebeaninternal.dbmigration.migrationreader.MigrationXmlReader;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.LineNumberReader;
|
import java.io.LineNumberReader;
|
||||||
|
import java.io.Reader;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -89,8 +90,7 @@ public class Helper {
|
|||||||
|
|
||||||
public static String asText(InputStream in) throws IOException {
|
public static String asText(InputStream in) throws IOException {
|
||||||
|
|
||||||
try {
|
try (Reader reader = IOUtils.newReader(in)) {
|
||||||
InputStreamReader reader = new InputStreamReader(in);
|
|
||||||
|
|
||||||
LineNumberReader lineNumberReader = new LineNumberReader(reader);
|
LineNumberReader lineNumberReader = new LineNumberReader(reader);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
package misc.migration.mysql_v1_0;
|
||||||
|
|
||||||
|
import io.ebean.annotation.DbDefault;
|
||||||
|
import io.ebean.annotation.EnumValue;
|
||||||
|
import io.ebean.annotation.NotNull;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import javax.validation.constraints.Size;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "migtest_e_basic")
|
||||||
|
public class EBasic {
|
||||||
|
|
||||||
|
public enum Status {
|
||||||
|
@EnumValue("N")
|
||||||
|
NEW,
|
||||||
|
|
||||||
|
@EnumValue("A")
|
||||||
|
ACTIVE,
|
||||||
|
|
||||||
|
@EnumValue("I")
|
||||||
|
INACTIVE,
|
||||||
|
}
|
||||||
|
|
||||||
|
@Id
|
||||||
|
Integer id;
|
||||||
|
|
||||||
|
Status status;
|
||||||
|
|
||||||
|
@DbDefault("N")
|
||||||
|
@NotNull
|
||||||
|
Status status2;
|
||||||
|
|
||||||
|
@Size(max=127)
|
||||||
|
String name;
|
||||||
|
|
||||||
|
@Size(max=127)
|
||||||
|
String description;
|
||||||
|
|
||||||
|
public EBasic() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public EBasic(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Status getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(Status status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Status getStatus2() {
|
||||||
|
return status2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus2(final Status status2) {
|
||||||
|
this.status2 = status2;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
package misc.migration.mysql_v1_1;
|
||||||
|
|
||||||
|
import io.ebean.annotation.EnumValue;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import javax.validation.constraints.Size;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "migtest_e_basic")
|
||||||
|
public class EBasic {
|
||||||
|
|
||||||
|
public enum Status {
|
||||||
|
@EnumValue("N")
|
||||||
|
NEW,
|
||||||
|
|
||||||
|
@EnumValue("A")
|
||||||
|
ACTIVE,
|
||||||
|
|
||||||
|
@EnumValue("I")
|
||||||
|
INACTIVE,
|
||||||
|
}
|
||||||
|
|
||||||
|
@Id
|
||||||
|
Integer id;
|
||||||
|
|
||||||
|
Status status;
|
||||||
|
|
||||||
|
@Size(max=127)
|
||||||
|
String name;
|
||||||
|
|
||||||
|
public EBasic() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public EBasic(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Status getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(Status status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
helloäüü
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<migration xmlns="http://ebean-orm.github.io/xml/ns/dbmigration">
|
||||||
|
<changeSet type="apply">
|
||||||
|
<createTable name="migtest_e_basic" pkName="pk_migtest_e_basic">
|
||||||
|
<column name="id" type="integer" primaryKey="true"/>
|
||||||
|
<column name="status" type="varchar(1)" checkConstraint="check ( status in ('N','A','I'))" checkConstraintName="ck_migtest_e_basic_status"/>
|
||||||
|
<column name="status2" type="varchar(1)" defaultValue="'N'" notnull="true" checkConstraint="check ( status2 in ('N','A','I'))" checkConstraintName="ck_migtest_e_basic_status2"/>
|
||||||
|
<column name="name" type="varchar(127)"/>
|
||||||
|
<column name="description" type="varchar(127)"/>
|
||||||
|
</createTable>
|
||||||
|
</changeSet>
|
||||||
|
</migration>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<migration xmlns="http://ebean-orm.github.io/xml/ns/dbmigration">
|
||||||
|
<changeSet type="pendingDrops">
|
||||||
|
<dropColumn columnName="status2" tableName="migtest_e_basic"/>
|
||||||
|
<dropColumn columnName="description" tableName="migtest_e_basic"/>
|
||||||
|
</changeSet>
|
||||||
|
</migration>
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<migration xmlns="http://ebean-orm.github.io/xml/ns/dbmigration">
|
||||||
|
<changeSet type="apply" dropsFor="1.1">
|
||||||
|
<dropColumn columnName="status2" tableName="migtest_e_basic"/>
|
||||||
|
<dropColumn columnName="description" tableName="migtest_e_basic"/>
|
||||||
|
</changeSet>
|
||||||
|
</migration>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
-- Migrationscripts for ebean unittest
|
||||||
|
-- apply changes
|
||||||
|
create table migtest_e_basic (
|
||||||
|
id integer auto_increment not null,
|
||||||
|
status varchar(1),
|
||||||
|
status2 varchar(1) default 'N' not null,
|
||||||
|
name varchar(127),
|
||||||
|
description varchar(127),
|
||||||
|
constraint pk_migtest_e_basic primary key (id)
|
||||||
|
);
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
-- Migrationscripts for ebean unittest
|
||||||
|
-- apply changes
|
||||||
|
CALL usp_ebean_drop_column('migtest_e_basic', 'status2');
|
||||||
|
|
||||||
|
CALL usp_ebean_drop_column('migtest_e_basic', 'description');
|
||||||
|
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
-- Inital script to create stored procedures etc for mysql platform
|
||||||
|
DROP PROCEDURE IF EXISTS usp_ebean_drop_foreign_keys;
|
||||||
|
|
||||||
|
delimiter $$
|
||||||
|
--
|
||||||
|
-- PROCEDURE: usp_ebean_drop_foreign_keys TABLE, COLUMN
|
||||||
|
-- deletes all constraints and foreign keys referring to TABLE.COLUMN
|
||||||
|
--
|
||||||
|
CREATE PROCEDURE usp_ebean_drop_foreign_keys(IN p_table_name VARCHAR(255), IN p_column_name VARCHAR(255))
|
||||||
|
BEGIN
|
||||||
|
DECLARE done INT DEFAULT FALSE;
|
||||||
|
DECLARE c_fk_name CHAR(255);
|
||||||
|
DECLARE curs CURSOR FOR SELECT CONSTRAINT_NAME from information_schema.KEY_COLUMN_USAGE
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE() and TABLE_NAME = p_table_name and COLUMN_NAME = p_column_name
|
||||||
|
AND REFERENCED_TABLE_NAME IS NOT NULL;
|
||||||
|
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
|
||||||
|
|
||||||
|
OPEN curs;
|
||||||
|
|
||||||
|
read_loop: LOOP
|
||||||
|
FETCH curs INTO c_fk_name;
|
||||||
|
IF done THEN
|
||||||
|
LEAVE read_loop;
|
||||||
|
END IF;
|
||||||
|
SET @sql = CONCAT('ALTER TABLE ', p_table_name, ' DROP FOREIGN KEY ', c_fk_name);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
CLOSE curs;
|
||||||
|
END
|
||||||
|
$$
|
||||||
|
|
||||||
|
DROP PROCEDURE IF EXISTS usp_ebean_drop_column;
|
||||||
|
|
||||||
|
delimiter $$
|
||||||
|
--
|
||||||
|
-- PROCEDURE: usp_ebean_drop_column TABLE, COLUMN
|
||||||
|
-- deletes the column and ensures that all indices and constraints are dropped first
|
||||||
|
--
|
||||||
|
CREATE PROCEDURE usp_ebean_drop_column(IN p_table_name VARCHAR(255), IN p_column_name VARCHAR(255))
|
||||||
|
BEGIN
|
||||||
|
CALL usp_ebean_drop_foreign_keys(p_table_name, p_column_name);
|
||||||
|
SET @sql = CONCAT('ALTER TABLE ', p_table_name, ' DROP COLUMN ', p_column_name);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
END
|
||||||
|
$$
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
1835064798, I__create_procs.sql
|
||||||
|
1968521526, 1.0__initial.sql
|
||||||
|
-728933533, 1.2__dropsFor_1.1.sql
|
||||||
|
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ebean-parent</artifactId>
|
<artifactId>ebean-parent</artifactId>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<name>ebean external mapping api</name>
|
<name>ebean external mapping api</name>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ebean-parent</artifactId>
|
<artifactId>ebean-parent</artifactId>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<!-- <parent>-->
|
<!-- <parent>-->
|
||||||
<!-- <groupId>org.avaje</groupId>-->
|
<!-- <groupId>org.avaje</groupId>-->
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-externalmapping-api</artifactId>
|
<artifactId>ebean-externalmapping-api</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -59,14 +59,14 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-core</artifactId>
|
<artifactId>ebean-core</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-ddl-generator</artifactId>
|
<artifactId>ebean-ddl-generator</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ebean-parent</artifactId>
|
<artifactId>ebean-parent</artifactId>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<version>12.13.2-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-core</artifactId>
|
<artifactId>ebean-core</artifactId>
|
||||||
<version>12.13.2-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-test</artifactId>
|
<artifactId>ebean-test</artifactId>
|
||||||
<version>12.13.2-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ebean-parent</artifactId>
|
<artifactId>ebean-parent</artifactId>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<name>ebean postgis</name>
|
<name>ebean postgis</name>
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-core</artifactId>
|
<artifactId>ebean-core</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-test</artifactId>
|
<artifactId>ebean-test</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ebean-parent</artifactId>
|
<artifactId>ebean-parent</artifactId>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<name>ebean querybean</name>
|
<name>ebean querybean</name>
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-core</artifactId>
|
<artifactId>ebean-core</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
@@ -56,21 +56,21 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-ddl-generator</artifactId>
|
<artifactId>ebean-ddl-generator</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>querybean-generator</artifactId>
|
<artifactId>querybean-generator</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-test</artifactId>
|
<artifactId>ebean-test</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|||||||
+7
-7
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ebean-parent</artifactId>
|
<artifactId>ebean-parent</artifactId>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>ebean-redis</artifactId>
|
<artifactId>ebean-redis</artifactId>
|
||||||
@@ -16,41 +16,41 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>redis.clients</groupId>
|
<groupId>redis.clients</groupId>
|
||||||
<artifactId>jedis</artifactId>
|
<artifactId>jedis</artifactId>
|
||||||
<version>3.6.3</version>
|
<version>3.8.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-api</artifactId>
|
<artifactId>ebean-api</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-core</artifactId>
|
<artifactId>ebean-core</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-querybean</artifactId>
|
<artifactId>ebean-querybean</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>querybean-generator</artifactId>
|
<artifactId>querybean-generator</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-test</artifactId>
|
<artifactId>ebean-test</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ebean-parent</artifactId>
|
<artifactId>ebean-parent</artifactId>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<name>ebean test</name>
|
<name>ebean test</name>
|
||||||
@@ -29,14 +29,14 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-core</artifactId>
|
<artifactId>ebean-core</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-ddl-generator</artifactId>
|
<artifactId>ebean-ddl-generator</artifactId>
|
||||||
<version>12.13.3-SNAPSHOT</version>
|
<version>12.14.2-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -56,7 +56,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-test-docker</artifactId>
|
<artifactId>ebean-test-docker</artifactId>
|
||||||
<version>4.3</version>
|
<version>4.4</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -91,7 +91,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-migration</artifactId>
|
<artifactId>ebean-migration</artifactId>
|
||||||
<version>12.12.1</version>
|
<version>12.13.0</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
@@ -226,7 +226,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ch.qos.logback</groupId>
|
<groupId>ch.qos.logback</groupId>
|
||||||
<artifactId>logback-classic</artifactId>
|
<artifactId>logback-classic</artifactId>
|
||||||
<version>1.2.3</version>
|
<version>1.2.9</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class ClickHouseSetup implements PlatformSetup {
|
|||||||
config.setDefaultPort(8123);
|
config.setDefaultPort(8123);
|
||||||
config.setUsername("default");
|
config.setUsername("default");
|
||||||
config.setPassword("");
|
config.setPassword("");
|
||||||
config.setUrl("jdbc:clickhouse://localhost:${port}/${databaseName}");
|
config.setUrl("jdbc:clickhouse://${host}:${port}/${databaseName}");
|
||||||
config.setDriver("ru.yandex.clickhouse.ClickHouseDriver");
|
config.setDriver("ru.yandex.clickhouse.ClickHouseDriver");
|
||||||
config.datasourceDefaults();
|
config.datasourceDefaults();
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class CockroachSetup implements PlatformSetup {
|
|||||||
config.setDefaultPort(26257);
|
config.setDefaultPort(26257);
|
||||||
config.setUsername("root");
|
config.setUsername("root");
|
||||||
config.setPassword("");
|
config.setPassword("");
|
||||||
config.setUrl("jdbc:postgresql://localhost:${port}/${databaseName}?sslmode=disable");
|
config.setUrl("jdbc:postgresql://${host}:${port}/${databaseName}?sslmode=disable");
|
||||||
config.setDriver("org.postgresql.Driver");
|
config.setDriver("org.postgresql.Driver");
|
||||||
config.datasourceDefaults();
|
config.datasourceDefaults();
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import io.ebean.config.DatabaseConfig;
|
|||||||
import io.ebean.datasource.DataSourceConfig;
|
import io.ebean.datasource.DataSourceConfig;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -26,11 +26,9 @@ class Config {
|
|||||||
private final String db;
|
private final String db;
|
||||||
private final String platform;
|
private final String platform;
|
||||||
private String dockerPlatform;
|
private String dockerPlatform;
|
||||||
|
|
||||||
private String databaseName;
|
private String databaseName;
|
||||||
|
|
||||||
private final Properties properties;
|
private final Properties properties;
|
||||||
|
|
||||||
private int port;
|
private int port;
|
||||||
|
|
||||||
private String url;
|
private String url;
|
||||||
@@ -38,12 +36,10 @@ class Config {
|
|||||||
private String schema;
|
private String schema;
|
||||||
private String username;
|
private String username;
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
private final DatabaseConfig config;
|
private final DatabaseConfig config;
|
||||||
|
|
||||||
private boolean containerDropCreate;
|
private boolean containerDropCreate;
|
||||||
|
|
||||||
private final Properties dockerProperties = new Properties();
|
private final Properties dockerProperties = new Properties();
|
||||||
|
private final DockerHost dockerHost = new DockerHost();
|
||||||
|
|
||||||
Config(String db, String platform, String databaseName, DatabaseConfig config) {
|
Config(String db, String platform, String databaseName, DatabaseConfig config) {
|
||||||
this.db = db;
|
this.db = db;
|
||||||
@@ -231,11 +227,17 @@ class Config {
|
|||||||
|
|
||||||
void setUrl(String urlPattern) {
|
void setUrl(String urlPattern) {
|
||||||
String val = getPlatformKey("url", urlPattern);
|
String val = getPlatformKey("url", urlPattern);
|
||||||
|
val = val.replace("${host}", host());
|
||||||
val = val.replace("${port}", String.valueOf(port));
|
val = val.replace("${port}", String.valueOf(port));
|
||||||
val = val.replace("${databaseName}", databaseName);
|
val = val.replace("${databaseName}", databaseName);
|
||||||
this.url = val;
|
this.url = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String host() {
|
||||||
|
String explicitDockerHost = getKey("dockerHost", null);
|
||||||
|
return getKey("host", dockerHost.dockerHost(explicitDockerHost));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Append to the connection URL.
|
* Append to the connection URL.
|
||||||
*/
|
*/
|
||||||
@@ -322,7 +324,6 @@ class Config {
|
|||||||
void setDockerVersion(String version) {
|
void setDockerVersion(String version) {
|
||||||
String val = getPlatformKey("version", version);
|
String val = getPlatformKey("version", version);
|
||||||
dockerProperties.setProperty(dockerKey("version"), val);
|
dockerProperties.setProperty(dockerKey("version"), val);
|
||||||
|
|
||||||
if (containerDropCreate) {
|
if (containerDropCreate) {
|
||||||
dockerProperties.setProperty(dockerKey("startMode"), "dropCreate");
|
dockerProperties.setProperty(dockerKey("startMode"), "dropCreate");
|
||||||
}
|
}
|
||||||
@@ -369,7 +370,10 @@ class Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initDockerProperties() {
|
private void initDockerProperties() {
|
||||||
|
if (dockerHost.runningInDocker()) {
|
||||||
|
// tell ebean-docker-test we are not using localhost (for jdbc DB setup commands)
|
||||||
|
dockerProperties.setProperty(dockerKey("host"), dockerHost.dockerHost());
|
||||||
|
}
|
||||||
dockerProperties.setProperty(dockerKey("port"), String.valueOf(port));
|
dockerProperties.setProperty(dockerKey("port"), String.valueOf(port));
|
||||||
dockerProperties.setProperty(dockerKey("dbName"), databaseName);
|
dockerProperties.setProperty(dockerKey("dbName"), databaseName);
|
||||||
if (schema != null) {
|
if (schema != null) {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class Db2Setup implements PlatformSetup {
|
|||||||
config.setDefaultPort(50000);
|
config.setDefaultPort(50000);
|
||||||
config.setUsernameDefault();
|
config.setUsernameDefault();
|
||||||
config.setPasswordDefault();
|
config.setPasswordDefault();
|
||||||
config.setUrl("jdbc:db2://localhost:${port}/${databaseName}");
|
config.setUrl("jdbc:db2://${host}:${port}/${databaseName}");
|
||||||
config.setDriver("com.ibm.db2.jcc.DB2Driver");
|
config.setDriver("com.ibm.db2.jcc.DB2Driver");
|
||||||
config.datasourceDefaults();
|
config.datasourceDefaults();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package io.ebean.test.config.platform;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to detect if running inside docker and determine host name for that case.
|
||||||
|
*/
|
||||||
|
class DockerHost {
|
||||||
|
|
||||||
|
private final boolean runningInDocker;
|
||||||
|
private String dockerHost;
|
||||||
|
|
||||||
|
DockerHost() {
|
||||||
|
runningInDocker = initInDocker();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean runningInDocker() {
|
||||||
|
return runningInDocker;
|
||||||
|
}
|
||||||
|
|
||||||
|
String dockerHost() {
|
||||||
|
return dockerHost;
|
||||||
|
}
|
||||||
|
|
||||||
|
String dockerHost(String explicitHost) {
|
||||||
|
if (!runningInDocker) {
|
||||||
|
return "localhost";
|
||||||
|
}
|
||||||
|
dockerHost = explicitHost != null ? explicitHost : defaultDockerHost();
|
||||||
|
return dockerHost;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if running inside a docker container (we are using docker in docker).
|
||||||
|
*/
|
||||||
|
boolean initInDocker() {
|
||||||
|
return new File("/.dockerenv").exists();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the default host name to use when running in docker.
|
||||||
|
* <p>
|
||||||
|
* Can instead be explicitly specified via <code>ebean.test.dockerHost</code>.
|
||||||
|
*/
|
||||||
|
String defaultDockerHost() {
|
||||||
|
String os = System.getProperty("os.name", "generic").toLowerCase(Locale.ENGLISH);
|
||||||
|
if (os.contains("mac") || os.contains("darwin") || os.contains("win")) {
|
||||||
|
return "host.docker.internal";
|
||||||
|
} else {
|
||||||
|
return "172.17.0.1";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -20,7 +20,7 @@ class HanaSetup implements PlatformSetup {
|
|||||||
config.setUsername("SYSTEM");
|
config.setUsername("SYSTEM");
|
||||||
config.setPassword("HXEHana1");
|
config.setPassword("HXEHana1");
|
||||||
config.setDatabaseName("HXE");
|
config.setDatabaseName("HXE");
|
||||||
config.setUrl("jdbc:sap://localhost:${port}/?databaseName=${databaseName}");
|
config.setUrl("jdbc:sap://${host}:${port}/?databaseName=${databaseName}");
|
||||||
String schema = config.getSchema();
|
String schema = config.getSchema();
|
||||||
if (schema != null && !schema.equals(config.getUsername())) {
|
if (schema != null && !schema.equals(config.getUsername())) {
|
||||||
config.urlAppend("¤tSchema=" + schema);
|
config.urlAppend("¤tSchema=" + schema);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class MariaDBSetup implements PlatformSetup {
|
|||||||
config.setDefaultPort(defaultPort);
|
config.setDefaultPort(defaultPort);
|
||||||
config.setUsernameDefault();
|
config.setUsernameDefault();
|
||||||
config.setPasswordDefault();
|
config.setPasswordDefault();
|
||||||
config.setUrl("jdbc:mariadb://localhost:${port}/${databaseName}?useLegacyDatetimeCode=false");
|
config.setUrl("jdbc:mariadb://${host}:${port}/${databaseName}?useLegacyDatetimeCode=false");
|
||||||
config.datasourceDefaults();
|
config.datasourceDefaults();
|
||||||
|
|
||||||
return dockerProperties(config);
|
return dockerProperties(config);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class MySqlSetup implements PlatformSetup {
|
|||||||
config.setDefaultPort(defaultPort);
|
config.setDefaultPort(defaultPort);
|
||||||
config.setUsernameDefault();
|
config.setUsernameDefault();
|
||||||
config.setPasswordDefault();
|
config.setPasswordDefault();
|
||||||
config.setUrl("jdbc:mysql://localhost:${port}/${databaseName}");
|
config.setUrl("jdbc:mysql://${host}:${port}/${databaseName}");
|
||||||
config.setDriver(defaultDriver());
|
config.setDriver(defaultDriver());
|
||||||
config.datasourceDefaults();
|
config.datasourceDefaults();
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class PostgisSetup implements PlatformSetup {
|
|||||||
config.setUsernameDefault();
|
config.setUsernameDefault();
|
||||||
config.setPasswordDefault();
|
config.setPasswordDefault();
|
||||||
config.setDriver("org.postgis.DriverWrapperLW");
|
config.setDriver("org.postgis.DriverWrapperLW");
|
||||||
config.setUrl("jdbc:postgresql_lwgis://localhost:${port}/${databaseName}");
|
config.setUrl("jdbc:postgresql_lwgis://${host}:${port}/${databaseName}");
|
||||||
|
|
||||||
String schema = config.getSchema();
|
String schema = config.getSchema();
|
||||||
if (schema != null && !schema.equals(config.getUsername())) {
|
if (schema != null && !schema.equals(config.getUsername())) {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class PostgresSetup implements PlatformSetup {
|
|||||||
config.setDefaultPort(defaultPort);
|
config.setDefaultPort(defaultPort);
|
||||||
config.setUsernameDefault();
|
config.setUsernameDefault();
|
||||||
config.setPasswordDefault();
|
config.setPasswordDefault();
|
||||||
config.setUrl("jdbc:postgresql://localhost:${port}/${databaseName}");
|
config.setUrl("jdbc:postgresql://${host}:${port}/${databaseName}");
|
||||||
|
|
||||||
String schema = config.getSchema();
|
String schema = config.getSchema();
|
||||||
if (schema != null && !schema.equals(config.getUsername())) {
|
if (schema != null && !schema.equals(config.getUsername())) {
|
||||||
@@ -44,7 +44,7 @@ class PostgresSetup implements PlatformSetup {
|
|||||||
config.setDefaultPort(defaultPort);
|
config.setDefaultPort(defaultPort);
|
||||||
config.setExtraUsernameDefault();
|
config.setExtraUsernameDefault();
|
||||||
config.setExtraDbPasswordDefault();
|
config.setExtraDbPasswordDefault();
|
||||||
config.setUrl("jdbc:postgresql://localhost:${port}/${databaseName}");
|
config.setUrl("jdbc:postgresql://${host}:${port}/${databaseName}");
|
||||||
config.setDriver("org.postgresql.Driver");
|
config.setDriver("org.postgresql.Driver");
|
||||||
config.extraDatasourceDefaults();
|
config.extraDatasourceDefaults();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,10 +8,14 @@ import java.util.Properties;
|
|||||||
class RedisSetup {
|
class RedisSetup {
|
||||||
|
|
||||||
static void run(Properties properties) {
|
static void run(Properties properties) {
|
||||||
|
|
||||||
String version = properties.getProperty("ebean.test.redis");
|
String version = properties.getProperty("ebean.test.redis");
|
||||||
version = properties.getProperty("ebean.test.redis.version", version);
|
version = properties.getProperty("ebean.test.redis.version", version);
|
||||||
if (version != null) {
|
if (version != null) {
|
||||||
|
DockerHost dockerHost = new DockerHost();
|
||||||
|
if (dockerHost.runningInDocker()) {
|
||||||
|
String host = dockerHost.dockerHost(properties.getProperty("ebean.test.dockerHost"));
|
||||||
|
properties.setProperty("redis.host", host);
|
||||||
|
}
|
||||||
RedisConfig redisConfig = new RedisConfig(version, properties);
|
RedisConfig redisConfig = new RedisConfig(version, properties);
|
||||||
RedisContainer container = new RedisContainer(redisConfig);
|
RedisContainer container = new RedisContainer(redisConfig);
|
||||||
container.start();
|
container.start();
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class SqlServerSetup implements PlatformSetup {
|
|||||||
config.setDefaultPort(1433);
|
config.setDefaultPort(1433);
|
||||||
config.setUsernameDefault();
|
config.setUsernameDefault();
|
||||||
config.setPassword("SqlS3rv#r");
|
config.setPassword("SqlS3rv#r");
|
||||||
config.setUrl("jdbc:sqlserver://localhost:${port};databaseName=${databaseName}");
|
config.setUrl("jdbc:sqlserver://${host}:${port};databaseName=${databaseName};sendTimeAsDateTime=false");
|
||||||
config.setDriver("com.microsoft.sqlserver.jdbc.SQLServerDriver");
|
config.setDriver("com.microsoft.sqlserver.jdbc.SQLServerDriver");
|
||||||
config.datasourceDefaults();
|
config.datasourceDefaults();
|
||||||
|
|
||||||
|
|||||||
@@ -27,16 +27,17 @@ public class DatabaseConfigTest {
|
|||||||
@Test
|
@Test
|
||||||
public void evalPropertiesInput() {
|
public void evalPropertiesInput() {
|
||||||
|
|
||||||
String home = System.getenv("HOME");
|
String home = System.getProperty("user.home");
|
||||||
|
String fileSeparator = System.getProperty("file.separator");
|
||||||
|
|
||||||
Properties props = new Properties();
|
Properties props = new Properties();
|
||||||
props.setProperty("ddl.initSql", "${HOME}/initSql");
|
props.setProperty("ddl.initSql", "${user.home}" + fileSeparator + "initSql");
|
||||||
|
|
||||||
DatabaseConfig config = new DatabaseConfig();
|
DatabaseConfig config = new DatabaseConfig();
|
||||||
config.loadFromProperties(props);
|
config.loadFromProperties(props);
|
||||||
|
|
||||||
String ddlInitSql = config.getDdlInitSql();
|
String ddlInitSql = config.getDdlInitSql();
|
||||||
assertThat(ddlInitSql).isEqualTo(home+"/initSql");
|
assertThat(ddlInitSql).isEqualTo(home + fileSeparator + "initSql");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -50,30 +50,31 @@ public class PropertiesWrapperTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testGetProperties() {
|
public void testGetProperties() {
|
||||||
|
|
||||||
String home = System.getenv("HOME");
|
String home = System.getProperty("user.home");
|
||||||
String tmpDir = System.getProperty("java.io.tmpdir");
|
String tmpDir = System.getProperty("java.io.tmpdir");
|
||||||
|
String fileSeparator = System.getProperty("file.separator");
|
||||||
|
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
properties.put("someBasic", "hello");
|
properties.put("someBasic", "hello");
|
||||||
properties.put("someInt", "42");
|
properties.put("someInt", "42");
|
||||||
properties.put("someDouble", "5.5");
|
properties.put("someDouble", "5.5");
|
||||||
properties.put("somePath", "${HOME}/hello");
|
properties.put("somePath", "${user.home}" + fileSeparator + "hello");
|
||||||
properties.put("someSystemProp", "/aaa/${java.io.tmpdir}/bbb");
|
properties.put("someSystemProp", fileSeparator + "aaa" + fileSeparator + "${java.io.tmpdir}" + fileSeparator + "bbb");
|
||||||
|
|
||||||
Properties evalCopy = Config.asConfiguration().eval(properties);
|
Properties evalCopy = Config.asConfiguration().eval(properties);
|
||||||
PropertiesWrapper pw = new PropertiesWrapper("pref", "myserver", evalCopy, null);
|
PropertiesWrapper pw = new PropertiesWrapper("pref", "myserver", evalCopy, null);
|
||||||
|
|
||||||
assertEquals(42, pw.getInt("someInt", 99));
|
assertEquals(42, pw.getInt("someInt", 99));
|
||||||
assertEquals(Double.valueOf(5.5D), (Double.valueOf(pw.getDouble("someDouble", 99.9D))));
|
assertEquals(Double.valueOf(5.5D), (Double.valueOf(pw.getDouble("someDouble", 99.9D))));
|
||||||
assertEquals(home + "/hello", pw.get("somePath", null));
|
assertEquals(home + fileSeparator + "hello", pw.get("somePath", null));
|
||||||
assertEquals("/aaa/" + tmpDir + "/bbb", pw.get("someSystemProp"));
|
assertEquals(fileSeparator + "aaa" + fileSeparator + tmpDir + fileSeparator + "bbb", pw.get("someSystemProp"));
|
||||||
|
|
||||||
pw = new PropertiesWrapper(evalCopy, null);
|
pw = new PropertiesWrapper(evalCopy, null);
|
||||||
|
|
||||||
assertEquals(42, pw.getInt("someInt", 99));
|
assertEquals(42, pw.getInt("someInt", 99));
|
||||||
assertEquals(Double.valueOf(5.5D), (Double.valueOf(pw.getDouble("someDouble", 99.9D))));
|
assertEquals(Double.valueOf(5.5D), (Double.valueOf(pw.getDouble("someDouble", 99.9D))));
|
||||||
assertEquals(home + "/hello", pw.get("somePath", null));
|
assertEquals(home + fileSeparator + "hello", pw.get("somePath", null));
|
||||||
assertEquals("/aaa/" + tmpDir + "/bbb", pw.get("someSystemProp"));
|
assertEquals(fileSeparator + "aaa" + fileSeparator + tmpDir + fileSeparator + "bbb", pw.get("someSystemProp"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2,28 +2,34 @@ package io.ebean.config.dbplatform;
|
|||||||
|
|
||||||
import io.ebean.config.PlatformConfig;
|
import io.ebean.config.PlatformConfig;
|
||||||
import io.ebean.config.dbplatform.oracle.Oracle11Platform;
|
import io.ebean.config.dbplatform.oracle.Oracle11Platform;
|
||||||
|
import io.ebean.config.dbplatform.oracle.Oracle12Platform;
|
||||||
import io.ebean.config.dbplatform.oracle.OraclePlatform;
|
import io.ebean.config.dbplatform.oracle.OraclePlatform;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
public class OraclePlatformTest {
|
class OraclePlatformTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void columnAliasPrefix_Oracle11Platform() {
|
void columnAliasPrefix_Oracle11Platform() {
|
||||||
Oracle11Platform platform11 = new Oracle11Platform();
|
Oracle11Platform platform11 = new Oracle11Platform();
|
||||||
assertThat(platform11.columnAliasPrefix).isEqualTo("c");
|
assertThat(platform11.columnAliasPrefix).isEqualTo("c");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void columnAliasPrefix_OraclePlatform() {
|
void columnAliasPrefix_Oracle12Platform() {
|
||||||
OraclePlatform platform = new OraclePlatform();
|
Oracle12Platform platform12 = new Oracle12Platform();
|
||||||
assertThat(platform.columnAliasPrefix).isEqualTo("c");
|
assertThat(platform12.columnAliasPrefix).isEqualTo("c");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void uuid_default() {
|
void columnAliasPrefix_OraclePlatform() {
|
||||||
|
OraclePlatform platform = new OraclePlatform();
|
||||||
|
assertThat(platform.columnAliasPrefix).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void uuid_default() {
|
||||||
OraclePlatform platform = new OraclePlatform();
|
OraclePlatform platform = new OraclePlatform();
|
||||||
platform.configure(new PlatformConfig(), false);
|
platform.configure(new PlatformConfig(), false);
|
||||||
DbPlatformType dbType = platform.getDbTypeMap().get(DbPlatformType.UUID);
|
DbPlatformType dbType = platform.getDbTypeMap().get(DbPlatformType.UUID);
|
||||||
@@ -31,8 +37,7 @@ public class OraclePlatformTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void uuid_as_binary() {
|
void uuid_as_binary() {
|
||||||
|
|
||||||
OraclePlatform platform = new OraclePlatform();
|
OraclePlatform platform = new OraclePlatform();
|
||||||
PlatformConfig config = new PlatformConfig();
|
PlatformConfig config = new PlatformConfig();
|
||||||
config.setDbUuid(PlatformConfig.DbUuid.AUTO_BINARY);
|
config.setDbUuid(PlatformConfig.DbUuid.AUTO_BINARY);
|
||||||
|
|||||||
@@ -4,24 +4,22 @@ import com.fasterxml.jackson.core.JsonFactory;
|
|||||||
import com.fasterxml.jackson.core.JsonParser;
|
import com.fasterxml.jackson.core.JsonParser;
|
||||||
import io.ebean.ModifyAwareType;
|
import io.ebean.ModifyAwareType;
|
||||||
import io.ebean.text.json.EJson;
|
import io.ebean.text.json.EJson;
|
||||||
|
import io.ebean.util.IOUtils;
|
||||||
import io.ebeaninternal.json.ModifyAwareMap;
|
import io.ebeaninternal.json.ModifyAwareMap;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
|
import java.io.Writer;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
public class EJsonTests {
|
public class EJsonTests {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(EJsonTests.class);
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test_map_simple() throws IOException {
|
public void test_map_simple() throws IOException {
|
||||||
|
|
||||||
@@ -46,15 +44,13 @@ public class EJsonTests {
|
|||||||
public void write_withWriter_expect_writerNotClosed() throws IOException {
|
public void write_withWriter_expect_writerNotClosed() throws IOException {
|
||||||
|
|
||||||
File temp = Files.createTempFile("some", ".json").toFile();
|
File temp = Files.createTempFile("some", ".json").toFile();
|
||||||
FileWriter writer = new FileWriter(temp);
|
try (Writer writer = IOUtils.newWriter(temp)) {
|
||||||
Map<String,Object> map = new LinkedHashMap<>();
|
Map<String, Object> map = new LinkedHashMap<>();
|
||||||
map.put("foo", "bar");
|
map.put("foo", "bar");
|
||||||
EJson.write(map, writer);
|
EJson.write(map, writer);
|
||||||
writer.write("The end.");
|
writer.write("The end.");
|
||||||
writer.flush();
|
}
|
||||||
writer.close();
|
assertThat(temp).hasContent("{\"foo\":\"bar\"}The end.");
|
||||||
|
|
||||||
log.info("write to file {}", temp.getAbsolutePath());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -0,0 +1,87 @@
|
|||||||
|
package io.ebean.test.config.platform;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Disabled;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
class DockerHostTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void runningInDocker_when_false_alwaysUseLocalhost() {
|
||||||
|
DockerHost dockerHost = new DockerHost();
|
||||||
|
assertFalse(dockerHost.runningInDocker());
|
||||||
|
assertEquals("localhost", dockerHost.dockerHost("foo"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void runningInDocker_when_true_useExplicit() {
|
||||||
|
TDDockerHost dockerHost = new TDDockerHost();
|
||||||
|
assertTrue(dockerHost.runningInDocker());
|
||||||
|
|
||||||
|
assertEquals("my-host", dockerHost.dockerHost("my-host"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Disabled
|
||||||
|
@Test
|
||||||
|
void runningInDocker_when_trueAndLinux_useDefault() {
|
||||||
|
TDDockerHost dockerHost = new TDDockerHost();
|
||||||
|
assertTrue(dockerHost.runningInDocker());
|
||||||
|
|
||||||
|
assertEquals("172.17.0.1", dockerHost.dockerHost(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void runningInDocker_when_windowsDefault() {
|
||||||
|
TDDockerHost dockerHost = new TDDockerHost();
|
||||||
|
assertTrue(dockerHost.runningInDocker());
|
||||||
|
|
||||||
|
String origName = System.getProperty("os.name");
|
||||||
|
System.setProperty("os.name", "win");
|
||||||
|
try {
|
||||||
|
assertEquals("host.docker.internal",dockerHost.defaultDockerHost());
|
||||||
|
assertEquals("host.docker.internal", dockerHost.dockerHost(null));
|
||||||
|
} finally {
|
||||||
|
System.setProperty("os.name", origName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void runningInDocker_when_macDefault() {
|
||||||
|
TDDockerHost dockerHost = new TDDockerHost();
|
||||||
|
assertTrue(dockerHost.runningInDocker());
|
||||||
|
|
||||||
|
String origName = System.getProperty("os.name");
|
||||||
|
System.setProperty("os.name", "mac");
|
||||||
|
try {
|
||||||
|
assertEquals("host.docker.internal",dockerHost.defaultDockerHost());
|
||||||
|
assertEquals("host.docker.internal", dockerHost.dockerHost(null));
|
||||||
|
} finally {
|
||||||
|
System.setProperty("os.name", origName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void runningInDocker_when_linuxDefault() {
|
||||||
|
TDDockerHost dockerHost = new TDDockerHost();
|
||||||
|
assertTrue(dockerHost.runningInDocker());
|
||||||
|
|
||||||
|
String origName = System.getProperty("os.name");
|
||||||
|
System.setProperty("os.name", "linux");
|
||||||
|
try {
|
||||||
|
assertEquals("172.17.0.1",dockerHost.defaultDockerHost());
|
||||||
|
assertEquals("172.17.0.1", dockerHost.dockerHost(null));
|
||||||
|
} finally {
|
||||||
|
System.setProperty("os.name", origName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class TDDockerHost extends DockerHost {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean initInDocker() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-1
@@ -11,6 +11,7 @@ import org.tests.model.basic.ResetBasicData;
|
|||||||
import org.tests.model.basic.TBytesOnly;
|
import org.tests.model.basic.TBytesOnly;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -94,7 +95,7 @@ public class CachedBeanDataSerializeTest extends BaseTestCase {
|
|||||||
|
|
||||||
TBytesOnly bean = new TBytesOnly();
|
TBytesOnly bean = new TBytesOnly();
|
||||||
bean.setId(42);
|
bean.setId(42);
|
||||||
bean.setContent(stringContent.getBytes("UTF-8"));
|
bean.setContent(stringContent.getBytes(StandardCharsets.UTF_8));
|
||||||
|
|
||||||
BeanDescriptor<TBytesOnly> desc = getBeanDescriptor(TBytesOnly.class);
|
BeanDescriptor<TBytesOnly> desc = getBeanDescriptor(TBytesOnly.class);
|
||||||
CachedBeanData extract = CachedBeanDataFromBean.extract(desc, (EntityBean) bean);
|
CachedBeanData extract = CachedBeanDataFromBean.extract(desc, (EntityBean) bean);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import io.ebean.config.EncryptKey;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.tests.basic.encrypt.BasicEncryptKey;
|
import org.tests.basic.encrypt.BasicEncryptKey;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
@@ -19,7 +20,7 @@ public class TestSimpleEncryptor extends BaseTestCase {
|
|||||||
|
|
||||||
EncryptKey key = new BasicEncryptKey("hello");
|
EncryptKey key = new BasicEncryptKey("hello");
|
||||||
|
|
||||||
byte[] data = "test123".getBytes();
|
byte[] data = "test123".getBytes(StandardCharsets.UTF_8);
|
||||||
|
|
||||||
byte[] ecData = e.encrypt(data, key);
|
byte[] ecData = e.encrypt(data, key);
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ import org.tests.model.ivo.converter.MoneyTypeConverter;
|
|||||||
import javax.persistence.EnumType;
|
import javax.persistence.EnumType;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.GregorianCalendar;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.fail;
|
import static org.assertj.core.api.Assertions.fail;
|
||||||
@@ -29,7 +31,6 @@ public class TestTypeManager extends BaseTestCase {
|
|||||||
DefaultTypeManager typeManager = createTypeManager();
|
DefaultTypeManager typeManager = createTypeManager();
|
||||||
|
|
||||||
ScalarType<?> type = typeManager.createEnumScalarType(MyEnum.class, null);
|
ScalarType<?> type = typeManager.createEnumScalarType(MyEnum.class, null);
|
||||||
typeManager.addEnumType(type, MyEnum.class);
|
|
||||||
|
|
||||||
Object val = type.read(new DummyDataReader("A"));
|
Object val = type.read(new DummyDataReader("A"));
|
||||||
assertThat(val).isEqualTo(MyEnum.Aval);
|
assertThat(val).isEqualTo(MyEnum.Aval);
|
||||||
@@ -131,6 +132,13 @@ public class TestTypeManager extends BaseTestCase {
|
|||||||
return new DefaultTypeManager(config, bootupClasses);
|
return new DefaultTypeManager(config, bootupClasses);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCalendar() throws SQLException {
|
||||||
|
|
||||||
|
DefaultTypeManager typeManager = createTypeManager();
|
||||||
|
ScalarType<?> typeB = typeManager.getScalarType(GregorianCalendar.class);
|
||||||
|
assertThat(typeB).isInstanceOf(ScalarTypeCalendar.class);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Test double DataReader implementation.
|
* Test double DataReader implementation.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -8,12 +8,14 @@ import org.tests.model.basic.PFileContent;
|
|||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
public class TestDeleteImportedPartial extends BaseTestCase {
|
public class TestDeleteImportedPartial extends BaseTestCase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void test() {
|
||||||
|
|
||||||
PFile persistentFile = new PFile("test.txt", new PFileContent("test".getBytes()));
|
PFile persistentFile = new PFile("test.txt", new PFileContent("test".getBytes(StandardCharsets.UTF_8)));
|
||||||
|
|
||||||
DB.save(persistentFile);
|
DB.save(persistentFile);
|
||||||
Integer id = persistentFile.getId();
|
Integer id = persistentFile.getId();
|
||||||
|
|||||||
@@ -8,13 +8,15 @@ import org.tests.model.basic.PersistentFileContent;
|
|||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
public class TestDeleteOneToOne extends BaseTestCase {
|
public class TestDeleteOneToOne extends BaseTestCase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateDeletePersistentFile() {
|
public void testCreateDeletePersistentFile() {
|
||||||
|
|
||||||
PersistentFile persistentFile = new PersistentFile("test.txt", new PersistentFileContent(
|
PersistentFile persistentFile = new PersistentFile("test.txt", new PersistentFileContent(
|
||||||
"test".getBytes()));
|
"test".getBytes(StandardCharsets.UTF_8)));
|
||||||
|
|
||||||
DB.save(persistentFile);
|
DB.save(persistentFile);
|
||||||
Integer id = persistentFile.getId();
|
Integer id = persistentFile.getId();
|
||||||
|
|||||||
@@ -8,16 +8,18 @@ import org.tests.model.basic.PFileContent;
|
|||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
public class TestDeleteOneToOneMultiple extends BaseTestCase {
|
public class TestDeleteOneToOneMultiple extends BaseTestCase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateDeletePersistentFile() {
|
public void testCreateDeletePersistentFile() {
|
||||||
|
|
||||||
PFile persistentFile = new PFile("test.txt", new PFileContent("test".getBytes()));
|
PFile persistentFile = new PFile("test.txt", new PFileContent("test".getBytes(StandardCharsets.UTF_8)));
|
||||||
// PFile persistentFile = new PFile();
|
// PFile persistentFile = new PFile();
|
||||||
// persistentFile.setName("test.txt");
|
// persistentFile.setName("test.txt");
|
||||||
// PFileContent content = new PFileContent();
|
// PFileContent content = new PFileContent();
|
||||||
// content.setContent("test".getBytes());
|
// content.setContent("test".getBytes(StandardCharsets.UTF_8));
|
||||||
// persistentFile.setFileContent(content);
|
// persistentFile.setFileContent(content);
|
||||||
|
|
||||||
DB.save(persistentFile);
|
DB.save(persistentFile);
|
||||||
|
|||||||
@@ -8,12 +8,14 @@ import org.tests.model.basic.PersistentFileContent;
|
|||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
public class TestSaveDeleteOneToOne extends BaseTestCase {
|
public class TestSaveDeleteOneToOne extends BaseTestCase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateDeletePersistentFile() {
|
public void testCreateDeletePersistentFile() {
|
||||||
PersistentFile persistentFile = new PersistentFile("test.txt",
|
PersistentFile persistentFile = new PersistentFile("test.txt",
|
||||||
new PersistentFileContent("test".getBytes()));
|
new PersistentFileContent("test".getBytes(StandardCharsets.UTF_8)));
|
||||||
|
|
||||||
DB.save(persistentFile);
|
DB.save(persistentFile);
|
||||||
DB.delete(persistentFile);
|
DB.delete(persistentFile);
|
||||||
@@ -22,7 +24,7 @@ public class TestSaveDeleteOneToOne extends BaseTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testCreateLoadDeletePersistentFile() {
|
public void testCreateLoadDeletePersistentFile() {
|
||||||
PersistentFile persistentFile = new PersistentFile("test.txt",
|
PersistentFile persistentFile = new PersistentFile("test.txt",
|
||||||
new PersistentFileContent("test".getBytes()));
|
new PersistentFileContent("test".getBytes(StandardCharsets.UTF_8)));
|
||||||
|
|
||||||
DB.save(persistentFile);
|
DB.save(persistentFile);
|
||||||
|
|
||||||
|
|||||||
@@ -8,11 +8,13 @@ import org.tests.model.basic.PFileContent;
|
|||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
public class TestSaveDeleteOneToOneMultiple extends BaseTestCase {
|
public class TestSaveDeleteOneToOneMultiple extends BaseTestCase {
|
||||||
|
|
||||||
// public void testCreateDeletePFile() {
|
// public void testCreateDeletePFile() {
|
||||||
// PFile persistentFile = new PFile("test.txt",
|
// PFile persistentFile = new PFile("test.txt",
|
||||||
// new PFileContent("test".getBytes()));
|
// new PFileContent("test".getBytes(StandardCharsets.UTF_8)));
|
||||||
//
|
//
|
||||||
// DB.save(persistentFile);
|
// DB.save(persistentFile);
|
||||||
// DB.delete(persistentFile);
|
// DB.delete(persistentFile);
|
||||||
@@ -21,7 +23,7 @@ public class TestSaveDeleteOneToOneMultiple extends BaseTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testCreateLoadDeletePFile() {
|
public void testCreateLoadDeletePFile() {
|
||||||
PFile persistentFile = new PFile("test.txt",
|
PFile persistentFile = new PFile("test.txt",
|
||||||
new PFileContent("test".getBytes()));
|
new PFileContent("test".getBytes(StandardCharsets.UTF_8)));
|
||||||
|
|
||||||
DB.save(persistentFile);
|
DB.save(persistentFile);
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import io.ebean.DB;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.tests.model.basic.TWithPreInsert;
|
import org.tests.model.basic.TWithPreInsert;
|
||||||
import org.tests.model.basic.TWithPreInsertChild;
|
import org.tests.model.basic.TWithPreInsertChild;
|
||||||
|
import org.tests.model.basic.event.TWithPreInsertPersistAdapter;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
@@ -27,6 +28,7 @@ class TestPreInsertValidation extends BaseTestCase {
|
|||||||
assertThat(e.requestCascadeState()).isEqualTo(2);
|
assertThat(e.requestCascadeState()).isEqualTo(2);
|
||||||
|
|
||||||
TWithPreInsert e1 = DB.find(TWithPreInsert.class, e.getId());
|
TWithPreInsert e1 = DB.find(TWithPreInsert.class, e.getId());
|
||||||
|
assert e1 != null;
|
||||||
|
|
||||||
e1.setTitle("Missus");
|
e1.setTitle("Missus");
|
||||||
DB.save(e1);
|
DB.save(e1);
|
||||||
@@ -54,11 +56,21 @@ class TestPreInsertValidation extends BaseTestCase {
|
|||||||
assert e1 != null;
|
assert e1 != null;
|
||||||
|
|
||||||
e1.setTitle("ParentCascading-changed");
|
e1.setTitle("ParentCascading-changed");
|
||||||
e1.children().get(0).setName("Child0-changed");
|
TWithPreInsertChild childBean = e1.children().get(0);
|
||||||
|
childBean.setName("Child0-changed");
|
||||||
DB.save(e1);
|
DB.save(e1);
|
||||||
|
|
||||||
assertThat(e1.requestCascadeState()).isEqualTo(12);
|
assertThat(e1.requestCascadeState()).isEqualTo(12);
|
||||||
assertThat(e1.children().get(0).requestCascadeState()).isEqualTo(11);
|
assertThat(childBean.requestCascadeState()).isEqualTo(11);
|
||||||
|
|
||||||
|
DB.delete(e1);
|
||||||
|
|
||||||
|
assertThat(e1.requestCascadeState()).isEqualTo(22);
|
||||||
|
|
||||||
|
// assert that isCascade() was true for the child bean
|
||||||
|
assertThat(TWithPreInsertPersistAdapter.cascadeDelete).hasSize(1);
|
||||||
|
String deleteCascade = TWithPreInsertPersistAdapter.cascadeDelete.get(0);
|
||||||
|
assertThat(deleteCascade).isEqualTo("class org.tests.model.basic.TWithPreInsertChild:1");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ public class TestDefaults extends BaseTestCase {
|
|||||||
final List<String> current = LoggedSql.collect();
|
final List<String> current = LoggedSql.collect();
|
||||||
|
|
||||||
assertThat(current).isNotEmpty();
|
assertThat(current).isNotEmpty();
|
||||||
if (isMySql() || isMariaDB()) {
|
if (isMySql() || isMariaDB() || isOracle()) {
|
||||||
assertThat(current.get(0)).contains("insert into defaults_model_draft values (default);");
|
assertThat(current.get(0)).contains("insert into defaults_model_draft values (default);");
|
||||||
} else if (isSqlServer()) {
|
} else if (isSqlServer()) {
|
||||||
assertThat(current.get(0)).contains("insert into defaults_model_draft (id) values (?)");
|
assertThat(current.get(0)).contains("insert into defaults_model_draft (id) values (?)");
|
||||||
|
|||||||
+3
-1
@@ -9,12 +9,14 @@ import org.tests.model.basic.PFileContent;
|
|||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
public class TestConstructorPutfieldReplacement extends BaseTestCase {
|
public class TestConstructorPutfieldReplacement extends BaseTestCase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void test() {
|
||||||
|
|
||||||
PFile persistentFile = new PFile("test.txt", new PFileContent("test".getBytes()));
|
PFile persistentFile = new PFile("test.txt", new PFileContent("test".getBytes(StandardCharsets.UTF_8)));
|
||||||
|
|
||||||
EntityBean eb = (EntityBean) persistentFile;
|
EntityBean eb = (EntityBean) persistentFile;
|
||||||
EntityBeanIntercept ebi = eb._ebean_getIntercept();
|
EntityBeanIntercept ebi = eb._ebean_getIntercept();
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ import org.tests.idkeys.db.GenKeySeqB;
|
|||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
||||||
@@ -24,6 +26,7 @@ public class TestGeneratedKeys extends BaseTestCase {
|
|||||||
@ForPlatform(Platform.H2) // readSequenceValue is H2 specific
|
@ForPlatform(Platform.H2) // readSequenceValue is H2 specific
|
||||||
public void testGenKeySeqA() throws SQLException {
|
public void testGenKeySeqA() throws SQLException {
|
||||||
assumeTrue(idType() == IdType.SEQUENCE);
|
assumeTrue(idType() == IdType.SEQUENCE);
|
||||||
|
|
||||||
SpiEbeanServer server = spiEbeanServer();
|
SpiEbeanServer server = spiEbeanServer();
|
||||||
|
|
||||||
try (Transaction tx = server.beginTransaction()) {
|
try (Transaction tx = server.beginTransaction()) {
|
||||||
@@ -69,20 +72,34 @@ public class TestGeneratedKeys extends BaseTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private long readSequenceValue(Transaction tx, String sequence) throws SQLException {
|
private long readSequenceValue(Transaction tx, String sequence) throws SQLException {
|
||||||
Statement stm = null;
|
String sql;
|
||||||
try {
|
switch (spiEbeanServer().databasePlatform().getPlatform().base()) {
|
||||||
stm = tx.connection().createStatement();
|
case H2 :
|
||||||
ResultSet rs = stm.executeQuery("select currval('" + sequence + "')");
|
sql = "select currval('" + sequence + "')";
|
||||||
rs.next();
|
break;
|
||||||
|
|
||||||
|
case DB2 :
|
||||||
|
sql = "values previous value for " + sequence;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case SQLSERVER :
|
||||||
|
sql = "select current_value from sys.sequences where name = '" + sequence + "'";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MARIADB :
|
||||||
|
throw new UnsupportedOperationException("reading sequence value outside of the current connection is not supported. "
|
||||||
|
+ "See https://mariadb.com/kb/en/previous-value-for-sequence_name/#description");
|
||||||
|
|
||||||
|
default :
|
||||||
|
throw new UnsupportedOperationException("reading sequence value from "
|
||||||
|
+ spiEbeanServer().databasePlatform().getPlatform()
|
||||||
|
+ " is not supported.");
|
||||||
|
|
||||||
|
}
|
||||||
|
try (Statement stm = tx.connection().createStatement()) {
|
||||||
|
ResultSet rs = stm.executeQuery(sql);
|
||||||
|
rs.next();
|
||||||
return rs.getLong(1);
|
return rs.getLong(1);
|
||||||
} finally {
|
|
||||||
if (stm != null) {
|
|
||||||
try {
|
|
||||||
stm.close();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,5 +126,25 @@ public class TestGeneratedKeys extends BaseTestCase {
|
|||||||
assertNotNull(al.getId());
|
assertNotNull(al.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@ForPlatform({Platform.H2, Platform.MARIADB, Platform.SQLSERVER, Platform.DB2})
|
||||||
|
public void testGeneratedKeys() throws SQLException {
|
||||||
|
assumeTrue(idType() == IdType.SEQUENCE);
|
||||||
|
|
||||||
|
SpiEbeanServer server = spiEbeanServer();
|
||||||
|
List<Long> idList = new ArrayList<>(52);
|
||||||
|
|
||||||
|
try (Transaction tx = server.beginTransaction()) {
|
||||||
|
// bigger than increment
|
||||||
|
for (int i = 1; i < 52; i++) {
|
||||||
|
GenKeySeqA gks = new GenKeySeqA();
|
||||||
|
gks.setDescription("my description " + i);
|
||||||
|
server.save(gks);
|
||||||
|
assertFalse(idList.contains(gks.getId()));
|
||||||
|
idList.add(gks.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -7,7 +7,7 @@ import javax.validation.constraints.NotNull;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static javax.persistence.CascadeType.PERSIST;
|
import static javax.persistence.CascadeType.ALL;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
public class TWithPreInsert implements TWithPreInsertCommon {
|
public class TWithPreInsert implements TWithPreInsertCommon {
|
||||||
@@ -20,7 +20,7 @@ public class TWithPreInsert implements TWithPreInsertCommon {
|
|||||||
|
|
||||||
private String title;
|
private String title;
|
||||||
|
|
||||||
@OneToMany(cascade = PERSIST)
|
@OneToMany(cascade = ALL)
|
||||||
private List<TWithPreInsertChild> children = new ArrayList<>();
|
private List<TWithPreInsertChild> children = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package org.tests.model.basic;
|
|||||||
|
|
||||||
public interface TWithPreInsertCommon {
|
public interface TWithPreInsertCommon {
|
||||||
|
|
||||||
|
Integer getId();
|
||||||
|
|
||||||
String getName();
|
String getName();
|
||||||
|
|
||||||
void setName(String name);
|
void setName(String name);
|
||||||
|
|||||||
+15
@@ -4,8 +4,13 @@ import io.ebean.event.BeanPersistAdapter;
|
|||||||
import io.ebean.event.BeanPersistRequest;
|
import io.ebean.event.BeanPersistRequest;
|
||||||
import org.tests.model.basic.TWithPreInsertCommon;
|
import org.tests.model.basic.TWithPreInsertCommon;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class TWithPreInsertPersistAdapter extends BeanPersistAdapter {
|
public class TWithPreInsertPersistAdapter extends BeanPersistAdapter {
|
||||||
|
|
||||||
|
public static List<String> cascadeDelete = new ArrayList<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isRegisterFor(Class<?> cls) {
|
public boolean isRegisterFor(Class<?> cls) {
|
||||||
return TWithPreInsertCommon.class.isAssignableFrom(cls);
|
return TWithPreInsertCommon.class.isAssignableFrom(cls);
|
||||||
@@ -32,4 +37,14 @@ public class TWithPreInsertPersistAdapter extends BeanPersistAdapter {
|
|||||||
return super.preUpdate(request);
|
return super.preUpdate(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean preDelete(BeanPersistRequest<?> request) {
|
||||||
|
TWithPreInsertCommon bean = (TWithPreInsertCommon) request.bean();
|
||||||
|
if (request.isCascade()) {
|
||||||
|
cascadeDelete.add(bean.getClass() + ":" + bean.getId());
|
||||||
|
} else {
|
||||||
|
bean.requestCascadeState(22);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
package org.tests.model.elementcollection;
|
||||||
|
|
||||||
|
import io.ebean.annotation.Cache;
|
||||||
|
|
||||||
|
import javax.persistence.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Cache
|
||||||
|
@Entity
|
||||||
|
public class EcblPerson2 {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
long id;
|
||||||
|
|
||||||
|
String name;
|
||||||
|
|
||||||
|
@ElementCollection
|
||||||
|
@CollectionTable(joinColumns = @JoinColumn(name = "person_id"))
|
||||||
|
List<EcPhone> phoneNumbers = new ArrayList<>();
|
||||||
|
|
||||||
|
@Version
|
||||||
|
long version;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "person id:" + id + " name:" + name + " phs:" + phoneNumbers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<EcPhone> getPhoneNumbers() {
|
||||||
|
return phoneNumbers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPhoneNumbers(List<EcPhone> phoneNumbers) {
|
||||||
|
this.phoneNumbers = phoneNumbers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVersion(long version) {
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-4
@@ -9,10 +9,10 @@ import java.util.List;
|
|||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
public class TestElementCollectionEmbeddedListCache extends BaseTestCase {
|
class TestElementCollectionEmbeddedListCache extends BaseTestCase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
void test() {
|
||||||
|
|
||||||
EcblPerson person = new EcblPerson("CacheL");
|
EcblPerson person = new EcblPerson("CacheL");
|
||||||
person.getPhoneNumbers().add(new EcPhone("64", "021","1234"));
|
person.getPhoneNumbers().add(new EcPhone("64", "021","1234"));
|
||||||
@@ -86,12 +86,10 @@ public class TestElementCollectionEmbeddedListCache extends BaseTestCase {
|
|||||||
assertThat(four.getPhoneNumbers().toString()).contains("61-07-11");
|
assertThat(four.getPhoneNumbers().toString()).contains("61-07-11");
|
||||||
assertThat(four.getPhoneNumbers()).hasSize(1);
|
assertThat(four.getPhoneNumbers()).hasSize(1);
|
||||||
|
|
||||||
|
|
||||||
DB.delete(four);
|
DB.delete(four);
|
||||||
sql = LoggedSql.collect();
|
sql = LoggedSql.collect();
|
||||||
assertThat(sql).hasSize(2);
|
assertThat(sql).hasSize(2);
|
||||||
|
|
||||||
|
|
||||||
LoggedSql.stop();
|
LoggedSql.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+99
@@ -0,0 +1,99 @@
|
|||||||
|
package org.tests.model.elementcollection;
|
||||||
|
|
||||||
|
import io.ebean.BaseTestCase;
|
||||||
|
import io.ebean.DB;
|
||||||
|
import io.ebean.test.LoggedSql;
|
||||||
|
import org.junit.jupiter.api.Disabled;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
class TestElementCollectionEmbeddedListCache2 extends BaseTestCase {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void test() {
|
||||||
|
|
||||||
|
EcblPerson2 person = new EcblPerson2();
|
||||||
|
person.setName("CacheL");
|
||||||
|
person.getPhoneNumbers().add(new EcPhone("64", "021","1234"));
|
||||||
|
person.getPhoneNumbers().add(new EcPhone("64","021","4321"));
|
||||||
|
DB.save(person);
|
||||||
|
|
||||||
|
EcblPerson2 one = DB.find(EcblPerson2.class)
|
||||||
|
.setId(person.getId())
|
||||||
|
.fetch("phoneNumbers")
|
||||||
|
.findOne();
|
||||||
|
|
||||||
|
LoggedSql.start();
|
||||||
|
|
||||||
|
one.getPhoneNumbers().size();
|
||||||
|
|
||||||
|
List<String> sql = LoggedSql.collect();
|
||||||
|
assertThat(sql).isEmpty();
|
||||||
|
|
||||||
|
EcblPerson2 two = DB.find(EcblPerson2.class )
|
||||||
|
.setId(person.getId())
|
||||||
|
.findOne();
|
||||||
|
|
||||||
|
two.getPhoneNumbers().size();
|
||||||
|
assertThat(two.getPhoneNumbers().toString()).contains("64-021-1234", "64-021-4321");
|
||||||
|
|
||||||
|
sql = LoggedSql.collect();
|
||||||
|
assertThat(sql).isEmpty(); // cache hit
|
||||||
|
|
||||||
|
two.getPhoneNumbers().add(new EcPhone("61", "07", "11"));
|
||||||
|
two.getPhoneNumbers().remove(1);
|
||||||
|
|
||||||
|
DB.save(two);
|
||||||
|
|
||||||
|
sql = LoggedSql.collect();
|
||||||
|
if (isPersistBatchOnCascade()) {
|
||||||
|
assertThat(sql).hasSize(5); // update of collection only
|
||||||
|
assertSql(sql.get(0)).contains("delete from ecbl_person2_phone_numbers where person_id=?");
|
||||||
|
assertSqlBind(sql.get(1));
|
||||||
|
assertSql(sql.get(2)).contains("insert into ecbl_person2_phone_numbers (person_id,country_code,area,phnum) values (?,?,?,?)");
|
||||||
|
assertSqlBind(sql, 3, 4);
|
||||||
|
} else {
|
||||||
|
assertThat(sql).hasSize(3); // update of collection only
|
||||||
|
assertSql(sql.get(0)).contains("delete from ecbl_person2_phone_numbers where person_id=?");
|
||||||
|
assertSql(sql.get(1)).contains("insert into ecbl_person2_phone_numbers (person_id,country_code,area,phnum) values (?,?,?,?)");
|
||||||
|
assertSql(sql.get(2)).contains("insert into ecbl_person2_phone_numbers (person_id,country_code,area,phnum) values (?,?,?,?)");
|
||||||
|
}
|
||||||
|
|
||||||
|
EcblPerson2 three = DB.find(EcblPerson2.class )
|
||||||
|
.setId(person.getId())
|
||||||
|
.findOne();
|
||||||
|
|
||||||
|
assertThat(three.getPhoneNumbers().toString()).contains("61-07-11", "64-021-1234");
|
||||||
|
assertThat(three.getPhoneNumbers()).hasSize(2);
|
||||||
|
|
||||||
|
sql = LoggedSql.collect();
|
||||||
|
assertThat(sql).isEmpty(); // cache hit
|
||||||
|
|
||||||
|
|
||||||
|
three.setName("mod-3");
|
||||||
|
three.getPhoneNumbers().remove(0);
|
||||||
|
|
||||||
|
DB.save(three);
|
||||||
|
|
||||||
|
sql = LoggedSql.collect();
|
||||||
|
assertThat(sql).hasSize(5);
|
||||||
|
|
||||||
|
EcblPerson2 four = DB.find(EcblPerson2.class )
|
||||||
|
.setId(person.getId())
|
||||||
|
.findOne();
|
||||||
|
|
||||||
|
assertThat(four.getPhoneNumbers().toString()).contains("61-07-11");
|
||||||
|
assertThat(four.getPhoneNumbers()).hasSize(1);
|
||||||
|
|
||||||
|
|
||||||
|
DB.delete(four);
|
||||||
|
sql = LoggedSql.collect();
|
||||||
|
assertThat(sql).hasSize(2);
|
||||||
|
|
||||||
|
|
||||||
|
LoggedSql.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package org.tests.model.embedded;
|
||||||
|
|
||||||
|
import io.ebean.annotation.DbArray;
|
||||||
|
|
||||||
|
import javax.persistence.*;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class EmbArrayMaster {
|
||||||
|
|
||||||
|
@Embeddable
|
||||||
|
public static class EmbArrayDetail {
|
||||||
|
@DbArray
|
||||||
|
List<String> vals;
|
||||||
|
|
||||||
|
public EmbArrayDetail(List<String> vals) {
|
||||||
|
this.vals = vals;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Id
|
||||||
|
int id;
|
||||||
|
|
||||||
|
@ElementCollection
|
||||||
|
@CollectionTable(name = "test_array_detail", joinColumns = {@JoinColumn(name = "master_id")})
|
||||||
|
List<EmbArrayDetail> details;
|
||||||
|
|
||||||
|
public EmbArrayMaster(List<EmbArrayDetail> details) {
|
||||||
|
this.details = details;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package org.tests.model.embedded;
|
||||||
|
|
||||||
|
import io.ebean.DB;
|
||||||
|
import org.junit.jupiter.api.Disabled;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static java.util.Collections.emptyList;
|
||||||
|
import static java.util.Collections.singletonList;
|
||||||
|
|
||||||
|
class TestEmbeddedDbArray {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Failing test case for #2477
|
||||||
|
*/
|
||||||
|
@Disabled
|
||||||
|
@Test
|
||||||
|
void testArrayInsert() {
|
||||||
|
EmbArrayMaster t = new EmbArrayMaster(singletonList(new EmbArrayMaster.EmbArrayDetail(emptyList())));
|
||||||
|
DB.insert(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loaded 100 of 113 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user