Compare commits

...
Author SHA1 Message Date
rob 19d2b04175 [maven-release-plugin] prepare release ebean-parent-13.13.0 2023-02-15 10:22:38 +13:00
rob d1844c9b5a Use kotlin-querybean-generator 13.13.0-RC1 for release 2023-02-15 10:18:01 +13:00
rob 93803eade4 Put the test kotlin-querybean-generator version back 1 for release plugin 2023-02-15 10:07:30 +13:00
rob ca6171f697 Ignore TestStdFunctions.concatEq for DB2 2023-02-14 22:39:26 +13:00
rob aa80bc0c10 Bump version to 13.13.0-SNAPSHOT 2023-02-14 20:28:45 +13:00
rob 638cfbca5e Bump ebean-agent to 13.13.0 2023-02-14 20:27:29 +13:00
rob afa9d89cfe #2971 - Bump ebean-datasource to 8.5 - use connection.setSchema() rather than connection Properties 2023-02-14 19:48:03 +13:00
Rob BygraveandGitHub 22a433997e Merge pull request #2970 from ebean-orm/feature/bump-ebean-migration
Bump ebean-migration to 13.7.0 - DB2 uses logical lock due to reorg tables
2023-02-14 19:44:39 +13:00
rob b9d8a9c532 Bump ebean-migration to 13.7.0 - DB2 uses logical lock due to reorg tables 2023-02-14 19:43:41 +13:00
rob 1f0191b9e4 Tidy ebean-test internals, final classes and whitespace 2023-02-14 19:41:45 +13:00
Rob BygraveandGitHub 2d78c5c5e8 Merge pull request #2969 from ebean-orm/feature/registerTestTenantProvider-default-false
#2968 - [ebean-test] - Default ebean.test.registerTestTenantProvider = false ... by default not auto register a test TenantProvider
2023-02-14 19:40:15 +13:00
rob 7c54d21760 #2968 - [ebean-test] - Default ebean.test.registerTestTenantProvider = false ... by default not auto register a test TenantProvider 2023-02-14 19:34:35 +13:00
Rob BygraveandGitHub b9a502ca85 Merge pull request #2957 from FOCONIS/detailed-evict-stats
ENH: add statistics trimmedByGC/LRU/TTL/Idle to ServerCacheStatistics?
2023-02-14 16:29:35 +13:00
rob b622d85292 #2967 - [ebean-joda] Joda JSON ISO8601 format for DateMidnight includes timezone 2023-02-14 15:56:45 +13:00
rob 320ffb4a2d #2966 - DateTimeParseException when ScalarTypeJodaLocalDateTime parsing Json ISO8601 2023-02-14 15:50:13 +13:00
Rob BygraveandGitHub 0292b4b558 Merge pull request #2912 from ebean-orm/wip/spi-txn-logging
Refactoring SpiLogger to better support conditional logging
2023-02-14 15:03:47 +13:00
rob 2c8ae16179 Update to use String format and Object varargs 2023-02-14 14:54:23 +13:00
Rob BygraveandGitHub 381ac58eed Merge pull request #2936 from FOCONIS/mem-leak-streaming-queries
BUG: Memory-leak on streaming queries when LoadBuffers are not aligned
2023-02-14 11:45:29 +13:00
rob af9459e41e Fix build for kotlin-querybean-generator annotation processor version, didn't get bumped after release 2023-02-14 11:42:47 +13:00
rob 5882169641 Merge branch 'feature/StdExpressions' 2023-02-14 11:35:31 +13:00
rob f694f2946a Rename test to StdOperatorsTest 2023-02-14 11:34:00 +13:00
rob 4c0144de61 Fix SqlOperators for sql injection 2023-02-14 11:33:28 +13:00
rob 5e70ea5095 Bump test version after release 2023-02-14 08:24:30 +13:00
rob acb28925f2 [maven-release-plugin] prepare for next development iteration 2023-02-14 08:07:15 +13:00
Roland Praml 010f73fea2 ENH: add statistics trimmedByGC/LRU/TTL/Idle to ServerCacheStatistics? 2023-02-02 14:10:54 +01:00
Roland Praml 61d6cccbcb FIX: Using weak references in load buffer for streaming queries 2023-01-20 16:51:51 +01:00
Roland Praml a3540057b7 BUG: Memory-leak on streaming queries when LoadBuffers are not aligned 2023-01-18 09:24:47 +01:00
Rob Bygrave 9720cd8189 Add SpiTxnLogger as main point to log SQL, SUM and TXN messages on a per transaction basis 2022-12-02 02:34:14 +13:00
Rob Bygrave bc4d9837c6 Modify SpiLogger removing isTrace(), trace() and the 2 uses
- Not bothered to log when changing isolation level
- Not bothering to log at end of query only transaction
2022-12-01 23:45:40 +13:00
Rob Bygrave 4a0f8931a0 Add parameter type for Query.Property with DefaultUpdateQuery and TQRootBean 2022-11-09 23:41:42 +13:00
Rob Bygrave 3c8c52ca7f Simplify to use single type (not use another different type for Query.Property) 2022-11-09 23:30:51 +13:00
Rob Bygrave d29ef8934d Add more operators to StdOperators
- stricter use of UpdateQuery.set()
- Numbers just use their own type - PBaseNumber
- PEnum just uses its own type
- Expr.factory() to expose factory
2022-11-09 17:47:16 +13:00
Rob Bygrave a4c3949cfc Merge branch 'master' into feature/StdExpressions 2022-11-08 21:58:34 +13:00
Rob Bygrave 97bbce321d Make Query.Property parameterised with <BT> "Base Type" as Number, String, Temporal, Boolean or Object
These types then determine which functions are valid for the types. So:
- Number functions
- String/varchar functions
- Temporal Date, DateTime, Time functions
- Boolean functions
- Object being everything else
2022-11-08 21:57:36 +13:00
Rob Bygrave 0b9d199829 #2774 - Postgres ANY / MultiValueSupport with byte[]/binary data
Add Postgres specific support for binding an array of byte[] with ANY(?)
which is used as with client side encryption where the bind values are
implicitly converted to byte[].

