Compare commits

..
Author SHA1 Message Date
rob bygrave 108a1c7181 [maven-release-plugin] prepare release ebean-parent-12.6.0 2020-11-19 09:29:16 +13:00
rob bygrave 5ce07afed8 Bump ebean-agent version in BOM 2020-11-19 09:23:55 +13:00
rob bygrave d9c4798d4e Bump ebean-test-docker dependency with io.ebean groupId 2020-11-19 09:15:02 +13:00
rob bygrave 6ecd849499 #2104 - Refactor rename ebean-ddlgen module to ebean-ddl-generator 2020-11-18 22:28:33 +13:00
rob bygrave e5b0b31da6 Improve javadoc for DbMigration for pending drops 2020-11-18 22:20:18 +13:00
rob bygrave 1371cb4ff6 #2103 - Bump dependency avaje-config to 1.2 - no effective change, added JPMS Java module support 2020-11-18 22:13:10 +13:00
rob bygrave c788d339fe #2102 - Add to BOM entries for ebean-ddl-runner, ebean-datasource, ebean-migration, ebean-test-docker 2020-11-18 22:09:54 +13:00
rob bygrave 35580fa62b #2101 - Refactor to make ebean-migration optional dependency 2020-11-18 21:52:32 +13:00
rob bygrave b61ae74d3d Tidy only - organise imports in ebean-api 2020-11-17 19:20:28 +13:00
rob bygrave fead4350ce Tidy remove unused imports 2020-11-17 19:15:10 +13:00
rob bygrave 04a651c40d #2100 - Refactor move io.ebean.dbmigration.DbMigration [generation] from ebean-api to ebean-ddlgen module 2020-11-12 22:54:36 +13:00
rob bygrave f394e7f39b #2099 - Refactor internals introduce use of ebean-ddl-runner 2020-11-12 22:42:00 +13:00
rob bygrave 8f7827d3d9 No effective change - bump provided dependency slf4j-api to 1.7.30 2020-11-12 21:19:05 +13:00
rob bygrave 06b54bd824 No effective change - tidy test properties 2020-11-12 14:51:16 +13:00
rob bygrave f473e40bfc #2098 - Refactor simplify SequenceIdGenerator.loadInBackground() to use AtomicBoolean 2020-11-12 13:58:16 +13:00
rob bygrave 1eb5cf1d22 Fix test TransactionManagerTest - close leaked connection
Connection properties to help find leaks are capturestacktrace and maxStackTraceSize, e.g.

