mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Compare commits
322
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
714bbadbc0 | ||
|
|
9e811e9aef | ||
|
|
f97dcb60c0 | ||
|
|
65c76cb2c0 | ||
|
|
874427dac1 | ||
|
|
1176c2e97a | ||
|
|
44e0585fb7 | ||
|
|
889c0f12e0 | ||
|
|
0135263dbd | ||
|
|
564194042b | ||
|
|
244d45674a | ||
|
|
4722f10f5e | ||
|
|
3f5140e7f3 | ||
|
|
43dec17d08 | ||
|
|
f1ee45d7d1 | ||
|
|
3263e7bfc3 | ||
|
|
e01f19b3aa | ||
|
|
20f6a659fe | ||
|
|
09fe923770 | ||
|
|
e6f5e42c2d | ||
|
|
5150ecba62 | ||
|
|
978b1dbe02 | ||
|
|
9813703ce5 | ||
|
|
09001e80b5 | ||
|
|
4aa3ca6d95 | ||
|
|
5ec8469ddc | ||
|
|
39099bbcc9 | ||
|
|
cb2ca0de11 | ||
|
|
b25233b0b9 | ||
|
|
743f1b10e3 | ||
|
|
371f50fb4d | ||
|
|
a3be2041c8 | ||
|
|
09a831f2d6 | ||
|
|
27d9e03691 | ||
|
|
5a3c6b9dad | ||
|
|
502eb78ffd | ||
|
|
761ec584b2 | ||
|
|
144b8c3077 | ||
|
|
79a1b3a024 | ||
|
|
519b75a778 | ||
|
|
1659c526d7 | ||
|
|
93fc7b07a0 | ||
|
|
d7e6feebc2 | ||
|
|
2a6c60c89b | ||
|
|
b569ec97ee | ||
|
|
6b6cf48ae2 | ||
|
|
f09cba3ab5 | ||
|
|
724183f669 | ||
|
|
a40212d41e | ||
|
|
c9ce02c43d | ||
|
|
03c9782d63 | ||
|
|
130e9451f4 | ||
|
|
dce6a3e9e1 | ||
|
|
486044d29b | ||
|
|
934b0f0044 | ||
|
|
2633cd6bfe | ||
|
|
2c81d0df03 | ||
|
|
9ef59e359b | ||
|
|
6561f6f5e7 | ||
|
|
b2e8e628fa | ||
|
|
bbb8d85971 | ||
|
|
14b94ebe12 | ||
|
|
f5f59d90d4 | ||
|
|
ac3f4ca369 | ||
|
|
10133e6040 | ||
|
|
321fb26df3 | ||
|
|
28bd018d1f | ||
|
|
cceb29313b | ||
|
|
530bfa982e | ||
|
|
3cfa636e88 | ||
|
|
a2e8f098cf | ||
|
|
9e42cfd7d7 | ||
|
|
a3c54d4d20 | ||
|
|
1d48e2afb3 | ||
|
|
d84c9dc1a9 | ||
|
|
6165bf5a6c | ||
|
|
712d3ea78f | ||
|
|
96e3c95c29 | ||
|
|
e6e25b979f | ||
|
|
50fd0f6b1a | ||
|
|
0e9b83a1ce | ||
|
|
d2f629e7bb | ||
|
|
e290f68b29 | ||
|
|
a17e62b491 | ||
|
|
928db1f0f6 | ||
|
|
c317092dc5 | ||
|
|
95512d4851 | ||
|
|
62ed5a9f2b | ||
|
|
37ba0b63e4 | ||
|
|
22a5bd9b9d | ||
|
|
45529958ef | ||
|
|
7aa64f47c8 | ||
|
|
919adf331a | ||
|
|
9f229e3cc2 | ||
|
|
3277fe81a1 | ||
|
|
6c6ec3663a | ||
|
|
0461580d1c | ||
|
|
75dbb58c85 | ||
|
|
808f69cac1 | ||
|
|
974953a376 | ||
|
|
f85a367e98 | ||
|
|
87a3c58d93 | ||
|
|
1d1aea77d0 | ||
|
|
2a02935cee | ||
|
|
fd2e5c0fc7 | ||
|
|
6d6b07bf87 | ||
|
|
2cac3cd0bb | ||
|
|
d56098dbf0 | ||
|
|
07682c97a7 | ||
|
|
331a9152aa | ||
|
|
e87a06a713 | ||
|
|
3b5393dca6 | ||
|
|
101c5e52b1 | ||
|
|
5d3bcf4008 | ||
|
|
dd7605ac3a | ||
|
|
47dfbb6157 | ||
|
|
013123c1a7 | ||
|
|
cbc463cd10 | ||
|
|
6e9a8704b4 | ||
|
|
0fd2f34ed0 | ||
|
|
72f1ab18cc | ||
|
|
b1bba9da5d | ||
|
|
8966faeb7e | ||
|
|
fed4413259 | ||
|
|
14dddb4866 | ||
|
|
d7d6082038 | ||
|
|
c96357377b | ||
|
|
2789d0f97c | ||
|
|
79cd1da9a4 | ||
|
|
759cf18c41 | ||
|
|
0a61852711 | ||
|
|
6f5e144a93 | ||
|
|
391b33beae | ||
|
|
08e1a05bc9 | ||
|
|
f145aaa1e2 | ||
|
|
245ba9c6b3 | ||
|
|
66f4055b8f | ||
|
|
5170b9f329 | ||
|
|
3a2b20eb43 | ||
|
|
dd0ed8ea76 | ||
|
|
600aa10453 | ||
|
|
f6b87ed0b4 | ||
|
|
b300db77ff | ||
|
|
3f5800da3b | ||
|
|
c5612d50fe | ||
|
|
30bdfc4755 | ||
|
|
8fd24491da | ||
|
|
61deb2517c | ||
|
|
faa58f0fe4 | ||
|
|
d2bb985016 | ||
|
|
d190cd3a08 | ||
|
|
c8853cda58 | ||
|
|
e2d75f4c2e | ||
|
|
b56fa851e0 | ||
|
|
a82ba6d4aa | ||
|
|
359f8b41fe | ||
|
|
22e1403f43 | ||
|
|
9d60ebd19e | ||
|
|
87a27da2b9 | ||
|
|
f8c6a3c960 | ||
|
|
f4c747c6af | ||
|
|
7152cf656b | ||
|
|
c855df8b8d | ||
|
|
d710925cc7 | ||
|
|
f24f912693 | ||
|
|
8f9772e493 | ||
|
|
3c298a67ff | ||
|
|
27504a4dae | ||
|
|
9c64a69b8c | ||
|
|
6c354357ff | ||
|
|
19bbe6e860 | ||
|
|
62adaa7527 | ||
|
|
9a25fb584c | ||
|
|
475f937421 | ||
|
|
227968ef8e | ||
|
|
8e02dedf9f | ||
|
|
5a49041a3b | ||
|
|
ea341a556d | ||
|
|
7affd20092 | ||
|
|
9d9960ded2 | ||
|
|
62a055ef1f | ||
|
|
993607ef4b | ||
|
|
18765b3ac2 | ||
|
|
ea8e195183 | ||
|
|
f54c212b67 | ||
|
|
14d11b1c70 | ||
|
|
7f5f0f6b8e | ||
|
|
318b22448c | ||
|
|
610b3f7dc8 | ||
|
|
7a887d219f | ||
|
|
e74e4ba532 | ||
|
|
d5f753d110 | ||
|
|
c53ca6c16e | ||
|
|
5981d313ae | ||
|
|
cba3d24df1 | ||
|
|
27beab2980 | ||
|
|
aeb4b8ed25 | ||
|
|
edddc935df | ||
|
|
5c1b478085 | ||
|
|
39de9d56db | ||
|
|
94dbd9d6ad | ||
|
|
7c23dd06f8 | ||
|
|
e813edae01 | ||
|
|
4218d5bd48 | ||
|
|
aaf7aa8386 | ||
|
|
fbe84a7c62 | ||
|
|
cbd213aad3 | ||
|
|
13622f6b62 | ||
|
|
8fe6de376d | ||
|
|
808ba719f4 | ||
|
|
117844b5ee | ||
|
|
fbb73d465c | ||
|
|
a5c3bbb97e | ||
|
|
674150dc75 | ||
|
|
ad938b2ce2 | ||
|
|
5b1ace8607 | ||
|
|
74321277ff | ||
|
|
c60362f6e1 | ||
|
|
c1320e4184 | ||
|
|
a7ea2cf3ef | ||
|
|
f86a0ac973 | ||
|
|
bcc21b1c04 | ||
|
|
d517dea27f | ||
|
|
7df168f232 | ||
|
|
563340edbd | ||
|
|
28d70cf9c4 | ||
|
|
25d0675532 | ||
|
|
c8ffad2831 | ||
|
|
8233058d2e | ||
|
|
f7e00aab78 | ||
|
|
a111f3ff10 | ||
|
|
29e2b81092 | ||
|
|
0dda3e0e93 | ||
|
|
f07c7411fa | ||
|
|
b4d037fa18 | ||
|
|
e46bbcf8cf | ||
|
|
0c2ab729bc | ||
|
|
81ef967d9f | ||
|
|
2d733795c7 | ||
|
|
7ce85fe5f2 | ||
|
|
e3e30cafdd | ||
|
|
e51ac7de36 | ||
|
|
ee71c79125 | ||
|
|
bce2dec1cd | ||
|
|
3f2d0ef520 | ||
|
|
bbb3ad9333 | ||
|
|
b7e62df371 | ||
|
|
7b3405ca25 | ||
|
|
9984b53070 | ||
|
|
5e1aef1953 | ||
|
|
4c13a3a779 | ||
|
|
100719ac1f | ||
|
|
a13f581a65 | ||
|
|
f319ee66ad | ||
|
|
6f249c7b72 | ||
|
|
09e20934d7 | ||
|
|
5b22506b9b | ||
|
|
13a913428e | ||
|
|
5667f1b118 | ||
|
|
fcb8e4ca64 | ||
|
|
c5e8b217e3 | ||
|
|
f98b6b0e2a | ||
|
|
f01d8174e8 | ||
|
|
ccf790a630 | ||
|
|
efe80a534c | ||
|
|
1aac01ead0 | ||
|
|
216c43eea6 | ||
|
|
5b2a8cdacb | ||
|
|
d2da4f7e52 | ||
|
|
186019da7f | ||
|
|
7d1772cb54 | ||
|
|
cd30c47951 | ||
|
|
4b11147b83 | ||
|
|
6d7a5f07f0 | ||
|
|
26f0605d72 | ||
|
|
4959053ce0 | ||
|
|
10c9b2addd | ||
|
|
3092b59622 | ||
|
|
8b086e0e49 | ||
|
|
981c3595a8 | ||
|
|
5414fa17cf | ||
|
|
807b017463 | ||
|
|
96b674114c | ||
|
|
456086fb3c | ||
|
|
341b9a7449 | ||
|
|
6c7cedc1f1 | ||
|
|
01155c3466 | ||
|
|
c297ebda5a | ||
|
|
cec7492c10 | ||
|
|
4252445eb4 | ||
|
|
a23f241fff | ||
|
|
d145e6494d | ||
|
|
2563d52ecf | ||
|
|
8632aef268 | ||
|
|
f827a292ff | ||
|
|
a027c630b1 | ||
|
|
ab1a49abee | ||
|
|
bc5cf0e326 | ||
|
|
348535ec6c | ||
|
|
273f994cdf | ||
|
|
c0a3f7e05d | ||
|
|
1bc9bab988 | ||
|
|
dc730fd97b | ||
|
|
6c15115530 | ||
|
|
841b268fc7 | ||
|
|
6c8db9dec7 | ||
|
|
51d2f52d19 | ||
|
|
ff45f9ab63 | ||
|
|
507027df0a | ||
|
|
50d45c6da9 | ||
|
|
f5e9356451 | ||
|
|
dfe46cc011 | ||
|
|
34cdbc5620 | ||
|
|
595c057964 | ||
|
|
73bc9e516e | ||
|
|
6a4cfb231d | ||
|
|
4523db85c3 | ||
|
|
d703709f14 | ||
|
|
e8afba7ed2 | ||
|
|
dd5bb3edff | ||
|
|
475b05052e | ||
|
|
4cc012b974 |
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-clickhouse</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,14 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-clickhouse</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.11.4</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-cockroach</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,14 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.11.4</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-db2</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,14 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-db2</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.11.4</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-h2</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,14 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-h2</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.11.4</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-hana</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,14 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-hana</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.11.4</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-mariadb</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,14 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-mariadb</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.11.4</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-mysql</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,14 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-mysql</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.11.4</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-nuodb</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,14 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-nuodb</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.11.4</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-oracle</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,14 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-oracle</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.11.4</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-postgres</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,14 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.11.4</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-sqlite</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,14 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-sqlite</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.11.4</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-sqlserver</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,14 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-sqlserver</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.11.4</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-yugabyte</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,14 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.11.4</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean (all platforms)</name>
|
||||
@@ -16,13 +16,31 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-joda-time</artifactId>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-jackson-jsonnode</artifactId>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-jackson-mapper</artifactId>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,14 +53,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-all</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.11.4</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>composites</artifactId>
|
||||
|
||||
+22
-18
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean api</name>
|
||||
@@ -13,27 +13,23 @@
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!--
|
||||
Projects are expected to explicit depend on version
|
||||
of slf4j that they want to use
|
||||
-->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.36</version>
|
||||
<scope>provided</scope>
|
||||
<groupId>io.avaje</groupId>
|
||||
<artifactId>avaje-applog</artifactId>
|
||||
<version>1.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- exclude avaje-applog-slf4j to direct logging to something else -->
|
||||
<dependency>
|
||||
<groupId>io.avaje</groupId>
|
||||
<artifactId>avaje-applog-slf4j</artifactId>
|
||||
<version>1.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.avaje</groupId>
|
||||
<artifactId>avaje-config</artifactId>
|
||||
<version>2.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.avaje</groupId>
|
||||
<artifactId>avaje-applog-slf4j</artifactId>
|
||||
<version>1.0</version>
|
||||
<version>2.4</version>
|
||||
</dependency>
|
||||
|
||||
<!--
|
||||
@@ -49,7 +45,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>persistence-api</artifactId>
|
||||
<version>3.0</version>
|
||||
<version>${ebean-persistence-api.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -61,7 +57,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-types</artifactId>
|
||||
<version>3.0</version>
|
||||
<version>${ebean-types.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -70,6 +66,14 @@
|
||||
<version>${ebean-datasource.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Support MdcBackgroundExecutorWrapper -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.36</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- Jackson core used internally by Ebean -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
|
||||
@@ -5,7 +5,6 @@ import io.avaje.lang.Nullable;
|
||||
import io.ebean.annotation.TxIsolation;
|
||||
import io.ebean.cache.ServerCacheManager;
|
||||
import io.ebean.plugin.Property;
|
||||
import io.ebean.text.csv.CsvReader;
|
||||
import io.ebean.text.json.JsonContext;
|
||||
|
||||
import javax.persistence.OptimisticLockException;
|
||||
@@ -785,12 +784,6 @@ public final class DB {
|
||||
return getDefault().createUpdate(beanType, ormUpdate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a CsvReader for a given beanType.
|
||||
*/
|
||||
public static <T> CsvReader<T> createCsvReader(Class<T> beanType) {
|
||||
return getDefault().createCsvReader(beanType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a named query.
|
||||
|
||||
@@ -9,7 +9,6 @@ import io.ebean.config.DatabaseConfig;
|
||||
import io.ebean.meta.MetaInfoManager;
|
||||
import io.ebean.plugin.Property;
|
||||
import io.ebean.plugin.SpiServer;
|
||||
import io.ebean.text.csv.CsvReader;
|
||||
import io.ebean.text.json.JsonContext;
|
||||
|
||||
import javax.persistence.OptimisticLockException;
|
||||
@@ -204,10 +203,6 @@ public interface Database {
|
||||
*/
|
||||
<T> T createEntityBean(Class<T> type);
|
||||
|
||||
/**
|
||||
* Create a CsvReader for a given beanType.
|
||||
*/
|
||||
<T> CsvReader<T> createCsvReader(Class<T> beanType);
|
||||
|
||||
/**
|
||||
* Create an Update query to perform a bulk update.
|
||||
|
||||
@@ -2,20 +2,20 @@ package io.ebean;
|
||||
|
||||
import io.ebean.config.BeanNotEnhancedException;
|
||||
import io.ebean.datasource.DataSourceConfigurationException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import static java.lang.System.Logger.Level.ERROR;
|
||||
|
||||
/**
|
||||
* Holds Database instances.
|
||||
*/
|
||||
final class DbContext {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger("io.ebean");
|
||||
private static final System.Logger log = EbeanVersion.log;
|
||||
static {
|
||||
EbeanVersion.getVersion();
|
||||
}
|
||||
@@ -23,14 +23,9 @@ final class DbContext {
|
||||
private static final DbContext INSTANCE = new DbContext();
|
||||
|
||||
private final ConcurrentHashMap<String, Database> concMap = new ConcurrentHashMap<>();
|
||||
|
||||
private final HashMap<String, Database> syncMap = new HashMap<>();
|
||||
|
||||
private final ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
/**
|
||||
* The 'default' Database.
|
||||
*/
|
||||
private Database defaultDatabase;
|
||||
|
||||
private DbContext() {
|
||||
@@ -52,7 +47,7 @@ final class DbContext {
|
||||
throw new DataSourceConfigurationException(msg, e);
|
||||
|
||||
} catch (Throwable e) {
|
||||
log.error("Error trying to create the default Database", e);
|
||||
log.log(ERROR, "Error trying to create the default Database", e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
@@ -69,9 +64,9 @@ final class DbContext {
|
||||
*/
|
||||
Database getDefault() {
|
||||
if (defaultDatabase == null) {
|
||||
String msg = "The default Database has not been defined?";
|
||||
msg += " This is normally set via the ebean.datasource.default property.";
|
||||
msg += " Otherwise it should be registered programmatically via registerServer()";
|
||||
String msg = "The default Database has not been defined?"
|
||||
+ " This is normally set via the ebean.datasource.default property."
|
||||
+ " Otherwise it should be registered programmatically via registerServer()";
|
||||
throw new PersistenceException(msg);
|
||||
}
|
||||
return defaultDatabase;
|
||||
|
||||
@@ -129,6 +129,11 @@ public interface DtoQuery<T> extends CancelableQuery {
|
||||
*/
|
||||
DtoQuery<T> setParameter(String name, Object value);
|
||||
|
||||
/**
|
||||
* Bind the named parameter to SQL NULL.
|
||||
*/
|
||||
DtoQuery<T> setNullParameter(String name, int jdbcType);
|
||||
|
||||
/**
|
||||
* Bind the named multi-value array parameter which we would use with Postgres ANY.
|
||||
* <p>
|
||||
@@ -141,6 +146,11 @@ public interface DtoQuery<T> extends CancelableQuery {
|
||||
*/
|
||||
DtoQuery<T> setParameter(int position, Object value);
|
||||
|
||||
/**
|
||||
* Set a positioned parameter to SQL NULL.
|
||||
*/
|
||||
DtoQuery<T> setNullParameter(int position, int jdbcType);
|
||||
|
||||
/**
|
||||
* Set the index of the first row of the results to return.
|
||||
*/
|
||||
|
||||
@@ -2,6 +2,28 @@ package io.ebean;
|
||||
|
||||
/**
|
||||
* Thrown when a duplicate is attempted on a unique constraint.
|
||||
* <p>
|
||||
* In terms of catching this exception with the view of continuing processing
|
||||
* using the same transaction look to use {@link Transaction#rollbackAndContinue()}.
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* try (Transaction txn = database.beginTransaction()) {
|
||||
*
|
||||
* try {
|
||||
* ...
|
||||
* database.save(bean);
|
||||
* database.flush();
|
||||
* } catch (DuplicateKeyException e) {
|
||||
* // carry on processing using the transaction
|
||||
* txn.rollbackAndContinue();
|
||||
* ...
|
||||
* }
|
||||
*
|
||||
* txn.commit();
|
||||
* }
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
public class DuplicateKeyException extends DataIntegrityException {
|
||||
private static final long serialVersionUID = -4771932723285724817L;
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
package io.ebean;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import io.avaje.applog.AppLog;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.LineNumberReader;
|
||||
import java.util.Properties;
|
||||
|
||||
import static java.lang.System.Logger.Level.*;
|
||||
|
||||
/**
|
||||
* Class to determine the ebean version.
|
||||
*
|
||||
@@ -13,7 +17,7 @@ import java.util.Properties;
|
||||
*/
|
||||
public final class EbeanVersion {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger("io.ebean");
|
||||
public static final System.Logger log = AppLog.getLogger("io.ebean");
|
||||
|
||||
/**
|
||||
* Maintain the minimum ebean-agent version manually based on required ebean-agent bug fixes.
|
||||
@@ -21,6 +25,7 @@ public final class EbeanVersion {
|
||||
private static final int MIN_AGENT_MAJOR_VERSION = 12;
|
||||
private static final int MIN_AGENT_MINOR_VERSION = 12;
|
||||
private static String version = "unknown";
|
||||
|
||||
static {
|
||||
readVersion();
|
||||
checkAgentVersion();
|
||||
@@ -32,12 +37,12 @@ public final class EbeanVersion {
|
||||
if (in != null) {
|
||||
try (LineNumberReader reader = new LineNumberReader(new InputStreamReader(in))) {
|
||||
version = reader.readLine();
|
||||
log.log(INFO, "ebean version: {0}", version);
|
||||
}
|
||||
}
|
||||
}
|
||||
log.info("ebean version: {}", version);
|
||||
} catch (IOException e) {
|
||||
log.warn("Could not determine ebean version: {}", e.getMessage());
|
||||
log.log(WARNING, "Could not determine ebean version: {0}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,13 +54,13 @@ public final class EbeanVersion {
|
||||
String agentVersion = readVersion(in);
|
||||
if (agentVersion != null) {
|
||||
if (checkMinAgentVersion(agentVersion)) {
|
||||
log.error("Expected minimum ebean-agent version {}.{}.0 but we have {}, please update the ebean-agent", MIN_AGENT_MAJOR_VERSION, MIN_AGENT_MINOR_VERSION, agentVersion);
|
||||
log.log(ERROR, "Expected minimum ebean-agent version {0}.{1}.0 but we have {2}, please update the ebean-agent", MIN_AGENT_MAJOR_VERSION, MIN_AGENT_MINOR_VERSION, agentVersion);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.warn("Could not check minimum ebean-agent version {}.{}.0 required due to - {}", MIN_AGENT_MAJOR_VERSION, MIN_AGENT_MINOR_VERSION, e.getMessage());
|
||||
log.log(WARNING, "Could not check minimum ebean-agent version {0}.{1}.0 required due to - {2}", MIN_AGENT_MAJOR_VERSION, MIN_AGENT_MINOR_VERSION, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -117,6 +117,11 @@ public interface ExpressionFactory {
|
||||
*/
|
||||
Expression arrayIsNotEmpty(String propertyName);
|
||||
|
||||
/**
|
||||
* Equal To the result of a sub-query.
|
||||
*/
|
||||
Expression eq(String propertyName, Query<?> subQuery);
|
||||
|
||||
/**
|
||||
* Equal To - property equal to the given value.
|
||||
*/
|
||||
@@ -127,6 +132,11 @@ public interface ExpressionFactory {
|
||||
*/
|
||||
Expression eqOrNull(String propertyName, Object value);
|
||||
|
||||
/**
|
||||
* Not Equal To the result of a sub-query.
|
||||
*/
|
||||
Expression ne(String propertyName, Query<?> subQuery);
|
||||
|
||||
/**
|
||||
* Not Equal To - property not equal to the given value.
|
||||
*/
|
||||
@@ -181,6 +191,23 @@ public interface ExpressionFactory {
|
||||
*/
|
||||
Expression inRangeWith(String lowProperty, String highProperty, Object value);
|
||||
|
||||
/**
|
||||
* A Property is in Range between 2 properties.
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* .orderDate.inRangeWith(QOrder.Alias.product.startDate, QOrder.Alias.product.endDate)
|
||||
*
|
||||
* // which equates to
|
||||
* product.startDate <= orderDate and (orderDate < product.endDate or product.endDate is null)
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* This is a convenience expression combining a number of simple expressions.
|
||||
*/
|
||||
Expression inRangeWithProperties(String propertyName, String lowProperty, String highProperty);
|
||||
|
||||
/**
|
||||
* Between - property between the two given values.
|
||||
*/
|
||||
@@ -207,11 +234,21 @@ public interface ExpressionFactory {
|
||||
*/
|
||||
Expression geOrNull(String propertyName, Object value);
|
||||
|
||||
/**
|
||||
* Greater Than the result of a sub-query.
|
||||
*/
|
||||
Expression gt(String propertyName, Query<?> subQuery);
|
||||
|
||||
/**
|
||||
* Greater Than - property greater than the given value.
|
||||
*/
|
||||
Expression gt(String propertyName, Object value);
|
||||
|
||||
/**
|
||||
* Greater Than or Equal to the result of a sub-query.
|
||||
*/
|
||||
Expression ge(String propertyName, Query<?> subQuery);
|
||||
|
||||
/**
|
||||
* Greater Than or Equal to - property greater than or equal to the given
|
||||
* value.
|
||||
@@ -234,11 +271,21 @@ public interface ExpressionFactory {
|
||||
*/
|
||||
Expression leOrNull(String propertyName, Object value);
|
||||
|
||||
/**
|
||||
* Less Than the result of a sub-query.
|
||||
*/
|
||||
Expression lt(String propertyName, Query<?> subQuery);
|
||||
|
||||
/**
|
||||
* Less Than - property less than the given value.
|
||||
*/
|
||||
Expression lt(String propertyName, Object value);
|
||||
|
||||
/**
|
||||
* Less Than or Equal to the result of a sub-query.
|
||||
*/
|
||||
Expression le(String propertyName, Query<?> subQuery);
|
||||
|
||||
/**
|
||||
* Less Than or Equal to - property less than or equal to the given value.
|
||||
*/
|
||||
|
||||
@@ -830,6 +830,11 @@ public interface ExpressionList<T> {
|
||||
*/
|
||||
ExpressionList<T> addAll(ExpressionList<T> exprList);
|
||||
|
||||
/**
|
||||
* Equal To the result of a sub-query.
|
||||
*/
|
||||
ExpressionList<T> eq(String propertyName, Query<?> subQuery);
|
||||
|
||||
/**
|
||||
* Equal To - property is equal to a given value.
|
||||
*/
|
||||
@@ -854,6 +859,11 @@ public interface ExpressionList<T> {
|
||||
*/
|
||||
ExpressionList<T> eqOrNull(String propertyName, Object value);
|
||||
|
||||
/**
|
||||
* Not Equal To the result of a sub-query.
|
||||
*/
|
||||
ExpressionList<T> ne(String propertyName, Query<?> subQuery);
|
||||
|
||||
/**
|
||||
* Not Equal To - property not equal to the given value.
|
||||
*/
|
||||
@@ -890,6 +900,23 @@ public interface ExpressionList<T> {
|
||||
*/
|
||||
ExpressionList<T> inRangeWith(String lowProperty, String highProperty, Object value);
|
||||
|
||||
/**
|
||||
* A Property is in Range between 2 properties.
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* .orderDate.inRangeWith(QOrder.Alias.product.startDate, QOrder.Alias.product.endDate)
|
||||
*
|
||||
* // which equates to
|
||||
* product.startDate <= orderDate and (orderDate < product.endDate or product.endDate is null)
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* This is a convenience expression combining a number of simple expressions.
|
||||
*/
|
||||
ExpressionList<T> inRangeWithProperties(String propertyName, String lowProperty, String highProperty);
|
||||
|
||||
/**
|
||||
* In Range - {@code property >= value1 and property < value2}.
|
||||
* <p>
|
||||
@@ -908,6 +935,11 @@ public interface ExpressionList<T> {
|
||||
*/
|
||||
ExpressionList<T> betweenProperties(String lowProperty, String highProperty, Object value);
|
||||
|
||||
/**
|
||||
* Greater Than the result of a sub-query.
|
||||
*/
|
||||
ExpressionList<T> gt(String propertyName, Query<?> subQuery);
|
||||
|
||||
/**
|
||||
* Greater Than - property greater than the given value.
|
||||
*/
|
||||
@@ -923,12 +955,22 @@ public interface ExpressionList<T> {
|
||||
*/
|
||||
ExpressionList<T> geOrNull(String propertyName, Object value);
|
||||
|
||||
/**
|
||||
* Greater Than or Equal to the result of a sub-query.
|
||||
*/
|
||||
ExpressionList<T> ge(String propertyName, Query<?> subQuery);
|
||||
|
||||
/**
|
||||
* Greater Than or Equal to - property greater than or equal to the given
|
||||
* value.
|
||||
*/
|
||||
ExpressionList<T> ge(String propertyName, Object value);
|
||||
|
||||
/**
|
||||
* Less Than the result of a sub-query.
|
||||
*/
|
||||
ExpressionList<T> lt(String propertyName, Query<?> subQuery);
|
||||
|
||||
/**
|
||||
* Less Than - property less than the given value.
|
||||
*/
|
||||
@@ -944,6 +986,11 @@ public interface ExpressionList<T> {
|
||||
*/
|
||||
ExpressionList<T> leOrNull(String propertyName, Object value);
|
||||
|
||||
/**
|
||||
* Less Than or Equal to the result of a sub-query.
|
||||
*/
|
||||
ExpressionList<T> le(String propertyName, Query<?> subQuery);
|
||||
|
||||
/**
|
||||
* Less Than or Equal to - property less than or equal to the given value.
|
||||
*/
|
||||
@@ -1683,4 +1730,8 @@ public interface ExpressionList<T> {
|
||||
*/
|
||||
ExpressionList<T> endNot();
|
||||
|
||||
/**
|
||||
* Clears the current expression list.
|
||||
*/
|
||||
ExpressionList<T> clear();
|
||||
}
|
||||
|
||||
@@ -231,18 +231,6 @@ public class OrderBy<T> implements Serializable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this order by can be used in select clause.
|
||||
*/
|
||||
public boolean supportsSelect() {
|
||||
for (Property property : list) {
|
||||
if (!property.supportsSelect()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* A property and its ascending descending order.
|
||||
*/
|
||||
@@ -403,12 +391,6 @@ public class OrderBy<T> implements Serializable {
|
||||
this.ascending = ascending;
|
||||
}
|
||||
|
||||
/**
|
||||
* Support use in select clause if no collation or nulls ordering.
|
||||
*/
|
||||
boolean supportsSelect() {
|
||||
return nulls == null;
|
||||
}
|
||||
}
|
||||
|
||||
private void parse(String orderByClause) {
|
||||
|
||||
@@ -931,7 +931,7 @@ public interface Query<T> extends CancelableQuery {
|
||||
<A> Set<A> findSingleAttributeSet();
|
||||
|
||||
/**
|
||||
* Execute a query returning a single value of a single property/column.
|
||||
* Execute a query returning a single value or null for a single property/column.
|
||||
* <p>
|
||||
* <pre>{@code
|
||||
*
|
||||
@@ -943,6 +943,7 @@ public interface Query<T> extends CancelableQuery {
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
@Nullable
|
||||
<A> A findSingleAttribute();
|
||||
|
||||
/**
|
||||
|
||||
@@ -144,6 +144,35 @@ public interface Transaction extends AutoCloseable {
|
||||
*/
|
||||
void rollback(Throwable e) throws PersistenceException;
|
||||
|
||||
/**
|
||||
* Performs a rollback on the underlying JDBC connection with the intention of
|
||||
* continuing to use this same transaction and performing a commit or rollback
|
||||
* later to complete the transaction.
|
||||
* <p>
|
||||
* Typically used when catching {@link DuplicateKeyException} where we wish to
|
||||
* rollback work done at that point but carry on processing using the transaction.
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* try (Transaction txn = database.beginTransaction()) {
|
||||
*
|
||||
* try {
|
||||
* ...
|
||||
* database.save(bean);
|
||||
* database.flush();
|
||||
* } catch (DuplicateKeyException e) {
|
||||
* // carry on processing using the transaction
|
||||
* txn.rollbackAndContinue();
|
||||
* ...
|
||||
* }
|
||||
*
|
||||
* txn.commit();
|
||||
* }
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
void rollbackAndContinue();
|
||||
|
||||
/**
|
||||
* Set when we want nested transactions to use Savepoint's.
|
||||
* <p>
|
||||
|
||||
@@ -725,7 +725,7 @@ public final class InterceptReadWrite implements EntityBeanIntercept {
|
||||
loader.loadBean(this);
|
||||
if (lazyLoadFailure) {
|
||||
// failed when lazy loading this bean
|
||||
throw new EntityNotFoundException("Lazy loading failed on type:" + owner.getClass().getName() + " id:" + ownerId + " - Bean has been deleted.");
|
||||
throw new EntityNotFoundException("Lazy loading failed on type:" + owner.getClass().getName() + " id:" + ownerId + " - Bean has been deleted. BeanLoader: " + beanLoader);
|
||||
}
|
||||
// bean should be loaded and intercepting now. setLoaded() has
|
||||
// been called by the lazy loading mechanism
|
||||
|
||||
@@ -6,7 +6,6 @@ import java.util.Set;
|
||||
* Notification event that dependent tables have been modified.
|
||||
* <p>
|
||||
* This is sent to other interested servers (in the cluster).
|
||||
* </p>
|
||||
*/
|
||||
public class ServerCacheNotification {
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ import io.ebean.config.DatabaseConfig;
|
||||
* Plugin that provides a ServerCacheNotify implementation.
|
||||
* <p>
|
||||
* Is supplied this will be used to send the ServerCacheNotification event to other cluster members.
|
||||
* </p>
|
||||
*/
|
||||
public interface ServerCacheNotifyPlugin {
|
||||
|
||||
|
||||
@@ -237,7 +237,7 @@ public abstract class AbstractNamingConvention implements NamingConvention {
|
||||
}
|
||||
buffer.append(rhsTableName);
|
||||
|
||||
int maxTableNameLength = databasePlatform.getMaxTableNameLength();
|
||||
int maxTableNameLength = databasePlatform.maxTableNameLength();
|
||||
|
||||
// maxConstraintNameLength is used as the max table name length.
|
||||
if (buffer.length() > maxTableNameLength) {
|
||||
|
||||
@@ -6,6 +6,10 @@ import java.util.concurrent.Callable;
|
||||
* BackgroundExecutorWrapper that can be used to wrap tasks that are sent to background (i.e. another thread).
|
||||
* It should copy all necessary thread-local variables. See {@link MdcBackgroundExecutorWrapper} for implementation details.
|
||||
*
|
||||
* Note: only tasks that are executed immediately (submit, execute) are wrapped. Periodic or scheduled tasks are not wrapped,
|
||||
* as these may keep copied variables in memory either forever or until the scheduled task is finished.
|
||||
* The caller is responsible to handle these cases.
|
||||
*
|
||||
* @author Roland Praml, FOCONIS AG
|
||||
*/
|
||||
public interface BackgroundExecutorWrapper {
|
||||
|
||||
@@ -32,13 +32,11 @@ import java.util.function.Function;
|
||||
* <p>
|
||||
* Used to programmatically construct an Database and optionally register it
|
||||
* with the DB singleton.
|
||||
* </p>
|
||||
* <p>
|
||||
* If you just use DB thout this programmatic configuration Ebean will read
|
||||
* the application.properties file and take the configuration from there. This usually
|
||||
* includes searching the class path and automatically registering any entity
|
||||
* classes and listeners etc.
|
||||
* </p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* DatabaseConfig config = new DatabaseConfig();
|
||||
@@ -58,7 +56,6 @@ import java.util.function.Function;
|
||||
* <p>
|
||||
* Note that DatabaseConfigProvider provides a standard Java ServiceLoader mechanism that can
|
||||
* be used to apply configuration to the DatabaseConfig.
|
||||
* </p>
|
||||
*
|
||||
* @author emcgreal
|
||||
* @author rbygrave
|
||||
@@ -615,7 +612,7 @@ public class DatabaseConfig {
|
||||
}
|
||||
|
||||
/**
|
||||
* Put a service object into configuration such that it can be passed to a plugin.
|
||||
* Put a service object into configuration such that it can be used by ebean or a plugin.
|
||||
* <p>
|
||||
* For example, put IgniteConfiguration in to be passed to the Ignite plugin.
|
||||
*/
|
||||
@@ -623,6 +620,23 @@ public class DatabaseConfig {
|
||||
serviceObject.put(key, configObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Put a service object into configuration such that it can be used by ebean or a plugin.
|
||||
* <p>
|
||||
* For example, put IgniteConfiguration in to be passed to the Ignite plugin.
|
||||
* You can also override some SPI objects that should be used for that Database. Currently, the following
|
||||
* objects are possible.
|
||||
* <ul>
|
||||
* <li>DataSourceAlertFactory (e.g. add different alert factories for different ebean instances)</li>
|
||||
* <li>DocStoreFactory</li>
|
||||
* <li>SlowQueryListener (e.g. add custom query listener for a certain ebean instance)</li>
|
||||
* <li>ServerCacheNotifyPlugin</li>
|
||||
* </ul>
|
||||
*/
|
||||
public <T> void putServiceObject(Class<T> iface, T configObject) {
|
||||
serviceObject.put(serviceObjectKey(iface), configObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the service object given the key.
|
||||
*/
|
||||
@@ -631,7 +645,7 @@ public class DatabaseConfig {
|
||||
}
|
||||
|
||||
/**
|
||||
* Put a service object into configuration such that it can be passed to a plugin.
|
||||
* Put a service object into configuration such that it can be used by ebean or a plugin.
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
@@ -656,7 +670,7 @@ public class DatabaseConfig {
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by plugins to obtain service objects.
|
||||
* Used by ebean or plugins to obtain service objects.
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
@@ -3024,7 +3038,7 @@ public class DatabaseConfig {
|
||||
public PersistBatch appliedPersistBatchOnCascade() {
|
||||
if (persistBatchOnCascade == PersistBatch.INHERIT) {
|
||||
// use the platform default (ALL except SQL Server which has NONE)
|
||||
return databasePlatform.getPersistBatchOnCascade();
|
||||
return databasePlatform.persistBatchOnCascade();
|
||||
}
|
||||
return persistBatchOnCascade;
|
||||
}
|
||||
|
||||
+5
-10
@@ -1,20 +1,16 @@
|
||||
package io.ebean.platform.db2;
|
||||
package io.ebean.config.dbplatform;
|
||||
|
||||
import io.ebean.config.dbplatform.SqlLimitRequest;
|
||||
import io.ebean.config.dbplatform.SqlLimitResponse;
|
||||
import io.ebean.config.dbplatform.SqlLimiter;
|
||||
|
||||
public class Db2SqlLimiter implements SqlLimiter {
|
||||
public final class AnsiSqlRowsLimiter implements SqlLimiter {
|
||||
|
||||
@Override
|
||||
public SqlLimitResponse limit(SqlLimitRequest request) {
|
||||
|
||||
StringBuilder sb = new StringBuilder(512);
|
||||
String dbSql = request.getDbSql();
|
||||
StringBuilder sb = new StringBuilder(50 + dbSql.length());
|
||||
sb.append("select ");
|
||||
if (request.isDistinct()) {
|
||||
sb.append("distinct ");
|
||||
}
|
||||
sb.append(request.getDbSql());
|
||||
sb.append(dbSql);
|
||||
int firstRow = request.getFirstRow();
|
||||
if (firstRow > 0) {
|
||||
sb.append(" offset ").append(firstRow).append(" rows");
|
||||
@@ -23,7 +19,6 @@ public class Db2SqlLimiter implements SqlLimiter {
|
||||
if (maxRows > 0) {
|
||||
sb.append(" fetch next ").append(maxRows).append(" rows only");
|
||||
}
|
||||
|
||||
String sql = request.getDbPlatform().completeSql(sb.toString(), request.getOrmQuery());
|
||||
return new SqlLimitResponse(sql);
|
||||
}
|
||||
@@ -1,49 +1,26 @@
|
||||
package io.ebean.config.dbplatform;
|
||||
|
||||
import io.ebean.BackgroundExecutor;
|
||||
import io.ebean.EbeanVersion;
|
||||
import io.ebean.Query;
|
||||
import io.ebean.annotation.PartitionMode;
|
||||
import io.ebean.annotation.PersistBatch;
|
||||
import io.ebean.annotation.Platform;
|
||||
import io.ebean.config.CustomDbTypeMapping;
|
||||
import io.ebean.config.PlatformConfig;
|
||||
import io.ebean.util.JdbcClose;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.sql.Types;
|
||||
import java.sql.*;
|
||||
|
||||
import static java.lang.System.Logger.Level.*;
|
||||
|
||||
/**
|
||||
* Database platform specific settings.
|
||||
*/
|
||||
public class DatabasePlatform {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger("io.ebean");
|
||||
|
||||
/**
|
||||
* Behavior used when ending a query only transaction (at read committed isolation level).
|
||||
*/
|
||||
public enum OnQueryOnly {
|
||||
|
||||
/**
|
||||
* Rollback the transaction.
|
||||
*/
|
||||
ROLLBACK,
|
||||
|
||||
/**
|
||||
* Commit the transaction
|
||||
*/
|
||||
COMMIT
|
||||
}
|
||||
|
||||
private static final System.Logger log = EbeanVersion.log;
|
||||
|
||||
/**
|
||||
* Set to true for MySql, no other jdbc drivers need this workaround.
|
||||
@@ -60,16 +37,11 @@ public class DatabasePlatform {
|
||||
* Can we use native java time API objects in
|
||||
* {@link ResultSet#getObject(int, Class)} and
|
||||
* {@link PreparedStatement#setObject(int, Object)}.
|
||||
*
|
||||
* <p>
|
||||
* Not all drivers (DB2 e.g.) will support this.
|
||||
*/
|
||||
protected boolean supportsNativeJavaTime = true;
|
||||
|
||||
/**
|
||||
* The behaviour used when ending a read only transaction at read committed isolation level.
|
||||
*/
|
||||
protected OnQueryOnly onQueryOnly = OnQueryOnly.COMMIT;
|
||||
|
||||
/**
|
||||
* The open quote used by quoted identifiers.
|
||||
*/
|
||||
@@ -146,11 +118,6 @@ public class DatabasePlatform {
|
||||
*/
|
||||
protected int clobDbType = Types.CLOB;
|
||||
|
||||
/**
|
||||
* For Oracle treat empty strings as null.
|
||||
*/
|
||||
protected boolean treatEmptyStringsAsNull;
|
||||
|
||||
/**
|
||||
* The database platform name.
|
||||
*/
|
||||
@@ -165,7 +132,7 @@ public class DatabasePlatform {
|
||||
* want to use quoted identifiers for. The backticks get converted to the
|
||||
* appropriate characters in convertQuotedIdentifiers
|
||||
*/
|
||||
private static final char[] QUOTED_IDENTIFIERS = new char[] { '"', '\'', '[', ']', '`' };
|
||||
private static final char[] QUOTED_IDENTIFIERS = new char[]{'"', '\'', '[', ']', '`'};
|
||||
|
||||
/**
|
||||
* The non-escaped like clause (to stop slash being escaped on some platforms).
|
||||
@@ -299,7 +266,7 @@ public class DatabasePlatform {
|
||||
/**
|
||||
* Return the platform key.
|
||||
*/
|
||||
public Platform getPlatform() {
|
||||
public Platform platform() {
|
||||
return platform;
|
||||
}
|
||||
|
||||
@@ -309,14 +276,14 @@ public class DatabasePlatform {
|
||||
* "generic" is returned when no specific database platform has been set or found.
|
||||
* </p>
|
||||
*/
|
||||
public String getName() {
|
||||
public String name() {
|
||||
return platform.name().toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if we are using Sequence batch mode rather than STEP.
|
||||
*/
|
||||
public boolean isSequenceBatchMode() {
|
||||
public boolean sequenceBatchMode() {
|
||||
return sequenceBatchMode;
|
||||
}
|
||||
|
||||
@@ -330,52 +297,52 @@ public class DatabasePlatform {
|
||||
/**
|
||||
* Return true if this database platform supports native ILIKE expression.
|
||||
*/
|
||||
public boolean isSupportsNativeIlike() {
|
||||
public boolean supportsNativeIlike() {
|
||||
return supportsNativeIlike;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the platform supports delete statements with table alias.
|
||||
*/
|
||||
public boolean isSupportsDeleteTableAlias() {
|
||||
public boolean supportsDeleteTableAlias() {
|
||||
return supportsDeleteTableAlias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the collation is case sensitive.
|
||||
* Return true if the collation is case-sensitive.
|
||||
* <p>
|
||||
* This is expected to be used for testing only.
|
||||
* </p>
|
||||
*/
|
||||
public boolean isCaseSensitiveCollation() {
|
||||
public boolean caseSensitiveCollation() {
|
||||
return caseSensitiveCollation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the platform supports SavepointId values.
|
||||
*/
|
||||
public boolean isSupportsSavepointId() {
|
||||
public boolean supportsSavepointId() {
|
||||
return supportsSavepointId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if migrations should use stored procedures.
|
||||
*/
|
||||
public boolean isUseMigrationStoredProcedures() {
|
||||
public boolean useMigrationStoredProcedures() {
|
||||
return useMigrationStoredProcedures;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the platform supports LIMIT with sql update.
|
||||
*/
|
||||
public boolean isInlineSqlUpdateLimit() {
|
||||
public boolean inlineSqlUpdateLimit() {
|
||||
return inlineSqlUpdateLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the maximum number of bind values this database platform allows or zero for no limit.
|
||||
*/
|
||||
public int getMaxInBinding() {
|
||||
public int maxInBinding() {
|
||||
return maxInBinding;
|
||||
}
|
||||
|
||||
@@ -385,14 +352,14 @@ public class DatabasePlatform {
|
||||
* This is used when deriving names of intersection tables.
|
||||
* </p>
|
||||
*/
|
||||
public int getMaxTableNameLength() {
|
||||
public int maxTableNameLength() {
|
||||
return maxTableNameLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the maximum constraint name allowed for the platform.
|
||||
*/
|
||||
public int getMaxConstraintNameLength() {
|
||||
public int maxConstraintNameLength() {
|
||||
return maxConstraintNameLength;
|
||||
}
|
||||
|
||||
@@ -420,24 +387,10 @@ public class DatabasePlatform {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the behaviour to use when ending a read only transaction.
|
||||
*/
|
||||
public OnQueryOnly getOnQueryOnly() {
|
||||
return onQueryOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the behaviour to use when ending a read only transaction.
|
||||
*/
|
||||
public void setOnQueryOnly(OnQueryOnly onQueryOnly) {
|
||||
this.onQueryOnly = onQueryOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the DbEncrypt handler for this DB platform.
|
||||
*/
|
||||
public DbEncrypt getDbEncrypt() {
|
||||
public DbEncrypt dbEncrypt() {
|
||||
return dbEncrypt;
|
||||
}
|
||||
|
||||
@@ -451,7 +404,7 @@ public class DatabasePlatform {
|
||||
/**
|
||||
* Return the history support for this database platform.
|
||||
*/
|
||||
public DbHistorySupport getHistorySupport() {
|
||||
public DbHistorySupport historySupport() {
|
||||
return historySupport;
|
||||
}
|
||||
|
||||
@@ -465,14 +418,14 @@ public class DatabasePlatform {
|
||||
/**
|
||||
* So no except for Postgres and CockroachDB.
|
||||
*/
|
||||
public boolean isNativeArrayType() {
|
||||
public boolean nativeArrayType() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the DB supports native UUID.
|
||||
*/
|
||||
public boolean isNativeUuidType() {
|
||||
public boolean nativeUuidType() {
|
||||
return nativeUuidType;
|
||||
}
|
||||
|
||||
@@ -481,21 +434,21 @@ public class DatabasePlatform {
|
||||
*
|
||||
* @return the db type map
|
||||
*/
|
||||
public DbPlatformTypeMapping getDbTypeMap() {
|
||||
public DbPlatformTypeMapping dbTypeMap() {
|
||||
return dbTypeMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the mapping for DB column default values.
|
||||
*/
|
||||
public DbDefaultValue getDbDefaultValue() {
|
||||
public DbDefaultValue dbDefaultValue() {
|
||||
return dbDefaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the column alias prefix.
|
||||
*/
|
||||
public String getColumnAliasPrefix() {
|
||||
public String columnAliasPrefix() {
|
||||
return columnAliasPrefix;
|
||||
}
|
||||
|
||||
@@ -509,21 +462,21 @@ public class DatabasePlatform {
|
||||
/**
|
||||
* Return the close quote for quoted identifiers.
|
||||
*/
|
||||
public String getCloseQuote() {
|
||||
public String closeQuote() {
|
||||
return closeQuote;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the open quote for quoted identifiers.
|
||||
*/
|
||||
public String getOpenQuote() {
|
||||
public String openQuote() {
|
||||
return openQuote;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the JDBC type used to store booleans.
|
||||
*/
|
||||
public int getBooleanDbType() {
|
||||
public int booleanDbType() {
|
||||
return booleanDbType;
|
||||
}
|
||||
|
||||
@@ -534,7 +487,7 @@ public class DatabasePlatform {
|
||||
* example.
|
||||
* </p>
|
||||
*/
|
||||
public int getBlobDbType() {
|
||||
public int blobDbType() {
|
||||
return blobDbType;
|
||||
}
|
||||
|
||||
@@ -544,25 +497,16 @@ public class DatabasePlatform {
|
||||
* This is typically Types.CLOB but for Postgres is Types.VARCHAR.
|
||||
* </p>
|
||||
*/
|
||||
public int getClobDbType() {
|
||||
public int clobDbType() {
|
||||
return clobDbType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if empty strings should be treated as null.
|
||||
*
|
||||
* @return true, if checks if is treat empty strings as null
|
||||
*/
|
||||
public boolean isTreatEmptyStringsAsNull() {
|
||||
return treatEmptyStringsAsNull;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if a compound ID in (...) type expression needs to be in
|
||||
* expanded form of (a=? and b=?) or (a=? and b=?) or ... rather than (a,b) in
|
||||
* ((?,?),(?,?),...);
|
||||
*/
|
||||
public boolean isIdInExpandedForm() {
|
||||
public boolean idInExpandedForm() {
|
||||
return idInExpandedForm;
|
||||
}
|
||||
|
||||
@@ -573,7 +517,7 @@ public class DatabasePlatform {
|
||||
* This specifically is required for MySql when processing large results.
|
||||
* </p>
|
||||
*/
|
||||
public boolean isForwardOnlyHintOnFindIterate() {
|
||||
public boolean forwardOnlyHintOnFindIterate() {
|
||||
return forwardOnlyHintOnFindIterate;
|
||||
}
|
||||
|
||||
@@ -591,7 +535,7 @@ public class DatabasePlatform {
|
||||
* This specifically is required for Hana which doesn't support CONCUR_UPDATABLE
|
||||
* </p>
|
||||
*/
|
||||
public boolean isSupportsResultSetConcurrencyModeUpdatable() {
|
||||
public boolean supportsResultSetConcurrencyModeUpdatable() {
|
||||
return supportsResultSetConcurrencyModeUpdatable;
|
||||
}
|
||||
|
||||
@@ -611,7 +555,7 @@ public class DatabasePlatform {
|
||||
*
|
||||
* @return the db identity
|
||||
*/
|
||||
public DbIdentity getDbIdentity() {
|
||||
public DbIdentity dbIdentity() {
|
||||
return dbIdentity;
|
||||
}
|
||||
|
||||
@@ -624,14 +568,14 @@ public class DatabasePlatform {
|
||||
*
|
||||
* @return the sql limiter
|
||||
*/
|
||||
public SqlLimiter getSqlLimiter() {
|
||||
public SqlLimiter sqlLimiter() {
|
||||
return sqlLimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the BasicSqlLimiter for limit/offset of SqlQuery queries.
|
||||
*/
|
||||
public BasicSqlLimiter getBasicSqlLimiter() {
|
||||
public BasicSqlLimiter basicSqlLimiter() {
|
||||
return basicSqlLimiter;
|
||||
}
|
||||
|
||||
@@ -666,7 +610,7 @@ public class DatabasePlatform {
|
||||
if (isQuote(dbName.charAt(dbName.length() - 1))) {
|
||||
return openQuote + dbName.substring(1, dbName.length() - 1) + closeQuote;
|
||||
} else {
|
||||
log.error("Missing backquote on [" + dbName + "]");
|
||||
log.log(ERROR, "Missing backquote on [" + dbName + "]");
|
||||
}
|
||||
} else if (allQuotedIdentifiers) {
|
||||
return openQuote + dbName + closeQuote;
|
||||
@@ -676,8 +620,8 @@ public class DatabasePlatform {
|
||||
}
|
||||
|
||||
private boolean isQuote(char ch) {
|
||||
for (char identifer : QUOTED_IDENTIFIERS) {
|
||||
if (identifer == ch) {
|
||||
for (char identifier : QUOTED_IDENTIFIERS) {
|
||||
if (identifier == ch) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -700,14 +644,14 @@ public class DatabasePlatform {
|
||||
/**
|
||||
* Set to true if select count against anonymous view requires an alias.
|
||||
*/
|
||||
public boolean isSelectCountWithAlias() {
|
||||
public boolean selectCountWithAlias() {
|
||||
return selectCountWithAlias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if select count with subquery needs column alias (SQL Server).
|
||||
*/
|
||||
public boolean isSelectCountWithColumnAlias() {
|
||||
public boolean selectCountWithColumnAlias() {
|
||||
return selectCountWithColumnAlias;
|
||||
}
|
||||
|
||||
@@ -729,7 +673,7 @@ public class DatabasePlatform {
|
||||
|
||||
protected String withForUpdate(String sql, Query.LockWait lockWait, Query.LockType lockType) {
|
||||
// silently assume the database does not support the "for update" clause.
|
||||
log.info("it seems your database does not support the 'for update' clause");
|
||||
log.log(INFO, "it seems your database does not support the 'for update' clause");
|
||||
return sql;
|
||||
}
|
||||
|
||||
@@ -738,14 +682,14 @@ public class DatabasePlatform {
|
||||
* <p>
|
||||
* This may include an escape clause to disable a default escape character.
|
||||
*/
|
||||
public String getLikeClause(boolean rawLikeExpression) {
|
||||
public String likeClause(boolean rawLikeExpression) {
|
||||
return rawLikeExpression ? likeClauseRaw : likeClauseEscaped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the platform default JDBC batch mode for persist cascade.
|
||||
*/
|
||||
public PersistBatch getPersistBatchOnCascade() {
|
||||
public PersistBatch persistBatchOnCascade() {
|
||||
return persistBatchOnCascade;
|
||||
}
|
||||
|
||||
@@ -763,7 +707,7 @@ public class DatabasePlatform {
|
||||
if (!schemaExists(dbSchema, connection)) {
|
||||
Statement query = connection.createStatement();
|
||||
try {
|
||||
log.debug("create schema:{}", dbSchema);
|
||||
log.log(DEBUG, "create schema:{0}", dbSchema);
|
||||
query.executeUpdate("create schema " + dbSchema);
|
||||
} finally {
|
||||
JdbcClose.close(query);
|
||||
@@ -789,19 +733,6 @@ public class DatabasePlatform {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the table exists.
|
||||
*/
|
||||
public boolean tableExists(Connection connection, String catalog, String schema, String table) throws SQLException {
|
||||
DatabaseMetaData metaData = connection.getMetaData();
|
||||
ResultSet tables = metaData.getTables(catalog, schema, table, null);
|
||||
try {
|
||||
return tables.next();
|
||||
} finally {
|
||||
JdbcClose.close(tables);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes the like string for this DB-Platform
|
||||
*/
|
||||
|
||||
@@ -3,42 +3,25 @@ package io.ebean.config.dbplatform;
|
||||
/**
|
||||
* Adds LIMIT OFFSET clauses to a SQL query.
|
||||
*/
|
||||
public class LimitOffsetSqlLimiter implements SqlLimiter {
|
||||
|
||||
/**
|
||||
* LIMIT keyword.
|
||||
*/
|
||||
private static final String LIMIT = "limit";
|
||||
|
||||
/**
|
||||
* OFFSET keyword.
|
||||
*/
|
||||
private static final String OFFSET = "offset";
|
||||
public final class LimitOffsetSqlLimiter implements SqlLimiter {
|
||||
|
||||
@Override
|
||||
public SqlLimitResponse limit(SqlLimitRequest request) {
|
||||
|
||||
String dbSql = request.getDbSql();
|
||||
|
||||
StringBuilder sb = new StringBuilder(50 + dbSql.length());
|
||||
sb.append("select ");
|
||||
if (request.isDistinct()) {
|
||||
sb.append("distinct ");
|
||||
}
|
||||
|
||||
sb.append(dbSql);
|
||||
|
||||
int firstRow = request.getFirstRow();
|
||||
int maxRows = request.getMaxRows();
|
||||
|
||||
if (maxRows > 0 || firstRow > 0) {
|
||||
sb.append(" ").append(LIMIT).append(" ").append(maxRows);
|
||||
if (firstRow > 0) {
|
||||
sb.append(" ").append(OFFSET).append(" ");
|
||||
sb.append(firstRow);
|
||||
}
|
||||
if (maxRows > 0) {
|
||||
sb.append(" limit ").append(maxRows);
|
||||
}
|
||||
int firstRow = request.getFirstRow();
|
||||
if (firstRow > 0) {
|
||||
sb.append(" offset ").append(firstRow);
|
||||
}
|
||||
|
||||
String sql = request.getDbPlatform().completeSql(sb.toString(), request.getOrmQuery());
|
||||
return new SqlLimitResponse(sql);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package io.ebean.config.dbplatform;
|
||||
|
||||
import io.avaje.applog.AppLog;
|
||||
import io.ebean.BackgroundExecutor;
|
||||
import io.ebean.Transaction;
|
||||
import io.ebean.util.JdbcClose;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
import javax.sql.DataSource;
|
||||
@@ -19,12 +18,15 @@ import java.util.TreeSet;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import static java.lang.System.Logger.Level.DEBUG;
|
||||
import static java.lang.System.Logger.Level.ERROR;
|
||||
|
||||
/**
|
||||
* Database sequence based IdGenerator.
|
||||
*/
|
||||
public abstract class SequenceIdGenerator implements PlatformIdGenerator {
|
||||
|
||||
protected static final Logger log = LoggerFactory.getLogger("io.ebean.SEQ");
|
||||
protected static final System.Logger log = AppLog.getLogger("io.ebean.SEQ");
|
||||
|
||||
private final ReentrantLock lock = new ReentrantLock();
|
||||
protected final String seqName;
|
||||
@@ -120,7 +122,7 @@ public abstract class SequenceIdGenerator implements PlatformIdGenerator {
|
||||
protected void loadInBackground(final int requestSize) {
|
||||
if (currentlyBackgroundLoading.get()) {
|
||||
// skip as already background loading
|
||||
log.debug("... skip background sequence load (another load in progress)");
|
||||
log.log(DEBUG, "... skip background sequence load (another load in progress)");
|
||||
return;
|
||||
}
|
||||
currentlyBackgroundLoading.set(true);
|
||||
@@ -152,9 +154,6 @@ public abstract class SequenceIdGenerator implements PlatformIdGenerator {
|
||||
resultSet = statement.executeQuery();
|
||||
|
||||
List<Long> newIds = readIds(resultSet, requestSize);
|
||||
if (log.isTraceEnabled()) {
|
||||
log.trace("seq:{} loaded:{} sql:{}", seqName, newIds.size(), sql);
|
||||
}
|
||||
if (newIds.isEmpty()) {
|
||||
throw new PersistenceException("Always expecting more than 1 row from " + sql);
|
||||
}
|
||||
@@ -164,7 +163,7 @@ public abstract class SequenceIdGenerator implements PlatformIdGenerator {
|
||||
} catch (SQLException e) {
|
||||
if (e.getMessage().contains("Database is already closed")) {
|
||||
String msg = "Error getting SEQ when DB shutting down " + e.getMessage();
|
||||
log.error(msg);
|
||||
log.log(ERROR, msg);
|
||||
System.out.println(msg);
|
||||
return Collections.emptyList();
|
||||
} else {
|
||||
|
||||
@@ -32,7 +32,12 @@ public class SqlCodeTranslator implements SqlExceptionTranslator {
|
||||
}
|
||||
|
||||
private DataErrorType getErrorType(SQLException e) {
|
||||
DataErrorType errorType = map.get(e.getSQLState());
|
||||
String sqlState = e.getSQLState();
|
||||
while (sqlState == null && e.getCause() instanceof SQLException) {
|
||||
e = (SQLException)e.getCause();
|
||||
sqlState = e.getSQLState();
|
||||
}
|
||||
DataErrorType errorType = map.get(sqlState);
|
||||
if (errorType == null) {
|
||||
// fall back to error code
|
||||
errorType = map.get(String.valueOf(e.getErrorCode()));
|
||||
|
||||
@@ -5,14 +5,6 @@ package io.ebean.config.dbplatform;
|
||||
*/
|
||||
public interface SqlLimiter {
|
||||
|
||||
/**
|
||||
* the new line character used.
|
||||
* <p>
|
||||
* Note that this is removed for logging sql to the transaction log.
|
||||
* </p>
|
||||
*/
|
||||
char NEW_LINE = '\n';
|
||||
|
||||
/**
|
||||
* Add the SQL limiting statements around the query.
|
||||
*/
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package io.ebean.event;
|
||||
|
||||
import io.ebean.Database;
|
||||
import io.ebean.EbeanVersion;
|
||||
import io.ebean.service.SpiContainer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.sql.Driver;
|
||||
import java.sql.DriverManager;
|
||||
@@ -13,6 +12,8 @@ import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import static java.lang.System.Logger.Level.*;
|
||||
|
||||
/**
|
||||
* Manages the shutdown of Ebean.
|
||||
* <p>
|
||||
@@ -20,13 +21,14 @@ import java.util.concurrent.locks.ReentrantLock;
|
||||
*/
|
||||
public final class ShutdownManager {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger("io.ebean");
|
||||
private static final System.Logger log = EbeanVersion.log;
|
||||
private static final ReentrantLock lock = new ReentrantLock();
|
||||
private static final List<Database> databases = new ArrayList<>();
|
||||
private static final ShutdownHook shutdownHook = new ShutdownHook();
|
||||
|
||||
private static boolean stopping;
|
||||
private static SpiContainer container;
|
||||
|
||||
static {
|
||||
// Register the Shutdown hook
|
||||
registerShutdownHook();
|
||||
@@ -120,9 +122,7 @@ public final class ShutdownManager {
|
||||
// Already run shutdown...
|
||||
return;
|
||||
}
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Ebean shutting down");
|
||||
}
|
||||
log.log(DEBUG, "Ebean shutting down");
|
||||
stopping = true;
|
||||
deregisterShutdownHook();
|
||||
|
||||
@@ -133,7 +133,7 @@ public final class ShutdownManager {
|
||||
Runnable r = (Runnable) ClassUtil.newInstance(shutdownRunner);
|
||||
r.run();
|
||||
} catch (Exception e) {
|
||||
log.error("Error running custom shutdown runnable", e);
|
||||
log.log(ERROR, "Error running custom shutdown runnable", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ public final class ShutdownManager {
|
||||
try {
|
||||
server.shutdown();
|
||||
} catch (Exception ex) {
|
||||
log.error("Error executing shutdown runnable", ex);
|
||||
log.log(ERROR, "Error executing shutdown runnable", ex);
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
@@ -165,10 +165,10 @@ public final class ShutdownManager {
|
||||
while (drivers.hasMoreElements()) {
|
||||
Driver driver = drivers.nextElement();
|
||||
try {
|
||||
log.info("De-registering jdbc driver: " + driver);
|
||||
log.log(INFO, "De-registering jdbc driver: " + driver);
|
||||
DriverManager.deregisterDriver(driver);
|
||||
} catch (SQLException e) {
|
||||
log.error("Error de-registering driver " + driver, e);
|
||||
log.log(ERROR, "Error de-registering driver " + driver, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -204,6 +204,7 @@ public final class ShutdownManager {
|
||||
private ShutdownHook() {
|
||||
super("EbeanHook");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
ShutdownManager.shutdown();
|
||||
|
||||
@@ -39,18 +39,6 @@ public interface ExpressionPath {
|
||||
*/
|
||||
StringParser stringParser();
|
||||
|
||||
/**
|
||||
* For DateTime capable scalar types convert the long systemTimeMillis into
|
||||
* an appropriate java time (Date,Timestamp,Time,Calendar, JODA type etc).
|
||||
*/
|
||||
Object parseDateTime(long systemTimeMillis);
|
||||
|
||||
/**
|
||||
* Return true if the last type is "DateTime capable" - can support
|
||||
* {@link #parseDateTime(long)}.
|
||||
*/
|
||||
boolean isDateTimeCapable();
|
||||
|
||||
/**
|
||||
* Return the underlying JDBC type or 0 if this is not a scalar type.
|
||||
*/
|
||||
|
||||
@@ -6,6 +6,7 @@ package io.ebean.text;
|
||||
* Basic interface to support CSV, JSON and XML processing.
|
||||
* </p>
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface StringFormatter {
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,6 +5,7 @@ package io.ebean.text;
|
||||
* <p>
|
||||
* Basic interface to support CSV, JSON and XML processing.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface StringParser {
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,171 +0,0 @@
|
||||
package io.ebean.text.csv;
|
||||
|
||||
import io.ebean.text.StringParser;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Reads CSV data turning it into object graphs that you can be saved (inserted)
|
||||
* or processed yourself.
|
||||
* <p>
|
||||
* This first example doesn't use a {@link CsvCallback} and this means it will
|
||||
* automatically create a transaction, save the customers and commit the
|
||||
* transaction when successful.
|
||||
* </p>
|
||||
*
|
||||
* <pre>{@code
|
||||
* try {
|
||||
* File f = new File("src/test/resources/test1.csv");
|
||||
*
|
||||
* FileReader reader = new FileReader(f, encoding);
|
||||
*
|
||||
* CsvReader<Customer> csvReader = DB.createCsvReader(Customer.class);
|
||||
*
|
||||
* csvReader.setPersistBatchSize(20);
|
||||
*
|
||||
* csvReader.addProperty("status");
|
||||
* // ignore the next property
|
||||
* csvReader.addIgnore();
|
||||
* csvReader.addProperty("name");
|
||||
* csvReader.addDateTime("anniversary", "dd-MMM-yyyy");
|
||||
* csvReader.addProperty("billingAddress.line1");
|
||||
* csvReader.addProperty("billingAddress.city");
|
||||
*
|
||||
* csvReader.process(reader);
|
||||
*
|
||||
* } catch (Exception e) {
|
||||
* throw new RuntimeException(e);
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* @param <T> the entity bean type
|
||||
*/
|
||||
public interface CsvReader<T> {
|
||||
|
||||
/**
|
||||
* Explicitly set the default Locale.
|
||||
*/
|
||||
void setDefaultLocale(Locale defaultLocale);
|
||||
|
||||
/**
|
||||
* Set the default format to use for Time types.
|
||||
*/
|
||||
void setDefaultTimeFormat(String defaultTimeFormat);
|
||||
|
||||
/**
|
||||
* Set the default format to use for Date types.
|
||||
*/
|
||||
void setDefaultDateFormat(String defaultDateFormat);
|
||||
|
||||
/**
|
||||
* Set the default format to use for Timestamp types.
|
||||
*/
|
||||
void setDefaultTimestampFormat(String defaultTimestampFormat);
|
||||
|
||||
/**
|
||||
* Set the batch size for using JDBC statement batching.
|
||||
* <p>
|
||||
* By default this is set to 20 and setting this to 1 will disable the use of
|
||||
* JDBC statement batching.
|
||||
* </p>
|
||||
*/
|
||||
void setPersistBatchSize(int persistBatchSize);
|
||||
|
||||
/**
|
||||
* Set to true if there is a header row that should be ignored.
|
||||
* <p>
|
||||
* If addPropertiesFromHeader is true then all the properties are added using
|
||||
* the default time,date and timestamp formats.
|
||||
* <p>
|
||||
* If you have a mix of dateTime formats you can not use this method and must
|
||||
* add the properties yourself.
|
||||
* </p>
|
||||
*/
|
||||
void setHasHeader(boolean hasHeader, boolean addPropertiesFromHeader);
|
||||
|
||||
/**
|
||||
* Same as setHasHeader(true,true);
|
||||
* <p>
|
||||
* This will use a header to define all the properties to load using the
|
||||
* default formats for time, date and datetime types.
|
||||
* </p>
|
||||
*/
|
||||
void setAddPropertiesFromHeader();
|
||||
|
||||
/**
|
||||
* Same as setHasHeader(true, false);
|
||||
* <p>
|
||||
* This indicates that there is a header but that it should be ignored.
|
||||
* </p>
|
||||
*/
|
||||
void setIgnoreHeader();
|
||||
|
||||
/**
|
||||
* Set the frequency with which a INFO message will be logged showing the
|
||||
* progress of the processing. You might set this to 1000 or 10000 etc.
|
||||
* <p>
|
||||
* If this is not set then no INFO messages will be logged.
|
||||
* </p>
|
||||
*/
|
||||
void setLogInfoFrequency(int logInfoFrequency);
|
||||
|
||||
/**
|
||||
* Ignore the next column of data.
|
||||
*/
|
||||
void addIgnore();
|
||||
|
||||
/**
|
||||
* Define the property which will be loaded from the next column of data.
|
||||
* <p>
|
||||
* This takes into account the data type of the property and handles the
|
||||
* String to object conversion automatically.
|
||||
* </p>
|
||||
*/
|
||||
void addProperty(String propertyName);
|
||||
|
||||
/**
|
||||
* Define the next property and use a custom StringParser to convert the
|
||||
* string content into the appropriate type for the property.
|
||||
*/
|
||||
void addProperty(String propertyName, StringParser parser);
|
||||
|
||||
/**
|
||||
* Add a property with a custom Date/Time/Timestamp format using the default
|
||||
* Locale. This will convert the string into the appropriate java type for the
|
||||
* given property (Date, Calendar, SQL Date, Time, Timestamp, JODA etc).
|
||||
*/
|
||||
void addDateTime(String propertyName, String dateTimeFormat);
|
||||
|
||||
/**
|
||||
* Add a property with a custom Date/Time/Timestamp format. This will convert
|
||||
* the string into the appropriate java type for the given property (Date,
|
||||
* Calendar, SQL Date, Time, Timestamp, JODA etc).
|
||||
*/
|
||||
void addDateTime(String propertyName, String dateTimeFormat, Locale locale);
|
||||
|
||||
/**
|
||||
* Automatically create a transaction if required to process all the CSV
|
||||
* content from the reader.
|
||||
* <p>
|
||||
* This will check for a current transaction. If there is no current
|
||||
* transaction then one is started and will commit (or rollback) at the end of
|
||||
* processing. This will also set the persistBatchSize on the transaction.
|
||||
* </p>
|
||||
*/
|
||||
void process(Reader reader) throws Exception;
|
||||
|
||||
/**
|
||||
* Process the CSV content passing the bean to the CsvCallback after each row.
|
||||
* <p>
|
||||
* This provides you with the ability to modify and process the bean.
|
||||
* </p>
|
||||
* <p>
|
||||
* When using a CsvCallback the reader WILL NOT create a transaction or save
|
||||
* the bean(s) for you. If you want to insert the processed beans you must
|
||||
* create your own transaction and save the bean(s) yourself.
|
||||
* </p>
|
||||
*/
|
||||
void process(Reader reader, CsvCallback<T> callback) throws Exception;
|
||||
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
/**
|
||||
* CSV processing objects.
|
||||
*/
|
||||
package io.ebean.text.csv;
|
||||
@@ -1,19 +1,20 @@
|
||||
package io.ebean.util;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import io.ebean.EbeanVersion;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
|
||||
import static java.lang.System.Logger.Level.WARNING;
|
||||
|
||||
/**
|
||||
* Utility for closing raw Jdbc resources.
|
||||
*/
|
||||
public final class JdbcClose {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger("io.ebean");
|
||||
private static final System.Logger log = EbeanVersion.log;
|
||||
|
||||
/**
|
||||
* Close the resultSet logging if an error occurs.
|
||||
@@ -24,7 +25,7 @@ public final class JdbcClose {
|
||||
statement.close();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
log.warn("Error closing statement", e);
|
||||
log.log(WARNING, "Error closing statement", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +38,7 @@ public final class JdbcClose {
|
||||
resultSet.close();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
log.warn("Error closing resultSet", e);
|
||||
log.log(WARNING, "Error closing resultSet", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +51,7 @@ public final class JdbcClose {
|
||||
connection.close();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
log.warn("Error closing connection", e);
|
||||
log.log(WARNING, "Error closing connection", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +64,7 @@ public final class JdbcClose {
|
||||
connection.rollback();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
log.warn("Error on connection rollback", e);
|
||||
log.log(WARNING, "Error on connection rollback", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +77,7 @@ public final class JdbcClose {
|
||||
stmt.cancel();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
log.warn("Error on cancelling statement", e);
|
||||
log.log(WARNING, "Error on cancelling statement", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,9 @@ module io.ebean.api {
|
||||
requires transitive persistence.api;
|
||||
requires transitive io.ebean.annotation;
|
||||
requires transitive io.ebean.datasource.api;
|
||||
requires transitive org.slf4j;
|
||||
requires transitive io.avaje.applog;
|
||||
|
||||
requires static org.slf4j;
|
||||
requires static io.ebean.types;
|
||||
requires static com.fasterxml.jackson.core;
|
||||
requires static com.fasterxml.jackson.databind;
|
||||
@@ -39,7 +40,6 @@ module io.ebean.api {
|
||||
exports io.ebean.service;
|
||||
exports io.ebean.text;
|
||||
exports io.ebean.text.json;
|
||||
exports io.ebean.text.csv;
|
||||
exports io.ebean.util;
|
||||
|
||||
}
|
||||
|
||||
+9
-14
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</parent>
|
||||
<!-- <parent>-->
|
||||
<!-- <groupId>org.avaje</groupId>-->
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
<scm>
|
||||
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
|
||||
<tag>HEAD</tag>
|
||||
<tag>ebean-parent-13.11.4</tag>
|
||||
</scm>
|
||||
|
||||
<name>ebean autotune</name>
|
||||
@@ -26,21 +26,16 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- needed for java 11+ -->
|
||||
<dependency>
|
||||
<groupId>jakarta.xml.bind</groupId>
|
||||
<artifactId>jakarta.xml.bind-api</artifactId>
|
||||
<version>4.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.xml.bind</groupId>
|
||||
<artifactId>jaxb-impl</artifactId>
|
||||
<version>4.0.0</version>
|
||||
<scope>runtime</scope>
|
||||
<groupId>org.glassfish.jaxb</groupId>
|
||||
<artifactId>jaxb-runtime</artifactId>
|
||||
<version>2.3.6</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -60,7 +55,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-h2</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -75,7 +70,7 @@
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<tiles>
|
||||
<tile>io.ebean.tile:enhancement:13.6.5</tile>
|
||||
<tile>io.ebean.tile:enhancement:13.10.1</tile>
|
||||
</tiles>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package io.ebeaninternal.server.autotune.model;
|
||||
|
||||
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||
import jakarta.xml.bind.annotation.XmlRootElement;
|
||||
import jakarta.xml.bind.annotation.XmlType;
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
package io.ebeaninternal.server.autotune.model;
|
||||
|
||||
import jakarta.xml.bind.annotation.XmlRegistry;
|
||||
import javax.xml.bind.annotation.XmlRegistry;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package io.ebeaninternal.server.autotune.model;
|
||||
|
||||
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||
import jakarta.xml.bind.annotation.XmlAttribute;
|
||||
import jakarta.xml.bind.annotation.XmlRootElement;
|
||||
import jakarta.xml.bind.annotation.XmlType;
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
+4
-4
@@ -1,9 +1,9 @@
|
||||
package io.ebeaninternal.server.autotune.model;
|
||||
|
||||
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||
import jakarta.xml.bind.annotation.XmlRootElement;
|
||||
import jakarta.xml.bind.annotation.XmlType;
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
+4
-4
@@ -1,9 +1,9 @@
|
||||
package io.ebeaninternal.server.autotune.model;
|
||||
|
||||
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||
import jakarta.xml.bind.annotation.XmlRootElement;
|
||||
import jakarta.xml.bind.annotation.XmlType;
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package io.ebeaninternal.server.autotune.model;
|
||||
|
||||
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||
import jakarta.xml.bind.annotation.XmlRootElement;
|
||||
import jakarta.xml.bind.annotation.XmlType;
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
@jakarta.xml.bind.annotation.XmlSchema(namespace = "http://ebean-orm.github.io/xml/ns/autotune", elementFormDefault = jakarta.xml.bind.annotation.XmlNsForm.QUALIFIED)
|
||||
@javax.xml.bind.annotation.XmlSchema(namespace = "http://ebean-orm.github.io/xml/ns/autotune", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
|
||||
package io.ebeaninternal.server.autotune.model;
|
||||
|
||||
+3
-3
@@ -3,9 +3,9 @@ package io.ebeaninternal.server.autotune.service;
|
||||
|
||||
import io.ebeaninternal.server.autotune.model.Autotune;
|
||||
|
||||
import jakarta.xml.bind.JAXBContext;
|
||||
import jakarta.xml.bind.JAXBException;
|
||||
import jakarta.xml.bind.Unmarshaller;
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
+3
-3
@@ -3,9 +3,9 @@ package io.ebeaninternal.server.autotune.service;
|
||||
|
||||
import io.ebeaninternal.server.autotune.model.Autotune;
|
||||
|
||||
import jakarta.xml.bind.JAXBContext;
|
||||
import jakarta.xml.bind.JAXBException;
|
||||
import jakarta.xml.bind.Marshaller;
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Marshaller;
|
||||
import java.io.File;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
+1
-1
@@ -148,7 +148,7 @@ public class BaseQueryTuner {
|
||||
case UPDATE:
|
||||
case DELETE:
|
||||
case SQ_EXISTS:
|
||||
case SQ_IN:
|
||||
case SQ_EX:
|
||||
return false;
|
||||
default:
|
||||
// not using autoTune when explicitly loading the l2 bean cache
|
||||
|
||||
+15
-14
@@ -1,5 +1,6 @@
|
||||
package io.ebeaninternal.server.autotune.service;
|
||||
|
||||
import io.avaje.applog.AppLog;
|
||||
import io.ebean.config.AutoTuneConfig;
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebeaninternal.api.SpiEbeanServer;
|
||||
@@ -7,8 +8,6 @@ import io.ebeaninternal.api.SpiQuery;
|
||||
import io.ebeaninternal.server.autotune.AutoTuneService;
|
||||
import io.ebeaninternal.server.autotune.model.Autotune;
|
||||
import io.ebeaninternal.server.autotune.model.Origin;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -16,12 +15,14 @@ import java.io.InputStream;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import static java.lang.System.Logger.Level.*;
|
||||
|
||||
/**
|
||||
* Implementation of the AutoTuneService which is comprised of profiling and query tuning.
|
||||
*/
|
||||
public class DefaultAutoTuneService implements AutoTuneService {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(DefaultAutoTuneService.class);
|
||||
private static final System.Logger logger = AppLog.getLogger(DefaultAutoTuneService.class);
|
||||
|
||||
private final ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
@@ -111,7 +112,7 @@ public class DefaultAutoTuneService implements AutoTuneService {
|
||||
if (stream != null) {
|
||||
loadAutoTuneProfiling(AutoTuneXmlReader.read(stream));
|
||||
} else {
|
||||
logger.warn("AutoTune file {} not found - no initial automatic query tuning", tuningFile);
|
||||
logger.log(WARNING, "AutoTune file {0} not found - no initial automatic query tuning", tuningFile);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Error on auto close of " + tuningFile, e);
|
||||
@@ -120,7 +121,7 @@ public class DefaultAutoTuneService implements AutoTuneService {
|
||||
}
|
||||
|
||||
private void loadAutoTuneProfiling(Autotune profiling) {
|
||||
logger.info("AutoTune loading {} tuning entries", profiling.getOrigin().size());
|
||||
logger.log(INFO, "AutoTune loading {0} tuning entries", profiling.getOrigin().size());
|
||||
for (Origin origin : profiling.getOrigin()) {
|
||||
queryTuner.put(origin);
|
||||
}
|
||||
@@ -141,17 +142,17 @@ public class DefaultAutoTuneService implements AutoTuneService {
|
||||
event.process();
|
||||
if (event.isEmpty()) {
|
||||
long exeMillis = System.currentTimeMillis() - start;
|
||||
logger.debug("No query tuning updates for server:{} executionMillis:{}", serverName, exeMillis);
|
||||
logger.log(DEBUG, "No query tuning updates for server:{0} executionMillis:{1}", serverName, exeMillis);
|
||||
|
||||
} else {
|
||||
// report the query tuning changes that have been made
|
||||
runtimeChangeCount += event.getChangeCount();
|
||||
event.writeFile(profilingFile + "-" + serverName + "-update");
|
||||
long exeMillis = System.currentTimeMillis() - start;
|
||||
logger.info("query tuning updates - new:{} diff:{} for server:{} executionMillis:{}", event.getNewCount(), event.getDiffCount(), serverName, exeMillis);
|
||||
logger.log(INFO, "query tuning updates - new:{0} diff:{1} for server:{2} executionMillis:{3}", event.getNewCount(), event.getDiffCount(), serverName, exeMillis);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
logger.error("Error collecting or applying automatic query tuning", e);
|
||||
logger.log(ERROR, "Error collecting or applying automatic query tuning", e);
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
@@ -172,11 +173,11 @@ public class DefaultAutoTuneService implements AutoTuneService {
|
||||
AutoTuneDiffCollection event = new AutoTuneDiffCollection(profiling, queryTuner, false);
|
||||
event.process();
|
||||
if (event.isEmpty()) {
|
||||
logger.info("No new or diff entries for profiling server:{}", serverName);
|
||||
logger.log(INFO, "No new or diff entries for profiling server:{0}", serverName);
|
||||
|
||||
} else {
|
||||
event.writeFile(profilingFile + "-" + serverName);
|
||||
logger.info("writing new:{} diff:{} profiling entries for server:{}", event.getNewCount(), event.getDiffCount(), serverName);
|
||||
logger.log(INFO, "writing new:{0} diff:{1} profiling entries for server:{2}", event.getNewCount(), event.getDiffCount(), serverName);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
@@ -196,7 +197,7 @@ public class DefaultAutoTuneService implements AutoTuneService {
|
||||
private void outputAllTuning() {
|
||||
|
||||
if (runtimeChangeCount == 0) {
|
||||
logger.info("no runtime query tuning changes for server:{}", serverName);
|
||||
logger.log(INFO, "no runtime query tuning changes for server:{0}", serverName);
|
||||
|
||||
} else {
|
||||
AutoTuneAllCollection event = new AutoTuneAllCollection(queryTuner);
|
||||
@@ -205,12 +206,12 @@ public class DefaultAutoTuneService implements AutoTuneService {
|
||||
if (existingTuning.exists()) {
|
||||
// rename the existing autotune.xml file (appending 'now')
|
||||
if (!existingTuning.renameTo(new File(tuningFile + "." + AutoTuneXmlWriter.now()))) {
|
||||
logger.warn("Failed to rename autotune file [{}]", tuningFile);
|
||||
logger.log(WARNING, "Failed to rename autotune file [{0}]", tuningFile);
|
||||
}
|
||||
}
|
||||
|
||||
event.writeFile(tuningFile, false);
|
||||
logger.info("query tuning detected [{}] changes, writing all [{}] tuning entries for server:{}", runtimeChangeCount, size, serverName);
|
||||
logger.log(INFO, "query tuning detected [{0}] changes, writing all [{1}] tuning entries for server:{2}", runtimeChangeCount, size, serverName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,7 +280,7 @@ public class DefaultAutoTuneService implements AutoTuneService {
|
||||
} catch (InterruptedException e) {
|
||||
// restore the interrupted status
|
||||
Thread.currentThread().interrupt();
|
||||
logger.warn("Error while sleeping after System.gc() request.", e);
|
||||
logger.log(WARNING, "Error while sleeping after System.gc() request.", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-5
@@ -1,5 +1,6 @@
|
||||
package io.ebeaninternal.server.autotune.service;
|
||||
|
||||
import io.avaje.applog.AppLog;
|
||||
import io.ebean.bean.NodeUsageCollector;
|
||||
import io.ebean.text.PathProperties;
|
||||
import io.ebean.util.SplitName;
|
||||
@@ -7,19 +8,19 @@ import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import io.ebeaninternal.server.deploy.BeanProperty;
|
||||
import io.ebeaninternal.server.deploy.BeanPropertyAssoc;
|
||||
import io.ebeaninternal.server.el.ElPropertyValue;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import static java.lang.System.Logger.Level.WARNING;
|
||||
|
||||
/**
|
||||
* Collects usages statistics for a given node in the object graph.
|
||||
*/
|
||||
public class ProfileOriginNodeUsage {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ProfileOriginNodeUsage.class);
|
||||
private static final System.Logger logger = AppLog.getLogger(ProfileOriginNodeUsage.class);
|
||||
|
||||
private final ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
@@ -45,7 +46,7 @@ public class ProfileOriginNodeUsage {
|
||||
if (path != null) {
|
||||
ElPropertyValue elGetValue = rootDesc.elGetValue(path);
|
||||
if (elGetValue == null) {
|
||||
logger.warn("AutoTune: Can't find join for path[" + path + "] for " + rootDesc.name());
|
||||
logger.log(WARNING, "AutoTune: Can't find join for path[" + path + "] for " + rootDesc.name());
|
||||
return;
|
||||
} else {
|
||||
BeanProperty beanProperty = elGetValue.beanProperty();
|
||||
@@ -61,7 +62,7 @@ public class ProfileOriginNodeUsage {
|
||||
for (String propName : aggregateUsed) {
|
||||
BeanProperty beanProp = desc.findPropertyFromPath(propName);
|
||||
if (beanProp == null) {
|
||||
logger.warn("AutoTune: Can't find property[" + propName + "] for " + desc.name());
|
||||
logger.log(WARNING, "AutoTune: Can't find property[" + propName + "] for " + desc.name());
|
||||
|
||||
} else {
|
||||
if (beanProp.isId()) {
|
||||
|
||||
@@ -10,5 +10,6 @@ module io.ebean.autotune {
|
||||
|
||||
requires io.ebean.api;
|
||||
requires io.ebean.core;
|
||||
requires jakarta.xml.bind;
|
||||
requires java.xml;
|
||||
requires java.xml.bind;
|
||||
}
|
||||
|
||||
+112
-15
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean bom</name>
|
||||
@@ -18,12 +18,23 @@
|
||||
|
||||
<!-- dependencies external to this ebean.git build -->
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>persistence-api</artifactId>
|
||||
<version>${ebean-persistence-api.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-annotation</artifactId>
|
||||
<version>${ebean-annotation.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-types</artifactId>
|
||||
<version>${ebean-types.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
@@ -78,88 +89,174 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core-type</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-joda-time</artifactId>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-jackson-jsonnode</artifactId>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-jackson-mapper</artifactId>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-ddl-generator</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-externalmapping-api</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-externalmapping-xml</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-autotune</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>querybean-generator</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>kotlin-querybean-generator</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-test</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-postgis</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-redis</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<!-- platforms -->
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-clickhouse</artifactId>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-db2</artifactId>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-h2</artifactId>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-hana</artifactId>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-mariadb</artifactId>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-mysql</artifactId>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-nuodb</artifactId>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-oracle</artifactId>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-postgres</artifactId>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-sqlite</artifactId>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-sqlserver</artifactId>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
+17
-2
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>ebean-core-type</artifactId>
|
||||
@@ -16,7 +16,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -26,6 +26,21 @@
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- Provided scope for Postgres JSON/JSONB support -->
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>42.4.3</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.avaje</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>1.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
||||
+28
-108
@@ -1,8 +1,5 @@
|
||||
package io.ebeaninternal.server.core;
|
||||
package io.ebean.core.type;
|
||||
|
||||
import io.ebeaninternal.server.type.ScalarTypeUUIDBinary;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.sql.Timestamp;
|
||||
@@ -14,14 +11,9 @@ import java.util.Calendar;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Default implementation of TypeConverter.
|
||||
* <p>
|
||||
* Converts objects to the required type if required.
|
||||
* </p>
|
||||
* Helper to converts objects to the basic types if required.
|
||||
*/
|
||||
public final class BasicTypeConverter implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 7691463236204070311L;
|
||||
public final class BasicTypeConverter {
|
||||
|
||||
/**
|
||||
* Type code for java.util.Calendar.
|
||||
@@ -43,7 +35,6 @@ public final class BasicTypeConverter implements Serializable {
|
||||
* @param toDataType the dataType as per java.sql.Types.
|
||||
*/
|
||||
public static Object convert(Object value, int toDataType) {
|
||||
|
||||
try {
|
||||
switch (toDataType) {
|
||||
case UTIL_DATE: {
|
||||
@@ -58,7 +49,8 @@ public final class BasicTypeConverter implements Serializable {
|
||||
case Types.INTEGER: {
|
||||
return toInteger(value);
|
||||
}
|
||||
case Types.BIT: {
|
||||
case Types.BIT:
|
||||
case Types.BOOLEAN: {
|
||||
return toBoolean(value);
|
||||
}
|
||||
case Types.TINYINT: {
|
||||
@@ -67,59 +59,42 @@ public final class BasicTypeConverter implements Serializable {
|
||||
case Types.SMALLINT: {
|
||||
return toShort(value);
|
||||
}
|
||||
case Types.NUMERIC: {
|
||||
return toBigDecimal(value);
|
||||
}
|
||||
case Types.NUMERIC:
|
||||
case Types.DECIMAL: {
|
||||
return toBigDecimal(value);
|
||||
}
|
||||
case Types.REAL: {
|
||||
return toFloat(value);
|
||||
}
|
||||
case Types.DOUBLE: {
|
||||
return toDouble(value);
|
||||
}
|
||||
case Types.DOUBLE:
|
||||
case Types.FLOAT: {
|
||||
return toDouble(value);
|
||||
}
|
||||
case Types.BOOLEAN: {
|
||||
return toBoolean(value);
|
||||
}
|
||||
case Types.TIMESTAMP: {
|
||||
return toTimestamp(value);
|
||||
}
|
||||
case Types.DATE: {
|
||||
return toDate(value);
|
||||
}
|
||||
case Types.VARCHAR: {
|
||||
return toString(value);
|
||||
}
|
||||
case Types.VARCHAR:
|
||||
case Types.CHAR: {
|
||||
return toString(value);
|
||||
}
|
||||
case Types.OTHER: {
|
||||
return value;
|
||||
}
|
||||
case Types.JAVA_OBJECT: {
|
||||
return value;
|
||||
}
|
||||
case Types.OTHER:
|
||||
case Types.BINARY:
|
||||
case Types.LONGVARBINARY:
|
||||
case Types.BLOB: {
|
||||
return value;
|
||||
}
|
||||
case Types.BLOB:
|
||||
case Types.JAVA_OBJECT:
|
||||
case Types.LONGVARCHAR:
|
||||
case Types.CLOB: {
|
||||
return value;
|
||||
}
|
||||
default: {
|
||||
String msg = "Unhandled data type [" + toDataType + "] converting [" + value + "]";
|
||||
throw new RuntimeException(msg);
|
||||
throw new RuntimeException("Unhandled data type - " + toDataType);
|
||||
}
|
||||
}
|
||||
} catch (ClassCastException e) {
|
||||
String m = "ClassCastException converting to data type [" + toDataType + "] value [" + value + "]";
|
||||
throw new RuntimeException(m);
|
||||
throw new RuntimeException("ClassCastException converting to data type: " + toDataType + " value: " + value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +102,6 @@ public final class BasicTypeConverter implements Serializable {
|
||||
* Convert the value to a String.
|
||||
*/
|
||||
public static String toString(Object value) {
|
||||
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -137,7 +111,6 @@ public final class BasicTypeConverter implements Serializable {
|
||||
if (value instanceof char[]) {
|
||||
return String.valueOf((char[]) value);
|
||||
}
|
||||
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
@@ -145,8 +118,7 @@ public final class BasicTypeConverter implements Serializable {
|
||||
/**
|
||||
* Convert the value to a Boolean with an explicit String true value.
|
||||
*/
|
||||
public static Boolean toBoolean(Object value, String dbTrueValue) {
|
||||
|
||||
public static Boolean toBoolean(Object value, String trueValue) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -156,8 +128,7 @@ public final class BasicTypeConverter implements Serializable {
|
||||
if (value instanceof Number) {
|
||||
return ((Number) value).intValue() == 1;
|
||||
}
|
||||
String s = value.toString();
|
||||
return s.equalsIgnoreCase(dbTrueValue);
|
||||
return value.toString().equalsIgnoreCase(trueValue);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -165,14 +136,12 @@ public final class BasicTypeConverter implements Serializable {
|
||||
* "true" or "false".
|
||||
*/
|
||||
public static Boolean toBoolean(Object value) {
|
||||
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value instanceof Boolean) {
|
||||
return (Boolean) value;
|
||||
}
|
||||
|
||||
return Boolean.valueOf(value.toString());
|
||||
}
|
||||
|
||||
@@ -180,7 +149,6 @@ public final class BasicTypeConverter implements Serializable {
|
||||
* Convert the value to a UUID.
|
||||
*/
|
||||
public static UUID toUUID(Object value, boolean optimizedBinary) {
|
||||
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -191,17 +159,15 @@ public final class BasicTypeConverter implements Serializable {
|
||||
return UUID.fromString((String) value);
|
||||
}
|
||||
if (value instanceof byte[]) {
|
||||
return ScalarTypeUUIDBinary.convertFromBytes((byte[]) value, optimizedBinary);
|
||||
return ScalarTypeUtils.uuidFromBytes((byte[]) value, optimizedBinary);
|
||||
}
|
||||
return UUID.fromString(value.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* convert the passed in object to a BigDecimal. It should be another
|
||||
* numeric type.
|
||||
* convert the passed in object to a BigDecimal. It should be another numeric type.
|
||||
*/
|
||||
public static BigDecimal toBigDecimal(Object value) {
|
||||
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -212,7 +178,6 @@ public final class BasicTypeConverter implements Serializable {
|
||||
}
|
||||
|
||||
public static Float toFloat(Object value) {
|
||||
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -226,7 +191,6 @@ public final class BasicTypeConverter implements Serializable {
|
||||
}
|
||||
|
||||
public static Short toShort(Object value) {
|
||||
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -240,7 +204,6 @@ public final class BasicTypeConverter implements Serializable {
|
||||
}
|
||||
|
||||
public static Byte toByte(Object value) {
|
||||
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -251,11 +214,9 @@ public final class BasicTypeConverter implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* convert the passed in object to a Integer. It should be another numeric
|
||||
* type.
|
||||
* convert the passed in object to an Integer.
|
||||
*/
|
||||
public static Integer toInteger(Object value) {
|
||||
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -269,10 +230,9 @@ public final class BasicTypeConverter implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the object to a Long. It should be another numeric type.
|
||||
* Convert the object to a Long.
|
||||
*/
|
||||
public static Long toLong(Object value) {
|
||||
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -294,8 +254,7 @@ public final class BasicTypeConverter implements Serializable {
|
||||
return Long.valueOf(value.toString());
|
||||
}
|
||||
|
||||
public static BigInteger toMathBigInteger(Object value) {
|
||||
|
||||
public static BigInteger toBigInteger(Object value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -306,10 +265,9 @@ public final class BasicTypeConverter implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the object to a Double. It should be another numberic type.
|
||||
* Convert the object to a Double.
|
||||
*/
|
||||
public static Double toDouble(Object value) {
|
||||
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -323,56 +281,42 @@ public final class BasicTypeConverter implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* convert the passed in object to a Timestamp. It is expected to be a
|
||||
* java.sql.Date really.
|
||||
* convert the passed in object to a Timestamp.
|
||||
*/
|
||||
public static Timestamp toTimestamp(Object value) {
|
||||
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value instanceof Timestamp) {
|
||||
return (Timestamp) value;
|
||||
|
||||
} else if (value instanceof java.util.Date) {
|
||||
// no nanos here... so hopefully ok
|
||||
return new Timestamp(((java.util.Date) value).getTime());
|
||||
|
||||
} else if (value instanceof Calendar) {
|
||||
return new Timestamp(((Calendar) value).getTime().getTime());
|
||||
|
||||
} else if (value instanceof String) {
|
||||
return Timestamp.valueOf((String) value);
|
||||
|
||||
} else if (value instanceof LocalDateTime) {
|
||||
return Timestamp.valueOf((LocalDateTime) value);
|
||||
|
||||
} else if (value instanceof Number) {
|
||||
return new Timestamp(((Number) value).longValue());
|
||||
|
||||
} else {
|
||||
String msg = "Unable to convert [" + value.getClass().getName() + "] into a Timestamp.";
|
||||
throw new RuntimeException(msg);
|
||||
throw new RuntimeException("Unable to convert " + value);
|
||||
}
|
||||
}
|
||||
|
||||
public static java.sql.Time toTime(Object value) {
|
||||
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value instanceof java.sql.Time) {
|
||||
return (java.sql.Time) value;
|
||||
|
||||
} else if (value instanceof String) {
|
||||
return java.sql.Time.valueOf((String) value);
|
||||
|
||||
} else if (value instanceof LocalTime) {
|
||||
return java.sql.Time.valueOf((LocalTime) value);
|
||||
|
||||
} else {
|
||||
String m = "Unable to convert [" + value.getClass().getName() + "] into a java.sql.Date.";
|
||||
throw new RuntimeException(m);
|
||||
throw new RuntimeException("Unable to convert " + value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -380,31 +324,23 @@ public final class BasicTypeConverter implements Serializable {
|
||||
* convert the passed in object to a java sql Date.
|
||||
*/
|
||||
public static java.sql.Date toDate(Object value) {
|
||||
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value instanceof java.sql.Date) {
|
||||
return (java.sql.Date) value;
|
||||
|
||||
} else if (value instanceof java.util.Date) {
|
||||
return new java.sql.Date(((java.util.Date) value).getTime());
|
||||
|
||||
} else if (value instanceof Calendar) {
|
||||
return new java.sql.Date(((Calendar) value).getTime().getTime());
|
||||
|
||||
} else if (value instanceof String) {
|
||||
return java.sql.Date.valueOf((String) value);
|
||||
|
||||
} else if (value instanceof Number) {
|
||||
return new java.sql.Date(((Number) value).longValue());
|
||||
|
||||
} else if (value instanceof LocalDate) {
|
||||
return java.sql.Date.valueOf((LocalDate)value);
|
||||
|
||||
return java.sql.Date.valueOf((LocalDate) value);
|
||||
} else {
|
||||
String m = "Unable to convert [" + value.getClass().getName() + "] into a java.sql.Date.";
|
||||
throw new RuntimeException(m);
|
||||
throw new RuntimeException("Unable to convert " + value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -412,7 +348,6 @@ public final class BasicTypeConverter implements Serializable {
|
||||
* convert the passed in object to a java sql Date.
|
||||
*/
|
||||
public static java.util.Date toUtilDate(Object value) {
|
||||
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -420,26 +355,19 @@ public final class BasicTypeConverter implements Serializable {
|
||||
// loss of nanos precision
|
||||
return new java.util.Date(((java.sql.Timestamp) value).getTime());
|
||||
}
|
||||
// DEVNOTE: strictly speaking do I need to convert a java.sql.Date to
|
||||
// java.util.Date? equals() is symmetrical so perhaps this is not
|
||||
// really required?
|
||||
if (value instanceof java.sql.Date) {
|
||||
return new java.util.Date(((java.sql.Date) value).getTime());
|
||||
}
|
||||
if (value instanceof java.util.Date) {
|
||||
return (java.util.Date) value;
|
||||
|
||||
} else if (value instanceof Calendar) {
|
||||
return ((Calendar) value).getTime();
|
||||
|
||||
} else if (value instanceof String) {
|
||||
return new java.util.Date(Timestamp.valueOf((String) value).getTime());
|
||||
|
||||
} else if (value instanceof Number) {
|
||||
return new java.util.Date(((Number) value).longValue());
|
||||
|
||||
} else {
|
||||
throw new RuntimeException("Unable to convert [" + value.getClass().getName() + "] into a java.util.Date");
|
||||
throw new RuntimeException("Unable to convert " + value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -447,37 +375,29 @@ public final class BasicTypeConverter implements Serializable {
|
||||
* convert the passed in object to a java sql Date.
|
||||
*/
|
||||
public static Calendar toCalendar(Object value) {
|
||||
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value instanceof Calendar) {
|
||||
return (Calendar) value;
|
||||
|
||||
} else if (value instanceof java.util.Date) {
|
||||
java.util.Date date = ((java.util.Date) value);
|
||||
return toCalendarFromDate(date);
|
||||
|
||||
} else if (value instanceof String) {
|
||||
java.util.Date date = toUtilDate(value);
|
||||
return toCalendarFromDate(date);
|
||||
|
||||
} else if (value instanceof Number) {
|
||||
long timeMillis = ((Number) value).longValue();
|
||||
java.util.Date date = new java.util.Date(timeMillis);
|
||||
return toCalendarFromDate(date);
|
||||
|
||||
} else {
|
||||
String m = "Unable to convert [" + value.getClass().getName() + "] into a java.util.Date";
|
||||
throw new RuntimeException(m);
|
||||
throw new RuntimeException("Unable to convert " + value);
|
||||
}
|
||||
}
|
||||
|
||||
private static Calendar toCalendarFromDate(java.util.Date date) {
|
||||
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(date);
|
||||
|
||||
return cal;
|
||||
}
|
||||
|
||||
+14
-3
@@ -1,5 +1,7 @@
|
||||
package io.ebeaninternal.server.type;
|
||||
package io.ebean.core.type;
|
||||
|
||||
import io.ebean.annotation.Platform;
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import org.postgresql.util.PGobject;
|
||||
|
||||
import java.sql.SQLException;
|
||||
@@ -9,12 +11,12 @@ public final class PostgresHelper {
|
||||
/**
|
||||
* The Postgres JSON DB type.
|
||||
*/
|
||||
static final String JSON_TYPE = "json";
|
||||
public static final String JSON_TYPE = "json";
|
||||
|
||||
/**
|
||||
* The Postgres JSONB DB type.
|
||||
*/
|
||||
static final String JSONB_TYPE = "jsonb";
|
||||
public static final String JSONB_TYPE = "jsonb";
|
||||
|
||||
static final String INET_TYPE = "inet";
|
||||
|
||||
@@ -31,4 +33,13 @@ public final class PostgresHelper {
|
||||
pgo.setValue(rawJson);
|
||||
return pgo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the platform is Postgres or compatible like Yugabyte, Cockroach.
|
||||
*/
|
||||
public static boolean isPostgresCompatible(DatabasePlatform databasePlatform) {
|
||||
return databasePlatform.isPlatform(Platform.POSTGRES)
|
||||
|| databasePlatform.isPlatform(Platform.YUGABYTE)
|
||||
|| databasePlatform.isPlatform(Platform.COCKROACH);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package io.ebean.core.type;
|
||||
|
||||
import io.ebean.annotation.MutationDetection;
|
||||
|
||||
/**
|
||||
* Holds the configured mapper and default mutation detection mode to be used.
|
||||
*/
|
||||
public interface ScalarJsonManager {
|
||||
|
||||
/**
|
||||
* Return the default mutation detection mode.
|
||||
*/
|
||||
MutationDetection mutationDetection();
|
||||
|
||||
/**
|
||||
* Return the object mapper supplied in DatabaseConfig.
|
||||
*/
|
||||
Object mapper();
|
||||
|
||||
/**
|
||||
* Return the Postgres type given the jdbc type.
|
||||
*/
|
||||
String postgresType(int dbType);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package io.ebean.core.type;
|
||||
|
||||
import io.avaje.lang.Nullable;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
/**
|
||||
* Supports JSON bean properties that use something like Jackson ObjectMapper to convert between
|
||||
* JSON content and the logical bean property value.
|
||||
*/
|
||||
public interface ScalarJsonMapper {
|
||||
|
||||
/**
|
||||
* Return a ScalarType for the given JSON property.
|
||||
*/
|
||||
ScalarType<?> createType(ScalarJsonRequest request);
|
||||
|
||||
/**
|
||||
* Return a marker annotation to detect when the JSON mapper should be used explicitly.
|
||||
*/
|
||||
@Nullable
|
||||
<A extends Annotation> Class<A> markerAnnotation();
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package io.ebean.core.type;
|
||||
|
||||
import io.ebean.annotation.MutationDetection;
|
||||
|
||||
/**
|
||||
* A request to create a ScalarType for a bean property (typically annotated with {@code @DbJson}).
|
||||
*/
|
||||
public final class ScalarJsonRequest {
|
||||
|
||||
private final ScalarJsonManager manager;
|
||||
private final int dbType;
|
||||
private final DocPropertyType docType;
|
||||
private final Class<?> beanType;
|
||||
private final MutationDetection mode;
|
||||
private final String name;
|
||||
|
||||
public ScalarJsonRequest(ScalarJsonManager manager, int dbType, DocPropertyType docType, Class<?> beanType, MutationDetection mode, String name) {
|
||||
this.manager = manager;
|
||||
this.dbType = dbType;
|
||||
this.docType = docType;
|
||||
this.beanType = beanType;
|
||||
this.mode = mode;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the manager.
|
||||
*/
|
||||
public ScalarJsonManager manager() {
|
||||
return manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the jdbc type this property maps to (e.g. JSON, JSONB etc).
|
||||
*/
|
||||
public int dbType() {
|
||||
return dbType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the document store docType.
|
||||
*/
|
||||
public DocPropertyType docType() {
|
||||
return docType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type of the bean that this property belongs to.
|
||||
*/
|
||||
public Class<?> beanType() {
|
||||
return beanType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the mutation detection mode the property should use.
|
||||
*/
|
||||
public MutationDetection mode() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the property name.
|
||||
*/
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package io.ebean.core.type;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
|
||||
import io.ebean.text.StringFormatter;
|
||||
import io.ebean.text.StringParser;
|
||||
|
||||
@@ -34,7 +33,7 @@ public interface ScalarType<T> extends StringParser, StringFormatter, ScalarData
|
||||
/**
|
||||
* Return true for types that do mutation detection based on json content.
|
||||
*/
|
||||
default boolean isJsonMapper() {
|
||||
default boolean jsonMapper() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -42,14 +41,14 @@ public interface ScalarType<T> extends StringParser, StringFormatter, ScalarData
|
||||
* Return true if this is a binary type and can not support parse() and format() from/to string.
|
||||
* This allows Ebean to optimise marshalling types to string.
|
||||
*/
|
||||
default boolean isBinaryType() {
|
||||
default boolean binary() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this is a mutable scalar type (like hstore).
|
||||
*/
|
||||
default boolean isMutable() {
|
||||
default boolean mutable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -67,7 +66,7 @@ public interface ScalarType<T> extends StringParser, StringFormatter, ScalarData
|
||||
* If a BeanProperty has no explicit length defined then this length should
|
||||
* be assigned.
|
||||
*/
|
||||
default int getLength() {
|
||||
default int length() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -77,7 +76,7 @@ public interface ScalarType<T> extends StringParser, StringFormatter, ScalarData
|
||||
* If it is native to JDBC then its values/instances do not need to be
|
||||
* converted to and from an associated JDBC type.
|
||||
*/
|
||||
boolean isJdbcNative();
|
||||
boolean jdbcNative();
|
||||
|
||||
/**
|
||||
* Return the type as per java.sql.Types that this maps to.
|
||||
@@ -85,14 +84,19 @@ public interface ScalarType<T> extends StringParser, StringFormatter, ScalarData
|
||||
* This type should be consistent with the toJdbcType() method in converting
|
||||
* the type to the appropriate type for binding to preparedStatements.
|
||||
*/
|
||||
int getJdbcType();
|
||||
int jdbcType();
|
||||
|
||||
/**
|
||||
* Return the type that matches the bean property type.
|
||||
* <p>
|
||||
* This represents the 'logical' type rather than the JDBC type this maps to.
|
||||
*/
|
||||
Class<T> getType();
|
||||
Class<T> type();
|
||||
|
||||
/**
|
||||
* Return the type this maps to for JSON document stores.
|
||||
*/
|
||||
DocPropertyType docType();
|
||||
|
||||
/**
|
||||
* Read the value from the resultSet and convert if necessary to the logical
|
||||
@@ -101,12 +105,6 @@ public interface ScalarType<T> extends StringParser, StringFormatter, ScalarData
|
||||
@Override
|
||||
T read(DataReader reader) throws SQLException;
|
||||
|
||||
/**
|
||||
* Ignore the reading of this value. Typically, this means moving the index
|
||||
* position in the ResultSet.
|
||||
*/
|
||||
void loadIgnore(DataReader reader);
|
||||
|
||||
/**
|
||||
* Convert (if necessary) and bind the value to the preparedStatement.
|
||||
* <p>
|
||||
@@ -135,6 +133,14 @@ public interface ScalarType<T> extends StringParser, StringFormatter, ScalarData
|
||||
*/
|
||||
T toBeanType(Object value);
|
||||
|
||||
/**
|
||||
* Convert the string value to the appropriate java object.
|
||||
* <p>
|
||||
* Mostly used to support CSV, JSON and XML parsing.
|
||||
*/
|
||||
@Override
|
||||
T parse(String value);
|
||||
|
||||
/**
|
||||
* Convert the type into a string representation.
|
||||
*/
|
||||
@@ -147,34 +153,10 @@ public interface ScalarType<T> extends StringParser, StringFormatter, ScalarData
|
||||
* <p>
|
||||
* This is so that ScalarType also implements the StringFormatter interface.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
String format(Object value);
|
||||
|
||||
/**
|
||||
* Convert the string value to the appropriate java object.
|
||||
* <p>
|
||||
* Mostly used to support CSV, JSON and XML parsing.
|
||||
*/
|
||||
@Override
|
||||
T parse(String value);
|
||||
|
||||
/**
|
||||
* Return the type this maps to for JSON document stores.
|
||||
*/
|
||||
DocPropertyType getDocType();
|
||||
|
||||
/**
|
||||
* Return true if the type can accept long systemTimeMillis input.
|
||||
* <p>
|
||||
* This is used to determine if it is sensible to use the
|
||||
* {@link #convertFromMillis(long)} method.
|
||||
* <p>
|
||||
* This includes the Date, Calendar, sql Date, Time, Timestamp, JODA types
|
||||
* as well as Long, BigDecimal and String (although it generally is not
|
||||
* expected to parse systemTimeMillis to a String or BigDecimal).
|
||||
*/
|
||||
default boolean isDateTimeCapable() {
|
||||
return false;
|
||||
default String format(Object value) {
|
||||
return formatValue((T) value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -184,15 +166,6 @@ public interface ScalarType<T> extends StringParser, StringFormatter, ScalarData
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the systemTimeMillis into the appropriate java object.
|
||||
* <p>
|
||||
* For non dateTime types this will throw an exception.
|
||||
*/
|
||||
default T convertFromMillis(long dateTime) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the value from binary input.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package io.ebean.core.type;
|
||||
|
||||
/**
|
||||
* Base ScalarType object.
|
||||
*/
|
||||
public abstract class ScalarTypeBase<T> implements ScalarType<T> {
|
||||
|
||||
protected final Class<T> type;
|
||||
protected final boolean jdbcNative;
|
||||
protected final int jdbcType;
|
||||
|
||||
public ScalarTypeBase(Class<T> type, boolean jdbcNative, int jdbcType) {
|
||||
this.type = type;
|
||||
this.jdbcNative = jdbcNative;
|
||||
this.jdbcType = jdbcType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean jdbcNative() {
|
||||
return jdbcNative;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int jdbcType() {
|
||||
return jdbcType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<T> type() {
|
||||
return type;
|
||||
}
|
||||
|
||||
}
|
||||
+20
-33
@@ -1,4 +1,4 @@
|
||||
package io.ebeaninternal.server.type;
|
||||
package io.ebean.core.type;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
@@ -7,6 +7,7 @@ import io.ebean.config.JsonConfig;
|
||||
import io.ebean.core.type.DataBinder;
|
||||
import io.ebean.core.type.DataReader;
|
||||
import io.ebean.core.type.DocPropertyType;
|
||||
import io.ebean.core.type.ScalarTypeBase;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
@@ -18,15 +19,20 @@ import java.sql.Types;
|
||||
/**
|
||||
* Base class for Date types.
|
||||
*/
|
||||
abstract class ScalarTypeBaseDate<T> extends ScalarTypeBase<T> {
|
||||
public abstract class ScalarTypeBaseDate<T> extends ScalarTypeBase<T> {
|
||||
|
||||
protected final JsonConfig.Date mode;
|
||||
|
||||
ScalarTypeBaseDate(JsonConfig.Date mode, Class<T> type, boolean jdbcNative, int jdbcType) {
|
||||
public ScalarTypeBaseDate(JsonConfig.Date mode, Class<T> type, boolean jdbcNative, int jdbcType) {
|
||||
super(type, jdbcNative, jdbcType);
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the value to ISO8601 format.
|
||||
*/
|
||||
protected abstract String toIsoFormat(T value);
|
||||
|
||||
/**
|
||||
* Convert the target value to millis.
|
||||
*/
|
||||
@@ -53,38 +59,27 @@ abstract class ScalarTypeBaseDate<T> extends ScalarTypeBase<T> {
|
||||
|
||||
@Override
|
||||
public T read(DataReader reader) throws SQLException {
|
||||
Date ts = reader.getDate();
|
||||
return ts == null ? null : convertFromDate(ts);
|
||||
final Date date = reader.getDate();
|
||||
return date == null ? null : convertFromDate(date);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String formatValue(T t) {
|
||||
Date date = convertToDate(t);
|
||||
// format all dates into epoch millis
|
||||
long epochMillis = date.getTime();
|
||||
return Long.toString(epochMillis);
|
||||
public String formatValue(T value) {
|
||||
final Date date = convertToDate(value);
|
||||
return Long.toString(date.getTime());
|
||||
}
|
||||
|
||||
@Override
|
||||
public T parse(String value) {
|
||||
try {
|
||||
long epochMillis = Long.parseLong(value);
|
||||
return convertFromDate(new Date(epochMillis));
|
||||
return convertFromDate(new Date(Long.parseLong(value)));
|
||||
} catch (NumberFormatException e) {
|
||||
Date date = Date.valueOf(value);
|
||||
return convertFromDate(date);
|
||||
return convertFromDate(Date.valueOf(value));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public T convertFromMillis(long systemTimeMillis) {
|
||||
Date ts = new Date(systemTimeMillis);
|
||||
return convertFromDate(ts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDateTimeCapable() {
|
||||
return true;
|
||||
return convertFromDate(new Date(systemTimeMillis));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -105,13 +100,8 @@ abstract class ScalarTypeBaseDate<T> extends ScalarTypeBase<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the value to ISO8601 format.
|
||||
*/
|
||||
protected abstract String toIsoFormat(T value);
|
||||
|
||||
@Override
|
||||
public DocPropertyType getDocType() {
|
||||
public DocPropertyType docType() {
|
||||
return DocPropertyType.DATE;
|
||||
}
|
||||
|
||||
@@ -120,9 +110,7 @@ abstract class ScalarTypeBaseDate<T> extends ScalarTypeBase<T> {
|
||||
if (!dataInput.readBoolean()) {
|
||||
return null;
|
||||
} else {
|
||||
long val = dataInput.readLong();
|
||||
Date date = new Date(val);
|
||||
return convertFromDate(date);
|
||||
return convertFromDate(new Date(dataInput.readLong()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,8 +120,7 @@ abstract class ScalarTypeBaseDate<T> extends ScalarTypeBase<T> {
|
||||
dataOutput.writeBoolean(false);
|
||||
} else {
|
||||
dataOutput.writeBoolean(true);
|
||||
Date date = convertToDate(value);
|
||||
dataOutput.writeLong(date.getTime());
|
||||
dataOutput.writeLong(convertToDate(value).getTime());
|
||||
}
|
||||
}
|
||||
|
||||
+7
-18
@@ -1,11 +1,8 @@
|
||||
package io.ebeaninternal.server.type;
|
||||
package io.ebean.core.type;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import io.ebean.config.JsonConfig;
|
||||
import io.ebean.core.type.DataBinder;
|
||||
import io.ebean.core.type.DataReader;
|
||||
import io.ebean.core.type.DocPropertyType;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
@@ -16,16 +13,14 @@ import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.time.Instant;
|
||||
|
||||
import static io.ebeaninternal.server.type.IsoJsonDateTimeParser.parseIso;
|
||||
|
||||
/**
|
||||
* Base type for DateTime types.
|
||||
*/
|
||||
abstract class ScalarTypeBaseDateTime<T> extends ScalarTypeBase<T> {
|
||||
public abstract class ScalarTypeBaseDateTime<T> extends ScalarTypeBase<T> {
|
||||
|
||||
protected final JsonConfig.DateTime mode;
|
||||
|
||||
ScalarTypeBaseDateTime(JsonConfig.DateTime mode, Class<T> type, boolean jdbcNative, int jdbcType) {
|
||||
public ScalarTypeBaseDateTime(JsonConfig.DateTime mode, Class<T> type, boolean jdbcNative, int jdbcType) {
|
||||
super(type, jdbcNative, jdbcType);
|
||||
this.mode = mode;
|
||||
}
|
||||
@@ -53,7 +48,6 @@ abstract class ScalarTypeBaseDateTime<T> extends ScalarTypeBase<T> {
|
||||
/**
|
||||
* Convert from epoch millis to the value.
|
||||
*/
|
||||
@Override
|
||||
public abstract T convertFromMillis(long systemTimeMillis);
|
||||
|
||||
/**
|
||||
@@ -75,7 +69,7 @@ abstract class ScalarTypeBaseDateTime<T> extends ScalarTypeBase<T> {
|
||||
* Convert the value to ISO8601 format.
|
||||
*/
|
||||
protected T fromJsonISO8601(String value) {
|
||||
return convertFromInstant(parseIso(value));
|
||||
return convertFromInstant(ScalarTypeUtils.parseInstant(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -101,7 +95,7 @@ abstract class ScalarTypeBaseDateTime<T> extends ScalarTypeBase<T> {
|
||||
* Helper method that given epoch seconds and nanos return a JSON nanos formatted string.
|
||||
*/
|
||||
protected String toJsonNanos(long epochSecs, int nanos) {
|
||||
return DecimalUtils.toDecimal(epochSecs, nanos);
|
||||
return ScalarTypeUtils.toDecimal(epochSecs, nanos);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -112,7 +106,7 @@ abstract class ScalarTypeBaseDateTime<T> extends ScalarTypeBase<T> {
|
||||
}
|
||||
case VALUE_NUMBER_FLOAT: {
|
||||
BigDecimal value = parser.getDecimalValue();
|
||||
Timestamp timestamp = DecimalUtils.toTimestamp(value);
|
||||
Timestamp timestamp = ScalarTypeUtils.toTimestamp(value);
|
||||
return convertFromTimestamp(timestamp);
|
||||
}
|
||||
default: {
|
||||
@@ -139,7 +133,7 @@ abstract class ScalarTypeBaseDateTime<T> extends ScalarTypeBase<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public DocPropertyType getDocType() {
|
||||
public DocPropertyType docType() {
|
||||
return DocPropertyType.DATETIME;
|
||||
}
|
||||
|
||||
@@ -160,11 +154,6 @@ abstract class ScalarTypeBaseDateTime<T> extends ScalarTypeBase<T> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDateTimeCapable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T readData(DataInput dataInput) throws IOException {
|
||||
if (!dataInput.readBoolean()) {
|
||||
+7
-16
@@ -1,11 +1,7 @@
|
||||
package io.ebeaninternal.server.type;
|
||||
package io.ebean.core.type;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import io.ebean.core.type.DataBinder;
|
||||
import io.ebean.core.type.DataReader;
|
||||
import io.ebean.core.type.DocPropertyType;
|
||||
import io.ebean.text.TextException;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
@@ -17,13 +13,13 @@ import java.sql.Types;
|
||||
* Base ScalarType for types which converts to and from a VARCHAR database
|
||||
* column.
|
||||
*/
|
||||
abstract class ScalarTypeBaseVarchar<T> extends ScalarTypeBase<T> {
|
||||
public abstract class ScalarTypeBaseVarchar<T> extends ScalarTypeBase<T> {
|
||||
|
||||
ScalarTypeBaseVarchar(Class<T> type) {
|
||||
public ScalarTypeBaseVarchar(Class<T> type) {
|
||||
super(type, false, Types.VARCHAR);
|
||||
}
|
||||
|
||||
ScalarTypeBaseVarchar(Class<T> type, boolean jdbcNative, int jdbcType) {
|
||||
public ScalarTypeBaseVarchar(Class<T> type, boolean jdbcNative, int jdbcType) {
|
||||
super(type, jdbcNative, jdbcType);
|
||||
}
|
||||
|
||||
@@ -88,12 +84,6 @@ abstract class ScalarTypeBaseVarchar<T> extends ScalarTypeBase<T> {
|
||||
return format(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public String format(Object value) {
|
||||
return formatValue((T) value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T readData(DataInput dataInput) throws IOException {
|
||||
if (!dataInput.readBoolean()) {
|
||||
@@ -108,7 +98,8 @@ abstract class ScalarTypeBaseVarchar<T> extends ScalarTypeBase<T> {
|
||||
if (value == null) {
|
||||
dataOutput.writeBoolean(false);
|
||||
} else {
|
||||
ScalarHelp.writeUTF(dataOutput, convertToDbString(value));
|
||||
dataOutput.writeBoolean(true);
|
||||
dataOutput.writeUTF(convertToDbString(value));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,7 +114,7 @@ abstract class ScalarTypeBaseVarchar<T> extends ScalarTypeBase<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public DocPropertyType getDocType() {
|
||||
public DocPropertyType docType() {
|
||||
return DocPropertyType.TEXT;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package io.ebean.core.type;
|
||||
|
||||
import io.avaje.lang.Nullable;
|
||||
|
||||
/**
|
||||
* A ScalarType that has variations based on the mapped JDBC type (like VARCHAR, CLOB, JSON etc).
|
||||
*/
|
||||
public interface ScalarTypeSet<T> {
|
||||
|
||||
/**
|
||||
* The property type these scalar types map to.
|
||||
*/
|
||||
Class<?> type();
|
||||
|
||||
/**
|
||||
* Return a default ScalarType to use when no other annotations like {@code @DbJson} are present.
|
||||
*/
|
||||
@Nullable
|
||||
ScalarType<?> defaultType();
|
||||
|
||||
/**
|
||||
* Return the scalarType to use for the given jdbc type.
|
||||
* <p>
|
||||
* For example VARCHAR, CLOB, JSON etc.
|
||||
*/
|
||||
ScalarType<T> forType(int jdbcType);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package io.ebean.core.type;
|
||||
|
||||
import io.avaje.lang.Nullable;
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
|
||||
/**
|
||||
* Factory to create ScalarTypeSet.
|
||||
*/
|
||||
public interface ScalarTypeSetFactory {
|
||||
|
||||
/**
|
||||
* Create the ScalarTypeSet given the config and optional objectMapper.
|
||||
*/
|
||||
@Nullable
|
||||
ScalarTypeSet<?> createTypeSet(DatabaseConfig config, @Nullable Object objectMapper);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
package io.ebean.core.type;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeFormatterBuilder;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Utilities to aid in the translation of decimal types to/from multiple parts.
|
||||
*
|
||||
* @author Nick Williams
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public final class ScalarTypeUtils {
|
||||
|
||||
private static final char[] ZEROES = new char[]{'0', '0', '0', '0', '0', '0', '0', '0', '0'};
|
||||
|
||||
private static final BigDecimal ONE_BILLION = new BigDecimal(1000000000L);
|
||||
|
||||
private static final DateTimeFormatter ISO_MILLIS = new DateTimeFormatterBuilder()
|
||||
.parseCaseInsensitive()
|
||||
.appendInstant(3)
|
||||
.toFormatter();
|
||||
|
||||
/**
|
||||
* Parse using ISO8601.
|
||||
*/
|
||||
public static Instant parseInstant(String jsonDateTime) {
|
||||
return Instant.parse(jsonDateTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format using ISO8601.
|
||||
*/
|
||||
public static String formatInstant(Instant value) {
|
||||
return ISO_MILLIS.format(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert decimal to duration with nanos.
|
||||
*/
|
||||
public static Duration toDuration(BigDecimal value) {
|
||||
long seconds = value.longValue();
|
||||
int nanoseconds = extractNanosecondDecimal(value, seconds);
|
||||
return Duration.ofSeconds(seconds, nanoseconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert duration to decimal with nanos.
|
||||
*/
|
||||
public static BigDecimal toDecimal(Duration instant) {
|
||||
return new BigDecimal(toDecimal(instant.getSeconds(), instant.getNano()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert decimal to timestamp with nanos.
|
||||
*/
|
||||
public static Timestamp toTimestamp(BigDecimal value) {
|
||||
long seconds = value.longValue();
|
||||
int nanoseconds = extractNanosecondDecimal(value, seconds);
|
||||
Timestamp ts = new Timestamp(seconds * 1000);
|
||||
ts.setNanos(nanoseconds);
|
||||
return ts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert timestamp to decimal with nanos.
|
||||
*/
|
||||
public static BigDecimal toDecimal(Timestamp instant) {
|
||||
long millis = instant.getTime();
|
||||
long secs = millis / 1000;
|
||||
return new BigDecimal(toDecimal(secs, instant.getNanos()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to decimal string with nanos.
|
||||
*/
|
||||
public static String toDecimal(long seconds, int nanoseconds) {
|
||||
StringBuilder string = new StringBuilder(Integer.toString(nanoseconds));
|
||||
if (string.length() < 9)
|
||||
string.insert(0, ZEROES, 0, 9 - string.length());
|
||||
return seconds + "." + string;
|
||||
}
|
||||
|
||||
private static int extractNanosecondDecimal(BigDecimal value, long integer) {
|
||||
return value.subtract(new BigDecimal(integer)).multiply(ONE_BILLION).intValue();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert from byte[] to UUID.
|
||||
*/
|
||||
public static UUID uuidFromBytes(byte[] bytes, boolean optimized) {
|
||||
int usableBytes = Math.min(bytes.length, 16);
|
||||
|
||||
// Need exactly 16 bytes - pad the input if not enough bytes are provided
|
||||
// Use provided bytes in the least significant position; if more than 16 bytes are given,
|
||||
// then use the first 16 bytes from the array;
|
||||
byte[] barr = new byte[16];
|
||||
for (int i = 15, j = usableBytes - 1; j >= 0; i--, j--) {
|
||||
barr[i] = bytes[j];
|
||||
}
|
||||
|
||||
long msb;
|
||||
if (optimized) {
|
||||
msb = ((long)barr[4] << 56) + // XXXXXXXX-____-____-...
|
||||
((long)(barr[5] & 255) << 48) + // -> put at end 4..7 of buf
|
||||
((long)(barr[6] & 255) << 40) +
|
||||
((long)(barr[7] & 255) << 32) +
|
||||
((long)(barr[2] & 255) << 24) + // ________-XXXX-____-...
|
||||
((barr[3] & 255) << 16) + // put at 2..3 in buf
|
||||
((barr[0] & 255) << 8) + // ________-____-XXXX-...
|
||||
((barr[1] & 255) << 0); // put at 0..1 in buf
|
||||
} else {
|
||||
msb = ((long)barr[0] << 56) + // XXXXXXXX-____-____-...
|
||||
((long)(barr[1] & 255) << 48) +
|
||||
((long)(barr[2] & 255) << 40) +
|
||||
((long)(barr[3] & 255) << 32) +
|
||||
((long)(barr[4] & 255) << 24) + // ________-XXXX-____-...
|
||||
((barr[5] & 255) << 16) +
|
||||
((barr[6] & 255) << 8) + // ________-____-XXXX-...
|
||||
((barr[7] & 255) << 0);
|
||||
}
|
||||
long lsb = ((long)barr[8] << 56) +
|
||||
((long)(barr[9] & 255) << 48) +
|
||||
((long)(barr[10] & 255) << 40) +
|
||||
((long)(barr[11] & 255) << 32) +
|
||||
((long)(barr[12] & 255) << 24) +
|
||||
((barr[13] & 255) << 16) +
|
||||
((barr[14] & 255) << 8) +
|
||||
((barr[15] & 255) << 0);
|
||||
|
||||
return new UUID(msb, lsb);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert from UUID to byte[].
|
||||
*/
|
||||
public static byte[] uuidToBytes(UUID uuid, boolean optimized) {
|
||||
byte[] ret = new byte[16];
|
||||
long l = uuid.getMostSignificantBits();
|
||||
|
||||
if (optimized) {
|
||||
ret[0] = (byte) (l >>> 8); // was 6/7
|
||||
ret[1] = (byte) (l >>> 0);
|
||||
|
||||
ret[2] = (byte) (l >>> 24); // was 4/5
|
||||
ret[3] = (byte) (l >>> 16);
|
||||
|
||||
ret[4] = (byte) (l >>> 56); // was 0..3
|
||||
ret[5] = (byte) (l >>> 48);
|
||||
ret[6] = (byte) (l >>> 40);
|
||||
ret[7] = (byte) (l >>> 32);
|
||||
} else {
|
||||
ret[0] = (byte) (l >>> 56);
|
||||
ret[1] = (byte) (l >>> 48);
|
||||
ret[2] = (byte) (l >>> 40);
|
||||
ret[3] = (byte) (l >>> 32);
|
||||
ret[4] = (byte) (l >>> 24);
|
||||
ret[5] = (byte) (l >>> 16);
|
||||
ret[6] = (byte) (l >>> 8);
|
||||
ret[7] = (byte) (l >>> 0);
|
||||
}
|
||||
l = uuid.getLeastSignificantBits();
|
||||
ret[8] = (byte) (l >>> 56);
|
||||
ret[9] = (byte) (l >>> 48);
|
||||
ret[10] = (byte) (l >>> 40);
|
||||
ret[11] = (byte) (l >>> 32);
|
||||
ret[12] = (byte) (l >>> 24);
|
||||
ret[13] = (byte) (l >>> 16);
|
||||
ret[14] = (byte) (l >>> 8);
|
||||
ret[15] = (byte) (l >>> 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ module io.ebean.core.type {
|
||||
|
||||
requires transitive java.sql;
|
||||
requires transitive io.ebean.api;
|
||||
requires static org.postgresql.jdbc;
|
||||
|
||||
requires static com.fasterxml.jackson.core;
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package io.ebean.core.type;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
class DecimalUtilsTest {
|
||||
|
||||
@Test
|
||||
void testToDecimal() {
|
||||
Instant now = Instant.now();
|
||||
Timestamp sourceTimestamp = Timestamp.from(now);
|
||||
|
||||
BigDecimal decimal = ScalarTypeUtils.toDecimal(sourceTimestamp);
|
||||
Timestamp timestamp = ScalarTypeUtils.toTimestamp(decimal);
|
||||
|
||||
assertEquals(now, timestamp.toInstant());
|
||||
assertEquals(sourceTimestamp, timestamp);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDuration() {
|
||||
Duration duration = Duration.ofSeconds(323, 1500000);
|
||||
|
||||
BigDecimal bigDecimal = ScalarTypeUtils.toDecimal(duration);
|
||||
Duration duration1 = ScalarTypeUtils.toDuration(bigDecimal);
|
||||
|
||||
assertEquals(duration, duration1);
|
||||
assertEquals("PT5M23.0015S", duration1.toString());
|
||||
}
|
||||
}
|
||||
+11
-12
@@ -1,5 +1,4 @@
|
||||
package io.ebeaninternal.server.type;
|
||||
|
||||
package io.ebean.core.type;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -7,43 +6,43 @@ import java.time.Instant;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class IsoJsonDateTimeParserTest {
|
||||
class IsoJsonDateTimeParserTest {
|
||||
|
||||
private IsoJsonDateTimeParser parser = new IsoJsonDateTimeParser();
|
||||
private ScalarTypeUtils parser = new ScalarTypeUtils();
|
||||
|
||||
@Test
|
||||
public void parseFormat_when_hasMillis() {
|
||||
void parseFormat_when_hasMillis() {
|
||||
parseAndFormat("2016-02-28T20:39:00.123Z", "2016-02-28T20:39:00.123Z");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseFormat_when_noMillis() {
|
||||
void parseFormat_when_noMillis() {
|
||||
parseAndFormat("2016-02-28T20:39:00Z", "2016-02-28T20:39:00.000Z");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseFormat_when_millis_1dp() {
|
||||
void parseFormat_when_millis_1dp() {
|
||||
parseAndFormat("2016-02-28T20:39:00.0Z", "2016-02-28T20:39:00.000Z");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseFormat_when_millis_2dp() {
|
||||
void parseFormat_when_millis_2dp() {
|
||||
parseAndFormat("2016-02-28T20:39:00.00Z", "2016-02-28T20:39:00.000Z");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseFormat_when_millis_3dp() {
|
||||
void parseFormat_when_millis_3dp() {
|
||||
parseAndFormat("2016-02-28T20:39:00.000Z", "2016-02-28T20:39:00.000Z");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseFormat_when_millis_3dp_2() {
|
||||
void parseFormat_when_millis_3dp_2() {
|
||||
parseAndFormat("2016-02-28T20:39:32.999000Z", "2016-02-28T20:39:32.999Z");
|
||||
}
|
||||
|
||||
private void parseAndFormat(String input, String expected) {
|
||||
Instant timestamp = parser.parseIso(input);
|
||||
String format = parser.formatIso(timestamp);
|
||||
Instant timestamp = parser.parseInstant(input);
|
||||
String format = parser.formatInstant(timestamp);
|
||||
assertThat(format).isEqualTo(expected);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package io.ebean.core.type;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
class ScalarTypeUtilsUuidBytesTest {
|
||||
|
||||
@Test
|
||||
void testConversion() {
|
||||
UUID id = UUID.randomUUID();
|
||||
|
||||
byte[] bytes = ScalarTypeUtils.uuidToBytes(id, false);
|
||||
assertEquals(16, bytes.length);
|
||||
|
||||
UUID id2 = ScalarTypeUtils.uuidFromBytes(bytes, false);
|
||||
assertEquals(id, id2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConversionOptimized() {
|
||||
UUID id = UUID.randomUUID();
|
||||
|
||||
byte[] bytes = ScalarTypeUtils.uuidToBytes(id, true);
|
||||
assertEquals(16, bytes.length);
|
||||
|
||||
UUID id2 = ScalarTypeUtils.uuidFromBytes(bytes, true);
|
||||
assertEquals(id, id2);
|
||||
}
|
||||
|
||||
}
|
||||
+14
-15
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>ebean-core</artifactId>
|
||||
@@ -15,10 +15,15 @@
|
||||
|
||||
<scm>
|
||||
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
|
||||
<tag>HEAD</tag>
|
||||
<tag>ebean-parent-13.11.4</tag>
|
||||
</scm>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
@@ -38,22 +43,16 @@
|
||||
<version>${ebean-migration-auto.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.7.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core-type</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-externalmapping-api</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -106,7 +105,7 @@
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
<version>2.9.7</version>
|
||||
<version>2.11.1</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
@@ -136,7 +135,7 @@
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>42.4.1</version>
|
||||
<version>42.5.1</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
@@ -144,21 +143,21 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-h2</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-sqlserver</artifactId>
|
||||
<version>13.7.0</version>
|
||||
<version>13.11.4</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -228,10 +228,9 @@ public final class BindParams implements Serializable {
|
||||
/**
|
||||
* Set a named In parameter that is multi-valued.
|
||||
*/
|
||||
public Param setArrayParameter(String name, Collection<?> value) {
|
||||
public void setArrayParameter(String name, Collection<?> value) {
|
||||
Param p = getParam(name);
|
||||
p.setInValue(new MultiValueWrapper(value));
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,7 +9,7 @@ public interface CQueryPlanKey {
|
||||
* Used by read audit such that we can log read audit entries without the full sql
|
||||
* (which would make the read audit logs verbose).
|
||||
*/
|
||||
String getPartialKey();
|
||||
String partialKey();
|
||||
|
||||
/**
|
||||
* Return a query plan key taking into account persist cascading.
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package io.ebeaninternal.api;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import io.avaje.applog.AppLog;
|
||||
|
||||
/**
|
||||
* Common loggers used in ebean-core.
|
||||
*/
|
||||
public final class CoreLog {
|
||||
|
||||
public static final Logger log = LoggerFactory.getLogger("io.ebean.core");
|
||||
public static final Logger internal = LoggerFactory.getLogger("io.ebean.internal");
|
||||
public static final System.Logger log = AppLog.getLogger("io.ebean.core");
|
||||
public static final System.Logger internal = AppLog.getLogger("io.ebean.internal");
|
||||
public static final System.Logger markedAsDeleted = AppLog.getLogger("io.ebean.MarkedAsDeleted");
|
||||
}
|
||||
|
||||
@@ -6,10 +6,7 @@ import io.ebeaninternal.api.SpiQuery.Mode;
|
||||
import io.ebeaninternal.server.core.OrmQueryRequest;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Request for loading ManyToOne and OneToOne relationships.
|
||||
@@ -103,7 +100,7 @@ public final class LoadBeanRequest extends LoadRequest {
|
||||
/**
|
||||
* Load the beans into the L2 cache if that is requested and check for load failures due to deletes.
|
||||
*/
|
||||
public void postLoad(List<?> list) {
|
||||
public Result postLoad(List<?> list) {
|
||||
Set<Object> loadedIds = new HashSet<>();
|
||||
BeanDescriptor<?> desc = loadBuffer.descriptor();
|
||||
// collect Ids and maybe load bean cache
|
||||
@@ -114,6 +111,7 @@ public final class LoadBeanRequest extends LoadRequest {
|
||||
desc.cacheBeanPutAll(list);
|
||||
}
|
||||
if (lazyLoadProperty != null) {
|
||||
Set<Object> missedIds = new HashSet<>();
|
||||
for (EntityBeanIntercept ebi : batch) {
|
||||
// check if the underlying row in DB was deleted. Mark the bean as 'failed' if
|
||||
// necessary but allow processing to continue until it is accessed by client code
|
||||
@@ -121,8 +119,36 @@ public final class LoadBeanRequest extends LoadRequest {
|
||||
if (!loadedIds.contains(id)) {
|
||||
// assume this is logically deleted (hence not found)
|
||||
desc.markAsDeleted(ebi.getOwner());
|
||||
missedIds.add(id);
|
||||
}
|
||||
}
|
||||
return new Result(loadedIds, missedIds);
|
||||
}
|
||||
return EMPTY_RESULT;
|
||||
}
|
||||
|
||||
static final Result EMPTY_RESULT = new Result(Collections.emptySet(),Collections.emptySet());
|
||||
|
||||
public static class Result {
|
||||
|
||||
private final Set<Object> loadedIds;
|
||||
private final Set<Object> missedIds;
|
||||
|
||||
Result(Set<Object> loadedIds, Set<Object> missedIds) {
|
||||
this.loadedIds = loadedIds;
|
||||
this.missedIds = missedIds;
|
||||
}
|
||||
|
||||
public boolean markedDeleted() {
|
||||
return !missedIds.isEmpty();
|
||||
}
|
||||
|
||||
public Set<Object> missedIds() {
|
||||
return missedIds;
|
||||
}
|
||||
|
||||
public Set<Object> loadedIds() {
|
||||
return loadedIds;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,17 +7,18 @@ import io.ebeaninternal.server.core.BindPadding;
|
||||
import io.ebeaninternal.server.core.OrmQueryRequest;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import io.ebeaninternal.server.deploy.BeanPropertyAssocMany;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static java.lang.System.Logger.Level.DEBUG;
|
||||
|
||||
/**
|
||||
* Request for loading Associated Many Beans.
|
||||
*/
|
||||
public final class LoadManyRequest extends LoadRequest {
|
||||
|
||||
private static final Logger log = CoreLog.log;
|
||||
private static final System.Logger log = CoreLog.log;
|
||||
|
||||
private final List<BeanCollection<?>> batch;
|
||||
private final LoadManyBuffer loadContext;
|
||||
@@ -113,13 +114,13 @@ public final class LoadManyRequest extends LoadRequest {
|
||||
// in the +query or +lazy load due to no rows (predicates)
|
||||
for (BeanCollection<?> bc : batch) {
|
||||
if (bc.checkEmptyLazyLoad()) {
|
||||
if (log.isDebugEnabled()) {
|
||||
if (log.isLoggable(DEBUG)) {
|
||||
EntityBean ownerBean = bc.getOwnerBean();
|
||||
Object parentId = desc.getId(ownerBean);
|
||||
log.debug("BeanCollection after lazy load was empty. type:" + ownerBean.getClass().getName() + " id:" + parentId + " owner:" + 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.getId(bc.getOwnerBean()));
|
||||
desc.cacheManyPropPut(many, bc, desc.cacheKeyForBean(bc.getOwnerBean()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,6 @@ public final class ManyWhereJoins implements Serializable {
|
||||
* Add a many where join.
|
||||
*/
|
||||
public void add(ElPropertyDeploy elProp) {
|
||||
|
||||
String join = elProp.elPrefix();
|
||||
BeanProperty p = elProp.beanProperty();
|
||||
if (p instanceof BeanPropertyAssocMany<?>) {
|
||||
@@ -111,7 +110,6 @@ public final class ManyWhereJoins implements Serializable {
|
||||
* Return the set of property names for the many where joins.
|
||||
*/
|
||||
public TreeSet<String> getPropertyNames() {
|
||||
|
||||
TreeSet<String> propertyNames = new TreeSet<>();
|
||||
for (PropertyJoin join : joins.values()) {
|
||||
propertyNames.add(join.getProperty());
|
||||
|
||||
@@ -142,7 +142,9 @@ public final class NaturalKeyQueryData<T> {
|
||||
*/
|
||||
private boolean matchProperties() {
|
||||
if (naturalKey.isSingleProperty()) {
|
||||
naturalKey.matchSingleProperty((inProperty != null) ? inProperty : eqList.get(0).property);
|
||||
if (naturalKey.matchSingleProperty((inProperty != null) ? inProperty : eqList.get(0).property)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// multiple properties case
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package io.ebeaninternal.api;
|
||||
|
||||
import io.ebeaninternal.server.type.bindcapture.BindCapture;
|
||||
import io.ebeaninternal.server.bind.capture.BindCapture;
|
||||
|
||||
final class NoopQueryBindCapture implements SpiQueryBindCapture {
|
||||
|
||||
|
||||
@@ -45,15 +45,14 @@ public final class ScopeTrans {
|
||||
* Flag set when nested commit has occurred.
|
||||
*/
|
||||
private boolean nestedCommit;
|
||||
private boolean nestedUseSavepoint;
|
||||
|
||||
public ScopeTrans(boolean rollbackOnChecked, boolean created, SpiTransaction transaction, TxScope txScope) {
|
||||
|
||||
this.rollbackOnChecked = rollbackOnChecked;
|
||||
this.created = created;
|
||||
this.transaction = transaction;
|
||||
this.noRollbackFor = txScope.getNoRollbackFor();
|
||||
this.rollbackFor = txScope.getRollbackFor();
|
||||
|
||||
if (transaction != null) {
|
||||
if (!created && txScope.isBatchSet() || txScope.isBatchOnCascadeSet() || txScope.isBatchSizeSet()) {
|
||||
restoreBatch = transaction.isBatchMode();
|
||||
@@ -87,13 +86,21 @@ public final class ScopeTrans {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ScopeTrans[" + transaction + "]";
|
||||
return "ScopeTrans " + transaction;
|
||||
}
|
||||
|
||||
void setNestedUseSavepoint() {
|
||||
nestedUseSavepoint = true;
|
||||
}
|
||||
|
||||
boolean isNestedUseSavepoint() {
|
||||
return nestedUseSavepoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current/active transaction.
|
||||
*/
|
||||
protected SpiTransaction getTransaction() {
|
||||
SpiTransaction getTransaction() {
|
||||
return transaction;
|
||||
}
|
||||
|
||||
@@ -101,7 +108,6 @@ public final class ScopeTrans {
|
||||
* Complete the transaction from enhanced transactional. Try to commit.
|
||||
*/
|
||||
void complete(Object returnOrThrowable, int opCode) {
|
||||
|
||||
if (opCode == OPCODE_ATHROW) {
|
||||
// exited with a Throwable
|
||||
caughtThrowable((Throwable) returnOrThrowable);
|
||||
@@ -124,7 +130,7 @@ public final class ScopeTrans {
|
||||
}
|
||||
}
|
||||
|
||||
protected void commitTransaction() {
|
||||
void commitTransaction() {
|
||||
if (created) {
|
||||
transaction.commit();
|
||||
} else {
|
||||
@@ -168,14 +174,13 @@ public final class ScopeTrans {
|
||||
* Returns the exception and this should be thrown by the calling code.
|
||||
*/
|
||||
public <T extends Throwable> T caughtThrowable(T e) {
|
||||
|
||||
if (isRollbackThrowable(e)) {
|
||||
rollback(e);
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
protected void rollback(Throwable e) {
|
||||
void rollback(Throwable e) {
|
||||
if (transaction != null && transaction.isActive()) {
|
||||
// transaction is null for NOT_SUPPORTED and sometimes SUPPORTS
|
||||
// and Inactive (already rolled back) if nested REQUIRED
|
||||
@@ -188,21 +193,17 @@ public final class ScopeTrans {
|
||||
* Return true if this throwable should cause a rollback to occur.
|
||||
*/
|
||||
private boolean isRollbackThrowable(Throwable e) {
|
||||
|
||||
if (e instanceof Error) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (noRollbackFor != null) {
|
||||
for (Class<? extends Throwable> aNoRollbackFor : noRollbackFor) {
|
||||
if (aNoRollbackFor.equals(e.getClass())) {
|
||||
|
||||
// explicit no rollback for this one
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rollbackFor != null) {
|
||||
for (Class<? extends Throwable> aRollbackFor : rollbackFor) {
|
||||
if (aRollbackFor.equals(e.getClass())) {
|
||||
@@ -211,7 +212,6 @@ public final class ScopeTrans {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// checked exceptions...
|
||||
// EJB defaults this to false which is not intuitive IMO
|
||||
// Ebean makes this configurable (default to true)
|
||||
|
||||
@@ -7,7 +7,7 @@ import javax.persistence.PersistenceException;
|
||||
|
||||
/**
|
||||
* Manage scoped (typically thread local) transactions.
|
||||
*
|
||||
* <p>
|
||||
* These can be nested and internally they are pushed and popped from a stack.
|
||||
*/
|
||||
public final class ScopedTransaction extends SpiTransactionProxy {
|
||||
@@ -30,16 +30,29 @@ public final class ScopedTransaction extends SpiTransactionProxy {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ScopedTransaction[" + current + "]";
|
||||
return "ScopedTransaction " + current;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNestedUseSavepoint() {
|
||||
current.setNestedUseSavepoint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNestedUseSavepoint() {
|
||||
return current.isNestedUseSavepoint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Push the scope transaction.
|
||||
*/
|
||||
public void push(ScopeTrans scopeTrans) {
|
||||
|
||||
if (current != null) {
|
||||
stack.push(current);
|
||||
if (current.isNestedUseSavepoint()) {
|
||||
// child scope 'inherits' nestedUseSavepoint
|
||||
scopeTrans.setNestedUseSavepoint();
|
||||
}
|
||||
}
|
||||
current = scopeTrans;
|
||||
transaction = scopeTrans.getTransaction();
|
||||
@@ -111,6 +124,11 @@ public final class ScopedTransaction extends SpiTransactionProxy {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollbackAndContinue() {
|
||||
transaction.rollbackAndContinue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws PersistenceException {
|
||||
try {
|
||||
|
||||
@@ -13,8 +13,8 @@ import java.io.IOException;
|
||||
*/
|
||||
public interface SpiExpression extends Expression {
|
||||
|
||||
static final String SQL_TRUE = "1=1";
|
||||
static final String SQL_FALSE = "1=0";
|
||||
String SQL_TRUE = "1=1";
|
||||
String SQL_FALSE = "1=0";
|
||||
|
||||
/**
|
||||
* Simplify nested expressions if possible.
|
||||
@@ -110,4 +110,11 @@ public interface SpiExpression extends Expression {
|
||||
* Apply property prefix when filterMany expressions included into main query.
|
||||
*/
|
||||
void prefixProperty(String path);
|
||||
|
||||
/**
|
||||
* Return a copy of the expression (as part of creating a query copy).
|
||||
*/
|
||||
default SpiExpression copy() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,14 +103,14 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
|
||||
COUNT(FIND_COUNT, "findCount"),
|
||||
|
||||
/**
|
||||
* A subquery used as part of an exists where clause.
|
||||
* A sub-query used as part of an exists where clause.
|
||||
*/
|
||||
SQ_EXISTS(FIND_SUBQUERY, "sqExists", false, false),
|
||||
|
||||
/**
|
||||
* A subquery used as part of an in where clause.
|
||||
* A sub-query expression used as part of where clause.
|
||||
*/
|
||||
SQ_IN(FIND_SUBQUERY, "sqIn", false, false),
|
||||
SQ_EX(FIND_SUBQUERY, "sqEx", false, false),
|
||||
|
||||
/**
|
||||
* Delete query.
|
||||
@@ -314,7 +314,7 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
|
||||
* Return true if select all properties was used to ensure the property
|
||||
* invoking a lazy load was included in the query.
|
||||
*/
|
||||
boolean selectAllForLazyLoadProperty();
|
||||
void selectAllForLazyLoadProperty();
|
||||
|
||||
/**
|
||||
* Set the select properties.
|
||||
@@ -759,6 +759,11 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
|
||||
*/
|
||||
BindParams getBindParams();
|
||||
|
||||
/**
|
||||
* Return the bind parameters ensuring it is initialised.
|
||||
*/
|
||||
BindParams initBindParams();
|
||||
|
||||
/**
|
||||
* Replace the query detail. This is used by the AutoTune feature to as a
|
||||
* fast way to set the query properties and joins.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package io.ebeaninternal.api;
|
||||
|
||||
import io.ebeaninternal.server.type.bindcapture.BindCapture;
|
||||
import io.ebeaninternal.server.bind.capture.BindCapture;
|
||||
|
||||
/**
|
||||
* Capture query bind values and with those actual database query plans.
|
||||
|
||||
@@ -10,27 +10,27 @@ public interface SpiQueryPlan {
|
||||
/**
|
||||
* The related entity bean type
|
||||
*/
|
||||
Class<?> getBeanType();
|
||||
Class<?> beanType();
|
||||
|
||||
/**
|
||||
* The plan name.
|
||||
*/
|
||||
String getName();
|
||||
String name();
|
||||
|
||||
/**
|
||||
* The hash of the sql.
|
||||
*/
|
||||
String getHash();
|
||||
String hash();
|
||||
|
||||
/**
|
||||
* The SQL for the query plan.
|
||||
*/
|
||||
String getSql();
|
||||
String sql();
|
||||
|
||||
/**
|
||||
* The related profile location.
|
||||
*/
|
||||
ProfileLocation getProfileLocation();
|
||||
ProfileLocation profileLocation();
|
||||
|
||||
/**
|
||||
* Initiate bind capture with the give threshold.
|
||||
|
||||
@@ -139,7 +139,7 @@ public final class TransactionEvent implements Serializable {
|
||||
|
||||
/**
|
||||
* Return the CacheChangeSet that we add cache notification messages to.
|
||||
*
|
||||
* <p>
|
||||
* We want to add to this change set as we process requests allowing the
|
||||
* PersistRequestBean to be garbage collected for large transactions.
|
||||
*/
|
||||
|
||||
@@ -2,7 +2,7 @@ package io.ebeaninternal.api;
|
||||
|
||||
/**
|
||||
* Event codes used in transaction profiling.
|
||||
*
|
||||
* <p>
|
||||
* These appear in verbose transaction profile logs.
|
||||
*/
|
||||
public interface TxnProfileEventCodes {
|
||||
|
||||
@@ -12,7 +12,7 @@ import java.util.Map;
|
||||
|
||||
public interface SpiJsonReader {
|
||||
|
||||
PersistenceContext getPersistenceContext();
|
||||
PersistenceContext persistenceContext();
|
||||
|
||||
SpiJsonReader forJson(JsonParser moreJson);
|
||||
|
||||
@@ -20,9 +20,9 @@ public interface SpiJsonReader {
|
||||
|
||||
Object persistenceContextPutIfAbsent(Object id, EntityBean bean, BeanDescriptor<?> beanDesc);
|
||||
|
||||
ObjectMapper getObjectMapper();
|
||||
ObjectMapper mapper();
|
||||
|
||||
JsonParser getParser();
|
||||
JsonParser parser();
|
||||
|
||||
JsonToken nextToken() throws IOException;
|
||||
|
||||
@@ -34,5 +34,5 @@ public interface SpiJsonReader {
|
||||
|
||||
Object readValueUsingObjectMapper(Class<?> propertyType) throws IOException;
|
||||
|
||||
boolean isIntercept();
|
||||
boolean intercept();
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ public interface SpiJsonWriter extends JsonWriter {
|
||||
/**
|
||||
* Return true if the value is a parent bean.
|
||||
*/
|
||||
boolean isParentBean(Object value);
|
||||
boolean parentBean(Object value);
|
||||
|
||||
/**
|
||||
* Start an assoc one path.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user