Compare commits

..
115 Commits
Author SHA1 Message Date
Rob Bygrave 6826fe1015 [maven-release-plugin] prepare release ebean-9.1.1 2016-11-08 00:32:38 +13:00
Rob Bygrave e67860cbe3 Merge branch 'master' of https://github.com/ebean-orm/ebean 2016-11-08 00:27:40 +13:00
Rob Bygrave b41238ddbb No effective change - modify TestHistoryInsert for more wait time and logging (PG test failing sometimes in CI) 2016-11-08 00:25:13 +13:00
Rob BygraveandGitHub c0b1c3d3ee Merge pull request #868 from 0xbaadf00d/feature/array-copy-performance
Use "Collection.addAll(...)" rather than manually copying arrays
2016-11-08 00:16:33 +13:00
Rob Bygrave ae69fcb80a #862 - ENH: Change ServerConfig such that if H2 ... no using createOnly = true in case the test EbeanServer instance is created for each test (and hence we need to drop if the same in memory db is used) 2016-11-08 00:10:15 +13:00
Rob Bygrave 6c4c33f1f3 No effective change - reduce logging in test (for CI) 2016-11-08 00:03:15 +13:00
Rob Bygrave 2986290947 Refactor - change use of 31 prime in various hash to 92821 2016-11-07 23:57:51 +13:00
Rob Bygrave 376cb9ebcb #869 - Clash on bind hash value for query cache with consecutive values of "01","20" and "02", "10" 2016-11-07 23:47:29 +13:00
Rob Bygrave 5cf5629232 #869 - Test for ... Clash on bind hash value for query cache with consecutive values of "01","20" and "02", "10" 2016-11-07 23:46:28 +13:00
Thibault Meyer 98aa5e9da9 Use "Collection.addAll(...)" rather than manually copying arrays 2016-11-07 11:07:37 +01:00
Rob BygraveandGitHub ed1df5bcbb Merge pull request #864 from 0xbaadf00d/feature/redundant-local-var
Remove redundant local variables
2016-11-07 22:14:59 +13:00
Thibault Meyer 6704ccc6a7 Merge branch 'master' into feature/redundant-local-var 2016-11-07 10:11:03 +01:00
Thibault Meyer 5f35e3c944 Remove redundant local variables 2016-11-07 10:03:50 +01:00
Rob Bygrave 0893972115 Fix for running CI tests as Postgres (where we need to explicitly turn on DDL generation and running for the tests). 2016-11-07 22:00:33 +13:00
Rob Bygrave 7a8d1b85a9 #866 - Fix RawSql mapping such that it automatically maps foreign key columns 2016-11-07 21:57:03 +13:00
Rob Bygrave 686593e9e8 No effective change - tidy up test Order entity bean 2016-11-07 21:36:19 +13:00
Rob Bygrave d05b593432 #862 - ENH: Change ServerConfig such that if H2 is the DataSource/DatabasePlatform then automatically it sets up for testing (ddl generation) 2016-11-07 19:50:05 +13:00
Rob Bygrave b581c893ec No effective change - tidy up test conversation User entity bean 2016-11-07 19:47:34 +13:00
Rob Bygrave 63f852475d #863 - @Enumerated(EnumType.STRING) DayOfWeek day; ... incorrectly maps to SQL Integer type 2016-11-07 17:15:47 +13:00
Rob BygraveandGitHub 51364763fb Merge pull request #860 from 0xbaadf00d/feature/replace-anonymous-classes
Replace anonymous classes with lambda expressions
2016-11-07 13:02:33 +13:00
Rob BygraveandGitHub ea408fd4c7 Merge pull request #861 from 0xbaadf00d/feature/coding-style
Remove redundant "public" modifier for interface methods
2016-11-07 12:58:23 +13:00
Thibault Meyer 8dc521ca8b Remove redundant "public" modifier for interface methods 2016-11-06 11:48:59 +01:00
Thibault Meyer 6680e2ea75 Replace anonymous classes with lambda expressions 2016-11-06 11:17:53 +01:00
Rob BygraveandGitHub da30df3b2b Merge pull request #858 from 0xbaadf00d/feature/deprecated-api-usage
Deprecated API usage - Modify ScalarTypeJodaLocalTime to use toDateTimeToday().getMillis()
2016-11-06 22:59:32 +13:00
Rob BygraveandGitHub d12ea89388 Merge pull request #854 from 0xbaadf00d/feature/explicit-type-to-diamond
Replace explicit type with <>
2016-11-06 22:54:24 +13:00
Thibault Meyer e0931e41e5 Remove deprecated API usage 2016-11-06 10:50:31 +01:00
Rob BygraveandGitHub c98d258127 Merge pull request #857 from 0xbaadf00d/feature/boxing-unboxing
Remove unnecessary boxing and unboxing
2016-11-06 22:43:33 +13:00
Rob BygraveandGitHub a4922a5b1d Merge pull request #856 from 0xbaadf00d/feature/identical-catch
Change identical 'catch' statements
2016-11-06 22:42:13 +13:00
Rob BygraveandGitHub edb2a69f6e Merge pull request #853 from 0xbaadf00d/fix/javadoc-error
Javadoc error
2016-11-06 22:40:52 +13:00
Thibault Meyer b94f852b67 Remove unnecessary boxing and unboxing 2016-11-06 10:29:42 +01:00
Thibault Meyer a8778ef14c Change identical 'catch' statements 2016-11-06 10:26:13 +01:00
Rob Bygrave cbfce0d14d #855 - Fix @Aggregation lazy loading and base select issue 2016-11-06 22:18:23 +13:00
Thibault Meyer abb25d397a Fix comments 2016-11-06 10:03:33 +01:00
Thibault Meyer 969a3c8b8d Replace explicit type with <> 2016-11-06 10:00:12 +01:00
Rob Bygrave 2a6d38eef2 #852 - javax.persistence.PersistenceException: No ScalarType registered for class Foo$1 ... where Foo is an Enum where individual instances override a method (example below). 2016-11-06 20:33:56 +13:00
Rob Bygrave d84080fb76 Refactor - clean up DefaultTypeManager, diamond operator and access modifiers only 2016-11-06 19:45:46 +13:00
Rob Bygrave 54d7a6fb42 Refactor - clean up docstore api mapping, diamond operator only 2016-11-05 23:04:33 +13:00
Rob Bygrave e5356e7118 Refactor - tidy up in com.avaje.ebeaninternal util, no effective change 2016-11-05 23:01:03 +13:00
Rob Bygrave e83556cada Refactor - clean up OrmQueryDetailParser, remove unused sections 2016-11-05 22:51:51 +13:00
Rob Bygrave 201a2826ab Refactor - tidy up in com.avaje.ebeaninternal.server.querydefn, no effective change 2016-11-05 22:46:43 +13:00
Rob Bygrave 670bac52f8 Refactor - tidy up in com.avaje.ebeaninternal.server.query, no effective change 2016-11-05 22:32:36 +13:00
Rob Bygrave 77e3346d9e Refactor - clean up CQueryPlan, CQueryPlanStats 2016-11-05 15:11:17 +13:00
Rob Bygrave 4663162f95 Refactor - no effective chang - Add SpiQuery getOriginKey() 2016-11-05 14:48:03 +13:00
Rob BygraveandGitHub 83a3ef43bd Merge pull request #851 from FOCONIS/fix/javawarnings
FIX some java warnings / rawtypes
2016-11-05 09:23:07 +13:00
Roland Praml 3701b314a0 FIX some java warnings / rawtypes 2016-11-04 12:19:38 +01:00
Rob Bygrave fad8358a9d Bump to java8-parent, update to Java8 LongAdder 2016-11-04 20:04:25 +13:00
Rob Bygrave 78c4dbb44d [maven-release-plugin] prepare for next development iteration 2016-11-04 19:19:11 +13:00
Rob Bygrave 9c74520a4b [maven-release-plugin] prepare release ebean-8.8.1 2016-11-04 19:19:02 +13:00
Rob Bygrave c911c710d5 Bump pom to 8.8.1-SNAPSHOT 2016-11-04 01:17:08 +13:00
Rob Bygrave f08dd01035 #836 - ENH: Add support for @DbArray even for H2 db 2016-11-04 01:16:32 +13:00
Rob Bygrave a1b4af2716 Refactor - no effective change - remove un-required callback from PersistExecute to PersistRequestBean 2016-11-03 23:42:43 +13:00
Rob Bygrave 8c500c5836 #846 - Add soft delete related callbacks 2016-11-03 23:27:39 +13:00
Rob Bygrave c1d6cc7b75 Refactor - no real change - tighter access on SqlTreeNodeBean 2016-11-03 23:18:14 +13:00
Rob Bygrave d6fe16ffda Change permissions on travis scripts 2016-11-03 23:14:14 +13:00
Rob Bygrave d0230491e5 #99 - ENH (419) : Simplify aggregation queries - part 2 2016-11-03 23:06:54 +13:00
Rob Bygrave 3526f71f0a #99 - ENH (419) : Simplify aggregation queries 2016-11-02 22:10:22 +13:00
Rob Bygrave 18f943ab2b [maven-release-plugin] prepare for next development iteration 2016-10-31 21:59:39 +13:00
Rob Bygrave 03ff53c7af [maven-release-plugin] prepare release ebean-8.7.1 2016-10-31 21:59:30 +13:00
Rob Bygrave c20d111ea2 Bump version to 8.7.1-SNAPSHOT 2016-10-31 21:58:43 +13:00
Rob Bygrave 920fa73d11 #837 - ENH: Support using @HistoryExclude on normal properties (other than @ManyToMany) 2016-10-31 21:57:16 +13:00
Rob Bygrave cd62686337 #845 - Fix EQL parsing to support the 'inverse' form - e.g. where 'Rob' eq firstName (where the path is on the RHS rather than LHS) 2016-10-31 21:32:29 +13:00
Rob Bygrave e9ad459fa5 #843 - Change ServerConfig name to default to "db" (prior default was null) and defaultServer to true 2016-10-31 20:40:26 +13:00
Rob Bygrave ea5e9fa75a #842 - For @DbJson map the type Map<String, ?> (using the wildcard) ... the same as Map<String, Object> 2016-10-31 20:15:23 +13:00
Rob BygraveandGitHub d44460e180 Merge pull request #841 from FOCONIS/bugfix/softdelete-calls-wrong-lifecycle-method
Bugfix/softdelete calls wrong lifecycle method
2016-10-27 10:17:29 +13:00
Roland Praml 0e5ebf3fea FIX: softDeleting an entity calls now preUpdate/postUpdate 2016-10-26 15:47:54 +02:00
Roland Praml 42d35f8ec6 FIX: removed trailing commas in logs 2016-10-26 15:45:10 +02:00
Rob Bygrave 7f52e466e0 [maven-release-plugin] prepare for next development iteration 2016-10-25 22:23:13 +13:00
Rob Bygrave 861a8a4ee5 [maven-release-plugin] prepare release ebean-8.6.1 2016-10-25 22:23:04 +13:00
Rob Bygrave abe2f76d5c Bump pom to 8.6.1-SNAPSHOT 2016-10-25 22:22:16 +13:00
Rob Bygrave d0f75a940c #239 - Support Geometric types of Postgres, Also adding LineString, MultiLineString and MultiPoint 2016-10-25 22:19:33 +13:00
Rob Bygrave 44ad78b5e0 #239 - Support Geometric types of Postgres 2016-10-21 02:45:06 +13:00
Rob Bygrave 967b4de784 #239 - Support Geometric types of Postgres 2016-10-21 02:42:25 +13:00
Rob Bygrave ea45201905 [maven-release-plugin] prepare for next development iteration 2016-10-17 20:58:19 +13:00
Rob Bygrave 938f4ec9c2 [maven-release-plugin] prepare release ebean-8.5.1 2016-10-17 20:58:10 +13:00
Rob Bygrave 99bd2972d0 Bump pom version to 8.5.1-SNAPSHOT 2016-10-17 20:57:26 +13:00
Rob Bygrave deac291951 #835 - A query that includes a fetch() of a many that is @SoftDelete where all the rows are soft deleted returns incorrect results 2016-10-17 20:52:18 +13:00
Rob Bygrave 3161e24677 #835 - Tests for - A query that includes a fetch() of a many that is @SoftDelete where all the rows are soft deleted returns incorrect results 2016-10-17 20:51:22 +13:00
Rob Bygrave 37804bd083 Modify tests to avoid MySql keyword (mod) for column names 2016-10-17 20:50:48 +13:00
Rob Bygrave 0a2a987695 Modify tests to avoid Oracle keywords for column names 2016-10-15 17:03:32 +13:00
Rob Bygrave 4a085cb819 #834 - Oracle DDL for drop index and drop constraints incorrectly includes "if exits" 2016-10-15 17:02:44 +13:00
Rob Bygrave 67469ef4d3 No effective change - change Line endings to CR (from CRLF) 2016-10-15 14:39:20 +13:00
Rob Bygrave c3f43d503f #832 - Refactor: Change generated SQL to use "left join" rather than "left outer join" - change tests 2016-10-15 14:37:36 +13:00
Rob Bygrave 9158f46bb3 #832 - Refactor: Change generated SQL to use "left join" rather than "left outer join" 2016-10-15 14:36:11 +13:00
Rob Bygrave b3bfa88eb5 [maven-release-plugin] prepare for next development iteration 2016-10-15 01:14:29 +13:00
Rob Bygrave 185dec9c02 [maven-release-plugin] prepare release ebean-8.4.2 2016-10-15 01:14:18 +13:00
Rob Bygrave 20634233ca Update tests only - handle MySql specifics (boolean literal, lack of order by nulls last) 2016-10-15 00:55:09 +13:00
Rob Bygrave 7c9dda586e No effective change - format only 2016-10-14 23:49:00 +13:00
Rob BygraveandGitHub 3ca0f7b776 Merge pull request #828 from FOCONIS/feature/postconstruct
Feature/postconstruct
2016-10-14 23:44:45 +13:00
Rob Bygrave 85caca48de No effective change - add tests for naming convention on m2m columns 2016-10-14 23:29:50 +13:00
Rob Bygrave ff85a51994 No effective change - format only 2016-10-14 23:29:27 +13:00
Rob BygraveandGitHub 6dc3038d0d Merge pull request #830 from lvffilho/master
Add NamingConvention support to ManyToMany columns
2016-10-14 23:27:32 +13:00
Rob BygraveandGitHub c0fcb77f3d Merge pull request #829 from kdazzle/patch-1
Remove outdated findPageList(int, int) javadocs
2016-10-14 23:17:42 +13:00
Rob Bygrave da5d5296b6 #831 - EQL query language parser needs to throw exception on invalid query ... "find ..." - remove unhelpful tests 2016-10-14 21:09:23 +13:00
Rob Bygrave f04ab28c3f #831 - EQL query language parser needs to throw exception on invalid query ... "find ..." 2016-10-14 21:08:23 +13:00
Rob Bygrave d6cd41f8d2 #831 - EQL query language parser needs to throw exception on invalid query ... "find ..." - tests 2016-10-14 21:07:31 +13:00
Rob Bygrave 504a209a78 Merge branch 'master' of https://github.com/ebean-orm/ebean 2016-10-14 20:24:13 +13:00
Rob Bygrave 9f98b5333d Update tests - for asserts trim column alias from generated SQL if necessary (to support generating without column alias) 2016-10-14 20:23:36 +13:00
Eddie Mc Greal 2a600adbcf Added tests for EQL - syntactically incorrect und named parameter on LHS of comparison operator 2016-10-12 19:42:31 +02:00
Luiz Filho 9ce6007330 Add NamingConvention support to ManyToMany columns 2016-10-07 16:46:40 -03:00
Kyle ValadeandGitHub 7780dd6272 Remove outdated findPageList(int, int) javadocs
The class no longer supports that type of call
2016-10-07 12:26:06 -04:00
Roland Praml b01ddea781 FIX: fixed non-deterministic failing TestHistoryInsert testcase 2016-10-05 21:51:42 +02:00
Roland Praml b848587cd3 ADD: Testcases for PostConstruct 2016-10-05 21:51:04 +02:00
Roland Praml fe7e929a99 Refactor: Removed duplicate code from BootupClasses - use generics. 2016-10-05 21:50:22 +02:00
Roland Praml 3ee0b0224e ENH: Support for javax.annotation.PostConstruct. BeanPostConstructListener will be informed when an entity-bean is constructed/created to perform dependency-injection (e.g. Spring-Autowire) 2016-10-05 21:48:11 +02:00
Roland Praml 169eba4296 No effective code change - fixed commets 2016-10-05 21:39:44 +02:00
Robin Bygrave 91d3279061 [maven-release-plugin] prepare for next development iteration 2016-10-03 23:40:32 +13:00
Robin Bygrave b4b7c631da [maven-release-plugin] prepare release ebean-8.4.1 2016-10-03 23:40:22 +13:00
Robin Bygrave 4f98ca5d91 #821 - CQueryIteratorSimple not working with consecutive calls to hasNext() - ie. without matching calls to next() 2016-10-03 23:36:03 +13:00
Robin Bygrave 014a9aef6f #826 - Remove deprecated methods - migrate findRowCount() to findCount() & findFutureRowCount() to findFutureCount() 2016-10-03 22:31:33 +13:00
Robin Bygrave f21c33df7b Bump pom to 8.4.1-SNAPSHOT 2016-10-03 22:16:52 +13:00
Robin Bygrave f1eb494e0d #824 - Refactor com.avaje.ebean.config.dbplatform DbType & DbPlatformType - handle logical and plaform ddl conversion 2016-10-03 22:04:37 +13:00
Robin Bygrave d26203db1f #824 - Refactor com.avaje.ebean.config.dbplatform DbType & DbPlatformType - support custom DbType mapping options 2016-10-03 20:52:53 +13:00
Robin Bygrave abfe58fb06 #824 - Refactor com.avaje.ebean.config.dbplatform DbType & DbPlatformType - no effective change, tidy. 2016-09-23 00:27:39 +12:00
Robin Bygrave d0ad5f6c48 #824 - Refactor com.avaje.ebean.config.dbplatform DbType & DbPlatformType 2016-09-23 00:17:51 +12:00
Robin Bygrave bc4a246f33 [maven-release-plugin] prepare for next development iteration 2016-09-22 22:25:14 +12:00
618 changed files with 9057 additions and 7973 deletions
+4 -30
View File
@@ -3,13 +3,13 @@
<parent>
<groupId>org.avaje</groupId>
<artifactId>oss-parent</artifactId>
<artifactId>java8-parent</artifactId>
<version>1.1</version>
</parent>
<groupId>org.avaje.ebean</groupId>
<artifactId>ebean</artifactId>
<version>8.3.1</version>
<version>9.1.1</version>
<packaging>jar</packaging>
<name>ebean</name>
@@ -19,25 +19,9 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<id>rbygrave</id>
<name>Rob Bygrave</name>
<email>robin.bygrave@gmail.com</email>
</developer>
</developers>
<scm>
<developerConnection>scm:git:https://github.com/ebean-orm/ebean.git</developerConnection>
<tag>ebean-8.3.1</tag>
<tag>ebean-9.1.1</tag>
</scm>
<dependencies>
@@ -236,16 +220,6 @@
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.avaje.ebean</groupId>
<artifactId>ebean-maven-plugin</artifactId>
@@ -303,7 +277,7 @@
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<configuration>
<doctitle>Ebean 8</doctitle>
<doctitle>Ebean 9</doctitle>
<overview>src/main/java/com/avaje/ebean/overview.html</overview>
<source>1.8</source>
<doclet>org.avaje.doclet.PygmentsDoclet</doclet>
@@ -30,7 +30,7 @@ final class DRawSqlColumnsParser {
private ColumnMapping parse() {
ArrayList<ColumnMapping.Column> columns = new ArrayList<ColumnMapping.Column>();
ArrayList<ColumnMapping.Column> columns = new ArrayList<>();
while (pos <= end) {
ColumnMapping.Column c = nextColumnInfo();
columns.add(c);
@@ -47,7 +47,7 @@ final class DRawSqlColumnsParser {
String[] split = colInfo.split("\\s(?=[^\\)]*(?:\\(|$))");
if (split.length > 1) {
ArrayList<String> tmp = new ArrayList<String>(split.length);
ArrayList<String> tmp = new ArrayList<>(split.length);
for (int i = 0; i < split.length; i++) {
if (!split[i].trim().isEmpty()) {
tmp.add(split[i].trim());
@@ -1,6 +1,7 @@
package com.avaje.ebean;
import com.avaje.ebean.RawSql.Sql;
import com.avaje.ebeaninternal.server.querydefn.SimpleTextParser;
/**
* Parses sql-select queries to try and determine the location where WHERE and
@@ -8,13 +9,13 @@ import com.avaje.ebean.RawSql.Sql;
*/
class DRawSqlParser {
public static final String $_AND_HAVING = "${andHaving}";
private static final String $_AND_HAVING = "${andHaving}";
public static final String $_HAVING = "${having}";
private static final String $_HAVING = "${having}";
public static final String $_AND_WHERE = "${andWhere}";
private static final String $_AND_WHERE = "${andWhere}";
public static final String $_WHERE = "${where}";
private static final String $_WHERE = "${where}";
private final SimpleTextParser textParser;
+2 -2
View File
@@ -132,13 +132,13 @@ public final class Ebean {
/**
* Cache for fast concurrent read access.
*/
private final ConcurrentHashMap<String, EbeanServer> concMap = new ConcurrentHashMap<String, EbeanServer>();
private final ConcurrentHashMap<String, EbeanServer> concMap = new ConcurrentHashMap<>();
/**
* Cache for synchronized read, creation and put. Protected by the monitor
* object.
*/
private final HashMap<String, EbeanServer> syncMap = new HashMap<String, EbeanServer>();
private final HashMap<String, EbeanServer> syncMap = new HashMap<>();
private final Object monitor = new Object();
+6 -21
View File
@@ -167,8 +167,9 @@ public interface EbeanServer {
/**
* Create a new instance of T that is an EntityBean.
* <p>
* Generally not expected to be useful (now dynamic subclassing support was removed in
* favour of always using enhancement).
* Useful if you use BeanPostConstructListeners or &#64;PostConstruct Annotations.
* In this case you should not use "new Bean...()". Making all bean construtors protected
* could be a good idea here.
* </p>
*/
<T> T createEntityBean(Class<T> type);
@@ -746,20 +747,12 @@ public interface EbeanServer {
*/
<T> int findCount(Query<T> query, Transaction transaction);
/**
* Deprecated in favor of findCount()
*
* Return the number of 'top level' or 'root' entities this query should return.
* @deprecated
*/
<T> int findRowCount(Query<T> query, Transaction transaction);
/**
* Return the Id values of the query as a List.
*
* @see Query#findIds()
*/
<A> List<A> findIds(Query<?> query, Transaction transaction);
<A, T> List<A> findIds(Query<T> query, Transaction transaction);
/**
* Return a QueryIterator for the query.
@@ -892,18 +885,10 @@ public interface EbeanServer {
* @param query the query to execute the row count on
* @param transaction the transaction (can be null).
* @return a Future object for the row count query
* @see com.avaje.ebean.Query#findFutureRowCount()
* @see com.avaje.ebean.Query#findFutureCount()
*/
<T> FutureRowCount<T> findFutureCount(Query<T> query, Transaction transaction);
/**
* Deprecated in favor of findFutureCount().
*
* Execute find row count query in a background thread.
* @deprecated
*/
<T> FutureRowCount<T> findFutureRowCount(Query<T> query, Transaction transaction);
/**
* Execute find Id's query in a background thread.
* <p>
@@ -1039,7 +1024,7 @@ public interface EbeanServer {
*
* @see Query#findSingleAttributeList()
*/
<A> List<A> findSingleAttributeList(Query<?> query, Transaction transaction);
<A, T> List<A> findSingleAttributeList(Query<T> query, Transaction transaction);
/**
* Execute the query returning at most one entity bean or null (if no matching
@@ -185,13 +185,6 @@ public interface ExpressionList<T> {
*/
int findCount();
/**
* Deprecated in favor of findCount().
*
* @deprecated
*/
int findRowCount();
/**
* Execute the query returning a set.
*
@@ -265,13 +258,6 @@ public interface ExpressionList<T> {
*/
FutureRowCount<T> findFutureCount();
/**
* Deprecated in favor of findFutureCount().
*
* @deprecated
*/
FutureRowCount<T> findFutureRowCount();
/**
* Execute find Id's query in a background thread.
* <p>
@@ -9,6 +9,7 @@ import java.util.concurrent.Future;
* It extends the java.util.concurrent.Future.
* </p>
*
* @param <T> the BeanType
* @author rbygrave
*/
public interface FutureRowCount<T> extends Future<Integer> {
+1 -1
View File
@@ -512,7 +512,7 @@ public abstract class Model {
* Create and return a new Finder for a different server.
*/
public Finder<I, T> on(String server) {
return new Finder<I, T>(server, type);
return new Finder<>(server, type);
}
/**
+6 -6
View File
@@ -28,7 +28,7 @@ public final class OrderBy<T> implements Serializable {
* Create an empty OrderBy with no associated query.
*/
public OrderBy() {
this.list = new ArrayList<Property>(3);
this.list = new ArrayList<>(3);
}
private OrderBy(List<Property> list) {
@@ -52,7 +52,7 @@ public final class OrderBy<T> implements Serializable {
*/
public OrderBy(Query<T> query, String orderByClause) {
this.query = query;
this.list = new ArrayList<Property>(3);
this.list = new ArrayList<>(3);
parse(orderByClause);
}
@@ -100,11 +100,11 @@ public final class OrderBy<T> implements Serializable {
* Return a copy of this OrderBy with the path trimmed.
*/
public OrderBy<T> copyWithTrim(String path) {
List<Property> newList = new ArrayList<Property>(list.size());
List<Property> newList = new ArrayList<>(list.size());
for (int i = 0; i < list.size(); i++) {
newList.add(list.get(i).copyWithTrim(path));
}
return new OrderBy<T>(newList);
return new OrderBy<>(newList);
}
/**
@@ -141,7 +141,7 @@ public final class OrderBy<T> implements Serializable {
*/
public OrderBy<T> copy() {
OrderBy<T> copy = new OrderBy<T>();
OrderBy<T> copy = new OrderBy<>();
for (int i = 0; i < list.size(); i++) {
copy.add(list.get(i).copy());
}
@@ -370,7 +370,7 @@ public final class OrderBy<T> implements Serializable {
return null;
}
ArrayList<String> wordList = new ArrayList<String>(pairs.length);
ArrayList<String> wordList = new ArrayList<>(pairs.length);
for (int i = 0; i < pairs.length; i++) {
if (!isEmptyString(pairs[i])) {
wordList.add(pairs[i]);
+1 -25
View File
@@ -8,7 +8,7 @@ import java.util.concurrent.Future;
* <p>
* The benefit of using PagedList over just using the normal Query with
* {@link Query#setFirstRow(int)} and {@link Query#setMaxRows(int)} is that it additionally wraps
* functionality that can call {@link Query#findFutureRowCount()} to determine total row count,
* functionality that can call {@link Query#findFutureCount()} to determine total row count,
* total page count etc.
* </p>
* <p>
@@ -44,30 +44,6 @@ import java.util.concurrent.Future;
*
* }</pre>
*
* <h4>Example: typical use including total row count</h4>
* <pre>{@code
*
* // We want to find the first 100 new orders
* // ... 0 means first page
* // ... page size is 100
*
* PagedList<Order> pagedList
* = ebeanServer.find(Order.class)
* .where().eq("status", Order.Status.NEW)
* .order().asc("id")
* .findPagedList(0, 100);
*
* // Optional: initiate the loading of the total
* // row count in a background thread
* pagedList.loadRowCount();
*
* // fetch and return the list in the foreground thread
* List<Order> orders = pagedList.getList();
*
* // get the total row count (from the future)
* int totalRowCount = pagedList.getTotalRowCount();
*
* }</pre>
*
* <h4>Example: No total row count required</h4>
* <pre>{@code
@@ -7,6 +7,8 @@ import javax.persistence.PersistenceException;
*/
public class PersistenceIOException extends PersistenceException {
private static final long serialVersionUID = -7630050437148176148L;
public PersistenceIOException(String msg, Exception cause) {
super(msg, cause);
}
-24
View File
@@ -845,15 +845,6 @@ public interface Query<T> {
*/
int findCount();
/**
* Deprecated in favor of findCount().
* <p>
* Return the count of entities this query should return.
*
* @deprecated
*/
int findRowCount();
/**
* Execute find row count query in a background thread.
* <p>
@@ -866,21 +857,6 @@ public interface Query<T> {
*/
FutureRowCount<T> findFutureCount();
/**
* Deprecated in favor of findFutureCount().
* <p>
* Execute find row count query in a background thread.
* <p>
* This returns a Future object which can be used to cancel, check the
* execution status (isDone etc) and get the value (with or without a
* timeout).
* </p>
*
* @return a Future object for the row count query
* @deprecated
*/
FutureRowCount<T> findFutureRowCount();
/**
* Execute find Id's query in a background thread.
* <p>
+5 -5
View File
@@ -401,7 +401,7 @@ public final class RawSql implements Serializable {
this.parsed = true;
this.propertyMap = null;
this.propertyColumnMap = null;
this.dbColumnMap = new LinkedHashMap<String, Column>();
this.dbColumnMap = new LinkedHashMap<>();
for (int i = 0; i < columns.size(); i++) {
Column c = columns.get(i);
dbColumnMap.put(c.getDbColumnKey(), c);
@@ -416,7 +416,7 @@ public final class RawSql implements Serializable {
this.parsed = false;
this.propertyMap = null;
this.propertyColumnMap = null;
this.dbColumnMap = new LinkedHashMap<String, Column>();
this.dbColumnMap = new LinkedHashMap<>();
}
/**
@@ -426,7 +426,7 @@ public final class RawSql implements Serializable {
this.immutable = false;
this.parsed = false;
this.propertyMap = null;
this.dbColumnMap = new LinkedHashMap<String, Column>();
this.dbColumnMap = new LinkedHashMap<>();
int pos = 0;
for (String prop : propertyNames) {
@@ -443,8 +443,8 @@ public final class RawSql implements Serializable {
this.parsed = parsed;
this.dbColumnMap = dbColumnMap;
HashMap<String, Column> pcMap = new HashMap<String, Column>();
HashMap<String, String> pMap = new HashMap<String, String>();
HashMap<String, Column> pcMap = new HashMap<>();
HashMap<String, String> pMap = new HashMap<>();
for (Column c : dbColumnMap.values()) {
pMap.put(c.getPropertyName(), c.getDbColumn());
@@ -1,167 +0,0 @@
package com.avaje.ebean;
class SimpleTextParser {
private final String oql;
private final char[] chars;
private final int eof;
private int pos;
private String word;
private String lowerWord;
SimpleTextParser(String oql) {
this.oql = oql;
this.chars = oql.toCharArray();
this.eof = oql.length();
}
public int getPos() {
return pos;
}
public String getWord() {
return word;
}
public String peekNextWord() {
int origPos = pos;
String nw = nextWordInternal();
pos = origPos;
return nw;
}
/**
* Match the current and the next word.
*/
public boolean isMatch(String lowerMatch, String nextWordMatch) {
if (isMatch(lowerMatch)) {
String nw = peekNextWord();
if (nw != null) {
nw = nw.toLowerCase();
return nw.equals(nextWordMatch);
}
}
return false;
}
public boolean isFinished() {
return word == null;
}
public int findWordLower(String lowerMatch, int afterPos) {
this.pos = afterPos;
return findWordLower(lowerMatch);
}
public int findWordLower(String lowerMatch) {
do {
if (nextWord() == null) {
return -1;
}
if (lowerMatch.equals(lowerWord)) {
return pos - lowerWord.length();
}
} while (true);
}
/**
* Match the current word.
*/
public boolean isMatch(String lowerMatch) {
return lowerMatch.equals(lowerWord);
}
public String nextWord() {
word = nextWordInternal();
if (word != null) {
lowerWord = word.toLowerCase();
}
return word;
}
private String nextWordInternal() {
trimLeadingWhitespace();
if (pos >= eof) {
return null;
}
int start = pos;
if (chars[pos] == '(') {
moveToClose();
} else {
moveToEndOfWord();
}
return oql.substring(start, pos);
}
private void moveToClose() {
pos++;
int openParenthesisCount = 0;
for (; pos < eof; pos++) {
char c = chars[pos];
if (c == '(') {
// count nested parenthesis
openParenthesisCount++;
} else if (c == ')') {
if (openParenthesisCount > 0) {
// still in nested parenthesis
--openParenthesisCount;
} else {
// we have found the end
pos++;
return;
}
}
}
}
private void moveToEndOfWord() {
char c = chars[pos];
boolean isOperator = isOperator(c);
for (; pos < eof; pos++) {
c = chars[pos];
if (isWordTerminator(c, isOperator)) {
return;
}
}
}
private boolean isWordTerminator(char c, boolean isOperator) {
if (Character.isWhitespace(c)) {
return true;
}
if (isOperator(c)) {
return !isOperator;
}
return c == '(' || isOperator;
}
private boolean isOperator(char c) {
switch (c) {
case '<':
return true;
case '>':
return true;
case '=':
return true;
case '!':
return true;
default:
return false;
}
}
private void trimLeadingWhitespace() {
for (; pos < eof; pos++) {
char c = chars[pos];
if (!Character.isWhitespace(c)) {
break;
}
}
}
}
+4 -4
View File
@@ -282,7 +282,7 @@ public final class TxScope {
*/
public TxScope setRollbackFor(Class<? extends Throwable> rollbackThrowable) {
if (rollbackFor == null) {
rollbackFor = new ArrayList<Class<? extends Throwable>>(2);
rollbackFor = new ArrayList<>(2);
}
rollbackFor.add(rollbackThrowable);
return this;
@@ -294,7 +294,7 @@ public final class TxScope {
@SuppressWarnings("unchecked")
public TxScope setRollbackFor(Class<?>[] rollbackThrowables) {
if (rollbackFor == null) {
rollbackFor = new ArrayList<Class<? extends Throwable>>(rollbackThrowables.length);
rollbackFor = new ArrayList<>(rollbackThrowables.length);
}
for (int i = 0; i < rollbackThrowables.length; i++) {
rollbackFor.add((Class<? extends Throwable>) rollbackThrowables[i]);
@@ -316,7 +316,7 @@ public final class TxScope {
*/
public TxScope setNoRollbackFor(Class<? extends Throwable> noRollback) {
if (noRollbackFor == null) {
noRollbackFor = new ArrayList<Class<? extends Throwable>>(2);
noRollbackFor = new ArrayList<>(2);
}
this.noRollbackFor.add(noRollback);
return this;
@@ -328,7 +328,7 @@ public final class TxScope {
@SuppressWarnings("unchecked")
public TxScope setNoRollbackFor(Class<?>[] noRollbacks) {
if (noRollbackFor == null) {
noRollbackFor = new ArrayList<Class<? extends Throwable>>(noRollbacks.length);
noRollbackFor = new ArrayList<>(noRollbacks.length);
}
for (int i = 0; i < noRollbacks.length; i++) {
noRollbackFor.add((Class<? extends Throwable>) noRollbacks[i]);
@@ -57,7 +57,7 @@ package com.avaje.ebean;
* where id in (
* select t0.id c0
* from o_customer t0
* left outer join o_address t1 on t1.id = t0.billing_address_id
* left join o_address t1 on t1.id = t0.billing_address_id
* where t0.status = ?
* and t1.country_code = ?
* and t0.id > ? )
@@ -0,0 +1,50 @@
package com.avaje.ebean.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Specify a property to be an aggregation formula.
* <p>
* The aggregation formula should be a sum, count, avg, min or max.
* By default aggregation properties are treated as transient and not
* included in a query. To populate the aggregation property it must be
* explicitly included in the select().
* </p>
*
* <h3>Example:</h3>
* <pre>{@code
*
* @Aggregation("count(details)")
* Long totalCount;
*
* @Aggregation("sum(details.quantity*details.unitPrice)")
* Long totalAmount;
*
* }</pre>
*
* <h3>Example query</h3>
* <pre>{@code
*
* List<TEventOne> list = Ebean.find(TEventOne.class)
* .select("name, totalCount, totalUnits, totalAmount")
* .where()
* .startsWith("logs.description", "a")
* .having()
* .ge("count", 1)
* .orderBy().asc("name")
* .findList();
*
* }</pre>
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Aggregation {
/**
* Aggregation formula using sum, count, avg, min, max.
*/
String value();
}
@@ -82,7 +82,7 @@ public @interface Formula {
* as count, sum etc.
* </p>
* <p>
* The join string should start with either "left outer join" or "join".
* The join string should start with either "left join" or "join".
* </p>
*
* <p>
@@ -587,7 +587,7 @@ public final class EntityBeanIntercept implements Serializable {
if (fullyLoadedBean) {
return null;
}
Set<String> props = new LinkedHashSet<String>();
Set<String> props = new LinkedHashSet<>();
for (int i=0; i<loadedProps.length; i++) {
if (loadedProps[i]) {
props.add(getProperty(i));
@@ -617,7 +617,7 @@ public final class EntityBeanIntercept implements Serializable {
* Return the set of dirty properties.
*/
public Set<String> getDirtyPropertyNames() {
Set<String> props = new LinkedHashSet<String>();
Set<String> props = new LinkedHashSet<>();
addDirtyPropertyNames(props, null);
return props;
}
@@ -666,7 +666,7 @@ public final class EntityBeanIntercept implements Serializable {
* Return a map of dirty properties with their new and old values.
*/
public Map<String,ValuePair> getDirtyValues() {
Map<String,ValuePair> dirtyValues = new LinkedHashMap<String, ValuePair>();
Map<String,ValuePair> dirtyValues = new LinkedHashMap<>();
addDirtyPropertyValues(dirtyValues, null);
return dirtyValues;
}
@@ -29,7 +29,7 @@ public final class NodeUsageCollector {
/**
* The properties used at this profile point.
*/
private final Set<String> used = new LinkedHashSet<String>();
private final Set<String> used = new LinkedHashSet<>();
/**
* set to true if the bean is modified (setter called)
@@ -159,7 +159,7 @@ public abstract class AbstractBeanCollection<E> implements BeanCollection<E> {
protected ModifyHolder<E> getModifyHolder() {
if (modifyHolder == null) {
modifyHolder = new ModifyHolder<E>();
modifyHolder = new ModifyHolder<>();
}
return modifyHolder;
}
@@ -37,7 +37,7 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
* Uses an ArrayList as the underlying List implementation.
*/
public BeanList() {
this(new ArrayList<E>());
this(new ArrayList<>());
}
/**
@@ -68,7 +68,7 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
@SuppressWarnings("unchecked")
public void loadFrom(BeanCollection<?> other) {
if (list == null) {
list = new ArrayList<E>();
list = new ArrayList<>();
}
list.addAll((Collection<? extends E>) other.getActualDetails());
}
@@ -76,7 +76,7 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
@SuppressWarnings("unchecked")
public void internalAdd(Object bean) {
if (list == null) {
list = new ArrayList<E>();
list = new ArrayList<>();
}
if (bean != null) {
list.add((E) bean);
@@ -92,7 +92,7 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
public boolean checkEmptyLazyLoad() {
if (list == null) {
list = new ArrayList<E>();
list = new ArrayList<>();
return true;
} else {
return false;
@@ -105,7 +105,7 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
if (!disableLazyLoad && modifyListening) {
lazyLoadCollection(true);
} else {
list = new ArrayList<E>();
list = new ArrayList<>();
}
}
}
@@ -115,7 +115,7 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
synchronized (this) {
if (list == null) {
if (disableLazyLoad) {
list = new ArrayList<E>();
list = new ArrayList<>();
} else {
lazyLoadCollection(false);
}
@@ -296,11 +296,11 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
public Iterator<E> iterator() {
init();
if (isReadOnly()) {
return new ReadOnlyListIterator<E>(list.listIterator());
return new ReadOnlyListIterator<>(list.listIterator());
}
if (modifyListening) {
Iterator<E> it = list.iterator();
return new ModifyIterator<E>(this, it);
return new ModifyIterator<>(this, it);
}
return list.iterator();
}
@@ -313,11 +313,11 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
public ListIterator<E> listIterator() {
init();
if (isReadOnly()) {
return new ReadOnlyListIterator<E>(list.listIterator());
return new ReadOnlyListIterator<>(list.listIterator());
}
if (modifyListening) {
ListIterator<E> it = list.listIterator();
return new ModifyListIterator<E>(this, it);
return new ModifyListIterator<>(this, it);
}
return list.listIterator();
}
@@ -325,11 +325,11 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
public ListIterator<E> listIterator(int index) {
init();
if (isReadOnly()) {
return new ReadOnlyListIterator<E>(list.listIterator(index));
return new ReadOnlyListIterator<>(list.listIterator(index));
}
if (modifyListening) {
ListIterator<E> it = list.listIterator(index);
return new ModifyListIterator<E>(this, it);
return new ModifyListIterator<>(this, it);
}
return list.listIterator(index);
}
@@ -425,7 +425,7 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
return Collections.unmodifiableList(list.subList(fromIndex, toIndex));
}
if (modifyListening) {
return new ModifyList<E>(this, list.subList(fromIndex, toIndex));
return new ModifyList<>(this, list.subList(fromIndex, toIndex));
}
return list.subList(fromIndex, toIndex);
}
@@ -33,7 +33,7 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
* Create using a underlying LinkedHashMap.
*/
public BeanMap() {
this(new LinkedHashMap<K, E>());
this(new LinkedHashMap<>());
}
public BeanMap(BeanCollectionLoader ebeanServer, EntityBean ownerBean, String propertyName) {
@@ -61,14 +61,14 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
public void internalPutNull() {
if (map == null) {
map = new LinkedHashMap<K, E>();
map = new LinkedHashMap<>();
}
}
@SuppressWarnings("unchecked")
public void internalPut(Object key, Object bean) {
if (map == null) {
map = new LinkedHashMap<K, E>();
map = new LinkedHashMap<>();
}
if (key != null) {
map.put((K) key, (E) bean);
@@ -108,7 +108,7 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
public boolean checkEmptyLazyLoad() {
if (map == null) {
map = new LinkedHashMap<K, E>();
map = new LinkedHashMap<>();
return true;
} else {
return false;
@@ -121,7 +121,7 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
if (modifyListening) {
lazyLoadCollection(true);
} else {
map = new LinkedHashMap<K, E>();
map = new LinkedHashMap<>();
}
}
}
@@ -265,7 +265,6 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
return map.put(key, value);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public void putAll(Map<? extends K, ? extends E> puts) {
checkReadOnly();
init();
@@ -314,7 +313,7 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
}
if (modifyListening) {
Collection<E> c = map.values();
return new ModifyCollection<E>(this, c);
return new ModifyCollection<>(this, c);
}
return map.values();
}
@@ -34,7 +34,7 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
* Create using an underlying LinkedHashSet.
*/
public BeanSet() {
this(new LinkedHashSet<E>());
this(new LinkedHashSet<>());
}
public BeanSet(BeanCollectionLoader loader, EntityBean ownerBean, String propertyName) {
@@ -61,7 +61,7 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
@SuppressWarnings("unchecked")
public void loadFrom(BeanCollection<?> other) {
if (set == null) {
set = new LinkedHashSet<E>();
set = new LinkedHashSet<>();
}
set.addAll((Collection<? extends E>) other.getActualDetails());
}
@@ -76,7 +76,7 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
@SuppressWarnings("unchecked")
public void internalAdd(Object bean) {
if (set == null) {
set = new LinkedHashSet<E>();
set = new LinkedHashSet<>();
}
if (bean != null) {
set.add((E) bean);
@@ -100,7 +100,7 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
public boolean checkEmptyLazyLoad() {
if (set == null) {
set = new LinkedHashSet<E>();
set = new LinkedHashSet<>();
return true;
} else {
return false;
@@ -113,7 +113,7 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
if (modifyListening) {
lazyLoadCollection(true);
} else {
set = new LinkedHashSet<E>();
set = new LinkedHashSet<>();
}
}
}
@@ -256,10 +256,10 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
public Iterator<E> iterator() {
init();
if (isReadOnly()) {
return new ReadOnlyIterator<E>(set.iterator());
return new ReadOnlyIterator<>(set.iterator());
}
if (modifyListening) {
return new ModifyIterator<E>(this, set.iterator());
return new ModifyIterator<>(this, set.iterator());
}
return set.iterator();
}
@@ -72,7 +72,7 @@ class ModifyCollection<E> implements Collection<E> {
@Override
public Iterator<E> iterator() {
Iterator<E> it = c.iterator();
return new ModifyIterator<E>(owner, it);
return new ModifyIterator<>(owner, it);
}
@Override
@@ -21,16 +21,16 @@ class ModifyHolder<E> implements Serializable {
/**
* Deletions list for manyToMany persistence.
*/
private Set<E> modifyDeletions = new LinkedHashSet<E>();
private Set<E> modifyDeletions = new LinkedHashSet<>();
/**
* Additions list for manyToMany persistence.
*/
private Set<E> modifyAdditions = new LinkedHashSet<E>();
private Set<E> modifyAdditions = new LinkedHashSet<>();
void reset() {
modifyDeletions = new LinkedHashSet<E>();
modifyAdditions = new LinkedHashSet<E>();
modifyDeletions = new LinkedHashSet<>();
modifyAdditions = new LinkedHashSet<>();
}
/**
@@ -61,11 +61,11 @@ class ModifyList<E> extends ModifyCollection<E> implements List<E> {
}
public ListIterator<E> listIterator() {
return new ModifyListIterator<E>(owner, list.listIterator());
return new ModifyListIterator<>(owner, list.listIterator());
}
public ListIterator<E> listIterator(int index) {
return new ModifyListIterator<E>(owner, list.listIterator(index));
return new ModifyListIterator<>(owner, list.listIterator(index));
}
public E remove(int index) {
@@ -82,7 +82,7 @@ class ModifyList<E> extends ModifyCollection<E> implements List<E> {
}
public List<E> subList(int fromIndex, int toIndex) {
return new ModifyList<E>(owner, list.subList(fromIndex, toIndex));
return new ModifyList<>(owner, list.subList(fromIndex, toIndex));
}
}
@@ -91,7 +91,7 @@ public class ClassLoadConfig {
/**
* Return true if the given class is present.
*/
protected boolean isPresent(String className) {
public boolean isPresent(String className) {
try {
forName(className);
return true;
@@ -0,0 +1,54 @@
package com.avaje.ebean.config;
import com.avaje.ebean.config.dbplatform.DbType;
/**
* Custom mappings for DB types that override the default.
*
* @see ServerConfig#addCustomMapping(DbType, String)
*/
public class CustomDbTypeMapping {
protected final DbType type;
protected final String columnDefinition;
protected final Platform platform;
/**
* Create a mapping.
*/
public CustomDbTypeMapping(DbType type, String columnDefinition, Platform platform) {
this.type = type;
this.columnDefinition = columnDefinition;
this.platform = platform;
}
/**
* Create a mapping that should apply to all the database platforms.
*/
public CustomDbTypeMapping(DbType type, String columnDefinition) {
this(type, columnDefinition, null);
}
/**
* Return the DB type the mapping applies to.
*/
public DbType getType() {
return type;
}
/**
* Return the DB column definition to use.
*/
public String getColumnDefinition() {
return columnDefinition;
}
/**
* Return the platform this mapping should apply to. Null means it applied to all platforms.
*/
public Platform getPlatform() {
return platform;
}
}
@@ -1,7 +1,6 @@
package com.avaje.ebean.config;
import com.avaje.ebean.EbeanServer;
import com.avaje.ebean.config.dbplatform.DbPlatformName;
import com.avaje.ebean.dbmigration.DbMigration;
import org.avaje.dbmigration.MigrationConfig;
import org.avaje.dbmigration.MigrationRunner;
@@ -20,7 +19,7 @@ public class DbMigrationConfig {
/**
* The database platform to generate migration DDL for.
*/
protected DbPlatformName platform;
protected Platform platform;
/**
* Set to true if the DB migration should be generated on server start.
@@ -112,14 +111,14 @@ public class DbMigrationConfig {
* We typically need to explicitly specify this as migration can often be generated
* when running against H2.
*/
public DbPlatformName getPlatform() {
public Platform getPlatform() {
return platform;
}
/**
* Set the DB platform to generate migration DDL for.
*/
public void setPlatform(DbPlatformName platform) {
public void setPlatform(Platform platform) {
this.platform = platform;
}
@@ -366,7 +365,7 @@ public class DbMigrationConfig {
includeGeneratedFileComment = properties.getBoolean("migration.includeGeneratedFileComment", includeGeneratedFileComment);
generatePendingDrop = properties.get("migration.generatePendingDrop", generatePendingDrop);
platform = properties.getEnum(DbPlatformName.class, "migration.platform", platform);
platform = properties.getEnum(Platform.class, "migration.platform", platform);
generate = properties.getBoolean("migration.generate", generate);
version = properties.get("migration.version", version);
@@ -1,9 +1,9 @@
package com.avaje.ebean.config.dbplatform;
package com.avaje.ebean.config;
/**
* Built in supported platforms.
*/
public enum DbPlatformName {
public enum Platform {
/**
* Generic base platform configured via properties or code.
@@ -16,7 +16,7 @@ public final class PropertyMap implements Serializable {
private static final long serialVersionUID = 1L;
private final LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
private final LinkedHashMap<String, String> map = new LinkedHashMap<>();
/**
* Return properties loaded from test-ebean.properties.
@@ -7,9 +7,11 @@ import com.avaje.ebean.cache.ServerCacheManager;
import com.avaje.ebean.cache.ServerCachePlugin;
import com.avaje.ebean.config.dbplatform.DatabasePlatform;
import com.avaje.ebean.config.dbplatform.DbEncrypt;
import com.avaje.ebean.config.dbplatform.DbType;
import com.avaje.ebean.event.BeanFindController;
import com.avaje.ebean.event.BeanPersistController;
import com.avaje.ebean.event.BeanPersistListener;
import com.avaje.ebean.event.BeanPostConstructListener;
import com.avaje.ebean.event.BeanPostLoad;
import com.avaje.ebean.event.BeanQueryAdapter;
import com.avaje.ebean.event.BulkTableEventListener;
@@ -73,16 +75,24 @@ public class ServerConfig {
/**
* The EbeanServer name.
*/
private String name;
private String name = "db";
/**
* When false (default) H2 automatically uses DDL generate and run
* (i.e. assumes we are running tests using in memory h2).
*/
private boolean h2ProductionMode;
/**
* Typically configuration type objects that are passed by this ServerConfig
* to plugins. For example - IgniteConfiguration passed to Ignite plugin.
*/
private Map<String, Object> serviceObject = new HashMap<String, Object>();
private Map<String, Object> serviceObject = new HashMap<>();
private ContainerConfig containerConfig;
private List<CustomDbTypeMapping> customDbTypeMappings = new ArrayList<>();
/**
* The underlying properties that were used during configuration.
*/
@@ -101,24 +111,29 @@ public class ServerConfig {
/**
* Set to true if this is the default/primary server.
*/
private boolean defaultServer;
private boolean defaultServer = true;
/**
* Set this to true to disable class path search.
*/
private boolean disableClasspathSearch;
/**
* The Geometry SRID value (default 4326).
*/
private int geometrySRID = 4326;
/**
* List of interesting classes such as entities, embedded, ScalarTypes,
* Listeners, Finders, Controllers etc.
*/
private List<Class<?>> classes = new ArrayList<Class<?>>();
private List<Class<?>> classes = new ArrayList<>();
/**
* The packages that are searched for interesting classes. Only used when
* classes is empty/not explicitly specified.
*/
private List<String> packages = new ArrayList<String>();
private List<String> packages = new ArrayList<>();
/**
* Configuration for the ElasticSearch integration.
@@ -322,14 +337,15 @@ public class ServerConfig {
private DbUuid dbUuid = DbUuid.AUTO_VARCHAR;
private List<IdGenerator> idGenerators = new ArrayList<IdGenerator>();
private List<BeanFindController> findControllers = new ArrayList<BeanFindController>();
private List<BeanPersistController> persistControllers = new ArrayList<BeanPersistController>();
private List<BeanPostLoad> postLoaders = new ArrayList<BeanPostLoad>();
private List<BeanPersistListener> persistListeners = new ArrayList<BeanPersistListener>();
private List<BeanQueryAdapter> queryAdapters = new ArrayList<BeanQueryAdapter>();
private List<BulkTableEventListener> bulkTableEventListeners = new ArrayList<BulkTableEventListener>();
private List<ServerConfigStartup> configStartupListeners = new ArrayList<ServerConfigStartup>();
private List<IdGenerator> idGenerators = new ArrayList<>();
private List<BeanFindController> findControllers = new ArrayList<>();
private List<BeanPersistController> persistControllers = new ArrayList<>();
private List<BeanPostLoad> postLoaders = new ArrayList<>();
private List<BeanPostConstructListener> postConstructListeners = new ArrayList<>();
private List<BeanPersistListener> persistListeners = new ArrayList<>();
private List<BeanQueryAdapter> queryAdapters = new ArrayList<>();
private List<BulkTableEventListener> bulkTableEventListeners = new ArrayList<>();
private List<ServerConfigStartup> configStartupListeners = new ArrayList<>();
/**
* By default inserts are included in the change log.
@@ -499,6 +515,27 @@ public class ServerConfig {
this.name = name;
}
/**
* Return true if H2 should be used in production mode.
* <p>
* Otherwise it is assumed we are using H2 for testing and DDL generate and run is turned on.
* </p>
*/
public boolean isH2ProductionMode() {
return h2ProductionMode;
}
/**
* Set to true for H2 to be used in production mode.
* <p>
* Do this when we want to use H2 and not have the DDL generation and run automatically turned on.
* Otherwise it is assumed we are using H2 for testing purposes.
* </p>
*/
public void setH2ProductionMode(boolean h2ProductionMode) {
this.h2ProductionMode = h2ProductionMode;
}
/**
* Return the container / clustering configuration.
* <p/>
@@ -553,7 +590,7 @@ public class ServerConfig {
}
/**
* Set true if this EbeanServer should be registered as the "default" server
* Set false if you do not want this EbeanServer to be registered as the "default" server
* with the Ebean singleton.
* <p>
* This is only used when {@link #setRegister(boolean)} is also true.
@@ -871,6 +908,20 @@ public class ServerConfig {
this.migrationConfig = migrationConfig;
}
/**
* Return the Geometry SRID.
*/
public int getGeometrySRID() {
return geometrySRID;
}
/**
* Set the Geometry SRID.
*/
public void setGeometrySRID(int geometrySRID) {
this.geometrySRID = geometrySRID;
}
/**
* Return the time zone to use when reading/writing Timestamps via JDBC.
* <p>
@@ -1420,6 +1471,11 @@ public class ServerConfig {
*/
public void setDatabasePlatform(DatabasePlatform databasePlatform) {
this.databasePlatform = databasePlatform;
if (!h2ProductionMode && databasePlatform != null && databasePlatform.isPlatform(Platform.H2)) {
// we are using H2 to run tests so turn on DDL generation and run
this.ddlGenerate = true;
this.ddlRun = true;
}
}
/**
@@ -1437,7 +1493,7 @@ public class ServerConfig {
* <p>
* You can also set this in ebean.proprerties:
* </p>
*
* <p>
* <pre>{@code
* # set via ebean.properties
* ebean.encryptKeyManager=com.avaje.tests.basic.encrypt.BasicEncyptKeyManager
@@ -1702,7 +1758,7 @@ public class ServerConfig {
*/
public void addClass(Class<?> cls) {
if (classes == null) {
classes = new ArrayList<Class<?>>();
classes = new ArrayList<>();
}
classes.add(cls);
}
@@ -1715,7 +1771,7 @@ public class ServerConfig {
*/
public void addPackage(String packageName) {
if (packages == null) {
packages = new ArrayList<String>();
packages = new ArrayList<>();
}
packages.add(packageName);
}
@@ -1770,7 +1826,7 @@ public class ServerConfig {
* queries that normally hit L2 bean cache automatically will not do so after a write/persist
* on the transaction.
* </p>
*
* <p>
* <pre>{@code
*
* // assume Customer has L2 bean caching enabled ...
@@ -1932,6 +1988,54 @@ public class ServerConfig {
this.resourceDirectory = resourceDirectory;
}
/**
* Add a custom type mapping.
* <p>
* <pre>{@code
*
* // set the default mapping for BigDecimal.class/decimal
* serverConfig.addCustomMapping(DbType.DECIMAL, "decimal(18,6)");
*
* // set the default mapping for String.class/varchar but only for Postgres
* serverConfig.addCustomMapping(DbType.VARCHAR, "text", Platform.POSTGRES);
*
* }</pre>
*
* @param type The DB type this mapping should apply to
* @param columnDefinition The column definition that should be used
* @param platform Optionally specify the platform this mapping should apply to.
*/
public void addCustomMapping(DbType type, String columnDefinition, Platform platform) {
customDbTypeMappings.add(new CustomDbTypeMapping(type, columnDefinition, platform));
}
/**
* Add a custom type mapping that applies to all platforms.
* <p>
* <pre>{@code
*
* // set the default mapping for BigDecimal/decimal
* serverConfig.addCustomMapping(DbType.DECIMAL, "decimal(18,6)");
*
* // set the default mapping for String/varchar
* serverConfig.addCustomMapping(DbType.VARCHAR, "text");
*
* }</pre>
*
* @param type The DB type this mapping should apply to
* @param columnDefinition The column definition that should be used
*/
public void addCustomMapping(DbType type, String columnDefinition) {
customDbTypeMappings.add(new CustomDbTypeMapping(type, columnDefinition));
}
/**
* Return the list of custom type mappings.
*/
public List<CustomDbTypeMapping> getCustomTypeMappings() {
return customDbTypeMappings;
}
/**
* Register a BeanQueryAdapter instance.
* <p>
@@ -2004,6 +2108,16 @@ public class ServerConfig {
postLoaders.add(postLoad);
}
/**
* Register a BeanPostConstructListener instance.
* <p>
* Note alternatively you can use {@link #setPostConstructListeners(List)} to set
* all the BeanPostConstructListener instances.
* </p>
*/
public void add(BeanPostConstructListener listener) {
postConstructListeners.add(listener);
}
/**
* Return the list of BeanFindController instances.
*/
@@ -2032,6 +2146,19 @@ public class ServerConfig {
this.postLoaders = postLoaders;
}
/**
* Return the list of BeanPostLoader instances.
*/
public List<BeanPostConstructListener> getPostConstructListeners() {
return postConstructListeners;
}
/**
* Set the list of BeanPostLoader instances.
*/
public void setPostConstructListeners(List<BeanPostConstructListener> listeners) {
this.postConstructListeners = listeners;
}
/**
* Return the BeanPersistController instances.
*/
@@ -2216,7 +2343,6 @@ public class ServerConfig {
* @param key properties key
* @param instance existing instance
*/
@SuppressWarnings("unchecked")
protected <T> T createInstance(PropertiesWrapper properties, Class<T> pluginType, String key, T instance) {
if (instance != null) {
@@ -2232,6 +2358,7 @@ public class ServerConfig {
* @param pluginType the type of plugin
* @param classname the implementation class as per properties
*/
@SuppressWarnings("unchecked")
protected <T> T createInstance(Class<T> pluginType, String classname) {
return classname == null ? null : (T) classLoadConfig.newInstance(classname);
}
@@ -2287,6 +2414,7 @@ public class ServerConfig {
}
loadDocStoreSettings(p);
geometrySRID = p.getInt("geometrySRID", geometrySRID);
disableL2Cache = p.getBoolean("disableL2Cache", disableL2Cache);
explicitTransactionBeginMode = p.getBoolean("explicitTransactionBeginMode", explicitTransactionBeginMode);
autoCommitMode = p.getBoolean("autoCommitMode", autoCommitMode);
@@ -2364,6 +2492,7 @@ public class ServerConfig {
jsonDateTime = JsonConfig.DateTime.MILLIS;
}
h2ProductionMode = p.getBoolean("h2ProductionMode", h2ProductionMode);
ddlGenerate = p.getBoolean("ddl.generate", ddlGenerate);
ddlRun = p.getBoolean("ddl.run", ddlRun);
ddlCreateOnly = p.getBoolean("ddl.createOnly", ddlCreateOnly);
@@ -2392,7 +2521,7 @@ public class ServerConfig {
return classes;
}
List<Class<?>> classes = new ArrayList<Class<?>>();
List<Class<?>> classes = new ArrayList<>();
String[] split = classNames.split("[ ,;]");
for (int i = 0; i < split.length; i++) {
@@ -2411,7 +2540,7 @@ public class ServerConfig {
private List<String> getSearchJarsPackages(String searchPackages) {
List<String> hitList = new ArrayList<String>();
List<String> hitList = new ArrayList<>();
if (searchPackages != null) {
@@ -24,9 +24,9 @@ public class DB2Platform extends DatabasePlatform {
this.dbIdentity.setSupportsSequence(true);
booleanDbType = Types.BOOLEAN;
dbTypeMap.put(Types.REAL, new DbType("real"));
dbTypeMap.put(Types.TINYINT, new DbType("smallint"));
dbTypeMap.put(Types.DECIMAL, new DbType("decimal", 15));
dbTypeMap.put(DbType.REAL, new DbPlatformType("real"));
dbTypeMap.put(DbType.TINYINT, new DbPlatformType("smallint"));
dbTypeMap.put(DbType.DECIMAL, new DbPlatformType("decimal", 15));
}
/**
@@ -2,7 +2,9 @@ package com.avaje.ebean.config.dbplatform;
import com.avaje.ebean.BackgroundExecutor;
import com.avaje.ebean.Query;
import com.avaje.ebean.config.CustomDbTypeMapping;
import com.avaje.ebean.config.PersistBatch;
import com.avaje.ebean.config.Platform;
import com.avaje.ebean.config.ServerConfig;
import com.avaje.ebean.dbmigration.ddlgeneration.DdlHandler;
import com.avaje.ebean.dbmigration.ddlgeneration.platform.PlatformDdl;
@@ -73,7 +75,7 @@ public class DatabasePlatform {
/**
* Mapping of JDBC to Database types.
*/
protected DbTypeMap dbTypeMap = new DbTypeMap();
protected DbPlatformTypeMapping dbTypeMap = new DbPlatformTypeMapping();
/**
* Default values for DB columns.
@@ -180,6 +182,26 @@ public class DatabasePlatform {
*/
public void configure(ServerConfig serverConfig) {
dbTypeMap.config(nativeUuidType, serverConfig.getDbUuid());
for (CustomDbTypeMapping mapping : serverConfig.getCustomTypeMappings()) {
if (platformMatch(mapping.getPlatform())) {
dbTypeMap.put(mapping.getType(), parse(mapping.getColumnDefinition()));
}
}
}
private DbPlatformType parse(String columnDefinition) {
return DbPlatformType.parse(columnDefinition);
}
private boolean platformMatch(Platform platform) {
return platform == null || platform.name().equalsIgnoreCase(name);
}
/**
* Return true if this matches the given platform.
*/
public boolean isPlatform(Platform platform) {
return platform.name().equalsIgnoreCase(name);
}
/**
@@ -309,7 +331,7 @@ public class DatabasePlatform {
*
* @return the db type map
*/
public DbTypeMap getDbTypeMap() {
public DbPlatformTypeMapping getDbTypeMap() {
return dbTypeMap;
}
@@ -23,7 +23,7 @@ public class DbDefaultValue {
*/
public static final String NOW = "now";
protected Map<String,String> map = new LinkedHashMap<String,String>();
protected Map<String,String> map = new LinkedHashMap<>();
/**
* Set the DB now function.
@@ -135,9 +135,9 @@ public class DbIdentity {
return supportsSequence ? IdType.SEQUENCE : idType;
case IDENTITY:
return supportsIdentity ? IdType.IDENTITY : idType;
default:
return idType;
}
// use the default
return idType;
}
}
@@ -0,0 +1,158 @@
package com.avaje.ebean.config.dbplatform;
/**
* Represents a DB type with name, length, precision, and scale.
* <p>
* The length is for VARCHAR types and precision/scale for DECIMAL types.
* </p>
*/
public class DbPlatformType implements ExtraDbTypes {
/**
* The data type name (VARCHAR, INTEGER ...)
*/
private final String name;
/**
* The default length or precision.
*/
private final int defaultLength;
/**
* The default scale (decimal).
*/
private final int defaultScale;
/**
* Set to true if the type should never have a length or scale.
*/
private final boolean canHaveLength;
/**
* Parse a type definition into a DbPlatformType.
* <p>
* e.g. "decimal(18,6)"
* e.g. "text"
* </p>
*/
public static DbPlatformType parse(String columnDefinition) {
return DbPlatformTypeParser.parse(columnDefinition);
}
/**
* Construct with no length or scale.
*/
public DbPlatformType(String name) {
this(name, 0, 0);
}
/**
* Construct with a given length.
*/
public DbPlatformType(String name, int defaultLength) {
this(name, defaultLength, 0);
}
/**
* Construct for Decimal with precision and scale.
*/
public DbPlatformType(String name, int defaultPrecision, int defaultScale) {
this.name = name;
this.defaultLength = defaultPrecision;
this.defaultScale = defaultScale;
this.canHaveLength = true;
}
/**
* Use with canHaveLength=false for types that should never have a length.
*
* @param name
* the type name
* @param canHaveLength
* set this to false for type that should never have a length
*/
public DbPlatformType(String name, boolean canHaveLength) {
this.name = name;
this.defaultLength = 0;
this.defaultScale = 0;
this.canHaveLength = canHaveLength;
}
/**
* Return the type name.
*/
public String getName() {
return name;
}
/**
* Return the default length/precision.
*/
public int getDefaultLength() {
return defaultLength;
}
/**
* Return the default scale.
*/
public int getDefaultScale() {
return defaultScale;
}
/**
* Return the type for a specific property that incorporates the name, length,
* precision and scale.
* <p>
* The deployLength and deployScale are for the property we are rendering the
* DB type for.
* </p>
*
* @param deployLength
* the length or precision defined by deployment on a specific
* property.
* @param deployScale
* the scale defined by deployment on a specific property.
*/
public String renderType(int deployLength, int deployScale) {
return renderType(deployLength, deployScale, true);
}
/**
* Render the type defining strict mode.
* <p>
* If strict mode if OFF then this will render with a scale value even if
* that is not strictly supported. The reason for supporting this is to enable
* use to use types like jsonb(200) as a "logical" type that maps to JSONB for
* Postgres and VARCHAR(200) for other databases.
* </p>
*/
public String renderType(int deployLength, int deployScale, boolean strict) {
StringBuilder sb = new StringBuilder();
sb.append(name);
if (canHaveLength || !strict) {
// see if there is a precision/scale to add (or not)
int len = deployLength != 0 ? deployLength : defaultLength;
if (len > 0) {
sb.append("(");
sb.append(len);
int scale = deployScale != 0 ? deployScale : defaultScale;
if (scale > 0) {
sb.append(",");
sb.append(scale);
}
sb.append(")");
}
}
return sb.toString();
}
/**
* Create a copy of the type with a new default length.
*/
public DbPlatformType withLength(int defaultLength) {
return new DbPlatformType(name, defaultLength);
}
}
@@ -0,0 +1,53 @@
package com.avaje.ebean.config.dbplatform;
import java.util.HashMap;
import java.util.Map;
/**
* Helper to reverse lookup a DbType given the name or JDBC int value.
*/
class DbPlatformTypeLookup {
/**
* A map to lookup the type by name.
*/
private Map<String, DbType> nameLookup = new HashMap<>();
/**
* A map to lookup the type by JDBC int value.
*/
private Map<Integer, DbType> idLookup = new HashMap<>();
DbPlatformTypeLookup() {
addAll();
}
/**
* Return the DbType for the given name.
*/
DbType byName(String name) {
return nameLookup.get(name.trim().toUpperCase());
}
/**
* Return the DbType for the given name.
*/
DbType byId(int jdbcId) {
return idLookup.get(jdbcId);
}
private void addAll() {
// Extra mapping for Float and Varchar2
add("FLOAT", DbType.REAL);
add("VARCHAR2", DbType.VARCHAR);
for (DbType type : DbType.values()) {
add(type.name(), type);
}
}
private void add(String name, DbType dbType) {
nameLookup.put(name, dbType);
idLookup.put(dbType.id(), dbType);
}
}
@@ -0,0 +1,193 @@
package com.avaje.ebean.config.dbplatform;
import com.avaje.ebean.config.ServerConfig;
import java.util.HashMap;
import java.util.Map;
/**
* Used to map bean property types to DB specific types for DDL generation.
*/
public class DbPlatformTypeMapping {
private static DbPlatformTypeLookup lookup = new DbPlatformTypeLookup();
private static final DbPlatformType UUID_NATIVE = new DbPlatformType("uuid", false);
private static final DbPlatformType UUID_PLACEHOLDER = new DbPlatformType("uuidPlaceholder");
private static final DbPlatformType JSON_CLOB_PLACEHOLDER = new DbPlatformType("jsonClobPlaceholder");
private static final DbPlatformType JSON_BLOB_PLACEHOLDER = new DbPlatformType("jsonBlobPlaceholder");
private static final DbPlatformType JSON_VARCHAR_PLACEHOLDER = new DbPlatformType("jsonVarcharPlaceholder");
private static final DbPlatformType POINT = new DbPlatformType("point");
private static final DbPlatformType POLYGON = new DbPlatformType("polygon");
private static final DbPlatformType LINESTRING = new DbPlatformType("linestring");
private static final DbPlatformType MULTIPOINT = new DbPlatformType("multipoint");
private static final DbPlatformType MULTILINESTRING = new DbPlatformType("multilinestring");
private static final DbPlatformType MULTIPOLYGON = new DbPlatformType("multipolygon");
private final Map<DbType, DbPlatformType> typeMap = new HashMap<>();
/**
* Return the DbTypeMap with standard (not platform specific) types.
* <p>
* This has some extended JSON types (JSON, JSONB, JSONVarchar, JSONClob, JSONBlob).
* These types get translated to specific database platform types during DDL generation.
*/
public static DbPlatformTypeMapping logicalTypes() {
return new DbPlatformTypeMapping(true);
}
public DbPlatformTypeMapping() {
loadDefaults(false);
}
private DbPlatformTypeMapping(boolean logicalTypes) {
loadDefaults(logicalTypes);
}
/**
* Load the standard types. These can be overridden by DB specific platform.
*/
private void loadDefaults(boolean logicalTypes) {
put(DbType.BOOLEAN);
put(DbType.BIT);
put(DbType.INTEGER);
put(DbType.BIGINT);
put(DbType.DOUBLE);
put(DbType.SMALLINT);
put(DbType.TINYINT);
put(DbType.BLOB);
put(DbType.CLOB);
put(DbType.ARRAY);
put(DbType.DATE);
put(DbType.TIME);
put(DbType.TIMESTAMP);
put(DbType.LONGVARBINARY);
put(DbType.LONGVARCHAR);
// most commonly real maps to db float
put(DbType.REAL, new DbPlatformType("float"));
put(DbType.POINT, POINT);
put(DbType.POLYGON, POLYGON);
put(DbType.LINESTRING, LINESTRING);
put(DbType.MULTIPOINT, MULTIPOINT);
put(DbType.MULTILINESTRING, MULTILINESTRING);
put(DbType.MULTIPOLYGON, MULTIPOLYGON);
if (logicalTypes) {
// keep it logical for 2 layer DDL generation
put(DbType.VARCHAR, new DbPlatformType("varchar"));
put(DbType.DECIMAL, new DbPlatformType("decimal"));
put(DbType.VARBINARY, new DbPlatformType("varbinary"));
put(DbType.BINARY, new DbPlatformType("binary"));
put(DbType.CHAR, new DbPlatformType("char"));
put(DbType.HSTORE, new DbPlatformType("hstore", false));
put(DbType.JSON, new DbPlatformType("json", false));
put(DbType.JSONB, new DbPlatformType("jsonb", false));
put(DbType.JSONCLOB, new DbPlatformType("jsonclob"));
put(DbType.JSONBLOB, new DbPlatformType("jsonblob"));
put(DbType.JSONVARCHAR, new DbPlatformType("jsonvarchar", 1000));
put(DbType.UUID, UUID_NATIVE);
} else {
put(DbType.VARCHAR, new DbPlatformType("varchar", 255));
put(DbType.DECIMAL, new DbPlatformType("decimal", 38));
put(DbType.VARBINARY, new DbPlatformType("varbinary", 255));
put(DbType.BINARY, new DbPlatformType("binary", 255));
put(DbType.CHAR, new DbPlatformType("char", 1));
put(DbType.JSON, JSON_CLOB_PLACEHOLDER); // Postgres maps this to JSON
put(DbType.JSONB, JSON_CLOB_PLACEHOLDER); // Postgres maps this to JSONB
put(DbType.JSONCLOB, JSON_CLOB_PLACEHOLDER);
put(DbType.JSONBLOB, JSON_BLOB_PLACEHOLDER);
put(DbType.JSONVARCHAR, JSON_VARCHAR_PLACEHOLDER);
put(DbType.UUID, UUID_PLACEHOLDER);
}
}
/**
* Lookup the platform specific DbType given the standard sql type name.
*/
public DbPlatformType lookup(String name, boolean withScale) {
DbType type = lookup.byName(name);
if (type == null) {
throw new IllegalArgumentException("Unknown type [" + name + "] - not standard sql type");
}
// handle JSON types mapped to clob, blob and varchar
switch (type) {
case JSONBLOB:
return get(DbType.BLOB);
case JSONCLOB:
return get(DbType.CLOB);
case JSONVARCHAR:
return get(DbType.VARCHAR);
case JSON:
return getJsonType(DbType.JSON, withScale);
case JSONB:
return getJsonType(DbType.JSONB, withScale);
default:
return get(type);
}
}
private DbPlatformType getJsonType(DbType type, boolean withScale) {
DbPlatformType dbType = get(type);
if (dbType == JSON_CLOB_PLACEHOLDER) {
// if we have scale that implies this maps to varchar
return withScale ? get(DbType.VARCHAR) : get(DbType.CLOB);
}
if (dbType == JSON_BLOB_PLACEHOLDER) {
return get(DbType.BLOB);
}
if (dbType == JSON_VARCHAR_PLACEHOLDER) {
return get(DbType.VARCHAR);
}
// Postgres has specific type
return get(type);
}
/**
* Override the type for a given JDBC type.
*/
private void put(DbType type) {
typeMap.put(type, type.createPlatformType());
}
/**
* Override the type for a given JDBC type.
*/
public void put(DbType type, DbPlatformType platformType) {
typeMap.put(type, platformType);
}
/**
* Return the type for a given jdbc type.
*/
public DbPlatformType get(int jdbcType) {
return get(lookup.byId(jdbcType));
}
/**
* Return the type for a given jdbc type.
*/
public DbPlatformType get(DbType dbType) {
return typeMap.get(dbType);
}
/**
* Map the UUID appropriately based on native DB support and ServerConfig.DbUuid.
*/
public void config(boolean nativeUuidType, ServerConfig.DbUuid dbUuid) {
if (nativeUuidType && dbUuid.useNativeType()) {
put(DbType.UUID, UUID_NATIVE);
} else if (dbUuid.useBinary()) {
put(DbType.UUID, get(DbType.BINARY).withLength(16));
} else {
put(DbType.UUID, get(DbType.VARCHAR).withLength(40));
}
}
}
@@ -0,0 +1,40 @@
package com.avaje.ebean.config.dbplatform;
/**
* Parse raw column definitions into DbPlatformType like "decimal(18,6)" and "varchar(20) and "json".
*/
class DbPlatformTypeParser {
/**
* Parse the column definition and return the DbPlatformType.
*/
static DbPlatformType parse(String columnDefinition) {
columnDefinition = columnDefinition.trim();
int openPos = columnDefinition.indexOf('(');
if (openPos == -1) {
return new DbPlatformType(columnDefinition, false);
}
int closePos = columnDefinition.indexOf(')', openPos);
if (closePos == -1) {
return new DbPlatformType(columnDefinition, false);
}
try {
int commaPos = columnDefinition.indexOf(',', openPos);
if (commaPos > -1) {
String type = columnDefinition.substring(0, openPos);
int scale = Integer.parseInt(columnDefinition.substring(openPos + 1, commaPos));
int precision = Integer.parseInt(columnDefinition.substring(commaPos + 1, closePos));
return new DbPlatformType(type, scale, precision);
} else {
String type = columnDefinition.substring(0, openPos);
int scale = Integer.parseInt(columnDefinition.substring(openPos + 1, closePos));
return new DbPlatformType(type, scale);
}
} catch (RuntimeException e) {
return new DbPlatformType(columnDefinition, false);
}
}
}
@@ -1,161 +1,72 @@
package com.avaje.ebean.config.dbplatform;
import java.sql.Types;
/**
* Represents a DB type with name, length, precision, and scale.
* The known DB types that are mapped.
* <p>
* The length is for VARCHAR types and precision/scale for DECIMAL types.
* This includes extra types such as UUID, JSON, JSONB and HSTORE.
* </p>
*/
public class DbType {
public enum DbType {
/**
* DB native UUID type (H2 and Postgres).
*/
public static final int UUID = 5010;
BOOLEAN(Types.BOOLEAN),
BIT(Types.BIT),
INTEGER(Types.INTEGER),
BIGINT(Types.BIGINT),
SMALLINT(Types.SMALLINT),
TINYINT(Types.TINYINT),
REAL(Types.REAL),
//FLOAT(Types.FLOAT),
DOUBLE(Types.DOUBLE),
DECIMAL(Types.DECIMAL),
VARCHAR(Types.VARCHAR),
CHAR(Types.CHAR),
BLOB(Types.BLOB),
CLOB(Types.CLOB),
LONGVARBINARY(Types.LONGVARBINARY),
LONGVARCHAR(Types.LONGVARCHAR),
VARBINARY(Types.VARBINARY),
BINARY(Types.BINARY),
DATE(Types.DATE),
TIME(Types.TIME),
TIMESTAMP(Types.TIMESTAMP),
/**
* Type to map Map content to Postgres HSTORE.
*/
public static final int HSTORE = 5000;
ARRAY(Types.ARRAY),
/**
* Type to map JSON content to Clob or Postgres JSON type.
*/
public static final int JSON = 5001;
UUID(ExtraDbTypes.UUID),
/**
* Type to map JSON content to Clob or Postgres JSONB type.
*/
public static final int JSONB = 5002;
POINT(ExtraDbTypes.POINT),
POLYGON(ExtraDbTypes.POLYGON),
LINESTRING(ExtraDbTypes.LINESTRING),
MULTIPOINT(ExtraDbTypes.MULTIPOINT),
MULTILINESTRING(ExtraDbTypes.MULTILINESTRING),
MULTIPOLYGON(ExtraDbTypes.MULTIPOLYGON),
/**
* Type to map JSON content to VARCHAR.
*/
public static final int JSONVarchar = 5003;
HSTORE(ExtraDbTypes.HSTORE),
JSON(ExtraDbTypes.JSON),
JSONB(ExtraDbTypes.JSONB),
JSONCLOB(ExtraDbTypes.JSONClob),
JSONBLOB(ExtraDbTypes.JSONBlob),
JSONVARCHAR(ExtraDbTypes.JSONVarchar);
/**
* Type to map JSON content to Clob.
*/
public static final int JSONClob = 5004;
private final int id;
/**
* Type to map JSON content to Blob.
*/
public static final int JSONBlob = 5005;
/**
* The data type name (VARCHAR, INTEGER ...)
*/
private final String name;
/**
* The default length or precision.
*/
private final int defaultLength;
/**
* The default scale (decimal).
*/
private final int defaultScale;
/**
* Set to true if the type should never have a length or scale.
*/
private final boolean canHaveLength;
/**
* Construct with no length or scale.
*/
public DbType(String name) {
this(name, 0, 0);
DbType(int id) {
this.id = id;
}
/**
* Construct with a given length.
* Return the JDBC java.sql.Types value.
*/
public DbType(String name, int defaultLength) {
this(name, defaultLength, 0);
public int id() {
return id;
}
/**
* Construct for Decimal with precision and scale.
* Create a platform type without scale or precision.
*/
public DbType(String name, int defaultPrecision, int defaultScale) {
this.name = name;
this.defaultLength = defaultPrecision;
this.defaultScale = defaultScale;
this.canHaveLength = true;
}
/**
* Use with canHaveLength=false for types that should never have a length.
*
* @param name
* the type name
* @param canHaveLength
* set this to false for type that should never have a length
*/
public DbType(String name, boolean canHaveLength) {
this.name = name;
this.defaultLength = 0;
this.defaultScale = 0;
this.canHaveLength = canHaveLength;
}
/**
* Return the type for a specific property that incorporates the name, length,
* precision and scale.
* <p>
* The deployLength and deployScale are for the property we are rendering the
* DB type for.
* </p>
*
* @param deployLength
* the length or precision defined by deployment on a specific
* property.
* @param deployScale
* the scale defined by deployment on a specific property.
*/
public String renderType(int deployLength, int deployScale) {
return renderType(deployLength, deployScale, true);
}
/**
* Render the type defining strict mode.
* <p>
* If strict mode if OFF then this will render with a scale value even if
* that is not strictly supported. The reason for supporting this is to enable
* use to use types like jsonb(200) as a "logical" type that maps to JSONB for
* Postgres and VARCHAR(200) for other databases.
* </p>
*/
public String renderType(int deployLength, int deployScale, boolean strict) {
StringBuilder sb = new StringBuilder();
sb.append(name);
if (canHaveLength || !strict) {
// see if there is a precision/scale to add (or not)
int len = deployLength != 0 ? deployLength : defaultLength;
if (len > 0) {
sb.append("(");
sb.append(len);
int scale = deployScale != 0 ? deployScale : defaultScale;
if (scale > 0) {
sb.append(",");
sb.append(scale);
}
sb.append(")");
}
}
return sb.toString();
}
/**
* Create a copy of the type with a new default length.
*/
public DbType withLength(int defaultLength) {
return new DbType(name, defaultLength);
public DbPlatformType createPlatformType() {
return new DbPlatformType(name().toLowerCase());
}
}
@@ -1,210 +0,0 @@
package com.avaje.ebean.config.dbplatform;
import com.avaje.ebean.config.ServerConfig;
import java.sql.Types;
import java.util.HashMap;
import java.util.Map;
/**
* Used to map bean property types to DB specific types for DDL generation.
*/
public class DbTypeMap {
private static final DbType UUID_NATIVE = new DbType("uuid", false);
private static final DbType UUID_PLACEHOLDER = new DbType("uuidPlaceholder");
private static final DbType JSON_CLOB_PLACEHOLDER = new DbType("jsonClobPlaceholder");
private static final DbType JSON_BLOB_PLACEHOLDER = new DbType("jsonBlobPlaceholder");
private static final DbType JSON_VARCHAR_PLACEHOLDER = new DbType("jsonVarcharPlaceholder");
/**
* A map to reverse lookup the type by name.
* <p>
* Used when converting from logical types to platform types which we
* want to do with 2 phase DDL generation.
*/
static Map<String, Integer> lookup = new HashMap<String, Integer>();
static {
lookup.put("BOOLEAN", Types.BOOLEAN);
lookup.put("BIT", Types.BIT);
lookup.put("INTEGER", Types.INTEGER);
lookup.put("BIGINT", Types.BIGINT);
lookup.put("REAL", Types.REAL);
// Float is most common REAL mapping to have that as well
lookup.put("FLOAT", Types.REAL);
lookup.put("DOUBLE", Types.DOUBLE);
lookup.put("SMALLINT", Types.SMALLINT);
lookup.put("TINYINT", Types.TINYINT);
lookup.put("DECIMAL", Types.DECIMAL);
lookup.put("VARCHAR", Types.VARCHAR);
// VARCHAR2 - extra for Oracle specific column definition
lookup.put("VARCHAR2", Types.VARCHAR);
lookup.put("CHAR", Types.CHAR);
lookup.put("BLOB", Types.BLOB);
lookup.put("CLOB", Types.CLOB);
lookup.put("LONGVARBINARY", Types.LONGVARBINARY);
lookup.put("LONGVARCHAR", Types.LONGVARCHAR);
lookup.put("VARBINARY", Types.VARBINARY);
lookup.put("BINARY", Types.BINARY);
lookup.put("DATE", Types.DATE);
lookup.put("TIME", Types.TIME);
lookup.put("TIMESTAMP", Types.TIMESTAMP);
lookup.put("ARRAY", Types.ARRAY);
lookup.put("UUID", DbType.UUID);
// Not standard java.sql.Types
// logical JSON storage types
lookup.put("JSON", DbType.JSON);
lookup.put("JSONB", DbType.JSONB);
lookup.put("JSONCLOB", DbType.JSONClob);
lookup.put("JSONBLOB", DbType.JSONBlob);
lookup.put("JSONVARCHAR", DbType.JSONVarchar);
}
private final Map<Integer, DbType> typeMap = new HashMap<Integer, DbType>();
/**
* Return the DbTypeMap with standard (not platform specific) types.
* <p>
* This has some extended JSON types (JSON, JSONB, JSONVarchar, JSONClob, JSONBlob).
* These types get translated to specific database platform types during DDL generation.
*/
public static DbTypeMap logicalTypes() {
return new DbTypeMap(true);
}
public DbTypeMap() {
loadDefaults(false);
}
private DbTypeMap(boolean logicalTypes) {
loadDefaults(logicalTypes);
}
/**
* Load the standard types. These can be overridden by DB specific platform.
*/
private void loadDefaults(boolean logicalTypes) {
put(Types.BOOLEAN, new DbType("boolean"));
put(Types.BIT, new DbType("bit"));
put(Types.INTEGER, new DbType("integer"));
put(Types.BIGINT, new DbType("bigint"));
put(Types.REAL, new DbType("float"));
put(Types.DOUBLE, new DbType("double"));
put(Types.SMALLINT, new DbType("smallint"));
put(Types.TINYINT, new DbType("tinyint"));
put(Types.DECIMAL, new DbType("decimal", 38));
put(Types.VARCHAR, new DbType("varchar", 255));
put(Types.CHAR, new DbType("char", 1));
put(Types.BLOB, new DbType("blob"));
put(Types.CLOB, new DbType("clob"));
put(Types.ARRAY, new DbType("array"));
if (logicalTypes) {
// keep it logical for 2 layer DDL generation
put(DbType.HSTORE, new DbType("hstore", false));
put(DbType.JSON, new DbType("json", false));
put(DbType.JSONB, new DbType("jsonb", false));
put(DbType.JSONClob, new DbType("jsonclob"));
put(DbType.JSONBlob, new DbType("jsonblob"));
put(DbType.JSONVarchar, new DbType("jsonvarchar", 1000));
put(DbType.UUID, UUID_NATIVE);
} else {
put(DbType.JSON, JSON_CLOB_PLACEHOLDER); // Postgres maps this to JSON
put(DbType.JSONB, JSON_CLOB_PLACEHOLDER); // Postgres maps this to JSONB
put(DbType.JSONClob, JSON_CLOB_PLACEHOLDER);
put(DbType.JSONBlob, JSON_BLOB_PLACEHOLDER);
put(DbType.JSONVarchar, JSON_VARCHAR_PLACEHOLDER);
put(DbType.UUID, UUID_PLACEHOLDER);
}
put(Types.LONGVARBINARY, new DbType("longvarbinary"));
put(Types.LONGVARCHAR, new DbType("lonvarchar"));
put(Types.VARBINARY, new DbType("varbinary", 255));
put(Types.BINARY, new DbType("binary", 255));
put(Types.DATE, new DbType("date"));
put(Types.TIME, new DbType("time"));
put(Types.TIMESTAMP, new DbType("timestamp"));
}
/**
* Lookup the platform specific DbType given the standard sql type name.
*/
public DbType lookup(String name, boolean withScale) {
name = name.trim().toUpperCase();
Integer typeKey = lookup.get(name);
if (typeKey == null) {
throw new IllegalArgumentException("Unknown type [" + name + "] - not standard sql type");
}
// handle JSON types mapped to clob, blob and varchar
switch (typeKey) {
case DbType.JSONBlob:
return get(Types.BLOB);
case DbType.JSONClob:
return get(Types.CLOB);
case DbType.JSONVarchar:
return get(Types.VARCHAR);
case DbType.JSON:
return getJsonType(DbType.JSON, withScale);
case DbType.JSONB:
return getJsonType(DbType.JSONB, withScale);
default:
return get(typeKey);
}
}
private DbType getJsonType(int type, boolean withScale) {
DbType dbType = get(type);
if (dbType == JSON_CLOB_PLACEHOLDER) {
// if we have scale that implies this maps to varchar
return withScale ? get(Types.VARCHAR) : get(Types.CLOB);
}
if (dbType == JSON_BLOB_PLACEHOLDER) {
return get(Types.BLOB);
}
if (dbType == JSON_VARCHAR_PLACEHOLDER) {
return get(Types.VARCHAR);
}
// Postgres has specific type
return get(type);
}
/**
* Override the type for a given JDBC type.
*/
public void put(int jdbcType, DbType dbType) {
typeMap.put(jdbcType, dbType);
}
/**
* Return the type for a given jdbc type.
*/
public DbType get(int jdbcType) {
return typeMap.get(jdbcType);
}
/**
* Map the UUID appropriately based on native DB support and ServerConfig.DbUuid.
*/
public void config(boolean nativeUuidType, ServerConfig.DbUuid dbUuid) {
if (nativeUuidType && dbUuid.useNativeType()) {
put(DbType.UUID, UUID_NATIVE);
} else if (dbUuid.useBinary()) {
put(DbType.UUID, get(Types.BINARY).withLength(16));
} else {
put(DbType.UUID, get(Types.VARCHAR).withLength(40));
}
}
}
@@ -0,0 +1,73 @@
package com.avaje.ebean.config.dbplatform;
/**
* Integer codes for the extra types beyond java.sql.Types.
*/
public interface ExtraDbTypes {
/**
* DB native UUID type (H2 and Postgres).
*/
int UUID = 5010;
/**
* Type to map Map content to Postgres HSTORE.
*/
int HSTORE = 5000;
/**
* Type to map JSON content to Clob or Postgres JSON type.
*/
int JSON = 5001;
/**
* Type to map JSON content to Clob or Postgres JSONB type.
*/
int JSONB = 5002;
/**
* Type to map JSON content to VARCHAR.
*/
int JSONVarchar = 5003;
/**
* Type to map JSON content to Clob.
*/
int JSONClob = 5004;
/**
* Type to map JSON content to Blob.
*/
int JSONBlob = 5005;
/**
* Geo Point
*/
int POINT = 6000;
/**
* Geo Polygon
*/
int POLYGON = 6001;
/**
* Geo Point
*/
int LINESTRING = 6002;
/**
* Geo MultiPolygon
*/
int MULTIPOINT = 6005;
/**
* Geo MultiPolygon
*/
int MULTIPOLYGON = 6006;
/**
* Geo MultiPolygon
*/
int MULTILINESTRING = 6007;
}
@@ -4,7 +4,6 @@ import com.avaje.ebean.BackgroundExecutor;
import com.avaje.ebean.dbmigration.ddlgeneration.platform.HsqldbDdl;
import javax.sql.DataSource;
import java.sql.Types;
/**
* H2 specific platform.
@@ -22,7 +21,7 @@ public class HsqldbPlatform extends DatabasePlatform {
this.dbIdentity.setSupportsSequence(true);
this.dbIdentity.setSupportsIdentity(true);
dbTypeMap.put(Types.INTEGER, new DbType("integer", false));
dbTypeMap.put(DbType.INTEGER, new DbPlatformType("integer", false));
}
@Override
@@ -2,8 +2,6 @@ package com.avaje.ebean.config.dbplatform;
import com.avaje.ebean.config.PersistBatch;
import java.sql.Types;
/**
* Microsoft SQL Server 2000 specific platform.
* <p>
@@ -29,22 +27,22 @@ public class MsSqlServer2000Platform extends DatabasePlatform {
this.openQuote = "[";
this.closeQuote = "]";
dbTypeMap.put(Types.BOOLEAN, new DbType("bit default 0"));
dbTypeMap.put(DbType.BOOLEAN, new DbPlatformType("bit default 0"));
dbTypeMap.put(Types.BIGINT, new DbType("numeric", 19));
dbTypeMap.put(Types.REAL, new DbType("float(16)"));
dbTypeMap.put(Types.DOUBLE, new DbType("float(32)"));
dbTypeMap.put(Types.TINYINT, new DbType("smallint"));
dbTypeMap.put(Types.DECIMAL, new DbType("numeric", 28));
dbTypeMap.put(DbType.BIGINT, new DbPlatformType("numeric", 19));
dbTypeMap.put(DbType.REAL, new DbPlatformType("float(16)"));
dbTypeMap.put(DbType.DOUBLE, new DbPlatformType("float(32)"));
dbTypeMap.put(DbType.TINYINT, new DbPlatformType("smallint"));
dbTypeMap.put(DbType.DECIMAL, new DbPlatformType("numeric", 28));
dbTypeMap.put(Types.BLOB, new DbType("image"));
dbTypeMap.put(Types.CLOB, new DbType("text"));
dbTypeMap.put(Types.LONGVARBINARY, new DbType("image"));
dbTypeMap.put(Types.LONGVARCHAR, new DbType("text"));
dbTypeMap.put(DbType.BLOB, new DbPlatformType("image"));
dbTypeMap.put(DbType.CLOB, new DbPlatformType("text"));
dbTypeMap.put(DbType.LONGVARBINARY, new DbPlatformType("image"));
dbTypeMap.put(DbType.LONGVARCHAR, new DbPlatformType("text"));
dbTypeMap.put(Types.DATE, new DbType("datetime"));
dbTypeMap.put(Types.TIME, new DbType("datetime"));
dbTypeMap.put(Types.TIMESTAMP, new DbType("datetime"));
dbTypeMap.put(DbType.DATE, new DbPlatformType("datetime"));
dbTypeMap.put(DbType.TIME, new DbPlatformType("datetime"));
dbTypeMap.put(DbType.TIMESTAMP, new DbPlatformType("datetime"));
}
@@ -3,8 +3,6 @@ package com.avaje.ebean.config.dbplatform;
import com.avaje.ebean.config.PersistBatch;
import com.avaje.ebean.dbmigration.ddlgeneration.platform.MsSqlServerDdl;
import java.sql.Types;
/**
* Microsoft SQL Server 2005 specific platform.
* <p>
@@ -34,23 +32,23 @@ public class MsSqlServer2005Platform extends DatabasePlatform {
this.openQuote = "[";
this.closeQuote = "]";
dbTypeMap.put(Types.BOOLEAN, new DbType("bit default 0"));
dbTypeMap.put(DbType.BOOLEAN, new DbPlatformType("bit default 0"));
dbTypeMap.put(Types.INTEGER, new DbType("integer", false));
dbTypeMap.put(Types.BIGINT, new DbType("numeric", 19));
dbTypeMap.put(Types.REAL, new DbType("float(16)"));
dbTypeMap.put(Types.DOUBLE, new DbType("float(32)"));
dbTypeMap.put(Types.TINYINT, new DbType("smallint"));
dbTypeMap.put(Types.DECIMAL, new DbType("numeric", 28));
dbTypeMap.put(DbType.INTEGER, new DbPlatformType("integer", false));
dbTypeMap.put(DbType.BIGINT, new DbPlatformType("numeric", 19));
dbTypeMap.put(DbType.REAL, new DbPlatformType("float(16)"));
dbTypeMap.put(DbType.DOUBLE, new DbPlatformType("float(32)"));
dbTypeMap.put(DbType.TINYINT, new DbPlatformType("smallint"));
dbTypeMap.put(DbType.DECIMAL, new DbPlatformType("numeric", 28));
dbTypeMap.put(Types.BLOB, new DbType("image"));
dbTypeMap.put(Types.CLOB, new DbType("text"));
dbTypeMap.put(Types.LONGVARBINARY, new DbType("image"));
dbTypeMap.put(Types.LONGVARCHAR, new DbType("text"));
dbTypeMap.put(DbType.BLOB, new DbPlatformType("image"));
dbTypeMap.put(DbType.CLOB, new DbPlatformType("text"));
dbTypeMap.put(DbType.LONGVARBINARY, new DbPlatformType("image"));
dbTypeMap.put(DbType.LONGVARCHAR, new DbPlatformType("text"));
dbTypeMap.put(Types.DATE, new DbType("date"));
dbTypeMap.put(Types.TIME, new DbType("time"));
dbTypeMap.put(Types.TIMESTAMP, new DbType("datetime2"));
dbTypeMap.put(DbType.DATE, new DbPlatformType("date"));
dbTypeMap.put(DbType.TIME, new DbPlatformType("time"));
dbTypeMap.put(DbType.TIMESTAMP, new DbPlatformType("datetime2"));
}
@@ -7,7 +7,7 @@ package com.avaje.ebean.config.dbplatform;
* If no deployment length is defined longblob is used.
* </p>
*/
public class MySqlBlob extends DbType {
public class MySqlBlob extends DbPlatformType {
private static final int POWER_2_16 = 65536;
private static final int POWER_2_24 = 16777216;
@@ -7,7 +7,7 @@ package com.avaje.ebean.config.dbplatform;
* If no deployment length is defined longtext is used.
* </p>
*/
public class MySqlClob extends DbType {
public class MySqlClob extends DbPlatformType {
private static final int POWER_2_16 = 65536;
private static final int POWER_2_24 = 16777216;
@@ -39,13 +39,13 @@ public class MySqlPlatform extends DatabasePlatform {
this.forwardOnlyHintOnFindIterate = true;
this.booleanDbType = Types.BIT;
dbTypeMap.put(Types.BIT, new DbType("tinyint(1) default 0"));
dbTypeMap.put(Types.BOOLEAN, new DbType("tinyint(1) default 0"));
dbTypeMap.put(Types.TIMESTAMP, new DbType("datetime(6)"));
dbTypeMap.put(Types.CLOB, new MySqlClob());
dbTypeMap.put(Types.BLOB, new MySqlBlob());
dbTypeMap.put(Types.BINARY, new DbType("binary", 255));
dbTypeMap.put(Types.VARBINARY, new DbType("varbinary", 255));
dbTypeMap.put(DbType.BIT, new DbPlatformType("tinyint(1) default 0"));
dbTypeMap.put(DbType.BOOLEAN, new DbPlatformType("tinyint(1) default 0"));
dbTypeMap.put(DbType.TIMESTAMP, new DbPlatformType("datetime(6)"));
dbTypeMap.put(DbType.CLOB, new MySqlClob());
dbTypeMap.put(DbType.BLOB, new MySqlBlob());
dbTypeMap.put(DbType.BINARY, new DbPlatformType("binary", 255));
dbTypeMap.put(DbType.VARBINARY, new DbPlatformType("varbinary", 255));
}
/**
@@ -34,24 +34,24 @@ public class OraclePlatform extends DatabasePlatform {
this.closeQuote = "\"";
booleanDbType = Types.INTEGER;
dbTypeMap.put(Types.BOOLEAN, new DbType("number(1) default 0"));
dbTypeMap.put(DbType.BOOLEAN, new DbPlatformType("number(1) default 0"));
dbTypeMap.put(Types.INTEGER, new DbType("number", 10));
dbTypeMap.put(Types.BIGINT, new DbType("number", 19));
dbTypeMap.put(Types.REAL, new DbType("number", 19, 4));
dbTypeMap.put(Types.DOUBLE, new DbType("number", 19, 4));
dbTypeMap.put(Types.SMALLINT, new DbType("number", 5));
dbTypeMap.put(Types.TINYINT, new DbType("number", 3));
dbTypeMap.put(Types.DECIMAL, new DbType("number", 38));
dbTypeMap.put(DbType.INTEGER, new DbPlatformType("number", 10));
dbTypeMap.put(DbType.BIGINT, new DbPlatformType("number", 19));
dbTypeMap.put(DbType.REAL, new DbPlatformType("number", 19, 4));
dbTypeMap.put(DbType.DOUBLE, new DbPlatformType("number", 19, 4));
dbTypeMap.put(DbType.SMALLINT, new DbPlatformType("number", 5));
dbTypeMap.put(DbType.TINYINT, new DbPlatformType("number", 3));
dbTypeMap.put(DbType.DECIMAL, new DbPlatformType("number", 38));
dbTypeMap.put(Types.VARCHAR, new DbType("varchar2", 255));
dbTypeMap.put(DbType.VARCHAR, new DbPlatformType("varchar2", 255));
dbTypeMap.put(Types.LONGVARBINARY, new DbType("blob"));
dbTypeMap.put(Types.LONGVARCHAR, new DbType("clob"));
dbTypeMap.put(Types.VARBINARY, new DbType("raw", 255));
dbTypeMap.put(Types.BINARY, new DbType("raw", 255));
dbTypeMap.put(DbType.LONGVARBINARY, new DbPlatformType("blob"));
dbTypeMap.put(DbType.LONGVARCHAR, new DbPlatformType("clob"));
dbTypeMap.put(DbType.VARBINARY, new DbPlatformType("raw", 255));
dbTypeMap.put(DbType.BINARY, new DbPlatformType("raw", 255));
dbTypeMap.put(Types.TIME, new DbType("timestamp"));
dbTypeMap.put(DbType.TIME, new DbPlatformType("timestamp"));
}
@Override
@@ -41,26 +41,26 @@ public class PostgresPlatform extends DatabasePlatform {
this.openQuote = "\"";
this.closeQuote = "\"";
DbType dbTypeText = new DbType("text");
DbType dbBytea = new DbType("bytea", false);
DbPlatformType dbTypeText = new DbPlatformType("text");
DbPlatformType dbBytea = new DbPlatformType("bytea", false);
dbTypeMap.put(DbType.HSTORE, new DbType("hstore", false));
dbTypeMap.put(DbType.JSON, new DbType("json", false));
dbTypeMap.put(DbType.JSONB, new DbType("jsonb", false));
dbTypeMap.put(DbType.HSTORE, new DbPlatformType("hstore", false));
dbTypeMap.put(DbType.JSON, new DbPlatformType("json", false));
dbTypeMap.put(DbType.JSONB, new DbPlatformType("jsonb", false));
dbTypeMap.put(Types.INTEGER, new DbType("integer", false));
dbTypeMap.put(Types.DOUBLE, new DbType("float"));
dbTypeMap.put(Types.TINYINT, new DbType("smallint"));
dbTypeMap.put(Types.DECIMAL, new DbType("decimal", 38));
dbTypeMap.put(Types.TIMESTAMP, new DbType("timestamptz"));
dbTypeMap.put(DbType.INTEGER, new DbPlatformType("integer", false));
dbTypeMap.put(DbType.DOUBLE, new DbPlatformType("float"));
dbTypeMap.put(DbType.TINYINT, new DbPlatformType("smallint"));
dbTypeMap.put(DbType.DECIMAL, new DbPlatformType("decimal", 38));
dbTypeMap.put(DbType.TIMESTAMP, new DbPlatformType("timestamptz"));
dbTypeMap.put(Types.BINARY, dbBytea);
dbTypeMap.put(Types.VARBINARY, dbBytea);
dbTypeMap.put(DbType.BINARY, dbBytea);
dbTypeMap.put(DbType.VARBINARY, dbBytea);
dbTypeMap.put(Types.BLOB, dbBytea);
dbTypeMap.put(Types.CLOB, dbTypeText);
dbTypeMap.put(Types.LONGVARBINARY, dbBytea);
dbTypeMap.put(Types.LONGVARCHAR, dbTypeText);
dbTypeMap.put(DbType.BLOB, dbBytea);
dbTypeMap.put(DbType.CLOB, dbTypeText);
dbTypeMap.put(DbType.LONGVARBINARY, dbBytea);
dbTypeMap.put(DbType.LONGVARCHAR, dbTypeText);
}
@Override
@@ -71,9 +71,23 @@ public class PostgresPlatform extends DatabasePlatform {
String tsType = properties.getProperty("ebean.postgres.timestamp");
if (tsType != null) {
// set timestamp type to "timestamp" without time zone
dbTypeMap.put(Types.TIMESTAMP, new DbType(tsType));
dbTypeMap.put(DbType.TIMESTAMP, new DbPlatformType(tsType));
}
}
addGeoTypes(serverConfig.getGeometrySRID());
}
private void addGeoTypes(int srid) {
dbTypeMap.put(DbType.POINT, geoType("point",srid));
dbTypeMap.put(DbType.POLYGON, geoType("polygon",srid));
dbTypeMap.put(DbType.LINESTRING, geoType("linestring",srid));
dbTypeMap.put(DbType.MULTIPOINT, geoType("multipoint",srid));
dbTypeMap.put(DbType.MULTILINESTRING, geoType("multilinestring",srid));
dbTypeMap.put(DbType.MULTIPOLYGON, geoType("multipolygon",srid));
}
private DbPlatformType geoType(String type, int srid) {
return new DbPlatformType("geometry("+type+","+srid+")");
}
/**
@@ -18,10 +18,10 @@ public class SQLitePlatform extends DatabasePlatform {
this.booleanDbType = Types.INTEGER;
dbTypeMap.put(Types.BIT, new DbType("int default 0"));
dbTypeMap.put(Types.BOOLEAN, new DbType("int default 0"));
dbTypeMap.put(Types.BIGINT, new DbType("integer"));
dbTypeMap.put(Types.SMALLINT, new DbType("integer"));
dbTypeMap.put(DbType.BIT, new DbPlatformType("int default 0"));
dbTypeMap.put(DbType.BOOLEAN, new DbPlatformType("int default 0"));
dbTypeMap.put(DbType.BIGINT, new DbPlatformType("integer"));
dbTypeMap.put(DbType.SMALLINT, new DbPlatformType("integer"));
}
@@ -40,7 +40,7 @@ public abstract class SequenceIdGenerator implements PlatformIdGenerator {
protected final BackgroundExecutor backgroundExecutor;
protected final ArrayList<Long> idList = new ArrayList<Long>(50);
protected final ArrayList<Long> idList = new ArrayList<>(50);
protected final int batchSize;
@@ -98,11 +98,7 @@ public abstract class SequenceIdGenerator implements PlatformIdGenerator {
protected void loadLargeAllocation(final int allocateSize) {
// preAllocateIds was called with a relatively large batchSize
// so we will just go ahead and load those anyway in background
backgroundExecutor.execute(new Runnable() {
public void run() {
loadMoreIds(allocateSize, null);
}
});
backgroundExecutor.execute(() -> loadMoreIds(allocateSize, null));
}
/**
@@ -145,12 +141,10 @@ public abstract class SequenceIdGenerator implements PlatformIdGenerator {
currentlyBackgroundLoading = batchSize;
backgroundExecutor.execute(new Runnable() {
public void run() {
loadMoreIds(batchSize, null);
synchronized (backgroundLoadMonitor) {
currentlyBackgroundLoading = 0;
}
backgroundExecutor.execute(() -> {
loadMoreIds(batchSize, null);
synchronized (backgroundLoadMonitor) {
currentlyBackgroundLoading = 0;
}
});
}
@@ -178,7 +172,7 @@ public abstract class SequenceIdGenerator implements PlatformIdGenerator {
String sql = getSql(loadSize);
ArrayList<Long> newIds = new ArrayList<Long>(loadSize);
ArrayList<Long> newIds = new ArrayList<>(loadSize);
boolean useTxnConnection = t != null;
@@ -1,7 +1,5 @@
package com.avaje.ebean.config.dbplatform;
import java.sql.Types;
/**
* Sybase SQL Anywhere specific platform.
* <p>
@@ -23,17 +21,17 @@ public class SqlAnywherePlatform extends DatabasePlatform {
this.dbIdentity.setSelectLastInsertedIdTemplate("select @@IDENTITY as X");
this.dbIdentity.setSupportsIdentity(true);
dbTypeMap.put(Types.BOOLEAN, new DbType("bit default 0"));
dbTypeMap.put(Types.BIGINT, new DbType("numeric", 19));
dbTypeMap.put(Types.REAL, new DbType("float(16)"));
dbTypeMap.put(Types.DOUBLE, new DbType("float(32)"));
dbTypeMap.put(Types.TINYINT, new DbType("smallint"));
dbTypeMap.put(Types.DECIMAL, new DbType("numeric", 28));
dbTypeMap.put(DbType.BOOLEAN, new DbPlatformType("bit default 0"));
dbTypeMap.put(DbType.BIGINT, new DbPlatformType("numeric", 19));
dbTypeMap.put(DbType.REAL, new DbPlatformType("float(16)"));
dbTypeMap.put(DbType.DOUBLE, new DbPlatformType("float(32)"));
dbTypeMap.put(DbType.TINYINT, new DbPlatformType("smallint"));
dbTypeMap.put(DbType.DECIMAL, new DbPlatformType("numeric", 28));
dbTypeMap.put(Types.BLOB, new DbType("binary(4500)"));
dbTypeMap.put(Types.CLOB, new DbType("long varchar"));
dbTypeMap.put(Types.LONGVARBINARY, new DbType("long binary"));
dbTypeMap.put(Types.LONGVARCHAR, new DbType("long varchar"));
dbTypeMap.put(DbType.BLOB, new DbPlatformType("binary(4500)"));
dbTypeMap.put(DbType.CLOB, new DbPlatformType("long varchar"));
dbTypeMap.put(DbType.LONGVARBINARY, new DbPlatformType("long binary"));
dbTypeMap.put(DbType.LONGVARCHAR, new DbPlatformType("long varchar"));
}
@@ -7,7 +7,7 @@ import com.avaje.ebean.config.DbMigrationConfig;
import com.avaje.ebean.config.ServerConfig;
import com.avaje.ebean.config.dbplatform.DB2Platform;
import com.avaje.ebean.config.dbplatform.DatabasePlatform;
import com.avaje.ebean.config.dbplatform.DbPlatformName;
import com.avaje.ebean.config.Platform;
import com.avaje.ebean.config.dbplatform.H2Platform;
import com.avaje.ebean.config.dbplatform.MsSqlServer2005Platform;
import com.avaje.ebean.config.dbplatform.MySqlPlatform;
@@ -79,7 +79,7 @@ public class DbMigration {
protected DatabasePlatform databasePlatform;
protected List<Pair> platforms = new ArrayList<Pair>();
protected List<Pair> platforms = new ArrayList<>();
protected ServerConfig serverConfig;
@@ -139,7 +139,7 @@ public class DbMigration {
* If not set this defaults to the platform of the default server.
* </p>
*/
public void setPlatform(DbPlatformName platform) {
public void setPlatform(Platform platform) {
setPlatform(getPlatform(platform));
}
@@ -163,7 +163,7 @@ public class DbMigration {
* from the migration (e.g. generate migration sql for MySql, Postgres and Oracle).
* </p>
*/
public void addPlatform(DbPlatformName platform, String prefix) {
public void addPlatform(Platform platform, String prefix) {
platforms.add(new Pair(getPlatform(platform), prefix));
}
@@ -515,7 +515,7 @@ public class DbMigration {
/**
* Return the DatabasePlatform given the platform key.
*/
protected DatabasePlatform getPlatform(DbPlatformName platform) {
protected DatabasePlatform getPlatform(Platform platform) {
switch (platform) {
case H2:
return new H2Platform();
@@ -1,6 +1,6 @@
package com.avaje.ebean.dbmigration;
import com.avaje.ebean.config.dbplatform.DbPlatformName;
import com.avaje.ebean.config.Platform;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -19,7 +19,7 @@ public class DbOffline {
/**
* Set the platform to use when creating the next EbeanServer instance.
*/
public static void setPlatform(DbPlatformName dbPlatform) {
public static void setPlatform(Platform dbPlatform) {
System.setProperty(KEY, dbPlatform.name());
}
@@ -41,7 +41,7 @@ public class DbOffline {
* Bring up the next EbeanServer instance using the H2 platform.
*/
public static void asH2() {
setPlatform(DbPlatformName.H2);
setPlatform(Platform.H2);
}
/**
@@ -53,7 +53,7 @@ public class BaseTableDdl implements TableDdl {
/**
* Used when unique constraints specifically for OneToOne can't be created normally (MsSqlServer).
*/
protected List<Column> externalUnique = new ArrayList<Column>();
protected List<Column> externalUnique = new ArrayList<>();
// counters used when constraint names are truncated due to maximum length
// and these counters are used to keep the constraint name unique
@@ -66,7 +66,7 @@ public class BaseTableDdl implements TableDdl {
* Base tables that have associated history tables that need their triggers/functions regenerated as
* columns have been added, removed, included or excluded.
*/
protected Map<String, HistoryTableUpdate> regenerateHistoryTriggers = new LinkedHashMap<String, HistoryTableUpdate>();
protected Map<String, HistoryTableUpdate> regenerateHistoryTriggers = new LinkedHashMap<>();
/**
* Construct with a naming convention and platform specific DDL.
@@ -499,7 +499,7 @@ public class BaseTableDdl implements TableDdl {
* Return the list of columns that make the primary key.
*/
protected List<Column> determinePrimaryKeyColumns(List<Column> columns) {
List<Column> pk = new ArrayList<Column>(3);
List<Column> pk = new ArrayList<>(3);
for (Column column : columns) {
if (isTrue(column.isPrimaryKey())) {
pk.add(column);
@@ -43,7 +43,7 @@ public class HistoryTableUpdate {
private final String baseTable;
private final List<Column> columnChanges = new ArrayList<Column>();
private final List<Column> columnChanges = new ArrayList<>();
/**
* Construct with a given base table name.
@@ -11,6 +11,8 @@ public class Oracle10Ddl extends PlatformDdl {
super(platform);
this.dropTableIfExists = "drop table ";
this.dropSequenceIfExists = "drop sequence ";
this.dropConstraintIfExists = "drop constraint";
this.dropIndexIfExists = "drop index ";
this.dropTableCascade = " cascade constraints purge";
this.foreignKeyRestrict = "";
this.alterColumn = "modify";
@@ -110,7 +110,6 @@ public class PlatformDdl {
* Set configuration options.
*/
public void configure(ServerConfig serverConfig) {
platform.configure(serverConfig);
historyDdl.configure(serverConfig, this);
naming = serverConfig.getConstraintNaming();
}
@@ -1,6 +1,7 @@
package com.avaje.ebean.dbmigration.ddlgeneration.platform.util;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
@@ -8,7 +9,7 @@ import java.util.List;
*/
public class IndexColumns {
List<String> columns = new ArrayList<String>(4);
List<String> columns = new ArrayList<>(4);
/**
* Construct representing as a single column index.
@@ -21,9 +22,7 @@ public class IndexColumns {
* Construct representing index.
*/
public IndexColumns(String[] columnNames) {
for (int i = 0; i < columnNames.length; i++) {
columns.add(columnNames[i]);
}
Collections.addAll(columns, columnNames);
}
/**
@@ -11,7 +11,7 @@ import java.util.List;
*/
public class IndexSet {
private List<IndexColumns> indexes = new ArrayList<IndexColumns>();
private List<IndexColumns> indexes = new ArrayList<>();
/**
* Clear the indexes (for each table).
@@ -1,7 +1,7 @@
package com.avaje.ebean.dbmigration.ddlgeneration.platform.util;
import com.avaje.ebean.config.dbplatform.DbType;
import com.avaje.ebean.config.dbplatform.DbTypeMap;
import com.avaje.ebean.config.dbplatform.DbPlatformType;
import com.avaje.ebean.config.dbplatform.DbPlatformTypeMapping;
/**
* Converts a logical column definition into platform specific one.
@@ -10,12 +10,12 @@ import com.avaje.ebean.config.dbplatform.DbTypeMap;
*/
public class PlatformTypeConverter {
protected final DbTypeMap platformTypes;
protected final DbPlatformTypeMapping platformTypes;
/**
* Construct with the platform specific types.
*/
public PlatformTypeConverter(DbTypeMap platformTypes) {
public PlatformTypeConverter(DbPlatformTypeMapping platformTypes) {
this.platformTypes = platformTypes;
}
@@ -47,7 +47,7 @@ public class PlatformTypeConverter {
String suffix = close + 1 < columnDefinition.length() ? columnDefinition.substring(close + 1) : "";
String type = columnDefinition.substring(0, open);
try {
DbType dbType = platformTypes.lookup(type, true);
DbPlatformType dbType = platformTypes.lookup(type, true);
int comma = columnDefinition.indexOf(',', open);
if (comma > -1) {
// scale and precision - decimal(10,4)
@@ -73,7 +73,7 @@ public class PlatformTypeConverter {
protected String convertNoScale(String columnDefinition) {
try {
DbType dbType = platformTypes.lookup(columnDefinition, false);
DbPlatformType dbType = platformTypes.lookup(columnDefinition, false);
return dbType.renderType(0, 0);
} catch (IllegalArgumentException e) {
@@ -70,7 +70,7 @@ public class AddColumn {
*/
public List<Column> getColumn() {
if (column == null) {
column = new ArrayList<Column>();
column = new ArrayList<>();
}
return this.column;
}
@@ -61,7 +61,7 @@ public class Applications {
*/
public List<Application> getApplication() {
if (application == null) {
application = new ArrayList<Application>();
application = new ArrayList<>();
}
return this.application;
}
@@ -113,7 +113,7 @@ public class ChangeSet {
*/
public List<Object> getChangeSetChildren() {
if (changeSetChildren == null) {
changeSetChildren = new ArrayList<Object>();
changeSetChildren = new ArrayList<>();
}
return this.changeSetChildren;
}
@@ -105,7 +105,7 @@ public class CreateTable {
*/
public List<Column> getColumn() {
if (column == null) {
column = new ArrayList<Column>();
column = new ArrayList<>();
}
return this.column;
}
@@ -134,7 +134,7 @@ public class CreateTable {
*/
public List<UniqueConstraint> getUniqueConstraint() {
if (uniqueConstraint == null) {
uniqueConstraint = new ArrayList<UniqueConstraint>();
uniqueConstraint = new ArrayList<>();
}
return this.uniqueConstraint;
}
@@ -163,7 +163,7 @@ public class CreateTable {
*/
public List<ForeignKey> getForeignKey() {
if (foreignKey == null) {
foreignKey = new ArrayList<ForeignKey>();
foreignKey = new ArrayList<>();
}
return this.foreignKey;
}
@@ -63,7 +63,7 @@ public class Migration {
*/
public List<ChangeSet> getChangeSet() {
if (changeSet == null) {
changeSet = new ArrayList<ChangeSet>();
changeSet = new ArrayList<>();
}
return this.changeSet;
}
@@ -16,8 +16,8 @@ import java.io.InputStream;
*/
public class MigrationXmlReader {
private static final MigrationXmlReader INSTANCE = new MigrationXmlReader();
private MigrationXmlReader() {}
/**
* Read and return a Migration from an xml document at the given resource path.
*/
@@ -28,7 +28,7 @@ public class MigrationXmlReader {
throw new IllegalArgumentException("No resource found for path [" + resourcePath + "]");
}
return INSTANCE.read(is);
return read(is);
}
/**
@@ -45,10 +45,7 @@ public class MigrationXmlWriter {
writer.close();
} catch (IOException e) {
throw new RuntimeException(e);
} catch (JAXBException e) {
} catch (IOException | JAXBException e) {
throw new RuntimeException(e);
}
}
@@ -16,8 +16,8 @@ public class MCompoundForeignKey {
private String name;
private final String referenceTable;
private final List<String> columns = new ArrayList<String>();
private final List<String> referenceColumns = new ArrayList<String>();
private final List<String> columns = new ArrayList<>();
private final List<String> referenceColumns = new ArrayList<>();
private String indexName;
public MCompoundForeignKey(String name, String referenceTable, String indexName) {
@@ -4,6 +4,7 @@ import com.avaje.ebean.dbmigration.migration.CreateIndex;
import com.avaje.ebean.dbmigration.migration.DropIndex;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
@@ -15,7 +16,7 @@ public class MIndex {
private String indexName;
private List<String> columns = new ArrayList<String>();
private List<String> columns = new ArrayList<>();
/**
* Create a single column non unique index.
@@ -32,9 +33,7 @@ public class MIndex {
public MIndex(String indexName, String tableName, String[] columnNames) {
this.tableName = tableName;
this.indexName = indexName;
for (int i = 0; i < columnNames.length; i++) {
this.columns.add(columnNames[i]);
}
Collections.addAll(this.columns, columnNames);
}
public MIndex(CreateIndex createIndex) {
@@ -101,7 +100,6 @@ public class MIndex {
* Return true if the index has changed.
*/
private boolean changed(MIndex newIndex) {
if (!tableName.equals(newIndex.getTableName())) {
return true;
}
@@ -119,12 +117,9 @@ public class MIndex {
private List<String> split(String columns) {
List<String> colList = new ArrayList<String>();
List<String> colList = new ArrayList<>();
String[] cols = columns.split(",");
for (int i = 0; i <cols.length; i++) {
colList.add(cols[i]);
}
Collections.addAll(colList, cols);
return colList;
}
@@ -99,17 +99,17 @@ public class MTable {
/**
* The columns on the table.
*/
private Map<String, MColumn> columns = new LinkedHashMap<String, MColumn>();
private Map<String, MColumn> columns = new LinkedHashMap<>();
/**
* Compound unique constraints.
*/
private List<MCompoundUniqueConstraint> uniqueConstraints = new ArrayList<MCompoundUniqueConstraint>();
private List<MCompoundUniqueConstraint> uniqueConstraints = new ArrayList<>();
/**
* Compound foreign keys.
*/
private List<MCompoundForeignKey> compoundKeys = new ArrayList<MCompoundForeignKey>();
private List<MCompoundForeignKey> compoundKeys = new ArrayList<>();
/**
* Column name for the 'When created' column. This can be used for the initial effective start date when adding
@@ -122,7 +122,7 @@ public class MTable {
*/
private AddColumn addColumn;
private List<String> droppedColumns = new ArrayList<String>();
private List<String> droppedColumns = new ArrayList<>();
/**
* Create a copy of this table structure as a 'draft' table.
@@ -369,7 +369,7 @@ public class MTable {
public List<String> allHistoryColumns(boolean includeDropped) {
List<String> columnNames = new ArrayList<String>(columns.size());
List<String> columnNames = new ArrayList<>(columns.size());
for (MColumn column : columns.values()) {
if (column.isIncludeInHistory()) {
columnNames.add(column.getName());
@@ -444,7 +444,7 @@ public class MTable {
* Return the list of columns that make the primary key.
*/
public List<MColumn> primaryKeyColumns() {
List<MColumn> pk = new ArrayList<MColumn>(3);
List<MColumn> pk = new ArrayList<>(3);
for (MColumn column : allColumns()) {
if (column.isPrimaryKey()) {
pk.add(column);
@@ -590,7 +590,7 @@ public class MTable {
* Return true if the foreign key names are not unique.
*/
private boolean hasDuplicateForeignKeys() {
Set<String> fkNames = new HashSet<String>();
Set<String> fkNames = new HashSet<>();
for (MCompoundForeignKey fk : compoundKeys) {
if (!fkNames.add(fk.getName())) {
return true;
@@ -42,14 +42,9 @@ public class MigrationModel {
private void readMigrations() {
// find all the migration xml files
File[] xmlFiles = modelDirectory.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.getName().toLowerCase().endsWith(modelSuffix);
}
});
File[] xmlFiles = modelDirectory.listFiles(pathname -> pathname.getName().toLowerCase().endsWith(modelSuffix));
List<MigrationResource> resources = new ArrayList<MigrationResource>();
List<MigrationResource> resources = new ArrayList<>();
for (File xmlFile: xmlFiles) {
resources.add(new MigrationResource(xmlFile, createVersion(xmlFile)));
@@ -28,12 +28,12 @@ public class ModelContainer {
/**
* All the tables in the model.
*/
private final Map<String, MTable> tables = new LinkedHashMap<String, MTable>();
private final Map<String, MTable> tables = new LinkedHashMap<>();
/**
* All the non unique non foreign key indexes.
*/
private final Map<String, MIndex> indexes = new LinkedHashMap<String, MIndex>();
private final Map<String, MIndex> indexes = new LinkedHashMap<>();
private final PendingDrops pendingDrops = new PendingDrops();
@@ -30,12 +30,12 @@ public class ModelDiff {
/**
* List of 'create' type changes.
*/
private final List<Object> applyChanges = new ArrayList<Object>();
private final List<Object> applyChanges = new ArrayList<>();
/**
* List of 'drop' type changes. Expected to be placed into a separate DDL script.
*/
private final List<Object> dropChanges = new ArrayList<Object>();
private final List<Object> dropChanges = new ArrayList<>();
/**
* Construct with a base model.
@@ -16,7 +16,7 @@ import java.util.List;
*/
public class PendingDrops {
private final LinkedHashMap<String, Entry> map = new LinkedHashMap<String, Entry>();
private final LinkedHashMap<String, Entry> map = new LinkedHashMap<>();
/**
* Add a 'pending drops' changeSet for the given version.
@@ -36,7 +36,7 @@ public class PendingDrops {
*/
public List<String> pendingDrops() {
List<String> versions = new ArrayList<String>();
List<String> versions = new ArrayList<>();
for (Entry value : map.values()) {
if (value.hasPendingDrops()) {
versions.add(value.version.asString());
@@ -143,7 +143,7 @@ public class PendingDrops {
final MigrationVersion version;
final List<ChangeSet> list = new ArrayList<ChangeSet>();
final List<ChangeSet> list = new ArrayList<>();
Entry(MigrationVersion version) {
this.version = version;
@@ -1,6 +1,6 @@
package com.avaje.ebean.dbmigration.model.build;
import com.avaje.ebean.config.dbplatform.DbType;
import com.avaje.ebean.config.dbplatform.DbPlatformType;
import com.avaje.ebean.config.dbplatform.IdType;
import com.avaje.ebean.dbmigration.migration.IdentityType;
import com.avaje.ebean.dbmigration.model.MColumn;
@@ -52,7 +52,7 @@ public class ModelBuildBeanVisitor implements BeanVisitor {
if (inheritInfo != null && inheritInfo.isRoot()) {
// add the discriminator column
String discColumn = inheritInfo.getDiscriminatorColumn();
DbType dbType = ctx.getDbTypeMap().get(inheritInfo.getDiscriminatorType());
DbPlatformType dbType = ctx.getDbTypeMap().get(inheritInfo.getDiscriminatorType());
String discDbType = dbType.renderType(inheritInfo.getDiscriminatorLength(), 0);
table.addColumn(new MColumn(discColumn, discDbType, true));
@@ -1,8 +1,8 @@
package com.avaje.ebean.dbmigration.model.build;
import com.avaje.ebean.config.DbConstraintNaming;
import com.avaje.ebean.config.dbplatform.DbType;
import com.avaje.ebean.config.dbplatform.DbTypeMap;
import com.avaje.ebean.config.dbplatform.DbPlatformType;
import com.avaje.ebean.config.dbplatform.DbPlatformTypeMapping;
import com.avaje.ebean.dbmigration.model.MColumn;
import com.avaje.ebean.dbmigration.model.MTable;
import com.avaje.ebean.dbmigration.model.ModelContainer;
@@ -21,7 +21,7 @@ public class ModelBuildContext {
* Use platform agnostic logical types. These types are converted to
* platform specific types in the DDL generation.
*/
private final DbTypeMap dbTypeMap = DbTypeMap.logicalTypes();
private final DbPlatformTypeMapping dbTypeMap = DbPlatformTypeMapping.logicalTypes();
private final ModelContainer model;
@@ -106,7 +106,7 @@ public class ModelBuildContext {
* Return the map used to determine the DB specific type
* for a given bean property.
*/
public DbTypeMap getDbTypeMap() {
public DbPlatformTypeMapping getDbTypeMap() {
return dbTypeMap;
}
@@ -115,14 +115,14 @@ public class ModelBuildContext {
* Render the DB type for this property given the strict mode.
*/
public String getColumnDefn(BeanProperty p, boolean strict) {
DbType dbType = getDbType(p);
DbPlatformType dbType = getDbType(p);
if (dbType == null) {
throw new IllegalStateException("Unknown DbType mapping for " + p.getFullBeanName());
}
return p.renderDbType(dbType, strict);
}
private DbType getDbType(BeanProperty p) {
private DbPlatformType getDbType(BeanProperty p) {
if (p.isDbEncrypted()) {
return dbTypeMap.get(p.getDbEncryptedType());
@@ -166,7 +166,7 @@ public class ModelBuildPropertyVisitor extends BaseTablePropertyVisitor {
ImportedId importedId = p.getImportedId();
List<MColumn> modelColumns = new ArrayList<MColumn>(columns.length);
List<MColumn> modelColumns = new ArrayList<>(columns.length);
MCompoundForeignKey compoundKey = null;
if (columns.length > 1) {
@@ -236,6 +236,7 @@ public class ModelBuildPropertyVisitor extends BaseTablePropertyVisitor {
col.setDefaultValue(p.getDbColumnDefault());
col.setComment(p.getDbComment());
col.setDraftOnly(p.isDraftOnly());
col.setHistoryExclude(p.isExcludedFromHistory());
if (p.isId()) {
col.setPrimaryKey(true);
@@ -66,7 +66,7 @@ public class VisitAllUsing {
BeanProperty[] propertiesNonTransient = desc.propertiesNonTransient();
for (int i = 0; i < propertiesNonTransient.length; i++) {
BeanProperty p = propertiesNonTransient[i];
if (!p.isFormula() && !p.isSecondaryTable()) {
if (p.isDDLColumn()) {
visit(propertyVisitor, p);
}
}
@@ -13,8 +13,7 @@ import java.util.Set;
public abstract class AbstractBeanPersistListener implements BeanPersistListener {
/**
* Notified that a bean has been inserted locally. Return true if you want the
* cluster to be notified of the event.
* Notified that a bean has been inserted.
*
* @param bean The bean that was inserted.
*/
@@ -23,8 +22,7 @@ public abstract class AbstractBeanPersistListener implements BeanPersistListener
}
/**
* Notified that a bean has been updated locally. Return true if you want the
* cluster to be notified of the event.
* Notified that a bean has been updated.
*
* @param bean The bean that was updated.
* @param updatedProperties The properties that were modified by this update.
@@ -34,8 +32,7 @@ public abstract class AbstractBeanPersistListener implements BeanPersistListener
}
/**
* Notified that a bean has been deleted locally. Return true if you want the
* cluster to be notified of the event.
* Notified that a bean has been deleted.
*
* @param bean The bean that was deleted.
*/
@@ -43,4 +40,12 @@ public abstract class AbstractBeanPersistListener implements BeanPersistListener
public void deleted(Object bean) {
}
/**
* Notified that a bean has been soft deleted.
*
* @param bean The bean that was deleted.
*/
@Override
public void softDeleted(Object bean) {
}
}
@@ -46,6 +46,13 @@ public abstract class BeanPersistAdapter implements BeanPersistController {
return true;
}
/**
* Returns true indicating normal processing should continue.
*/
public boolean preSoftDelete(BeanPersistRequest<?> request) {
return true;
}
/**
* Does nothing by default.
*/
@@ -64,4 +71,10 @@ public abstract class BeanPersistAdapter implements BeanPersistController {
public void postUpdate(BeanPersistRequest<?> request) {
}
/**
* Does nothing by default.
*/
public void postSoftDelete(BeanPersistRequest<?> request) {
}
}
@@ -89,6 +89,12 @@ public interface BeanPersistController {
*/
boolean preDelete(BeanPersistRequest<?> request);
/**
* Prior to a soft delete perform some action. Return true if you want the
* default functionality to continue.
*/
boolean preSoftDelete(BeanPersistRequest<?> request);
/**
* Called after the insert was performed.
*/
@@ -104,4 +110,8 @@ public interface BeanPersistController {
*/
void postDelete(BeanPersistRequest<?> request);
/**
* Called after the soft delete was performed.
*/
void postSoftDelete(BeanPersistRequest<?> request);
}
@@ -67,4 +67,12 @@ public interface BeanPersistListener {
*/
void deleted(Object bean);
/**
* Notified that a bean has been soft deleted.
*
* @param bean
* The bean that was soft deleted.
*/
void softDeleted(Object bean);
}
@@ -0,0 +1,40 @@
package com.avaje.ebean.event;
import com.avaje.ebean.EbeanServer;
/**
* Fired after a bean is constructed, but not yet loaded from database.
* <p>
* Note: You MUST NOT set any default values, as in a following step,
* properties will get unload. Use {@link BeanPostLoad} instead.
*
* it's intended to do some dependency-injection here.
* If you plan to use this feature you should use {@link EbeanServer#createEntityBean(Class)}
* to create new beans.
* </p>
*/
public interface BeanPostConstructListener {
/**
* Return true if this BeanPostConstructListener instance should be registered
* for post construct on this entity type.
*/
boolean isRegisterFor(Class<?> cls);
/**
* Called immediately after construction. Perform DI here.
*/
void autowire(Object bean);
/**
* Called after every &#64;PostConstruct annotated method of the bean is executed
*/
void postConstruct(Object bean);
/**
* Called after {@link EbeanServer#createEntityBean(Class)}. Only for new beans.
* intended to set default values here.
*/
void postCreate(Object bean);
}
@@ -49,7 +49,7 @@ public class ChangeSet {
/**
* The bean changes.
*/
List<BeanChange> changes = new ArrayList<BeanChange>();
List<BeanChange> changes = new ArrayList<>();
/**
* Construct with a txnId.
@@ -182,7 +182,7 @@ public class ChangeSet {
*/
public Map<String,String> getUserContext() {
if (userContext == null) {
userContext = new LinkedHashMap<String, String>();
userContext = new LinkedHashMap<>();
}
return userContext;
}
@@ -159,7 +159,7 @@ public class ReadEvent {
*/
public Map<String, String> getUserContext() {
if (userContext == null) {
userContext = new LinkedHashMap<String, String>();
userContext = new LinkedHashMap<>();
}
return userContext;
}
@@ -0,0 +1,17 @@
package com.avaje.ebean.plugin;
import com.avaje.ebean.config.ServerConfig;
import com.avaje.ebeaninternal.server.type.ScalarType;
import java.util.List;
/**
* A factory that provides extra types to Ebean.
*/
public interface ExtraTypeFactory {
/**
* Provide extra types to Ebean.
*/
List<? extends ScalarType<?>> createTypes(ServerConfig config, Object objectMapper);
}
@@ -42,7 +42,7 @@ public class PathProperties implements FetchPath {
*/
public PathProperties() {
this.rootProps = new Props(this, null, null);
this.pathMap = new LinkedHashMap<String, Props>();
this.pathMap = new LinkedHashMap<>();
this.pathMap.put(null, rootProps);
}
@@ -172,7 +172,7 @@ public class PathProperties implements FetchPath {
}
private Props(PathProperties owner, String parentPath, String path) {
this(owner, parentPath, path, new LinkedHashSet<String>());
this(owner, parentPath, path, new LinkedHashSet<>());
}
public String getPath() {
@@ -286,11 +286,11 @@ class EJsonReader {
private String key;
ObjectContext() {
map = new LinkedHashMap<String, Object>();
map = new LinkedHashMap<>();
}
ObjectContext(ModifyAwareOwner owner) {
map = new ModifyAwareMap<String, Object>(owner, new LinkedHashMap<String, Object>());
map = new ModifyAwareMap<>(owner, new LinkedHashMap<>());
}
public void popContext(Context temp) {
@@ -319,11 +319,11 @@ class EJsonReader {
private final List<Object> values;
ArrayContext() {
values = new ArrayList<Object>();
values = new ArrayList<>();
}
ArrayContext(ModifyAwareOwner owner) {
values = new ModifyAwareList<Object>(owner, new ArrayList<Object>());
values = new ModifyAwareList<>(owner, new ArrayList<>());
}
public void popContext(Context temp) {
@@ -8,6 +8,8 @@ package com.avaje.ebean.text.json;
*/
public class JsonIOException extends RuntimeException {
private static final long serialVersionUID = 3062982368161342209L;
/**
* Construct with an underlying cause.
*/
@@ -29,7 +29,7 @@ public class JsonReadOptions {
* Default constructor.
*/
public JsonReadOptions() {
this.visitorMap = new LinkedHashMap<String, JsonReadBeanVisitor<?>>();
this.visitorMap = new LinkedHashMap<>();
}
/**
@@ -85,7 +85,7 @@ public class JsonWriteOptions {
*/
public JsonWriteOptions setPathVisitor(String path, JsonWriteBeanVisitor<?> visitor) {
if (visitorMap == null) {
visitorMap = new HashMap<String, JsonWriteBeanVisitor<?>>();
visitorMap = new HashMap<>();
}
visitorMap.put(path, visitor);
return this;
@@ -37,7 +37,7 @@ public class StringHelper {
throw new RuntimeException("missing quoted value at the end of " + tag);
}
HashMap<String, String> map = new HashMap<String, String>();
HashMap<String, String> map = new HashMap<>();
// recursively parse out the name value pairs...
return parseNameQuotedValue(map, tag, 0);
}
@@ -122,7 +122,7 @@ public class StringHelper {
public static Map<String, String> delimitedToMap(String allNameValuePairs,
String listDelimiter, String nameValueSeparator) {
HashMap<String, String> params = new HashMap<String, String>();
HashMap<String, String> params = new HashMap<>();
if ((allNameValuePairs == null) || (allNameValuePairs.isEmpty())) {
return params;
}
@@ -237,7 +237,7 @@ public class StringHelper {
*/
public static String[] delimitedToArray(String str, String delimiter, boolean keepEmpties) {
ArrayList<String> list = new ArrayList<String>();
ArrayList<String> list = new ArrayList<>();
int startPos = 0;
delimiter(str, delimiter, keepEmpties, startPos, list);
String[] result = new String[list.size()];
@@ -20,9 +20,9 @@ public class BindParams implements Serializable {
private static final long serialVersionUID = 4541081933302086285L;
private final List<Param> positionedParameters = new ArrayList<Param>();
private final List<Param> positionedParameters = new ArrayList<>();
private final Map<String, Param> namedParameters = new LinkedHashMap<String, Param>();
private final Map<String, Param> namedParameters = new LinkedHashMap<>();
/**
* This is the sql. For named parameters this is the sql after the named
@@ -308,7 +308,7 @@ public class BindParams implements Serializable {
private final StringBuilder preparedSql;
public OrderedList() {
this(new ArrayList<Param>());
this(new ArrayList<>());
}
public OrderedList(List<Param> paramList) {
@@ -95,7 +95,7 @@ public class LoadBeanRequest extends LoadRequest {
*/
public List<Object> getIdList(int batchSize) {
List<Object> idList = new ArrayList<Object>(batchSize);
List<Object> idList = new ArrayList<>(batchSize);
BeanDescriptor<?> desc = loadBuffer.getBeanDescriptor();
for (int i = 0; i < batch.size(); i++) {
@@ -150,7 +150,7 @@ public class LoadBeanRequest extends LoadRequest {
*/
public void postLoad(List<?> list) {
Set<Object> loadedIds = new HashSet<Object>();
Set<Object> loadedIds = new HashSet<>();
BeanDescriptor<?> desc = loadBuffer.getBeanDescriptor();
// collect Ids and maybe load bean cache
@@ -101,7 +101,7 @@ public class LoadManyRequest extends LoadRequest {
private List<Object> getParentIdList(int batchSize) {
ArrayList<Object> idList = new ArrayList<Object>(batchSize);
ArrayList<Object> idList = new ArrayList<>(batchSize);
BeanPropertyAssocMany<?> many = getMany();
for (int i = 0; i < batch.size(); i++) {
@@ -19,12 +19,14 @@ public class ManyWhereJoins implements Serializable {
private static final long serialVersionUID = -6490181101871795417L;
private final TreeMap<String, PropertyJoin> joins = new TreeMap<String, PropertyJoin>();
private final TreeMap<String, PropertyJoin> joins = new TreeMap<>();
private StringBuilder formulaProperties = new StringBuilder();
private boolean formulaWithJoin;
private boolean aggregation;
/**
* 'Mode' indicating that joins added while this is true are required to be outer joins.
*/
@@ -93,10 +95,10 @@ public class ManyWhereJoins implements Serializable {
}
/**
* Return true if there are no extra many where joins.
* Return true if this is an aggregation query or if there are no extra many where joins.
*/
public boolean isEmpty() {
return joins.isEmpty();
public boolean requireSqlDistinct() {
return !aggregation && !joins.isEmpty();
}
/**
@@ -111,7 +113,7 @@ public class ManyWhereJoins implements Serializable {
*/
public TreeSet<String> getPropertyNames() {
TreeSet<String> propertyNames = new TreeSet<String>();
TreeSet<String> propertyNames = new TreeSet<>();
for (PropertyJoin join : joins.values()) {
propertyNames.add(join.getProperty());
}
@@ -146,4 +148,18 @@ public class ManyWhereJoins implements Serializable {
return formulaProperties.toString();
}
/**
* Mark this as part of an aggregation query (so using group by clause).
*/
public void setAggregation() {
aggregation = true;
}
/**
* Ensure we have the join required to support the aggregation properties.
*/
public void addAggregationJoin(String property) {
this.aggregation = true;
joins.put(property, new PropertyJoin(property, SqlJoinType.INNER));
}
}

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