datasource.h2.capturestacktrace=true
datasource.h2.maxStackTraceSize=20
2020-11-12 13:55:10 +13:00
rob bygrave b540d70b2d #2097 - Split ebean-datasource dependency to ebean-datasource-api and ebean-datasource 2020-11-12 12:53:32 +13:00
rob bygrave 7b5a8aef73 Bump parent to java8-oss 2.3 with autoReleaseAfterClose false 2020-11-12 12:20:42 +13:00
rob bygrave 3e4daf6947 Revert/Post deploy of ebean-querybean 12.5.2 2020-11-12 12:11:23 +13:00
rob bygrave 0918cbf221 Prepare deploy of ebean-querybean 12.5.2 2020-11-12 11:28:17 +13:00
rob bygrave 3e078e41ff [maven-release-plugin] prepare for next development iteration 2020-11-11 22:47:24 +13:00
rob bygrave a80ab94479 [maven-release-plugin] prepare release ebean-parent-12.5.2 2020-11-11 22:47:12 +13:00
rob bygrave e6f0ab90dc #2094 - Refactor remove isJavaTimePresent() ... we are Java 8+ so removing effectively redundant code 2020-10-23 01:25:28 +13:00
rob bygrave 53f4739c8f #2093 - Refactor remove isJava7Present() ... we are Java 8+ so Java 7 types are always present - Removing effectively redundant code 2020-10-23 01:21:48 +13:00
rob bygrave c6e33ba3ac Modify pom names of modules for more consistency 2020-10-23 00:33:16 +13:00
rob bygrave 0e2528e542 #2092 - Add support for mocking Database interface to MockiEbean 2020-10-23 00:10:50 +13:00
rob bygrave 6ecc10a35c #2091 - Using Postgis types with query gives PersistenceException Caused by: java.sql.SQLException: Unhandled data type [6000] bind number[0] 2020-10-22 22:48:53 +13:00
rob bygrave 59bd2bb251 Add ebean-postgis module 2020-10-22 21:22:41 +13:00
rob bygrave 9fa83cdd5a Move into ebean-postgres sub directory 2020-10-22 21:18:18 +13:00
Rob BygraveandGitHub f383f3f759 Merge pull request #3 from tobias-/failing_test
Failing tests for query with postgis types
2020-10-22 20:56:22 +13:00
rob bygrave 0abcc9e06e #2085 - Refactor promote getDataSource() and getReadOnlyDataSource() to Database from plugin.SpiServer interface 2020-10-20 12:08:21 +13:00
rob bygrave 4a594b32ef Refactor modify SpiServer to extend Database (rather than EbeanServer) 2020-10-20 11:36:01 +13:00
rob bygrave 8b9f760cb2 Update tests for DatabaseFactory.create() with shutdown 2020-10-19 12:12:00 +13:00
rob bygrave 1d1cf76b5e Update poms adding name, description, change to use explicit snapshot version rather than project.version 2020-10-19 11:21:18 +13:00
rob bygrave 194c14b99a Post manual release of autotune, externalmapping-xml, querybean and test modules 2020-10-19 10:16:25 +13:00
rob bygrave fa8c6839dd [maven-release-plugin] prepare for next development iteration 2020-10-19 09:44:18 +13:00
rob bygrave f8e4ce6b4c [maven-release-plugin] prepare release ebean-test-12.5.1 2020-10-19 09:44:07 +13:00
rob bygrave cce496016d [maven-release-plugin] prepare for next development iteration 2020-10-19 09:38:53 +13:00
rob bygrave 2c4d5dc304 [maven-release-plugin] prepare release ebean-querybean-12.5.1 2020-10-19 09:38:42 +13:00
rob bygrave 1c981130b6 [maven-release-plugin] prepare for next development iteration 2020-10-19 09:34:13 +13:00
rob bygrave c18d1fa288 [maven-release-plugin] prepare release ebean-externalmapping-xml-12.5.1 2020-10-19 09:34:01 +13:00
rob bygrave 5287d93a58 [maven-release-plugin] prepare for next development iteration 2020-10-19 09:30:52 +13:00
Tobias 1e44b81e87 Failing tests for the rest of the gis-types
Simple query tests for:
* Polygon
* LineString
* MultiPoint
* MultiPolygon
* MultiLineString
2020-10-13 15:29:18 +02:00
Tobias 85b21a02e8 Failing testcase for ebean query serializer 2020-10-12 13:23:49 +02:00
Tobias 4313fb6f58 Add .editorconfig 2020-10-12 11:51:44 +02:00
rob bygrave ee19fd17fa [maven-release-plugin] prepare for next development iteration 2020-09-18 01:22:40 +12:00
rob bygrave a7c6f9835a [maven-release-plugin] prepare release ebean-postgis-12.4.1 2020-09-18 01:22:29 +12:00
rob bygrave 06b1babed9 Bump to 12.4.1 2020-09-18 01:21:50 +12:00
rob bygrave 73ea91d4c9 [maven-release-plugin] prepare for next development iteration 2020-03-13 11:23:01 +13:00
rob bygrave 14839f0c0f [maven-release-plugin] prepare release ebean-postgis-12.2.1 2020-03-13 11:22:51 +13:00
rob bygrave db8f4e141d Bump to 12.2.1 2020-03-13 11:22:22 +13:00
rob bygrave 09fa406f84 [maven-release-plugin] prepare for next development iteration 2019-10-14 15:18:46 +13:00
rob bygrave 50d22ba357 [maven-release-plugin] prepare release ebean-postgis-12.1.1 2019-10-14 15:18:37 +13:00
rob bygrave c6f9d193be Bump to sync to Ebean 12.1.1 2019-10-14 15:18:01 +13:00
rob bygrave 5e1aa47c05 No effective change - update application-test.yml with dbSchema and ddlMode 2018-08-02 12:10:48 +12:00
rob bygrave 21dd8cee37 [maven-release-plugin] prepare for next development iteration 2018-08-02 11:51:10 +12:00
rob bygrave ece82996c2 [maven-release-plugin] prepare release ebean-postgis-11.1.1 2018-08-02 11:50:57 +12:00
rob bygrave fa520c95ea Bump to 11.1.1-SNAPSHOT 2018-08-02 11:50:25 +12:00
rob bygrave a6685141a4 #2 - No effective change - for running tests update to use docker postgis and application-test.yml 2018-08-02 11:48:49 +12:00
rob bygrave 78ab0ad923 No effective change - test logging config update 2018-08-02 11:44:25 +12:00
rob bygrave 4fb67a4c8c #1 - Support Ebean 11.x API - due to Ebean #1153 - Refactor move ExtraTypeFactory out of io.ebean.plugin into io.ebeaninternal 2018-08-02 11:43:52 +12:00
Rob Bygrave dd94e60d16 [maven-release-plugin] prepare for next development iteration 2016-12-13 21:59:31 +13:00
Rob Bygrave aa70e17657 [maven-release-plugin] prepare release ebean-postgis-0.1.3 2016-12-13 21:59:22 +13:00
Rob Bygrave 016cd3fb71 Update for Ebean 10.1.1 2016-12-13 21:58:56 +13:00
Rob Bygrave 17f28ba0aa [maven-release-plugin] prepare for next development iteration 2016-12-01 01:11:15 +13:00
Rob Bygrave ab88a879e9 [maven-release-plugin] prepare release ebean-postgis-0.1.2 2016-12-01 01:11:05 +13:00
Rob Bygrave 5b85f3c8dd Bump to java8 parent, update scm to ssh 2016-12-01 01:10:28 +13:00
Rob Bygrave 16a5100f35 Modify ScalarTypePgisBase to support the older protocol / objects when reading 2016-12-01 01:07:55 +13:00
Rob Bygrave 86b2c5d5b5 [maven-release-plugin] prepare for next development iteration 2016-10-25 22:53:16 +13:00
Rob Bygrave e0c3198ee6 [maven-release-plugin] prepare release ebean-postgis-0.1.1 2016-10-25 22:53:08 +13:00
Rob Bygrave 12bdd847b5 Update pom for initial release 2016-10-25 22:42:17 +13:00
Rob Bygrave 9860816ab7 Update 2016-10-25 22:36:38 +13:00
Rob Bygrave e17283726a Initial add 2016-10-21 02:37:13 +13:00
Rob Bygrave eff61ae5fc Initial commit 2016-10-21 01:32:47 +13:00
498 changed files with 2548 additions and 1288 deletions
+7 -11
View File
@@ -4,9 +4,11 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>12.5.2-SNAPSHOT</version>
<version>12.6.0</version>
</parent>
<name>ebean api</name>
<description>ebean api</description>
<artifactId>ebean-api</artifactId>
<properties>
@@ -23,14 +25,14 @@
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
<version>1.7.30</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-config</artifactId>
<version>1.1</version>
<version>1.2</version>
</dependency>
<!--
@@ -64,14 +66,8 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>6.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>12.1.4</version>
<artifactId>ebean-datasource-api</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<!-- Jackson core used internally by Ebean -->
+7
View File
@@ -70,6 +70,13 @@ public final class DB {
private DB() {
}
/**
* Backdoor for registering a mock implementation of Database as the default database.
*/
protected static Database mock(String name, Database server, boolean defaultServer) {
return context.mock(name, server, defaultServer);
}
/**
* Return the default database.
*/
@@ -14,6 +14,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.persistence.OptimisticLockException;
import javax.persistence.PersistenceException;
import javax.sql.DataSource;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -121,6 +122,16 @@ public interface Database {
*/
AutoTune getAutoTune();
/**
* Return the associated DataSource for this Database instance.
*/
DataSource getDataSource();
/**
* Return the associated read only DataSource for this Database instance (can be null).
*/
DataSource getReadOnlyDataSource();
/**
* Return the name. This is used with {@link DB#byName(String)} to get a
* Database that was registered with the DB singleton.
@@ -2,8 +2,8 @@ package io.ebean;
import io.ebean.docstore.DocQueryContext;
import io.ebean.docstore.RawDoc;
import javax.annotation.Nullable;
import javax.annotation.Nullable;
import java.io.IOException;
import java.util.List;
import java.util.Map;
@@ -2,13 +2,6 @@ package io.ebean;
import io.ebean.config.ContainerConfig;
import io.ebean.config.ServerConfig;
import io.ebean.service.SpiContainer;
import io.ebean.service.SpiContainerFactory;
import javax.persistence.PersistenceException;
import java.util.Iterator;
import java.util.Properties;
import java.util.ServiceLoader;
/**
* Deprecated - please migrate to DatabaseFactory.
@@ -2,8 +2,8 @@ package io.ebean;
import io.ebean.annotation.DocStoreMode;
import io.ebean.annotation.PersistBatch;
import io.ebean.config.DocStoreConfig;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.DocStoreConfig;
import javax.persistence.PersistenceException;
import java.sql.Connection;
@@ -26,20 +26,6 @@ public class ClassLoadConfig {
this.context = new ClassLoaderContext(classLoader);
}
/**
* Return true if the Java.time types are available and should be supported.
*/
public boolean isJavaTimePresent() {
return isPresent("java.time.LocalDate");
}
/**
* Return true if Java7 is present.
*/
public boolean isJava7Present() {
return isPresent("java.nio.file.Path");
}
/**
* Return true if the Joda types are available and should be supported.
*/
@@ -1,7 +1,7 @@
package io.ebean.config;
import io.ebean.config.dbplatform.DbType;
import io.ebean.annotation.Platform;
import io.ebean.config.dbplatform.DbType;
/**
* Custom mappings for DB types that override the default.
@@ -3,6 +3,7 @@ package io.ebean.config;
import com.fasterxml.jackson.core.JsonFactory;
import io.avaje.config.Config;
import io.ebean.DatabaseFactory;
import io.ebean.EbeanVersion;
import io.ebean.PersistenceContextScope;
import io.ebean.Query;
import io.ebean.Transaction;
@@ -28,12 +29,13 @@ import io.ebean.event.changelog.ChangeLogPrepare;
import io.ebean.event.changelog.ChangeLogRegister;
import io.ebean.event.readaudit.ReadAuditLogger;
import io.ebean.event.readaudit.ReadAuditPrepare;
import io.ebean.migration.MigrationRunner;
import io.ebean.util.StringHelper;
import javax.persistence.EnumType;
import javax.sql.DataSource;
import java.time.Clock;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -277,6 +279,25 @@ public class DatabaseConfig {
private String ddlSeedSql;
private String ddlHeader;
/**
* Mode used to check non-null columns added via migration have a default value specified etc.
*/
private boolean ddlStrictMode = true;
/**
* Comma and equals delimited key/value placeholders to replace in DDL scripts.
*/
private String ddlPlaceholders;
/**
* Map of key/value placeholders to replace in DDL scripts.
*/
private Map<String, String> ddlPlaceholderMap;
private boolean runMigration;
/**
* When true L2 bean cache use is skipped after a write has occurred on a transaction.
*/
@@ -322,11 +343,6 @@ public class DatabaseConfig {
*/
private String dbSchema;
/**
* The db migration config (migration resource path etc).
*/
private DbMigrationConfig migrationConfig = new DbMigrationConfig();
/**
* The ClassLoadConfig used to detect Joda, Java8, Jackson etc and create plugin instances given a className.
*/
@@ -1212,20 +1228,6 @@ public class DatabaseConfig {
this.dbSchema = dbSchema;
}
/**
* Return the DB migration configuration.
*/
public DbMigrationConfig getMigrationConfig() {
return migrationConfig;
}
/**
* Set the DB migration configuration.
*/
public void setMigrationConfig(DbMigrationConfig migrationConfig) {
this.migrationConfig = migrationConfig;
}
/**
* Return the Geometry SRID.
*/
@@ -2026,7 +2028,15 @@ public class DatabaseConfig {
* as it is often the only thing we need to configure for migrations.
*/
public void setRunMigration(boolean runMigration) {
migrationConfig.setRunMigration(runMigration);
this.runMigration = runMigration;
}
/**
* Return true if the DB migration should run on server start.
*/
public boolean isRunMigration() {
final String run = System.getProperty("ebean.migration.run");
return (run != null) ? Boolean.parseBoolean(run) : runMigration;
}
/**
@@ -2134,6 +2144,67 @@ public class DatabaseConfig {
return ddlExtra;
}
/**
* Set the header to use with DDL generation.
*/
public void setDdlHeader(String ddlHeader) {
this.ddlHeader = ddlHeader;
}
/**
* Return the header to use with DDL generation.
*/
public String getDdlHeader() {
if (ddlHeader != null && !ddlHeader.isEmpty()) {
String header = ddlHeader.replace("${version}", EbeanVersion.getVersion());
header = header.replace("${timestamp}", ZonedDateTime.now().format(DateTimeFormatter.ISO_INSTANT));
return header;
}
return ddlHeader;
}
/**
* Return true if strict mode is used which includes a check that non-null columns have a default value.
*/
public boolean isDdlStrictMode() {
return ddlStrictMode;
}
/**
* Set to false to turn off strict mode allowing non-null columns to not have a default value.
*/
public void setDdlStrictMode(boolean ddlStrictMode) {
this.ddlStrictMode = ddlStrictMode;
}
/**
* Return a comma and equals delimited placeholders that are substituted in DDL scripts.
*/
public String getDdlPlaceholders() {
return ddlPlaceholders;
}
/**
* Set a comma and equals delimited placeholders that are substituted in DDL scripts.
*/
public void setDdlPlaceholders(String ddlPlaceholders) {
this.ddlPlaceholders = ddlPlaceholders;
}
/**
* Return a map of placeholder values that are substituted in DDL scripts.
*/
public Map<String, String> getDdlPlaceholderMap() {
return ddlPlaceholderMap;
}
/**
* Set a map of placeholder values that are substituted in DDL scripts.
*/
public void setDdlPlaceholderMap(Map<String, String> ddlPlaceholderMap) {
this.ddlPlaceholderMap = ddlPlaceholderMap;
}
/**
* Return true if the class path search should be disabled.
*/
@@ -2699,13 +2770,8 @@ public class DatabaseConfig {
* Load the configuration settings from the properties file.
*/
protected void loadSettings(PropertiesWrapper p) {
dbSchema = p.get("dbSchema", dbSchema);
if (dbSchema != null) {
migrationConfig.setDefaultDbSchema(dbSchema);
}
profilingConfig.loadSettings(p, name);
migrationConfig.loadSettings(p, name);
platformConfig.loadSettings(p);
if (platformConfig.isAllQuotedIdentifiers()) {
adjustNamingConventionForAllQuoted();
@@ -2807,12 +2873,16 @@ public class DatabaseConfig {
jsonDateTime = p.getEnum(JsonConfig.DateTime.class, "jsonDateTime", jsonDateTime);
jsonDate = p.getEnum(JsonConfig.Date.class, "jsonDate", jsonDate);
runMigration = p.getBoolean("migration.run", runMigration);
ddlGenerate = p.getBoolean("ddl.generate", ddlGenerate);
ddlRun = p.getBoolean("ddl.run", ddlRun);
ddlExtra = p.getBoolean("ddl.extra", ddlExtra);
ddlCreateOnly = p.getBoolean("ddl.createOnly", ddlCreateOnly);
ddlInitSql = p.get("ddl.initSql", ddlInitSql);
ddlSeedSql = p.get("ddl.seedSql", ddlSeedSql);
ddlStrictMode = p.getBoolean("ddl.strictMode", ddlStrictMode);
ddlPlaceholders = p.get("ddl.placeholders", ddlPlaceholders);
ddlHeader = p.get("ddl.header", ddlHeader);
// read tenant-configuration from config:
// tenant.mode = NONE | DB | SCHEMA | CATALOG | PARTITION
@@ -3034,17 +3104,6 @@ public class DatabaseConfig {
this.queryPlanTTLSeconds = queryPlanTTLSeconds;
}
/**
* Run the DB migration against the DataSource.
*/
public DataSource runDbMigration(DataSource dataSource) {
if (migrationConfig.isRunMigration()) {
MigrationRunner runner = migrationConfig.createRunner(getClassLoadConfig().getClassLoader(), properties);
runner.run(dataSource);
}
return dataSource;
}
/**
* Create a new PlatformConfig based of the one held but with overridden properties by reading
* properties with the given path and prefix.
@@ -1,509 +0,0 @@
package io.ebean.config;
import io.ebean.EbeanVersion;
import io.ebean.annotation.Platform;
import io.ebean.migration.MigrationConfig;
import io.ebean.migration.MigrationRunner;
import io.ebean.util.StringHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;
import java.util.Properties;
import static io.ebean.util.StringHelper.replace;
/**
* Configuration for the DB migration processing.
*/
public class DbMigrationConfig {
protected static final Logger logger = LoggerFactory.getLogger(DbMigrationConfig.class);
protected MigrationConfig runnerConfig = new MigrationConfig();
/**
* The database platform to generate migration DDL for.
*/
protected Platform platform;
/**
* Resource path for the migration xml and sql.
*/
protected String migrationPath = "dbmigration";
protected String migrationInitPath = "dbinit";
/**
* Subdirectory the model xml files go into.
*/
protected String modelPath = "model";
protected String applySuffix = ".sql";
/**
* Set this to "V" to be compatible with FlywayDB.
*/
protected String applyPrefix = "";
protected String modelSuffix = ".model.xml";
/**
* For running migration the DB table that holds migration execution status.
*/
protected String metaTable = "db_migration";
/**
* Flag set to true means to run any outstanding migrations on startup.
*/
protected boolean runMigration;
/**
* Comma and equals delimited key/value placeholders to replace in DDL scripts.
*/
protected String runPlaceholders;
/**
* Map of key/value placeholders to replace in DDL scripts.
*/
protected Map<String, String> runPlaceholderMap;
/**
* DB schema used for the migration (and testing).
*/
protected String dbSchema;
/**
* Set to true if we consider this the 'default schema' (Postgres schema that matches DB username)
*/
protected boolean defaultDbSchema;
/**
* DB user used to run the DB migration.
*/
protected String dbUsername;
/**
* DB password used to run the DB migration.
*/
protected String dbPassword;
protected String patchInsertOn;
protected String patchResetChecksumOn;
/**
* Mode used to check non-null columns added via migration have a default value specified etc.
*/
protected boolean strictMode = true;
/**
* Contains the DDL-header information.
*/
protected String ddlHeader;
/**
* Return the DB platform to generate migration DDL for.
* <p>
* We typically need to explicitly specify this as migration can often be generated
* when running against H2.
*/
public Platform getPlatform() {
return platform;
}
/**
* Set the DB platform to generate migration DDL for.
*/
public void setPlatform(Platform platform) {
this.platform = platform;
}
/**
* Return the path for normal migrations or dbinit migrations.
*
* @param dbinitMigration When true return the path for dbinit migrations.
*/
public String getMigrationPath(boolean dbinitMigration) {
return dbinitMigration ? migrationInitPath : migrationPath;
}
/**
* Return the resource path for db migrations.
*/
public String getMigrationPath() {
return migrationPath;
}
/**
* Set the resource path for db migrations.
* <p>
* The default of "dbmigration" is reasonable in most cases. You may look to set this
* to be something like "dbmigration/myapp" where myapp gives it a unique resource path
* in the case there are multiple Database applications in the single classpath.
* </p>
*/
public void setMigrationPath(String migrationPath) {
this.migrationPath = migrationPath;
}
/**
* Return the relative path for the model files (defaults to model).
*/
public String getModelPath() {
return modelPath;
}
/**
* Set the relative path for the model files.
*/
public void setModelPath(String modelPath) {
this.modelPath = modelPath;
}
/**
* Return the model suffix (defaults to model.xml)
*/
public String getModelSuffix() {
return modelSuffix;
}
/**
* Set the model suffix.
*/
public void setModelSuffix(String modelSuffix) {
this.modelSuffix = modelSuffix;
}
/**
* Return the apply script suffix (defaults to sql).
*/
public String getApplySuffix() {
return applySuffix;
}
/**
* Set the apply script suffix (defaults to sql).
*/
public void setApplySuffix(String applySuffix) {
this.applySuffix = applySuffix;
}
/**
* Return the apply prefix.
*/
public String getApplyPrefix() {
return applyPrefix;
}
/**
* Set the apply prefix. This might be set to "V" for use with FlywayDB.
*/
public void setApplyPrefix(String applyPrefix) {
this.applyPrefix = applyPrefix;
}
/**
* Return the table name that holds the migration run details
* (used by DB Migration runner only).
*/
public String getMetaTable() {
return metaTable;
}
/**
* Set the table name that holds the migration run details
* (used by DB Migration runner only).
*/
public void setMetaTable(String metaTable) {
this.metaTable = metaTable;
}
/**
* Return a comma and equals delimited placeholders that are substituted in SQL scripts when running migration
* (used by DB Migration runner only).
*/
public String getRunPlaceholders() {
// environment properties take precedence
String placeholders = readEnvironment("ddl.migration.placeholders");
if (placeholders != null) {
return placeholders;
}
return runPlaceholders;
}
/**
* Set a comma and equals delimited placeholders that are substituted in SQL scripts when running migration
* (used by DB Migration runner only).
*/
public void setRunPlaceholders(String runPlaceholders) {
this.runPlaceholders = runPlaceholders;
}
/**
* Return a map of placeholder values that are substituted in SQL scripts when running migration
* (used by DB Migration runner only).
*/
public Map<String, String> getRunPlaceholderMap() {
return runPlaceholderMap;
}
/**
* Set a map of placeholder values that are substituted when running migration
* (used by DB Migration runner only).
*/
public void setRunPlaceholderMap(Map<String, String> runPlaceholderMap) {
this.runPlaceholderMap = runPlaceholderMap;
}
/**
* Return true if the DB migration should be run on startup.
*/
public boolean isRunMigration() {
// environment properties take precedence
String run = readEnvironment("ddl.migration.run");
if (run != null) {
return "true".equalsIgnoreCase(run.trim());
}
return runMigration;
}
/**
* Set to true to run the DB migration on startup.
*/
public void setRunMigration(boolean runMigration) {
this.runMigration = runMigration;
}
/**
* Return the DB username to use for running DB migrations.
*/
public String getDbUsername() {
// environment properties take precedence
String user = readEnvironment("ddl.migration.user");
if (user != null) {
return user;
}
return dbUsername;
}
/**
* Set the DB username to use for running DB migrations.
*/
public void setDbUsername(String dbUsername) {
this.dbUsername = dbUsername;
}
/**
* Return the DB password to use for running DB migrations.
*/
public String getDbPassword() {
String user = readEnvironment("ddl.migration.password");
if (user != null) {
return user;
}
return dbPassword;
}
/**
* Set the DB password to use for running DB migrations.
*/
public void setDbPassword(String dbPassword) {
this.dbPassword = dbPassword;
}
/**
* Return the DB schema to use (for migration, testing etc).
*/
public String getDbSchema() {
String schema = readEnvironment("ddl.migration.schema");
if (schema != null) {
return schema;
}
return dbSchema;
}
/**
* Set the Db schema to use.
*/
public void setDbSchema(String dbSchema) {
this.dbSchema = dbSchema;
}
/**
* Set the Db schema if it hasn't already been defined.
*/
public void setDefaultDbSchema(String dbSchema) {
this.defaultDbSchema = true;
this.dbSchema = dbSchema;
}
/**
* Return true if this is considered the default DB schema (Postgres schema matching DB username).
*/
public boolean isDefaultDbSchema() {
return defaultDbSchema;
}
/**
* Return migration versions that should be added to history without running.
*/
public String getPatchInsertOn() {
return patchInsertOn;
}
/**
* Set migration versions that should be added to history without running.
* <p>
* Value can be a string containing comma delimited list of version numbers.
* </p>
*/
public void setPatchInsertOn(String patchInsertOn) {
this.patchInsertOn = patchInsertOn;
}
/**
* Return migration versions that should have their checksum reset and not run.
*/
public String getPatchResetChecksumOn() {
return patchResetChecksumOn;
}
/**
* Returns a DDL header prepend for each DDL. E.g. for copyright headers
* You can use placeholders like ${version} or ${timestamp} in properties file.
*/
public String getDdlHeader() {
if (ddlHeader != null && !ddlHeader.isEmpty()) {
ddlHeader = replace(ddlHeader, "${version}", EbeanVersion.getVersion());
ddlHeader = replace(ddlHeader, "${timestamp}", ZonedDateTime.now().format( DateTimeFormatter.ISO_INSTANT ));
}
return ddlHeader;
}
/**
* Set the header prepended to the DDL.
*/
public void setDdlHeader(String ddlHeader) {
this.ddlHeader = ddlHeader;
}
/**
* Set migration versions that should have their checksum reset and not run.
* <p>
* Value can be a string containing comma delimited list of version numbers.
* </p>
*/
public void setPatchResetChecksumOn(String patchResetChecksumOn) {
this.patchResetChecksumOn = patchResetChecksumOn;
}
/**
* Return true if strict mode is used which includes a check that non-null columns have a default value.
*/
public boolean isStrictMode() {
String envValue = readEnvironment("ddl.migration.strictMode");
if (!isEmpty(envValue)) {
return Boolean.parseBoolean(envValue.trim());
}
return strictMode;
}
/**
* Set to false to turn off strict mode allowing non-null columns to not have a default value.
*/
public void setStrictMode(boolean strictMode) {
this.strictMode = strictMode;
}
/**
* Return the underlying migration runner configuration allowing for more advanced settings.
*/
public MigrationConfig getRunnerConfig() {
return runnerConfig;
}
/**
* Load the settings from the PropertiesWrapper.
*/
public void loadSettings(PropertiesWrapper properties, String serverName) {
migrationPath = properties.get("migration.migrationPath", migrationPath);
migrationInitPath = properties.get("migration.migrationInitPath", migrationInitPath);
modelPath = properties.get("migration.modelPath", modelPath);
applyPrefix = properties.get("migration.applyPrefix", applyPrefix);
applySuffix = properties.get("migration.applySuffix", applySuffix);
modelSuffix = properties.get("migration.modelSuffix", modelSuffix);
platform = properties.getEnum(Platform.class, "migration.platform", platform);
patchInsertOn = properties.get("migration.patchInsertOn", patchInsertOn);
patchResetChecksumOn = properties.get("migration.patchResetChecksumOn", patchResetChecksumOn);
runMigration = properties.getBoolean("migration.run", runMigration);
metaTable = properties.get("migration.metaTable", metaTable);
runPlaceholders = properties.get("migration.placeholders", runPlaceholders);
dbSchema = properties.get("migration.dbSchema", dbSchema);
//Do not set user and pass from "datasource.db.username"
//There is a null test in MigrationRunner::getConnection to handle this
//String adminUser = properties.get("datasource." + serverName + ".username", dbUsername);
String adminUser = properties.get("datasource." + serverName + ".adminusername", dbUsername);
dbUsername = properties.get("migration.dbusername", adminUser);
//String adminPwd = properties.get("datasource." + serverName + ".password", dbPassword);
String adminPwd = properties.get("datasource." + serverName + ".adminpassword", dbPassword);
dbPassword = properties.get("migration.dbpassword", adminPwd);
ddlHeader = properties.get("ddl.header", ddlHeader);
}
/**
* Return the system or environment property.
*/
protected String readEnvironment(String key) {
String val = System.getProperty(key);
if (val == null) {
val = System.getenv(key);
}
return val;
}
/**
* Return true if the string is null or empty.
*/
protected boolean isEmpty(String val) {
return val == null || val.trim().isEmpty();
}
/**
* Create the MigrationRunner to run migrations if necessary.
*/
public MigrationRunner createRunner(ClassLoader classLoader, Properties properties) {
runnerConfig.setMetaTable(metaTable);
runnerConfig.setApplySuffix(applySuffix);
runnerConfig.setMigrationPath(migrationPath);
runnerConfig.setMigrationInitPath(migrationInitPath);
runnerConfig.setRunPlaceholderMap(runPlaceholderMap);
runnerConfig.setRunPlaceholders(runPlaceholders);
runnerConfig.setDbUsername(getDbUsername());
runnerConfig.setDbPassword(getDbPassword());
runnerConfig.setDbSchema(getDbSchema());
if (defaultDbSchema) {
runnerConfig.setSetCurrentSchema(false);
}
runnerConfig.setClassLoader(classLoader);
if (patchInsertOn != null) {
runnerConfig.setPatchInsertOn(patchInsertOn);
}
if (patchResetChecksumOn != null) {
runnerConfig.setPatchResetChecksumOn(patchResetChecksumOn);
}
if (properties != null) {
runnerConfig.load(properties);
}
return new MigrationRunner(runnerConfig);
}
}
@@ -1,47 +1,6 @@
package io.ebean.config;
import com.fasterxml.jackson.core.JsonFactory;
import io.avaje.config.Config;
import io.ebean.DatabaseFactory;
import io.ebean.PersistenceContextScope;
import io.ebean.Query;
import io.ebean.Transaction;
import io.ebean.annotation.Encrypted;
import io.ebean.annotation.PersistBatch;
import io.ebean.annotation.Platform;
import io.ebean.cache.ServerCachePlugin;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebean.config.dbplatform.DbEncrypt;
import io.ebean.config.dbplatform.DbType;
import io.ebean.config.dbplatform.IdType;
import io.ebean.datasource.DataSourceConfig;
import io.ebean.event.BeanFindController;
import io.ebean.event.BeanPersistController;
import io.ebean.event.BeanPersistListener;
import io.ebean.event.BeanPostConstructListener;
import io.ebean.event.BeanPostLoad;
import io.ebean.event.BeanQueryAdapter;
import io.ebean.event.BulkTableEventListener;
import io.ebean.event.ServerConfigStartup;
import io.ebean.event.changelog.ChangeLogListener;
import io.ebean.event.changelog.ChangeLogPrepare;
import io.ebean.event.changelog.ChangeLogRegister;
import io.ebean.event.readaudit.ReadAuditLogger;
import io.ebean.event.readaudit.ReadAuditPrepare;
import io.ebean.migration.MigrationRunner;
import io.ebean.util.StringHelper;
import javax.persistence.EnumType;
import javax.sql.DataSource;
import java.time.Clock;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.ServiceLoader;
/**
* Deprecated - please migrate to <code>io.ebean.DatabaseConfig</code>.
@@ -16,6 +16,7 @@ import java.util.Collections;
import java.util.List;
import java.util.NavigableSet;
import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.ReentrantLock;
/**
@@ -42,7 +43,7 @@ public abstract class SequenceIdGenerator implements PlatformIdGenerator {
protected final int allocationSize;
protected boolean currentlyBackgroundLoading;
protected AtomicBoolean currentlyBackgroundLoading = new AtomicBoolean(false);
/**
* Construct given a dataSource and sql to return the next sequence value.
@@ -128,27 +129,16 @@ public abstract class SequenceIdGenerator implements PlatformIdGenerator {
* Load another batch of Id's using a background thread.
*/
protected void loadInBackground(final int requestSize) {
// single threaded processing...
loadLock.lock();
try {
if (currentlyBackgroundLoading) {
// skip as already background loading
logger.debug("... skip background sequence load (another load in progress)");
return;
}
currentlyBackgroundLoading = true;
backgroundExecutor.execute(() -> {
loadMore(requestSize);
loadLock.lock();
try {
currentlyBackgroundLoading = false;
} finally {
loadLock.unlock();
}
});
} finally {
loadLock.lock();
if (currentlyBackgroundLoading.get()) {
// skip as already background loading
logger.debug("... skip background sequence load (another load in progress)");
return;
}
currentlyBackgroundLoading.set(true);
backgroundExecutor.execute(() -> {
loadMore(requestSize);
currentlyBackgroundLoading.set(false);
});
}
/**
@@ -2,11 +2,11 @@ package io.ebean.plugin;
import io.ebean.Query;
import io.ebean.config.dbplatform.IdType;
import io.ebean.docstore.DocMapping;
import io.ebean.event.BeanFindController;
import io.ebean.event.BeanPersistController;
import io.ebean.event.BeanPersistListener;
import io.ebean.event.BeanQueryAdapter;
import io.ebean.docstore.DocMapping;
import javax.annotation.Nonnull;
import java.util.Collection;
@@ -1,18 +1,17 @@
package io.ebean.plugin;
import io.ebean.EbeanServer;
import io.ebean.Database;
import io.ebean.bean.BeanLoader;
import io.ebean.bean.EntityBeanIntercept;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.dbplatform.DatabasePlatform;
import javax.sql.DataSource;
import java.util.List;
/**
* Extensions to Database API made available to plugins.
*/
public interface SpiServer extends EbeanServer {
public interface SpiServer extends Database {
/**
* Return the DatabaseConfig.
@@ -44,16 +43,6 @@ public interface SpiServer extends EbeanServer {
*/
BeanType<?> getBeanTypeForQueueId(String queueId);
/**
* Return the associated DataSource for this Database instance.
*/
DataSource getDataSource();
/**
* Return the associated read only DataSource for this Database instance (can be null).
*/
DataSource getReadOnlyDataSource();
/**
* Return a BeanLoader.
*/
@@ -1,7 +1,7 @@
package io.ebean.text.json;
import io.ebean.bean.PersistenceContext;
import com.fasterxml.jackson.core.JsonParser;
import io.ebean.bean.PersistenceContext;
/**
* Provides a JSON reader that can hold a persistence context and load context while reading JSON.
@@ -1,9 +1,9 @@
package io.ebean.text.json;
import io.ebean.FetchPath;
import io.ebean.plugin.BeanType;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import io.ebean.FetchPath;
import io.ebean.plugin.BeanType;
import java.io.IOException;
import java.io.Reader;
+19 -12
View File
@@ -1,32 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- <parent>-->
<!-- <artifactId>ebean-parent</artifactId>-->
<!-- <groupId>io.ebean</groupId>-->
<!-- <version>12.5.2-SNAPSHOT</version>-->
<!-- </parent>-->
<parent>
<groupId>org.avaje</groupId>
<artifactId>java8-oss</artifactId>
<version>2.2</version>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>12.6.0</version>
</parent>
<!-- <parent>-->
<!-- <groupId>org.avaje</groupId>-->
<!-- <artifactId>java8-oss</artifactId>-->
<!-- <version>2.2</version>-->
<!-- </parent>-->
<scm>
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
<tag>ebean-autotune-12.5.1</tag>
<tag>ebean-parent-12.6.0</tag>
</scm>
<name>ebean autotune</name>
<description>ebean automatic query tuning module</description>
<artifactId>ebean-autotune</artifactId>
<groupId>io.ebean</groupId>
<version>12.5.1</version>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>12.5.1</version>
<version>12.6.0</version>
<scope>provided</scope>
</dependency>
@@ -38,6 +38,13 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.avaje.composite</groupId>
<artifactId>junit</artifactId>
+58 -15
View File
@@ -4,15 +4,22 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>12.5.2-SNAPSHOT</version>
<version>12.6.0</version>
</parent>
<name>ebean bom</name>
<description>ebean bill of materials pom</description>
<artifactId>ebean-bom</artifactId>
<packaging>pom</packaging>
<properties>
<ebean-agent.version>12.5.0</ebean-agent.version>
<ebean-maven-plugin.version>12.5.0</ebean-maven-plugin.version>
<ebean-ddl-runner.version>1.0</ebean-ddl-runner.version>
<ebean-migration-auto.version>1.0</ebean-migration-auto.version>
<ebean-migration.version>12.2.0</ebean-migration.version>
<ebean-test-docker.version>4.0</ebean-test-docker.version>
<ebean-datasource.version>7.0</ebean-datasource.version>
<ebean-agent.version>12.6.0</ebean-agent.version>
<ebean-maven-plugin.version>12.6.0</ebean-maven-plugin.version>
</properties>
<dependencyManagement>
@@ -21,6 +28,36 @@
<!-- dependencies external to this ebean.git build -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-runner</artifactId>
<version>${ebean-ddl-runner.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration-auto</artifactId>
<version>${ebean-migration-auto.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>${ebean-migration.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource-api</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-agent</artifactId>
@@ -33,74 +70,80 @@
<version>${ebean-maven-plugin.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test-docker</artifactId>
<version>${ebean-test-docker.version}</version>
</dependency>
<!-- modules -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean</artifactId>
<version>${project.version}</version>
<version>12.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>${project.version}</version>
<version>12.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>${project.version}</version>
<version>12.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddlgen</artifactId>
<version>${project.version}</version>
<artifactId>ebean-ddl-generator</artifactId>
<version>12.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-externalmapping-api</artifactId>
<version>${project.version}</version>
<version>12.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-externalmapping-xml</artifactId>
<version>${project.version}</version>
<version>12.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-autotune</artifactId>
<version>${project.version}</version>
<version>12.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>${project.version}</version>
<version>12.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>querybean-generator</artifactId>
<version>${project.version}</version>
<version>12.6.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>kotlin-querybean-generator</artifactId>
<version>${project.version}</version>
<version>12.6.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>${project.version}</version>
<version>12.6.0</version>
<scope>test</scope>
</dependency>
+45 -11
View File
@@ -3,18 +3,19 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>12.5.2-SNAPSHOT</version>
<version>12.6.0</version>
</parent>
<artifactId>ebean-core</artifactId>
<packaging>jar</packaging>
<name>ebean-core</name>
<url>http://ebean-orm.github.io/</url>
<name>ebean core</name>
<description>ebean core module</description>
<url>https://ebean.io/</url>
<scm>
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
<tag>HEAD</tag>
<tag>ebean-parent-12.6.0</tag>
</scm>
<properties>
@@ -47,14 +48,40 @@
</profiles>
<dependencies>
<!-- keep testing in core using ebean-ddlgen -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-runner</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>io.avaje</groupId>
<artifactId>classpath-scanner</artifactId>
<version>4.2</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration-auto</artifactId>
<version>1.0</version>
</dependency>
<!-- keep testing in core using ebean-ddl-generator & ebean-migration -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>12.2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddlgen</artifactId>
<version>12.5.0</version>
<version>12.5.2A</version>
<scope>test</scope>
</dependency>
<!-- test scope for supporting ebean-ddlgen -->
<!-- test scope for supporting ebean-ddl-generator -->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
@@ -65,13 +92,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>${project.version}</version>
<version>12.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-externalmapping-api</artifactId>
<version>${project.version}</version>
<version>12.6.0</version>
</dependency>
<dependency>
@@ -145,6 +172,13 @@
<!-- Test scope -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.nuodb.jdbc</groupId>
<artifactId>nuodb-jdbc</artifactId>
@@ -160,9 +194,9 @@
</dependency>
<dependency>
<groupId>io.ebean.test</groupId>
<groupId>io.ebean</groupId>
<artifactId>ebean-test-docker</artifactId>
<version>3.1.5</version>
<version>4.0</version>
<scope>test</scope>
</dependency>
@@ -0,0 +1,15 @@
package io.ebeaninternal.api;
import io.ebean.config.DatabaseConfig;
import io.ebeaninternal.server.type.GeoTypeBinder;
/**
* Provider of Geometry type binder support.
*/
public interface GeoTypeProvider {
/**
* Create a binder for binding geometry types.
*/
GeoTypeBinder createBinder(DatabaseConfig config);
}
@@ -1,8 +1,8 @@
package io.ebeaninternal.server.core;
import io.ebean.ScriptRunner;
import io.ebean.migration.ddl.DdlRunner;
import io.ebean.migration.runner.ScriptTransform;
import io.ebean.ddlrunner.DdlRunner;
import io.ebean.ddlrunner.ScriptTransform;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.util.UrlHelper;
@@ -102,7 +102,7 @@ class DScriptRunner implements ScriptRunner {
private Connection obtainConnection() {
try {
return server.getPluginApi().getDataSource().getConnection();
return server.getDataSource().getConnection();
} catch (SQLException e) {
throw new PersistenceException("Failed to obtain connection to run script", e);
}
@@ -61,6 +61,7 @@ import io.ebean.meta.MetaQueryPlan;
import io.ebean.meta.MetricVisitor;
import io.ebean.meta.QueryPlanInit;
import io.ebean.meta.QueryPlanRequest;
import io.ebean.migration.auto.AutoMigrationRunner;
import io.ebean.plugin.BeanType;
import io.ebean.plugin.Plugin;
import io.ebean.plugin.Property;
@@ -397,8 +398,17 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
* Start any services after registering with the ClusterManager.
*/
public void start() {
if (TenantMode.DB != config.getTenantMode()) {
config.runDbMigration(config.getDataSource());
if (config.isRunMigration() && TenantMode.DB != config.getTenantMode()) {
final AutoMigrationRunner migrationRunner = config.service(AutoMigrationRunner.class);
if (migrationRunner == null) {
throw new IllegalStateException("No AutoMigrationRunner found. Probably ebean-migration is not in the classpath?");
}
final String dbSchema = config.getDbSchema();
if (dbSchema != null) {
migrationRunner.setDefaultDbSchema(dbSchema);
}
migrationRunner.loadProperties(config.getProperties());
migrationRunner.run(config.getDataSource());
}
}
@@ -26,12 +26,10 @@ class InsertTimestampFactory {
map.put(Long.class, longTime);
map.put(long.class, longTime);
if (classLoadConfig.isJavaTimePresent()) {
map.put(Instant.class, new GeneratedInsertJavaTime.InstantDT());
map.put(LocalDateTime.class, new GeneratedInsertJavaTime.LocalDT());
map.put(OffsetDateTime.class, new GeneratedInsertJavaTime.OffsetDT());
map.put(ZonedDateTime.class, new GeneratedInsertJavaTime.ZonedDT());
}
map.put(Instant.class, new GeneratedInsertJavaTime.InstantDT());
map.put(LocalDateTime.class, new GeneratedInsertJavaTime.LocalDT());
map.put(OffsetDateTime.class, new GeneratedInsertJavaTime.OffsetDT());
map.put(ZonedDateTime.class, new GeneratedInsertJavaTime.ZonedDT());
if (classLoadConfig.isJodaTimePresent()) {
map.put(org.joda.time.LocalDateTime.class, new GeneratedInsertJodaTime.LocalDT());
map.put(org.joda.time.DateTime.class, new GeneratedInsertJodaTime.DateTimeDT());
@@ -26,12 +26,11 @@ class UpdateTimestampFactory {
map.put(Long.class, longTime);
map.put(long.class, longTime);
if (classLoadConfig.isJavaTimePresent()) {
map.put(Instant.class, new GeneratedUpdateJavaTime.InstantDT());
map.put(LocalDateTime.class, new GeneratedUpdateJavaTime.LocalDT());
map.put(OffsetDateTime.class, new GeneratedUpdateJavaTime.OffsetDT());
map.put(ZonedDateTime.class, new GeneratedUpdateJavaTime.ZonedDT());
}
map.put(Instant.class, new GeneratedUpdateJavaTime.InstantDT());
map.put(LocalDateTime.class, new GeneratedUpdateJavaTime.LocalDT());
map.put(OffsetDateTime.class, new GeneratedUpdateJavaTime.OffsetDT());
map.put(ZonedDateTime.class, new GeneratedUpdateJavaTime.ZonedDT());
if (classLoadConfig.isJodaTimePresent()) {
map.put(org.joda.time.LocalDateTime.class, new GeneratedUpdateJodaTime.LocalDT());
map.put(org.joda.time.DateTime.class, new GeneratedUpdateJodaTime.DateTimeDT());
@@ -8,6 +8,7 @@ import io.ebeaninternal.server.expression.platform.DbExpressionHandler;
import io.ebeaninternal.server.persist.platform.MultiValueBind;
import io.ebeaninternal.server.type.DataBind;
import io.ebeaninternal.server.type.DataReader;
import io.ebeaninternal.server.type.GeoTypeBinder;
import io.ebeaninternal.server.type.PostgresHelper;
import io.ebeaninternal.server.type.RsetDataReader;
import io.ebeaninternal.server.type.ScalarType;
@@ -35,26 +36,18 @@ public class Binder {
private static final Logger logger = LoggerFactory.getLogger(Binder.class);
private final TypeManager typeManager;
private final int asOfBindCount;
private final boolean asOfStandardsBased;
private final DbExpressionHandler dbExpressionHandler;
private final DataTimeZone dataTimeZone;
private final MultiValueBind multiValueBind;
private final boolean enableBindLog;
private final GeoTypeBinder geoTypeBinder;
/**
* Set the PreparedStatement with which to bind variables to.
*/
public Binder(TypeManager typeManager, SpiLogManager logManager, int asOfBindCount, boolean asOfStandardsBased,
DbExpressionHandler dbExpressionHandler, DataTimeZone dataTimeZone, MultiValueBind multiValueBind) {
this.typeManager = typeManager;
this.geoTypeBinder = typeManager.getGeoTypeBinder();
this.asOfBindCount = asOfBindCount;
this.asOfStandardsBased = asOfStandardsBased;
this.dbExpressionHandler = dbExpressionHandler;
@@ -88,9 +81,7 @@ public class Binder {
* Bind the values to the Prepared Statement.
*/
public void bind(BindValues bindValues, DataBind dataBind, StringBuilder bindBuf) throws SQLException {
String logPrefix = "";
ArrayList<BindValues.Value> list = bindValues.values();
for (BindValues.Value bindValue : list) {
Object val = bindValue.getValue();
@@ -124,7 +115,6 @@ public class Binder {
* Bind the list of positionedParameters in BindParams.
*/
private String bind(BindParams bindParams, DataBind dataBind) throws SQLException {
StringBuilder bindLog = new StringBuilder();
bind(bindParams, dataBind, bindLog);
return bindLog.toString();
@@ -134,7 +124,6 @@ public class Binder {
* Bind the list of positionedParameters in BindParams.
*/
public void bind(BindParams bindParams, DataBind dataBind, StringBuilder bindLog) throws SQLException {
bind(bindParams.positionedParameters(), dataBind, bindLog);
}
@@ -142,13 +131,10 @@ public class Binder {
* Bind the list of parameters..
*/
private void bind(List<BindParams.Param> list, DataBind dataBind, StringBuilder bindLog) throws SQLException {
CallableStatement cstmt = null;
if (dataBind.getPstmt() instanceof CallableStatement) {
cstmt = (CallableStatement) dataBind.getPstmt();
}
// the iterator is assumed to be in the correct order
Object value = null;
try {
@@ -211,7 +197,6 @@ public class Binder {
* Bind an Object with unknown data type.
*/
public Object bindObject(DataBind dataBind, Object value) throws SQLException {
if (value == null) {
// null of unknown type
bindObject(dataBind, null, Types.OTHER);
@@ -233,9 +218,7 @@ public class Binder {
// convert to a JDBC native type
value = type.toJdbcType(value);
}
int dbType = type.getJdbcType();
bindObject(dataBind, value, dbType);
bindObject(dataBind, value, type.getJdbcType());
return value;
}
}
@@ -261,12 +244,10 @@ public class Binder {
* </p>
*/
private void bindObject(DataBind dataBind, Object data, int dbType) throws SQLException {
if (data == null) {
dataBind.setNull(dbType);
return;
}
switch (dbType) {
case java.sql.Types.LONGVARCHAR:
bindLongVarChar(dataBind, data);
@@ -293,7 +274,6 @@ public class Binder {
* Binds the value to the statement according to the data type.
*/
private void bindSimpleData(DataBind b, int dataType, Object data) {
try {
switch (dataType) {
case java.sql.Types.BOOLEAN:
@@ -370,6 +350,15 @@ public class Binder {
b.setObject(PostgresHelper.asInet(data.toString()));
break;
case DbPlatformType.POINT:
case DbPlatformType.POLYGON:
case DbPlatformType.MULTIPOINT:
case DbPlatformType.LINESTRING:
case DbPlatformType.MULTILINESTRING:
case DbPlatformType.MULTIPOLYGON:
geoTypeBinder.bind(b, dataType, data);
break;
case java.sql.Types.OTHER:
b.setObject(data, dataType);
break;
@@ -393,7 +382,6 @@ public class Binder {
* Bind String data to a LONGVARCHAR column.
*/
private void bindLongVarChar(DataBind dataBind, Object data) throws SQLException {
dataBind.setClob((String) data);
}
@@ -401,7 +389,6 @@ public class Binder {
* Bind byte[] data to a LONGVARBINARY column.
*/
private void bindLongVarBinary(DataBind dataBind, Object data) throws SQLException {
dataBind.setBlob((byte[]) data);
}
@@ -409,7 +396,6 @@ public class Binder {
* Bind String data to a CLOB column.
*/
private void bindClob(DataBind dataBind, Object data) throws SQLException {
dataBind.setClob((String) data);
}
@@ -417,7 +403,6 @@ public class Binder {
* Bind byte[] data to a BLOB column.
*/
private void bindBlob(DataBind dataBind, Object data) throws SQLException {
dataBind.setBlob((byte[]) data);
}
@@ -19,6 +19,7 @@ import io.ebean.types.Inet;
import io.ebean.util.AnnotationUtil;
import io.ebeaninternal.api.ExtraTypeFactory;
import io.ebeaninternal.api.DbOffline;
import io.ebeaninternal.api.GeoTypeProvider;
import io.ebeaninternal.server.core.bootup.BootupClasses;
import io.ebeaninternal.server.deploy.meta.DeployBeanProperty;
import io.ebeanservice.docstore.api.mapping.DocPropertyType;
@@ -145,8 +146,6 @@ public final class DefaultTypeManager implements TypeManager {
private final Object objectMapper;
private final boolean java7Present;
private final boolean objectMapperPresent;
private final boolean postgres;
@@ -180,13 +179,12 @@ public final class DefaultTypeManager implements TypeManager {
private final PlatformArrayTypeFactory arrayTypeListFactory;
private final PlatformArrayTypeFactory arrayTypeSetFactory;
private GeoTypeBinder geoTypeBinder;
/**
* Create the DefaultTypeManager.
*/
public DefaultTypeManager(DatabaseConfig config, BootupClasses bootupClasses) {
this.java7Present = config.getClassLoadConfig().isJava7Present();
this.jsonDateTime = config.getJsonDateTime();
this.jsonDate = config.getJsonDate();
this.typeMap = new ConcurrentHashMap<>();
@@ -211,6 +209,7 @@ public final class DefaultTypeManager implements TypeManager {
initialiseJacksonTypes(config);
loadTypesFromProviders(config, objectMapper);
loadGeoTypeBinder(config);
if (bootupClasses != null) {
initialiseCustomScalarTypes(bootupClasses);
@@ -219,6 +218,13 @@ public final class DefaultTypeManager implements TypeManager {
}
}
private void loadGeoTypeBinder(DatabaseConfig config) {
final GeoTypeProvider provider = config.service(GeoTypeProvider.class);
if (provider != null) {
geoTypeBinder = provider.createBinder(config);
}
}
/**
* Return the factory to use to support DB ARRAY types.
*/
@@ -335,19 +341,17 @@ public final class DefaultTypeManager implements TypeManager {
}
private ScalarType<?> checkInterfaceTypes(Class<?> type) {
if (java7Present) {
return checkJava7InterfaceTypes(type);
}
return null;
}
private ScalarType<?> checkJava7InterfaceTypes(Class<?> type) {
if (java.nio.file.Path.class.isAssignableFrom(type)) {
return typeMap.get(java.nio.file.Path.class);
}
return null;
}
@Override
public GeoTypeBinder getGeoTypeBinder() {
return geoTypeBinder;
}
@Override
public ScalarType<?> getDbMapScalarType() {
return (postgres) ? hstoreType : ScalarTypeJsonMap.typeFor(false, Types.VARCHAR);
@@ -882,33 +886,25 @@ public final class DefaultTypeManager implements TypeManager {
}
private void initialiseJavaTimeTypes(DatabaseConfig config) {
if (java7Present) {
typeMap.put(java.nio.file.Path.class, new ScalarTypePath());
}
if (config.getClassLoadConfig().isJavaTimePresent()) {
logger.debug("Registering java.time data types");
addType(java.time.Period.class, new ScalarTypePeriod());
addType(java.time.LocalDate.class, new ScalarTypeLocalDate(jsonDate));
addType(java.time.LocalDateTime.class, new ScalarTypeLocalDateTime(jsonDateTime));
addType(OffsetDateTime.class, new ScalarTypeOffsetDateTime(jsonDateTime));
addType(ZonedDateTime.class, new ScalarTypeZonedDateTime(jsonDateTime));
addType(Instant.class, new ScalarTypeInstant(jsonDateTime));
addType(DayOfWeek.class, new ScalarTypeDayOfWeek());
addType(Month.class, new ScalarTypeMonth());
addType(Year.class, new ScalarTypeYear());
addType(YearMonth.class, new ScalarTypeYearMonthDate(jsonDate));
addType(MonthDay.class, new ScalarTypeMonthDay());
addType(OffsetTime.class, new ScalarTypeOffsetTime());
addType(ZoneId.class, new ScalarTypeZoneId());
addType(ZoneOffset.class, new ScalarTypeZoneOffset());
boolean localTimeNanos = config.isLocalTimeWithNanos();
addType(java.time.LocalTime.class, (localTimeNanos) ? new ScalarTypeLocalTimeWithNanos() : new ScalarTypeLocalTime());
boolean durationNanos = config.isDurationWithNanos();
addType(Duration.class, (durationNanos) ? new ScalarTypeDurationWithNanos() : new ScalarTypeDuration());
}
typeMap.put(java.nio.file.Path.class, new ScalarTypePath());
addType(java.time.Period.class, new ScalarTypePeriod());
addType(java.time.LocalDate.class, new ScalarTypeLocalDate(jsonDate));
addType(java.time.LocalDateTime.class, new ScalarTypeLocalDateTime(jsonDateTime));
addType(OffsetDateTime.class, new ScalarTypeOffsetDateTime(jsonDateTime));
addType(ZonedDateTime.class, new ScalarTypeZonedDateTime(jsonDateTime));
addType(Instant.class, new ScalarTypeInstant(jsonDateTime));
addType(DayOfWeek.class, new ScalarTypeDayOfWeek());
addType(Month.class, new ScalarTypeMonth());
addType(Year.class, new ScalarTypeYear());
addType(YearMonth.class, new ScalarTypeYearMonthDate(jsonDate));
addType(MonthDay.class, new ScalarTypeMonthDay());
addType(OffsetTime.class, new ScalarTypeOffsetTime());
addType(ZoneId.class, new ScalarTypeZoneId());
addType(ZoneOffset.class, new ScalarTypeZoneOffset());
boolean localTimeNanos = config.isLocalTimeWithNanos();
addType(java.time.LocalTime.class, (localTimeNanos) ? new ScalarTypeLocalTimeWithNanos() : new ScalarTypeLocalTime());
boolean durationNanos = config.isDurationWithNanos();
addType(Duration.class, (durationNanos) ? new ScalarTypeDurationWithNanos() : new ScalarTypeDuration());
}
private void addType(Class<?> clazz, ScalarType<?> scalarType) {
@@ -0,0 +1,14 @@
package io.ebeaninternal.server.type;
import java.sql.SQLException;
/**
* Binder for Geometry types.
*/
public interface GeoTypeBinder {
/**
* Bind the geometry type.
*/
void bind(DataBind b, int dataType, Object data) throws SQLException;
}
@@ -69,4 +69,9 @@ public interface TypeManager {
* Return the ScalarType used to handle HSTORE (Map<String,String>).
*/
ScalarType<?> getDbMapScalarType();
/**
* Return the Geometry type binder if provided.
*/
GeoTypeBinder getGeoTypeBinder();
}
@@ -1,7 +1,7 @@
package io.ebean;
import io.ebean.config.CurrentTenantProvider;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.TenantCatalogProvider;
import io.ebean.config.TenantDataSourceProvider;
import io.ebean.config.TenantMode;
@@ -29,7 +29,7 @@ public class EbeanServerFactory_MultiTenancy_Test extends BaseTestCase {
TenantDataSourceProvider dataSourceProvider = Mockito.mock(TenantDataSourceProvider.class);
Mockito.doReturn(mockedDataSource).when(dataSourceProvider).dataSource(tenant);
ServerConfig config = new ServerConfig();
DatabaseConfig config = new DatabaseConfig();
config.setName("multiTenantDb");
config.loadFromProperties();
config.setRegister(false);
@@ -45,7 +45,8 @@ public class EbeanServerFactory_MultiTenancy_Test extends BaseTestCase {
//config.setDdlRun(false);
config.setDatabasePlatform(new PostgresPlatform());
EbeanServerFactory.create(config);
final Database database = DatabaseFactory.create(config);
database.shutdown();
}
@@ -63,9 +64,10 @@ public class EbeanServerFactory_MultiTenancy_Test extends BaseTestCase {
TenantSchemaProvider schemaProvider = Mockito.mock(TenantSchemaProvider.class);
Mockito.doReturn("tenant_schema").when(schemaProvider).schema(tenant);
ServerConfig config = new ServerConfig();
DatabaseConfig config = new DatabaseConfig();
config.setName("h2");
config.loadFromProperties();
config.setName("multi-tenancy");
config.setRegister(false);
config.setDefaultServer(false);
@@ -76,7 +78,8 @@ public class EbeanServerFactory_MultiTenancy_Test extends BaseTestCase {
config.setDdlRun(false);
config.setDatabasePlatform(new MySqlPlatform());
EbeanServerFactory.create(config);
final Database database = DatabaseFactory.create(config);
database.shutdown();
}
/**
@@ -92,9 +95,10 @@ public class EbeanServerFactory_MultiTenancy_Test extends BaseTestCase {
TenantCatalogProvider catalogProvider = Mockito.mock(TenantCatalogProvider.class);
Mockito.doReturn("tenant_catalog").when(catalogProvider).catalog(tenant);
ServerConfig config = new ServerConfig();
DatabaseConfig config = new DatabaseConfig();
config.setName("h2");
config.loadFromProperties();
config.setName("multi-tenancy");
config.setRegister(false);
config.setDefaultServer(false);
@@ -105,6 +109,7 @@ public class EbeanServerFactory_MultiTenancy_Test extends BaseTestCase {
config.setDdlRun(false);
config.setDatabasePlatform(new MySqlPlatform());
EbeanServerFactory.create(config);
final Database database = DatabaseFactory.create(config);
database.shutdown();
}
}
@@ -3,7 +3,7 @@ package io.ebean.config;
import org.junit.Test;
import java.util.Properties;
import io.ebean.migration.MigrationConfig;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
@@ -13,12 +13,13 @@ public class DbMigrationConfigTest {
@Test
public void testLoad() {
ServerConfig config = new ServerConfig();
DatabaseConfig config = new DatabaseConfig();
config.setName("h2other");
config.loadFromProperties();
config.setDefaultServer(false);
DbMigrationConfig migrationConfig = config.getMigrationConfig();
MigrationConfig migrationConfig = new MigrationConfig();
migrationConfig.load(config.getProperties());
assertThat(migrationConfig.getMigrationPath()).isEqualTo("dbmigration/myapp");
}
@@ -27,20 +28,18 @@ public class DbMigrationConfigTest {
public void loadProperties_migration() {
Properties properties = new Properties();
properties.setProperty("ebean.migration.dbusername", "banana");
properties.setProperty("ebean.migration.dbpassword", "apple");
properties.setProperty("ebean.migration.username", "banana");
properties.setProperty("ebean.migration.password", "apple");
properties.setProperty("ebean.migration.patchInsertOn", "1.3,my_views");
properties.setProperty("ebean.migration.patchResetChecksumOn", "foo");
PropertiesWrapper wrapper = new PropertiesWrapper("ebean", "db", properties, null);
DbMigrationConfig migrationConfig = new DbMigrationConfig();
migrationConfig.loadSettings(wrapper, "db");
MigrationConfig migrationConfig = new MigrationConfig();
migrationConfig.load(properties);
assertEquals(migrationConfig.getDbUsername(),"banana");
assertEquals(migrationConfig.getDbPassword(),"apple");
assertEquals(migrationConfig.getPatchInsertOn(),"1.3,my_views");
assertEquals(migrationConfig.getPatchResetChecksumOn(),"foo");
assertThat(migrationConfig.getPatchInsertOn()).containsOnly("1.3","my_views");
assertThat(migrationConfig.getPatchResetChecksumOn()).containsOnly("foo");
}
@Test
@@ -50,29 +49,12 @@ public class DbMigrationConfigTest {
properties.setProperty("datasource.db.username", "banana");
properties.setProperty("datasource.db.password", "apple");
PropertiesWrapper wrapper = new PropertiesWrapper("ebean", "db", properties, null);
DbMigrationConfig migrationConfig = new DbMigrationConfig();
migrationConfig.loadSettings(wrapper, "db");
MigrationConfig migrationConfig = new MigrationConfig();
migrationConfig.load(properties);
// runnerConfig will fall back itsel to the correct password
assertEquals(migrationConfig.getDbUsername(),null);
assertEquals(migrationConfig.getDbPassword(),null);
}
@Test
public void loadProperties_datasource_adminusername() {
Properties properties = new Properties();
properties.setProperty("datasource.db.adminusername", "banana");
properties.setProperty("datasource.db.adminpassword", "apple");
PropertiesWrapper wrapper = new PropertiesWrapper("ebean", "db", properties, null);
DbMigrationConfig migrationConfig = new DbMigrationConfig();
migrationConfig.loadSettings(wrapper, "db");
assertEquals(migrationConfig.getDbUsername(),"banana");
assertEquals(migrationConfig.getDbPassword(),"apple");
}
}
@@ -1,8 +1,8 @@
package io.ebean.config;
import io.ebean.EbeanServer;
import io.ebean.EbeanServerFactory;
import io.ebean.Database;
import io.ebean.DatabaseFactory;
import io.ebean.annotation.ForPlatform;
import io.ebean.annotation.Platform;
import org.junit.Ignore;
@@ -26,7 +26,7 @@ public class ServerConfigSqlServerTest {
// no explicit databasePlatformName set ..
//props.setProperty("ebean.some_sqlserver.databasePlatformName", "sqlserver17");
ServerConfig config = new ServerConfig();
DatabaseConfig config = new DatabaseConfig();
config.setName("some_sqlserver");
config.loadFromProperties(props);
@@ -38,9 +38,10 @@ public class ServerConfigSqlServerTest {
config.setRegister(false);
config.getClasses().add(EBasicVer.class);
EbeanServer sqlServer = EbeanServerFactory.create(config);
Database sqlServer = DatabaseFactory.create(config);
assertThat(sqlServer).isNotNull();
sqlServer.shutdown();
// javax.persistence.PersistenceException: java.lang.IllegalArgumentException: For SqlServer please choose the more specific sqlserver16 or sqlserver17 platform via ServerConfig.setDatabasePlatformName. Refer to issue #1340 for details
//
@@ -61,7 +62,7 @@ public class ServerConfigSqlServerTest {
String name = "testsqlserver17";
ServerConfig config = new ServerConfig();
DatabaseConfig config = new DatabaseConfig();
config.setName(name);
Properties props = props(name);
@@ -79,9 +80,10 @@ public class ServerConfigSqlServerTest {
config.loadFromProperties(props);
config.getClasses().add(EBasicVer.class);
EbeanServer sqlServer = EbeanServerFactory.create(config);
Database sqlServer = DatabaseFactory.create(config);
assertThat(sqlServer).isNotNull();
sqlServer.shutdown();
}
@Ignore
@@ -93,7 +95,7 @@ public class ServerConfigSqlServerTest {
Properties props = props(name);
//props.setProperty("ebean.testsqlserver16.databasePlatformName", "sqlserver16");
ServerConfig config = new ServerConfig();
DatabaseConfig config = new DatabaseConfig();
config.setDefaultServer(false);
config.setRegister(false);
config.setDdlGenerate(true);
@@ -104,9 +106,10 @@ public class ServerConfigSqlServerTest {
config.loadFromProperties(props);
config.getClasses().add(EBasicVer.class);
EbeanServer sqlServer = EbeanServerFactory.create(config);
Database sqlServer = DatabaseFactory.create(config);
assertThat(sqlServer).isNotNull();
sqlServer.shutdown();
}
private Properties props(String dbName) {
@@ -27,7 +27,7 @@ public class SqlServerStepSequenceTest extends BaseTestCase {
server().sqlUpdate("create sequence sqls_testseq_9876 start with 1 increment by 50").execute();
BackgroundExecutor be = server().getBackgroundExecutor();
DataSource ds = server().getPluginApi().getDataSource();
DataSource ds = server().getDataSource();
SqlServerStepSequence s = new SqlServerStepSequence(be, ds, "sqls_testseq_9876", 50);
@@ -18,9 +18,9 @@ import static org.assertj.core.api.Assertions.assertThat;
public class BeanPersistControllerTest {
private PersistAdapter continuePersistingAdapter = new PersistAdapter(true);
private final PersistAdapter continuePersistingAdapter = new PersistAdapter(true);
private PersistAdapter stopPersistingAdapter = new PersistAdapter(false);
private final PersistAdapter stopPersistingAdapter = new PersistAdapter(false);
@Test
public void issue_1341() {
@@ -3,12 +3,12 @@ package io.ebean.event;
import io.ebean.BaseTestCase;
import io.ebean.BeanState;
import io.ebean.DB;
import io.ebean.Database;
import io.ebean.DatabaseFactory;
import io.ebean.Ebean;
import io.ebean.config.DatabaseConfig;
import org.tests.model.basic.EBasicVer;
import org.junit.Test;
import org.tests.model.basic.EBasicVer;
import java.util.ArrayList;
import java.util.List;
@@ -91,7 +91,7 @@ public class BeanPostLoadTest extends BaseTestCase {
public void postLoad(Object bean) {
this.methodsCalled.add("postLoad");
this.bean = bean;
this.beanState = Ebean.getBeanState(bean);
this.beanState = DB.getBeanState(bean);
}
}
@@ -53,6 +53,7 @@ import io.ebeaninternal.server.transaction.RemoteTransactionEvent;
import javax.persistence.OptimisticLockException;
import javax.persistence.PersistenceException;
import javax.sql.DataSource;
import java.lang.reflect.Type;
import java.time.Clock;
import java.util.Collection;
@@ -336,6 +337,16 @@ public class TDSpiEbeanServer implements SpiEbeanServer {
return null;
}
@Override
public DataSource getDataSource() {
return null;
}
@Override
public DataSource getReadOnlyDataSource() {
return null;
}
@Override
public String getName() {
return name;
@@ -26,10 +26,13 @@ public class BeanDescriptor_registerTest {
config.getClasses().add(EBasic.class);
SpiEbeanServer ebeanServer = (SpiEbeanServer)DatabaseFactory.create(config);
BeanDescriptor<EBasic> desc = ebeanServer.getBeanDescriptor(EBasic.class);
persistListenerRegistrationTests(desc);
persistControllerRegistrationTests(desc);
try {
BeanDescriptor<EBasic> desc = ebeanServer.getBeanDescriptor(EBasic.class);
persistListenerRegistrationTests(desc);
persistControllerRegistrationTests(desc);
} finally {
ebeanServer.shutdown();
}
}
private void persistControllerRegistrationTests(BeanDescriptor<EBasic> desc) {
@@ -258,7 +258,7 @@ public class TestRawSqlBuilder extends BaseTestCase {
"join o_customer c on o.kcustomer_id = c.id " +
"where c.id = ? and o.id > ?";
final DataSource dataSource = DB.getDefault().getPluginApi().getDataSource();
final DataSource dataSource = DB.getDefault().getDataSource();
try (Connection connection = dataSource.getConnection()) {
try (PreparedStatement stmt = connection.prepareStatement(sql)) {
@@ -105,29 +105,31 @@ public class DefaultTransactionThreadLocalTest extends BaseTestCase {
@ForPlatform(Platform.H2)
@Test
public void usingDatabase() {
// setup
Database otherDb = createOtherDatabase();
EBasicVer bean = new EBasicVer("TestUsingDatabase");
otherDb.save(bean);
try {
EBasicVer bean = new EBasicVer("TestUsingDatabase");
otherDb.save(bean);
// act
final EBasicVer foundOtherDb = DB.find(EBasicVer.class)
.usingDatabase(otherDb)
.where().eq("name", "TestUsingDatabase")
.findOne();
// act
final EBasicVer foundOtherDb = DB.find(EBasicVer.class)
.usingDatabase(otherDb)
.where().eq("name", "TestUsingDatabase")
.findOne();
assertNotNull(foundOtherDb);
assertThat(foundOtherDb.getId()).isEqualTo(bean.getId());
assertNotNull(foundOtherDb);
assertThat(foundOtherDb.getId()).isEqualTo(bean.getId());
final EBasicVer foundDefaultDb = DB.find(EBasicVer.class)
.where().eq("name", "TestUsingDatabase")
.findOne();
final EBasicVer foundDefaultDb = DB.find(EBasicVer.class)
.where().eq("name", "TestUsingDatabase")
.findOne();
assertNull(foundDefaultDb);
assertNull(foundDefaultDb);
otherDb.delete(bean);
otherDb.shutdown();
otherDb.delete(bean);
} finally {
otherDb.shutdown();
}
}
@@ -32,47 +32,50 @@ public class TransactionManagerTest extends BaseTestCase {
DataSource dataSource = transactionManager.getDataSource();
Connection connection = dataSource.getConnection();
SpiTransaction externalTxn = new ExternalJdbcTransaction("external0", true, connection, null);
// push an externally managed transaction onto scope
ScopedTransaction scopedTransaction = transactionManager.externalBeginTransaction(externalTxn, TxScope.required());
Transaction current = Transaction.current();
assertThat(current).as("external transaction is in scope").isSameAs(scopedTransaction);
Customer.find.byName("In external");
log.info("inner begin");
Transaction inner = Ebean.beginTransaction();
try {
SpiTransaction externalTxn = new ExternalJdbcTransaction("external0", true, connection, null);
// push an externally managed transaction onto scope
ScopedTransaction scopedTransaction = transactionManager.externalBeginTransaction(externalTxn, TxScope.required());
Transaction current = Transaction.current();
assertThat(current).as("external transaction is in scope").isSameAs(scopedTransaction);
Customer.find.byName("In external");
log.info("inner begin");
Transaction inner = Ebean.beginTransaction();
try {
current = Transaction.current();
assertThat(current).as("still using external transaction, nested transaction pushed").isSameAs(scopedTransaction);
Customer.find.byName("In inner");
log.info("inner commit");
inner.commit();
} finally {
log.info("inner end");
inner.end();
}
current = Transaction.current();
assertThat(current).as("still using external transaction, nested transaction pushed").isSameAs(scopedTransaction);
assertThat(current).as("external transaction still in scope").isSameAs(scopedTransaction);
Customer.find.byName("In inner");
log.info("inner commit");
inner.commit();
Customer.find.byName("external still active");
log.info("external transaction ends with commit and remove");
connection.commit();
// remove externally managed transaction out of scope
transactionManager.externalRemoveTransaction();
current = Transaction.current();
assertThat(current).as("external transaction out of scope").isNull();
} finally {
log.info("inner end");
inner.end();
connection.close();
}
current = Transaction.current();
assertThat(current).as("external transaction still in scope").isSameAs(scopedTransaction);
Customer.find.byName("external still active");
log.info("external transaction ends with commit and remove");
connection.commit();
// remove externally managed transaction out of scope
transactionManager.externalRemoveTransaction();
current = Transaction.current();
assertThat(current).as("external transaction out of scope").isNull();
Customer.find.byNameStatus("New implicit transaction", Customer.Status.ACTIVE);
}
}
+1 -1
View File
@@ -15,7 +15,7 @@ public class Main {
EbeanServer ms = Ebean.getServer("ms");
DataSource dataSource = ms.getPluginApi().getDataSource();
DataSource dataSource = ms.getDataSource();
Connection connection = dataSource.getConnection();
PreparedStatement statement = connection.prepareStatement("select next VALUE for j2_seq");
@@ -1,11 +1,11 @@
package org;
import io.ebean.EbeanServer;
import io.ebean.EbeanServerFactory;
import io.ebean.Database;
import io.ebean.DatabaseFactory;
import io.ebean.Transaction;
import io.ebean.annotation.Cache;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.PlatformNoGeneratedKeysTest;
import io.ebean.config.ServerConfig;
import javax.persistence.Entity;
import javax.persistence.Id;
@@ -40,13 +40,13 @@ public class MainMemoryLeak {
PlatformNoGeneratedKeysTest.OtherH2Platform platform = new PlatformNoGeneratedKeysTest.OtherH2Platform();
ServerConfig config = new ServerConfig();
DatabaseConfig config = new DatabaseConfig();
config.setDatabasePlatform(platform);
config.addClass(ECachedBean.class);
config.loadFromProperties();
EbeanServer server = EbeanServerFactory.create(config);
Database server = DatabaseFactory.create(config);
// create a string with 10k chars
char[] c = new char[10_000];
@@ -70,6 +70,6 @@ public class MainMemoryLeak {
System.out.println("Success, no mem limit detected");
txn.commit();
}
server.shutdown();
}
}
@@ -1,11 +1,12 @@
package org.multitenant.partition;
import io.ebean.BaseTestCase;
import io.ebean.EbeanServer;
import io.ebean.EbeanServerFactory;
import io.ebean.config.ServerConfig;
import io.ebean.Database;
import io.ebean.DatabaseFactory;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.TenantMode;
import org.ebeantest.LoggedSqlCollector;
import org.junit.AfterClass;
import org.junit.Test;
import java.util.ArrayList;
@@ -16,7 +17,7 @@ import static org.assertj.core.api.Assertions.assertThat;
public class MultiTenantPartitionTest extends BaseTestCase {
private static String[] names = {"Ace", "Base", "Case", "Dae", "Eva"};
private static final String[] names = {"Ace", "Base", "Case", "Dae", "Eva"};
static List<MtTenant> tenants() {
List<MtTenant> tenants = new ArrayList<>();
@@ -26,12 +27,16 @@ public class MultiTenantPartitionTest extends BaseTestCase {
return tenants;
}
private static EbeanServer server = init();
private static final Database server = init();
static {
server.saveAll(tenants());
}
@AfterClass
public static void shutdown() {
server.shutdown();
}
@Test
public void start() {
@@ -103,9 +108,9 @@ public class MultiTenantPartitionTest extends BaseTestCase {
}
private static EbeanServer init() {
private static Database init() {
ServerConfig config = new ServerConfig();
DatabaseConfig config = new DatabaseConfig();
config.setName("h2multitenant");
config.loadFromProperties();
@@ -120,6 +125,6 @@ public class MultiTenantPartitionTest extends BaseTestCase {
config.getClasses().add(MtTenant.class);
config.getClasses().add(MtContent.class);
return EbeanServerFactory.create(config);
return DatabaseFactory.create(config);
}
}
@@ -24,7 +24,7 @@ public class TestQueryUsingConnection extends BaseTestCase {
ResetBasicData.reset();
DataSource dataSource = DB.getDefault().getPluginApi().getDataSource();
DataSource dataSource = DB.getDefault().getDataSource();
try (Connection connection = dataSource.getConnection()) {
@@ -3,9 +3,10 @@ package org.tests.changelog;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.ebean.BaseTestCase;
import io.ebean.EbeanServerFactory;
import io.ebean.Database;
import io.ebean.DatabaseFactory;
import io.ebean.annotation.ChangeLog;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebean.event.BeanPersistRequest;
import io.ebean.event.changelog.BeanChange;
import io.ebean.event.changelog.ChangeLogFilter;
@@ -14,7 +15,6 @@ import io.ebean.event.changelog.ChangeLogPrepare;
import io.ebean.event.changelog.ChangeLogRegister;
import io.ebean.event.changelog.ChangeSet;
import io.ebean.event.changelog.ChangeType;
import io.ebeaninternal.api.SpiEbeanServer;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -31,16 +31,16 @@ public class TestChangeLog extends BaseTestCase {
TDChangeLogRegister changeLogRegister = new TDChangeLogRegister();
SpiEbeanServer server;
Database server;
@Before
public void setup() {
server = getServer();
server = createServer();
}
@After
public void shutdown() {
server.shutdown(true, false);
server.shutdown();
}
@Test
@@ -65,7 +65,7 @@ public class TestChangeLog extends BaseTestCase {
assertThat(change.getEvent()).isEqualTo(ChangeType.UPDATE);
assertThat(change.getOldData()).contains("\"name\":\"logBean\"");
assertThat(change.getData()) .contains("\"name\":\"ChangedName\"");
assertThat(change.getData()).contains("\"name\":\"ChangedName\"");
server.delete(bean);
@@ -120,31 +120,27 @@ public class TestChangeLog extends BaseTestCase {
}
private Database createServer() {
private SpiEbeanServer getServer() {
ServerConfig config = new ServerConfig();
DatabaseConfig config = new DatabaseConfig();
config.setName("h2other");
config.loadFromProperties();
config.setDdlGenerate(true);
config.setDdlRun(true);
config.setDdlExtra(false);
config.setDefaultServer(false);
config.setRegister(false);
config.setChangeLogAsync(false);
config.addClass(EBasicChangeLog.class);
config.setChangeLogPrepare(changeLogPrepare);
config.setChangeLogListener(changeLogListener);
config.setChangeLogRegister(changeLogRegister);
return (SpiEbeanServer) EbeanServerFactory.create(config);
return DatabaseFactory.create(config);
}
class TDChangeLogPrepare implements ChangeLogPrepare {
public static class TDChangeLogPrepare implements ChangeLogPrepare {
@Override
public boolean prepare(ChangeSet changes) {
changes.setUserId("appUser1");
@@ -153,14 +149,12 @@ public class TestChangeLog extends BaseTestCase {
}
}
class TDChangeLogListener implements ChangeLogListener {
public static class TDChangeLogListener implements ChangeLogListener {
ObjectMapper objectMapper = new ObjectMapper();
ChangeSet changes;
/**
*/
public TDChangeLogListener() {
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
}
@@ -184,7 +178,7 @@ public class TestChangeLog extends BaseTestCase {
}
class TDChangeLogRegister implements ChangeLogRegister {
public static class TDChangeLogRegister implements ChangeLogRegister {
@Override
public ChangeLogFilter getChangeFilter(Class<?> beanType) {
@@ -198,11 +192,10 @@ public class TestChangeLog extends BaseTestCase {
}
}
/**
* Change log filter that includes all the inserts, updates and deletes.
*/
class TDFilter implements ChangeLogFilter {
public static class TDFilter implements ChangeLogFilter {
/**
* Returns true including all the inserts.
@@ -1,27 +0,0 @@
package org.tests.ddl;
import io.ebean.EbeanServer;
import io.ebean.EbeanServerFactory;
import io.ebean.config.ServerConfig;
import org.tests.model.basic.EBasic;
public class MainDdlWithSchema {
public static void main(String[] args) {
ServerConfig cfg = new ServerConfig();
cfg.setName("h2");
cfg.loadFromProperties();
cfg.addClass(EBasic.class);
// .... other settings ...
//UnderscoreNamingConvention naming = new UnderscoreNamingConvention();
//naming.setSchema("test");
//cfg.setNamingConvention(naming);
cfg.setDdlGenerate(true);
cfg.setDdlRun(true);
EbeanServer ebean = EbeanServerFactory.create(cfg);
//ebean.createSqlUpdate("create schema foo").execute();
System.out.println(ebean);
}
}
@@ -1,16 +1,16 @@
package org.tests.persistencecontext;
import io.ebean.BaseTestCase;
import io.ebean.EbeanServer;
import io.ebean.EbeanServerFactory;
import io.ebean.Database;
import io.ebean.DatabaseFactory;
import io.ebean.PersistenceContextScope;
import io.ebean.Query;
import io.ebean.config.ContainerConfig;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.api.SpiQuery;
import org.tests.model.basic.EBasicVer;
import org.junit.Test;
import org.tests.model.basic.EBasicVer;
import java.util.Properties;
@@ -20,20 +20,20 @@ public class TestPersistenceContextServerConfig extends BaseTestCase {
@Test
public void test_config() {
SpiEbeanServer ebeanServer = (SpiEbeanServer) create();
try {
Query<EBasicVer> query = ebeanServer.find(EBasicVer.class);
PersistenceContextScope scope = ebeanServer.getPersistenceContextScope((SpiQuery<?>) query);
Query<EBasicVer> query = ebeanServer.find(EBasicVer.class);
PersistenceContextScope scope = ebeanServer.getPersistenceContextScope((SpiQuery<?>) query);
assertEquals(PersistenceContextScope.QUERY, scope);
assertEquals(PersistenceContextScope.QUERY, scope);
} finally {
ebeanServer.shutdown();
}
}
static EbeanServer create() {
static Database create() {
ServerConfig config = new ServerConfig();
DatabaseConfig config = new DatabaseConfig();
config.setName("withPCQuery");
config.setDdlExtra(false);
@@ -49,15 +49,7 @@ public class TestPersistenceContextServerConfig extends BaseTestCase {
config.setDefaultServer(false);
config.setRegister(false);
// DataSourceConfig dataSourceConfig = new DataSourceConfig();
// dataSourceConfig.setUsername("sa");
// dataSourceConfig.setPassword("");
// dataSourceConfig.setUrl("jdbc:h2:mem:withPCQuery;");
// dataSourceConfig.setDriver("org.h2.Driver");
// config.setDataSourceConfig(dataSourceConfig);
config.addClass(EBasicVer.class);
return EbeanServerFactory.create(config);
return DatabaseFactory.create(config);
}
}
@@ -235,7 +235,7 @@ public class TestQueryFindIterate extends BaseTestCase {
SpiServer pluginApi = server().getPluginApi();
DataSourcePool dsPool = (DataSourcePool) pluginApi.getServerConfig().getReadOnlyDataSource();
if (dsPool == null) {
dsPool = (DataSourcePool) server().getPluginApi().getDataSource();
dsPool = (DataSourcePool) server().getDataSource();
}
int startConns = dsPool.getStatus(false).getBusy();
@@ -5,9 +5,9 @@ import io.ebean.Ebean;
import io.ebean.Query;
import io.ebean.annotation.Platform;
import io.ebean.plugin.SpiServer;
import org.junit.Test;
import org.tests.model.basic.Customer;
import org.tests.model.basic.ResetBasicData;
import org.junit.Test;
import java.util.List;
@@ -38,7 +38,7 @@ public class TestNativeILikeExpression extends BaseTestCase {
SpiServer pluginApi = server().getPluginApi();
boolean expressionNativeIlike = pluginApi.getServerConfig().isExpressionNativeIlike();
Platform platform = pluginApi.getDatabasePlatform().getPlatform();
Platform platform = pluginApi.getPlatform().base();
return expressionNativeIlike && platform == Platform.POSTGRES;
}
@@ -1,22 +1,22 @@
package org.tests.readaudit;
import io.ebean.BaseTestCase;
import io.ebean.EbeanServerFactory;
import io.ebean.Database;
import io.ebean.DatabaseFactory;
import io.ebean.FutureList;
import io.ebean.cache.ServerCache;
import io.ebean.cache.ServerCacheStatistics;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebean.event.readaudit.ReadAuditLogger;
import io.ebean.event.readaudit.ReadAuditPrepare;
import io.ebean.event.readaudit.ReadAuditQueryPlan;
import io.ebean.event.readaudit.ReadEvent;
import io.ebeaninternal.api.SpiEbeanServer;
import org.tests.model.basic.Country;
import org.tests.model.basic.EBasicChangeLog;
import org.ebeantest.LoggedSqlCollector;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.tests.model.basic.Country;
import org.tests.model.basic.EBasicChangeLog;
import java.util.ArrayList;
import java.util.HashSet;
@@ -30,18 +30,18 @@ import static org.assertj.core.api.Assertions.assertThat;
public class TestReadAudit extends BaseTestCase {
TDReadAuditPrepare readAuditPrepare = new TDReadAuditPrepare(true);
TDReadAuditPrepare readAuditPrepare = new TDReadAuditPrepare();
TDReadAuditLogger readAuditLogger = new TDReadAuditLogger(true);
TDReadAuditLogger readAuditLogger = new TDReadAuditLogger();
SpiEbeanServer server;
Database server;
Long id1;
Long id2;
@Before
public void setup() {
server = getServer();
server = createServer();
EBasicChangeLog bean = new EBasicChangeLog();
bean.setName("readAudito1");
@@ -63,7 +63,7 @@ public class TestReadAudit extends BaseTestCase {
@After
public void shutdown() {
server.shutdown(true, false);
server.shutdown();
}
@Test
@@ -304,9 +304,9 @@ public class TestReadAudit extends BaseTestCase {
assertThat(readAuditLogger.many).hasSize(2);
}
private SpiEbeanServer getServer() {
private Database createServer() {
ServerConfig config = new ServerConfig();
DatabaseConfig config = new DatabaseConfig();
config.setName("h2other");
config.loadFromProperties();
@@ -323,7 +323,7 @@ public class TestReadAudit extends BaseTestCase {
config.setReadAuditLogger(readAuditLogger);
config.setReadAuditPrepare(readAuditPrepare);
return (SpiEbeanServer) EbeanServerFactory.create(config);
return DatabaseFactory.create(config);
}
private void resetCounters() {
@@ -331,13 +331,10 @@ public class TestReadAudit extends BaseTestCase {
readAuditPrepare.resetCounters();
}
class TDReadAuditPrepare implements ReadAuditPrepare {
static class TDReadAuditPrepare implements ReadAuditPrepare {
int count;
TDReadAuditPrepare(boolean dummy) {
}
void resetCounters() {
count = 0;
}
@@ -351,15 +348,12 @@ public class TestReadAudit extends BaseTestCase {
}
}
class TDReadAuditLogger implements ReadAuditLogger {
static class TDReadAuditLogger implements ReadAuditLogger {
Set<ReadAuditQueryPlan> plans = new HashSet<>();
List<ReadEvent> beans = new ArrayList<>();
List<ReadEvent> many = new ArrayList<>();
TDReadAuditLogger(boolean dummy) {
}
void resetCounters() {
plans.clear();
beans.clear();
@@ -72,21 +72,21 @@ datasource.db.databaseDriver=org.h2.Driver
datasource.h2.username=sa
datasource.h2.password=
datasource.h2.url=jdbc:h2:mem:tests
datasource.h2.url=jdbc:h2:mem:testsMem;DB_CLOSE_ON_EXIT=FALSE
datasource.h2.poolListener=org.tests.basic.MyTestDataSourcePoolListener
#datasource.h2.minConnections=1
#datasource.h2.maxConnections=25
#datasource.h2.capturestacktrace=true
#datasource.h2.maxStackTraceSize=20
#datasource.h2.driver=org.h2.Driver
datasource.h2.minConnections=1
datasource.h2.maxConnections=25
#datasource.h2.heartbeatsql=select 1
#datasource.h2.isolationlevel=read_committed
#datasource.h2.capturestacktrace=true
datasource.h2.maxStackTraceSize=20
datasource.h2.poolListener=org.tests.basic.MyTestDataSourcePoolListener
#datasource.h2.customProperties=IGNORECASE=TRUE;MODE=Oracle;
datasource.h2multitenant.username=sa
datasource.h2multitenant.password=
datasource.h2multitenant.url=jdbc:h2:mem:h2multitenant;DB_CLOSE_ON_EXIT=FALSE
datasource.h2multitenant.url=jdbc:h2:mem:h2multitenant
datasource.h2autocommit.autoCommit=true
datasource.h2autocommit.username=sa
@@ -100,11 +100,11 @@ datasource.h2autocommit2.url=jdbc:h2:mem:autocommit2tests
datasource.h2other.username=sa
datasource.h2other.password=
datasource.h2other.url=jdbc:h2:mem:h2other;DB_CLOSE_ON_EXIT=FALSE
datasource.h2other.url=jdbc:h2:mem:h2other
datasource.h2otherfind.username=sa
datasource.h2otherfind.password=
datasource.h2otherfind.url=jdbc:h2:mem:h2otherfind;DB_CLOSE_ON_EXIT=FALSE
datasource.h2otherfind.url=jdbc:h2:mem:h2otherfind
datasource.h2ebasicver.username=sa
datasource.h2ebasicver.password=
@@ -4,17 +4,33 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>12.5.2-SNAPSHOT</version>
<version>12.6.0</version>
</parent>
<artifactId>ebean-ddlgen</artifactId>
<name>ebean ddl generation</name>
<description>DDL and DB Migration generation</description>
<artifactId>ebean-ddl-generator</artifactId>
<!-- <version>12.5.2A</version>-->
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-runner</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>12.2.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>${project.version}</version>
<version>12.6.0</version>
<scope>provided</scope>
</dependency>
<!-- needed for java 11+ -->
@@ -33,6 +49,13 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
@@ -22,16 +22,41 @@ import java.util.ServiceLoader;
*
* <pre>{@code
*
* // optionally specify the version and name
* //System.setProperty("ddl.migration.version", "1.1");
* //System.setProperty("ddl.migration.name", "add bars");
* DbMigration migration = DbMigration.create();
*
* // generate a migration using drops from a prior version
* //System.setProperty("ddl.migration.pendingDropsFor", "1.2");
* migration.setPlatform(Platform.POSTGRES);
*
* // optionally specify the version and name
* migration.setName("add indexes to customer");
*
* migration.generateMigration();
*
* }</pre>
*
* <p>
* Drop column migrations are effectively breaking changes and should
* be held back and run in a later migration after the columns deleted
* are no longer being used by the application. These changes are called
* "pending drops" and we must explicitly specify to include these in
* a generated migration.
* </p>
* <p>
* Use <code>setGeneratePendingDrop()</code> to specify a prior migration
* that has drop column changes that we want to generate a migration for.
* </p>
*
* <h3>Example: Generate for pending drops</h3>
*
* <pre>{@code
*
* DbMigration migration = DbMigration.create();
*
* migration.setPlatform(Platform.POSTGRES);
*
* // set the migration version that has pending drops
* migration.setGeneratePendingDrop("1.3");
*
* // generates the migration with drop column changes
* migration.generateMigration();
*
* }</pre>
@@ -207,6 +232,23 @@ public interface DbMigration {
*
* }</pre>
* <p>
*
* <h3>Example: Generate for "pending drops" (drop column changes)</h3>
*
* <pre>{@code
*
* DbMigration migration = DbMigration.create();
*
* migration.setPlatform(Platform.POSTGRES);
*
* // set the migration version that has pending drops
* migration.setGeneratePendingDrop("1.3");
*
* // generates the migration with drop column changes
* migration.generateMigration();
*
* }</pre>
*
* <h3>Example: Run migration generating DDL for multiple platforms</h3>
* <pre>{@code
*
@@ -2,10 +2,9 @@ package io.ebeaninternal.dbmigration;
import io.ebean.annotation.Platform;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.DbMigrationConfig;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebean.migration.ddl.DdlRunner;
import io.ebean.migration.runner.ScriptTransform;
import io.ebean.ddlrunner.DdlRunner;
import io.ebean.ddlrunner.ScriptTransform;
import io.ebean.util.JdbcClose;
import io.ebeaninternal.api.SpiDdlGenerator;
import io.ebeaninternal.api.SpiEbeanServer;
@@ -76,7 +75,7 @@ public class DdlGenerator implements SpiDdlGenerator {
this.runDdl = config.isDdlRun();
this.ddlAutoCommit = databasePlatform.isDdlAutoCommit();
}
this.scriptTransform = createScriptTransform(config.getMigrationConfig());
this.scriptTransform = createScriptTransform(config);
this.baseDir = initBaseDir();
}
@@ -142,7 +141,7 @@ public class DdlGenerator implements SpiDdlGenerator {
private Connection obtainConnection() {
try {
return server.getPluginApi().getDataSource().getConnection();
return server.getDataSource().getConnection();
} catch (SQLException e) {
throw new PersistenceException("Failed to obtain connection to run DDL", e);
}
@@ -366,8 +365,8 @@ public class DdlGenerator implements SpiDdlGenerator {
/**
* Create the ScriptTransform for placeholder key/value replacement.
*/
private ScriptTransform createScriptTransform(DbMigrationConfig config) {
return ScriptTransform.build(config.getRunPlaceholders(), config.getRunPlaceholderMap());
private ScriptTransform createScriptTransform(DatabaseConfig config) {
return ScriptTransform.build(config.getDdlPlaceholders(), config.getDdlPlaceholderMap());
}
}
@@ -6,8 +6,8 @@ import io.ebean.EbeanServer;
import io.ebean.annotation.Platform;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.DbConstraintNaming;
import io.ebean.config.DbMigrationConfig;
import io.ebean.config.PlatformConfig;
import io.ebean.config.PropertiesWrapper;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebean.config.dbplatform.clickhouse.ClickHousePlatform;
import io.ebean.config.dbplatform.cockroach.CockroachPlatform;
@@ -28,7 +28,6 @@ import io.ebean.config.dbplatform.sqlite.SQLitePlatform;
import io.ebean.config.dbplatform.sqlserver.SqlServer16Platform;
import io.ebean.config.dbplatform.sqlserver.SqlServer17Platform;
import io.ebean.dbmigration.DbMigration;
import io.ebean.migration.MigrationVersion;
import io.ebeaninternal.api.DbOffline;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlOptions;
@@ -52,6 +51,7 @@ 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;
@@ -93,11 +93,12 @@ public class DefaultDbMigration implements DbMigration {
protected SpiEbeanServer server;
protected DbMigrationConfig migrationConfig;
protected String pathToResources = "src/main/resources";
protected String migrationPath;
protected String migrationPath = "dbmigration";
protected String migrationInitPath = "dbinit";
protected String modelPath = "model";
protected String modelSuffix = ".model.xml";
protected DatabasePlatform databasePlatform;
@@ -112,7 +113,7 @@ public class DefaultDbMigration implements DbMigration {
protected Boolean strictMode;
protected Boolean includeGeneratedFileComment;
protected String header;
protected String applyPrefix;
protected String applyPrefix = "";
protected String version;
protected String name;
protected String generatePendingDrop;
@@ -169,12 +170,17 @@ public class DefaultDbMigration implements DbMigration {
if (this.databaseConfig == null) {
this.databaseConfig = config;
}
if (migrationConfig == null) {
this.migrationConfig = databaseConfig.getMigrationConfig();
}
if (constraintNaming == null) {
this.constraintNaming = databaseConfig.getConstraintNaming();
}
Properties properties = config.getProperties();
if (properties != null) {
PropertiesWrapper props = new PropertiesWrapper("ebean", config.getName(), properties, null);
migrationPath = props.get("migration.migrationPath", migrationPath);
migrationInitPath = props.get("migration.migrationInitPath", migrationInitPath);
pathToResources = props.get("migration.pathToResources", pathToResources);
}
}
@Override
@@ -466,7 +472,7 @@ public class DefaultDbMigration implements DbMigration {
sb.append("R__");
}
sb.append(scriptName.replace(' ', '_'));
sb.append(migrationConfig.getApplySuffix());
sb.append(".sql");
return sb.toString();
}
@@ -529,7 +535,7 @@ public class DefaultDbMigration implements DbMigration {
this.migrated = new ModelContainer();
} else {
this.modelDir = getModelDirectory(migrationDir);
MigrationModel migrationModel = new MigrationModel(modelDir, migrationConfig.getModelSuffix());
MigrationModel migrationModel = new MigrationModel(modelDir, modelSuffix);
this.migrated = migrationModel.read(dbinitMigration);
}
}
@@ -605,7 +611,6 @@ public class DefaultDbMigration implements DbMigration {
* Return true if the next pending drop changeSet should be generated as the next migration.
*/
private String generatePendingDrop() {
String nextDrop = System.getProperty("ddl.migration.pendingDropsFor");
if (nextDrop != null) {
return nextDrop;
@@ -625,13 +630,13 @@ public class DefaultDbMigration implements DbMigration {
version = (nextVersion != null) ? nextVersion : initialVersion;
}
String fullVersion = migrationConfig.getApplyPrefix() + version;
String fullVersion = applyPrefix + version;
String name = getName();
if (name != null) {
fullVersion += "__" + toUnderScore(name);
} else if (dropsFor != null) {
fullVersion += "__" + toUnderScore("dropsFor_" + MigrationVersion.trim(dropsFor));
fullVersion += "__" + toUnderScore("dropsFor_" + trimDropsFor(dropsFor));
} else if (version.equals(initialVersion)) {
fullVersion += "__initial";
@@ -639,6 +644,18 @@ public class DefaultDbMigration implements DbMigration {
return fullVersion;
}
String trimDropsFor(String dropsFor) {
if (dropsFor.startsWith("V") || dropsFor.startsWith("v")) {
dropsFor = dropsFor.substring(1);
}
int commentStart = dropsFor.indexOf("__");
if (commentStart > -1) {
// trim off the trailing comment
dropsFor = dropsFor.substring(0, commentStart);
}
return dropsFor;
}
/**
* Replace spaces with underscores.
*/
@@ -650,7 +667,6 @@ public class DefaultDbMigration implements DbMigration {
* Write any extra platform ddl.
*/
private void writeExtraPlatformDdl(String fullVersion, CurrentModel currentModel, Migration dbMigration, File writePath) throws IOException {
DdlOptions options = new DdlOptions(addForeignKeySkipCheck);
for (Pair pair : platforms) {
DdlWrite platformBuffer = new DdlWrite(new MConfiguration(), currentModel.read(), options);
@@ -661,15 +677,14 @@ public class DefaultDbMigration implements DbMigration {
}
private PlatformDdlWriter createDdlWriter(DatabasePlatform platform) {
return new PlatformDdlWriter(platform, databaseConfig, migrationConfig, lockTimeoutSeconds);
return new PlatformDdlWriter(platform, databaseConfig, lockTimeoutSeconds);
}
/**
* Write the migration xml.
*/
private boolean writeMigrationXml(Migration dbMigration, File resourcePath, String fullVersion) {
String modelFile = fullVersion + migrationConfig.getModelSuffix();
String modelFile = fullVersion + modelSuffix;
File file = new File(resourcePath, modelFile);
if (file.exists()) {
return false;
@@ -691,18 +706,12 @@ public class DefaultDbMigration implements DbMigration {
// not explicitly set so use the platform of the server
databasePlatform = server.getDatabasePlatform();
}
if (migrationConfig != null) {
if (databaseConfig != null) {
if (strictMode != null) {
migrationConfig.setStrictMode(strictMode);
}
if (applyPrefix != null) {
migrationConfig.setApplyPrefix(applyPrefix);
}
if (migrationPath != null) {
migrationConfig.setMigrationPath(migrationPath);
databaseConfig.setDdlStrictMode(strictMode);
}
if (header != null) {
migrationConfig.setDdlHeader(header);
databaseConfig.setDdlHeader(header);
}
}
}
@@ -756,7 +765,6 @@ public class DefaultDbMigration implements DbMigration {
* Return the system or environment property.
*/
private String readEnvironment(String key) {
String val = System.getProperty(key);
if (val == null) {
val = System.getenv(key);
@@ -782,7 +790,7 @@ public class DefaultDbMigration implements DbMigration {
String msg = String.format("Error - path to resources %s does not exist. Absolute path is %s", pathToResources, resourceRootDir.getAbsolutePath());
throw new UnknownResourcePathException(msg);
}
String resourcePath = migrationConfig.getMigrationPath(dbinitMigration);
String resourcePath = getMigrationPath(dbinitMigration);
// expect to be a path to something like - src/main/resources/dbmigration/model
File path = new File(resourceRootDir, resourcePath);
@@ -794,15 +802,18 @@ public class DefaultDbMigration implements DbMigration {
return path;
}
private String getMigrationPath(boolean dbinitMigration) {
return dbinitMigration ? migrationInitPath : migrationPath;
}
/**
* Return the model directory (relative to the migration directory).
*/
private File getModelDirectory(File migrationDirectory) {
String modelPath = migrationConfig.getModelPath();
if (modelPath == null || modelPath.isEmpty()) {
return migrationDirectory;
}
File modelDir = new File(migrationDirectory, migrationConfig.getModelPath());
File modelDir = new File(migrationDirectory, modelPath);
if (!modelDir.exists() && !modelDir.mkdirs()) {
logInfo("Warning - Unable to ensure migration model directory exists at %s", modelDir.getAbsolutePath());
}
@@ -208,7 +208,7 @@ public class BaseTableDdl implements TableDdl {
this.historyTableSuffix = config.getHistoryTableSuffix();
this.platformDdl = platformDdl;
this.platformDdl.configure(config);
this.strictMode = config.getMigrationConfig().isStrictMode();
this.strictMode = config.isDdlStrictMode();
DbHistorySupport hist = platformDdl.getPlatform().getHistorySupport();
if (hist == null) {
this.historySupport = HistorySupport.NONE;

Some files were not shown because too many files have changed in this diff Show More