Fixes Postgres specific failure running TestEncryptClientSide.java
2022-11-07 17:36:04 +13:00
Rob Bygrave 3da924b943 Add Query.Property.of(), Move StdFunctions to ebean-api 2022-11-07 12:57:39 +13:00
Rob Bygrave 5ad313d290 Rename TQColumn -> Query.Property, fix compile for DefaultOrmQuery use of OrderBy.Property 2022-11-03 17:46:30 +13:00
Rob Bygrave 8565f5f807 Rename TQColumn -> Query.Property and move to api + use with UpdateQuery.set()
- Refactor rename TQColumn to Query.Property and move to ebean-api module
- Add UpdateQuery.set() methods to use Query.Property (as per #2849)
2022-11-03 17:33:11 +13:00
Rob Bygrave 96e79248dc Add StdFunctions, StdExpressions, TQColumn marker interface 2022-11-03 11:16:30 +13:00
166 changed files with 2098 additions and 787 deletions
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.12.0</version>
<version>13.13.0</version>
</parent>
<name>ebean-clickhouse</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-clickhouse</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.12.0</tag>
<tag>ebean-parent-13.13.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.12.0</version>
<version>13.13.0</version>
</parent>
<name>ebean-cockroach</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.12.0</tag>
<tag>ebean-parent-13.13.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.12.0</version>
<version>13.13.0</version>
</parent>
<name>ebean-db2</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-db2</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.12.0</tag>
<tag>ebean-parent-13.13.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.12.0</version>
<version>13.13.0</version>
</parent>
<name>ebean-h2</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.12.0</tag>
<tag>ebean-parent-13.13.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.12.0</version>
<version>13.13.0</version>
</parent>
<name>ebean-hana</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-hana</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.12.0</tag>
<tag>ebean-parent-13.13.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.12.0</version>
<version>13.13.0</version>
</parent>
<name>ebean-mariadb</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-mariadb</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.12.0</tag>
<tag>ebean-parent-13.13.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.12.0</version>
<version>13.13.0</version>
</parent>
<name>ebean-mysql</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-mysql</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.12.0</tag>
<tag>ebean-parent-13.13.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.12.0</version>
<version>13.13.0</version>
</parent>
<name>ebean-nuodb</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-nuodb</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.12.0</tag>
<tag>ebean-parent-13.13.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.12.0</version>
<version>13.13.0</version>
</parent>
<name>ebean-oracle</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-oracle</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.12.0</tag>
<tag>ebean-parent-13.13.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.12.0</version>
<version>13.13.0</version>
</parent>
<name>ebean-postgres</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.12.0</tag>
<tag>ebean-parent-13.13.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.12.0</version>
<version>13.13.0</version>
</parent>
<name>ebean-sqlite</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlite</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.12.0</tag>
<tag>ebean-parent-13.13.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.12.0</version>
<version>13.13.0</version>
</parent>
<name>ebean-sqlserver</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlserver</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.12.0</tag>
<tag>ebean-parent-13.13.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.12.0</version>
<version>13.13.0</version>
</parent>
<name>ebean-yugabyte</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.12.0</tag>
<tag>ebean-parent-13.13.0</tag>
</scm>
</project>
+9 -9
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.12.0</version>
<version>13.13.0</version>
</parent>
<name>ebean (all platforms)</name>
@@ -16,31 +16,31 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-joda-time</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-jsonnode</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-mapper</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
@@ -53,18 +53,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-all</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.12.0</tag>
<tag>ebean-parent-13.13.0</tag>
</scm>
</project>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.12.0</version>
<version>13.13.0</version>
</parent>
<artifactId>composites</artifactId>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.12.0</version>
<version>13.13.0</version>
</parent>
<name>ebean api</name>
@@ -30,6 +30,13 @@ public final class Expr {
private Expr() {
}
/**
* Return the underlying expression factory.
*/
public static ExpressionFactory factory() {
return DB.expressionFactory();
}
/**
* Equal To - property equal to the given value.
*/
@@ -1768,4 +1768,31 @@ public interface Query<T> extends CancelableQuery {
*/
Query<T> orderById(boolean orderById);
/**
* Type safe query bean properties and expressions (marker interface).
* <p>
* Implemented by query bean properties and expressions based on those properties.
* <p>
* The base type determines which {@link StdOperators} can be used on the property.
*
* @param <T> The property type.
*/
interface Property<T> {
/**
* Return a property given the expression.
*/
static <T> Property<T> of(String expression) {
return new SimpleProperty<>(expression);
}
/**
* Return the property in string expression form.
* <p>
* This is a path to a database column (like "name" or "billingAddress.city") or a function
* wrapping a path (like <em>lower(name)</em>, <em>concat(name, '-', billingAddress.city)</em>
*/
@Override
String toString();
}
}
@@ -0,0 +1,15 @@
package io.ebean;
final class SimpleProperty<T> implements Query.Property<T> {
private final String expression;
SimpleProperty(String expression) {
this.expression = expression;
}
@Override
public String toString() {
return expression;
}
}
@@ -0,0 +1,332 @@
package io.ebean;
import io.ebean.Query.Property;
import java.util.Collection;
/**
* Standard Operators for use with strongly typed query construction.
* <p>
* This is currently deemed to be experimental and subject to change.
*/
@Deprecated(since = "experimental")
public final class StdOperators {
// ---- Functions ---- //
/**
* Sum of the given property.
*/
public static Property<Number> sum(Property<? extends Number> property) {
return Property.of("sum(" + property + ")");
}
/**
* Count of the given property.
*/
public static Property<Number> count(Property<?> property) {
return Property.of("count(" + property + ")");
}
/**
* Average of the given property.
*/
public static <T> Property<T> avg(Property<T> property) {
return Property.of("avg(" + property + ")");
}
/**
* Max of the given property.
*/
public static <T> Property<T> max(Property<T> property) {
return Property.of("max(" + property + ")");
}
/**
* Min of the given property.
*/
public static <T> Property<T> min(Property<T> property) {
return Property.of("min(" + property + ")");
}
/**
* Coalesce of the property and value.
*/
public static <T> Property<T> coalesce(Property<T> property, Object value) {
return Property.of("coalesce(" + property.toString() + "," + sqlValue(value) + ")");
}
/**
* Lower of the given property.
*/
public static Property<String> lower(Property<String> property) {
return Property.of("lower(" + property + ")");
}
/**
* Upper of the given property.
*/
public static Property<String> upper(Property<String> property) {
return Property.of("upper(" + property + ")");
}
/**
* Concat of the given property and values or other properties.
*/
public static Property<String> concat(Property<?> property, Object... values) {
StringBuilder expression = new StringBuilder(50);
expression.append("concat(").append(property.toString());
for (Object value : values) {
expression.append(",").append(sqlConcatString(value));
}
expression.append(")");
return Property.of(expression.toString());
}
private static String sqlConcatString(Object value) {
if (value instanceof Property) {
return value.toString();
} else {
return sqlQuote(value);
}
}
/**
* Allows numbers to be unquoted.
*/
private static String sqlValue(Object value) {
if (value instanceof Property || value instanceof Number) {
return value.toString();
} else {
return sqlQuote(value);
}
}
/**
* SQL quoted escaping single quotes.
*/
private static String sqlQuote(Object value) {
return "'" + String.valueOf(value).replace("'", "''") + "'";
}
// ---- Operators ---- //
/**
* Equal to - for a property and value.
*/
public static <T> Expression eq(Property<T> property, T value) {
return Expr.eq(property.toString(), value);
}
/**
* Equal to - for a property and sub-query.
*/
public static <T> Expression eq(Property<T> property, Query<?> subQuery) {
return Expr.in(property.toString(), subQuery);
}
/**
* Equal to or null - for a property and value.
*/
public static <T> Expression eqOrNull(Property<T> property, T value) {
return Expr.factory().eqOrNull(property.toString(), value);
}
/**
* Not equal to - for a property and value.
*/
public static <T> Expression ne(Property<T> property, T value) {
return Expr.ne(property.toString(), value);
}
/**
* Not equal to - for a property and sub-query.
*/
public static <T> Expression ne(Property<T> property, Query<?> subQuery) {
return Expr.ne(property.toString(), subQuery);
}
/**
* Greater than - for a property and value.
*/
public static <T> Expression gt(Property<T> property, T value) {
return Expr.gt(property.toString(), value);
}
/**
* Greater than - for a property and sub-query.
*/
public static <T> Expression gt(Property<T> property, Query<?> subQuery) {
return Expr.gt(property.toString(), subQuery);
}
/**
* Greater than or null - for a property and value.
*/
public static <T> Expression gtOrNull(Property<T> property, T value) {
return Expr.factory().gtOrNull(property.toString(), value);
}
/**
* Greater than or equal to - for a property and value.
*/
public static <T> Expression ge(Property<T> property, T value) {
return Expr.ge(property.toString(), value);
}
/**
* Greater than or equal to - for a property and sub-query.
*/
public static <T> Expression ge(Property<T> property, Query<?> subQuery) {
return Expr.ge(property.toString(), subQuery);
}
/**
* Greater than or null - for a property and value.
*/
public static <T> Expression geOrNull(Property<T> property, T value) {
return Expr.factory().geOrNull(property.toString(), value);
}
/**
* Less than - for a property and value.
*/
public static <T> Expression lt(Property<T> property, T value) {
return Expr.lt(property.toString(), value);
}
/**
* Less than - for a property and sub-query.
*/
public static <T> Expression lt(Property<T> property, Query<?> subQuery) {
return Expr.lt(property.toString(), subQuery);
}
/**
* Less than or null - for a property and value.
*/
public static <T> Expression ltOrNull(Property<T> property, T value) {
return Expr.factory().ltOrNull(property.toString(), value);
}
/**
* Greater than or equal to - for a property and value.
*/
public static <T> Expression le(Property<T> property, T value) {
return Expr.le(property.toString(), value);
}
/**
* Greater than or equal to - for a property and sub-query.
*/
public static <T> Expression le(Property<T> property, Query<?> subQuery) {
return Expr.le(property.toString(), subQuery);
}
/**
* Greater than or equal to or null - for a property and value.
*/
public static <T> Expression leOrNull(Property<T> property, T value) {
return Expr.factory().leOrNull(property.toString(), value);
}
/**
* In range - for a property and values.
*/
public static <T> Expression inRange(Property<T> property, T lowValue, T highValue) {
return Expr.factory().inRange(property.toString(), lowValue, highValue);
}
/**
* In range - for properties and a value.
*/
public static <T> Expression inRange(Property<T> lowProperty, Property<T> highProperty, T value) {
return Expr.factory().inRangeWith(lowProperty.toString(), highProperty.toString(), value);
}
/**
* In range - for properties.
*/
public static <T> Expression inRange(Property<T> lowProperty, Property<T> property, Property<T> highProperty) {
return Expr.factory().inRangeWithProperties(lowProperty.toString(), property.toString(), highProperty.toString());
}
/**
* In - for a given property and collection of values.
*/
public static <T> Expression in(Property<T> property, Collection<T> value) {
return Expr.in(property.toString(), value);
}
/**
* In - for a given property and sub-query.
*/
public static <T> Expression in(Property<T> property, Query<?> subQuery) {
return Expr.in(property.toString(), subQuery);
}
/**
* In or empty - for a given property and collection of values.
*/
public static <T> Expression inOrEmpty(Property<T> property, Collection<T> value) {
return Expr.inOrEmpty(property.toString(), value);
}
/**
* Not In - for a given property and collection of values.
*/
public static <T> Expression notIn(Property<T> property, Collection<T> value) {
return Expr.factory().notIn(property.toString(), value);
}
/**
* Not In - for a given property and sub-query.
*/
public static <T> Expression notIn(Property<T> property, Query<?> subQuery) {
return Expr.factory().notIn(property.toString(), subQuery);
}
// ---- String operators ---- //
/**
* Like - for a given property and value.
*/
public static Expression like(Property<String> property, String value) {
return Expr.like(property.toString(), value);
}
/**
* Case-insensitive Like - for a given property and value.
*/
public static Expression ilike(Property<String> property, String value) {
return Expr.ilike(property.toString(), value);
}
/**
* Starts with - for a given property and value.
*/
public static Expression startsWith(Property<String> property, String value) {
return Expr.startsWith(property.toString(), value);
}
/**
* Case-insensitive starts with - for a given property and value.
*/
public static Expression istartsWith(Property<String> property, String value) {
return Expr.istartsWith(property.toString(), value);
}
/**
* Contains - for a given property and value.
*/
public static Expression contains(Property<String> property, String value) {
return Expr.contains(property.toString(), value);
}
/**
* Case-insensitive contains - for a given property and value.
*/
public static Expression icontains(Property<String> property, String value) {
return Expr.icontains(property.toString(), value);
}
}
@@ -14,7 +14,7 @@ package io.ebean;
*
* int rows = DB.update(Customer.class)
* .set("status", Customer.Status.ACTIVE)
* .set("updtime", new Timestamp(System.currentTimeMillis()))
* .set("whenUpdated", Instant.now())
* .where()
* .gt("id", 1000)
* .update();
@@ -25,6 +25,20 @@ package io.ebean;
* update o_customer set status=?, updtime=? where id > ?
*
* }</pre>
*
* <h4>Example: Using query bean</h4>
* <pre>{@code
*
* var cust = QCustomer.alias();
*
* int rows = new QCustomer()
* .id.gt(1000)
* .asUpdate()
* .set(cust.status, Customer.Status.COMPLETE)
* .set(cust.whenUpdated, Instant.now())
* .update();
*
* }</pre>
* <p>
* Note that if the where() clause contains a join then the SQL update changes to use a
* <code> WHERE ID IN () </code> form.
@@ -40,7 +54,7 @@ package io.ebean;
*
* int rows = DB.update(Customer.class)
* .set("status", Customer.Status.ACTIVE)
* .set("updtime", new Timestamp(System.currentTimeMillis()))
* .set("whenUpdated", Instant.now())
* .where()
* .eq("status", Customer.Status.NEW)
* .eq("billingAddress.country", nz)
@@ -73,7 +87,7 @@ public interface UpdateQuery<T> {
*
* int rows = DB.update(Customer.class)
* .set("status", Customer.Status.ACTIVE)
* .set("updtime", new Timestamp(System.currentTimeMillis()))
* .set("whenUpdated", Instant.now())
* .where()
* .gt("id", 1000)
* .update();
@@ -85,6 +99,27 @@ public interface UpdateQuery<T> {
*/
UpdateQuery<T> set(String property, Object value);
/**
* Set the value of a property.
* <p>
* <pre>{@code
*
* var cust = QCustomer.alias();
*
* int rows = new QCustomer()
* .id.gt(1000)
* .asUpdate()
* .set(cust.status, Customer.Status.COMPLETE)
* .set(cust.whenUpdated, Instant.now())
* .update();
*
* }</pre>
*
* @param property The bean property to be set
* @param value The value to set the property to
*/
<P> UpdateQuery<T> set(Query.Property<P> property, P value);
/**
* Set the property to be null.
* <p>
@@ -102,6 +137,13 @@ public interface UpdateQuery<T> {
*/
UpdateQuery<T> setNull(String property);
/**
* Set the property to be null.
*
* @param property The bean property to be set
*/
UpdateQuery<T> setNull(Query.Property<?> property);
/**
* Set using a property expression that does not need any bind values.
* <p>
@@ -29,6 +29,11 @@ public class ServerCacheStatistics {
protected long evictCount;
protected long gcCount;
protected long idleCount;
protected long ttlCount;
protected long lruCount;
@Override
public String toString() {
//noinspection StringBufferReplaceableByString
@@ -43,6 +48,10 @@ public class ServerCacheStatistics {
sb.append(" remove:").append(removeCount);
sb.append(" clear:").append(clearCount);
sb.append(" evict:").append(evictCount);
sb.append(" gc:").append(gcCount);
sb.append(" idle:").append(idleCount);
sb.append(" ttl:").append(ttlCount);
sb.append(" lru:").append(lruCount);
return sb.toString();
}
@@ -191,4 +200,37 @@ public class ServerCacheStatistics {
return evictCount;
}
/**
* Set the count of entries removed by the garbage collection.
*/
public void setGcCount(long gcCount) {
this.gcCount = gcCount;
}
/**
* Return the count of entries removed by the garbage collection.
*/
public long getGcCount() {
return gcCount;
}
public void setIdleCount(long idleCount) {
this.idleCount = idleCount;
}
public long getIdleCount() {
return idleCount;
}
public void setTtlCount(long ttlCount) {
this.ttlCount = ttlCount;
}
public long getTtlCount() {
return ttlCount;
}
public void setLruCount(long lruCount) {
this.lruCount = lruCount;
}
}
@@ -0,0 +1,78 @@
package io.ebean;
import org.junit.jupiter.api.Test;
import java.time.LocalDate;
import static io.ebean.StdOperators.*;
import static org.assertj.core.api.Assertions.assertThat;
class StdOperatorsTest {
final Query.Property<Number> amount = Query.Property.of("amount");
final Query.Property<String> foo = Query.Property.of("foo");
final Query.Property<String> bar = Query.Property.of("bar");
@Test
void testAvg() {
assertThat(avg(foo).toString()).isEqualTo("avg(foo)");
}
@Test
void testCount() {
assertThat(count(foo).toString()).isEqualTo("count(foo)");
}
@Test
void testMax() {
assertThat(max(foo).toString()).isEqualTo("max(foo)");
}
@Test
void testMin() {
assertThat(min(foo).toString()).isEqualTo("min(foo)");
}
@Test
void testSum() {
assertThat(sum(amount).toString()).isEqualTo("sum(amount)");
}
@Test
void testLower() {
assertThat(lower(foo).toString()).isEqualTo("lower(foo)");
}
@Test
void testUpper() {
assertThat(upper(foo).toString()).isEqualTo("upper(foo)");
}
@Test
void testConcat() {
assertThat(concat(foo, "+").toString()).isEqualTo("concat(foo,'+')");
assertThat(concat(foo, 42).toString()).isEqualTo("concat(foo,'42')");
assertThat(concat(foo, LocalDate.of(2022, 9, 1)).toString()).isEqualTo("concat(foo,'2022-09-01')");
assertThat(concat(foo, bar).toString()).isEqualTo("concat(foo,bar)");
assertThat(concat(foo, ":", 42, bar).toString()).isEqualTo("concat(foo,':','42',bar)");
}
@Test
void testCoalesce() {
assertThat(coalesce(foo, bar).toString()).isEqualTo("coalesce(foo,bar)");
assertThat(coalesce(foo, 42).toString()).isEqualTo("coalesce(foo,42)");
assertThat(coalesce(foo, 0).toString()).isEqualTo("coalesce(foo,0)");
assertThat(coalesce(foo, "apple").toString()).isEqualTo("coalesce(foo,'apple')");
assertThat(coalesce(foo, "banana").toString()).isEqualTo("coalesce(foo,'banana')");
}
@Test
void testCoalesceWithQuoted() {
assertThat(coalesce(foo, "ba'nana").toString()).isEqualTo("coalesce(foo,'ba''nana')");
}
@Test
void testConcatWithQuoted() {
assertThat(concat(foo, "ba'nana").toString()).isEqualTo("concat(foo,'ba''nana')");
}
}
+4 -4
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.12.0</version>
<version>13.13.0</version>
</parent>
<!-- <parent>-->
<!-- <groupId>org.avaje</groupId>-->
@@ -14,7 +14,7 @@
<scm>
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
<tag>ebean-parent-13.12.0</tag>
<tag>ebean-parent-13.13.0</tag>
</scm>
<name>ebean autotune</name>
@@ -26,7 +26,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
<scope>provided</scope>
</dependency>
@@ -55,7 +55,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
<scope>test</scope>
</dependency>
+29 -29
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.12.0</version>
<version>13.13.0</version>
</parent>
<name>ebean bom</name>
@@ -89,106 +89,106 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-joda-time</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-jsonnode</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-mapper</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-generator</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-externalmapping-api</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-externalmapping-xml</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-autotune</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>querybean-generator</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>kotlin-querybean-generator</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-postgis</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-redis</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<!-- platforms -->
@@ -196,67 +196,67 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-clickhouse</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-db2</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-h2</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-hana</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-mariadb</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-mysql</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-nuodb</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-oracle</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-postgres</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-sqlite</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-sqlserver</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
</dependencies>
+2 -2
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.12.0</version>
<version>13.13.0</version>
</parent>
<artifactId>ebean-core-type</artifactId>
@@ -16,7 +16,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
+8 -8
View File
@@ -3,7 +3,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.12.0</version>
<version>13.13.0</version>
</parent>
<artifactId>ebean-core</artifactId>
@@ -15,14 +15,14 @@
<scm>
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
<tag>ebean-parent-13.12.0</tag>
<tag>ebean-parent-13.13.0</tag>
</scm>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
@@ -46,13 +46,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-externalmapping-api</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
@@ -143,21 +143,21 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlserver</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
<scope>test</scope>
</dependency>
@@ -50,4 +50,9 @@ public interface LoadContext {
* Register a collection for lazy loading.
*/
void register(String path, BeanPropertyAssocMany<?> many, BeanCollection<?> bc);
/**
* Use soft-references for streaming queries, so unreachable entries can be garbage collected.
*/
void useReferences(boolean useReferences);
}
@@ -6,16 +6,30 @@ import io.ebean.bean.PersistenceContext;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeaninternal.server.deploy.BeanPropertyAssocMany;
import java.util.List;
/**
* A buffer of bean collections for batch lazy loading and secondary query loading.
*/
public interface LoadManyBuffer {
int getBatchSize();
/**
* The batch (max) size;
*/
int batchSize();
List<BeanCollection<?>> getBatch();
/**
* The actual size.
*/
int size();
/**
* Get the <code>i</code>th element from buffer. This can be null.
*/
BeanCollection<?> get(int i);
/**
* Removes an element from the buffer. This will NOT affect size.
*/
boolean removeFromBuffer(BeanCollection<?> collection);
BeanPropertyAssocMany<?> getBeanProperty();
@@ -19,8 +19,6 @@ import static java.lang.System.Logger.Level.DEBUG;
public final class LoadManyRequest extends LoadRequest {
private static final System.Logger log = CoreLog.log;
private final List<BeanCollection<?>> batch;
private final LoadManyBuffer loadContext;
private final boolean onlyIds;
private final boolean loadCache;
@@ -42,7 +40,6 @@ public final class LoadManyRequest extends LoadRequest {
private LoadManyRequest(LoadManyBuffer loadContext, OrmQueryRequest<?> parentRequest, boolean lazy, boolean onlyIds, boolean loadCache) {
super(parentRequest, lazy);
this.loadContext = loadContext;
this.batch = loadContext.getBatch();
this.onlyIds = onlyIds;
this.loadCache = loadCache;
}
@@ -59,9 +56,12 @@ public final class LoadManyRequest extends LoadRequest {
private List<Object> parentIdList(SpiEbeanServer server) {
List<Object> idList = new ArrayList<>();
BeanPropertyAssocMany<?> many = many();
for (BeanCollection<?> bc : batch) {
idList.add(many.parentId(bc.getOwnerBean()));
bc.setLoader(server); // don't use the load buffer again
for (int i = 0; i < loadContext.size(); i++) {
BeanCollection<?> bc = loadContext.get(i);
if (bc != null) {
idList.add(many.parentId(bc.getOwnerBean()));
bc.setLoader(server); // don't use the load buffer again
}
}
if (many.targetDescriptor().isPadInExpression()) {
BindPadding.padIds(idList);
@@ -91,7 +91,7 @@ public final class LoadManyRequest extends LoadRequest {
query.setPersistenceContext(loadContext.getPersistenceContext());
query.setLoadDescription(lazy ? "+lazy" : "+query", description());
if (lazy) {
query.setLazyLoadBatchSize(loadContext.getBatchSize());
query.setLazyLoadBatchSize(loadContext.batchSize());
} else {
query.setBeanCacheMode(CacheMode.OFF);
}
@@ -112,15 +112,18 @@ public final class LoadManyRequest extends LoadRequest {
BeanPropertyAssocMany<?> many = many();
// check for BeanCollection's that where never processed
// in the +query or +lazy load due to no rows (predicates)
for (BeanCollection<?> bc : batch) {
if (bc.checkEmptyLazyLoad()) {
if (log.isLoggable(DEBUG)) {
EntityBean ownerBean = bc.getOwnerBean();
Object parentId = desc.getId(ownerBean);
log.log(DEBUG, "BeanCollection after lazy load was empty. type:{0} id:{1} owner:{2}", ownerBean.getClass().getName(), parentId, ownerBean);
for (int i = 0; i < loadContext.size(); i++) {
BeanCollection<?> bc = loadContext.get(i);
if (bc != null) {
if (bc.checkEmptyLazyLoad()) {
if (log.isLoggable(DEBUG)) {
EntityBean ownerBean = bc.getOwnerBean();
Object parentId = desc.getId(ownerBean);
log.log(DEBUG, "BeanCollection after lazy load was empty. type:{0} id:{1} owner:{2}", ownerBean.getClass().getName(), parentId, ownerBean);
}
} else if (loadCache && many.isUseCache()) {
desc.cacheManyPropPut(many, bc, desc.cacheKeyForBean(bc.getOwnerBean()));
}
} else if (loadCache && many.isUseCache()) {
desc.cacheManyPropPut(many, bc, desc.cacheKeyForBean(bc.getOwnerBean()));
}
}
}
@@ -10,18 +10,25 @@ package io.ebeaninternal.api;
public interface SpiLogManager {
/**
* Return the SQL logger.
* Enable bind logging.
*/
boolean enableBindLog();
/**
* Logger used for general transactions.
*/
SpiTxnLogger logger();
/**
* Logger used for read only transactions.
*/
SpiTxnLogger readOnlyLogger();
/**
* Hmmmm, return the SQL logger for logging truncate statements.
* <p>
* Maybe we should get rid of this
*/
SpiLogger sql();
/**
* Return the TXN logger.
*/
SpiLogger txn();
/**
* Return the Summary logger.
*/
SpiLogger sum();
}
@@ -14,18 +14,9 @@ public interface SpiLogger {
*/
boolean isDebug();
/**
* Is trace logging enabled.
*/
boolean isTrace();
/**
* Log a debug level message.
*/
void debug(String msg);
void debug(String msg, Object... args);
/**
* Log a trace level message.
*/
void trace(String msg);
}
@@ -27,10 +27,6 @@ public interface SpiTransaction extends Transaction {
*/
String getLabel();
/**
* Return the string prefix with the transaction id and label used in logging.
*/
String getLogPrefix();
/**
* Return true if generated SQL and Bind values should be logged to the
@@ -47,12 +43,17 @@ public interface SpiTransaction extends Transaction {
/**
* Log a message to the SQL logger.
*/
void logSql(String msg);
void logSql(String msg, Object... args);
/**
* Log a message to the SUMMARY logger.
* Log a summary message to the SUMMARY logger.
*/
void logSummary(String msg);
void logSummary(String msg, Object... args);
/**
* Log a transaction message to the transaction logger.
*/
void logTxn(String msg, Object... args);
/**
* Register a "Deferred Relationship" that requires an additional update later.
@@ -137,10 +137,6 @@ public abstract class SpiTransactionProxy implements SpiTransaction {
transaction.setDocStoreBatchSize(batchSize);
}
@Override
public String getLogPrefix() {
return transaction.getLogPrefix();
}
@Override
public boolean isLogSql() {
@@ -153,13 +149,18 @@ public abstract class SpiTransactionProxy implements SpiTransaction {
}
@Override
public void logSql(String msg) {
transaction.logSql(msg);
public void logSql(String msg, Object... args) {
transaction.logSql(msg, args);
}
@Override
public void logSummary(String msg) {
transaction.logSummary(msg);
public void logSummary(String msg, Object... args) {
transaction.logSummary(msg, args);
}
@Override
public void logTxn(String msg, Object... args) {
transaction.logTxn(msg, args);
}
@Override
@@ -0,0 +1,49 @@
package io.ebeaninternal.api;
/**
* Per Transaction logging of SQL, TXN and Summary messages.
*/
public interface SpiTxnLogger {
String id();
/**
* Is debug logging enabled.
*/
boolean isLogSql();
/**
* Is summary logging enabled.
*/
boolean isLogSummary();
/**
* Log a SQL message.
*/
void sql(String msg, Object... args);
/**
* Log a Summary message.
*/
void sum(String msg, Object... args);
/**
* Log a Transaction message.
*/
void txn(String msg, Object... args);
/**
* Transaction Committed.
*/
void notifyCommit();
/**
* Query only transaction completed.
*/
void notifyQueryOnly();
/**
* Transaction Rolled back.
*/
void notifyRollback(Throwable cause);
}
@@ -44,7 +44,10 @@ public class DefaultServerCache implements ServerCache {
protected final CountMetric removeCount;
protected final CountMetric clearCount;
protected final CountMetric evictCount;
protected final CountMetric gcCount;
protected final CountMetric idleCount;
protected final CountMetric ttlCount;
protected final CountMetric lruCount;
protected final String name;
protected final String shortName;
protected final int maxSize;
@@ -55,6 +58,7 @@ public class DefaultServerCache implements ServerCache {
protected final ReentrantLock lock = new ReentrantLock();
protected final AtomicLong mutationCounter = new AtomicLong();
public DefaultServerCache(DefaultServerCacheConfig config) {
this.name = config.getName();
this.shortName = config.getShortName();
@@ -73,6 +77,11 @@ public class DefaultServerCache implements ServerCache {
this.removeCount = factory.createCountMetric(prefix + shortName + ".remove");
this.clearCount = factory.createCountMetric(prefix + shortName + ".clear");
this.evictCount = factory.createCountMetric(prefix + shortName + ".evict");
this.gcCount = factory.createCountMetric(prefix + shortName + ".gc");
this.idleCount = factory.createCountMetric(prefix + shortName + ".idle");
this.ttlCount = factory.createCountMetric(prefix + shortName + ".ttl");
this.lruCount = factory.createCountMetric(prefix + shortName + ".lru");
}
public void periodicTrim(BackgroundExecutor executor) {
@@ -90,6 +99,10 @@ public class DefaultServerCache implements ServerCache {
removeCount.visit(visitor);
clearCount.visit(visitor);
evictCount.visit(visitor);
gcCount.visit(visitor);
idleCount.visit(visitor);
ttlCount.visit(visitor);
lruCount.visit(visitor);
}
@Override
@@ -104,6 +117,10 @@ public class DefaultServerCache implements ServerCache {
cacheStats.setRemoveCount(removeCount.get(reset));
cacheStats.setClearCount(clearCount.get(reset));
cacheStats.setEvictCount(evictCount.get(reset));
cacheStats.setGcCount(gcCount.get(reset));
cacheStats.setIdleCount(idleCount.get(reset));
cacheStats.setTtlCount(ttlCount.get(reset));
cacheStats.setLruCount(lruCount.get(reset));
return cacheStats;
}
@@ -289,6 +306,12 @@ public class DefaultServerCache implements ServerCache {
evictCount.add(trimmedByGC);
evictCount.add(trimmedByTTL);
evictCount.add(trimmedByLRU);
gcCount.add(trimmedByGC);
idleCount.add(trimmedByIdle);
ttlCount.add(trimmedByTTL);
lruCount.add(trimmedByLRU);
if (logger.isLoggable(TRACE)) {
long exeMicros = TimeUnit.MICROSECONDS.convert(System.nanoTime() - startNanos, TimeUnit.NANOSECONDS);
logger.log(TRACE, "Executed trim of cache {0} in [{1}]millis idle[{2}] timeToLive[{3}] accessTime[{4}] gc[{5}]",
@@ -4,7 +4,6 @@ import io.ebean.CancelableQuery;
import io.ebean.Transaction;
import io.ebean.util.JdbcClose;
import io.ebeaninternal.api.*;
import io.ebeaninternal.server.util.Str;
import io.ebeaninternal.server.persist.Binder;
import io.ebeaninternal.server.persist.TrimLogSql;
import io.ebeaninternal.server.util.BindParamsParser;
@@ -151,7 +150,7 @@ public abstract class AbstractSqlQueryRequest implements CancelableQuery {
}
if (isLogSql()) {
long micros = (System.nanoTime() - startNano) / 1000L;
transaction.logSql(Str.add(TrimLogSql.trim(sql), "; --bind(", bindLog, ") --micros(", micros + ")"));
transaction.logSql("{0}; --bind({1}) --micros({2})", TrimLogSql.trim(sql), bindLog, micros);
}
} finally {
lock.unlock();
@@ -229,6 +229,7 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
persistenceContext.beginIterate();
}
loadContext = new DLoadContext(this, secondaryQueries);
loadContext.useReferences(Type.ITERATE == query.getType());
}
/**
@@ -700,8 +701,8 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
/**
* Log the SQL if the logLevel is appropriate.
*/
public void logSql(String sql) {
transaction.logSql(sql);
public void logSql(String msg, Object... args) {
transaction.logSql(msg, args);
}
/**
@@ -928,20 +928,20 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
}
private void logSummaryMessage() {
String draft = (beanDescriptor.isDraftable() && !publish) ? "] draft[true]" : "]";
String draft = (beanDescriptor.isDraftable() && !publish) ? " draft[true]" : "";
String name = beanDescriptor.name();
switch (type) {
case INSERT:
transaction.logSummary("Inserted [" + name + "] [" + (idValue == null ? "" : idValue) + draft);
transaction.logSummary("Inserted [{0}] [{1}]{2}", name, (idValue == null ? "" : idValue), draft);
break;
case UPDATE:
transaction.logSummary("Updated [" + name + "] [" + idValue + draft);
transaction.logSummary("Updated [{0}] [{1}]{2}", name, idValue , draft);
break;
case DELETE:
transaction.logSummary("Deleted [" + name + "] [" + idValue + draft);
transaction.logSummary("Deleted [{0}] [{1}]{2}", name, idValue , draft);
break;
case DELETE_SOFT:
transaction.logSummary("SoftDelete [" + name + "] [" + idValue + draft);
transaction.logSummary("SoftDelete [{0}] [{1}]{2}", name, idValue , draft);
break;
default:
break;
@@ -1,12 +1,8 @@
package io.ebeaninternal.server.core;
import io.ebean.CallableSql;
import io.ebeaninternal.api.BindParams;
import io.ebeaninternal.api.*;
import io.ebeaninternal.api.BindParams.Param;
import io.ebeaninternal.api.SpiCallableSql;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.api.SpiTransaction;
import io.ebeaninternal.api.TransactionEventTable;
import io.ebeaninternal.server.persist.PersistExecute;
import java.sql.CallableStatement;
@@ -86,7 +82,7 @@ public final class PersistRequestCallableSql extends PersistRequest {
persistExecute.collectSqlCall(label, startNanos);
}
if (transaction.isLogSummary()) {
transaction.logSummary("CallableSql label[" + callableSql.getLabel() + "]" + " rows[" + rowCount + "]" + " bind[" + bindLog + "]");
transaction.logSummary("CallableSql label[{0}] rows[{1}] bind[{2}]", callableSql.getLabel(), rowCount, bindLog);
}
// register table modifications with the transaction event
@@ -83,7 +83,7 @@ public final class PersistRequestOrmUpdate extends PersistRequest {
OrmUpdateType ormUpdateType = ormUpdate.getOrmUpdateType();
String tableName = ormUpdate.getBaseTable();
if (transaction.isLogSummary()) {
transaction.logSummary(ormUpdateType + " table[" + tableName + "] rows[" + rowCount + "] bind[" + bindLog + "]");
transaction.logSummary("{0} table[{1}] rows[{2}] bind[{3}]", ormUpdateType, tableName, rowCount, bindLog);
}
if (ormUpdate.isNotifyCache()) {
// add the modification info to the TransactionEvent
@@ -3,7 +3,6 @@ package io.ebeaninternal.server.core;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.api.SpiSqlUpdate;
import io.ebeaninternal.api.SpiTransaction;
import io.ebeaninternal.server.util.Str;
import io.ebeaninternal.server.persist.BatchControl;
import io.ebeaninternal.server.persist.PersistExecute;
import io.ebeaninternal.server.persist.TrimLogSql;
@@ -148,7 +147,7 @@ public final class PersistRequestUpdateSql extends PersistRequest {
*/
public void logSqlBatchBind() {
if (transaction.isLogSql()) {
transaction.logSql(Str.add(" -- bind(", bindLog, ")"));
transaction.logSql(" -- bind({0})", bindLog);
}
}
@@ -161,7 +160,7 @@ public final class PersistRequestUpdateSql extends PersistRequest {
persistExecute.collectSqlUpdate(label, startNanos);
}
if (transaction.isLogSql() && !batchThisRequest) {
transaction.logSql(Str.add(TrimLogSql.trim(updateSql.getGeneratedSql()), "; -- bind(", bindLog, ") rows(", String.valueOf(rowCount), ")"));
transaction.logSql("{0}; -- bind({1}) rows({2})", TrimLogSql.trim(updateSql.getGeneratedSql()), bindLog, rowCount);
}
if (updateSql.isAutoTableMod()) {
// add the modification info to the TransactionEvent
@@ -123,7 +123,7 @@ public final class RelationalQueryRequest extends AbstractSqlQueryRequest {
public void logSummary() {
if (transaction.isLogSummary()) {
long micros = (System.nanoTime() - startNano) / 1000L;
transaction.logSummary("SqlQuery rows[" + rows + "] micros[" + micros + "] bind[" + bindLog + "]");
transaction.logSummary("SqlQuery rows[{0}] micros[{1}] bind[{2}]", rows, micros, bindLog);
}
}
@@ -58,6 +58,7 @@ public final class DLoadContext implements LoadContext {
private final ProfilingListener profilingListener;
private final Map<String, ObjectGraphNode> nodePathMap = new HashMap<>();
private final PersistenceContext persistenceContext;
boolean useReferences;
private List<OrmQueryProperties> secQuery;
private Object tenantId;
@@ -118,7 +119,6 @@ public final class DLoadContext implements LoadContext {
this.origin = null;
this.relativePath = null;
}
// initialise rootBeanContext after origin and relativePath have been set
this.rootBeanContext = new DLoadBeanContext(this, rootDescriptor, null, null);
registerSecondaryQueries(secondaryQueries);
@@ -156,6 +156,11 @@ public final class DLoadContext implements LoadContext {
}
}
@Override
public void useReferences(boolean useReferences) {
this.useReferences = useReferences;
}
/**
* Setup the load context at this path with OrmQueryProperties which is
* used to build the appropriate query for +query or +lazy loading.
@@ -14,7 +14,10 @@ import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeaninternal.server.deploy.BeanPropertyAssocMany;
import io.ebeaninternal.server.querydefn.OrmQueryProperties;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
@@ -38,7 +41,7 @@ final class DLoadManyContext extends DLoadBaseContext implements LoadManyContext
}
private LoadBuffer createBuffer(int size) {
LoadBuffer buffer = new LoadBuffer(this, size);
LoadBuffer buffer = parent.useReferences ? new LoadBufferWeakRef(this, size) : new LoadBufferHardRef(this, size);
if (bufferList != null) {
bufferList.add(buffer);
}
@@ -94,7 +97,7 @@ final class DLoadManyContext extends DLoadBaseContext implements LoadManyContext
try {
if (bufferList != null) {
for (LoadBuffer loadBuffer : bufferList) {
if (!loadBuffer.list.isEmpty()) {
if (loadBuffer.size() > 0) {
LoadManyRequest req = new LoadManyRequest(loadBuffer, parentRequest);
parent.getEbeanServer().loadMany(req);
}
@@ -115,13 +118,12 @@ final class DLoadManyContext extends DLoadBaseContext implements LoadManyContext
* A buffer for batch loading bean collections on a given path.
* Supports batch lazy loading and secondary query loading.
*/
static class LoadBuffer implements BeanCollectionLoader, LoadManyBuffer {
static abstract class LoadBuffer implements BeanCollectionLoader, LoadManyBuffer {
private final ReentrantLock lock = new ReentrantLock();
private final PersistenceContext persistenceContext;
private final DLoadManyContext context;
private final int batchSize;
private final List<BeanCollection<?>> list;
final int batchSize;
LoadBuffer(DLoadManyContext context, int batchSize) {
this.context = context;
@@ -129,7 +131,6 @@ final class DLoadManyContext extends DLoadBaseContext implements LoadManyContext
// case it changes as part of a findIterate etc
this.persistenceContext = context.getPersistenceContext();
this.batchSize = batchSize;
this.list = new ArrayList<>(batchSize);
}
@Override
@@ -138,7 +139,7 @@ final class DLoadManyContext extends DLoadBaseContext implements LoadManyContext
}
@Override
public int getBatchSize() {
public int batchSize() {
return batchSize;
}
@@ -146,20 +147,15 @@ final class DLoadManyContext extends DLoadBaseContext implements LoadManyContext
* Return true if the buffer is full.
*/
public boolean isFull() {
return batchSize == list.size();
return batchSize() == size();
}
/**
* Return true if the buffer is full.
*/
public void add(BeanCollection<?> bc) {
list.add(bc);
}
public abstract void add(BeanCollection<?> bc);
@Override
public List<BeanCollection<?>> getBatch() {
return list;
}
abstract void clear();
@Override
public BeanPropertyAssocMany<?> getBeanProperty() {
@@ -208,25 +204,133 @@ final class DLoadManyContext extends DLoadBaseContext implements LoadManyContext
final String parentKey = parentDesc.cacheKey(parentId);
if (parentDesc.cacheManyPropLoad(context.property, bc, parentKey, context.parent.isReadOnly())) {
// we loaded the bean collection from cache so remove it from the buffer
for (int i = 0; i < list.size(); i++) {
// find it using instance equality - avoiding equals() and potential deadlock issue
if (list.get(i) == bc) {
list.remove(i);
bc.setLoader(context.parent.getEbeanServer());
return;
}
if (removeFromBuffer(bc)) {
bc.setLoader(context.parent.getEbeanServer());
}
// find it using instance equality - avoiding equals() and potential deadlock issue
return;
}
}
context.parent.getEbeanServer().loadMany(new LoadManyRequest(this, onlyIds, useCache));
// clear the buffer as all entries have been loaded
list.clear();
clear();
} finally {
lock.unlock();
}
}
}
static class LoadBufferHardRef extends LoadBuffer {
private final BeanCollection<?>[] list;
private int size;
LoadBufferHardRef(DLoadManyContext context, int batchSize) {
super(context, batchSize);
this.list = new BeanCollection<?>[batchSize];
}
/**
* Return true if the buffer is full.
*/
@Override
public void add(BeanCollection<?> bc) {
list[size++] = bc;
}
@Override
void clear() {
Arrays.fill(list, null);
size = 0;
}
@Override
public int size() {
return size;
}
@Override
public BeanCollection<?> get(int i) {
return list[i];
}
@Override
public boolean removeFromBuffer(BeanCollection<?> collection) {
for (int i = 0; i < size; i++) {
// find it using instance equality - avoiding equals() and potential deadlock issue
if (list[i] == collection) {
list[i] = null;
return true;
}
}
return false;
}
}
/**
* This load buffer uses weak references, so unreachable beanCollections will drop out from the buffer.
*/
static class LoadBufferWeakRef extends LoadBuffer {
private final Reference<BeanCollection<?>>[] list;
private int size;
LoadBufferWeakRef(DLoadManyContext context, int batchSize) {
super(context, batchSize);
this.list = new Reference[batchSize];
}
/**
* Return true if the buffer is full.
*/
@Override
public void add(BeanCollection<?> bc) {
list[size++] = new WeakReference<>(bc);
}
@Override
void clear() {
Arrays.fill(list, null);
size = 0;
}
@Override
public int size() {
return size;
}
@Override
public BeanCollection<?> get(int i) {
Reference<BeanCollection<?>> ref = list[i];
if (ref == null) {
return null;
}
BeanCollection<?> bc = ref.get();
if (bc == null) {
// remove dead references
list[i] = null;
}
return bc;
}
@Override
public boolean removeFromBuffer(BeanCollection<?> collection) {
for (int i = 0; i < size; i++) {
if (list[i] != null) {
BeanCollection<?> bc = list[i].get();
if (bc == null) {
// remove dead references
list[i] = null;
}
// find it using instance equality - avoiding equals() and potential deadlock issue
if (bc == collection) {
list[i] = null;
return true;
}
}
}
return false;
}
}
}
@@ -2,22 +2,30 @@ package io.ebeaninternal.server.logger;
import io.ebeaninternal.api.SpiLogManager;
import io.ebeaninternal.api.SpiLogger;
import io.ebeaninternal.api.SpiTxnLogger;
import java.util.concurrent.atomic.AtomicLong;
public final class DLogManager implements SpiLogManager {
private final SpiLogger sql;
private final SpiLogger summary;
private final SpiLogger txn;
private final boolean useIds;
private final AtomicLong counter = new AtomicLong(1000);
private final DTxnLogger readOnly;
public DLogManager(SpiLogger sql, SpiLogger summary, SpiLogger txn) {
this.sql = sql;
this.summary = summary;
this.txn = txn;
this.useIds = txn.isDebug();
this.readOnly = new DTxnLogger(null, sql, summary, txn);
}
@Override
public SpiLogger txn() {
return txn;
public boolean enableBindLog() {
return sql.isDebug();
}
@Override
@@ -26,8 +34,13 @@ public final class DLogManager implements SpiLogManager {
}
@Override
public SpiLogger sum() {
return summary;
public SpiTxnLogger logger() {
String id = useIds ? Long.toString(counter.incrementAndGet()) : "";
return new DTxnLogger(id, sql, summary, txn);
}
@Override
public SpiTxnLogger readOnlyLogger() {
return readOnly;
}
}
@@ -3,7 +3,6 @@ package io.ebeaninternal.server.logger;
import io.ebeaninternal.api.SpiLogger;
import static java.lang.System.Logger.Level.DEBUG;
import static java.lang.System.Logger.Level.TRACE;
final class DSpiLogger implements SpiLogger {
@@ -19,17 +18,7 @@ final class DSpiLogger implements SpiLogger {
}
@Override
public boolean isTrace() {
return logger.isLoggable(TRACE);
}
@Override
public void debug(String msg) {
logger.log(DEBUG, msg);
}
@Override
public void trace(String msg) {
logger.log(TRACE, msg);
public void debug(String msg, Object... args) {
logger.log(DEBUG, msg, args);
}
}
@@ -0,0 +1,96 @@
package io.ebeaninternal.server.logger;
import io.ebeaninternal.api.SpiLogger;
import io.ebeaninternal.api.SpiTxnLogger;
import io.ebeaninternal.server.util.Str;
final class DTxnLogger implements SpiTxnLogger {
private final String id;
private final String logPrefix;
private final SpiLogger sql;
private final SpiLogger sum;
private final SpiLogger txn;
DTxnLogger(String id, SpiLogger sql, SpiLogger sum, SpiLogger txn) {
this.id = id;
this.logPrefix = id == null ? "" : "txn[" + id + "] ";
this.sql = sql;
this.sum = sum;
this.txn = txn;
}
@Override
public String id() {
return id;
}
@Override
public boolean isLogSql() {
return sql.isDebug();
}
@Override
public boolean isLogSummary() {
return sum.isDebug();
}
@Override
public void sql(String msg, Object... args) {
sql.debug(Str.add(logPrefix, msg), args);
}
@Override
public void sum(String msg, Object... args) {
sum.debug(Str.add(logPrefix, msg), args);
}
@Override
public void txn(String msg, Object... args) {
txn.debug(Str.add(logPrefix, msg), args);
}
@Override
public void notifyCommit() {
txn.debug(Str.add(logPrefix, "Commit"));
}
@Override
public void notifyQueryOnly() {
// do nothing
}
@Override
public void notifyRollback(Throwable cause) {
if (txn.isDebug()) {
String msg = logPrefix + "Rollback";
if (cause != null) {
msg += " error: " + formatThrowable(cause);
}
txn.debug(msg);
}
}
private String formatThrowable(Throwable e) {
if (e == null) {
return "";
}
StringBuilder sb = new StringBuilder();
formatThrowable(e, sb);
return sb.toString();
}
private void formatThrowable(Throwable e, StringBuilder sb) {
sb.append(e.toString());
StackTraceElement[] stackTrace = e.getStackTrace();
if (stackTrace.length > 0) {
sb.append(" stack0: ");
sb.append(stackTrace[0]);
}
Throwable cause = e.getCause();
if (cause != null) {
sb.append(" cause: ");
formatThrowable(cause, sb);
}
}
}
@@ -313,7 +313,7 @@ public final class BatchControl {
BatchedBeanHolder[] bsArray = beanHolderArray();
Arrays.sort(bsArray, depthComparator);
if (transaction.isLogSummary()) {
transaction.logSummary("BatchControl flush " + Arrays.toString(bsArray));
transaction.logSummary("BatchControl flush {0}", Arrays.toString(bsArray));
}
for (BatchedBeanHolder beanHolder : bsArray) {
beanHolder.executeNow();
@@ -44,7 +44,7 @@ public final class Binder {
this.dbExpressionHandler = dbExpressionHandler;
this.dataTimeZone = dataTimeZone;
this.multiValueBind = multiValueBind;
this.enableBindLog = logManager.sql().isDebug();
this.enableBindLog = logManager.enableBindLog();
}
/**
@@ -672,7 +672,7 @@ public final class DefaultPersister implements Persister {
if (idList != null) {
q.where().idIn(idList);
if (t.isLogSummary()) {
t.logSummary("-- DeleteById of " + descriptor.name() + " ids[" + idList + "] requires fetch of foreign key values");
t.logSummary("-- DeleteById of {0} ids[{1}] requires fetch of foreign key values", descriptor.name(), idList);
}
List<?> beanList = server.findList(q, t);
deleteCascade(beanList, t, deleteMode, false);
@@ -681,7 +681,7 @@ public final class DefaultPersister implements Persister {
} else {
q.where().idEq(id);
if (t.isLogSummary()) {
t.logSummary("-- DeleteById of " + descriptor.name() + " id[" + id + "] requires fetch of foreign key values");
t.logSummary("-- DeleteById of {0} id[{1}] requires fetch of foreign key values", descriptor.name(), id);
}
EntityBean bean = (EntityBean) server.findOne(q, t);
if (bean == null) {
@@ -741,7 +741,7 @@ public final class DefaultPersister implements Persister {
for (BeanPropertyAssocMany<?> many : manys) {
SqlUpdate sqlDelete = many.deleteByParentId(id, idList);
if (t.isLogSummary()) {
t.logSummary("-- Deleting intersection table entries: " + many.fullName());
t.logSummary("-- Deleting intersection table entries: {0}", many.fullName());
}
executeSqlUpdate(sqlDelete, t);
}
@@ -751,9 +751,9 @@ public final class DefaultPersister implements Persister {
SqlUpdate deleteById = descriptor.deleteById(id, idList, deleteMode);
if (t.isLogSummary()) {
if (idList != null) {
t.logSummary("-- Deleting " + descriptor.name() + " Ids: " + idList);
t.logSummary("-- Deleting {0} Ids: {1}", descriptor.name(), idList);
} else {
t.logSummary("-- Deleting " + descriptor.name() + " Id: " + id);
t.logSummary("-- Deleting {0} Id: {1}", descriptor.name(), id);
}
}
@@ -69,7 +69,7 @@ final class DeleteUnloadedForeignKeys {
SpiTransaction t = request.transaction();
if (t.isLogSummary()) {
t.logSummary("-- Ebean fetching foreign key values for delete of " + descriptor.name() + " id:" + id);
t.logSummary("-- Ebean fetching foreign key values for delete of {0} id:{1}", descriptor.name(), id);
}
beanWithForeignKeys = (EntityBean) server.findOne(q, t);
}
@@ -8,7 +8,6 @@ import io.ebeaninternal.server.persist.BatchedPstmt;
import io.ebeaninternal.server.persist.BatchedPstmtHolder;
import io.ebeaninternal.server.persist.dmlbind.BindableRequest;
import io.ebeaninternal.server.bind.DataBind;
import io.ebeaninternal.server.util.Str;
import javax.persistence.OptimisticLockException;
import java.sql.Connection;
@@ -102,7 +101,7 @@ public abstract class DmlHandler implements PersistHandler, BindableRequest {
} catch (OptimisticLockException e) {
// add the SQL and bind values to error message
final String m = e.getMessage() + " sql[" + sql + "] bind[" + bindLog + "]";
persistRequest.transaction().logSummary("OptimisticLockException:" + m);
persistRequest.transaction().logSummary("OptimisticLockException:{0}", m);
throw new OptimisticLockException(m, null, e.getEntity());
}
}
@@ -146,15 +145,15 @@ public abstract class DmlHandler implements PersistHandler, BindableRequest {
switch (batchedStatus) {
case BATCHED_FIRST: {
transaction.logSql(sql);
transaction.logSql(Str.add(" -- bind(", bindLog.toString(), ")"));
transaction.logSql(" -- bind({0})", bindLog);
return;
}
case BATCHED: {
transaction.logSql(Str.add(" -- bind(", bindLog.toString(), ")"));
transaction.logSql(" -- bind({0})", bindLog);
return;
}
default: {
transaction.logSql(Str.add(sql, "; -- bind(", bindLog.toString(), ")"));
transaction.logSql("{0}; -- bind({1})", sql, bindLog);
}
}
}
@@ -18,7 +18,6 @@ import io.ebeaninternal.server.core.OrmQueryRequest;
import io.ebeaninternal.server.core.SpiResultSet;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeaninternal.server.persist.Binder;
import io.ebeaninternal.server.util.Str;
import javax.persistence.PersistenceException;
import java.sql.ResultSet;
@@ -73,7 +72,7 @@ public final class CQueryEngine {
try {
int rows = query.execute();
if (request.logSql()) {
request.logSql(Str.add(query.generatedSql(), "; --bind(", query.bindLog(), ") --micros(", query.micros() + ") --rows(", rows + ")"));
request.logSql("{0}; --bind({1}) --micros({2}) --rows({3})", query.generatedSql(), query.bindLog(), query.micros(), rows);
}
return rows;
} catch (SQLException e) {
@@ -129,7 +128,7 @@ public final class CQueryEngine {
SpiTransaction t = request.transaction();
if (t.isLogSummary()) {
// log the error to the transaction log
t.logSummary("ERROR executing query, bindLog[" + bindLog + "] error:" + StringHelper.removeNewLines(e.getMessage()));
t.logSummary("ERROR executing query, bindLog[{0}] error:{1}", bindLog, StringHelper.removeNewLines(e.getMessage()));
}
// ensure 'rollback' is logged if queryOnly transaction
t.connection();
@@ -147,7 +146,7 @@ public final class CQueryEngine {
}
private <T> void logGeneratedSql(OrmQueryRequest<T> request, String sql, String bindLog, long micros) {
request.logSql(Str.add(sql, "; --bind(", bindLog, ") --micros(", micros + ")"));
request.logSql("{0}; --bind({1}) --micros({2})", sql, bindLog, micros);
}
/**
@@ -403,7 +402,7 @@ public final class CQueryEngine {
* Log the generated SQL to the transaction log.
*/
private void logSql(CQuery<?> query) {
query.transaction().logSql(Str.add(query.generatedSql(), "; --bind(", query.bindLog(), ") --micros(", query.micros() + ")"));
query.transaction().logSql("{0}; --bind({1}) --micros({2})", query.generatedSql(), query.bindLog(), query.micros());
}
/**
@@ -2,7 +2,6 @@ package io.ebeaninternal.server.querydefn;
import io.avaje.lang.NonNullApi;
import io.ebean.*;
import io.ebean.OrderBy.Property;
import io.ebean.bean.CallOrigin;
import io.ebean.bean.ObjectGraphNode;
import io.ebean.bean.ObjectGraphOrigin;
@@ -420,7 +419,7 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
havingExpressions.containsMany(beanDescriptor, manyWhere);
}
if (orderBy != null) {
for (Property orderProperty : orderBy.getProperties()) {
for (OrderBy.Property orderProperty : orderBy.getProperties()) {
ElPropertyDeploy elProp = beanDescriptor.elPropertyDeploy(orderProperty.getProperty());
if (elProp != null && elProp.containsFormulaWithJoin()) {
manyWhere.addFormulaWithJoin(elProp.elPrefix(), elProp.name());
@@ -460,10 +459,10 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
for (OrmQueryProperties joinPath : queryJoins) {
// loop through the orderBy properties and
// move any ones related to the query join
List<Property> properties = orderBy.getProperties();
Iterator<Property> it = properties.iterator();
List<OrderBy.Property> properties = orderBy.getProperties();
Iterator<OrderBy.Property> it = properties.iterator();
while (it.hasNext()) {
Property property = it.next();
OrderBy.Property property = it.next();
if (property.getProperty().startsWith(joinPath.getPath())) {
// remove this orderBy segment and
// add it to the secondary join
@@ -1963,7 +1962,7 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
havingExpressions.validate(validation);
}
if (orderBy != null) {
for (Property property : orderBy.getProperties()) {
for (OrderBy.Property property : orderBy.getProperties()) {
validation.validate(property.getProperty());
}
}
@@ -2,6 +2,7 @@ package io.ebeaninternal.server.querydefn;
import io.ebean.ExpressionList;
import io.ebean.ProfileLocation;
import io.ebean.Query;
import io.ebean.UpdateQuery;
import io.ebean.core.type.ScalarType;
import io.ebeaninternal.server.deploy.BeanDescriptor;
@@ -34,6 +35,16 @@ public final class DefaultUpdateQuery<T> implements UpdateQuery<T> {
return this;
}
@Override
public <P> UpdateQuery<T> set(Query.Property<P> property, P value) {
return set(property.toString(), value);
}
@Override
public UpdateQuery<T> setNull(Query.Property<?> property) {
return setNull(property.toString());
}
@Override
public UpdateQuery<T> setNull(String property) {
values.setNull(property);
@@ -10,8 +10,8 @@ public final class DocStoreOnlyTransaction extends JdbcTransaction {
/**
* Create a new DocStore only Transaction.
*/
public DocStoreOnlyTransaction(String id, boolean explicit, TransactionManager manager) {
super(id, explicit, null, manager);
public DocStoreOnlyTransaction(boolean explicit, TransactionManager manager) {
super(explicit, null, manager);
}
@Override
@@ -25,11 +25,11 @@ public final class DocStoreTransactionManager extends TransactionManager {
@Override
public SpiTransaction createReadOnlyTransaction(Object tenantId) {
return new DocStoreOnlyTransaction("", false, this);
return new DocStoreOnlyTransaction(false, this);
}
@Override
protected SpiTransaction createTransaction(boolean explicit, Connection c) {
return new DocStoreOnlyTransaction(nextTxnId(), explicit, this);
return new DocStoreOnlyTransaction(explicit, this);
}
}
@@ -25,14 +25,14 @@ public class ExternalJdbcTransaction extends JdbcTransaction {
* </p>
*/
public ExternalJdbcTransaction(Connection connection) {
super(null, true, connection, null);
super(true, connection, null);
}
/**
* Construct will all explicit parameters.
*/
public ExternalJdbcTransaction(String id, boolean explicit, Connection connection, TransactionManager manager) {
super(id, explicit, connection, manager);
public ExternalJdbcTransaction(boolean explicit, Connection connection, TransactionManager manager) {
super(explicit, connection, manager);
}
/**
@@ -33,6 +33,7 @@ final class ImplicitReadOnlyTransaction implements SpiTransaction, TxnProfileEve
private static final String notExpectedMessage = "Not expected on read only transaction";
private final TransactionManager manager;
private final SpiTxnLogger logger;
private final boolean logSql;
private final boolean logSummary;
@@ -61,8 +62,9 @@ final class ImplicitReadOnlyTransaction implements SpiTransaction, TxnProfileEve
*/
ImplicitReadOnlyTransaction(TransactionManager manager, Connection connection) {
this.manager = manager;
this.logSql = manager.isLogSql();
this.logSummary = manager.isLogSummary();
this.logger = manager.loggerReadOnly();
this.logSql = logger.isLogSql();
this.logSummary = logger.isLogSummary();
this.active = true;
this.connection = connection;
this.persistenceContext = new DefaultPersistenceContext();
@@ -147,11 +149,6 @@ final class ImplicitReadOnlyTransaction implements SpiTransaction, TxnProfileEve
public void setSkipCache(boolean skipCache) {
}
@Override
public String getLogPrefix() {
return null;
}
@Override
public void addBeanChange(BeanChange beanChange) {
throw new IllegalStateException(notExpectedMessage);
@@ -433,13 +430,18 @@ final class ImplicitReadOnlyTransaction implements SpiTransaction, TxnProfileEve
}
@Override
public void logSql(String msg) {
manager.log().sql().debug(msg);
public void logSql(String msg, Object... args) {
logger.sql(msg, args);
}
@Override
public void logSummary(String msg) {
manager.log().sum().debug(msg);
public void logSummary(String msg, Object... args) {
logger.sum(msg, args);
}
@Override
public void logTxn(String msg, Object... args) {
// never called
}
/**
@@ -11,7 +11,6 @@ import io.ebeaninternal.server.core.PersistDeferredRelationship;
import io.ebeaninternal.server.core.PersistRequestBean;
import io.ebeaninternal.server.persist.BatchControl;
import io.ebeaninternal.server.persist.BatchedSqlException;
import io.ebeaninternal.server.util.Str;
import io.ebeanservice.docstore.api.DocStoreTransaction;
import javax.persistence.PersistenceException;
@@ -33,8 +32,8 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes {
private static final String illegalStateMessage = "Transaction is Inactive";
final TransactionManager manager;
private final SpiTxnLogger logger;
private final String id;
private final String logPrefix;
private final boolean logSql;
private final boolean logSummary;
private final boolean explicit;
@@ -95,17 +94,17 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes {
private final long startNanos;
private boolean autoPersistUpdates;
JdbcTransaction(String id, boolean explicit, Connection connection, TransactionManager manager) {
JdbcTransaction(boolean explicit, Connection connection, TransactionManager manager) {
try {
this.active = true;
this.id = id;
this.logPrefix = deriveLogPrefix(id);
this.explicit = explicit;
this.manager = manager;
this.connection = connection;
this.persistenceContext = new DefaultPersistenceContext();
this.startNanos = System.nanoTime();
if (manager == null) {
this.logger = null;
this.id = "";
this.logSql = false;
this.logSummary = false;
this.skipCacheAfterWrite = true;
@@ -113,9 +112,11 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes {
this.batchOnCascadeMode = false;
this.onQueryOnlyCommit = false;
} else {
this.logger = manager.logger();
this.id = logger.id();
this.autoPersistUpdates = explicit && manager.isAutoPersistUpdates();
this.logSql = manager.isLogSql();
this.logSummary = manager.isLogSummary();
this.logSql = logger.isLogSql();
this.logSummary = logger.isLogSummary();
this.skipCacheAfterWrite = manager.isSkipCacheAfterWrite();
this.batchMode = manager.isPersistBatch();
this.batchOnCascadeMode = manager.isPersistBatchOnCascade();
@@ -188,16 +189,7 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes {
}
}
private static String deriveLogPrefix(String id) {
StringBuilder sb = new StringBuilder();
sb.append("txn[");
if (id != null) {
sb.append(id);
}
sb.append("] ");
return sb.toString();
}
@Override
public final void setAutoPersistUpdates(boolean autoPersistUpdates) {
@@ -226,17 +218,13 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes {
this.skipCache = skipCache;
}
@Override
public final String getLogPrefix() {
return logPrefix;
}
@Override
public String toString() {
if (active) {
return logPrefix;
return id;
} else {
return logPrefix + "(inactive)";
return id + "(inactive)";
}
}
@@ -726,13 +714,18 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes {
}
@Override
public final void logSql(String msg) {
manager.log().sql().debug(Str.add(logPrefix, msg));
public void logSql(String msg, Object... args) {
logger.sql(msg, args);
}
@Override
public final void logSummary(String msg) {
manager.log().sum().debug(Str.add(logPrefix, msg));
public final void logSummary(String msg, Object... args) {
logger.sum(msg, args);
}
@Override
public void logTxn(String msg, Object... args) {
logger.txn(msg, args);
}
/**
@@ -805,9 +798,11 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes {
final void notifyCommit() {
if (manager != null) {
if (queryOnly) {
logger.notifyQueryOnly();
manager.notifyOfQueryOnly(this);
} else {
manager.notifyOfCommit(this);
logger.notifyCommit();
}
}
}
@@ -966,6 +961,7 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes {
manager.notifyOfQueryOnly(this);
} else {
manager.notifyOfRollback(this, cause);
logger.notifyRollback(cause);
}
}
}
@@ -20,8 +20,8 @@ public final class JtaTransaction extends JdbcTransaction {
/**
* Create the JtaTransaction.
*/
public JtaTransaction(String id, boolean explicit, UserTransaction utx, DataSource ds, TransactionManager manager) {
super(id, explicit, null, manager);
public JtaTransaction(boolean explicit, UserTransaction utx, DataSource ds, TransactionManager manager) {
super(explicit, null, manager);
userTransaction = utx;
try {
newTransaction = userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION;
@@ -105,8 +105,7 @@ public final class JtaTransactionManager implements ExternalTransactionManager {
// This is a transaction that Ebean has not seen before.
// "wrap" it in a Ebean specific JtaTransaction
String txnId = String.valueOf(System.currentTimeMillis());
JtaTransaction newTrans = new JtaTransaction(txnId, true, ut, dataSource(), transactionManager);
JtaTransaction newTrans = new JtaTransaction( true, ut, dataSource(), transactionManager);
// create and register transaction listener
JtaTxnListener txnListener = createJtaTxnListener(newTrans);
@@ -117,10 +117,6 @@ final class NoTransaction implements SpiTransaction {
// do nothing
}
@Override
public String getLogPrefix() {
return null;
}
@Override
public boolean isLogSql() {
@@ -133,12 +129,17 @@ final class NoTransaction implements SpiTransaction {
}
@Override
public void logSql(String msg) {
public void logSql(String msg, Object... args) {
}
@Override
public void logSummary(String msg) {
public void logSummary(String msg, Object... args) {
}
@Override
public void logTxn(String msg, Object... args) {
}
@@ -21,7 +21,6 @@ final class SavepointTransaction extends SpiTransactionProxy {
private final TransactionManager manager;
private final Savepoint savepoint;
private final Connection connection;
private final String logPrefix;
private final String spPrefix;
private boolean rollbackOnly;
@@ -33,13 +32,12 @@ final class SavepointTransaction extends SpiTransactionProxy {
this.transaction = transaction;
this.connection = transaction.getInternalConnection();
this.savepoint = connection.setSavepoint();
if (manager.isTxnDebug()) {
if (transaction.isLogSql()) {
int savepointId = manager.isSupportsSavepointId() ? savepoint.getSavepointId() : 0;
this.spPrefix = "sp[" + savepointId + "] ";
} else {
this.spPrefix = "sp[] ";
}
this.logPrefix = transaction.getLogPrefix() + spPrefix;
}
@Override
@@ -51,18 +49,13 @@ final class SavepointTransaction extends SpiTransactionProxy {
}
@Override
public String getLogPrefix() {
return logPrefix;
public void logSql(String msg, Object... args) {
transaction.logSql(Str.add(spPrefix, msg), args);
}
@Override
public void logSql(String msg) {
transaction.logSql(Str.add(spPrefix, msg));
}
@Override
public void logSummary(String msg) {
transaction.logSummary(Str.add(spPrefix, msg));
public void logSummary(String msg, Object... args) {
transaction.logSummary(Str.add(spPrefix, msg), args);
}
@Override
@@ -99,6 +92,7 @@ final class SavepointTransaction extends SpiTransactionProxy {
connection.releaseSavepoint(savepoint);
state = STATE_COMMITTED;
manager.notifyOfCommit(this);
transaction.logTxn(spPrefix + "commit");
} catch (SQLException e) {
throw new PersistenceException("Error trying to commit/release Savepoint", e);
}
@@ -109,6 +103,7 @@ final class SavepointTransaction extends SpiTransactionProxy {
connection.rollback(savepoint);
state = STATE_ROLLED_BACK;
manager.notifyOfRollback(this, cause);
transaction.logTxn(spPrefix + "rollback");//TODO: Pass the cause
} catch (SQLException e) {
throw new PersistenceException("Error trying to rollback Savepoint", e);
}
@@ -43,9 +43,6 @@ abstract class TransactionFactory {
throw new PersistenceException(e);
}
}
if (explicit && manager.log().txn().isTrace()) {
manager.log().txn().trace(t.getLogPrefix() + "Begin");
}
return t;
}
}
@@ -36,7 +36,6 @@ import java.sql.SQLException;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import static java.lang.System.Logger.Level.DEBUG;
import static java.lang.System.Logger.Level.ERROR;
@@ -63,8 +62,6 @@ public class TransactionManager implements SpiTransactionManager {
* Prefix for transaction id's (logging).
*/
final String prefix;
private final String externalTransPrefix;
private final AtomicLong counter = new AtomicLong(1000L);
/**
* The dataSource of connections.
@@ -96,8 +93,6 @@ public class TransactionManager implements SpiTransactionManager {
private final boolean skipCacheAfterWrite;
private final TransactionFactory transactionFactory;
private final SpiLogManager logManager;
private final SpiLogger txnLogger;
private final boolean txnDebug;
private final DatabasePlatform databasePlatform;
private final SpiProfileHandler profileHandler;
private final TimedMetric txnMain;
@@ -115,8 +110,6 @@ public class TransactionManager implements SpiTransactionManager {
public TransactionManager(TransactionManagerOptions options) {
this.server = options.server;
this.logManager = options.logManager;
this.txnLogger = logManager.txn();
this.txnDebug = txnLogger.isDebug();
this.databasePlatform = options.config.getDatabasePlatform();
this.supportsSavepointId = databasePlatform.supportsSavepointId();
this.skipCacheAfterWrite = options.config.isSkipCacheAfterWrite();
@@ -142,7 +135,6 @@ public class TransactionManager implements SpiTransactionManager {
this.profileHandler = options.profileHandler;
this.bulkEventListenerMap = new BulkEventListenerMap(options.config.getBulkTableEventListeners());
this.prefix = "";
this.externalTransPrefix = "e";
CurrentTenantProvider tenantProvider = options.config.getCurrentTenantProvider();
this.transactionFactory = TransactionFactoryBuilder.build(this, dataSourceSupplier, tenantProvider);
@@ -273,14 +265,7 @@ public class TransactionManager implements SpiTransactionManager {
* Wrap the externally supplied Connection.
*/
public SpiTransaction wrapExternalConnection(Connection c) {
return wrapExternalConnection(externalTransPrefix + c.hashCode(), c);
}
/**
* Wrap an externally supplied Connection with a known transaction id.
*/
private SpiTransaction wrapExternalConnection(String id, Connection c) {
ExternalJdbcTransaction t = new ExternalJdbcTransaction(id, true, c, this);
ExternalJdbcTransaction t = new ExternalJdbcTransaction(true, c, this);
// set the default batch mode
t.setBatchMode(persistBatch);
t.setBatchOnCascade(persistBatchOnCascade);
@@ -313,14 +298,7 @@ public class TransactionManager implements SpiTransactionManager {
* Create a new transaction.
*/
SpiTransaction createTransaction(boolean explicit, Connection c) {
return new JdbcTransaction(nextTxnId(), explicit, c, this);
}
/**
* Return the next transaction id.
*/
String nextTxnId() {
return txnDebug ? prefix + counter.incrementAndGet() : prefix;
return new JdbcTransaction(explicit, c, this);
}
/**
@@ -328,17 +306,7 @@ public class TransactionManager implements SpiTransactionManager {
*/
@Override
public final void notifyOfRollback(SpiTransaction transaction, Throwable cause) {
try {
if (txnLogger.isDebug()) {
String msg = transaction.getLogPrefix() + "Rollback";
if (cause != null) {
msg += " error: " + formatThrowable(cause);
}
txnLogger.debug(msg);
}
} catch (Exception ex) {
log.log(ERROR, "Error while notifying TransactionEventListener of rollback event", ex);
}
// Do nothing now
}
/**
@@ -347,32 +315,6 @@ public class TransactionManager implements SpiTransactionManager {
@Override
public final void notifyOfQueryOnly(SpiTransaction transaction) {
// Nothing that interesting here
if (txnLogger.isTrace()) {
txnLogger.trace(transaction.getLogPrefix() + "Commit - query only");
}
}
private String formatThrowable(Throwable e) {
if (e == null) {
return "";
}
StringBuilder sb = new StringBuilder();
formatThrowable(e, sb);
return sb.toString();
}
private void formatThrowable(Throwable e, StringBuilder sb) {
sb.append(e.toString());
StackTraceElement[] stackTrace = e.getStackTrace();
if (stackTrace.length > 0) {
sb.append(" stack0: ");
sb.append(stackTrace[0]);
}
Throwable cause = e.getCause();
if (cause != null) {
sb.append(" cause: ");
formatThrowable(cause, sb);
}
}
/**
@@ -381,9 +323,6 @@ public class TransactionManager implements SpiTransactionManager {
@Override
public final void notifyOfCommit(SpiTransaction transaction) {
try {
if (txnLogger.isDebug()) {
txnLogger.debug(transaction.getLogPrefix() + "Commit");
}
PostCommitProcessing postCommit = new PostCommitProcessing(clusterManager, this, transaction);
postCommit.notifyLocalCache();
backgroundExecutor.execute(postCommit.backgroundNotify());
@@ -676,25 +615,18 @@ public class TransactionManager implements SpiTransactionManager {
}
}
/**
* Return true if Transaction debug is on.
*/
public final boolean isTxnDebug() {
return txnDebug;
public SpiTxnLogger logger() {
return logManager.logger();
}
public SpiTxnLogger loggerReadOnly() {
return logManager.readOnlyLogger();
}
public final SpiLogManager log() {
return logManager;
}
public final boolean isLogSql() {
return logManager.sql().isDebug();
}
public final boolean isLogSummary() {
return logManager.sum().isDebug();
}
/**
* Experimental - find dirty beans in the persistence context and persist them.
*/
@@ -704,4 +636,5 @@ public class TransactionManager implements SpiTransactionManager {
server.updateAll(dirtyBeans, transaction);
}
}
}
@@ -43,4 +43,24 @@ public final class Str {
return sb.append(s0).append(s1).toString();
}
public static String add(String s0, String[] s1) {
if (s1 == null || s1.length == 0) {
return s0;
}
int len = s0.length();
for (String s : s1) {
if (s != null) {
len += s.length();
}
}
StringBuilder sb = new StringBuilder(len);
sb.append(s0);
for (String s : s1) {
if (s != null) {
sb.append(s);
}
}
return sb.toString();
}
}
+4 -4
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.12.0</version>
<version>13.13.0</version>
</parent>
<artifactId>ebean-csv-reader</artifactId>
@@ -14,21 +14,21 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
<scope>test</scope>
</dependency>
+4 -4
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.12.0</version>
<version>13.13.0</version>
</parent>
<name>ebean ddl generation</name>
@@ -28,14 +28,14 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
<scope>provided</scope>
</dependency>
@@ -58,7 +58,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-all</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
<scope>test</scope>
</dependency>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.12.0</version>
<version>13.13.0</version>
</parent>
<name>ebean external mapping api</name>
+6 -6
View File
@@ -4,12 +4,12 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.12.0</version>
<version>13.13.0</version>
</parent>
<scm>
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
<tag>ebean-parent-13.12.0</tag>
<tag>ebean-parent-13.13.0</tag>
</scm>
<name>ebean external mapping xml</name>
@@ -21,7 +21,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-externalmapping-api</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<dependency>
@@ -54,21 +54,21 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-generator</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
<scope>test</scope>
</dependency>
+2 -2
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.12.0</version>
<version>13.13.0</version>
</parent>
<artifactId>ebean-jackson-jsonnode</artifactId>
@@ -14,7 +14,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
<scope>provided</scope>
</dependency>
+2 -2
View File
@@ -3,7 +3,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.12.0</version>
<version>13.13.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -14,7 +14,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
<scope>provided</scope>
</dependency>
+2 -2
View File
@@ -3,7 +3,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.12.0</version>
<version>13.13.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -14,7 +14,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
<scope>provided</scope>
</dependency>
@@ -23,7 +23,7 @@ final class ScalarTypeJodaDateMidnight extends ScalarTypeBaseDate<DateMidnight>
@Override
protected String toIsoFormat(DateMidnight value) {
return value.toString();
return value.toLocalDate().toString();
}
@Override
@@ -28,6 +28,11 @@ final class ScalarTypeJodaLocalDateTime extends ScalarTypeBaseDateTime<LocalDate
return value.toString();
}
@Override
protected LocalDateTime fromJsonISO8601(String value) {
return LocalDateTime.parse(value);
}
@Override
public long convertToMillis(LocalDateTime value) {
return value.toDateTime().getMillis();
@@ -0,0 +1,30 @@
package io.ebean.joda.time;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import io.ebean.config.JsonConfig;
import org.joda.time.DateMidnight;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.StringReader;
import static org.junit.jupiter.api.Assertions.assertEquals;
class ScalarTypeJodaDateMidnightTest {
ScalarTypeJodaDateMidnight type = new ScalarTypeJodaDateMidnight(JsonConfig.Date.ISO8601);
JsonFactory jsonFactory = new JsonFactory();
@Test
void testIsoFormat() throws IOException {
// long millis = 1674472451640L;
JsonParser parser = jsonFactory.createParser(new StringReader("\"2023-01-23\""));
JsonToken token = parser.nextToken();
assertEquals(JsonToken.VALUE_STRING, token);
DateMidnight dm = type.jsonRead(parser);
String iso = type.toIsoFormat(dm);
assertEquals("2023-01-23", iso);
}
}
@@ -1,21 +1,37 @@
package io.ebean.joda.time;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import io.ebean.config.JsonConfig;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalDateTime;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.StringReader;
import java.sql.Timestamp;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class ScalarTypeJodaLocalDateTimeTest {
class ScalarTypeJodaLocalDateTimeTest {
ScalarTypeJodaLocalDateTime type = new ScalarTypeJodaLocalDateTime(JsonConfig.DateTime.ISO8601);
JsonFactory jsonFactory = new JsonFactory();
@Test
public void testConvertFromTimestamp() throws Exception {
void testIsoFormat() throws IOException {
JsonParser parser = jsonFactory.createParser(new StringReader("\"2023-01-23T12:14:11.640\""));
JsonToken token = parser.nextToken();
assertEquals(JsonToken.VALUE_STRING, token);
LocalDateTime ldt1 = type.jsonRead(parser);
String iso = type.toJsonISO8601(ldt1);
assertEquals("2023-01-23T12:14:11.640", iso);
}
@Test
void testConvertFromTimestamp() {
long now = System.currentTimeMillis();
Timestamp nowTs = new Timestamp(now);
@@ -30,12 +46,10 @@ public class ScalarTypeJodaLocalDateTimeTest {
assertEquals(ts1, ts2);
}
LocalDateTime localConvertFromTimestamp(Timestamp ts) {
return new LocalDateTime(ts.getTime(), DateTimeZone.getDefault());
}
Timestamp localConvertToTimestamp(LocalDateTime t) {
return new Timestamp(t.toDateTime(DateTimeZone.getDefault()).getMillis());
}
+3 -3
View File
@@ -6,7 +6,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.12.0-SNAPSHOT</version>
<version>13.13.0-SNAPSHOT</version>
</parent>
<artifactId>ebean-kotlin</artifactId>
@@ -28,7 +28,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.12.0-SNAPSHOT</version>
<version>13.13.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
@@ -50,7 +50,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>13.12.0-SNAPSHOT</version>
<version>13.13.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
+4 -4
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.12.0</version>
<version>13.13.0</version>
</parent>
<name>ebean postgis</name>
@@ -22,14 +22,14 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
</dependency>
<!-- provided scope -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
<scope>provided</scope>
</dependency>
@@ -65,7 +65,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
<scope>test</scope>
</dependency>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.12.0</version>
<version>13.13.0</version>
</parent>
<name>ebean querybean</name>
@@ -17,7 +17,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
<scope>provided</scope>
</dependency>
@@ -63,21 +63,21 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-generator</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>querybean-generator</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>13.12.0</version>
<version>13.13.0</version>
<scope>test</scope>
</dependency>
@@ -6,7 +6,7 @@ package io.ebean.typequery;
* @param <R> the root query bean type
* @param <E> the element type of the DbArray
*/
public final class PArray<R, E> extends TQPropertyBase<R> {
public final class PArray<R, E> extends TQPropertyBase<R, E> {
/**
* Construct with a property name and root instance.
@@ -9,8 +9,7 @@ import io.ebean.Query;
* @param <R> the root query bean type
* @param <T> the type of the scalar property
*/
@SuppressWarnings("rawtypes")
public class PBaseCompareable<R, T> extends PBaseValueEqual<R, T> {
public abstract class PBaseComparable<R, T> extends PBaseValueEqual<R, T> {
/**
* Construct with a property name and root instance.
@@ -18,14 +17,14 @@ public class PBaseCompareable<R, T> extends PBaseValueEqual<R, T> {
* @param name property name
* @param root the root query bean instance
*/
public PBaseCompareable(String name, R root) {
public PBaseComparable(String name, R root) {
super(name, root);
}
/**
* Construct with additional path prefix.
*/
public PBaseCompareable(String name, R root, String prefix) {
public PBaseComparable(String name, R root, String prefix) {
super(name, root, prefix);
}
@@ -44,12 +43,14 @@ public class PBaseCompareable<R, T> extends PBaseValueEqual<R, T> {
/**
* Greater than other property.
* <p>
* Note that the other property must have the same common "Base type" (String, Number, Temporal, Boolean or Object).
*
* @param other the other property to compare
* @return the root query bean instance
*/
public final R gt(TQProperty<?> other) {
expr().raw(_name + " > " + other.propertyName());
public final R gt(Query.Property<T> other) {
expr().raw(_name + " > " + other.toString());
return _root;
}
@@ -81,8 +82,8 @@ public class PBaseCompareable<R, T> extends PBaseValueEqual<R, T> {
* @param other the other property to compare
* @return the root query bean instance
*/
public final R ge(TQProperty<?> other) {
expr().raw(_name + " >= " + other.propertyName());
public final R ge(Query.Property<T> other) {
expr().raw(_name + " >= " + other.toString());
return _root;
}
@@ -114,8 +115,8 @@ public class PBaseCompareable<R, T> extends PBaseValueEqual<R, T> {
* @param other the other property to compare
* @return the root query bean instance
*/
public final R lt(TQProperty<?> other) {
expr().raw(_name + " < " + other.propertyName());
public final R lt(Query.Property<T> other) {
expr().raw(_name + " < " + other.toString());
return _root;
}
@@ -147,8 +148,8 @@ public class PBaseCompareable<R, T> extends PBaseValueEqual<R, T> {
* @param other the other property to compare
* @return the root query bean instance
*/
public final R le(TQProperty<?> other) {
expr().raw(_name + " <= " + other.propertyName());
public final R le(Query.Property<T> other) {
expr().raw(_name + " <= " + other.toString());
return _root;
}
@@ -197,8 +198,8 @@ public class PBaseCompareable<R, T> extends PBaseValueEqual<R, T> {
* The most common use of this could be called "effective dating" where 2 date or
* timestamp columns represent the date range in which
*/
public final R inRangeWith(TQProperty<R> highProperty, T value) {
expr().inRangeWith(_name, highProperty._name, value);
public final R inRangeWith(Query.Property<T> highProperty, T value) {
expr().inRangeWith(_name, highProperty.toString(), value);
return _root;
}
@@ -220,8 +221,8 @@ public class PBaseCompareable<R, T> extends PBaseValueEqual<R, T> {
* <p>
* This is a convenience expression combining a number of simple expressions.
*/
public final R inRangeWith(TQProperty<?> lowProperty, TQProperty<?> highProperty) {
expr().inRangeWithProperties(_name, lowProperty.propertyName(), highProperty.propertyName());
public final R inRangeWith(Query.Property<T> lowProperty, Query.Property<T> highProperty) {
expr().inRangeWithProperties(_name, lowProperty.toString(), highProperty.toString());
return _root;
}
@@ -4,10 +4,10 @@ package io.ebean.typequery;
* Base property for date and date time types.
*
* @param <R> the root query bean type
* @param <D> the date time type
* @param <T> the scalar type
*/
@SuppressWarnings("rawtypes")
public abstract class PBaseDate<R, D extends Comparable> extends PBaseCompareable<R, D> {
public abstract class PBaseDate<R, T extends Comparable> extends PBaseComparable<R, T> {
/**
* Construct with a property name and root instance.
@@ -32,7 +32,7 @@ public abstract class PBaseDate<R, D extends Comparable> extends PBaseCompareabl
* @param value the equal to bind value
* @return the root query bean instance
*/
public final R after(D value) {
public final R after(T value) {
expr().gt(_name, value);
return _root;
}
@@ -43,7 +43,7 @@ public abstract class PBaseDate<R, D extends Comparable> extends PBaseCompareabl
* @param value the equal to bind value
* @return the root query bean instance
*/
public final R before(D value) {
public final R before(T value) {
expr().lt(_name, value);
return _root;
}
@@ -4,10 +4,10 @@ package io.ebean.typequery;
* Base property for number types.
*
* @param <R> the root query bean type
* @param <T> the number type
* @param <T> the property type
*/
@SuppressWarnings("rawtypes")
public abstract class PBaseNumber<R,T extends Comparable> extends PBaseCompareable<R,T> {
public abstract class PBaseNumber<R, T extends Comparable> extends PBaseComparable<R, T> {
/**
* Construct with a property name and root instance.
@@ -16,7 +16,7 @@ public abstract class PBaseNumber<R,T extends Comparable> extends PBaseCompareab
* @param root the root query bean instance
*/
public PBaseNumber(String name, R root) {
super(name , root);
super(name, root);
}
/**
@@ -5,7 +5,7 @@ package io.ebean.typequery;
*
* @param <R> the root query bean type
*/
public abstract class PBaseString<R,T> extends PBaseCompareable<R, String> {
public abstract class PBaseString<R, T> extends PBaseComparable<R, T> {
/**
* Construct with a property name and root instance.
@@ -25,22 +25,28 @@ public abstract class PBaseString<R,T> extends PBaseCompareable<R, String> {
}
/**
* Deprecated migrate to eq().
* <p>
* Is equal to. The same as <code>eq</code> but uses the strong type as argument rather than String.
*
* @param value the equal to bind value
* @return the root query bean instance
*/
@Deprecated
public final R equalToType(T value) {
expr().eq(_name, value);
return _root;
}
/**
* Deprecated migrate to ne().
* <p>
* Is not equal to. The same as <code>ne</code> but uses the strong type as argument rather than String.
*
* @param value the equal to bind value
* @return the root query bean instance
*/
@Deprecated
public final R notEqualToType(T value) {
expr().ne(_name, value);
return _root;
@@ -49,7 +55,146 @@ public abstract class PBaseString<R,T> extends PBaseCompareable<R, String> {
// common string / expressions ------------
/**
* Case insensitive is equal to.
* Equal to.
*
* @param value the bind value
* @return the root query bean instance
*/
public final R eq(String value) {
expr().eq(_name, value);
return _root;
}
/**
* Not equal to.
*
* @param value the bind value
* @return the root query bean instance
*/
public final R ne(String value) {
expr().ne(_name, value);
return _root;
}
/**
* Greater than.
*
* @param value the bind value
* @return the root query bean instance
*/
public final R gt(String value) {
expr().gt(_name, value);
return _root;
}
/**
* Greater than OR Null.
*
* @param value the bind value
* @return the root query bean instance
*/
public final R gtOrNull(String value) {
expr().gtOrNull(_name, value);
return _root;
}
/**
* Greater than or Equal to.
*
* @param value the bind value
* @return the root query bean instance
*/
public final R ge(String value) {
expr().ge(_name, value);
return _root;
}
/**
* Greater than or Equal to OR Null.
*
* @param value the bind value
* @return the root query bean instance
*/
public final R geOrNull(String value) {
expr().geOrNull(_name, value);
return _root;
}
/**
* Less than.
*
* @param value the bind value
* @return the root query bean instance
*/
public final R lt(String value) {
expr().lt(_name, value);
return _root;
}
/**
* Less than OR Null.
*
* @param value the bind value
* @return the root query bean instance
*/
public final R ltOrNull(String value) {
expr().ltOrNull(_name, value);
return _root;
}
/**
* Less than or Equal to.
*
* @param value the bind value
* @return the root query bean instance
*/
public final R le(String value) {
expr().le(_name, value);
return _root;
}
/**
* Less than or Equal to OR null.
*
* @param value the bind value
* @return the root query bean instance
*/
public final R leOrNull(String value) {
expr().leOrNull(_name, value);
return _root;
}
/**
* Greater or equal to lower value and strictly less than upper value.
* <p>
* This is generally preferable over Between for date and datetime types
* as SQL Between is inclusive on the upper bound ({@code <= }) and generally
* we need the upper bound to be exclusive ({@code < }).
* </p>
*
* @param lower the lower bind value ({@code >= })
* @param upper the upper bind value ({@code < })
* @return the root query bean instance
*/
public final R inRange(String lower, String upper) {
expr().inRange(_name, lower, upper);
return _root;
}
/**
* Between lower and upper values.
*
* @param lower the lower bind value
* @param upper the upper bind value
* @return the root query bean instance
*/
public final R between(String lower, String upper) {
expr().between(_name, lower, upper);
return _root;
}
/**
* Case-insensitive is equal to.
*
* @param value the equal to bind value
* @return the root query bean instance
@@ -60,7 +205,7 @@ public abstract class PBaseString<R,T> extends PBaseCompareable<R, String> {
}
/**
* Case insensitive is equal to.
* Case-insensitive is equal to.
*
* @param value the equal to bind value
* @return the root query bean instance
@@ -115,7 +260,7 @@ public abstract class PBaseString<R,T> extends PBaseCompareable<R, String> {
}
/**
* Case insensitive like.
* Case-insensitive like.
*
* @param value the equal to bind value
* @return the root query bean instance
@@ -126,7 +271,7 @@ public abstract class PBaseString<R,T> extends PBaseCompareable<R, String> {
}
/**
* Case insensitive starts with.
* Case-insensitive starts with.
*
* @param value the equal to bind value
* @return the root query bean instance
@@ -137,7 +282,7 @@ public abstract class PBaseString<R,T> extends PBaseCompareable<R, String> {
}
/**
* Case insensitive ends with.
* Case-insensitive ends with.
*
* @param value the equal to bind value
* @return the root query bean instance
@@ -148,7 +293,7 @@ public abstract class PBaseString<R,T> extends PBaseCompareable<R, String> {
}
/**
* Case insensitive contains.
* Case-insensitive contains.
*
* @param value the equal to bind value
* @return the root query bean instance
@@ -0,0 +1,50 @@
package io.ebean.typequery;
/**
* Base property for time types.
*
* @param <R> the root query bean type
* @param <T> the number type
*/
@SuppressWarnings("rawtypes")
public abstract class PBaseTime<R, T extends Comparable> extends PBaseComparable<R, T> {
/**
* Construct with a property name and root instance.
*
* @param name property name
* @param root the root query bean instance
*/
public PBaseTime(String name, R root) {
super(name, root);
}
/**
* Construct with additional path prefix.
*/
public PBaseTime(String name, R root, String prefix) {
super(name, root, prefix);
}
/**
* Same as greater than.
*
* @param value the equal to bind value
* @return the root query bean instance
*/
public final R after(T value) {
expr().gt(_name, value);
return _root;
}
/**
* Same as less than.
*
* @param value the equal to bind value
* @return the root query bean instance
*/
public final R before(T value) {
expr().lt(_name, value);
return _root;
}
}
@@ -11,7 +11,7 @@ import java.util.Collection;
* @param <R> the root query bean type
* @param <T> the number type
*/
public abstract class PBaseValueEqual<R, T> extends TQPropertyBase<R> {
public abstract class PBaseValueEqual<R, T> extends TQPropertyBase<R, T> {
/**
* Construct with a property name and root instance.
@@ -89,8 +89,8 @@ public abstract class PBaseValueEqual<R, T> extends TQPropertyBase<R> {
* @param other the other property to compare
* @return the root query bean instance
*/
public final R eq(TQProperty<?> other) {
expr().raw(_name + " = " + other.propertyName());
public final R eq(Query.Property<T> other) {
expr().raw(_name + " = " + other.toString());
return _root;
}
@@ -152,8 +152,8 @@ public abstract class PBaseValueEqual<R, T> extends TQPropertyBase<R> {
* @param other the other property to compare
* @return the root query bean instance
*/
public final R ne(TQProperty<?> other) {
expr().raw(_name + " <> " + other.propertyName());
public final R ne(Query.Property<T> other) {
expr().raw(_name + " <> " + other.toString());
return _root;
}
@@ -24,5 +24,4 @@ public final class PByteArray<R> extends PBaseValueEqual<R, byte[]> {
super(name, root, prefix);
}
}
@@ -7,7 +7,7 @@ import java.util.Calendar;
*
* @param <R> the root query bean type
*/
public final class PCalendar<R> extends PBaseDate<R,Calendar> {
public final class PCalendar<R> extends PBaseDate<R, Calendar> {
/**
* Construct with a property name and root instance.
@@ -7,7 +7,7 @@ import io.ebean.types.Cidr;
*
* @param <R> the root query bean type
*/
public final class PCidr<R> extends PBaseValueEqual<R, Cidr> {
public final class PCidr<R> extends PBaseString<R, Cidr> {
/**
* Construct with a property name and root instance.
@@ -7,7 +7,7 @@ import java.util.Currency;
*
* @param <R> the root query bean type
*/
public final class PCurrency<R> extends PBaseValueEqual<R,Currency> {
public final class PCurrency<R> extends PBaseString<R, Currency> {
/**
* Construct with a property name and root instance.
@@ -1,12 +1,12 @@
package io.ebean.typequery;
/**
* BigDecimal property.
* Enum property.
*
* @param <E> the enum specific type
* @param <R> the root query bean type
*/
public final class PEnum<R,E> extends PBaseValueEqual<R,E> {
public final class PEnum<R, E> extends PBaseValueEqual<R, E> {
/**
* Construct with a property name and root instance.
@@ -9,7 +9,7 @@ package io.ebean.typequery;
*
* @param <R> the root query bean type
*/
public final class PFile<R> extends TQPropertyBase<R> {
public final class PFile<R> extends TQPropertyBase<R, Object> {
/**
* Construct with a property name and root instance.
@@ -7,7 +7,7 @@ import io.ebean.types.Inet;
*
* @param <R> the root query bean type
*/
public final class PInet<R> extends PBaseValueEqual<R, Inet> {
public final class PInet<R> extends PBaseString<R, Inet> {
/**
* Construct with a property name and root instance.
@@ -7,8 +7,7 @@ import java.net.InetAddress;
*
* @param <R> the root query bean type
*/
public final class PInetAddress<R> extends PBaseValueEqual<R,InetAddress> {
public final class PInetAddress<R> extends PBaseString<R, InetAddress> {
/**
* Construct with a property name and root instance.
@@ -8,7 +8,7 @@ import java.time.Instant;
*
* @param <R> the root query bean type
*/
public final class PInstant<R> extends PBaseDate<R,Instant> {
public final class PInstant<R> extends PBaseDate<R, Instant> {
/**
* Construct with a property name and root instance.
@@ -7,7 +7,7 @@ import org.joda.time.DateMidnight;
*
* @param <R> the root query bean type
*/
public final class PJodaDateMidnight<R> extends PBaseDate<R,DateMidnight> {
public final class PJodaDateMidnight<R> extends PBaseDate<R, DateMidnight> {
/**
* Construct with a property name and root instance.
@@ -7,7 +7,7 @@ import org.joda.time.DateTime;
*
* @param <R> the root query bean type
*/
public final class PJodaDateTime<R> extends PBaseDate<R,DateTime> {
public final class PJodaDateTime<R> extends PBaseDate<R, DateTime> {
/**
* Construct with a property name and root instance.

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