From 7a6071ac9aefd7564b86f71a100fe6e638de260e Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 27 Jan 2022 09:20:23 +1300 Subject: [PATCH 01/15] Support jedis 4.1.0 client (ScanParams, ScanResult in different package now) --- ebean-redis/pom.xml | 2 +- ebean-redis/src/main/java/io/ebean/redis/RedisCache.java | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ebean-redis/pom.xml b/ebean-redis/pom.xml index f33064c74..125a68c32 100644 --- a/ebean-redis/pom.xml +++ b/ebean-redis/pom.xml @@ -16,7 +16,7 @@ redis.clients jedis - 3.8.0 + 4.1.0 diff --git a/ebean-redis/src/main/java/io/ebean/redis/RedisCache.java b/ebean-redis/src/main/java/io/ebean/redis/RedisCache.java index 39dfec865..a9ce387f1 100644 --- a/ebean-redis/src/main/java/io/ebean/redis/RedisCache.java +++ b/ebean-redis/src/main/java/io/ebean/redis/RedisCache.java @@ -14,7 +14,9 @@ import io.ebean.redis.encode.EncodePrefixKey; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import redis.clients.jedis.*; +import redis.clients.jedis.params.ScanParams; import redis.clients.jedis.params.SetParams; +import redis.clients.jedis.resps.ScanResult; import redis.clients.jedis.util.SafeEncoder; import java.util.*; From 48c8f5e2caddb9d9a363f241ce112a073f9e415e Mon Sep 17 00:00:00 2001 From: Roland Praml Date: Thu, 27 Jan 2022 10:09:31 +0100 Subject: [PATCH 02/15] ADD: different DB2 platforms --- ...{DB2Platform.java => BaseDB2Platform.java} | 8 +--- .../dbplatform/db2/DB2ForIPlatform.java | 40 +++++++++++++++++++ .../dbplatform/db2/DB2LegacyPlatform.java | 20 ++++++++++ .../config/dbplatform/db2/DB2LuwPlatform.java | 17 ++++++++ .../config/dbplatform/db2/DB2ZosPlatform.java | 18 +++++++++ .../server/core/DatabasePlatformFactory.java | 21 ++++++++-- ebean-test/testconfig/ebean-db2.properties | 1 + 7 files changed, 116 insertions(+), 9 deletions(-) rename ebean-api/src/main/java/io/ebean/config/dbplatform/db2/{DB2Platform.java => BaseDB2Platform.java} (88%) create mode 100644 ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2ForIPlatform.java create mode 100644 ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2LegacyPlatform.java create mode 100644 ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2LuwPlatform.java create mode 100644 ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2ZosPlatform.java diff --git a/ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2Platform.java b/ebean-api/src/main/java/io/ebean/config/dbplatform/db2/BaseDB2Platform.java similarity index 88% rename from ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2Platform.java rename to ebean-api/src/main/java/io/ebean/config/dbplatform/db2/BaseDB2Platform.java index 5f2e44df9..fb4fff30a 100644 --- a/ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2Platform.java +++ b/ebean-api/src/main/java/io/ebean/config/dbplatform/db2/BaseDB2Platform.java @@ -15,15 +15,11 @@ import java.sql.Types; /** * DB2 specific platform. */ -public class DB2Platform extends DatabasePlatform { +public abstract class BaseDB2Platform extends DatabasePlatform { - public DB2Platform() { + public BaseDB2Platform() { super(); this.platform = Platform.DB2; - // Note: DB2 (at least LUW supports length up to 128) - // TOOD: Check if we need to introduce a new platform (DB2_LUW_11 ?) - this.maxTableNameLength = 18; - this.maxConstraintNameLength = 18; this.supportsNativeJavaTime = false; this.truncateTable = "truncate table %s reuse storage ignore delete triggers immediate"; this.sqlLimiter = new Db2SqlLimiter(); diff --git a/ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2ForIPlatform.java b/ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2ForIPlatform.java new file mode 100644 index 000000000..8271063bb --- /dev/null +++ b/ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2ForIPlatform.java @@ -0,0 +1,40 @@ +package io.ebean.config.dbplatform.db2; + +import io.ebean.annotation.PersistBatch; +import io.ebean.annotation.Platform; +import io.ebean.config.dbplatform.DbPlatformType; +import io.ebean.config.dbplatform.DbType; +import io.ebean.config.dbplatform.SqlErrorCodes; + +import java.sql.Types; + +/** + * DB2 specific platform for i Series. + * @author Cédric Sougné + */ +public class DB2ForIPlatform extends BaseDB2Platform { + + public DB2ForIPlatform() { + super(); + this.platform = Platform.DB2; + // Note: IBM i from 7.1 allow up to to 128 + // TODO: Check if we need to introduce older platform (DB2ForI_6 ? but older documentation is not anymore published on ibm.com), + this.maxTableNameLength = 128; + this.maxConstraintNameLength = 128; + + this.dbIdentity.setSupportsIdentity(true); + + this.exceptionTranslator = + new SqlErrorCodes() + .addAcquireLock("57033") // key -913 + .addDuplicateKey("23505") // -803 + // .addDataIntegrity("-407","-530","-531","-532","-543","-544","-545","-603","-667") + // we need SQLState, not code: https://www.ibm.com/support/knowledgecenter/en/SSEPEK_10.0.0/codes/src/tpc/db2z_n.html + .addDataIntegrity("23502","23503","23504","23507","23511","23512","23513","42917","23515") + .build(); + + booleanDbType = Types.SMALLINT; + dbTypeMap.put(DbType.BOOLEAN, new DbPlatformType("smallint default 0")); + } + +} \ No newline at end of file diff --git a/ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2LegacyPlatform.java b/ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2LegacyPlatform.java new file mode 100644 index 000000000..51f03c2a4 --- /dev/null +++ b/ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2LegacyPlatform.java @@ -0,0 +1,20 @@ +package io.ebean.config.dbplatform.db2; + +import io.ebean.annotation.Platform; + +/** + * DB2 specific platform for older DB2 versions. This platform is here for + * compatibility reasons. It uses a length limit of 18 chars for table and + * constraint names. Newer DB2 versions will support up to 128. It is strongly + * recommended to migrate to db2luw/DB2ForI or db2zos platform. + */ +public class DB2LegacyPlatform extends BaseDB2Platform { + public DB2LegacyPlatform() { + super(); + this.platform = Platform.DB2; + // Note: DB2 (at least LUW supports length up to 128) + // TOOD: Check if we need to introduce a new platform (DB2_LUW_11 ?) + this.maxTableNameLength = 18; + this.maxConstraintNameLength = 18; + } +} diff --git a/ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2LuwPlatform.java b/ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2LuwPlatform.java new file mode 100644 index 000000000..e1268f3d0 --- /dev/null +++ b/ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2LuwPlatform.java @@ -0,0 +1,17 @@ +package io.ebean.config.dbplatform.db2; + +import io.ebean.annotation.Platform; + +/** + * DB2 platform for Linux/Unix/Windows. + * @author Roland Praml, FOCONIS AG + * + */ +public class DB2LuwPlatform extends BaseDB2Platform { + public DB2LuwPlatform() { + super(); + this.platform = Platform.DB2; // TODO DB2LUW + this.maxTableNameLength = 128; + this.maxConstraintNameLength = 128; + } +} diff --git a/ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2ZosPlatform.java b/ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2ZosPlatform.java new file mode 100644 index 000000000..10cf70f8f --- /dev/null +++ b/ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2ZosPlatform.java @@ -0,0 +1,18 @@ +package io.ebean.config.dbplatform.db2; + +import io.ebean.annotation.Platform; + +/** + * DB2 platform for z/OS. + * Note: This platform is currently not tested! + * @author Roland Praml, FOCONIS AG + * + */ +public class DB2ZosPlatform extends BaseDB2Platform { + public DB2ZosPlatform() { + super(); + this.platform = Platform.DB2; // TODO DB2ZOS + this.maxTableNameLength = 128; + this.maxConstraintNameLength = 128; + } +} diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DatabasePlatformFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DatabasePlatformFactory.java index 96600609a..8a89db102 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DatabasePlatformFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DatabasePlatformFactory.java @@ -4,7 +4,10 @@ import io.ebean.config.DatabaseConfig; import io.ebean.config.dbplatform.DatabasePlatform; import io.ebean.config.dbplatform.clickhouse.ClickHousePlatform; import io.ebean.config.dbplatform.cockroach.CockroachPlatform; -import io.ebean.config.dbplatform.db2.DB2Platform; +import io.ebean.config.dbplatform.db2.DB2ForIPlatform; +import io.ebean.config.dbplatform.db2.DB2LegacyPlatform; +import io.ebean.config.dbplatform.db2.DB2LuwPlatform; +import io.ebean.config.dbplatform.db2.DB2ZosPlatform; import io.ebean.config.dbplatform.h2.H2Platform; import io.ebean.config.dbplatform.hana.HanaPlatform; import io.ebean.config.dbplatform.hsqldb.HsqldbPlatform; @@ -103,7 +106,19 @@ public class DatabasePlatformFactory { return new SqlAnywherePlatform(); } if (dbName.equals("db2")) { - return new DB2Platform(); + throw new IllegalArgumentException("Please choose the more specific db2luw/db2zos/db2fori platform. Refer to issue #xxxx for details"); + } + if (dbName.equals("db2legacy")) { + return new DB2LegacyPlatform(); + } + if (dbName.equals("db2zos")) { + return new DB2ZosPlatform(); + } + if (dbName.equals("db2fori")) { + return new DB2ForIPlatform(); + } + if (dbName.equals("db2luw")) { + return new DB2LuwPlatform(); } if (dbName.equals("clickhouse")) { return new ClickHousePlatform(); @@ -159,7 +174,7 @@ public class DatabasePlatformFactory { } else if (dbProductName.contains("sqlite")) { return new SQLitePlatform(); } else if (dbProductName.contains("db2")) { - return new DB2Platform(); + throw new IllegalArgumentException("For DB2 please explicitly choose either db2legacy/db2luw/db2zos/db2fori platform. Refer to issue #xxxx for details"); } else if (dbProductName.contains("sql anywhere")) { return new SqlAnywherePlatform(); } else if (dbProductName.contains("hdb")) { diff --git a/ebean-test/testconfig/ebean-db2.properties b/ebean-test/testconfig/ebean-db2.properties index 2aa2944dd..9f62e2389 100644 --- a/ebean-test/testconfig/ebean-db2.properties +++ b/ebean-test/testconfig/ebean-db2.properties @@ -2,3 +2,4 @@ ebean.test.platform=db2 ebean.test.dbName=unit ebean.test.dbPassword=unit datasource.default=db2-11 +ebean.db2-11.databasePlatformName=db2luw \ No newline at end of file From d8c2b3d583fd50bd4fbf046148c522c84db92df5 Mon Sep 17 00:00:00 2001 From: Roland Praml Date: Thu, 27 Jan 2022 10:34:25 +0100 Subject: [PATCH 03/15] FIX: Compile errors --- ebean-api/pom.xml | 2 +- .../config/dbplatform/db2/DB2ForIPlatform.java | 2 +- .../config/dbplatform/db2/DB2LuwPlatform.java | 2 +- .../config/dbplatform/db2/DB2ZosPlatform.java | 2 +- .../dbmigration/DefaultDbMigration.java | 14 ++++++++++++-- 5 files changed, 16 insertions(+), 6 deletions(-) diff --git a/ebean-api/pom.xml b/ebean-api/pom.xml index d11bb71f6..52e1f7c3f 100644 --- a/ebean-api/pom.xml +++ b/ebean-api/pom.xml @@ -49,7 +49,7 @@ io.ebean ebean-annotation - 7.3 + 7.5-SNAPSHOT diff --git a/ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2ForIPlatform.java b/ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2ForIPlatform.java index 8271063bb..4e3db3ca5 100644 --- a/ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2ForIPlatform.java +++ b/ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2ForIPlatform.java @@ -16,7 +16,7 @@ public class DB2ForIPlatform extends BaseDB2Platform { public DB2ForIPlatform() { super(); - this.platform = Platform.DB2; + this.platform = Platform.DB2FORI; // Note: IBM i from 7.1 allow up to to 128 // TODO: Check if we need to introduce older platform (DB2ForI_6 ? but older documentation is not anymore published on ibm.com), this.maxTableNameLength = 128; diff --git a/ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2LuwPlatform.java b/ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2LuwPlatform.java index e1268f3d0..967cc2428 100644 --- a/ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2LuwPlatform.java +++ b/ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2LuwPlatform.java @@ -10,7 +10,7 @@ import io.ebean.annotation.Platform; public class DB2LuwPlatform extends BaseDB2Platform { public DB2LuwPlatform() { super(); - this.platform = Platform.DB2; // TODO DB2LUW + this.platform = Platform.DB2LUW; this.maxTableNameLength = 128; this.maxConstraintNameLength = 128; } diff --git a/ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2ZosPlatform.java b/ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2ZosPlatform.java index 10cf70f8f..2cb4cb35b 100644 --- a/ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2ZosPlatform.java +++ b/ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2ZosPlatform.java @@ -11,7 +11,7 @@ import io.ebean.annotation.Platform; public class DB2ZosPlatform extends BaseDB2Platform { public DB2ZosPlatform() { super(); - this.platform = Platform.DB2; // TODO DB2ZOS + this.platform = Platform.DB2ZOS; this.maxTableNameLength = 128; this.maxConstraintNameLength = 128; } diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java index 4add6fe13..f8c4855a8 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java @@ -24,7 +24,10 @@ 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; -import io.ebean.config.dbplatform.db2.DB2Platform; +import io.ebean.config.dbplatform.db2.DB2ForIPlatform; +import io.ebean.config.dbplatform.db2.DB2LegacyPlatform; +import io.ebean.config.dbplatform.db2.DB2LuwPlatform; +import io.ebean.config.dbplatform.db2.DB2ZosPlatform; import io.ebean.config.dbplatform.h2.H2Platform; import io.ebean.config.dbplatform.hana.HanaPlatform; import io.ebean.config.dbplatform.hsqldb.HsqldbPlatform; @@ -831,7 +834,14 @@ public class DefaultDbMigration implements DbMigration { case SQLSERVER: throw new IllegalArgumentException("Please choose the more specific SQLSERVER16 or SQLSERVER17 platform. Refer to issue #1340 for details"); case DB2: - return new DB2Platform(); + logger.warn("Using DB2LegacyPlatform. It is recommended to migrate to db2luw/db2zos/db2fori. Refer to issue #xxxx for details"); + return new DB2LegacyPlatform(); + case DB2LUW: + return new DB2LuwPlatform(); + case DB2ZOS: + return new DB2ZosPlatform(); + case DB2FORI: + return new DB2ForIPlatform(); case SQLITE: return new SQLitePlatform(); case HANA: From 190b4ef588ddb9e954fa6f19c01372366850881a Mon Sep 17 00:00:00 2001 From: Roland Praml Date: Thu, 27 Jan 2022 15:58:44 +0100 Subject: [PATCH 04/15] Made some fixes in wrong ddl generation --- ebean-api/pom.xml | 2 +- .../ddlgeneration/PlatformDdlBuilder.java | 3 +++ .../dbmigration/ddlgeneration/platform/DB2Ddl.java | 2 ++ .../resources/dbmigration/migrationtest/db2/1.1.sql | 12 ++++++------ .../resources/dbmigration/migrationtest/db2/1.3.sql | 10 +++++----- .../dbmigration/migrationtest/db2/idx_db2.migrations | 4 ++-- 6 files changed, 19 insertions(+), 14 deletions(-) diff --git a/ebean-api/pom.xml b/ebean-api/pom.xml index 52e1f7c3f..15021541b 100644 --- a/ebean-api/pom.xml +++ b/ebean-api/pom.xml @@ -49,7 +49,7 @@ io.ebean ebean-annotation - 7.5-SNAPSHOT + 7.5 diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/PlatformDdlBuilder.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/PlatformDdlBuilder.java index 08d4e3b40..0133413e0 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/PlatformDdlBuilder.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/PlatformDdlBuilder.java @@ -31,6 +31,9 @@ public class PlatformDdlBuilder { case H2: return new H2Ddl(platform); case DB2: + case DB2LUW: + case DB2FORI: + case DB2ZOS: return new DB2Ddl(platform); case MARIADB: return new MariaDbDdl(platform); diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/DB2Ddl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/DB2Ddl.java index d3cf92028..7ee9e1c30 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/DB2Ddl.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/DB2Ddl.java @@ -15,6 +15,8 @@ public class DB2Ddl extends PlatformDdl { this.dropConstraintIfExists = "drop constraint"; this.dropIndexIfExists = "drop index "; this.identitySuffix = " generated by default as identity"; + this.columnSetNull = "drop not null"; + this.columnSetType = "set data type "; this.inlineUniqueWhenNullable = false; } diff --git a/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/db2/1.1.sql b/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/db2/1.1.sql index 605a24af3..3d7f846c7 100644 --- a/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/db2/1.1.sql +++ b/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/db2/1.1.sql @@ -36,16 +36,16 @@ alter table migtest_e_basic alter column status set default 'A'; alter table migtest_e_basic alter column status set not null; alter table migtest_e_basic add constraint ck_mgtst__bsc_stts check ( status in ('N','A','I','?')); alter table migtest_e_basic drop constraint ck_mgtst__b_z543fg; -alter table migtest_e_basic alter column status2 varchar(127); +alter table migtest_e_basic alter column status2 set data type varchar(127); alter table migtest_e_basic alter column status2 drop default; -alter table migtest_e_basic alter column status2 set null; +alter table migtest_e_basic alter column status2 drop not null; -- rename all collisions; -- NOT SUPPORTED alter table migtest_e_basic add constraint uq_mgtst__b_vs45xo unique (description); insert into migtest_e_user (id) select distinct user_id from migtest_e_basic; alter table migtest_e_basic add constraint fk_mgtst__bsc_sr_d foreign key (user_id) references migtest_e_user (id) on delete restrict; -alter table migtest_e_basic alter column user_id set null; +alter table migtest_e_basic alter column user_id drop not null; alter table migtest_e_basic add column new_string_field varchar(255) default 'foo''bar' not null; alter table migtest_e_basic add column new_boolean_field boolean default true not null; update migtest_e_basic set new_boolean_field = old_boolean; @@ -63,7 +63,7 @@ alter table migtest_e_basic drop constraint uq_mgtst__b_4ayc02; -- NOT SUPPORTED alter table migtest_e_basic add constraint uq_mgtst__b_4ayc01 unique (indextest5); alter table migtest_e_enum drop constraint ck_mgtst__n_773sok; comment on column migtest_e_history.test_string is 'Column altered to long now'; -alter table migtest_e_history alter column test_string bigint; +alter table migtest_e_history alter column test_string set data type bigint; comment on table migtest_e_history is 'We have history now'; -- NOTE: table has @History - special migration may be necessary @@ -74,7 +74,7 @@ alter table migtest_e_history2 add column test_string2 varchar(255); alter table migtest_e_history2 add column test_string3 varchar(255) default 'unknown' not null; alter table migtest_e_history2 add column new_column varchar(20); -alter table migtest_e_history4 alter column test_number bigint; +alter table migtest_e_history4 alter column test_number set data type bigint; alter table migtest_e_history5 add column test_boolean boolean default false not null; @@ -82,7 +82,7 @@ alter table migtest_e_history5 add column test_boolean boolean default false not update migtest_e_history6 set test_number1 = 42 where test_number1 is null; alter table migtest_e_history6 alter column test_number1 set default 42; alter table migtest_e_history6 alter column test_number1 set not null; -alter table migtest_e_history6 alter column test_number2 set null; +alter table migtest_e_history6 alter column test_number2 drop not null; alter table migtest_e_softdelete add column deleted boolean default false not null; alter table migtest_oto_child add column master_id bigint; diff --git a/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/db2/1.3.sql b/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/db2/1.3.sql index 9489c8d98..47fc898ae 100644 --- a/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/db2/1.3.sql +++ b/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/db2/1.3.sql @@ -16,12 +16,12 @@ alter table migtest_fk_set_null drop constraint fk_mgtst_fk_wicx8x; alter table migtest_fk_set_null add constraint fk_mgtst_fk_wicx8x foreign key (one_id) references migtest_fk_one (id) on delete set null; alter table migtest_e_basic drop constraint ck_mgtst__bsc_stts; alter table migtest_e_basic alter column status drop default; -alter table migtest_e_basic alter column status set null; +alter table migtest_e_basic alter column status drop not null; alter table migtest_e_basic add constraint ck_mgtst__bsc_stts check ( status in ('N','A','I')); update migtest_e_basic set status2 = 'N' where status2 is null; alter table migtest_e_basic drop constraint ck_mgtst__b_z543fg; -alter table migtest_e_basic alter column status2 varchar(1); +alter table migtest_e_basic alter column status2 set data type varchar(1); alter table migtest_e_basic alter column status2 set default 'N'; alter table migtest_e_basic alter column status2 set not null; alter table migtest_e_basic add constraint ck_mgtst__b_z543fg check ( status2 in ('N','A','I')); @@ -46,13 +46,13 @@ alter table migtest_e_enum add constraint ck_mgtst__n_773sok check ( test_status comment on column migtest_e_history.test_string is ''; comment on table migtest_e_history is ''; alter table migtest_e_history2 alter column test_string drop default; -alter table migtest_e_history2 alter column test_string set null; +alter table migtest_e_history2 alter column test_string drop not null; alter table migtest_e_history2 add column obsolete_string1 varchar(255); alter table migtest_e_history2 add column obsolete_string2 varchar(255); -alter table migtest_e_history4 alter column test_number integer; +alter table migtest_e_history4 alter column test_number set data type integer; alter table migtest_e_history6 alter column test_number1 drop default; -alter table migtest_e_history6 alter column test_number1 set null; +alter table migtest_e_history6 alter column test_number1 drop not null; -- NOTE: table has @History - special migration may be necessary update migtest_e_history6 set test_number2 = 7 where test_number2 is null; diff --git a/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/db2/idx_db2.migrations b/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/db2/idx_db2.migrations index ec4208068..9c74dc16e 100644 --- a/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/db2/idx_db2.migrations +++ b/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/db2/idx_db2.migrations @@ -1,6 +1,6 @@ 441570368, 1.0__initial.sql --94595879, 1.1.sql +367602802, 1.1.sql 578073685, 1.2__dropsFor_1.1.sql --509420890, 1.3.sql +-478470986, 1.3.sql -1475628451, 1.4__dropsFor_1.3.sql From 3e8cc87f0197b272db39c225e50075c373941e38 Mon Sep 17 00:00:00 2001 From: Roland Praml Date: Thu, 27 Jan 2022 16:02:18 +0100 Subject: [PATCH 05/15] Add: github workflow for db2 --- .github/workflows/multi-platform-test.yml | 2 ++ ebean-test/testconfig/ebean-db2.properties | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/multi-platform-test.yml b/.github/workflows/multi-platform-test.yml index f85636c9b..d923063fe 100644 --- a/.github/workflows/multi-platform-test.yml +++ b/.github/workflows/multi-platform-test.yml @@ -43,3 +43,5 @@ jobs: run: mvn clean test -Dprops.file=testconfig/ebean-sqlserver17.properties - name: mariadb run: mvn clean test -Dprops.file=testconfig/ebean-mariadb.properties + - name: db2 + run: mvn clean test -Dprops.file=testconfig/ebean-db2.properties diff --git a/ebean-test/testconfig/ebean-db2.properties b/ebean-test/testconfig/ebean-db2.properties index 9f62e2389..40e375ef5 100644 --- a/ebean-test/testconfig/ebean-db2.properties +++ b/ebean-test/testconfig/ebean-db2.properties @@ -2,4 +2,4 @@ ebean.test.platform=db2 ebean.test.dbName=unit ebean.test.dbPassword=unit datasource.default=db2-11 -ebean.db2-11.databasePlatformName=db2luw \ No newline at end of file +ebean.db2-11.databasePlatformName=db2luw From 5b63434f132c8df821bb97eb4eec0c6919a17588 Mon Sep 17 00:00:00 2001 From: Roland Praml Date: Thu, 27 Jan 2022 16:43:35 +0100 Subject: [PATCH 06/15] reindent code and linked #2514 --- .../config/dbplatform/db2/DB2ForIPlatform.java | 17 ++++++++--------- .../server/core/DatabasePlatformFactory.java | 4 ++-- .../dbmigration/DefaultDbMigration.java | 2 +- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2ForIPlatform.java b/ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2ForIPlatform.java index 4e3db3ca5..fa6028858 100644 --- a/ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2ForIPlatform.java +++ b/ebean-api/src/main/java/io/ebean/config/dbplatform/db2/DB2ForIPlatform.java @@ -1,6 +1,5 @@ package io.ebean.config.dbplatform.db2; -import io.ebean.annotation.PersistBatch; import io.ebean.annotation.Platform; import io.ebean.config.dbplatform.DbPlatformType; import io.ebean.config.dbplatform.DbType; @@ -10,6 +9,7 @@ import java.sql.Types; /** * DB2 specific platform for i Series. + * * @author Cédric Sougné */ public class DB2ForIPlatform extends BaseDB2Platform { @@ -18,23 +18,22 @@ public class DB2ForIPlatform extends BaseDB2Platform { super(); this.platform = Platform.DB2FORI; // Note: IBM i from 7.1 allow up to to 128 - // TODO: Check if we need to introduce older platform (DB2ForI_6 ? but older documentation is not anymore published on ibm.com), + // TODO: Check if we need to introduce older platform (DB2ForI_6 ? but older + // documentation is not anymore published on ibm.com), this.maxTableNameLength = 128; this.maxConstraintNameLength = 128; this.dbIdentity.setSupportsIdentity(true); - this.exceptionTranslator = - new SqlErrorCodes() - .addAcquireLock("57033") // key -913 + this.exceptionTranslator = new SqlErrorCodes().addAcquireLock("57033") // key -913 .addDuplicateKey("23505") // -803 // .addDataIntegrity("-407","-530","-531","-532","-543","-544","-545","-603","-667") - // we need SQLState, not code: https://www.ibm.com/support/knowledgecenter/en/SSEPEK_10.0.0/codes/src/tpc/db2z_n.html - .addDataIntegrity("23502","23503","23504","23507","23511","23512","23513","42917","23515") + // we need SQLState, not code: + // https://www.ibm.com/support/knowledgecenter/en/SSEPEK_10.0.0/codes/src/tpc/db2z_n.html + .addDataIntegrity("23502", "23503", "23504", "23507", "23511", "23512", "23513", "42917", "23515") .build(); booleanDbType = Types.SMALLINT; dbTypeMap.put(DbType.BOOLEAN, new DbPlatformType("smallint default 0")); } - -} \ No newline at end of file +} diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DatabasePlatformFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DatabasePlatformFactory.java index 8a89db102..ad03fd45f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DatabasePlatformFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DatabasePlatformFactory.java @@ -106,7 +106,7 @@ public class DatabasePlatformFactory { return new SqlAnywherePlatform(); } if (dbName.equals("db2")) { - throw new IllegalArgumentException("Please choose the more specific db2luw/db2zos/db2fori platform. Refer to issue #xxxx for details"); + throw new IllegalArgumentException("Please choose the more specific db2luw/db2zos/db2fori platform. Refer to issue #2514 for details"); } if (dbName.equals("db2legacy")) { return new DB2LegacyPlatform(); @@ -174,7 +174,7 @@ public class DatabasePlatformFactory { } else if (dbProductName.contains("sqlite")) { return new SQLitePlatform(); } else if (dbProductName.contains("db2")) { - throw new IllegalArgumentException("For DB2 please explicitly choose either db2legacy/db2luw/db2zos/db2fori platform. Refer to issue #xxxx for details"); + throw new IllegalArgumentException("For DB2 please explicitly choose either db2legacy/db2luw/db2zos/db2fori platform. Refer to issue #2514 for details"); } else if (dbProductName.contains("sql anywhere")) { return new SqlAnywherePlatform(); } else if (dbProductName.contains("hdb")) { diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java index f8c4855a8..cdfa5a528 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java @@ -834,7 +834,7 @@ public class DefaultDbMigration implements DbMigration { case SQLSERVER: throw new IllegalArgumentException("Please choose the more specific SQLSERVER16 or SQLSERVER17 platform. Refer to issue #1340 for details"); case DB2: - logger.warn("Using DB2LegacyPlatform. It is recommended to migrate to db2luw/db2zos/db2fori. Refer to issue #xxxx for details"); + logger.warn("Using DB2LegacyPlatform. It is recommended to migrate to db2luw/db2zos/db2fori. Refer to issue #2514 for details"); return new DB2LegacyPlatform(); case DB2LUW: return new DB2LuwPlatform(); From 29c591620376f6574c3b7443dcca4c2c1a96ab96 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 28 Jan 2022 08:54:21 +1300 Subject: [PATCH 07/15] Add build workflow for db2 --- .github/workflows/db2luw.yml | 38 +++++++++++++++++++ .../java/org/integration/ClusterTest.java | 2 +- 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/db2luw.yml diff --git a/.github/workflows/db2luw.yml b/.github/workflows/db2luw.yml new file mode 100644 index 000000000..e63b3d00c --- /dev/null +++ b/.github/workflows/db2luw.yml @@ -0,0 +1,38 @@ + +name: Postgres + +on: + workflow_dispatch: + schedule: + - cron: '10 8 * * 2,5' + +jobs: + build: + + runs-on: ${{ matrix.os }} + permissions: + contents: read + packages: write + strategy: + fail-fast: false + matrix: + java_version: [11] + os: [ubuntu-latest] + + steps: + - uses: actions/checkout@v2 + - name: Set up Java + uses: actions/setup-java@v2 + with: + java-version: ${{ matrix.java_version }} + distribution: 'adopt' + - name: Maven cache + uses: actions/cache@v2 + env: + cache-name: maven-cache + with: + path: + ~/.m2 + key: build-${{ env.cache-name }} + - name: db2 + run: mvn clean test -Dprops.file=testconfig/ebean-db2.properties diff --git a/ebean-redis/src/test/java/org/integration/ClusterTest.java b/ebean-redis/src/test/java/org/integration/ClusterTest.java index 6a8dc32ba..64cca33b9 100644 --- a/ebean-redis/src/test/java/org/integration/ClusterTest.java +++ b/ebean-redis/src/test/java/org/integration/ClusterTest.java @@ -114,6 +114,6 @@ public class ClusterTest { } private void allowAsyncMessaging() throws InterruptedException { - Thread.sleep(50); + Thread.sleep(100); } } From dbac184b4c3ec7048cbb2d8a8b23331dfa89f6c3 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 28 Jan 2022 08:58:25 +1300 Subject: [PATCH 08/15] Rename build workflows --- .github/workflows/{mariadb-10.6.yml => mariadb.yml} | 2 +- .../{multi-platform-test.yml => multi-db-platform.yml} | 2 +- .../workflows/{sqlserver-2019-latest.yml => sqlserver-2019.yml} | 2 +- .github/workflows/{sqlserver-2017-latest.yml => sqlserver.yml} | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename .github/workflows/{mariadb-10.6.yml => mariadb.yml} (97%) rename .github/workflows/{multi-platform-test.yml => multi-db-platform.yml} (97%) rename .github/workflows/{sqlserver-2019-latest.yml => sqlserver-2019.yml} (96%) rename .github/workflows/{sqlserver-2017-latest.yml => sqlserver.yml} (96%) diff --git a/.github/workflows/mariadb-10.6.yml b/.github/workflows/mariadb.yml similarity index 97% rename from .github/workflows/mariadb-10.6.yml rename to .github/workflows/mariadb.yml index cae97ac27..b7db361cd 100644 --- a/.github/workflows/mariadb-10.6.yml +++ b/.github/workflows/mariadb.yml @@ -1,5 +1,5 @@ -name: MariaDB 10.6 +name: MariaDB on: workflow_dispatch: diff --git a/.github/workflows/multi-platform-test.yml b/.github/workflows/multi-db-platform.yml similarity index 97% rename from .github/workflows/multi-platform-test.yml rename to .github/workflows/multi-db-platform.yml index d923063fe..19603f174 100644 --- a/.github/workflows/multi-platform-test.yml +++ b/.github/workflows/multi-db-platform.yml @@ -1,5 +1,5 @@ -name: Multi-database platform test +name: Multi-database platform on: [workflow_dispatch] diff --git a/.github/workflows/sqlserver-2019-latest.yml b/.github/workflows/sqlserver-2019.yml similarity index 96% rename from .github/workflows/sqlserver-2019-latest.yml rename to .github/workflows/sqlserver-2019.yml index fd803655f..6b87b1332 100644 --- a/.github/workflows/sqlserver-2019-latest.yml +++ b/.github/workflows/sqlserver-2019.yml @@ -1,5 +1,5 @@ -name: SqlServer 2019 latest +name: SqlServer 2019 on: [workflow_dispatch] diff --git a/.github/workflows/sqlserver-2017-latest.yml b/.github/workflows/sqlserver.yml similarity index 96% rename from .github/workflows/sqlserver-2017-latest.yml rename to .github/workflows/sqlserver.yml index 6c72d8980..fd10bafe6 100644 --- a/.github/workflows/sqlserver-2017-latest.yml +++ b/.github/workflows/sqlserver.yml @@ -1,5 +1,5 @@ -name: SqlServer 2017 latest +name: SqlServer on: workflow_dispatch: From b748c598a1c841af7a48d6b022e8321875c52b42 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 28 Jan 2022 09:04:56 +1300 Subject: [PATCH 09/15] build workflow rename for DB2 LUW --- .github/workflows/db2luw.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/db2luw.yml b/.github/workflows/db2luw.yml index e63b3d00c..2f3981ea2 100644 --- a/.github/workflows/db2luw.yml +++ b/.github/workflows/db2luw.yml @@ -1,5 +1,5 @@ -name: Postgres +name: DB2 LUW on: workflow_dispatch: From 44462e3513be5a743e99984c769574a3eb3ead4c Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 28 Jan 2022 09:46:03 +1300 Subject: [PATCH 10/15] Add maxInBinding - Oracle support for large delete by ids --- .../ebean/config/dbplatform/DatabasePlatform.java | 13 +++++++++++-- .../config/dbplatform/oracle/OraclePlatform.java | 1 + .../sqlserver/SqlServerBasePlatform.java | 1 + .../server/persist/DefaultPersister.java | 15 +++++++-------- .../java/org/tests/query/TestQueryFilterMany.java | 2 +- 5 files changed, 21 insertions(+), 11 deletions(-) diff --git a/ebean-api/src/main/java/io/ebean/config/dbplatform/DatabasePlatform.java b/ebean-api/src/main/java/io/ebean/config/dbplatform/DatabasePlatform.java index d46f6dd37..3950411aa 100644 --- a/ebean-api/src/main/java/io/ebean/config/dbplatform/DatabasePlatform.java +++ b/ebean-api/src/main/java/io/ebean/config/dbplatform/DatabasePlatform.java @@ -55,12 +55,12 @@ public class DatabasePlatform { protected boolean supportsSavepointId = true; protected boolean useMigrationStoredProcedures = false; - + /** * Can we use native java time API objects in * {@link ResultSet#getObject(int, Class)} and * {@link PreparedStatement#setObject(int, Object)}. - * + * * Not all drivers (DB2 e.g.) will support this. */ protected boolean supportsNativeJavaTime = true; @@ -214,6 +214,8 @@ public class DatabasePlatform { */ protected PersistBatch persistBatchOnCascade = PersistBatch.ALL; + protected int maxInBinding; + /** * The maximum length of table names - used specifically when derived * default table names for intersection tables. @@ -370,6 +372,13 @@ public class DatabasePlatform { return inlineSqlUpdateLimit; } + /** + * Return the maximum number of bind values this database platform allows or zero for no limit. + */ + public int getMaxInBinding() { + return maxInBinding; + } + /** * Return the maximum table name length. *

diff --git a/ebean-api/src/main/java/io/ebean/config/dbplatform/oracle/OraclePlatform.java b/ebean-api/src/main/java/io/ebean/config/dbplatform/oracle/OraclePlatform.java index e9dd57207..74f68ced7 100644 --- a/ebean-api/src/main/java/io/ebean/config/dbplatform/oracle/OraclePlatform.java +++ b/ebean-api/src/main/java/io/ebean/config/dbplatform/oracle/OraclePlatform.java @@ -23,6 +23,7 @@ public class OraclePlatform extends DatabasePlatform { super(); this.platform = Platform.ORACLE; this.supportsDeleteTableAlias = true; + this.maxInBinding = 1000; this.maxTableNameLength = 30; this.maxConstraintNameLength = 30; this.dbEncrypt = new OracleDbEncrypt(); diff --git a/ebean-api/src/main/java/io/ebean/config/dbplatform/sqlserver/SqlServerBasePlatform.java b/ebean-api/src/main/java/io/ebean/config/dbplatform/sqlserver/SqlServerBasePlatform.java index eb3dad7be..4dd2077b2 100644 --- a/ebean-api/src/main/java/io/ebean/config/dbplatform/sqlserver/SqlServerBasePlatform.java +++ b/ebean-api/src/main/java/io/ebean/config/dbplatform/sqlserver/SqlServerBasePlatform.java @@ -27,6 +27,7 @@ abstract class SqlServerBasePlatform extends DatabasePlatform { // SQL Server unless we are using sequences this.dbEncrypt = new SqlServerDbEncrypt(); this.persistBatchOnCascade = PersistBatch.NONE; + this.maxInBinding = 2000; this.idInExpandedForm = true; this.selectCountWithAlias = true; this.selectCountWithColumnAlias = true; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/DefaultPersister.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/DefaultPersister.java index eaa1e1c95..07410134b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/DefaultPersister.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/DefaultPersister.java @@ -1,7 +1,6 @@ package io.ebeaninternal.server.persist; import io.ebean.*; -import io.ebean.annotation.Platform; import io.ebean.bean.BeanCollection; import io.ebean.bean.BeanCollection.ModifyListenMode; import io.ebean.bean.EntityBean; @@ -42,15 +41,15 @@ public final class DefaultPersister implements Persister { * Actually does the persisting work. */ private final PersistExecute persistExecute; - private final SpiEbeanServer server; - private final BeanDescriptorManager beanDescriptorManager; + private final int maxInBinding; public DefaultPersister(SpiEbeanServer server, Binder binder, BeanDescriptorManager descMgr) { this.server = server; this.beanDescriptorManager = descMgr; this.persistExecute = new DefaultPersistExecute(binder, server.config().getPersistBatchSize()); + this.maxInBinding = server.databasePlatform().getMaxInBinding(); } @Override @@ -645,18 +644,18 @@ public final class DefaultPersister implements Persister { DeleteMode deleteMode = (permanent || !descriptor.isSoftDelete()) ? DeleteMode.HARD : DeleteMode.SOFT; return delete(descriptor, null, idList, transaction, deleteMode); } - + /** * Delete by Id or a List of Id's. */ private int delete(BeanDescriptor descriptor, Object id, List idList, Transaction transaction, DeleteMode deleteMode) { int rows = 0; - if (server.databasePlatform().isPlatform(Platform.SQLSERVER)) { + if (maxInBinding > 0) { // SqlServer has a 2100 parameter limit, so delete max 2000 ids at once // this gives space up to 100 more query parameters. - while (idList != null && idList.size() > 2000) { - rows += deleteBatch(descriptor, id, idList.subList(0, 2000), transaction, deleteMode); - idList = idList.subList(2000, idList.size()); + while (idList != null && idList.size() > maxInBinding) { + rows += deleteBatch(descriptor, id, idList.subList(0, maxInBinding), transaction, deleteMode); + idList = idList.subList(maxInBinding, idList.size()); } } rows += deleteBatch(descriptor, id, idList, transaction, deleteMode); diff --git a/ebean-test/src/test/java/org/tests/query/TestQueryFilterMany.java b/ebean-test/src/test/java/org/tests/query/TestQueryFilterMany.java index 967efb9ba..9460b1bf0 100644 --- a/ebean-test/src/test/java/org/tests/query/TestQueryFilterMany.java +++ b/ebean-test/src/test/java/org/tests/query/TestQueryFilterMany.java @@ -282,7 +282,7 @@ public class TestQueryFilterMany extends BaseTestCase { List sql = LoggedSql.stop(); - assertThat(sql).hasSize(2); + assertThat(sql.size()).isGreaterThan(1); assertSql(sql.get(0)).contains(" from o_customer t0 left join contact t1 on t1.customer_id = t0.id where t1.first_name is not null order by t0.id; --bind()"); platformAssertIn(sql.get(1), " from contact_note t0 where (t0.contact_id)"); assertSql(sql.get(1)).contains(" and lower(t0.title) like"); From a9bee03ba710e59ae3389cb1bf649c99e072f3b8 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 28 Jan 2022 09:57:49 +1300 Subject: [PATCH 11/15] Add workflow build for Oracle 18 --- .github/workflows/oracle18.yml | 38 ++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 .github/workflows/oracle18.yml diff --git a/.github/workflows/oracle18.yml b/.github/workflows/oracle18.yml new file mode 100644 index 000000000..9d29ee24e --- /dev/null +++ b/.github/workflows/oracle18.yml @@ -0,0 +1,38 @@ + +name: Oracle18 + +on: + workflow_dispatch: + schedule: + - cron: '10 6 * * 1,4' + +jobs: + build: + + runs-on: ${{ matrix.os }} + permissions: + contents: read + packages: write + strategy: + fail-fast: false + matrix: + java_version: [11] + os: [ubuntu-latest] + + steps: + - uses: actions/checkout@v2 + - name: Set up Java + uses: actions/setup-java@v2 + with: + java-version: ${{ matrix.java_version }} + distribution: 'zulu' + - name: Maven cache + uses: actions/cache@v2 + env: + cache-name: maven-cache + with: + path: + ~/.m2 + key: build-${{ env.cache-name }} + - name: postgres + run: mvn clean test -Dprops.file=testconfig/ebean-oracle.properties From 6af8968280d7b31c1ff3395075a81a3ac00df425 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 28 Jan 2022 10:44:25 +1300 Subject: [PATCH 12/15] Adjust workflow build for Oracle 18 --- .github/workflows/oracle18.yml | 2 +- ebean-test/testconfig/ebean-oracle.properties | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/oracle18.yml b/.github/workflows/oracle18.yml index 9d29ee24e..20a8d01e2 100644 --- a/.github/workflows/oracle18.yml +++ b/.github/workflows/oracle18.yml @@ -34,5 +34,5 @@ jobs: path: ~/.m2 key: build-${{ env.cache-name }} - - name: postgres + - name: oracle run: mvn clean test -Dprops.file=testconfig/ebean-oracle.properties diff --git a/ebean-test/testconfig/ebean-oracle.properties b/ebean-test/testconfig/ebean-oracle.properties index e9d4bf55b..32b3af249 100644 --- a/ebean-test/testconfig/ebean-oracle.properties +++ b/ebean-test/testconfig/ebean-oracle.properties @@ -1,3 +1,3 @@ ebean.test.platform=oracle -ebean.test.dbName=oracle -datasource.default=oracle-docker \ No newline at end of file +ebean.test.dbName=test_eb +datasource.default=oracle From 425124d8f7da7b979c73c945cfaa707ace3c8b30 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 28 Jan 2022 10:55:22 +1300 Subject: [PATCH 13/15] Adjust README for build badge changes --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a560d8c82..25ad08f5f 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,8 @@ [![Postgres](https://github.com/ebean-orm/ebean/actions/workflows/postgres.yml/badge.svg)](https://github.com/ebean-orm/ebean/actions/workflows/postgres.yml) [![MySql](https://github.com/ebean-orm/ebean/actions/workflows/mysql.yml/badge.svg)](https://github.com/ebean-orm/ebean/actions/workflows/mysql.yml) -[![MariaDB](https://github.com/ebean-orm/ebean/actions/workflows/mariadb-10.6.yml/badge.svg)](https://github.com/ebean-orm/ebean/actions/workflows/mariadb-10.6.yml) -[![SqlServer](https://github.com/ebean-orm/ebean/actions/workflows/sqlserver-2017-latest.yml/badge.svg)](https://github.com/ebean-orm/ebean/actions/workflows/sqlserver-2017-latest.yml) +[![MariaDB](https://github.com/ebean-orm/ebean/actions/workflows/mariadb.yml/badge.svg)](https://github.com/ebean-orm/ebean/actions/workflows/mariadb.yml) +[![SqlServer](https://github.com/ebean-orm/ebean/actions/workflows/sqlserver.yml/badge.svg)](https://github.com/ebean-orm/ebean/actions/workflows/sqlserver.yml) # Sponsors From 64605b5090945ab9e7cdc13342e05428f8192587 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 28 Jan 2022 17:04:19 +1300 Subject: [PATCH 14/15] Yugabyte platform support - Automatic detection and DDL support - Automatic detection similar to Cockroach - DDL very similar to Postgres but no CREATE TABLE LIKE support (for history DDL) --- ebean-api/pom.xml | 2 +- .../dbplatform/yugabyte/YugabytePlaform.java | 12 ++++++++ .../server/core/DatabasePlatformFactory.java | 12 ++++++-- .../platform/DbExpressionHandlerFactory.java | 2 ++ .../ddlgeneration/PlatformDdlBuilder.java | 18 ++---------- .../platform/DbTriggerBasedHistoryDdl.java | 11 ++++++-- .../platform/PostgresHistoryDdl.java | 12 ++------ .../ddlgeneration/platform/YugabyteDdl.java | 11 ++++++++ .../platform/YugabyteHistoryDdl.java | 16 +++++++++++ ebean-test/pom.xml | 2 +- .../src/test/java/main/StartYugabyte.java | 28 +++++++++++++++++++ .../src/test/resources/ebean.properties | 5 ++++ 12 files changed, 98 insertions(+), 33 deletions(-) create mode 100644 ebean-api/src/main/java/io/ebean/config/dbplatform/yugabyte/YugabytePlaform.java create mode 100644 ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/YugabyteDdl.java create mode 100644 ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/YugabyteHistoryDdl.java create mode 100644 ebean-test/src/test/java/main/StartYugabyte.java diff --git a/ebean-api/pom.xml b/ebean-api/pom.xml index 15021541b..b914e2c2b 100644 --- a/ebean-api/pom.xml +++ b/ebean-api/pom.xml @@ -49,7 +49,7 @@ io.ebean ebean-annotation - 7.5 + 7.6 diff --git a/ebean-api/src/main/java/io/ebean/config/dbplatform/yugabyte/YugabytePlaform.java b/ebean-api/src/main/java/io/ebean/config/dbplatform/yugabyte/YugabytePlaform.java new file mode 100644 index 000000000..622f8e5f8 --- /dev/null +++ b/ebean-api/src/main/java/io/ebean/config/dbplatform/yugabyte/YugabytePlaform.java @@ -0,0 +1,12 @@ +package io.ebean.config.dbplatform.yugabyte; + +import io.ebean.annotation.Platform; +import io.ebean.config.dbplatform.postgres.PostgresPlatform; + +public class YugabytePlaform extends PostgresPlatform { + + public YugabytePlaform() { + super(); + this.platform = Platform.YUGABYTE; + } +} diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DatabasePlatformFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DatabasePlatformFactory.java index ad03fd45f..5b49d5292 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DatabasePlatformFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DatabasePlatformFactory.java @@ -24,12 +24,14 @@ import io.ebean.config.dbplatform.sqlanywhere.SqlAnywherePlatform; import io.ebean.config.dbplatform.sqlite.SQLitePlatform; import io.ebean.config.dbplatform.sqlserver.SqlServer16Platform; import io.ebean.config.dbplatform.sqlserver.SqlServer17Platform; +import io.ebean.config.dbplatform.yugabyte.YugabytePlaform; import io.ebeaninternal.api.CoreLog; import io.ebeaninternal.api.DbOffline; import javax.persistence.PersistenceException; import javax.sql.DataSource; import java.sql.*; +import java.util.Locale; /** * Create a DatabasePlatform from the configuration. @@ -164,7 +166,8 @@ public class DatabasePlatformFactory { } else if (dbProductName.contains("hsql database engine")) { return new HsqldbPlatform(); } else if (dbProductName.contains("postgres")) { - return readPostgres(connection, majorVersion); + String productVersion = metaData.getDatabaseProductVersion().toLowerCase(Locale.ENGLISH); + return readPostgres(connection, majorVersion, productVersion); } else if (dbProductName.contains("mariadb")) { return new MariaDbPlatform(); } else if (dbProductName.contains("mysql")) { @@ -207,11 +210,14 @@ public class DatabasePlatformFactory { /** * Use a select version() query as it could be Postgres or CockroachDB. */ - private static DatabasePlatform readPostgres(Connection connection, int majorVersion) { + private static DatabasePlatform readPostgres(Connection connection, int majorVersion, String productVersion) { + if (productVersion.contains("-yb-")) { + return new YugabytePlaform(); + } try (PreparedStatement statement = connection.prepareStatement("select version() as \"version\"")) { try (ResultSet resultSet = statement.executeQuery()) { if (resultSet.next()) { - String productVersion = resultSet.getString("version").toLowerCase(); + productVersion = resultSet.getString("version").toLowerCase(); if (productVersion.contains("cockroach")) { return new CockroachPlatform(); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/DbExpressionHandlerFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/DbExpressionHandlerFactory.java index c555e33c5..1af660cae 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/DbExpressionHandlerFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/DbExpressionHandlerFactory.java @@ -15,6 +15,8 @@ public final class DbExpressionHandlerFactory { case H2: return new H2DbExpression(); case POSTGRES: + case YUGABYTE: + case COCKROACH: return new PostgresDbExpression(); case MARIADB: return new MariaDbExpression(); diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/PlatformDdlBuilder.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/PlatformDdlBuilder.java index 0133413e0..07e0be2bf 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/PlatformDdlBuilder.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/PlatformDdlBuilder.java @@ -1,21 +1,7 @@ package io.ebeaninternal.dbmigration.ddlgeneration; import io.ebean.config.dbplatform.DatabasePlatform; -import io.ebeaninternal.dbmigration.ddlgeneration.platform.ClickHouseDdl; -import io.ebeaninternal.dbmigration.ddlgeneration.platform.CockroachDdl; -import io.ebeaninternal.dbmigration.ddlgeneration.platform.DB2Ddl; -import io.ebeaninternal.dbmigration.ddlgeneration.platform.H2Ddl; -import io.ebeaninternal.dbmigration.ddlgeneration.platform.HanaColumnStoreDdl; -import io.ebeaninternal.dbmigration.ddlgeneration.platform.HsqldbDdl; -import io.ebeaninternal.dbmigration.ddlgeneration.platform.MariaDbDdl; -import io.ebeaninternal.dbmigration.ddlgeneration.platform.MySqlDdl; -import io.ebeaninternal.dbmigration.ddlgeneration.platform.NuoDbDdl; -import io.ebeaninternal.dbmigration.ddlgeneration.platform.OracleDdl; -import io.ebeaninternal.dbmigration.ddlgeneration.platform.PlatformDdl; -import io.ebeaninternal.dbmigration.ddlgeneration.platform.Postgres9Ddl; -import io.ebeaninternal.dbmigration.ddlgeneration.platform.PostgresDdl; -import io.ebeaninternal.dbmigration.ddlgeneration.platform.SQLiteDdl; -import io.ebeaninternal.dbmigration.ddlgeneration.platform.SqlServerDdl; +import io.ebeaninternal.dbmigration.ddlgeneration.platform.*; /** * Builds platform specific DDL handler. @@ -53,6 +39,8 @@ public class PlatformDdlBuilder { return new Postgres9Ddl(platform); case POSTGRES: return new PostgresDdl(platform); + case YUGABYTE: + return new YugabyteDdl(platform); case COCKROACH: return new CockroachDdl(platform); case SQLSERVER16: diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/DbTriggerBasedHistoryDdl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/DbTriggerBasedHistoryDdl.java index 575deb5a1..58bed4505 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/DbTriggerBasedHistoryDdl.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/DbTriggerBasedHistoryDdl.java @@ -174,16 +174,21 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl { } protected void createHistoryTable(DdlBuffer apply, MTable table) throws IOException { + createHistoryTableAs(apply, table); + createHistoryTableWithPeriod(apply); + } + protected void createHistoryTableAs(DdlBuffer apply, MTable table) throws IOException { apply.append(platformDdl.getCreateTableCommandPrefix()).append(" ").append(table.getName()).append(historySuffix).append("(").newLine(); - - Collection cols = table.allColumns(); - for (MColumn column : cols) { + for (MColumn column : table.allColumns()) { if (!column.isDraftOnly()) { writeColumnDefinition(apply, column.getName(), column.getType()); apply.append(",").newLine(); } } + } + + protected void createHistoryTableWithPeriod(DdlBuffer apply) throws IOException { writeColumnDefinition(apply, sysPeriodStart, sysPeriodType); apply.append(",").newLine(); writeColumnDefinition(apply, sysPeriodEnd, sysPeriodType); diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PostgresHistoryDdl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PostgresHistoryDdl.java index fe9b17f1b..b0257f96a 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PostgresHistoryDdl.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/PostgresHistoryDdl.java @@ -22,11 +22,8 @@ public class PostgresHistoryDdl extends DbTriggerBasedHistoryDdl { */ @Override protected void createHistoryTable(DdlBuffer apply, MTable table) throws IOException { - - String baseTable = table.getName(); - apply - .append("create table ").append(baseTable).append(historySuffix) - .append("(like ").append(baseTable).append(")").endOfStatement(); + apply.append("create table ").append(table.getName()).append(historySuffix) + .append("(like ").append(table.getName()).append(")").endOfStatement(); } /** @@ -57,7 +54,6 @@ public class PostgresHistoryDdl extends DbTriggerBasedHistoryDdl { @Override protected void createTriggers(DdlWrite writer, MTable table) throws IOException { - String baseTableName = table.getName(); String procedureName = procedureName(baseTableName); String triggerName = triggerName(baseTableName); @@ -110,7 +106,6 @@ public class PostgresHistoryDdl extends DbTriggerBasedHistoryDdl { @Override protected void createStoredFunction(DdlWrite writer, MTable table) throws IOException { - String procedureName = procedureName(table.getName()); String historyTable = historyTableName(table.getName()); @@ -120,16 +115,13 @@ public class PostgresHistoryDdl extends DbTriggerBasedHistoryDdl { @Override protected void updateHistoryTriggers(DbTriggerUpdate update) throws IOException { - String procedureName = procedureName(update.getBaseTable()); - recreateHistoryView(update); createOrReplaceFunction(update.historyTriggerBuffer(), procedureName, update.getHistoryTable(), update.getColumns()); } @Override protected void appendInsertIntoHistory(DdlBuffer buffer, String historyTable, List columns) throws IOException { - buffer.append(" insert into ").append(historyTable).append(" (").append(sysPeriod).append(","); appendColumnNames(buffer, columns, ""); buffer.append(") values (tstzrange(lowerTs,upperTs), "); diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/YugabyteDdl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/YugabyteDdl.java new file mode 100644 index 000000000..a78e5b339 --- /dev/null +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/YugabyteDdl.java @@ -0,0 +1,11 @@ +package io.ebeaninternal.dbmigration.ddlgeneration.platform; + +import io.ebean.config.dbplatform.DatabasePlatform; + +public class YugabyteDdl extends PostgresDdl { + + public YugabyteDdl(DatabasePlatform platform) { + super(platform); + this.historyDdl = new YugabyteHistoryDdl(); + } +} diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/YugabyteHistoryDdl.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/YugabyteHistoryDdl.java new file mode 100644 index 000000000..3ba023881 --- /dev/null +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/YugabyteHistoryDdl.java @@ -0,0 +1,16 @@ +package io.ebeaninternal.dbmigration.ddlgeneration.platform; + +import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer; +import io.ebeaninternal.dbmigration.model.MTable; + +import java.io.IOException; + +public class YugabyteHistoryDdl extends PostgresHistoryDdl { + + @Override + protected void createHistoryTable(DdlBuffer apply, MTable table) throws IOException { + createHistoryTableAs(apply, table); + writeColumnDefinition(apply, sysPeriod, "tstzrange"); + apply.newLine().append(")").endOfStatement(); + } +} diff --git a/ebean-test/pom.xml b/ebean-test/pom.xml index 2fcf19018..caeaaa5f7 100644 --- a/ebean-test/pom.xml +++ b/ebean-test/pom.xml @@ -56,7 +56,7 @@ io.ebean ebean-test-docker - 4.4 + 4.5 diff --git a/ebean-test/src/test/java/main/StartYugabyte.java b/ebean-test/src/test/java/main/StartYugabyte.java new file mode 100644 index 000000000..ed3d4ec46 --- /dev/null +++ b/ebean-test/src/test/java/main/StartYugabyte.java @@ -0,0 +1,28 @@ +package main; + +import io.ebean.docker.commands.YugabyteConfig; +import io.ebean.docker.commands.YugabyteContainer; + +public class StartYugabyte { + + public static void main(String[] args) { + + YugabyteConfig config = new YugabyteConfig("2.11.2.0-b89"); + config.setDbName("unit"); + config.setUser("unit"); + + YugabyteContainer container = new YugabyteContainer(config); + container.start(); + +// Run container ut_yugabyte with host:localhost port:6433 db:unit user:unit/test shutdown:None +// docker run -d --name ut_yugabyte -p 6433:5433 -p 7000:7000 -p 9000:9000 -p 9042:9042 yugabytedb/yugabyte:2.11.2.0-b89 bin/yugabyted start --daemon=false +// ... +// Commands - sqlRun: drop database if exists unit +// Commands - sqlRun: drop role if exists unit +// Commands - sqlRun: select 1 from pg_database where datname = 'unit' +// Commands - sqlRun: select rolname from pg_roles where rolname = 'unit' +// Commands - sqlRun: create role unit password 'test' login createrole +// Commands - sqlRun: create database unit with owner unit + + } +} diff --git a/ebean-test/src/test/resources/ebean.properties b/ebean-test/src/test/resources/ebean.properties index d7e1debae..2b8bdfa45 100644 --- a/ebean-test/src/test/resources/ebean.properties +++ b/ebean-test/src/test/resources/ebean.properties @@ -23,6 +23,7 @@ ebean.ddl.run=true ebean.ddl.header=-- Generated by ebean ${version} at ${timestamp} ebean.packages=org.tests,org.etest datasource.default=h2 +#datasource.default=yugabyte #datasource.h2.capturestacktrace=true #ebean.dumpMetricsOnShutdown=true @@ -144,6 +145,10 @@ datasource.cockroach.password= datasource.cockroach.url=jdbc:postgresql://localhost:26257/unit?sslmode=disable datasource.cockroach.driver=org.postgresql.Driver +datasource.yugabyte.username=unit +datasource.yugabyte.password=test +datasource.yugabyte.url=jdbc:postgresql://localhost:6433/unit?sslmode=disable + datasource.oracle.username=test_ebean datasource.oracle.password=test datasource.oracle.url=jdbc:oracle:thin:@localhost:1521:XE From 223e5160dca910348995b8a08ac71ce082bce093 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 28 Jan 2022 17:26:38 +1300 Subject: [PATCH 15/15] #2516 - Touch StartYugabyte --- ebean-test/src/test/java/main/StartYugabyte.java | 1 + 1 file changed, 1 insertion(+) diff --git a/ebean-test/src/test/java/main/StartYugabyte.java b/ebean-test/src/test/java/main/StartYugabyte.java index ed3d4ec46..b45f2b7f2 100644 --- a/ebean-test/src/test/java/main/StartYugabyte.java +++ b/ebean-test/src/test/java/main/StartYugabyte.java @@ -7,6 +7,7 @@ public class StartYugabyte { public static void main(String[] args) { + // Check add extensions ? YugabyteConfig config = new YugabyteConfig("2.11.2.0-b89"); config.setDbName("unit"); config.setUser("unit");