mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Compare commits
513
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08d241d946 | ||
|
|
1c24ebf6dc | ||
|
|
0ce39c73f1 | ||
|
|
82d6294dcb | ||
|
|
ba01103f48 | ||
|
|
3e14ec6a5a | ||
|
|
b9d5d35850 | ||
|
|
04adc35ccd | ||
|
|
bfc2b57df5 | ||
|
|
a5880fca97 | ||
|
|
8685f2056a | ||
|
|
2ac19bea1a | ||
|
|
9410f82f5a | ||
|
|
21382a52ed | ||
|
|
f871259f20 | ||
|
|
eb765056fd | ||
|
|
ddf3c753d6 | ||
|
|
4767aff046 | ||
|
|
75846edd97 | ||
|
|
f7c6745de1 | ||
|
|
f080f16e63 | ||
|
|
9135f87253 | ||
|
|
90ccf2d8b4 | ||
|
|
11409f8c09 | ||
|
|
fb472a0304 | ||
|
|
04c9007d22 | ||
|
|
8f75a04ad0 | ||
|
|
2236e4bfd7 | ||
|
|
6d1c3738de | ||
|
|
20160144f5 | ||
|
|
891166507d | ||
|
|
bce97b1063 | ||
|
|
c5b960c588 | ||
|
|
009b400ed3 | ||
|
|
b6ee6ade8c | ||
|
|
0891c067d5 | ||
|
|
7b3b32f0ff | ||
|
|
3878b02cff | ||
|
|
92995b807e | ||
|
|
907d36123d | ||
|
|
2db95f909d | ||
|
|
5213e8b653 | ||
|
|
2314fd267f | ||
|
|
b24f093bbb | ||
|
|
444c868124 | ||
|
|
81b16b8f73 | ||
|
|
850db70be3 | ||
|
|
ee81ee4d7c | ||
|
|
4cbeb282eb | ||
|
|
5278c010ba | ||
|
|
ea490a5ac3 | ||
|
|
e4390ed8a2 | ||
|
|
a23d9f7db8 | ||
|
|
b1704ff5dc | ||
|
|
c0d752b445 | ||
|
|
ef5ea59559 | ||
|
|
de42655bbd | ||
|
|
661230909c | ||
|
|
e9325a81f7 | ||
|
|
78b9066345 | ||
|
|
1959e01844 | ||
|
|
cf6179c86b | ||
|
|
168dacffa7 | ||
|
|
e0d322d80a | ||
|
|
1dd0f3cbf8 | ||
|
|
6961bf5787 | ||
|
|
a14288b06d | ||
|
|
171d1a19f4 | ||
|
|
cbaaad89ab | ||
|
|
413290a040 | ||
|
|
8feb100ac6 | ||
|
|
d236988035 | ||
|
|
df0d84424c | ||
|
|
fb30a15a5b | ||
|
|
3707d611b1 | ||
|
|
60aa720777 | ||
|
|
427152a894 | ||
|
|
3e43d544fb | ||
|
|
62b1da1be2 | ||
|
|
8b4eae2f91 | ||
|
|
4ed3a18b9d | ||
|
|
3c9d7e3127 | ||
|
|
a89744a7bd | ||
|
|
5962f14874 | ||
|
|
f161a38334 | ||
|
|
13f8da6b2e | ||
|
|
9ad14c5306 | ||
|
|
61ed4a5a74 | ||
|
|
275f2dbc98 | ||
|
|
521b6a36ef | ||
|
|
0a6c26e5d3 | ||
|
|
33416bffd0 | ||
|
|
4ce484f3f2 | ||
|
|
cacf033647 | ||
|
|
e3dba6bfe1 | ||
|
|
c0b6f291a1 | ||
|
|
9eab67d82e | ||
|
|
840cb2ee7b | ||
|
|
e0f171b638 | ||
|
|
2bb52a9581 | ||
|
|
f1cf94365c | ||
|
|
a894924e96 | ||
|
|
680a11a532 | ||
|
|
605150de5c | ||
|
|
5ff44703cf | ||
|
|
99175bf679 | ||
|
|
acff330b37 | ||
|
|
df63eeaa8c | ||
|
|
07aa39c5de | ||
|
|
c51a1b07a4 | ||
|
|
bb56725b12 | ||
|
|
099adcf6cd | ||
|
|
05be24b8b2 | ||
|
|
7d98355d39 | ||
|
|
56562915bf | ||
|
|
07f4ad2500 | ||
|
|
22e43f5fa7 | ||
|
|
3127bc2154 | ||
|
|
8aa1ed6676 | ||
|
|
8a0dea1218 | ||
|
|
1e266a1532 | ||
|
|
57cfd25eb5 | ||
|
|
2bcce2e648 | ||
|
|
f6e45a6999 | ||
|
|
fa3de7158e | ||
|
|
792785dabe | ||
|
|
d0cd74b400 | ||
|
|
71d762ab97 | ||
|
|
e00713aa29 | ||
|
|
d70a49e105 | ||
|
|
159a9a8e54 | ||
|
|
db027eb030 | ||
|
|
ec55b2f096 | ||
|
|
b854943a86 | ||
|
|
8a263d243c | ||
|
|
0a4f93adc5 | ||
|
|
ffb11019fa | ||
|
|
6fcac27dfe | ||
|
|
71295077a5 | ||
|
|
ddbad284ad | ||
|
|
1fcec429b0 | ||
|
|
c6062fe93e | ||
|
|
d8d35b7dd9 | ||
|
|
590cd07d67 | ||
|
|
5cd74bc468 | ||
|
|
502b20be67 | ||
|
|
b3077d44f6 | ||
|
|
d4b35cb445 | ||
|
|
91e7540a39 | ||
|
|
06bd60aaf7 | ||
|
|
3db2a69312 | ||
|
|
5a983b9e0d | ||
|
|
ab7b34779a | ||
|
|
c7aad6078e | ||
|
|
ccfe9c39cd | ||
|
|
dbdac04883 | ||
|
|
1d369c002d | ||
|
|
5a1be81603 | ||
|
|
dee73da1aa | ||
|
|
a7dde87c5f | ||
|
|
60fadd448d | ||
|
|
0140d09007 | ||
|
|
da5604a38d | ||
|
|
937df1395c | ||
|
|
89c05007c2 | ||
|
|
4cc9278183 | ||
|
|
9841a2c03a | ||
|
|
74929472d9 | ||
|
|
e274a4c512 | ||
|
|
5d93c44475 | ||
|
|
63b802d0b8 | ||
|
|
1d7e751b60 | ||
|
|
5f8690fb87 | ||
|
|
e093675444 | ||
|
|
a04594540c | ||
|
|
269f2de333 | ||
|
|
be12910aec | ||
|
|
996e582a85 | ||
|
|
aa4c6b7889 | ||
|
|
27a4e8951d | ||
|
|
1fc4082abe | ||
|
|
1c5d7a97e1 | ||
|
|
67c2e1d24c | ||
|
|
eb292e017e | ||
|
|
88839f7613 | ||
|
|
ca71fef74a | ||
|
|
6c91ed0c76 | ||
|
|
8761c0486d | ||
|
|
fee6a9f04a | ||
|
|
17ff04e2b9 | ||
|
|
aa11095d17 | ||
|
|
c2a30f786f | ||
|
|
9b0dd2b0c4 | ||
|
|
aa96d10491 | ||
|
|
dfefbecf44 | ||
|
|
738f19491a | ||
|
|
61257bea7f | ||
|
|
566a01d815 | ||
|
|
a7116d1606 | ||
|
|
615a2aea46 | ||
|
|
20d538c428 | ||
|
|
01054bf470 | ||
|
|
affd720390 | ||
|
|
7d77df58c5 | ||
|
|
51fad2dec6 | ||
|
|
997378ce72 | ||
|
|
1a8a43603e | ||
|
|
d2c88bf7c6 | ||
|
|
0929147b08 | ||
|
|
ecab219635 | ||
|
|
7a974320ed | ||
|
|
1b7dc83a9a | ||
|
|
9827d9056f | ||
|
|
c8d5d9b552 | ||
|
|
dac55ab8e9 | ||
|
|
de75bcdaf9 | ||
|
|
5785124a2b | ||
|
|
4d1c0bfaa8 | ||
|
|
9a29c988cd | ||
|
|
80309f844e | ||
|
|
56ddc49ab4 | ||
|
|
1e7de83019 | ||
|
|
1db1f0312a | ||
|
|
d27bf14887 | ||
|
|
d4e7d4eebc | ||
|
|
30c44d0928 | ||
|
|
443c5dba58 | ||
|
|
f24b4dba71 | ||
|
|
a474880735 | ||
|
|
4cfab3a2de | ||
|
|
4807070147 | ||
|
|
e00aa479ae | ||
|
|
b665d8375c | ||
|
|
4e74c68603 | ||
|
|
2694aa3fe1 | ||
|
|
f7a28aa904 | ||
|
|
4bc2559e8e | ||
|
|
c2faf0e0a7 | ||
|
|
895b331e8f | ||
|
|
8890079b80 | ||
|
|
20dd33ebca | ||
|
|
e2a1489743 | ||
|
|
d6bab46ac3 | ||
|
|
573673ef2b | ||
|
|
eb69499ca3 | ||
|
|
d9323b8ab6 | ||
|
|
a01ba128e5 | ||
|
|
fdc67b3ce5 | ||
|
|
5d433ff603 | ||
|
|
a3f9c4c889 | ||
|
|
769fc485ec | ||
|
|
61ef4fa420 | ||
|
|
8cf37e2f0a | ||
|
|
80a764a448 | ||
|
|
6621c5dfbb | ||
|
|
5e7dda1ec8 | ||
|
|
7bc6368f69 | ||
|
|
fb5a69adea | ||
|
|
0e7607bb27 | ||
|
|
1098b572fe | ||
|
|
7a6662a2dc | ||
|
|
1c6c812d4d | ||
|
|
e58a85f0af | ||
|
|
e3551152bb | ||
|
|
5138d1723f | ||
|
|
9b5ab542d7 | ||
|
|
f0bc4c786c | ||
|
|
b98739bb49 | ||
|
|
fcadc63338 | ||
|
|
3574479627 | ||
|
|
cecf2fc650 | ||
|
|
a1dab24414 | ||
|
|
c12ea28ea9 | ||
|
|
a2b418df8b | ||
|
|
2fb533a606 | ||
|
|
5d89897bbd | ||
|
|
9640e02b6a | ||
|
|
8a0ef33f79 | ||
|
|
d2ece76ca8 | ||
|
|
3495d03706 | ||
|
|
bc90fa50d7 | ||
|
|
777fc0ff30 | ||
|
|
9413f72939 | ||
|
|
1416647d04 | ||
|
|
63bddb4d54 | ||
|
|
6fddd418a1 | ||
|
|
faba55d772 | ||
|
|
ac6db11e3d | ||
|
|
ca7d8ecfc1 | ||
|
|
46eeee68c9 | ||
|
|
c1487daea8 | ||
|
|
b329ae42db | ||
|
|
13429daddc | ||
|
|
98a80295fe | ||
|
|
f8587368ee | ||
|
|
8ae2ae7f8b | ||
|
|
46f3b74b38 | ||
|
|
df51ccd2c4 | ||
|
|
730d43c008 | ||
|
|
81c2c804a6 | ||
|
|
533be356f2 | ||
|
|
589191f3f4 | ||
|
|
0e65efea57 | ||
|
|
be66872249 | ||
|
|
85a0354d42 | ||
|
|
0b8613fd4c | ||
|
|
e734c0010c | ||
|
|
e08333ef26 | ||
|
|
4a3eabbd6b | ||
|
|
ae68d41519 | ||
|
|
722692d934 | ||
|
|
21a3f322e1 | ||
|
|
0d175557b0 | ||
|
|
57ccd19fe6 | ||
|
|
9674711516 | ||
|
|
9155716752 | ||
|
|
d7d8c3e651 | ||
|
|
16f6f2ee7f | ||
|
|
fea6dfd62b | ||
|
|
464ed4322e | ||
|
|
c3f556f0dc | ||
|
|
ba6810891e | ||
|
|
c530883e5e | ||
|
|
06542b031e | ||
|
|
4b5365e708 | ||
|
|
1d471fee92 | ||
|
|
3825dea00a | ||
|
|
3fd130ac4c | ||
|
|
196645e7a2 | ||
|
|
f5459920e9 | ||
|
|
ee6452cfb0 | ||
|
|
ad7e18561b | ||
|
|
c640524bfc | ||
|
|
fea840c859 | ||
|
|
bb7df71391 | ||
|
|
cb6f0335b1 | ||
|
|
762899ef10 | ||
|
|
848d4f031e | ||
|
|
481f828507 | ||
|
|
b3d0c21a80 | ||
|
|
a115cdf095 | ||
|
|
410e9d475b | ||
|
|
462385c7d0 | ||
|
|
3655e2c6f8 | ||
|
|
318f6ae3f5 | ||
|
|
c63acad7e0 | ||
|
|
6dba4a3d28 | ||
|
|
ecf1e53616 | ||
|
|
0ff9a00427 | ||
|
|
725ff8dc58 | ||
|
|
a780dc133e | ||
|
|
b111fcfecc | ||
|
|
114693b7cd | ||
|
|
5a39dcb39c | ||
|
|
b04f887bc3 | ||
|
|
5c38561049 | ||
|
|
f40eb011c3 | ||
|
|
a08cf548e7 | ||
|
|
f12f0d7f7a | ||
|
|
0c53efcbbc | ||
|
|
1aeed8ad12 | ||
|
|
bcb136b692 | ||
|
|
8b670fd615 | ||
|
|
970bc8e973 | ||
|
|
007b06e9db | ||
|
|
4513dbf29d | ||
|
|
53bcc62a0c | ||
|
|
858c55c978 | ||
|
|
cedba089e1 | ||
|
|
cbf7811f7c | ||
|
|
ea13b322ca | ||
|
|
486a8cf1c0 | ||
|
|
bfe46432da | ||
|
|
272eae5f22 | ||
|
|
502104eba8 | ||
|
|
fa45c79bd2 | ||
|
|
ee4d1bf866 | ||
|
|
dcf7b60d37 | ||
|
|
0663a97941 | ||
|
|
f31ab4d6a8 | ||
|
|
f77388738b | ||
|
|
945175c533 | ||
|
|
7d37c6cfd8 | ||
|
|
496672b394 | ||
|
|
1ffe359573 | ||
|
|
23cd9b6a93 | ||
|
|
333ac8edd9 | ||
|
|
081cb20260 | ||
|
|
53f1da32be | ||
|
|
5544a2cc3e | ||
|
|
84c3008db1 | ||
|
|
d949d4d6a2 | ||
|
|
03669dc307 | ||
|
|
2a8fad7364 | ||
|
|
e62db11f01 | ||
|
|
8c8f2b95da | ||
|
|
576eb01187 | ||
|
|
8b18b2a20e | ||
|
|
f5c12a916d | ||
|
|
2f8a99c304 | ||
|
|
cd9a43c3ab | ||
|
|
f251ca5431 | ||
|
|
2c44c80f65 | ||
|
|
d9efeac0a1 | ||
|
|
f4a7d0b6ad | ||
|
|
bc5db1e46a | ||
|
|
8743148238 | ||
|
|
68db6723d0 | ||
|
|
9b1fa43792 | ||
|
|
5f2454831e | ||
|
|
140178bb47 | ||
|
|
f95b4b5c4b | ||
|
|
d3b3a79342 | ||
|
|
52398317bc | ||
|
|
7f2e4f54ff | ||
|
|
9f19ed5376 | ||
|
|
d49a7c415f | ||
|
|
8ffc9ede85 | ||
|
|
eba521563a | ||
|
|
ed71e106df | ||
|
|
050ae49f6b | ||
|
|
d5d9a897ae | ||
|
|
ddf200ffdd | ||
|
|
7fa5e2aa8c | ||
|
|
8bfae9deef | ||
|
|
e6c9f151c1 | ||
|
|
30a0935300 | ||
|
|
b4182d4519 | ||
|
|
93cc0399f1 | ||
|
|
5404dab5a3 | ||
|
|
d70da1d805 | ||
|
|
2225d5b7e8 | ||
|
|
270369bd65 | ||
|
|
a932d61a94 | ||
|
|
24b08663af | ||
|
|
bb6c9c84ba | ||
|
|
a1e185b0f6 | ||
|
|
e2a467ca5a | ||
|
|
4b28933298 | ||
|
|
6077acf134 | ||
|
|
8a4ffd21ab | ||
|
|
d1314124af | ||
|
|
36f018b6aa | ||
|
|
87ccb6e333 | ||
|
|
3432c365f6 | ||
|
|
b7d5aa344f | ||
|
|
7e768623e4 | ||
|
|
73ab2ee1fe | ||
|
|
122fed448c | ||
|
|
6e52bee91f | ||
|
|
cc26afad13 | ||
|
|
bf20449fb5 | ||
|
|
6af5fae8e9 | ||
|
|
e26a38ecaa | ||
|
|
1cdf68f1c0 | ||
|
|
2923dd1d96 | ||
|
|
9067508e1d | ||
|
|
385cc76e34 | ||
|
|
c14cb4b85e | ||
|
|
52644647e4 | ||
|
|
3bf9dd6743 | ||
|
|
aececa2199 | ||
|
|
b4e22a4ca7 | ||
|
|
9b8b4414c4 | ||
|
|
b8fd2c7a02 | ||
|
|
a94f5d74ca | ||
|
|
3829613c37 | ||
|
|
0762eaf0ab | ||
|
|
7fbdab6220 | ||
|
|
cf4d45befb | ||
|
|
dcd81a857d | ||
|
|
0cac723eac | ||
|
|
c6ba4d8155 | ||
|
|
201958f38c | ||
|
|
9326c9c79e | ||
|
|
1042fdb280 | ||
|
|
197056dbc5 | ||
|
|
895b5ee4ff | ||
|
|
c839fe6520 | ||
|
|
2678f85506 | ||
|
|
2b1b4af7a2 | ||
|
|
4218b8a2e8 | ||
|
|
fe7d73a4a4 | ||
|
|
81e86b07e3 | ||
|
|
910c04e373 | ||
|
|
205f1f5e89 | ||
|
|
a1a6d2b725 | ||
|
|
30da589ea0 | ||
|
|
c66e9547e1 | ||
|
|
73990e3fb7 | ||
|
|
f7920de3c2 | ||
|
|
3dd5069f5a | ||
|
|
1d363776ec | ||
|
|
c512eb564d | ||
|
|
7f332e91ff | ||
|
|
8e9d644bc6 | ||
|
|
fa5ce9cbba | ||
|
|
b7905daeb5 | ||
|
|
9da7c9468e | ||
|
|
9eee224e03 | ||
|
|
906d5f04ad | ||
|
|
654c3f7f67 | ||
|
|
c61e6b04a2 | ||
|
|
f893653090 | ||
|
|
579c1efcf6 | ||
|
|
662f9cdeb3 | ||
|
|
b4782425f8 | ||
|
|
2648423930 | ||
|
|
b62cea5073 | ||
|
|
c10ad11b8b | ||
|
|
4aa8a0dc63 | ||
|
|
e4569f9362 | ||
|
|
ed83bababc |
@@ -0,0 +1,3 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
custom: https://ebean.io/sponsors
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
dist: trusty
|
||||
dist: xenial
|
||||
sudo: required
|
||||
language: java
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
- openjdk11
|
||||
|
||||
git:
|
||||
depth: 3
|
||||
|
||||
addons:
|
||||
postgresql: "9.6"
|
||||
postgresql: 10
|
||||
# apt:
|
||||
# packages:
|
||||
# - mysql-server-5.7
|
||||
|
||||
@@ -20,6 +20,11 @@
|
||||
<img width="222px" src="https://ebean.io/images/logo-med-principal.png">
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://timerbee.de" target="_blank">
|
||||
<img width="222px" src="https://ebean.io/images/logo-timerbee.png">
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -39,4 +44,3 @@ Goto [https://ebean.io/docs/](https://ebean.io/docs/)
|
||||
## Other versions
|
||||
* [](https://maven-badges.herokuapp.com/maven-central/io.ebean/ebean-agent) - ebean-agent
|
||||
* [](https://maven-badges.herokuapp.com/maven-central/io.ebean/ebean-maven-plugin) - ebean-maven-plugin
|
||||
|
||||
|
||||
@@ -3,56 +3,29 @@
|
||||
|
||||
<parent>
|
||||
<groupId>org.avaje</groupId>
|
||||
<artifactId>java8-parent</artifactId>
|
||||
<version>1.3</version>
|
||||
<artifactId>java8-oss</artifactId>
|
||||
<version>2.1</version>
|
||||
</parent>
|
||||
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean</artifactId>
|
||||
<version>11.38.1</version>
|
||||
<version>12.1.14-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>ebean</name>
|
||||
<url>http://ebean-orm.github.io/</url>
|
||||
|
||||
<properties>
|
||||
<jackson-core.version>2.9.8</jackson-core.version>
|
||||
<snakeyaml.version>1.21</snakeyaml.version>
|
||||
<jackson-core.version>2.10.0</jackson-core.version>
|
||||
<jackson-databind.version>2.10.0</jackson-databind.version>
|
||||
</properties>
|
||||
|
||||
<scm>
|
||||
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
|
||||
<tag>ebean-11.38.1</tag>
|
||||
<tag>HEAD</tag>
|
||||
</scm>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<!-- Note: to use this profile, you need credentials for the oracle repository in your
|
||||
settings.xml as described here:
|
||||
http://docs.oracle.com/middleware/1213/core/MAVEN/config_maven_repo.htm#MAVEN9010 -->
|
||||
<id>oracle</id>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.oracle.jdbc</groupId>
|
||||
<artifactId>ojdbc8</artifactId>
|
||||
<version>12.2.0.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>maven.oracle.com</id>
|
||||
<releases>
|
||||
<enabled>true</enabled>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
<url>https://maven.oracle.com</url>
|
||||
<layout>default</layout>
|
||||
</repository>
|
||||
</repositories>
|
||||
</profile>
|
||||
<profile>
|
||||
<!-- Note: to use this profile, you need to download manually the db2jcc4 driver.
|
||||
After that, install it into your local maven repository:
|
||||
@@ -88,13 +61,10 @@
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!--
|
||||
Exclude snakeyaml if you desire - it is not strictly required.
|
||||
-->
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
<version>${snakeyaml.version}</version>
|
||||
<groupId>io.avaje</groupId>
|
||||
<artifactId>config</artifactId>
|
||||
<version>1.0</version>
|
||||
</dependency>
|
||||
|
||||
<!--
|
||||
@@ -117,31 +87,25 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-annotation</artifactId>
|
||||
<version>4.10</version>
|
||||
<version>6.9</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-types</artifactId>
|
||||
<version>1.3</version>
|
||||
<version>2.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-datasource</artifactId>
|
||||
<version>4.5.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.avaje</groupId>
|
||||
<artifactId>avaje-classpath-scanner</artifactId>
|
||||
<version>3.1.1</version>
|
||||
<version>4.7.3</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-migration</artifactId>
|
||||
<version>11.14.1</version>
|
||||
<version>12.1.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -161,7 +125,7 @@
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>${jackson-core.version}</version>
|
||||
<version>${jackson-databind.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -198,7 +162,7 @@
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jaxb</groupId>
|
||||
<artifactId>jaxb-runtime</artifactId>
|
||||
<version>2.4.0-b180830.0438</version>
|
||||
<version>2.3.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -213,23 +177,30 @@
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>42.2.2</version>
|
||||
<version>42.2.10</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Test scope -->
|
||||
|
||||
<!--<dependency>-->
|
||||
<!--<groupId>oracle</groupId>-->
|
||||
<!--<artifactId>oracle-jdbc</artifactId>-->
|
||||
<!--<version>7.0</version>-->
|
||||
<!--<scope>test</scope>-->
|
||||
<!--</dependency>-->
|
||||
<dependency>
|
||||
<groupId>com.nuodb.jdbc</groupId>
|
||||
<artifactId>nuodb-jdbc</artifactId>
|
||||
<version>20.2.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-docker-run</artifactId>
|
||||
<version>1.5.1</version>
|
||||
<groupId>com.oracle.ojdbc</groupId>
|
||||
<artifactId>ojdbc10</artifactId>
|
||||
<version>19.3.0.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean.test</groupId>
|
||||
<artifactId>ebean-test-docker</artifactId>
|
||||
<version>3.1.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -240,26 +211,12 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.avaje</groupId>
|
||||
<artifactId>avaje-agentloader</artifactId>
|
||||
<version>3.0.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-agent</artifactId>
|
||||
<version>11.37.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Provided scope so that the H2HistoryTrigger can live in Ebean core
|
||||
and not require a separate module for it -->
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>1.4.197</version>
|
||||
<version>1.4.199</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -280,15 +237,14 @@
|
||||
<dependency>
|
||||
<groupId>com.microsoft.sqlserver</groupId>
|
||||
<artifactId>mssql-jdbc</artifactId>
|
||||
<version>7.2.0.jre8</version>
|
||||
<version>7.2.2.jre8</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<!-- Do not upgrade to 6.0.6: https://bugs.mysql.com/bug.php?id=82896 -->
|
||||
<version>5.1.43</version>
|
||||
<version>8.0.17</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -299,12 +255,18 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.avaje.composite</groupId>
|
||||
<artifactId>avaje-composite-testing</artifactId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>1.1</version>
|
||||
<scope>test</scope>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -315,9 +277,9 @@
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.avaje.moduuid</groupId>
|
||||
<artifactId>avaje-moduuid</artifactId>
|
||||
<version>2.1</version>
|
||||
<groupId>io.avaje</groupId>
|
||||
<artifactId>mod-uuid</artifactId>
|
||||
<version>1.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -330,13 +292,13 @@
|
||||
<plugin>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-maven-plugin</artifactId>
|
||||
<version>11.37.1</version>
|
||||
<version>12.1.12</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>test</id>
|
||||
<phase>process-test-classes</phase>
|
||||
<configuration>
|
||||
<transformArgs>debug=1</transformArgs>
|
||||
<transformArgs>debug=0</transformArgs>
|
||||
</configuration>
|
||||
<goals>
|
||||
<goal>testEnhance</goal>
|
||||
@@ -387,25 +349,11 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>2.9.1</version>
|
||||
<version>3.1.1</version>
|
||||
<configuration>
|
||||
<doctitle>Ebean 11</doctitle>
|
||||
<doctitle>Ebean 12</doctitle>
|
||||
<overview>src/main/java/io/ebean/overview.html</overview>
|
||||
<source>1.8</source>
|
||||
<doclet>org.avaje.doclet.PygmentsDoclet</doclet>
|
||||
<excludePackageNames>io.ebeaninternal.*:io.ebeanservice:io.ebean.common:io.ebean.bean:io.ebean.service:io.ebean.metric:io.ebean.util:io.ebean.config.properties:io.ebean.config.dbplatform*</excludePackageNames>
|
||||
<docletArtifact>
|
||||
<groupId>org.avaje</groupId>
|
||||
<artifactId>pygments-doclet</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</docletArtifact>
|
||||
<additionalparam>
|
||||
-Xdoclint:none
|
||||
-include-basedir ${project.basedir}
|
||||
-attributes "idseparator=-; project_name=${project.name}; \
|
||||
project_version=${project.version}; \
|
||||
project_desc=${project.description}"
|
||||
</additionalparam>
|
||||
<excludePackageNames>io.ebeaninternal.*:io.ebeanservice:io.ebean.common:io.ebean.bean:io.ebean.service:io.ebean.metric:io.ebean.util:io.ebean.config.properties:io.ebean.config.dbplatform</excludePackageNames>
|
||||
<linksource>true</linksource>
|
||||
<overview>src/main/java/com/avaje/ebean/overview.html</overview>
|
||||
</configuration>
|
||||
|
||||
@@ -69,8 +69,8 @@ public enum CacheMode {
|
||||
*/
|
||||
GET(true, false);
|
||||
|
||||
private boolean get;
|
||||
private boolean put;
|
||||
private final boolean get;
|
||||
private final boolean put;
|
||||
|
||||
CacheMode(boolean get, boolean put) {
|
||||
this.get = get;
|
||||
|
||||
@@ -2,7 +2,6 @@ package io.ebean;
|
||||
|
||||
import io.ebean.annotation.TxIsolation;
|
||||
import io.ebean.cache.ServerCacheManager;
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebean.plugin.Property;
|
||||
import io.ebean.text.csv.CsvReader;
|
||||
import io.ebean.text.json.JsonContext;
|
||||
@@ -87,14 +86,14 @@ public class DB {
|
||||
|
||||
// /**
|
||||
// * Register the server with this Ebean singleton. Specify if the registered
|
||||
// * server is the primary/default server.
|
||||
// * server is the primary/default database.
|
||||
// */
|
||||
// public static void register(EbeanServer server, boolean defaultServer) {
|
||||
// serverMgr.register(server, defaultServer);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Backdoor for registering a mock implementation of EbeanServer as the default server.
|
||||
// * Backdoor for registering a mock implementation of EbeanServer as the default database.
|
||||
// */
|
||||
// protected static EbeanServer mock(String name, EbeanServer server, boolean defaultServer) {
|
||||
// EbeanServer originalPrimaryServer = serverMgr.defaultServer;
|
||||
@@ -177,6 +176,18 @@ public class DB {
|
||||
return getDefault().beginTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new transaction that is not held in TransactionThreadLocal.
|
||||
* <p>
|
||||
* You will want to do this if you want multiple Transactions in a single
|
||||
* thread or generally use transactions outside of the TransactionThreadLocal
|
||||
* management.
|
||||
* </p>
|
||||
*/
|
||||
public static Transaction createTransaction() {
|
||||
return getDefault().createTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a transaction additionally specifying the isolation level.
|
||||
*
|
||||
@@ -396,15 +407,6 @@ public class DB {
|
||||
* called then no optimistic locking is performed (internally ConcurrencyMode.NONE is used).
|
||||
* </p>
|
||||
* <p>
|
||||
* <b>{@link DatabaseConfig#setUpdatesDeleteMissingChildren(boolean)}: </b> When cascade saving to a
|
||||
* OneToMany or ManyToMany the updatesDeleteMissingChildren setting controls if any other children
|
||||
* that are in the database but are not in the collection are deleted.
|
||||
* </p>
|
||||
* <p>
|
||||
* <b>{@link DatabaseConfig#setUpdateChangesOnly(boolean)}: </b> The updateChangesOnly setting
|
||||
* controls if only the changed properties are included in the update or if all the loaded
|
||||
* properties are included instead.
|
||||
* </p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* // A 'stateless update' example
|
||||
@@ -414,9 +416,6 @@ public class DB {
|
||||
* database.update(customer);
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @see DatabaseConfig#setUpdatesDeleteMissingChildren(boolean)
|
||||
* @see DatabaseConfig#setUpdateChangesOnly(boolean)
|
||||
*/
|
||||
public static void update(Object bean) throws OptimisticLockException {
|
||||
getDefault().update(bean);
|
||||
@@ -455,6 +454,13 @@ public class DB {
|
||||
return getDefault().saveAll(beans);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save all the beans from a Collection.
|
||||
*/
|
||||
public static int saveAll(Object... beans) throws OptimisticLockException {
|
||||
return getDefault().saveAll(beans);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method checks the uniqueness of a bean. I.e. if the save will work. It will return the
|
||||
* properties that violates an unique / primary key. This may be done in an UI save action to
|
||||
@@ -663,7 +669,7 @@ public class DB {
|
||||
* // find orders and their customers
|
||||
* List<Order> list = DB.find(Order.class)
|
||||
* .fetch("customer")
|
||||
* .orderBy("id")
|
||||
* .order("id")
|
||||
* .findList();
|
||||
*
|
||||
* // sort by customer name ascending, then by order shipDate
|
||||
@@ -749,8 +755,11 @@ public class DB {
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated - migrate to sqlQuery().
|
||||
* <p>
|
||||
* This is an alias for {@link #sqlQuery(String)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static SqlQuery createSqlQuery(String sql) {
|
||||
return sqlQuery(sql);
|
||||
}
|
||||
@@ -773,8 +782,11 @@ public class DB {
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated - migrate to sqlUpdate().
|
||||
* <p>
|
||||
* This is an alias for {@link #sqlUpdate(String)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static SqlUpdate createSqlUpdate(String sql) {
|
||||
return sqlUpdate(sql);
|
||||
}
|
||||
@@ -1215,6 +1227,13 @@ public class DB {
|
||||
return getDefault().getBeanState(bean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value of the Id property for a given bean.
|
||||
*/
|
||||
public static Object getBeanId(Object bean) {
|
||||
return getDefault().getBeanId(bean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the manager of the level 2 cache ("L2" cache).
|
||||
*/
|
||||
@@ -1237,4 +1256,18 @@ public class DB {
|
||||
return getDefault().json();
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncate the base tables for the given bean types.
|
||||
*/
|
||||
public static void truncate(Class<?>... types) {
|
||||
getDefault().truncate(types);
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncate the given tables.
|
||||
*/
|
||||
public static void truncate(String... tables) {
|
||||
getDefault().truncate(tables);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package io.ebean;
|
||||
import io.ebean.annotation.TxIsolation;
|
||||
import io.ebean.cache.ServerCacheManager;
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebean.config.ServerConfig;
|
||||
import io.ebean.meta.MetaInfoManager;
|
||||
import io.ebean.plugin.Property;
|
||||
import io.ebean.plugin.SpiServer;
|
||||
@@ -123,7 +122,7 @@ public interface Database {
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Return the ExpressionFactory for this server.
|
||||
* Return the ExpressionFactory for this database.
|
||||
*/
|
||||
ExpressionFactory getExpressionFactory();
|
||||
|
||||
@@ -376,7 +375,7 @@ public interface Database {
|
||||
* // find orders and their customers
|
||||
* List<Order> list = database.find(Order.class)
|
||||
* .fetch("customer")
|
||||
* .orderBy("id")
|
||||
* .order("id")
|
||||
* .findList();
|
||||
*
|
||||
* // sort by customer name ascending, then by order shipDate
|
||||
@@ -465,8 +464,11 @@ public interface Database {
|
||||
SqlQuery sqlQuery(String sql);
|
||||
|
||||
/**
|
||||
* Deprecated - migrate to sqlQuery().
|
||||
* <p>
|
||||
* This is an alias for {@link #sqlQuery(String)}.
|
||||
*/
|
||||
@Deprecated
|
||||
SqlQuery createSqlQuery(String sql);
|
||||
|
||||
/**
|
||||
@@ -485,8 +487,11 @@ public interface Database {
|
||||
SqlUpdate sqlUpdate(String sql);
|
||||
|
||||
/**
|
||||
* Deprecated - migrate to sqlUpdate().
|
||||
* <p>
|
||||
* This is an alias for {@link #sqlUpdate(String)}.
|
||||
*/
|
||||
@Deprecated
|
||||
SqlUpdate createSqlUpdate(String sql);
|
||||
|
||||
/**
|
||||
@@ -856,7 +861,7 @@ public interface Database {
|
||||
* <pre>{@code
|
||||
* public class Order { ...
|
||||
*
|
||||
* @OneToMany(cascade=CascadeType.ALL, mappedBy="order")
|
||||
* @OneToMany(cascade=CascadeType.ALL, mappedBy="order")
|
||||
* List<OrderDetail> details;
|
||||
* ...
|
||||
* }
|
||||
@@ -876,6 +881,11 @@ public interface Database {
|
||||
*/
|
||||
int saveAll(Collection<?> beans) throws OptimisticLockException;
|
||||
|
||||
/**
|
||||
* Save all the beans.
|
||||
*/
|
||||
int saveAll(Object... beans) throws OptimisticLockException;
|
||||
|
||||
/**
|
||||
* Delete the bean.
|
||||
* <p>
|
||||
@@ -1051,7 +1061,6 @@ public interface Database {
|
||||
* Integer returnValue = (Integer) cs.getObject(3);
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
*/
|
||||
int execute(CallableSql callableSql);
|
||||
|
||||
@@ -1196,17 +1205,6 @@ public interface Database {
|
||||
* <b>Optimistic Locking: </b> Note that if the version property is not set when update() is
|
||||
* called then no optimistic locking is performed (internally ConcurrencyMode.NONE is used).
|
||||
* </p>
|
||||
* <p>
|
||||
* <b>{@link ServerConfig#setUpdatesDeleteMissingChildren(boolean)}: </b> When cascade saving to a
|
||||
* OneToMany or ManyToMany the updatesDeleteMissingChildren setting controls if any other children
|
||||
* that are in the database but are not in the collection are deleted.
|
||||
* </p>
|
||||
* <p>
|
||||
* <b>{@link ServerConfig#setUpdateChangesOnly(boolean)}: </b> The updateChangesOnly setting
|
||||
* controls if only the changed properties are included in the update or if all the loaded
|
||||
* properties are included instead.
|
||||
* </p>
|
||||
* <p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* // A 'stateless update' example
|
||||
@@ -1216,9 +1214,6 @@ public interface Database {
|
||||
* database.update(customer);
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @see ServerConfig#setUpdatesDeleteMissingChildren(boolean)
|
||||
* @see ServerConfig#setUpdateChangesOnly(boolean)
|
||||
*/
|
||||
void update(Object bean) throws OptimisticLockException;
|
||||
|
||||
@@ -1227,16 +1222,6 @@ public interface Database {
|
||||
*/
|
||||
void update(Object bean, Transaction transaction) throws OptimisticLockException;
|
||||
|
||||
/**
|
||||
* Update a bean additionally specifying a transaction and the deleteMissingChildren setting.
|
||||
*
|
||||
* @param bean the bean to update
|
||||
* @param transaction the transaction to use (can be null).
|
||||
* @param deleteMissingChildren specify false if you do not want 'missing children' of a OneToMany
|
||||
* or ManyToMany to be automatically deleted.
|
||||
*/
|
||||
void update(Object bean, Transaction transaction, boolean deleteMissingChildren) throws OptimisticLockException;
|
||||
|
||||
/**
|
||||
* Update a collection of beans. If there is no current transaction one is created and used to
|
||||
* update all the beans in the collection.
|
||||
@@ -1323,7 +1308,7 @@ public interface Database {
|
||||
* public void run() {
|
||||
* User u1 = database.find(User.class, 1);
|
||||
* ...
|
||||
* }
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* }</pre>
|
||||
@@ -1372,7 +1357,7 @@ public interface Database {
|
||||
* User u1 = database.find(User.class, 1);
|
||||
* ...
|
||||
* return u1.getEmail();
|
||||
* }
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* }</pre>
|
||||
@@ -1580,4 +1565,15 @@ public interface Database {
|
||||
* </p>
|
||||
*/
|
||||
<T> Set<String> validateQuery(Query<T> query);
|
||||
|
||||
/**
|
||||
* Truncate all the given tables.
|
||||
*/
|
||||
void truncate(String... tables);
|
||||
|
||||
/**
|
||||
* Truncate the base tables for the given bean types.
|
||||
*/
|
||||
void truncate(Class<?>... tables);
|
||||
|
||||
}
|
||||
|
||||
@@ -34,14 +34,14 @@ public class DatabaseFactory {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create using ebean.properties to configure the server.
|
||||
* Create using ebean.properties to configure the database.
|
||||
*/
|
||||
public static synchronized Database create(String name) {
|
||||
return EbeanServerFactory.create(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create using the ServerConfig object to configure the server.
|
||||
* Create using the ServerConfig object to configure the database.
|
||||
*/
|
||||
public static synchronized Database create(DatabaseConfig config) {
|
||||
return EbeanServerFactory.create(config);
|
||||
|
||||
@@ -61,7 +61,7 @@ public interface DocumentStore {
|
||||
* <pre>{@code
|
||||
*
|
||||
* Customer customer =
|
||||
* server.find(Customer.class)
|
||||
* database.find(Customer.class)
|
||||
* .setUseDocStore(true)
|
||||
* .setId(42)
|
||||
* .findOne();
|
||||
@@ -79,7 +79,7 @@ public interface DocumentStore {
|
||||
* <pre>{@code
|
||||
*
|
||||
* List<Customer> newCustomers =
|
||||
* server.find(Customer.class)
|
||||
* database.find(Customer.class)
|
||||
* .setUseDocStore(true)
|
||||
* .where().eq("status, Customer.Status.NEW)
|
||||
* .findList();
|
||||
@@ -99,7 +99,7 @@ public interface DocumentStore {
|
||||
* <pre>{@code
|
||||
*
|
||||
* PagedList<Customer> newCustomers =
|
||||
* server.find(Customer.class)
|
||||
* database.find(Customer.class)
|
||||
* .setUseDocStore(true)
|
||||
* .where().eq("status, Customer.Status.NEW)
|
||||
* .setMaxRows(50)
|
||||
@@ -120,7 +120,7 @@ public interface DocumentStore {
|
||||
* </p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* server.find(Order.class)
|
||||
* database.find(Order.class)
|
||||
* .setUseDocStore(true)
|
||||
* .where()... // perhaps add predicates
|
||||
* .findEach((Order order) -> {
|
||||
@@ -145,7 +145,7 @@ public interface DocumentStore {
|
||||
* </p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* server.find(Order.class)
|
||||
* database.find(Order.class)
|
||||
* .setUseDocStore(true)
|
||||
* .where()... // perhaps add predicates
|
||||
* .findEachWhile(new Predicate<Order>() {
|
||||
@@ -190,7 +190,7 @@ public interface DocumentStore {
|
||||
* Drop the index from the document store (similar to DDL drop table).
|
||||
* <pre>{@code
|
||||
*
|
||||
* DocumentStore documentStore = server.docStore();
|
||||
* DocumentStore documentStore = database.docStore();
|
||||
*
|
||||
* documentStore.dropIndex("product_copy");
|
||||
*
|
||||
@@ -202,7 +202,7 @@ public interface DocumentStore {
|
||||
* Create an index given a mapping file as a resource in the classPath (similar to DDL create table).
|
||||
* <pre>{@code
|
||||
*
|
||||
* DocumentStore documentStore = server.docStore();
|
||||
* DocumentStore documentStore = database.docStore();
|
||||
*
|
||||
* // uses product_copy.mapping.json resource
|
||||
* // ... to define mappings for the index
|
||||
@@ -289,7 +289,7 @@ public interface DocumentStore {
|
||||
* <pre>{@code
|
||||
*
|
||||
* // predicates to select the source documents to copy
|
||||
* Query<Product> query = server.find(Product.class)
|
||||
* Query<Product> query = database.find(Product.class)
|
||||
* .where()
|
||||
* .ge("whenModified", new Timestamp(since))
|
||||
* .ge("name", "A")
|
||||
|
||||
@@ -77,12 +77,29 @@ public interface DtoQuery<T> {
|
||||
Optional<T> findOneOrEmpty();
|
||||
|
||||
/**
|
||||
* The same as bind for named parameters.
|
||||
* Bind all the parameters using index positions.
|
||||
* <p>
|
||||
* Binds each parameter moving the index position each time.
|
||||
* <p>
|
||||
* A convenience for multiple calls to {@link #setParameter(Object)}
|
||||
*/
|
||||
DtoQuery<T> setParameters(Object... value);
|
||||
|
||||
/**
|
||||
* Bind the next parameter using index position.
|
||||
* <p>
|
||||
* Bind the parameter using index position starting at 1 and incrementing.
|
||||
* <p>
|
||||
*/
|
||||
DtoQuery<T> setParameter(Object value);
|
||||
|
||||
/**
|
||||
* Bind the named parameter.
|
||||
*/
|
||||
DtoQuery<T> setParameter(String name, Object value);
|
||||
|
||||
/**
|
||||
* The same as bind for positioned parameters.
|
||||
* Bind the parameter by its index position (1 based like JDBC).
|
||||
*/
|
||||
DtoQuery<T> setParameter(int position, Object value);
|
||||
|
||||
@@ -136,4 +153,8 @@ public interface DtoQuery<T> {
|
||||
*/
|
||||
DtoQuery<T> setBufferFetchSizeHint(int bufferFetchSizeHint);
|
||||
|
||||
/**
|
||||
* Use the explicit transaction to execute the query.
|
||||
*/
|
||||
DtoQuery<T> usingTransaction(Transaction transaction);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Ebean will be Deprecated - please migrate to use DB.
|
||||
* <p>
|
||||
* Ebean is a registry of {@link Database} by name. Ebean has now been renamed to {@link DB}.
|
||||
* <p>
|
||||
* Ebean is effectively this is an alias for {@link DB} which is the new and improved name for Ebean.
|
||||
@@ -80,7 +82,7 @@ public final class Ebean {
|
||||
|
||||
} catch (DataSourceConfigurationException e) {
|
||||
String msg = "Configuration error creating DataSource for the default Database." +
|
||||
" This typically means a missing application-test.yaml or missing ebean-test-config dependency." +
|
||||
" This typically means a missing application-test.yaml or missing ebean-test dependency." +
|
||||
" See https://ebean.io/docs/trouble-shooting#datasource";
|
||||
throw new DataSourceConfigurationException(msg, e);
|
||||
|
||||
@@ -185,7 +187,7 @@ public final class Ebean {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ExpressionFactory from the default server.
|
||||
* Return the ExpressionFactory from the default database.
|
||||
* <p>
|
||||
* The ExpressionFactory is used internally by the query and ExpressionList to
|
||||
* build the WHERE and HAVING clauses. Alternatively you can use the
|
||||
@@ -207,14 +209,14 @@ public final class Ebean {
|
||||
|
||||
/**
|
||||
* Register the server with this Ebean singleton. Specify if the registered
|
||||
* server is the primary/default server.
|
||||
* server is the primary/default database.
|
||||
*/
|
||||
public static void register(EbeanServer server, boolean defaultServer) {
|
||||
serverMgr.register(server, defaultServer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Backdoor for registering a mock implementation of EbeanServer as the default server.
|
||||
* Backdoor for registering a mock implementation of EbeanServer as the default database.
|
||||
*/
|
||||
protected static EbeanServer mock(String name, EbeanServer server, boolean defaultServer) {
|
||||
EbeanServer originalPrimaryServer = serverMgr.defaultServer;
|
||||
@@ -462,7 +464,7 @@ public final class Ebean {
|
||||
* <pre>{@code
|
||||
* public class Order { ...
|
||||
*
|
||||
* @OneToMany(cascade=CascadeType.ALL, mappedBy="order")
|
||||
* @OneToMany(cascade=CascadeType.ALL, mappedBy="order")
|
||||
* List<OrderDetail> details;
|
||||
* ...
|
||||
* }
|
||||
@@ -548,9 +550,6 @@ public final class Ebean {
|
||||
* DB.update(customer);
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @see ServerConfig#setUpdatesDeleteMissingChildren(boolean)
|
||||
* @see ServerConfig#setUpdateChangesOnly(boolean)
|
||||
*/
|
||||
public static void update(Object bean) throws OptimisticLockException {
|
||||
serverMgr.getDefaultServer().update(bean);
|
||||
@@ -797,7 +796,7 @@ public final class Ebean {
|
||||
* // find orders and their customers
|
||||
* List<Order> list = Ebean.find(Order.class)
|
||||
* .fetch("customer")
|
||||
* .orderBy("id")
|
||||
* .order("id")
|
||||
* .findList();
|
||||
*
|
||||
* // sort by customer name ascending, then by order shipDate
|
||||
@@ -868,6 +867,8 @@ public final class Ebean {
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated - migrate to DB.sqlQuery().
|
||||
* <p>
|
||||
* Create a SqlQuery for executing native sql
|
||||
* query statements.
|
||||
* <p>
|
||||
@@ -875,22 +876,24 @@ public final class Ebean {
|
||||
* annotation for examples.
|
||||
* </p>
|
||||
*/
|
||||
@Deprecated
|
||||
public static SqlQuery createSqlQuery(String sql) {
|
||||
return serverMgr.getDefaultServer().createSqlQuery(sql);
|
||||
return serverMgr.getDefaultServer().sqlQuery(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated - migrate to DB.sqlUpdate().
|
||||
* <p>
|
||||
* Create a sql update for executing native dml statements.
|
||||
* <p>
|
||||
* Use this to execute a Insert Update or Delete statement. The statement will
|
||||
* be native to the database and contain database table and column names.
|
||||
* </p>
|
||||
* <p>
|
||||
* See {@link SqlUpdate} for example usage.
|
||||
* </p>
|
||||
*/
|
||||
@Deprecated
|
||||
public static SqlUpdate createSqlUpdate(String sql) {
|
||||
return serverMgr.getDefaultServer().createSqlUpdate(sql);
|
||||
return serverMgr.getDefaultServer().sqlUpdate(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1196,7 +1199,7 @@ public final class Ebean {
|
||||
* public void run() {
|
||||
* User u1 = Ebean.find(User.class, 1);
|
||||
* ...
|
||||
* }
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* }</pre>
|
||||
@@ -1248,7 +1251,7 @@ public final class Ebean {
|
||||
* User u1 = Ebean.find(User.class, 1);
|
||||
* ...
|
||||
* return u1.getEmail();
|
||||
* }
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* }</pre>
|
||||
|
||||
@@ -48,7 +48,7 @@ public class EbeanServerFactory {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create using ebean.properties to configure the server.
|
||||
* Create using ebean.properties to configure the database.
|
||||
*/
|
||||
public static synchronized EbeanServer create(String name) {
|
||||
|
||||
@@ -59,7 +59,7 @@ public class EbeanServerFactory {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create using the ServerConfig object to configure the server.
|
||||
* Create using the ServerConfig object to configure the database.
|
||||
*/
|
||||
public static synchronized EbeanServer create(ServerConfig config) {
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ public class EbeanVersion {
|
||||
static {
|
||||
try {
|
||||
Properties prop = new Properties();
|
||||
try (InputStream in = Ebean.class.getResourceAsStream("/META-INF/maven/io.ebean/ebean/pom.properties")) {
|
||||
try (InputStream in = DB.class.getResourceAsStream("/META-INF/maven/io.ebean/ebean/pom.properties")) {
|
||||
if (in != null) {
|
||||
prop.load(in);
|
||||
in.close();
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
package io.ebean;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
/**
|
||||
* An empty PagedList.
|
||||
* <p>
|
||||
* For use in application code when we need to return a PagedList but don't want to
|
||||
* execute a query.
|
||||
* </p>
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* PagedList<Customer> empty = PagedList.emptyList();
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
public class EmptyPagedList<T> implements PagedList<T> {
|
||||
|
||||
@Override
|
||||
public void loadCount() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Future<Integer> getFutureCount() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public List<T> getList() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTotalCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTotalPageCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPageSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPageIndex() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPrev() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayXtoYofZ(String to, String of) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -34,14 +34,14 @@ public class Expr {
|
||||
* Equal To - property equal to the given value.
|
||||
*/
|
||||
public static Expression eq(String propertyName, Object value) {
|
||||
return Ebean.getExpressionFactory().eq(propertyName, value);
|
||||
return DB.getExpressionFactory().eq(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Not Equal To - property not equal to the given value.
|
||||
*/
|
||||
public static Expression ne(String propertyName, Object value) {
|
||||
return Ebean.getExpressionFactory().ne(propertyName, value);
|
||||
return DB.getExpressionFactory().ne(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,7 +49,7 @@ public class Expr {
|
||||
* using a lower() function to make it case insensitive).
|
||||
*/
|
||||
public static Expression ieq(String propertyName, String value) {
|
||||
return Ebean.getExpressionFactory().ieq(propertyName, value);
|
||||
return DB.getExpressionFactory().ieq(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,28 +59,28 @@ public class Expr {
|
||||
* </p>
|
||||
*/
|
||||
public static Expression inRange(String propertyName, Object value1, Object value2) {
|
||||
return Ebean.getExpressionFactory().inRange(propertyName, value1, value2);
|
||||
return DB.getExpressionFactory().inRange(propertyName, value1, value2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Between - property between the two given values.
|
||||
*/
|
||||
public static Expression between(String propertyName, Object value1, Object value2) {
|
||||
return Ebean.getExpressionFactory().between(propertyName, value1, value2);
|
||||
return DB.getExpressionFactory().between(propertyName, value1, value2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Between - value between two given properties.
|
||||
*/
|
||||
public static Expression between(String lowProperty, String highProperty, Object value) {
|
||||
return Ebean.getExpressionFactory().betweenProperties(lowProperty, highProperty, value);
|
||||
return DB.getExpressionFactory().betweenProperties(lowProperty, highProperty, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Greater Than - property greater than the given value.
|
||||
*/
|
||||
public static Expression gt(String propertyName, Object value) {
|
||||
return Ebean.getExpressionFactory().gt(propertyName, value);
|
||||
return DB.getExpressionFactory().gt(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,42 +88,42 @@ public class Expr {
|
||||
* value.
|
||||
*/
|
||||
public static Expression ge(String propertyName, Object value) {
|
||||
return Ebean.getExpressionFactory().ge(propertyName, value);
|
||||
return DB.getExpressionFactory().ge(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Less Than - property less than the given value.
|
||||
*/
|
||||
public static Expression lt(String propertyName, Object value) {
|
||||
return Ebean.getExpressionFactory().lt(propertyName, value);
|
||||
return DB.getExpressionFactory().lt(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Less Than or Equal to - property less than or equal to the given value.
|
||||
*/
|
||||
public static Expression le(String propertyName, Object value) {
|
||||
return Ebean.getExpressionFactory().le(propertyName, value);
|
||||
return DB.getExpressionFactory().le(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Null - property is null.
|
||||
*/
|
||||
public static Expression isNull(String propertyName) {
|
||||
return Ebean.getExpressionFactory().isNull(propertyName);
|
||||
return DB.getExpressionFactory().isNull(propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Not Null - property is not null.
|
||||
*/
|
||||
public static Expression isNotNull(String propertyName) {
|
||||
return Ebean.getExpressionFactory().isNotNull(propertyName);
|
||||
return DB.getExpressionFactory().isNotNull(propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Case insensitive {@link #exampleLike(Object)}
|
||||
*/
|
||||
public static ExampleExpression iexampleLike(Object example) {
|
||||
return Ebean.getExpressionFactory().iexampleLike(example);
|
||||
return DB.getExpressionFactory().iexampleLike(example);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,14 +131,14 @@ public class Expr {
|
||||
* LikeType.RAW (you need to add you own wildcards % and _).
|
||||
*/
|
||||
public static ExampleExpression exampleLike(Object example) {
|
||||
return Ebean.getExpressionFactory().exampleLike(example);
|
||||
return DB.getExpressionFactory().exampleLike(example);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the query by Example expression specifying more options.
|
||||
*/
|
||||
public static ExampleExpression exampleLike(Object example, boolean caseInsensitive, LikeType likeType) {
|
||||
return Ebean.getExpressionFactory().exampleLike(example, caseInsensitive, likeType);
|
||||
return DB.getExpressionFactory().exampleLike(example, caseInsensitive, likeType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -146,7 +146,7 @@ public class Expr {
|
||||
* characters % (percentage) and _ (underscore).
|
||||
*/
|
||||
public static Expression like(String propertyName, String value) {
|
||||
return Ebean.getExpressionFactory().like(propertyName, value);
|
||||
return DB.getExpressionFactory().like(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -155,14 +155,14 @@ public class Expr {
|
||||
* a lower() function to make the expression case insensitive.
|
||||
*/
|
||||
public static Expression ilike(String propertyName, String value) {
|
||||
return Ebean.getExpressionFactory().ilike(propertyName, value);
|
||||
return DB.getExpressionFactory().ilike(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts With - property like value%.
|
||||
*/
|
||||
public static Expression startsWith(String propertyName, String value) {
|
||||
return Ebean.getExpressionFactory().startsWith(propertyName, value);
|
||||
return DB.getExpressionFactory().startsWith(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -170,14 +170,14 @@ public class Expr {
|
||||
* lower() function to make the expression case insensitive.
|
||||
*/
|
||||
public static Expression istartsWith(String propertyName, String value) {
|
||||
return Ebean.getExpressionFactory().istartsWith(propertyName, value);
|
||||
return DB.getExpressionFactory().istartsWith(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends With - property like %value.
|
||||
*/
|
||||
public static Expression endsWith(String propertyName, String value) {
|
||||
return Ebean.getExpressionFactory().endsWith(propertyName, value);
|
||||
return DB.getExpressionFactory().endsWith(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -185,14 +185,14 @@ public class Expr {
|
||||
* function to make the expression case insensitive.
|
||||
*/
|
||||
public static Expression iendsWith(String propertyName, String value) {
|
||||
return Ebean.getExpressionFactory().iendsWith(propertyName, value);
|
||||
return DB.getExpressionFactory().iendsWith(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains - property like %value%.
|
||||
*/
|
||||
public static Expression contains(String propertyName, String value) {
|
||||
return Ebean.getExpressionFactory().contains(propertyName, value);
|
||||
return DB.getExpressionFactory().contains(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -200,42 +200,42 @@ public class Expr {
|
||||
* function to make the expression case insensitive.
|
||||
*/
|
||||
public static Expression icontains(String propertyName, String value) {
|
||||
return Ebean.getExpressionFactory().icontains(propertyName, value);
|
||||
return DB.getExpressionFactory().icontains(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* For collection properties that are empty (have not existing elements).
|
||||
*/
|
||||
public static Expression isEmpty(String propertyName) {
|
||||
return Ebean.getExpressionFactory().isEmpty(propertyName);
|
||||
return DB.getExpressionFactory().isEmpty(propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* For collection properties that are not empty (have existing elements).
|
||||
*/
|
||||
public static Expression isNotEmpty(String propertyName) {
|
||||
return Ebean.getExpressionFactory().isNotEmpty(propertyName);
|
||||
return DB.getExpressionFactory().isNotEmpty(propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* In - property has a value in the array of values.
|
||||
*/
|
||||
public static Expression in(String propertyName, Object[] values) {
|
||||
return Ebean.getExpressionFactory().in(propertyName, values);
|
||||
return DB.getExpressionFactory().in(propertyName, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* In - using a subQuery.
|
||||
*/
|
||||
public static Expression in(String propertyName, Query<?> subQuery) {
|
||||
return Ebean.getExpressionFactory().in(propertyName, subQuery);
|
||||
return DB.getExpressionFactory().in(propertyName, subQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* In - property has a value in the collection of values.
|
||||
*/
|
||||
public static Expression in(String propertyName, Collection<?> values) {
|
||||
return Ebean.getExpressionFactory().in(propertyName, values);
|
||||
return DB.getExpressionFactory().in(propertyName, values);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -272,14 +272,14 @@ public class Expr {
|
||||
* }</pre>
|
||||
*/
|
||||
public static Expression inOrEmpty(String propertyName, Collection<?> values) {
|
||||
return Ebean.getExpressionFactory().inOrEmpty(propertyName, values);
|
||||
return DB.getExpressionFactory().inOrEmpty(propertyName, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Id Equal to - ID property is equal to the value.
|
||||
*/
|
||||
public static Expression idEq(Object value) {
|
||||
return Ebean.getExpressionFactory().idEq(value);
|
||||
return DB.getExpressionFactory().idEq(value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -292,7 +292,7 @@ public class Expr {
|
||||
* @param propertyMap a map keyed by property names.
|
||||
*/
|
||||
public static Expression allEq(Map<String, Object> propertyMap) {
|
||||
return Ebean.getExpressionFactory().allEq(propertyMap);
|
||||
return DB.getExpressionFactory().allEq(propertyMap);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -303,7 +303,7 @@ public class Expr {
|
||||
* </p>
|
||||
*/
|
||||
public static Expression raw(String raw, Object value) {
|
||||
return Ebean.getExpressionFactory().raw(raw, value);
|
||||
return DB.getExpressionFactory().raw(raw, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -314,14 +314,14 @@ public class Expr {
|
||||
* </p>
|
||||
*/
|
||||
public static Expression raw(String raw, Object[] values) {
|
||||
return Ebean.getExpressionFactory().raw(raw, values);
|
||||
return DB.getExpressionFactory().raw(raw, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add raw expression with no parameters.
|
||||
*/
|
||||
public static Expression raw(String raw) {
|
||||
return Ebean.getExpressionFactory().raw(raw);
|
||||
return DB.getExpressionFactory().raw(raw);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -329,7 +329,7 @@ public class Expr {
|
||||
*/
|
||||
public static Expression and(Expression expOne, Expression expTwo) {
|
||||
|
||||
return Ebean.getExpressionFactory().and(expOne, expTwo);
|
||||
return DB.getExpressionFactory().and(expOne, expTwo);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -337,7 +337,7 @@ public class Expr {
|
||||
*/
|
||||
public static Expression or(Expression expOne, Expression expTwo) {
|
||||
|
||||
return Ebean.getExpressionFactory().or(expOne, expTwo);
|
||||
return DB.getExpressionFactory().or(expOne, expTwo);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -345,7 +345,7 @@ public class Expr {
|
||||
*/
|
||||
public static Expression not(Expression exp) {
|
||||
|
||||
return Ebean.getExpressionFactory().not(exp);
|
||||
return DB.getExpressionFactory().not(exp);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -353,7 +353,7 @@ public class Expr {
|
||||
*/
|
||||
public static <T> Junction<T> conjunction(Query<T> query) {
|
||||
|
||||
return Ebean.getExpressionFactory().conjunction(query);
|
||||
return DB.getExpressionFactory().conjunction(query);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -361,6 +361,6 @@ public class Expr {
|
||||
*/
|
||||
public static <T> Junction<T> disjunction(Query<T> query) {
|
||||
|
||||
return Ebean.getExpressionFactory().disjunction(query);
|
||||
return DB.getExpressionFactory().disjunction(query);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -536,4 +536,12 @@ public interface ExpressionFactory {
|
||||
*/
|
||||
<T> Junction<T> junction(Junction.Type type, Query<T> query, ExpressionList<T> parent);
|
||||
|
||||
/**
|
||||
* Add the expressions to the given expression list.
|
||||
*
|
||||
* @param where The expression list to add the expressions to
|
||||
* @param expressions The expressions that are parsed
|
||||
* @param params Bind parameters to match ? or ?1 bind positions.
|
||||
*/
|
||||
<T> void where(ExpressionList<T> where, String expressions, Object[] params);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ import java.util.function.Predicate;
|
||||
* </p>
|
||||
* <p>
|
||||
* The ExpressionList also duplicates methods that are found on the Query such
|
||||
* as findList() and orderBy(). The purpose of these methods is provide a fluid
|
||||
* as findList() and order(). The purpose of these methods is provide a fluid
|
||||
* API. The upside of this approach is that you can build and execute a query
|
||||
* via chained methods. The down side is that this ExpressionList object has
|
||||
* more methods than you would initially expect (the ones duplicated from
|
||||
@@ -52,6 +52,14 @@ public interface ExpressionList<T> {
|
||||
*/
|
||||
Query<T> query();
|
||||
|
||||
/**
|
||||
* Controls, if paginated queries should always append an 'order by id' statement at the end to
|
||||
* guarantee a deterministic sort result. This may affect performance.
|
||||
* If this is not enabled, and an orderBy is set on the query, it's up to the programmer that
|
||||
* this query provides a deterministic result.
|
||||
*/
|
||||
Query<T> orderById(boolean orderById);
|
||||
|
||||
/**
|
||||
* Set the order by clause replacing the existing order by clause if there is
|
||||
* one.
|
||||
@@ -59,12 +67,8 @@ public interface ExpressionList<T> {
|
||||
* This follows SQL syntax using commas between each property with the
|
||||
* optional asc and desc keywords representing ascending and descending order
|
||||
* respectively.
|
||||
* </p>
|
||||
* <p>
|
||||
* This is EXACTLY the same as {@link #orderBy(String)}.
|
||||
* </p>
|
||||
*/
|
||||
Query<T> order(String orderByClause);
|
||||
ExpressionList<T> order(String orderByClause);
|
||||
|
||||
/**
|
||||
* Return the OrderBy so that you can append an ascending or descending
|
||||
@@ -77,27 +81,21 @@ public interface ExpressionList<T> {
|
||||
OrderBy<T> order();
|
||||
|
||||
/**
|
||||
* Return the OrderBy so that you can append an ascending or descending
|
||||
* property to the order by clause.
|
||||
* <p>
|
||||
* This will never return a null. If no order by clause exists then an 'empty'
|
||||
* OrderBy object is returned.
|
||||
* </p>
|
||||
* Deprecated migrate to order().
|
||||
*/
|
||||
@Deprecated
|
||||
OrderBy<T> orderBy();
|
||||
|
||||
/**
|
||||
* Add an orderBy clause to the query.
|
||||
*
|
||||
* @see Query#orderBy(String)
|
||||
* Deprecated migrate to {@link #order(String)}
|
||||
*/
|
||||
@Deprecated
|
||||
Query<T> orderBy(String orderBy);
|
||||
|
||||
/**
|
||||
* Add an orderBy clause to the query.
|
||||
*
|
||||
* @see Query#orderBy(String)
|
||||
* Deprecated migrate to {@link #order(String)}
|
||||
*/
|
||||
@Deprecated
|
||||
Query<T> setOrderBy(String orderBy);
|
||||
|
||||
/**
|
||||
@@ -334,7 +332,7 @@ public interface ExpressionList<T> {
|
||||
* List<String> names =
|
||||
* DB.find(Customer.class)
|
||||
* .select("name")
|
||||
* .orderBy().asc("name")
|
||||
* .order().asc("name")
|
||||
* .findSingleAttributeList();
|
||||
*
|
||||
* }</pre>
|
||||
@@ -347,7 +345,7 @@ public interface ExpressionList<T> {
|
||||
* .setDistinct(true)
|
||||
* .select("name")
|
||||
* .where().eq("status", Customer.Status.NEW)
|
||||
* .orderBy().asc("name")
|
||||
* .order().asc("name")
|
||||
* .setMaxRows(100)
|
||||
* .findSingleAttributeList();
|
||||
*
|
||||
@@ -489,7 +487,26 @@ public interface ExpressionList<T> {
|
||||
* Add some filter predicate expressions to the many property.
|
||||
*/
|
||||
@Nonnull
|
||||
ExpressionList<T> filterMany(String prop);
|
||||
ExpressionList<T> filterMany(String manyProperty);
|
||||
|
||||
/**
|
||||
* Add filter expressions to the many property.
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* DB.find(Customer.class)
|
||||
* .where()
|
||||
* .eq("name", "Rob")
|
||||
* .filterMany("orders", "status = ?", Status.NEW)
|
||||
* .findList();
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @param manyProperty The many property
|
||||
* @param expressions Filter expressions with and, or and ? or ?1 type bind parameters
|
||||
* @param params Bind parameters used in the expressions
|
||||
*/
|
||||
ExpressionList<T> filterMany(String manyProperty, String expressions, Object... params);
|
||||
|
||||
/**
|
||||
* Specify specific properties to fetch on the main/root bean (aka partial
|
||||
@@ -540,14 +557,14 @@ public interface ExpressionList<T> {
|
||||
*
|
||||
* @see Query#setFirstRow(int)
|
||||
*/
|
||||
Query<T> setFirstRow(int firstRow);
|
||||
ExpressionList<T> setFirstRow(int firstRow);
|
||||
|
||||
/**
|
||||
* Set the maximum number of rows to fetch.
|
||||
*
|
||||
* @see Query#setMaxRows(int)
|
||||
*/
|
||||
Query<T> setMaxRows(int maxRows);
|
||||
ExpressionList<T> setMaxRows(int maxRows);
|
||||
|
||||
/**
|
||||
* Set the name of the property which values become the key of a map.
|
||||
@@ -663,6 +680,14 @@ public interface ExpressionList<T> {
|
||||
*/
|
||||
ExpressionList<T> where();
|
||||
|
||||
/**
|
||||
* Add the expressions to this expression list.
|
||||
*
|
||||
* @param expressions The expressions that are parsed and added to this expression list
|
||||
* @param params Bind parameters to match ? or ?1 bind positions.
|
||||
*/
|
||||
ExpressionList<T> where(String expressions, Object... params);
|
||||
|
||||
/**
|
||||
* Path exists - for the given path in a JSON document.
|
||||
* <pre>{@code
|
||||
@@ -831,9 +856,9 @@ public interface ExpressionList<T> {
|
||||
*/
|
||||
ExpressionList<T> inRange(String propertyName, Object value1, Object value2);
|
||||
|
||||
/**
|
||||
* Between - property between the two given values.
|
||||
*/
|
||||
/**
|
||||
* Between - property between the two given values.
|
||||
*/
|
||||
ExpressionList<T> between(String propertyName, Object value1, Object value2);
|
||||
|
||||
/**
|
||||
@@ -1327,7 +1352,7 @@ public interface ExpressionList<T> {
|
||||
*
|
||||
* }</pre>
|
||||
* <p>
|
||||
* Note that we need to cast the Postgres array for UUID types like:
|
||||
* Note that we need to cast the Postgres array for UUID types like:
|
||||
* </p>
|
||||
* <pre>{@code
|
||||
*
|
||||
@@ -1335,7 +1360,7 @@ public interface ExpressionList<T> {
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @param raw The raw expression that is typically a subquery
|
||||
* @param raw The raw expression that is typically a subquery
|
||||
* @param values The values which is typically a list or set of id values.
|
||||
*/
|
||||
ExpressionList<T> rawOrEmpty(String raw, Collection<?> values);
|
||||
@@ -1424,7 +1449,7 @@ public interface ExpressionList<T> {
|
||||
* .eq("status", Customer.Status.ACTIVE)
|
||||
* .gt("id", 0)
|
||||
* .endAnd()
|
||||
* .orderBy().asc("name")
|
||||
* .order().asc("name")
|
||||
* .findList();
|
||||
* }</pre>
|
||||
*/
|
||||
@@ -1445,7 +1470,7 @@ public interface ExpressionList<T> {
|
||||
* .or()
|
||||
* .eq("status", Customer.Status.ACTIVE)
|
||||
* .isNull("anniversary")
|
||||
* .orderBy().asc("name")
|
||||
* .order().asc("name")
|
||||
* .findList();
|
||||
*
|
||||
* }</pre>
|
||||
@@ -1465,7 +1490,7 @@ public interface ExpressionList<T> {
|
||||
* .eq("status", Customer.Status.ACTIVE)
|
||||
* .gt("id", 0)
|
||||
* .endAnd()
|
||||
* .orderBy().asc("name")
|
||||
* .order().asc("name")
|
||||
* .findList();
|
||||
*
|
||||
* }</pre>
|
||||
@@ -1499,7 +1524,7 @@ public interface ExpressionList<T> {
|
||||
* .gt("id", 1)
|
||||
* .eq("anniversary", onAfter)
|
||||
* .endNot()
|
||||
* .orderBy()
|
||||
* .order()
|
||||
* .asc("name")
|
||||
* .findList();
|
||||
*
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.ebeaninternal.api.SpiQuery;
|
||||
import io.ebeaninternal.api.SpiTransaction;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.NonUniqueResultException;
|
||||
@@ -13,6 +10,7 @@ import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* The extended API for Database.
|
||||
@@ -69,7 +67,7 @@ public interface ExtendedServer {
|
||||
*
|
||||
* @return True if the query finds a matching row in the database
|
||||
*/
|
||||
<T> boolean exists(SpiQuery<?> ormQuery, SpiTransaction transaction);
|
||||
<T> boolean exists(Query<?> ormQuery, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Return the number of 'top level' or 'root' entities this query should return.
|
||||
@@ -107,6 +105,24 @@ public interface ExtendedServer {
|
||||
@Nonnull
|
||||
<T> QueryIterator<T> findIterate(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Return the query result as a Stream using a single persistence context.
|
||||
* <p>
|
||||
* Note that the stream needs to be closed so use with try with resources.
|
||||
* </p>
|
||||
*/
|
||||
@Nonnull
|
||||
<T> Stream<T> findStream(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Return the query result as a Stream (with multiple persistence contexts).
|
||||
* <p>
|
||||
* Note that the stream needs to be closed so use with try with resources.
|
||||
* </p>
|
||||
*/
|
||||
@Nonnull
|
||||
<T> Stream<T> findLargeStream(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Execute the query visiting the each bean one at a time.
|
||||
* <p>
|
||||
@@ -341,7 +357,7 @@ public interface ExtendedServer {
|
||||
* List<String> names =
|
||||
* DB.find(Customer.class)
|
||||
* .select("name")
|
||||
* .orderBy().asc("name")
|
||||
* .order().asc("name")
|
||||
* .findSingleAttributeList();
|
||||
*
|
||||
* }</pre>
|
||||
@@ -353,7 +369,7 @@ public interface ExtendedServer {
|
||||
* .setDistinct(true)
|
||||
* .select("name")
|
||||
* .where().eq("status", Customer.Status.NEW)
|
||||
* .orderBy().asc("name")
|
||||
* .order().asc("name")
|
||||
* .setMaxRows(100)
|
||||
* .findSingleAttributeList();
|
||||
*
|
||||
|
||||
@@ -148,6 +148,8 @@ public class FetchConfig implements Serializable {
|
||||
|
||||
private boolean queryAll;
|
||||
|
||||
private boolean cache;
|
||||
|
||||
/**
|
||||
* Construct the fetch configuration object.
|
||||
*/
|
||||
@@ -188,6 +190,17 @@ public class FetchConfig implements Serializable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Eagerly fetch the beans fetching the beans from the L2 bean cache
|
||||
* and using the DB for beans not in the cache.
|
||||
*/
|
||||
public FetchConfig cache() {
|
||||
this.cache = true;
|
||||
this.queryBatchSize = 0;
|
||||
this.queryAll = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Eagerly fetch the beans in this path as a separate query (rather than as
|
||||
* part of the main query).
|
||||
@@ -247,6 +260,13 @@ public class FetchConfig implements Serializable {
|
||||
return queryAll;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this uses L2 bean cache.
|
||||
*/
|
||||
public boolean isCache() {
|
||||
return cache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
@@ -255,6 +275,7 @@ public class FetchConfig implements Serializable {
|
||||
FetchConfig that = (FetchConfig) o;
|
||||
if (lazyBatchSize != that.lazyBatchSize) return false;
|
||||
if (queryBatchSize != that.queryBatchSize) return false;
|
||||
if (cache != that.cache) return false;
|
||||
return queryAll == that.queryAll;
|
||||
}
|
||||
|
||||
@@ -263,6 +284,7 @@ public class FetchConfig implements Serializable {
|
||||
int result = lazyBatchSize;
|
||||
result = 92821 * result + queryBatchSize;
|
||||
result = 92821 * result + (queryAll ? 1 : 0);
|
||||
result = 92821 * result + (cache ? 1 : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.ebean.service.SpiFetchGroupQuery;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
@@ -111,4 +113,11 @@ public interface FetchGroup<T> {
|
||||
return XServiceProvider.fetchGroupOf(cls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a query to be used by query beans for constructing FetchGroup.
|
||||
*/
|
||||
static <T> SpiFetchGroupQuery<T> queryFor(Class<T> beanType) {
|
||||
return XServiceProvider.fetchGroupQueryFor(beanType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -67,12 +67,26 @@ public interface FetchGroupBuilder<T> {
|
||||
@Nonnull
|
||||
FetchGroupBuilder<T> fetchQuery(String path);
|
||||
|
||||
/**
|
||||
* Fetch the path including all its properties using L2 cache.
|
||||
* Cache misses fallback to fetchQuery().
|
||||
*/
|
||||
@Nonnull
|
||||
FetchGroupBuilder<T> fetchCache(String path);
|
||||
|
||||
/**
|
||||
* Fetch the path including specified properties using a query join.
|
||||
*/
|
||||
@Nonnull
|
||||
FetchGroupBuilder<T> fetchQuery(String path, String properties);
|
||||
|
||||
/**
|
||||
* Fetch the path including specified properties using L2 cache.
|
||||
* Cache misses fallback to fetchQuery().
|
||||
*/
|
||||
@Nonnull
|
||||
FetchGroupBuilder<T> fetchCache(String path, String properties);
|
||||
|
||||
/**
|
||||
* Fetch the path including all its properties lazily.
|
||||
*/
|
||||
|
||||
@@ -86,7 +86,7 @@ public interface Filter<T> {
|
||||
* expressions.
|
||||
* </p>
|
||||
* <p>
|
||||
* Refer to {@link Ebean#sort(List, String)} for more detail.
|
||||
* Refer to {@link DB#sort(List, String)} for more detail.
|
||||
* </p>
|
||||
*/
|
||||
Filter<T> sort(String sortByClause);
|
||||
|
||||
@@ -32,7 +32,7 @@ import java.util.List;
|
||||
* public List<Customer> findNew() {
|
||||
* return query().where()
|
||||
* .eq("status", Customer.Status.NEW)
|
||||
* .orderBy("name")
|
||||
* .order("name")
|
||||
* .findList()
|
||||
* }
|
||||
* }
|
||||
|
||||
@@ -192,6 +192,13 @@ public abstract class Model {
|
||||
db().save(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save this entity with an explicit transaction.
|
||||
*/
|
||||
public void save(Transaction transaction) {
|
||||
db().save(this, transaction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush any batched changes to the database.
|
||||
* <p>
|
||||
@@ -212,6 +219,13 @@ public abstract class Model {
|
||||
db().update(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update this entity with an explicit transaction.
|
||||
*/
|
||||
public void update(Transaction transaction) {
|
||||
db().update(this, transaction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert this entity.
|
||||
*
|
||||
@@ -221,6 +235,13 @@ public abstract class Model {
|
||||
db().insert(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert with an explicit transaction.
|
||||
*/
|
||||
public void insert(Transaction transaction) {
|
||||
db().insert(this, transaction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete this bean.
|
||||
* <p>
|
||||
@@ -242,6 +263,13 @@ public abstract class Model {
|
||||
return db().delete(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete this entity with an explicit transaction.
|
||||
*/
|
||||
public boolean delete(Transaction transaction) {
|
||||
return db().delete(this, transaction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a bean permanently without soft delete.
|
||||
* <p>
|
||||
@@ -255,6 +283,13 @@ public abstract class Model {
|
||||
return db().deletePermanent(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a bean permanently without soft delete using an explicit transaction.
|
||||
*/
|
||||
public boolean deletePermanent(Transaction transaction) {
|
||||
return db().deletePermanent(this, transaction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes this entity from the database.
|
||||
*
|
||||
|
||||
@@ -80,7 +80,6 @@ public final class OrderBy<T> implements Serializable {
|
||||
* Add a property with ascending order to this OrderBy.
|
||||
*/
|
||||
public Query<T> asc(String propertyName, String collation) {
|
||||
|
||||
list.add(new Property(propertyName, true, collation));
|
||||
return query;
|
||||
}
|
||||
@@ -89,7 +88,6 @@ public final class OrderBy<T> implements Serializable {
|
||||
* Add a property with descending order to this OrderBy.
|
||||
*/
|
||||
public Query<T> desc(String propertyName) {
|
||||
|
||||
list.add(new Property(propertyName, false));
|
||||
return query;
|
||||
}
|
||||
@@ -98,7 +96,6 @@ public final class OrderBy<T> implements Serializable {
|
||||
* Add a property with descending order to this OrderBy.
|
||||
*/
|
||||
public Query<T> desc(String propertyName, String collation) {
|
||||
|
||||
list.add(new Property(propertyName, false, collation));
|
||||
return query;
|
||||
}
|
||||
@@ -108,7 +105,6 @@ public final class OrderBy<T> implements Serializable {
|
||||
* Return true if the property is known to be contained in the order by clause.
|
||||
*/
|
||||
public boolean containsProperty(String propertyName) {
|
||||
|
||||
for (Property aList : list) {
|
||||
if (propertyName.equals(aList.getProperty())) {
|
||||
return true;
|
||||
@@ -161,10 +157,9 @@ public final class OrderBy<T> implements Serializable {
|
||||
* Return a copy of the OrderBy.
|
||||
*/
|
||||
public OrderBy<T> copy() {
|
||||
|
||||
OrderBy<T> copy = new OrderBy<>();
|
||||
for (Property aList : list) {
|
||||
copy.add(aList.copy());
|
||||
for (Property property : list) {
|
||||
copy.add(property.copy());
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
@@ -241,6 +236,18 @@ public final 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.
|
||||
*/
|
||||
@@ -401,6 +408,12 @@ public final 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) {
|
||||
|
||||
@@ -60,6 +60,13 @@ import java.util.concurrent.Future;
|
||||
*/
|
||||
public interface PagedList<T> {
|
||||
|
||||
/**
|
||||
* Return an empty PagedList.
|
||||
*/
|
||||
static <B> PagedList<B> emptyList() {
|
||||
return new EmptyPagedList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiate the loading of the total row count in the background.
|
||||
* <pre>{@code
|
||||
|
||||
@@ -30,7 +30,7 @@ import java.util.List;
|
||||
* .where()
|
||||
* .eq("store", "def")
|
||||
* .inPairs(pairs) // IN clause with 'pairs' of values
|
||||
* .orderBy("sku desc")
|
||||
* .order("sku desc")
|
||||
*
|
||||
* // query expressions cover the natural key properties
|
||||
* // so we can choose to hit the L2 bean cache if we want
|
||||
|
||||
@@ -1,38 +1,36 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.ebean.config.properties.PropertiesLoader;
|
||||
import io.avaje.config.Config;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Provides singleton state for the default server.
|
||||
* Provides singleton state for the default database.
|
||||
* <p/>
|
||||
* Intended for internal use as part of bootup, construction, registration of the default server.
|
||||
* Intended for internal use as part of bootup, construction, registration of the default database.
|
||||
*/
|
||||
class PrimaryServer {
|
||||
|
||||
private static Properties globalProperties;
|
||||
|
||||
private static String defaultServerName;
|
||||
|
||||
private static boolean skip;
|
||||
|
||||
/**
|
||||
* Set whether to skip automatically creating the primary server.
|
||||
* Set whether to skip automatically creating the primary database.
|
||||
*/
|
||||
static synchronized void setSkip(boolean skip) {
|
||||
PrimaryServer.skip = skip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true to skip automatically creating the primary server.
|
||||
* Return true to skip automatically creating the primary database.
|
||||
*/
|
||||
static synchronized boolean isSkip() {
|
||||
return skip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default server name.
|
||||
* Return the default database name.
|
||||
*/
|
||||
static synchronized String getDefaultServerName() {
|
||||
getProperties();
|
||||
@@ -43,14 +41,10 @@ class PrimaryServer {
|
||||
* Return the default configuration Properties.
|
||||
*/
|
||||
static synchronized Properties getProperties() {
|
||||
if (globalProperties == null) {
|
||||
globalProperties = PropertiesLoader.load();
|
||||
}
|
||||
if (defaultServerName == null) {
|
||||
defaultServerName = determineDefaultServerName();
|
||||
}
|
||||
return globalProperties;
|
||||
|
||||
return Config.asProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,15 +56,9 @@ class PrimaryServer {
|
||||
defaultServerName = System.getProperty("db", defaultServerName);
|
||||
defaultServerName = System.getProperty("ebean_db", defaultServerName);
|
||||
if (isEmpty(defaultServerName)) {
|
||||
defaultServerName = System.getProperty("datasource.default");
|
||||
defaultServerName = Config.get("datasource.default", null);
|
||||
if (isEmpty(defaultServerName)) {
|
||||
defaultServerName = System.getProperty("ebean.default.datasource");
|
||||
if (isEmpty(defaultServerName)) {
|
||||
defaultServerName = globalProperties.getProperty("datasource.default");
|
||||
if (isEmpty(defaultServerName)) {
|
||||
defaultServerName = globalProperties.getProperty("ebean.default.datasource");
|
||||
}
|
||||
}
|
||||
defaultServerName = Config.get("ebean.default.datasource", null);
|
||||
}
|
||||
}
|
||||
if (defaultServerName == null) {
|
||||
|
||||
@@ -31,22 +31,37 @@ public interface ProfileLocation {
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the location description.
|
||||
* Obtain the description returning true if this is the initial call.
|
||||
*/
|
||||
String obtain();
|
||||
boolean obtain();
|
||||
|
||||
/**
|
||||
* Return a short version of the location description.
|
||||
*/
|
||||
String shortDescription();
|
||||
String location();
|
||||
|
||||
/**
|
||||
* Return the short label.
|
||||
*/
|
||||
String label();
|
||||
|
||||
/**
|
||||
* Return the full location.
|
||||
*/
|
||||
String fullLocation();
|
||||
|
||||
/**
|
||||
* Add execution time.
|
||||
*/
|
||||
void add(long executionTime);
|
||||
|
||||
/**
|
||||
* Return true if this request should be traced.
|
||||
*/
|
||||
boolean trace();
|
||||
|
||||
/**
|
||||
* Set the number of times to trace the transactions for this profile location.
|
||||
*/
|
||||
void setTraceCount(int traceCount);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Object relational query for finding a List, Set, Map or single entity bean.
|
||||
@@ -24,7 +25,7 @@ import java.util.function.Predicate;
|
||||
* .where()
|
||||
* .like("customer.name","rob%")
|
||||
* .gt("orderDate",lastWeek)
|
||||
* .orderBy("customer.id, id desc")
|
||||
* .order("customer.id, id desc")
|
||||
* .setMaxRows(50)
|
||||
* .findList();
|
||||
*
|
||||
@@ -501,6 +502,14 @@ public interface Query<T> {
|
||||
*/
|
||||
Query<T> fetchQuery(String path, String fetchProperties);
|
||||
|
||||
/**
|
||||
* Fetch the path and properties using L2 bean cache.
|
||||
*
|
||||
* @param path The path of the beans we are fetching from L2 cache.
|
||||
* @param fetchProperties The properties that should be loaded.
|
||||
*/
|
||||
Query<T> fetchCache(String path, String fetchProperties);
|
||||
|
||||
/**
|
||||
* Fetch the path and properties lazily (via batch lazy loading).
|
||||
* <p>
|
||||
@@ -587,6 +596,11 @@ public interface Query<T> {
|
||||
*/
|
||||
Query<T> fetchQuery(String path);
|
||||
|
||||
/**
|
||||
* Fetch the path eagerly using L2 cache.
|
||||
*/
|
||||
Query<T> fetchCache(String path);
|
||||
|
||||
/**
|
||||
* Fetch the path lazily (via batch lazy loading).
|
||||
* <p>
|
||||
@@ -642,6 +656,11 @@ public interface Query<T> {
|
||||
*/
|
||||
Query<T> usingConnection(Connection connection);
|
||||
|
||||
/**
|
||||
* Execute the query using the given database.
|
||||
*/
|
||||
Query<T> usingDatabase(Database database);
|
||||
|
||||
/**
|
||||
* Execute the query returning the list of Id's.
|
||||
* <p>
|
||||
@@ -689,6 +708,49 @@ public interface Query<T> {
|
||||
@Nonnull
|
||||
QueryIterator<T> findIterate();
|
||||
|
||||
/**
|
||||
* Execute the query returning the result as a Stream.
|
||||
* <p>
|
||||
* Note that this will hold all resulting beans in memory using a single
|
||||
* persistence context. Use findLargeStream() for queries that expect to
|
||||
* return a large number of results.
|
||||
* </p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* // use try with resources to ensure Stream is closed
|
||||
*
|
||||
* try (Stream<Customer> stream = query.findStream()) {
|
||||
* stream
|
||||
* .map(...)
|
||||
* .collect(...);
|
||||
* }
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
@Nonnull
|
||||
Stream<T> findStream();
|
||||
|
||||
/**
|
||||
* Execute the query returning the result as a Stream.
|
||||
* <p>
|
||||
* Note that this uses multiple persistence contexts such that we can use
|
||||
* it with a large number of results.
|
||||
* </p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* // use try with resources to ensure Stream is closed
|
||||
*
|
||||
* try (Stream<Customer> stream = query.findLargeStream()) {
|
||||
* stream
|
||||
* .map(...)
|
||||
* .collect(...);
|
||||
* }
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
@Nonnull
|
||||
Stream<T> findLargeStream();
|
||||
|
||||
/**
|
||||
* Execute the query processing the beans one at a time.
|
||||
* <p>
|
||||
@@ -828,7 +890,7 @@ public interface Query<T> {
|
||||
* List<String> names =
|
||||
* DB.find(Customer.class)
|
||||
* .select("name")
|
||||
* .orderBy().asc("name")
|
||||
* .order().asc("name")
|
||||
* .findSingleAttributeList();
|
||||
*
|
||||
* }</pre>
|
||||
@@ -841,7 +903,7 @@ public interface Query<T> {
|
||||
* .setDistinct(true)
|
||||
* .select("name")
|
||||
* .where().eq("status", Customer.Status.NEW)
|
||||
* .orderBy().asc("name")
|
||||
* .order().asc("name")
|
||||
* .setMaxRows(100)
|
||||
* .findSingleAttributeList();
|
||||
*
|
||||
@@ -1126,6 +1188,30 @@ public interface Query<T> {
|
||||
*/
|
||||
Query<T> setParameter(int position, Object value);
|
||||
|
||||
/**
|
||||
* Bind the next positioned parameter.
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* // a query with a positioned parameters
|
||||
* String oql = "where status = ? and name = ?";
|
||||
*
|
||||
* List<Order> list = DB.createQuery(Order.class, oql)
|
||||
* .setParameter(OrderStatus.NEW)
|
||||
* .setParameter("Rob")
|
||||
* .findList();
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
Query<T> setParameter(Object value);
|
||||
|
||||
/**
|
||||
* Bind all the positioned parameters.
|
||||
* <p>
|
||||
* A convenience for multiple calls to {@link #setParameter(Object)}
|
||||
*/
|
||||
Query<T> setParameters(Object... values);
|
||||
|
||||
/**
|
||||
* Set the Id value to query. This is used with findOne().
|
||||
* <p>
|
||||
@@ -1266,17 +1352,9 @@ public interface Query<T> {
|
||||
Query<T> having(Expression addExpressionToHaving);
|
||||
|
||||
/**
|
||||
* Set the order by clause replacing the existing order by clause if there is
|
||||
* one.
|
||||
* <p>
|
||||
* This follows SQL syntax using commas between each property with the
|
||||
* optional asc and desc keywords representing ascending and descending order
|
||||
* respectively.
|
||||
* </p>
|
||||
* <p>
|
||||
* This is EXACTLY the same as {@link #order(String)}.
|
||||
* </p>
|
||||
* Deprecated migrate to {@link #order(String)}
|
||||
*/
|
||||
@Deprecated
|
||||
Query<T> orderBy(String orderByClause);
|
||||
|
||||
/**
|
||||
@@ -1286,10 +1364,6 @@ public interface Query<T> {
|
||||
* This follows SQL syntax using commas between each property with the
|
||||
* optional asc and desc keywords representing ascending and descending order
|
||||
* respectively.
|
||||
* </p>
|
||||
* <p>
|
||||
* This is EXACTLY the same as {@link #orderBy(String)}.
|
||||
* </p>
|
||||
*/
|
||||
Query<T> order(String orderByClause);
|
||||
|
||||
@@ -1299,40 +1373,24 @@ public interface Query<T> {
|
||||
* <p>
|
||||
* This will never return a null. If no order by clause exists then an 'empty'
|
||||
* OrderBy object is returned.
|
||||
* </p>
|
||||
* <p>
|
||||
* This is EXACTLY the same as {@link #orderBy()}.
|
||||
* </p>
|
||||
*/
|
||||
OrderBy<T> order();
|
||||
|
||||
/**
|
||||
* Return the OrderBy so that you can append an ascending or descending
|
||||
* property to the order by clause.
|
||||
* <p>
|
||||
* This will never return a null. If no order by clause exists then an 'empty'
|
||||
* OrderBy object is returned.
|
||||
* </p>
|
||||
* <p>
|
||||
* This is EXACTLY the same as {@link #order()}.
|
||||
* </p>
|
||||
* Deprecated migrate to order().
|
||||
*/
|
||||
@Deprecated
|
||||
OrderBy<T> orderBy();
|
||||
|
||||
/**
|
||||
* Set an OrderBy object to replace any existing OrderBy clause.
|
||||
* <p>
|
||||
* This is EXACTLY the same as {@link #setOrderBy(OrderBy)}.
|
||||
* </p>
|
||||
*/
|
||||
Query<T> setOrder(OrderBy<T> orderBy);
|
||||
|
||||
/**
|
||||
* Set an OrderBy object to replace any existing OrderBy clause.
|
||||
* <p>
|
||||
* This is EXACTLY the same as {@link #setOrder(OrderBy)}.
|
||||
* </p>
|
||||
* Deprecated migrate to {@link #setOrder(OrderBy)}
|
||||
*/
|
||||
@Deprecated
|
||||
Query<T> setOrderBy(OrderBy<T> orderBy);
|
||||
|
||||
/**
|
||||
@@ -1467,17 +1525,6 @@ public interface Query<T> {
|
||||
return setUseQueryCache(enabled ? CacheMode.ON : CacheMode.OFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an id to identify this query for profiling purposes.
|
||||
* <p>
|
||||
* The profileId is expected to be unique for a given bean type.
|
||||
* </p>
|
||||
* <p>
|
||||
* Note that the profileId is treated as a short internally and has a MAX value of 32,767.
|
||||
* </p>
|
||||
*/
|
||||
Query<T> setProfileId(int profileId);
|
||||
|
||||
/**
|
||||
* Set the profile location of this query. This is used to relate query execution metrics
|
||||
* back to a location like a specific line of code.
|
||||
|
||||
@@ -23,9 +23,9 @@ import java.util.Iterator;
|
||||
* <h3>Try finally style</h3>
|
||||
* <pre>{@code
|
||||
*
|
||||
* Query<Customer> query = server.find(Customer.class)
|
||||
* Query<Customer> query = database.find(Customer.class)
|
||||
* .where().gt("id", 0)
|
||||
* .orderBy("id")
|
||||
* .order("id")
|
||||
* .setMaxRows(2);
|
||||
*
|
||||
* QueryIterator<Customer> it = query.findIterate();
|
||||
|
||||
@@ -18,7 +18,7 @@ import java.sql.SQLException;
|
||||
* <pre>{@code
|
||||
*
|
||||
* //
|
||||
* // A mapper from ResultSet into our CustomerDto bean
|
||||
* // Map from ResultSet to CustomerDto bean
|
||||
* //
|
||||
* class CustomerMapper implements RowMapper<CustomerDto> {
|
||||
*
|
||||
@@ -42,7 +42,8 @@ import java.sql.SQLException;
|
||||
*
|
||||
* CustomerDto rob = DB.sqlQuery(sql)
|
||||
* .setParameter(1, "Rob")
|
||||
* .findOne(CUSTOMER_MAPPER);
|
||||
* .mapTo(CUSTOMER_MAPPER)
|
||||
* .findOne();
|
||||
*
|
||||
*
|
||||
* }</pre>
|
||||
|
||||
@@ -50,4 +50,13 @@ public interface ScriptRunner {
|
||||
*/
|
||||
void run(URL resource, Map<String, String> placeholderMap);
|
||||
|
||||
/**
|
||||
* Run the raw provided DDL or SQL script.
|
||||
*
|
||||
* @param name The name of the script for logging purposes
|
||||
* @param content The SQL content
|
||||
* @param useAutoCommit Set to true to use auto commit true and continue when any errors occur
|
||||
*/
|
||||
void runScript(String name, String content, boolean useAutoCommit);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package io.ebean;
|
||||
|
||||
import javax.persistence.OptimisticLockException;
|
||||
|
||||
/**
|
||||
* Thrown at SERIALIZABLE isolation level for non-recoverable concurrent conflict.
|
||||
*/
|
||||
public class SerializableConflictException extends OptimisticLockException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Create with a message and cause.
|
||||
*/
|
||||
public SerializableConflictException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@@ -75,17 +75,15 @@ public interface SqlQuery extends Serializable {
|
||||
SqlRow findOne();
|
||||
|
||||
/**
|
||||
* Execute the query returning a single result using the mapper.
|
||||
*
|
||||
* @param mapper Used to map each ResultSet row into the result object.
|
||||
* Deprecated migrate to use {@link #mapTo(RowMapper)}
|
||||
*/
|
||||
@Deprecated
|
||||
<T> T findOne(RowMapper<T> mapper);
|
||||
|
||||
/**
|
||||
* Execute the query returning a list using the mapper.
|
||||
*
|
||||
* @param mapper Used to map each ResultSet row into the result object.
|
||||
* Deprecated migrate to use {@link #mapTo(RowMapper)}
|
||||
*/
|
||||
@Deprecated
|
||||
<T> List<T> findList(RowMapper<T> mapper);
|
||||
|
||||
/**
|
||||
@@ -125,77 +123,53 @@ public interface SqlQuery extends Serializable {
|
||||
Optional<SqlRow> findOneOrEmpty();
|
||||
|
||||
/**
|
||||
* Execute the query returning a single scalar attribute.
|
||||
* <pre>@{code
|
||||
* Deprecated - migrate to <code>.mapToScalar(attributeType).findOne()</code>.
|
||||
* <pre>{@code
|
||||
*
|
||||
* String sql = "select max(unit_price) from o_order_detail where order_qty > ?";
|
||||
*
|
||||
* BigDecimal maxPrice = DB.sqlQuery(sql)
|
||||
* .setParameter(1, 2)
|
||||
* .findSingleAttribute(BigDecimal.class);
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* The attributeType can be any scalar type that Ebean supports (includes javax time types, Joda types etc).
|
||||
* </p>
|
||||
*
|
||||
* @param attributeType The type of the returned value
|
||||
* .mapToScalar(BigDecimal.class)
|
||||
* .findOne();
|
||||
* }
|
||||
*/
|
||||
@Deprecated
|
||||
<T> T findSingleAttribute(Class<T> attributeType);
|
||||
|
||||
/**
|
||||
* Execute the query returning a single BigDecimal value.
|
||||
* <p>
|
||||
* This is an alias for <code>findSingleAttribute(BigDecimal.class)</code>
|
||||
* </p>
|
||||
* Deprecated - migrate to <code>.mapToScalar(BigDecimal.class).findOne()</code>.
|
||||
* <pre>{@code
|
||||
*
|
||||
* .mapToScalar(BigDecimal.class)
|
||||
* .findOne();
|
||||
* }
|
||||
*/
|
||||
@Deprecated
|
||||
BigDecimal findSingleDecimal();
|
||||
|
||||
/**
|
||||
* Execute the query returning a single Long value.
|
||||
* <p>
|
||||
* This is an alias for <code>findSingleAttribute(Long.class)</code>
|
||||
* </p>
|
||||
* Deprecated - migrate to <code>.mapToScalar(Long.class).findOne()</code>.
|
||||
* <pre>{@code
|
||||
*
|
||||
* .mapToScalar(Long.class)
|
||||
* .findOne();
|
||||
* }
|
||||
*/
|
||||
@Deprecated
|
||||
Long findSingleLong();
|
||||
|
||||
/**
|
||||
* Execute the query returning a list of scalar attribute values.
|
||||
*
|
||||
* Deprecated - migrate to <code>.mapToScalar(Long.class).findList()</code>.
|
||||
* <pre>{@code
|
||||
*
|
||||
* String sql =
|
||||
* " select (unit_price * order_qty) " +
|
||||
* " from o_order_detail " +
|
||||
* " where unit_price > ? " +
|
||||
* " order by (unit_price * order_qty) desc";
|
||||
*
|
||||
* //
|
||||
* List<BigDecimal> lineAmounts =
|
||||
* DB.sqlQuery(sql)
|
||||
* .setParameter(1, 3)
|
||||
* .findSingleAttributeList(BigDecimal.class);
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* The attributeType can be any scalar type that Ebean supports (includes javax time types, Joda types etc).
|
||||
* </p>
|
||||
*
|
||||
* @param attributeType The type of the returned value
|
||||
* .mapToScalar(Long.class)
|
||||
* .findList();
|
||||
* }
|
||||
*/
|
||||
@Deprecated
|
||||
<T> List<T> findSingleAttributeList(Class<T> attributeType);
|
||||
|
||||
/**
|
||||
* The same as bind for named parameters.
|
||||
*/
|
||||
SqlQuery setParameter(String name, Object value);
|
||||
|
||||
/**
|
||||
* Set one of more positioned parameters.
|
||||
* <p>
|
||||
* This is a convenient alternative to multiple calls setParameter().
|
||||
* This is a convenient alternative to multiple calls to {@link #setParameter(Object)}.
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
@@ -203,27 +177,67 @@ public interface SqlQuery extends Serializable {
|
||||
*
|
||||
* List<SqlRow> list =
|
||||
* DB.sqlQuery(sql)
|
||||
* .setParams("Rob", Status.NEW)
|
||||
* .setParameters("Rob", Status.NEW)
|
||||
* .findList();
|
||||
*
|
||||
*
|
||||
* // is the same as ...
|
||||
* // effectively the same as ...
|
||||
*
|
||||
* .setParameter("Rob")
|
||||
* .setParameter("Status.NEW)
|
||||
*
|
||||
* // and ...
|
||||
*
|
||||
* List<SqlRow> list =
|
||||
* DB.sqlQuery(sql)
|
||||
* .setParameter(1, "Rob")
|
||||
* .setParameter(2, "Status.NEW)
|
||||
* .findList();
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
SqlQuery setParameters(Object... values);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to setParameters(Object... values)
|
||||
*/
|
||||
@Deprecated
|
||||
SqlQuery setParams(Object... values);
|
||||
|
||||
/**
|
||||
* The same as bind for positioned parameters.
|
||||
* Set the next bind parameter by position.
|
||||
* <pre>{@code
|
||||
*
|
||||
* String sql = "select id, name from customer where name like ? and status = ?";
|
||||
*
|
||||
* List<SqlRow> list =
|
||||
* DB.sqlQuery(sql)
|
||||
* .setParameter("Rob")
|
||||
* .setParameter("Status.NEW)
|
||||
* .findList();
|
||||
*
|
||||
* // the same as ...
|
||||
*
|
||||
* .setParameters("Rob", Status.NEW)
|
||||
*
|
||||
* // and ...
|
||||
*
|
||||
* .setParameter(1, "Rob")
|
||||
* .setParameter(2, "Status.NEW)
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @param value The value to bind
|
||||
*/
|
||||
SqlQuery setParameter(Object value);
|
||||
|
||||
/**
|
||||
* Bind the parameter by its index position (1 based like JDBC).
|
||||
*/
|
||||
SqlQuery setParameter(int position, Object value);
|
||||
|
||||
/**
|
||||
* Bind the named parameter value.
|
||||
*/
|
||||
SqlQuery setParameter(String name, Object value);
|
||||
|
||||
/**
|
||||
* Set the index of the first row of the results to return.
|
||||
*/
|
||||
@@ -260,4 +274,59 @@ public interface SqlQuery extends Serializable {
|
||||
*/
|
||||
SqlQuery setBufferFetchSizeHint(int bufferFetchSizeHint);
|
||||
|
||||
/**
|
||||
* The query result maps to a single scalar value like Long, BigDecimal,
|
||||
* String, UUID, OffsetDateTime etc.
|
||||
* <p>
|
||||
* Any scalar type Ebean is aware of can be used including java time
|
||||
* types like Instant, LocalDate, OffsetDateTime, UUID, Inet, Cdir etc.
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* String sql = " select min(updtime) from o_order_detail " +
|
||||
* " where unit_price > ? and updtime is not null ";
|
||||
*
|
||||
* OffsetDateTime minCreated = DB.sqlQuery(sql)
|
||||
* .setParameter(42)
|
||||
* .mapToScalar(OffsetDateTime.class)
|
||||
* .findOne();
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @param attributeType The type the result is returned as
|
||||
* @return The query to execute via findOne() findList() etc
|
||||
*/
|
||||
<T> TypeQuery<T> mapToScalar(Class<T> attributeType);
|
||||
|
||||
/**
|
||||
* Use a RowMapper to map the result to beans.
|
||||
*
|
||||
* @param mapper Maps rows to beans
|
||||
* @param <T> The type of beans mapped to
|
||||
* @return The query to execute by findOne() findList() etc
|
||||
*/
|
||||
<T> TypeQuery<T> mapTo(RowMapper<T> mapper);
|
||||
|
||||
/**
|
||||
* Query mapping to single scalar values.
|
||||
*
|
||||
* @param <T> The type of the scalar values
|
||||
*/
|
||||
interface TypeQuery<T> {
|
||||
|
||||
/**
|
||||
* Return the single value.
|
||||
*/
|
||||
T findOne();
|
||||
|
||||
/**
|
||||
* Return the single value that is optional.
|
||||
*/
|
||||
Optional<T> findOneOrEmpty();
|
||||
|
||||
/**
|
||||
* Return the list of values.
|
||||
*/
|
||||
List<T> findList();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,8 +126,6 @@ public interface SqlUpdate {
|
||||
* {@link Transaction#setBatchMode(boolean)} and
|
||||
* {@link Transaction#setBatchSize(int)}.
|
||||
* </p>
|
||||
*
|
||||
* @see Ebean#execute(SqlUpdate)
|
||||
*/
|
||||
int execute();
|
||||
|
||||
@@ -241,28 +239,47 @@ public interface SqlUpdate {
|
||||
* String sql = "insert into audit_log (id, name, version) values (?,?,?)";
|
||||
*
|
||||
* DB.sqlUpdate(sql)
|
||||
* .setParams(UUID.randomUUID(), "Hello", 1)
|
||||
* .setParameters(UUID.randomUUID(), "Hello", 1)
|
||||
* .executeNow();
|
||||
*
|
||||
*
|
||||
* // is the same as ...
|
||||
*
|
||||
* DB.sqlUpdate(sql)
|
||||
* .setParameter(UUID.randomUUID())
|
||||
* .setParameter("Hello")
|
||||
* .setParameter(1)
|
||||
* .executeNow();
|
||||
*
|
||||
* // which is the same as ...
|
||||
*
|
||||
* DB.sqlUpdate(sql)
|
||||
* .setParameter(1, UUID.randomUUID())
|
||||
* .setParameter(2, "Hello")
|
||||
* .setParameter(3, 1)
|
||||
* .executeNow();
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
*/
|
||||
SqlUpdate setParameters(Object... values);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to setParameters(Object... values).
|
||||
*/
|
||||
@Deprecated
|
||||
SqlUpdate setParams(Object... values);
|
||||
|
||||
/**
|
||||
* Set the next positioned parameter.
|
||||
* Set the next bind parameter by position.
|
||||
*
|
||||
* @param value The value to bind
|
||||
*/
|
||||
SqlUpdate setParameter(Object value);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to setParameter(value).
|
||||
*/
|
||||
@Deprecated
|
||||
SqlUpdate setNextParameter(Object value);
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,7 +27,7 @@ public interface Transaction extends AutoCloseable {
|
||||
* @see Database#currentTransaction()
|
||||
*/
|
||||
static Transaction current() {
|
||||
return Ebean.currentTransaction();
|
||||
return DB.currentTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -295,7 +295,7 @@ public interface Transaction extends AutoCloseable {
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* try (Transaction transaction = server.beginTransaction()) {
|
||||
* try (Transaction transaction = database.beginTransaction()) {
|
||||
*
|
||||
* // turn on JDBC batch
|
||||
* transaction.setBatchMode(true);
|
||||
@@ -318,7 +318,7 @@ public interface Transaction extends AutoCloseable {
|
||||
* </p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* try (Transaction transaction = server.beginTransaction()) {
|
||||
* try (Transaction transaction = database.beginTransaction()) {
|
||||
*
|
||||
* transaction.setBatchMode(true);
|
||||
* transaction.setBatchSize(100);
|
||||
|
||||
@@ -12,16 +12,16 @@ import java.util.concurrent.Callable;
|
||||
* <p>
|
||||
* This information matches the features of the Transactional annotation. You
|
||||
* can use it directly with Runnable or Callable via
|
||||
* {@link Ebean#execute(TxScope, Runnable)} or
|
||||
* {@link Ebean#executeCall(TxScope, Callable)}.
|
||||
* {@link DB#execute(TxScope, Runnable)} or
|
||||
* {@link DB#executeCall(TxScope, Callable)}.
|
||||
* </p>
|
||||
* <p>
|
||||
* This object is used internally with the enhancement of a method with
|
||||
* Transactional annotation.
|
||||
* </p>
|
||||
*
|
||||
* @see Ebean#execute(TxScope, Runnable)
|
||||
* @see Ebean#executeCall(TxScope, Callable)
|
||||
* @see DB#execute(TxScope, Runnable)
|
||||
* @see DB#executeCall(TxScope, Callable)
|
||||
*/
|
||||
public final class TxScope {
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.ebean.service.SpiFetchGroupQuery;
|
||||
import io.ebean.service.SpiFetchGroupService;
|
||||
import io.ebean.service.SpiProfileLocationFactory;
|
||||
import io.ebean.service.SpiRawSqlService;
|
||||
@@ -19,29 +20,23 @@ class XServiceProvider {
|
||||
private static SpiFetchGroupService fetchGroupService = initSpiFetchGroupService();
|
||||
|
||||
private static SpiFetchGroupService initSpiFetchGroupService() {
|
||||
Iterator<SpiFetchGroupService> loader = ServiceLoader.load(SpiFetchGroupService.class).iterator();
|
||||
if (loader.hasNext()) {
|
||||
return loader.next();
|
||||
}
|
||||
throw new IllegalStateException("No service implementation found for SpiFetchGroupService?");
|
||||
return loadFirstService(SpiFetchGroupService.class);
|
||||
}
|
||||
|
||||
private static SpiRawSqlService initRawSql() {
|
||||
|
||||
Iterator<SpiRawSqlService> loader = ServiceLoader.load(SpiRawSqlService.class).iterator();
|
||||
if (loader.hasNext()) {
|
||||
return loader.next();
|
||||
}
|
||||
throw new IllegalStateException("No service implementation found for SpiRawSqlService?");
|
||||
return loadFirstService(SpiRawSqlService.class);
|
||||
}
|
||||
|
||||
private static SpiProfileLocationFactory initProfileLocation() {
|
||||
return loadFirstService(SpiProfileLocationFactory.class);
|
||||
}
|
||||
|
||||
Iterator<SpiProfileLocationFactory> loader = ServiceLoader.load(SpiProfileLocationFactory.class).iterator();
|
||||
private static <T> T loadFirstService(Class<T> cls) {
|
||||
Iterator<T> loader = ServiceLoader.load(cls).iterator();
|
||||
if (loader.hasNext()) {
|
||||
return loader.next();
|
||||
}
|
||||
throw new IllegalStateException("No service implementation found for SpiProfileLocationFactory?");
|
||||
throw new IllegalStateException("No service implementation found for " + cls);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,4 +66,11 @@ class XServiceProvider {
|
||||
static <T> FetchGroupBuilder<T> fetchGroupOf(Class<T> cls) {
|
||||
return fetchGroupService.of(cls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the FetchGroup Query for building fetch groups via query beans.
|
||||
*/
|
||||
static <T> SpiFetchGroupQuery<T> fetchGroupQueryFor(Class<T> cls) {
|
||||
return fetchGroupService.queryFor(cls);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package io.ebean.bean;
|
||||
|
||||
/**
|
||||
* A call origin for query execution profiling to collect graph use (for query tuning).
|
||||
*/
|
||||
public interface CallOrigin {
|
||||
|
||||
/**
|
||||
* Return the top element. Typically the top stack element with class and line.
|
||||
*/
|
||||
String getTopElement();
|
||||
|
||||
/**
|
||||
* Return the full description of the call origin.
|
||||
*/
|
||||
String getFullDescription();
|
||||
|
||||
/**
|
||||
* Compute and return an origin key based on the query hash.
|
||||
*/
|
||||
String getOriginKey(int queryHash);
|
||||
}
|
||||
@@ -3,6 +3,8 @@ package io.ebean.bean;
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static io.ebean.util.EncodeB64.enc;
|
||||
|
||||
/**
|
||||
* Represent the call stack (stack trace elements).
|
||||
* <p>
|
||||
@@ -17,15 +19,15 @@ import java.util.Arrays;
|
||||
* Note the call stack is trimmed to remove the common ebean internal elements.
|
||||
* </p>
|
||||
*/
|
||||
public final class CallStack implements Serializable {
|
||||
public final class CallStack implements Serializable, CallOrigin {
|
||||
|
||||
private static final long serialVersionUID = -8590644046907438579L;
|
||||
|
||||
private static final String NEWLINE = "\n";
|
||||
|
||||
private final String zeroHash;
|
||||
private final String pathHash;
|
||||
|
||||
private final StackTraceElement[] callStack;
|
||||
|
||||
private final int hc;
|
||||
|
||||
public CallStack(StackTraceElement[] callStack, int zeroHash, int pathHash) {
|
||||
@@ -37,12 +39,17 @@ public final class CallStack implements Serializable {
|
||||
|
||||
private int computeHashCode() {
|
||||
int hc = 0;
|
||||
for (StackTraceElement aCallStack : callStack) {
|
||||
hc = 92821 * hc + aCallStack.hashCode();
|
||||
for (StackTraceElement element : callStack) {
|
||||
hc = 92821 * hc + element.hashCode();
|
||||
}
|
||||
return hc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return zeroHash + ":" + pathHash + ":" + callStack[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return hc;
|
||||
@@ -63,73 +70,29 @@ public final class CallStack implements Serializable {
|
||||
/**
|
||||
* Return the first element of the call stack.
|
||||
*/
|
||||
public StackTraceElement getFirstStackTraceElement() {
|
||||
return callStack[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the call stack.
|
||||
*/
|
||||
public StackTraceElement[] getCallStack() {
|
||||
return callStack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the hash for the first stack element.
|
||||
*/
|
||||
public String getZeroHash() {
|
||||
return zeroHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the hash for the stack elements (excluding first stack element).
|
||||
*/
|
||||
public String getPathHash() {
|
||||
return pathHash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return zeroHash + ":" + pathHash + ":" + callStack[0];
|
||||
public String getTopElement() {
|
||||
return callStack[0].toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the call stack lines appended with the given newLine string.
|
||||
*/
|
||||
public String description(String newLine) {
|
||||
@Override
|
||||
public String getFullDescription() {
|
||||
StringBuilder sb = new StringBuilder(400);
|
||||
for (StackTraceElement aCallStack : callStack) {
|
||||
sb.append(aCallStack.toString()).append(newLine);
|
||||
for (int i = 0; i < callStack.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(NEWLINE);
|
||||
}
|
||||
sb.append(callStack[i].toString());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOriginKey(int queryHash) {
|
||||
return enc(queryHash) + "." + zeroHash + "." + pathHash;
|
||||
}
|
||||
|
||||
private static final int radix = 1 << 6;
|
||||
private static final int mask = radix - 1;
|
||||
|
||||
/**
|
||||
* Convert the integer to unsigned base 64.
|
||||
*/
|
||||
public static String enc(int i) {
|
||||
char[] buf = new char[32];
|
||||
int charPos = 32;
|
||||
do {
|
||||
buf[--charPos] = intToBase64[i & mask];
|
||||
i >>>= 6;
|
||||
} while (i != 0);
|
||||
|
||||
return new String(buf, charPos, (32 - charPos));
|
||||
}
|
||||
|
||||
private static final char intToBase64[] = {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
||||
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
|
||||
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_'
|
||||
};
|
||||
}
|
||||
|
||||
@@ -16,12 +16,16 @@ public interface EntityBean extends Serializable {
|
||||
/**
|
||||
* Return all the property names in defined order.
|
||||
*/
|
||||
String[] _ebean_getPropertyNames();
|
||||
default String[] _ebean_getPropertyNames() {
|
||||
throw new NotEnhancedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the property name at the given position.
|
||||
*/
|
||||
String _ebean_getPropertyName(int pos);
|
||||
default String _ebean_getPropertyName(int pos) {
|
||||
throw new NotEnhancedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the enhancement marker value.
|
||||
@@ -30,28 +34,38 @@ public interface EntityBean extends Serializable {
|
||||
* entity classes are enhanced (specifically not just a super class).
|
||||
* </p>
|
||||
*/
|
||||
String _ebean_getMarker();
|
||||
default String _ebean_getMarker() {
|
||||
throw new NotEnhancedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return a new entity bean instance.
|
||||
*/
|
||||
Object _ebean_newInstance();
|
||||
default Object _ebean_newInstance() {
|
||||
throw new NotEnhancedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generated method that sets the loaded state on all the embedded beans on
|
||||
* this entity bean by using EntityBeanIntercept.setEmbeddedLoaded(Object o);
|
||||
*/
|
||||
void _ebean_setEmbeddedLoaded();
|
||||
default void _ebean_setEmbeddedLoaded() {
|
||||
throw new NotEnhancedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if any embedded beans are new or dirty.
|
||||
*/
|
||||
boolean _ebean_isEmbeddedNewOrDirty();
|
||||
default boolean _ebean_isEmbeddedNewOrDirty() {
|
||||
throw new NotEnhancedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the intercept for this object.
|
||||
*/
|
||||
EntityBeanIntercept _ebean_getIntercept();
|
||||
default EntityBeanIntercept _ebean_getIntercept() {
|
||||
throw new NotEnhancedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to _ebean_getIntercept() except it checks to see if the intercept
|
||||
@@ -66,7 +80,9 @@ public interface EntityBean extends Serializable {
|
||||
* frameworks that can't take into account our ebean fields.
|
||||
* </p>
|
||||
*/
|
||||
EntityBeanIntercept _ebean_intercept();
|
||||
default EntityBeanIntercept _ebean_intercept() {
|
||||
throw new NotEnhancedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of a field of an entity bean of this type.
|
||||
@@ -75,12 +91,16 @@ public interface EntityBean extends Serializable {
|
||||
* on entity beans. That means lazy loading and oldValues creation.
|
||||
* </p>
|
||||
*/
|
||||
void _ebean_setField(int fieldIndex, Object value);
|
||||
default void _ebean_setField(int fieldIndex, Object value) {
|
||||
throw new NotEnhancedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the field value with interception.
|
||||
*/
|
||||
void _ebean_setFieldIntercept(int fieldIndex, Object value);
|
||||
default void _ebean_setFieldIntercept(int fieldIndex, Object value) {
|
||||
throw new NotEnhancedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value of a field from an entity bean of this type.
|
||||
@@ -89,11 +109,15 @@ public interface EntityBean extends Serializable {
|
||||
* on entity beans. That means lazy loading.
|
||||
* </p>
|
||||
*/
|
||||
Object _ebean_getField(int fieldIndex);
|
||||
default Object _ebean_getField(int fieldIndex) {
|
||||
throw new NotEnhancedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the field value with interception.
|
||||
*/
|
||||
Object _ebean_getFieldIntercept(int fieldIndex);
|
||||
default Object _ebean_getFieldIntercept(int fieldIndex) {
|
||||
throw new NotEnhancedException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.ebean.bean;
|
||||
|
||||
import io.ebean.Ebean;
|
||||
import io.ebean.DB;
|
||||
import io.ebean.Database;
|
||||
import io.ebean.ValuePair;
|
||||
|
||||
import javax.persistence.EntityNotFoundException;
|
||||
@@ -95,27 +96,29 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
private final byte[] flags;
|
||||
|
||||
private boolean fullyLoadedBean;
|
||||
|
||||
private boolean loadedFromCache;
|
||||
private Object[] origValues;
|
||||
|
||||
private Exception[] loadErrors;
|
||||
|
||||
private int lazyLoadProperty = -1;
|
||||
|
||||
private Object ownerId;
|
||||
private int sortOrder;
|
||||
|
||||
/**
|
||||
* Create a intercept with a given entity.
|
||||
* <p>
|
||||
* Refer to agent ProxyConstructor.
|
||||
* </p>
|
||||
*/
|
||||
public EntityBeanIntercept(Object ownerBean) {
|
||||
this.owner = (EntityBean) ownerBean;
|
||||
this.flags = new byte[owner._ebean_getPropertyNames().length];
|
||||
}
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL - Constructor only for use by serialization frameworks.
|
||||
*/
|
||||
public EntityBeanIntercept() {
|
||||
this.owner = null;
|
||||
this.flags = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the 'owning' entity bean.
|
||||
*/
|
||||
@@ -303,6 +306,22 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set true when the bean has been loaded from L2 bean cache.
|
||||
* The effect of this is that we should skip the cache if there
|
||||
* is subsequent lazy loading (bean cache partially populated).
|
||||
*/
|
||||
public void setLoadedFromCache(boolean loadedFromCache) {
|
||||
this.loadedFromCache = loadedFromCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this bean was loaded from L2 bean cache.
|
||||
*/
|
||||
public boolean isLoadedFromCache() {
|
||||
return loadedFromCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the bean should be treated as readOnly. If a setter method
|
||||
* is called when it is readOnly an Exception is thrown.
|
||||
@@ -772,7 +791,7 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
}
|
||||
|
||||
public boolean[] getLoaded() {
|
||||
boolean[] ret= new boolean[flags.length];
|
||||
boolean[] ret = new boolean[flags.length];
|
||||
for (int i = 0; i < ret.length; i++) {
|
||||
ret[i] = (flags[i] & FLAG_LOADED_PROP) != 0;
|
||||
}
|
||||
@@ -800,14 +819,14 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
|
||||
synchronized (this) {
|
||||
if (beanLoader == null) {
|
||||
BeanLoader serverLoader = (BeanLoader) Ebean.getServer(ebeanServerName);
|
||||
if (serverLoader == null) {
|
||||
throw new PersistenceException("Server [" + ebeanServerName + "] was not found?");
|
||||
final Database database = DB.byName(ebeanServerName);
|
||||
if (database == null) {
|
||||
throw new PersistenceException("Database [" + ebeanServerName + "] was not found?");
|
||||
}
|
||||
|
||||
// For stand alone reference bean or after deserialisation lazy load
|
||||
// using the ebeanServer. Synchronise only on the bean.
|
||||
loadBeanInternal(loadProperty, serverLoader);
|
||||
loadBeanInternal(loadProperty, database.getPluginApi());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package io.ebean.bean;
|
||||
|
||||
/**
|
||||
* This exception is thrown, when the default implementation of EntityBean is not or not properly overwritten by enhancer.
|
||||
*
|
||||
* @author Roland Praml, FOCONIS AG
|
||||
*
|
||||
*/
|
||||
public class NotEnhancedException extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.ebean.bean;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Identifies a unique node of an object graph.
|
||||
@@ -85,8 +86,7 @@ public final class ObjectGraphNode implements Serializable {
|
||||
}
|
||||
|
||||
ObjectGraphNode e = (ObjectGraphNode) obj;
|
||||
//noinspection StringEquality
|
||||
return ((e.path == path) || (e.path != null && e.path.equals(path)))
|
||||
return (Objects.equals(e.path, path))
|
||||
&& e.originQueryPoint.equals(originQueryPoint);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ public final class ObjectGraphOrigin implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 410937765287968708L;
|
||||
|
||||
private final CallStack callStack;
|
||||
private final CallOrigin callOrigin;
|
||||
|
||||
private final String beanType;
|
||||
|
||||
@@ -24,11 +24,11 @@ public final class ObjectGraphOrigin implements Serializable {
|
||||
|
||||
private final String key;
|
||||
|
||||
public ObjectGraphOrigin(int queryHash, CallStack callStack, String beanType) {
|
||||
this.callStack = callStack;
|
||||
public ObjectGraphOrigin(int queryHash, CallOrigin callOrigin, String beanType) {
|
||||
this.callOrigin = callOrigin;
|
||||
this.beanType = beanType;
|
||||
this.queryHash = queryHash;
|
||||
this.key = callStack.getOriginKey(queryHash);
|
||||
this.key = callOrigin.getOriginKey(queryHash);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,22 +49,22 @@ public final class ObjectGraphOrigin implements Serializable {
|
||||
/**
|
||||
* The call stack involved.
|
||||
*/
|
||||
public CallStack getCallStack() {
|
||||
return callStack;
|
||||
public CallOrigin getCallOrigin() {
|
||||
return callOrigin;
|
||||
}
|
||||
|
||||
public String getFirstStackElement() {
|
||||
return callStack.getFirstStackTraceElement().toString();
|
||||
public String getTopElement() {
|
||||
return callOrigin.getTopElement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "key[" + key + "] type[" + beanType + "] " + callStack.getFirstStackTraceElement() + " ";
|
||||
return "key[" + key + "] type[" + beanType + "] " + callOrigin.getTopElement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hc = 92821 * callStack.hashCode();
|
||||
int hc = 92821 * callOrigin.hashCode();
|
||||
hc = 92821 * hc + beanType.hashCode();
|
||||
hc = 92821 * hc + queryHash;
|
||||
return hc;
|
||||
@@ -82,6 +82,6 @@ public final class ObjectGraphOrigin implements Serializable {
|
||||
ObjectGraphOrigin e = (ObjectGraphOrigin) obj;
|
||||
return e.queryHash == queryHash
|
||||
&& e.beanType.equals(beanType)
|
||||
&& e.callStack.equals(callStack);
|
||||
&& e.callOrigin.equals(callOrigin);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package io.ebean.bean;
|
||||
|
||||
import io.ebean.Database;
|
||||
|
||||
/**
|
||||
* BeanLoader used when single beans are loaded (which is usually not ideal / N+1).
|
||||
*/
|
||||
public abstract class SingleBeanLoader implements BeanLoader {
|
||||
|
||||
protected final Database database;
|
||||
|
||||
SingleBeanLoader(Database database) {
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return database.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Single bean lazy loaded when bean from L2 cache.
|
||||
*/
|
||||
public static class L2 extends SingleBeanLoader {
|
||||
public L2(Database database) {
|
||||
super(database);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadBean(EntityBeanIntercept ebi) {
|
||||
database.getPluginApi().loadBeanL2(ebi);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Single bean lazy loaded when a reference bean.
|
||||
*/
|
||||
public static class Ref extends SingleBeanLoader {
|
||||
public Ref(Database database) {
|
||||
super(database);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadBean(EntityBeanIntercept ebi) {
|
||||
database.getPluginApi().loadBeanRef(ebi);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,22 +10,15 @@ import java.util.Set;
|
||||
*/
|
||||
public class ServerCacheNotification {
|
||||
|
||||
private final long modifyTimestamp;
|
||||
|
||||
private final Set<String> dependentTables;
|
||||
|
||||
public ServerCacheNotification(long modifyTimestamp, Set<String> dependentTables) {
|
||||
this.modifyTimestamp = modifyTimestamp;
|
||||
public ServerCacheNotification(Set<String> dependentTables) {
|
||||
this.dependentTables = dependentTables;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ts:" + modifyTimestamp + " tables:" + dependentTables;
|
||||
}
|
||||
|
||||
public long getModifyTimestamp() {
|
||||
return modifyTimestamp;
|
||||
return "tables:" + dependentTables;
|
||||
}
|
||||
|
||||
public Set<String> getDependentTables() {
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ public enum ServerCacheType {
|
||||
*/
|
||||
QUERY("_Q");
|
||||
|
||||
private String code;
|
||||
private final String code;
|
||||
|
||||
ServerCacheType(String code) {
|
||||
this.code = code;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package io.ebean.common;
|
||||
|
||||
import io.ebean.Ebean;
|
||||
import io.ebean.DB;
|
||||
import io.ebean.ExpressionList;
|
||||
import io.ebean.bean.BeanCollection;
|
||||
import io.ebean.bean.BeanCollectionLoader;
|
||||
@@ -93,7 +93,7 @@ abstract class AbstractBeanCollection<E> implements BeanCollection<E> {
|
||||
|
||||
void lazyLoadCollection(boolean onlyIds) {
|
||||
if (loader == null) {
|
||||
loader = (BeanCollectionLoader) Ebean.getServer(ebeanServerName);
|
||||
loader = (BeanCollectionLoader) DB.byName(ebeanServerName);
|
||||
}
|
||||
loader.loadMany(this, onlyIds);
|
||||
checkEmptyLazyLoad();
|
||||
@@ -219,7 +219,6 @@ abstract class AbstractBeanCollection<E> implements BeanCollection<E> {
|
||||
|
||||
/**
|
||||
* Copies all relevant properties for a clone. See {@link #getShallowCopy()}
|
||||
* @param other
|
||||
*/
|
||||
protected void setFromOriginal(AbstractBeanCollection<E> other) {
|
||||
this.disableLazyLoad = other.disableLazyLoad;
|
||||
|
||||
@@ -237,7 +237,7 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public Set<Entry<K, E>> entrySet() {
|
||||
init();
|
||||
if (isReadOnly()) {
|
||||
|
||||
@@ -83,10 +83,13 @@ public abstract class AbstractNamingConvention implements NamingConvention {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSequenceName(String tableName, String pkColumn) {
|
||||
String s = TABLE_REPLACE.matcher(sequenceFormat).replaceAll(Matcher.quoteReplacement(tableName));
|
||||
public String getSequenceName(String rawTableName, String pkColumn) {
|
||||
final String tableNameUnquoted = databasePlatform.unQuote(rawTableName);
|
||||
String s = TABLE_REPLACE.matcher(sequenceFormat).replaceAll(Matcher.quoteReplacement(tableNameUnquoted));
|
||||
if (pkColumn == null) {
|
||||
pkColumn = "";
|
||||
} else {
|
||||
pkColumn = databasePlatform.unQuote(pkColumn);
|
||||
}
|
||||
return COLUMN_REPLACE.matcher(s).replaceAll(Matcher.quoteReplacement(pkColumn));
|
||||
}
|
||||
|
||||
@@ -88,7 +88,6 @@ public class DbConstraintNaming {
|
||||
* Return the primary key constraint name.
|
||||
*/
|
||||
public String primaryKeyName(String tableName) {
|
||||
|
||||
return pkPrefix + normaliseTable(tableName) + pkSuffix;
|
||||
}
|
||||
|
||||
@@ -103,7 +102,6 @@ public class DbConstraintNaming {
|
||||
* Return the index name associated with a foreign key constraint given multiple columns.
|
||||
*/
|
||||
public String foreignKeyIndexName(String tableName, String[] columns) {
|
||||
|
||||
String colPart = joinColumnNames(columns);
|
||||
return fkIndexPrefix + normaliseTable(tableName) + fkIndexMiddle + colPart + fkIndexSuffix;
|
||||
}
|
||||
@@ -112,7 +110,6 @@ public class DbConstraintNaming {
|
||||
* Return the index name associated with a foreign key constraint given a single column foreign key.
|
||||
*/
|
||||
public String foreignKeyIndexName(String tableName, String column) {
|
||||
|
||||
String colPart = normaliseTable(column);
|
||||
return fkIndexPrefix + normaliseTable(tableName) + fkIndexMiddle + colPart + fkIndexSuffix;
|
||||
}
|
||||
@@ -121,7 +118,6 @@ public class DbConstraintNaming {
|
||||
* Return the index name for a general index (not associated with a foreign key).
|
||||
*/
|
||||
public String indexName(String tableName, String column) {
|
||||
|
||||
String colPart = normaliseTable(column);
|
||||
return indexPrefix + normaliseTable(tableName) + indexMiddle + colPart + indexSuffix;
|
||||
}
|
||||
@@ -130,7 +126,6 @@ public class DbConstraintNaming {
|
||||
* Return the index name for a general index (not associated with a foreign key).
|
||||
*/
|
||||
public String indexName(String tableName, String[] columns) {
|
||||
|
||||
String colPart = joinColumnNames(columns);
|
||||
return indexPrefix + normaliseTable(tableName) + indexMiddle + colPart + indexSuffix;
|
||||
}
|
||||
@@ -139,7 +134,6 @@ public class DbConstraintNaming {
|
||||
* Join the column names together with underscores.
|
||||
*/
|
||||
protected String joinColumnNames(String[] columns) {
|
||||
|
||||
if (columns.length == 1) {
|
||||
return normaliseColumn(columns[0]);
|
||||
}
|
||||
@@ -157,7 +151,6 @@ public class DbConstraintNaming {
|
||||
* Return the unique constraint name.
|
||||
*/
|
||||
public String uniqueConstraintName(String tableName, String columnName) {
|
||||
|
||||
return uqPrefix + normaliseTable(tableName) + "_" + normaliseColumn(columnName) + uqSuffix;
|
||||
}
|
||||
|
||||
@@ -165,7 +158,6 @@ public class DbConstraintNaming {
|
||||
* Return the unique constraint name.
|
||||
*/
|
||||
public String uniqueConstraintName(String tableName, String[] columns) {
|
||||
|
||||
String colPart = joinColumnNames(columns);
|
||||
return uqPrefix + normaliseTable(tableName) + "_" + colPart + uqSuffix;
|
||||
}
|
||||
@@ -174,7 +166,6 @@ public class DbConstraintNaming {
|
||||
* Return the check constraint name.
|
||||
*/
|
||||
public String checkConstraintName(String tableName, String columnName) {
|
||||
|
||||
return ckPrefix + normaliseTable(tableName) + "_" + normaliseColumn(columnName) + ckSuffix;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,17 +41,20 @@ public class DbConstraintNormalise {
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalise the column name by removing any quoted identifier characters.
|
||||
* Normalise the column name by removing any quoted identifier characters and formula brackets.
|
||||
*/
|
||||
public String normaliseColumn(String columnName) {
|
||||
|
||||
columnName = trimQuotes(columnName);
|
||||
columnName = trimBrackets(trimQuotes(columnName));
|
||||
if (lowerCaseColumns) {
|
||||
columnName = columnName.toLowerCase();
|
||||
}
|
||||
return columnName;
|
||||
}
|
||||
|
||||
private String trimBrackets(String value) {
|
||||
return value.replace("(","").replace(")","");
|
||||
}
|
||||
|
||||
/**
|
||||
* Lower case the table name checking for quoted identifiers.
|
||||
*/
|
||||
|
||||
@@ -29,7 +29,7 @@ public class DocStoreConfig {
|
||||
protected boolean create;
|
||||
|
||||
/**
|
||||
* The URL of the Document store server. For example: http://localhost:9200.
|
||||
* The URL of the Document store. For example: http://localhost:9200.
|
||||
*/
|
||||
protected String url;
|
||||
|
||||
@@ -131,7 +131,7 @@ public class DocStoreConfig {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the URL to the Document store server.
|
||||
* Set the URL to the Document store.
|
||||
* <p>
|
||||
* For a local ElasticSearch server this would be: http://localhost:9200
|
||||
*/
|
||||
|
||||
@@ -36,8 +36,7 @@ public class MatchingNamingConvention extends AbstractNamingConvention {
|
||||
|
||||
@Override
|
||||
public TableName getTableNameByConvention(Class<?> beanClass) {
|
||||
|
||||
return new TableName(getCatalog(), getSchema(), beanClass.getSimpleName());
|
||||
return new TableName(quoteIdentifiers(getCatalog()), quoteIdentifiers(getSchema()), quoteIdentifiers(beanClass.getSimpleName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package io.ebean.config;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Used by generated code to hold entity classes to register with Ebean.
|
||||
*/
|
||||
@Target({ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface ModuleInfo {
|
||||
|
||||
/**
|
||||
* Returns the entity classes with db name prefix.
|
||||
* <p>
|
||||
* The db name prefix is added to entity classes for non default databases.
|
||||
*/
|
||||
String[] entities() default {};
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package io.ebean.config;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Loads and returns entity classes to register with Ebean databases.
|
||||
*/
|
||||
public interface ModuleInfoLoader {
|
||||
|
||||
/**
|
||||
* Return the entity classes to register with the default DB.
|
||||
*/
|
||||
List<Class<?>> entityClasses();
|
||||
|
||||
/**
|
||||
* Return entity classes to register for a named DB (not default DB).
|
||||
*/
|
||||
List<Class<?>> entityClassesFor(String dbName);
|
||||
}
|
||||
@@ -17,6 +17,13 @@ public class PlatformConfig {
|
||||
|
||||
private boolean allQuotedIdentifiers;
|
||||
|
||||
private DbConstraintNaming constraintNaming;
|
||||
|
||||
/**
|
||||
* Flag set when a supplied constraintNaming is used.
|
||||
*/
|
||||
private boolean customConstraintNaming;
|
||||
|
||||
/**
|
||||
* The database boolean true value (typically either 1, T, or Y).
|
||||
*/
|
||||
@@ -27,11 +34,6 @@ public class PlatformConfig {
|
||||
*/
|
||||
private String databaseBooleanFalse;
|
||||
|
||||
/**
|
||||
* For DB's using sequences this is the number of sequence values prefetched.
|
||||
*/
|
||||
private int databaseSequenceBatchSize = 20;
|
||||
|
||||
/**
|
||||
* Set for DB's that support both Sequence and Identity (and the default choice is not desired).
|
||||
*/
|
||||
@@ -52,6 +54,8 @@ public class PlatformConfig {
|
||||
*/
|
||||
private boolean databaseInetAddressVarchar;
|
||||
|
||||
private boolean caseSensitiveCollation = true;
|
||||
|
||||
/**
|
||||
* Modify the default mapping of standard types such as default precision for DECIMAL etc.
|
||||
*/
|
||||
@@ -61,7 +65,7 @@ public class PlatformConfig {
|
||||
* Construct with defaults.
|
||||
*/
|
||||
public PlatformConfig() {
|
||||
|
||||
this.constraintNaming = new DbConstraintNaming();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,10 +74,26 @@ public class PlatformConfig {
|
||||
public PlatformConfig(PlatformConfig platformConfig) {
|
||||
this.databaseBooleanFalse = platformConfig.databaseBooleanFalse;
|
||||
this.databaseBooleanTrue = platformConfig.databaseBooleanTrue;
|
||||
this.databaseSequenceBatchSize = platformConfig.databaseSequenceBatchSize;
|
||||
this.idType = platformConfig.idType;
|
||||
this.geometrySRID = platformConfig.geometrySRID;
|
||||
this.dbUuid = platformConfig.dbUuid;
|
||||
this.caseSensitiveCollation = platformConfig.caseSensitiveCollation;
|
||||
this.allQuotedIdentifiers = platformConfig.allQuotedIdentifiers;
|
||||
this.databaseInetAddressVarchar = platformConfig.databaseInetAddressVarchar;
|
||||
this.customDbTypeMappings = platformConfig.customDbTypeMappings;
|
||||
this.constraintNaming = new DbConstraintNaming(!allQuotedIdentifiers);
|
||||
}
|
||||
|
||||
public DbConstraintNaming getConstraintNaming() {
|
||||
return constraintNaming;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a custom database constraint naming convention.
|
||||
*/
|
||||
public void setConstraintNaming(DbConstraintNaming constraintNaming) {
|
||||
this.customConstraintNaming = true;
|
||||
this.constraintNaming = constraintNaming;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,6 +108,23 @@ public class PlatformConfig {
|
||||
*/
|
||||
public void setAllQuotedIdentifiers(boolean allQuotedIdentifiers) {
|
||||
this.allQuotedIdentifiers = allQuotedIdentifiers;
|
||||
if (!customConstraintNaming) {
|
||||
this.constraintNaming = new DbConstraintNaming(!allQuotedIdentifiers);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the collation is case sensitive.
|
||||
*/
|
||||
public boolean isCaseSensitiveCollation() {
|
||||
return caseSensitiveCollation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to false to indicate that the collation is case insensitive.
|
||||
*/
|
||||
public void setCaseSensitiveCollation(boolean caseSensitiveCollation) {
|
||||
this.caseSensitiveCollation = caseSensitiveCollation;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,20 +167,6 @@ public class PlatformConfig {
|
||||
this.databaseBooleanFalse = databaseBooleanFalse;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of DB sequence values that should be preallocated.
|
||||
*/
|
||||
public int getDatabaseSequenceBatchSize() {
|
||||
return databaseSequenceBatchSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the number of DB sequence values that should be preallocated.
|
||||
*/
|
||||
public void setDatabaseSequenceBatchSize(int databaseSequenceBatchSize) {
|
||||
this.databaseSequenceBatchSize = databaseSequenceBatchSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Geometry SRID.
|
||||
*/
|
||||
@@ -251,10 +274,10 @@ public class PlatformConfig {
|
||||
public void loadSettings(PropertiesWrapper p) {
|
||||
|
||||
idType = p.getEnum(IdType.class, "idType", idType);
|
||||
databaseSequenceBatchSize = p.getInt("databaseSequenceBatchSize", databaseSequenceBatchSize);
|
||||
databaseBooleanTrue = p.get("databaseBooleanTrue", databaseBooleanTrue);
|
||||
databaseBooleanFalse = p.get("databaseBooleanFalse", databaseBooleanFalse);
|
||||
databaseInetAddressVarchar = p.getBoolean("databaseInetAddressVarchar", databaseInetAddressVarchar);
|
||||
caseSensitiveCollation = p.getBoolean("caseSensitiveCollation", caseSensitiveCollation);
|
||||
|
||||
DbUuid dbUuid = p.getEnum(DbUuid.class, "dbuuid", null);
|
||||
if (dbUuid != null) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.ebean.config;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonFactory;
|
||||
import io.avaje.config.Config;
|
||||
import io.ebean.DatabaseFactory;
|
||||
import io.ebean.PersistenceContextScope;
|
||||
import io.ebean.Query;
|
||||
@@ -13,7 +14,6 @@ import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebean.config.dbplatform.DbEncrypt;
|
||||
import io.ebean.config.dbplatform.DbType;
|
||||
import io.ebean.config.dbplatform.IdType;
|
||||
import io.ebean.config.properties.PropertiesLoader;
|
||||
import io.ebean.datasource.DataSourceConfig;
|
||||
import io.ebean.event.BeanFindController;
|
||||
import io.ebean.event.BeanPersistController;
|
||||
@@ -28,7 +28,6 @@ import io.ebean.event.changelog.ChangeLogPrepare;
|
||||
import io.ebean.event.changelog.ChangeLogRegister;
|
||||
import io.ebean.event.readaudit.ReadAuditLogger;
|
||||
import io.ebean.event.readaudit.ReadAuditPrepare;
|
||||
import io.ebean.meta.MetaInfoManager;
|
||||
import io.ebean.migration.MigrationRunner;
|
||||
import io.ebean.util.StringHelper;
|
||||
|
||||
@@ -133,6 +132,15 @@ public class ServerConfig {
|
||||
|
||||
private TenantCatalogProvider tenantCatalogProvider;
|
||||
|
||||
/**
|
||||
* When true will load entity classes via ModuleInfoLoader.
|
||||
* <p>
|
||||
* NB: ModuleInfoLoader implementations are generated by querybean generator.
|
||||
* Having this on and registering entity classes means we don't need to manually
|
||||
* write that code or use classpath scanning to find entity classes.
|
||||
*/
|
||||
private boolean loadModuleInfo;
|
||||
|
||||
/**
|
||||
* List of interesting classes such as entities, embedded, ScalarTypes,
|
||||
* Listeners, Finders, Controllers etc.
|
||||
@@ -345,26 +353,11 @@ public class ServerConfig {
|
||||
*/
|
||||
private NamingConvention namingConvention = new UnderscoreNamingConvention();
|
||||
|
||||
/**
|
||||
* Naming convention used in DDL generation for primary keys, foreign keys etc.
|
||||
*/
|
||||
private DbConstraintNaming constraintNaming = new DbConstraintNaming();
|
||||
|
||||
/**
|
||||
* Behaviour of update to include on the change properties.
|
||||
*/
|
||||
private boolean updateChangesOnly = true;
|
||||
|
||||
/**
|
||||
* Behaviour of updates in JDBC batch to by default include all properties.
|
||||
*/
|
||||
private boolean updateAllPropertiesInBatch;
|
||||
|
||||
/**
|
||||
* Default behaviour for updates when cascade save on a O2M or M2M to delete any missing children.
|
||||
*/
|
||||
private boolean updatesDeleteMissingChildren = true;
|
||||
|
||||
/**
|
||||
* Database platform configuration.
|
||||
*/
|
||||
@@ -425,10 +418,6 @@ public class ServerConfig {
|
||||
|
||||
private ServerCachePlugin serverCachePlugin;
|
||||
|
||||
private boolean collectQueryStatsByNode = true;
|
||||
|
||||
private boolean collectQueryOrigins = true;
|
||||
|
||||
/**
|
||||
* The default PersistenceContextScope used if one is not explicitly set on a query.
|
||||
*/
|
||||
@@ -503,6 +492,11 @@ public class ServerConfig {
|
||||
*/
|
||||
private boolean collectQueryPlans;
|
||||
|
||||
/**
|
||||
* The default threshold in micros for collecting query plans.
|
||||
*/
|
||||
private long collectQueryPlanThresholdMicros = Long.MAX_VALUE;
|
||||
|
||||
/**
|
||||
* The time in millis used to determine when a query is alerted for being slow.
|
||||
*/
|
||||
@@ -518,7 +512,7 @@ public class ServerConfig {
|
||||
/**
|
||||
* Controls the default order by id setting of queries. See {@link Query#orderById(boolean)}
|
||||
*/
|
||||
private boolean defaultOrderById = false;
|
||||
private boolean defaultOrderById;
|
||||
|
||||
/**
|
||||
* The mappingLocations for searching xml mapping.
|
||||
@@ -585,8 +579,9 @@ public class ServerConfig {
|
||||
|
||||
|
||||
/**
|
||||
* Sets the default orderById setting for queries.
|
||||
* Deprecated - look to have explicit order by. Sets the default orderById setting for queries.
|
||||
*/
|
||||
@Deprecated
|
||||
public void setDefaultOrderById(boolean defaultOrderById) {
|
||||
this.defaultOrderById = defaultOrderById;
|
||||
}
|
||||
@@ -652,6 +647,7 @@ public class ServerConfig {
|
||||
* @param cls The type of the service object to obtain
|
||||
* @return The service object given the class type
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <P> P getServiceObject(Class<P> cls) {
|
||||
return (P) serviceObject.get(serviceObjectKey(cls));
|
||||
}
|
||||
@@ -1054,18 +1050,6 @@ public class ServerConfig {
|
||||
this.lazyLoadBatchSize = lazyLoadBatchSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the number of sequences to fetch/preallocate when using DB sequences.
|
||||
* <p>
|
||||
* This is a performance optimisation to reduce the number times Ebean
|
||||
* requests a sequence to be used as an Id for a bean (aka reduce network
|
||||
* chatter).
|
||||
* </p>
|
||||
*/
|
||||
public void setDatabaseSequenceBatchSize(int databaseSequenceBatchSize) {
|
||||
platformConfig.setDatabaseSequenceBatchSize(databaseSequenceBatchSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default JDBC fetchSize hint for findList queries.
|
||||
*/
|
||||
@@ -1613,14 +1597,14 @@ public class ServerConfig {
|
||||
* Return the constraint naming convention used in DDL generation.
|
||||
*/
|
||||
public DbConstraintNaming getConstraintNaming() {
|
||||
return constraintNaming;
|
||||
return platformConfig.getConstraintNaming();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the constraint naming convention used in DDL generation.
|
||||
*/
|
||||
public void setConstraintNaming(DbConstraintNaming constraintNaming) {
|
||||
this.constraintNaming = constraintNaming;
|
||||
platformConfig.setConstraintNaming(constraintNaming);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1832,32 +1816,6 @@ public class ServerConfig {
|
||||
this.platformConfig.setDatabaseBooleanFalse(databaseFalse);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of DB sequence values that should be preallocated.
|
||||
*/
|
||||
public int getDatabaseSequenceBatchSize() {
|
||||
return platformConfig.getDatabaseSequenceBatchSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the number of DB sequence values that should be preallocated and cached
|
||||
* by Ebean.
|
||||
* <p>
|
||||
* This is only used for DB's that use sequences and is a performance
|
||||
* optimisation. This reduces the number of times Ebean needs to get a
|
||||
* sequence value from the Database reducing network chatter.
|
||||
* </p>
|
||||
* <p>
|
||||
* By default this value is 10 so when we need another Id (and don't have one
|
||||
* in our cache) Ebean will fetch 10 id's from the database. Note that when
|
||||
* the cache drops to have full (which is 5 by default) Ebean will fetch
|
||||
* another batch of Id's in a background thread.
|
||||
* </p>
|
||||
*/
|
||||
public void setDatabaseSequenceBatch(int databaseSequenceBatchSize) {
|
||||
this.platformConfig.setDatabaseSequenceBatchSize(databaseSequenceBatchSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the database platform name (can be null).
|
||||
* <p>
|
||||
@@ -1890,7 +1848,7 @@ public class ServerConfig {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the database platform to use for this server.
|
||||
* Return the database platform to use for this database.
|
||||
*/
|
||||
public DatabasePlatform getDatabasePlatform() {
|
||||
return databasePlatform;
|
||||
@@ -2286,15 +2244,21 @@ public class ServerConfig {
|
||||
* </p>
|
||||
*
|
||||
* @param cls the entity type (or other type) that should be registered by this
|
||||
* server.
|
||||
* database.
|
||||
*/
|
||||
public void addClass(Class<?> cls) {
|
||||
if (classes == null) {
|
||||
classes = new ArrayList<>();
|
||||
}
|
||||
classes.add(cls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register all the classes (typically entity classes).
|
||||
*/
|
||||
public void addAll(List<Class<?>> classList) {
|
||||
if (classList != null && !classList.isEmpty()) {
|
||||
classes.addAll(classList);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a package to search for entities via class path search.
|
||||
* <p>
|
||||
@@ -2302,9 +2266,6 @@ public class ServerConfig {
|
||||
* </p>
|
||||
*/
|
||||
public void addPackage(String packageName) {
|
||||
if (packages == null) {
|
||||
packages = new ArrayList<>();
|
||||
}
|
||||
packages.add(packageName);
|
||||
}
|
||||
|
||||
@@ -2330,7 +2291,7 @@ public class ServerConfig {
|
||||
|
||||
/**
|
||||
* Set the list of classes (entities, listeners, scalarTypes etc) that should
|
||||
* be used for this server.
|
||||
* be used for this database.
|
||||
* <p>
|
||||
* If no classes are specified then the classes are found automatically via
|
||||
* searching the class path.
|
||||
@@ -2344,7 +2305,7 @@ public class ServerConfig {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the classes registered for this server. Typically this includes
|
||||
* Return the classes registered for this database. Typically this includes
|
||||
* entities and perhaps listeners.
|
||||
*/
|
||||
public List<Class<?>> getClasses() {
|
||||
@@ -2407,20 +2368,6 @@ public class ServerConfig {
|
||||
this.skipCacheAfterWrite = skipCacheAfterWrite;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true to only update changed properties.
|
||||
*/
|
||||
public boolean isUpdateChangesOnly() {
|
||||
return updateChangesOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to true to only update changed properties.
|
||||
*/
|
||||
public void setUpdateChangesOnly(boolean updateChangesOnly) {
|
||||
this.updateChangesOnly = updateChangesOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if updates in JDBC batch default to include all properties by default.
|
||||
*/
|
||||
@@ -2440,68 +2387,6 @@ public class ServerConfig {
|
||||
this.updateAllPropertiesInBatch = updateAllPropertiesInBatch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if updates by default delete missing children when cascading save to a OneToMany or
|
||||
* ManyToMany. When not set this defaults to true.
|
||||
*/
|
||||
public boolean isUpdatesDeleteMissingChildren() {
|
||||
return updatesDeleteMissingChildren;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if updates by default delete missing children when cascading save to a OneToMany or
|
||||
* ManyToMany. When not set this defaults to true.
|
||||
*/
|
||||
public void setUpdatesDeleteMissingChildren(boolean updatesDeleteMissingChildren) {
|
||||
this.updatesDeleteMissingChildren = updatesDeleteMissingChildren;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if query statistics should be collected by ObjectGraphNode.
|
||||
*/
|
||||
public boolean isCollectQueryStatsByNode() {
|
||||
return collectQueryStatsByNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to true to collection query execution statistics by ObjectGraphNode.
|
||||
* <p>
|
||||
* These statistics can be used to highlight code/query 'origin points' that result in lots of lazy loading.
|
||||
* </p>
|
||||
* <p>
|
||||
* It is considered safe/fine to have this set to true for production.
|
||||
* </p>
|
||||
* <p>
|
||||
* This information can be later retrieved via {@link MetaInfoManager}.
|
||||
* </p>
|
||||
*
|
||||
* @see MetaInfoManager
|
||||
*/
|
||||
public void setCollectQueryStatsByNode(boolean collectQueryStatsByNode) {
|
||||
this.collectQueryStatsByNode = collectQueryStatsByNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if query plans should also collect their 'origins'. This means for a given query plan you
|
||||
* can identify the code/origin points where this query resulted from including lazy loading origins.
|
||||
*/
|
||||
public boolean isCollectQueryOrigins() {
|
||||
return collectQueryOrigins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to true if query plans should collect their 'origin' points. This means for a given query plan you
|
||||
* can identify the code/origin points where this query resulted from including lazy loading origins.
|
||||
* <p>
|
||||
* This information can be later retrieved via {@link MetaInfoManager}.
|
||||
* </p>
|
||||
*
|
||||
* @see MetaInfoManager
|
||||
*/
|
||||
public void setCollectQueryOrigins(boolean collectQueryOrigins) {
|
||||
this.collectQueryOrigins = collectQueryOrigins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the resource directory.
|
||||
*/
|
||||
@@ -2823,7 +2708,7 @@ public class ServerConfig {
|
||||
* Load settings from ebean.properties.
|
||||
*/
|
||||
public void loadFromProperties() {
|
||||
this.properties = PropertiesLoader.load();
|
||||
this.properties = Config.asProperties();
|
||||
configureFromProperties();
|
||||
}
|
||||
|
||||
@@ -2832,7 +2717,7 @@ public class ServerConfig {
|
||||
*/
|
||||
public void loadFromProperties(Properties properties) {
|
||||
// keep the properties used for configuration so that these are available for plugins
|
||||
this.properties = PropertiesLoader.eval(properties);
|
||||
this.properties = Config.asConfiguration().eval(properties);
|
||||
configureFromProperties();
|
||||
}
|
||||
|
||||
@@ -2927,11 +2812,14 @@ public class ServerConfig {
|
||||
}
|
||||
loadDocStoreSettings(p);
|
||||
|
||||
loadModuleInfo = p.getBoolean("loadModuleInfo", loadModuleInfo);
|
||||
maxCallStack = p.getInt("maxCallStack", maxCallStack);
|
||||
dumpMetricsOnShutdown = p.getBoolean("dumpMetricsOnShutdown", dumpMetricsOnShutdown);
|
||||
dumpMetricsOptions = p.get("dumpMetricsOptions", dumpMetricsOptions);
|
||||
queryPlanTTLSeconds = p.getInt("queryPlanTTLSeconds", queryPlanTTLSeconds);
|
||||
slowQueryMillis = p.getLong("slowQueryMillis", slowQueryMillis);
|
||||
collectQueryPlans = p.getBoolean("collectQueryPlans", collectQueryPlans);
|
||||
collectQueryPlanThresholdMicros = p.getLong("collectQueryPlanThresholdMicros", collectQueryPlanThresholdMicros);
|
||||
docStoreOnly = p.getBoolean("docStoreOnly", docStoreOnly);
|
||||
disableL2Cache = p.getBoolean("disableL2Cache", disableL2Cache);
|
||||
enabledL2Regions = p.get("enabledL2Regions", enabledL2Regions);
|
||||
@@ -2958,15 +2846,8 @@ public class ServerConfig {
|
||||
String packagesProp = p.get("search.packages", p.get("packages", null));
|
||||
packages = getSearchList(packagesProp, packages);
|
||||
|
||||
collectQueryStatsByNode = p.getBoolean("collectQueryStatsByNode", collectQueryStatsByNode);
|
||||
collectQueryOrigins = p.getBoolean("collectQueryOrigins", collectQueryOrigins);
|
||||
|
||||
skipCacheAfterWrite = p.getBoolean("skipCacheAfterWrite", skipCacheAfterWrite);
|
||||
updateAllPropertiesInBatch = p.getBoolean("updateAllPropertiesInBatch", updateAllPropertiesInBatch);
|
||||
updateChangesOnly = p.getBoolean("updateChangesOnly", updateChangesOnly);
|
||||
|
||||
boolean defaultDeleteMissingChildren = p.getBoolean("defaultDeleteMissingChildren", updatesDeleteMissingChildren);
|
||||
updatesDeleteMissingChildren = p.getBoolean("updatesDeleteMissingChildren", defaultDeleteMissingChildren);
|
||||
|
||||
if (p.get("batch.mode") != null || p.get("persistBatching") != null) {
|
||||
throw new IllegalArgumentException("Property 'batch.mode' or 'persistBatching' is being set but no longer used. Please change to use 'persistBatchMode'");
|
||||
@@ -3057,20 +2938,20 @@ public class ServerConfig {
|
||||
return classes;
|
||||
}
|
||||
|
||||
List<Class<?>> classes = new ArrayList<>();
|
||||
List<Class<?>> classList = new ArrayList<>();
|
||||
|
||||
String[] split = StringHelper.splitNames(classNames);
|
||||
for (String cn : split) {
|
||||
if (!"class".equalsIgnoreCase(cn)) {
|
||||
try {
|
||||
classes.add(Class.forName(cn));
|
||||
classList.add(Class.forName(cn));
|
||||
} catch (ClassNotFoundException e) {
|
||||
String msg = "Error registering class [" + cn + "] from [" + classNames + "]";
|
||||
throw new RuntimeException(msg, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return classes;
|
||||
return classList;
|
||||
}
|
||||
|
||||
private List<String> getSearchList(String searchNames, List<String> defaultValue) {
|
||||
@@ -3324,6 +3205,20 @@ public class ServerConfig {
|
||||
this.collectQueryPlans = collectQueryPlans;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the query plan collection threshold in microseconds.
|
||||
*/
|
||||
public long getCollectQueryPlanThresholdMicros() {
|
||||
return collectQueryPlanThresholdMicros;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the query plan collection threshold in microseconds.
|
||||
*/
|
||||
public void setCollectQueryPlanThresholdMicros(long collectQueryPlanThresholdMicros) {
|
||||
this.collectQueryPlanThresholdMicros = collectQueryPlanThresholdMicros;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if metrics should be dumped when the server is shutdown.
|
||||
*/
|
||||
@@ -3354,6 +3249,17 @@ public class ServerConfig {
|
||||
this.dumpMetricsOptions = dumpMetricsOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if entity classes should be loaded and registered via ModuleInfoLoader.
|
||||
* <p>
|
||||
* When false we either register entity classes via application code or use classpath
|
||||
* scanning to find and register entity classes.
|
||||
* </p>
|
||||
*/
|
||||
public boolean isAutoLoadModuleInfo() {
|
||||
return loadModuleInfo && classes.isEmpty();
|
||||
}
|
||||
|
||||
public enum UuidVersion {
|
||||
VERSION4,
|
||||
VERSION1,
|
||||
|
||||
@@ -35,9 +35,9 @@ public enum TenantMode {
|
||||
* (that holds configuration e.g.)
|
||||
*/
|
||||
DB_WITH_MASTER(true, true);
|
||||
|
||||
boolean dynamicDataSource;
|
||||
boolean ddlEnabled;
|
||||
|
||||
final boolean dynamicDataSource;
|
||||
final boolean ddlEnabled;
|
||||
|
||||
TenantMode(boolean dynamicDataSource, boolean ddlEnabled) {
|
||||
this.dynamicDataSource = dynamicDataSource;
|
||||
@@ -50,12 +50,12 @@ public enum TenantMode {
|
||||
public boolean isDynamicDataSource() {
|
||||
return dynamicDataSource;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true, if DDL is enabled.
|
||||
*/
|
||||
public boolean isDdlEnabled() {
|
||||
return ddlEnabled;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -18,5 +18,10 @@ public enum DataErrorType {
|
||||
/**
|
||||
* Data integrity error like an invalid foreign key.
|
||||
*/
|
||||
DataIntegrity
|
||||
DataIntegrity,
|
||||
|
||||
/**
|
||||
* Non recoverable concurrency conflict.
|
||||
*/
|
||||
SerializableConflict
|
||||
}
|
||||
|
||||
@@ -51,6 +51,8 @@ public class DatabasePlatform {
|
||||
|
||||
protected boolean supportsDeleteTableAlias;
|
||||
|
||||
protected boolean supportsSavepointId = true;
|
||||
|
||||
/**
|
||||
* The behaviour used when ending a read only transaction at read committed isolation level.
|
||||
*/
|
||||
@@ -71,6 +73,13 @@ public class DatabasePlatform {
|
||||
*/
|
||||
protected boolean allQuotedIdentifiers;
|
||||
|
||||
protected boolean caseSensitiveCollation = true;
|
||||
|
||||
/**
|
||||
* Set true if the Database support LIMIT clause on sql update.
|
||||
*/
|
||||
protected boolean inlineSqlUpdateLimit;
|
||||
|
||||
/**
|
||||
* For limit/offset, row_number etc limiting of SQL queries.
|
||||
*/
|
||||
@@ -101,10 +110,6 @@ public class DatabasePlatform {
|
||||
*/
|
||||
protected DbIdentity dbIdentity = new DbIdentity();
|
||||
|
||||
protected boolean sequenceBatchMode = true;
|
||||
|
||||
protected int sequenceBatchSize = 20;
|
||||
|
||||
/**
|
||||
* The history support for this database platform.
|
||||
*/
|
||||
@@ -135,9 +140,9 @@ public class DatabasePlatform {
|
||||
*/
|
||||
protected Platform platform = Platform.GENERIC;
|
||||
|
||||
protected String columnAliasPrefix = "c";
|
||||
protected String truncateTable = "truncate table %s";
|
||||
|
||||
protected String tableAliasPlaceHolder = "${ta}";
|
||||
protected String columnAliasPrefix = "c";
|
||||
|
||||
/**
|
||||
* Use a BackTick ` at the beginning and end of table or column names that you
|
||||
@@ -165,13 +170,14 @@ public class DatabasePlatform {
|
||||
/**
|
||||
* Characters escaped for startsWith, endsWith and contains.
|
||||
*/
|
||||
protected char[] likeSpecialCharacters = { '%', '_', '|' };
|
||||
protected char[] likeSpecialCharacters = {'%', '_', '|'};
|
||||
|
||||
protected DbEncrypt dbEncrypt;
|
||||
|
||||
protected boolean idInExpandedForm;
|
||||
|
||||
protected boolean selectCountWithAlias;
|
||||
protected boolean selectCountWithColumnAlias;
|
||||
|
||||
/**
|
||||
* If set then use the FORWARD ONLY hint when creating ResultSets for
|
||||
@@ -181,7 +187,7 @@ public class DatabasePlatform {
|
||||
|
||||
/**
|
||||
* If set then use the CONCUR_UPDATABLE hint when creating ResultSets.
|
||||
*
|
||||
* <p>
|
||||
* This is {@code false} for HANA
|
||||
*/
|
||||
protected boolean supportsResultSetConcurrencyModeUpdatable = true;
|
||||
@@ -225,7 +231,7 @@ public class DatabasePlatform {
|
||||
* Configure the platform given the server configuration.
|
||||
*/
|
||||
public void configure(PlatformConfig config) {
|
||||
this.sequenceBatchSize = config.getDatabaseSequenceBatchSize();
|
||||
this.caseSensitiveCollation = config.isCaseSensitiveCollation();
|
||||
configureIdType(config.getIdType());
|
||||
configure(config, config.isAllQuotedIdentifiers());
|
||||
}
|
||||
@@ -267,7 +273,7 @@ public class DatabasePlatform {
|
||||
* Return true if this matches the given platform.
|
||||
*/
|
||||
public boolean isPlatform(Platform platform) {
|
||||
return this.platform == platform;
|
||||
return this.platform.base() == platform;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -287,20 +293,6 @@ public class DatabasePlatform {
|
||||
return platform.name().toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if we are using Sequence batch mode rather than STEP.
|
||||
*/
|
||||
public boolean isSequenceBatchMode() {
|
||||
return sequenceBatchMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to false to not use sequence batch mode but instead STEP mode.
|
||||
*/
|
||||
public void setSequenceBatchMode(boolean sequenceBatchMode) {
|
||||
this.sequenceBatchMode = sequenceBatchMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this database platform supports native ILIKE expression.
|
||||
*/
|
||||
@@ -315,6 +307,30 @@ public class DatabasePlatform {
|
||||
return supportsDeleteTableAlias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the collation is case sensitive.
|
||||
* <p>
|
||||
* This is expected to be used for testing only.
|
||||
* </p>
|
||||
*/
|
||||
public boolean isCaseSensitiveCollation() {
|
||||
return caseSensitiveCollation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the platform supports SavepointId values.
|
||||
*/
|
||||
public boolean isSupportsSavepointId() {
|
||||
return supportsSavepointId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the platform supports LIMIT with sql update.
|
||||
*/
|
||||
public boolean isInlineSqlUpdateLimit() {
|
||||
return inlineSqlUpdateLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the maximum table name length.
|
||||
* <p>
|
||||
@@ -349,10 +365,10 @@ public class DatabasePlatform {
|
||||
* @param be the BackgroundExecutor that can be used to load the sequence if
|
||||
* desired
|
||||
* @param ds the DataSource
|
||||
* @param stepSize the sequence allocation size as defined by mapping (defaults to 50)
|
||||
* @param increment the sequence allocation size as defined by mapping (defaults to 50)
|
||||
* @param seqName the name of the sequence
|
||||
*/
|
||||
public PlatformIdGenerator createSequenceIdGenerator(BackgroundExecutor be, DataSource ds, int stepSize, String seqName) {
|
||||
public PlatformIdGenerator createSequenceIdGenerator(BackgroundExecutor be, DataSource ds, int increment, String seqName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -442,20 +458,6 @@ public class DatabasePlatform {
|
||||
this.columnAliasPrefix = columnAliasPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the table alias placeholder.
|
||||
*/
|
||||
public String getTableAliasPlaceHolder() {
|
||||
return tableAliasPlaceHolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the table alias placeholder.
|
||||
*/
|
||||
public void setTableAliasPlaceHolder(String tableAliasPlaceHolder) {
|
||||
this.tableAliasPlaceHolder = tableAliasPlaceHolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the close quote for quoted identifiers.
|
||||
*/
|
||||
@@ -555,7 +557,7 @@ public class DatabasePlatform {
|
||||
/**
|
||||
* Normally not needed - overridden in CockroachPlatform.
|
||||
*/
|
||||
public boolean isDdlCommitOnCreateIndex() {
|
||||
public boolean isDdlAutoCommit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -635,7 +637,7 @@ public class DatabasePlatform {
|
||||
if (dbName != null && !dbName.isEmpty()) {
|
||||
if (dbName.startsWith(openQuote)) {
|
||||
// trim off the open and close quotes
|
||||
return dbName.substring(1, dbName.length()-1);
|
||||
return dbName.substring(1, dbName.length() - 1);
|
||||
}
|
||||
}
|
||||
return dbName;
|
||||
@@ -648,6 +650,14 @@ public class DatabasePlatform {
|
||||
return selectCountWithAlias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if select count with subquery needs column alias (SQL Server).
|
||||
*/
|
||||
public boolean isSelectCountWithColumnAlias() {
|
||||
return selectCountWithColumnAlias;
|
||||
}
|
||||
|
||||
|
||||
public String completeSql(String sql, Query<?> query) {
|
||||
if (query.isForUpdate()) {
|
||||
sql = withForUpdate(sql, query.getForUpdateMode());
|
||||
@@ -686,6 +696,13 @@ public class DatabasePlatform {
|
||||
return persistBatchOnCascade;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a statement to truncate a table.
|
||||
*/
|
||||
public String truncateStatement(String table) {
|
||||
return String.format(truncateTable, table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the DB schema if it does not exist.
|
||||
*/
|
||||
@@ -755,7 +772,7 @@ public class DatabasePlatform {
|
||||
for (int i = 0; i < value.length(); i++) {
|
||||
char ch = value.charAt(i);
|
||||
boolean escaped = false;
|
||||
for (char escapeChar: likeSpecialCharacters) {
|
||||
for (char escapeChar : likeSpecialCharacters) {
|
||||
if (ch == escapeChar) {
|
||||
if (sb == null) {
|
||||
sb = new StringBuilder(value.substring(0, i));
|
||||
|
||||
@@ -27,15 +27,13 @@ public class DbDefaultValue {
|
||||
* The key for the NOW / current timestamp.
|
||||
*/
|
||||
public static final String NOW = "now";
|
||||
|
||||
|
||||
/**
|
||||
* The 'null' literal.
|
||||
*/
|
||||
public static final String NULL = "null";
|
||||
|
||||
|
||||
|
||||
protected Map<String, String> map = new LinkedHashMap<>();
|
||||
protected final Map<String, String> map = new LinkedHashMap<>();
|
||||
|
||||
/**
|
||||
* Set the DB now function.
|
||||
@@ -82,10 +80,9 @@ public class DbDefaultValue {
|
||||
return val != null ? val : dbDefaultLiteral;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method checks & convert the {@link DbDefault#value()} to a valid SQL literal.
|
||||
*
|
||||
*
|
||||
* This is mainly to quote string literals and verify integer/dates for correctness.
|
||||
* <p>
|
||||
* Note: There are some special cases:
|
||||
@@ -98,24 +95,24 @@ public class DbDefaultValue {
|
||||
* If you need really the String "null", you have to specify <code>@DbDefault("'null'")</code>
|
||||
* which gives you the <code>default 'null'</code> statement.</li>
|
||||
* <li>Any statement, that begins and ends with single quote will not be checked or get quoted again.</li>
|
||||
* <li>A statement that begins with "$RAW:", e.g <code>@DbDefault("$RAW:N'SANDNES'")</code> will lead to
|
||||
* <li>A statement that begins with "$RAW:", e.g <code>@DbDefault("$RAW:N'SANDNES'")</code> will lead to
|
||||
* a <code>default N'SANDNES'</code> in DDL. Note that this is platform specific!</li>
|
||||
* </ul>
|
||||
*/
|
||||
public static String toSqlLiteral(String defaultValue, Class<?> propertyType, int sqlType) {
|
||||
if (propertyType == null
|
||||
|| defaultValue == null
|
||||
|| defaultValue == null
|
||||
|| NULL.equals(defaultValue)
|
||||
|| (defaultValue.startsWith("'") && defaultValue.endsWith("'"))
|
||||
|| (defaultValue.startsWith("$RAW:"))) {
|
||||
|| (defaultValue.startsWith("$RAW:"))) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
if (Boolean.class.isAssignableFrom(propertyType) || Boolean.TYPE.isAssignableFrom(propertyType)) {
|
||||
return toBooleanLiteral(defaultValue);
|
||||
}
|
||||
|
||||
if (Number.class.isAssignableFrom(propertyType)
|
||||
|
||||
if (Number.class.isAssignableFrom(propertyType)
|
||||
|| Byte.TYPE.equals(propertyType)
|
||||
|| Short.TYPE.equals(propertyType)
|
||||
|| Integer.TYPE.equals(propertyType)
|
||||
@@ -126,7 +123,7 @@ public class DbDefaultValue {
|
||||
Double.valueOf(defaultValue); // verify if it is a number
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
|
||||
// check if it is a date/time - in all other cases return quoted defaultValue
|
||||
switch (sqlType) {
|
||||
// date
|
||||
@@ -155,7 +152,7 @@ public class DbDefaultValue {
|
||||
}
|
||||
throw new IllegalArgumentException("'" + value + "' is not a valid value for boolean");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This adds single qoutes around the <code>value</code> and doubles single quotes.
|
||||
* "User's home" will return "'User''s home'"
|
||||
@@ -175,7 +172,7 @@ public class DbDefaultValue {
|
||||
return sb.toString();
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static String toDateLiteral(String value) {
|
||||
if (NOW.equals(value)) {
|
||||
return value; // this will get translated later
|
||||
@@ -191,7 +188,7 @@ public class DbDefaultValue {
|
||||
DatatypeConverter.parseTime(value); // verify
|
||||
return toTextLiteral(value);
|
||||
}
|
||||
|
||||
|
||||
private static String toDateTimeLiteral(String value) {
|
||||
if (NOW.equals(value)) {
|
||||
return value; // this will get translated later
|
||||
|
||||
@@ -11,12 +11,12 @@ class DbPlatformTypeLookup {
|
||||
/**
|
||||
* A map to lookup the type by name.
|
||||
*/
|
||||
private Map<String, DbType> nameLookup = new HashMap<>();
|
||||
private final Map<String, DbType> nameLookup = new HashMap<>();
|
||||
|
||||
/**
|
||||
* A map to lookup the type by JDBC int value.
|
||||
*/
|
||||
private Map<Integer, DbType> idLookup = new HashMap<>();
|
||||
private final Map<Integer, DbType> idLookup = new HashMap<>();
|
||||
|
||||
DbPlatformTypeLookup() {
|
||||
addAll();
|
||||
|
||||
@@ -23,12 +23,14 @@ public class DbPlatformTypeMapping {
|
||||
}
|
||||
}
|
||||
|
||||
private static DbPlatformTypeLookup lookup = new DbPlatformTypeLookup();
|
||||
private static final DbPlatformTypeLookup lookup = new DbPlatformTypeLookup();
|
||||
|
||||
private static final DbPlatformType BOOLEAN_LOGICAL = new BooleanLogicalType();
|
||||
|
||||
private static final DbPlatformType INET_NATIVE = new DbPlatformType("inet", false);
|
||||
private static final DbPlatformType INET_VARCHAR = new DbPlatformType("varchar", 50);
|
||||
private static final DbPlatformType CIDR_NATIVE = new DbPlatformType("cidr", false);
|
||||
private static final DbPlatformType CIDR_VARCHAR = new DbPlatformType("varchar", 50);
|
||||
|
||||
private static final DbPlatformType UUID_NATIVE = new DbPlatformType("uuid", false);
|
||||
@SuppressWarnings("unused")
|
||||
@@ -110,6 +112,7 @@ public class DbPlatformTypeMapping {
|
||||
put(DbType.JSONVARCHAR, new DbPlatformType("jsonvarchar", 1000));
|
||||
put(DbType.UUID, UUID_NATIVE);
|
||||
put(DbType.INET, INET_NATIVE);
|
||||
put(DbType.CIDR, CIDR_NATIVE);
|
||||
|
||||
} else {
|
||||
put(DbType.VARCHAR, new DbPlatformType("varchar", 255));
|
||||
@@ -126,6 +129,7 @@ public class DbPlatformTypeMapping {
|
||||
// default to native UUID and override on platform configure()
|
||||
put(DbType.UUID, UUID_NATIVE);
|
||||
put(DbType.INET, INET_VARCHAR);
|
||||
put(DbType.CIDR, CIDR_VARCHAR);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ public enum DbType {
|
||||
|
||||
UUID(ExtraDbTypes.UUID),
|
||||
INET(ExtraDbTypes.INET),
|
||||
CDIR(ExtraDbTypes.CDIR),
|
||||
CIDR(ExtraDbTypes.CIDR),
|
||||
|
||||
POINT(ExtraDbTypes.POINT),
|
||||
POLYGON(ExtraDbTypes.POLYGON),
|
||||
|
||||
@@ -41,7 +41,7 @@ public interface ExtraDbTypes {
|
||||
int JSONBlob = 5005;
|
||||
|
||||
int INET = 5020;
|
||||
int CDIR = 5021;
|
||||
int CIDR = 5021;
|
||||
|
||||
/**
|
||||
* Geo Point
|
||||
|
||||
@@ -35,6 +35,11 @@ public enum IdType {
|
||||
* Used when the key is a compound key or lookup table code.
|
||||
* </p>
|
||||
*/
|
||||
EXTERNAL
|
||||
EXTERNAL,
|
||||
|
||||
/**
|
||||
* Auto mapping to platform preferred identity strategy.
|
||||
*/
|
||||
AUTO
|
||||
|
||||
}
|
||||
|
||||
@@ -40,8 +40,7 @@ public class LimitOffsetSqlLimiter implements SqlLimiter {
|
||||
}
|
||||
|
||||
String sql = request.getDbPlatform().completeSql(sb.toString(), request.getOrmQuery());
|
||||
|
||||
return new SqlLimitResponse(sql, false);
|
||||
return new SqlLimitResponse(sql);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
package io.ebean.config.dbplatform;
|
||||
|
||||
/**
|
||||
* Adds the ROW_NUMBER() OVER function to a query.
|
||||
*/
|
||||
public class RowNumberSqlLimiter implements SqlLimiter {
|
||||
|
||||
/**
|
||||
* ROW_NUMBER() OVER (ORDER BY
|
||||
*/
|
||||
private static final String ROW_NUMBER_OVER = "row_number() over (order by ";
|
||||
|
||||
/**
|
||||
* ) as rn,
|
||||
*/
|
||||
private static final String ROW_NUMBER_AS = ") as rn, ";
|
||||
|
||||
private final String rowNumberWindowAlias;
|
||||
|
||||
/**
|
||||
* Specify the name of the rowNumberWindowAlias.
|
||||
*/
|
||||
public RowNumberSqlLimiter(String rowNumberWindowAlias) {
|
||||
this.rowNumberWindowAlias = rowNumberWindowAlias;
|
||||
}
|
||||
|
||||
public RowNumberSqlLimiter() {
|
||||
this("as limitresult");
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqlLimitResponse limit(SqlLimitRequest request) {
|
||||
|
||||
String dbSql = request.getDbSql();
|
||||
|
||||
StringBuilder sb = new StringBuilder(60 + dbSql.length());
|
||||
|
||||
int firstRow = request.getFirstRow();
|
||||
|
||||
int lastRow = request.getMaxRows();
|
||||
if (lastRow > 0) {
|
||||
lastRow += firstRow;
|
||||
}
|
||||
|
||||
sb.append("select * from ( ");
|
||||
|
||||
sb.append("select ");
|
||||
if (request.isDistinct()) {
|
||||
sb.append("distinct ");
|
||||
}
|
||||
|
||||
sb.append(ROW_NUMBER_OVER);
|
||||
sb.append(request.getDbOrderBy());
|
||||
sb.append(ROW_NUMBER_AS);
|
||||
|
||||
sb.append(dbSql);
|
||||
|
||||
sb.append(" ) ");
|
||||
sb.append(rowNumberWindowAlias);
|
||||
sb.append(" where ");
|
||||
if (firstRow > 0) {
|
||||
sb.append(" rn > ").append(firstRow);
|
||||
if (lastRow > 0) {
|
||||
sb.append(" and ");
|
||||
}
|
||||
}
|
||||
if (lastRow > 0) {
|
||||
sb.append(" rn <= ").append(lastRow);
|
||||
}
|
||||
|
||||
String sql = request.getDbPlatform().completeSql(sb.toString(), request.getOrmQuery());
|
||||
|
||||
return new SqlLimitResponse(sql, true);
|
||||
}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
package io.ebean.config.dbplatform;
|
||||
|
||||
/**
|
||||
* Add ROWNUM column etc around SQL query to limit results.
|
||||
*/
|
||||
public class RownumSqlLimiter implements SqlLimiter {
|
||||
|
||||
private final String rnum;
|
||||
|
||||
private final boolean useFirstRowsHint;
|
||||
|
||||
/**
|
||||
* Create with default inner rownum column alias and used FIRST_ROWS hint.
|
||||
*/
|
||||
public RownumSqlLimiter() {
|
||||
this("rn_", true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the inner rownum column alias and whether to include the FIRST_ROWS
|
||||
* hint.
|
||||
*/
|
||||
public RownumSqlLimiter(String rnum, boolean useFirstRowsHint) {
|
||||
this.rnum = rnum;
|
||||
this.useFirstRowsHint = useFirstRowsHint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqlLimitResponse limit(SqlLimitRequest request) {
|
||||
|
||||
// select *
|
||||
// from ( select /*+ FIRST_ROWS(n) */ ROWNUM rnum, a.*
|
||||
// from ( your_query_goes_here,
|
||||
// with order by ) a
|
||||
// where ROWNUM <=
|
||||
// :MAX_ROW_TO_FETCH )
|
||||
// where rnum >= :MIN_ROW_TO_FETCH;
|
||||
|
||||
String dbSql = request.getDbSql();
|
||||
|
||||
StringBuilder sb = new StringBuilder(60 + dbSql.length());
|
||||
|
||||
int firstRow = request.getFirstRow();
|
||||
|
||||
int lastRow = request.getMaxRows();
|
||||
if (lastRow > 0) {
|
||||
lastRow += firstRow;
|
||||
}
|
||||
|
||||
sb.append("select * from ( ");
|
||||
|
||||
sb.append("select ");
|
||||
if (useFirstRowsHint && request.getMaxRows() > 0) {
|
||||
sb.append("/*+ FIRST_ROWS(").append(request.getMaxRows()).append(") */ ");
|
||||
}
|
||||
|
||||
sb.append("rownum ").append(rnum).append(", a.* ");
|
||||
sb.append(" from (");
|
||||
|
||||
sb.append(" select ");
|
||||
if (request.isDistinct()) {
|
||||
sb.append("distinct ");
|
||||
}
|
||||
sb.append(dbSql);
|
||||
|
||||
sb.append(NEW_LINE).append(" ) a ");
|
||||
if (lastRow > 0) {
|
||||
sb.append(" where rownum <= ").append(lastRow);
|
||||
}
|
||||
sb.append(" ) ");
|
||||
if (firstRow > 0) {
|
||||
sb.append(" where ");
|
||||
sb.append(rnum).append(" > ").append(firstRow);
|
||||
}
|
||||
|
||||
String sql = request.getDbPlatform().completeSql(sb.toString(), request.getOrmQuery());
|
||||
|
||||
return new SqlLimitResponse(sql, true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
package io.ebean.config.dbplatform;
|
||||
|
||||
import io.ebean.BackgroundExecutor;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Database sequence based IdGenerator using Sequence Step 1 but batch fetch many sequence values.
|
||||
*/
|
||||
public abstract class SequenceBatchIdGenerator extends SequenceIdGenerator {
|
||||
|
||||
/**
|
||||
* Construct where batchSize is the sequence step size.
|
||||
*
|
||||
*/
|
||||
public SequenceBatchIdGenerator(BackgroundExecutor be, DataSource ds, String seqName, int batchSize) {
|
||||
super(be, ds, seqName, batchSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* If allocateSize is large load some sequences in a background thread.
|
||||
* <p>
|
||||
* For example, when inserting a bean with a cascade on a OneToMany with many
|
||||
* beans Ebean can call this to ensure .
|
||||
* </p>
|
||||
*/
|
||||
@Override
|
||||
public void preAllocateIds(int requestSize) {
|
||||
if (allocationSize > 1 && requestSize > allocationSize) {
|
||||
// only bother if allocateSize is bigger than
|
||||
// the normal loading batchSize
|
||||
if (requestSize > 100) {
|
||||
// max out at 100 for now
|
||||
requestSize = 100;
|
||||
}
|
||||
loadInBackground(requestSize);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the next set of Ids as the next value plus all the following numbers up to the step size.
|
||||
*/
|
||||
@Override
|
||||
protected List<Long> readIds(ResultSet resultSet, int loadSize) throws SQLException {
|
||||
|
||||
List<Long> newIds = new ArrayList<>(loadSize);
|
||||
while (resultSet.next()) {
|
||||
newIds.add(resultSet.getLong(1));
|
||||
}
|
||||
return newIds;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,9 +12,10 @@ import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.NavigableSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
* Database sequence based IdGenerator.
|
||||
@@ -42,7 +43,7 @@ public abstract class SequenceIdGenerator implements PlatformIdGenerator {
|
||||
|
||||
protected final BackgroundExecutor backgroundExecutor;
|
||||
|
||||
protected final ArrayList<Long> idList = new ArrayList<>(50);
|
||||
protected final NavigableSet<Long> idList = new TreeSet<>();
|
||||
|
||||
protected final int allocationSize;
|
||||
|
||||
@@ -58,7 +59,7 @@ public abstract class SequenceIdGenerator implements PlatformIdGenerator {
|
||||
this.allocationSize = allocationSize;
|
||||
}
|
||||
|
||||
public abstract String getSql(int batchSize);
|
||||
public abstract String getSql();
|
||||
|
||||
/**
|
||||
* Returns the sequence name.
|
||||
@@ -97,15 +98,13 @@ public abstract class SequenceIdGenerator implements PlatformIdGenerator {
|
||||
@Override
|
||||
public Object nextId(Transaction t) {
|
||||
synchronized (monitor) {
|
||||
|
||||
int size = idList.size();
|
||||
if (size > 0) {
|
||||
maybeLoadMoreInBackground(size);
|
||||
} else {
|
||||
loadMore(allocationSize);
|
||||
loadMore();
|
||||
}
|
||||
|
||||
return idList.remove(0);
|
||||
return idList.pollFirst();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,8 +116,8 @@ public abstract class SequenceIdGenerator implements PlatformIdGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
private void loadMore(int requestSize) {
|
||||
List<Long> newIds = getMoreIds(requestSize);
|
||||
private void loadMore() {
|
||||
List<Long> newIds = getMoreIds();
|
||||
synchronized (monitor) {
|
||||
idList.addAll(newIds);
|
||||
}
|
||||
@@ -140,7 +139,7 @@ public abstract class SequenceIdGenerator implements PlatformIdGenerator {
|
||||
currentlyBackgroundLoading = true;
|
||||
|
||||
backgroundExecutor.execute(() -> {
|
||||
loadMore(requestSize);
|
||||
loadMore();
|
||||
synchronized (backgroundLoadMonitor) {
|
||||
currentlyBackgroundLoading = false;
|
||||
}
|
||||
@@ -151,14 +150,14 @@ public abstract class SequenceIdGenerator implements PlatformIdGenerator {
|
||||
/**
|
||||
* Read the resultSet returning the list of Id values.
|
||||
*/
|
||||
protected abstract List<Long> readIds(ResultSet resultSet, int loadSize) throws SQLException;
|
||||
protected abstract List<Long> readIds(ResultSet resultSet) throws SQLException;
|
||||
|
||||
/**
|
||||
* Get more Id's by executing a query and reading the Id's returned.
|
||||
*/
|
||||
protected List<Long> getMoreIds(int requestSize) {
|
||||
protected List<Long> getMoreIds() {
|
||||
|
||||
String sql = getSql(requestSize);
|
||||
String sql = getSql();
|
||||
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
@@ -169,7 +168,7 @@ public abstract class SequenceIdGenerator implements PlatformIdGenerator {
|
||||
statement = connection.prepareStatement(sql);
|
||||
resultSet = statement.executeQuery();
|
||||
|
||||
List<Long> newIds = readIds(resultSet, requestSize);
|
||||
List<Long> newIds = readIds(resultSet);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("seq:{} loaded:{} sql:{}", seqName, newIds.size(), sql);
|
||||
}
|
||||
|
||||
@@ -13,19 +13,25 @@ import java.util.List;
|
||||
*/
|
||||
public abstract class SequenceStepIdGenerator extends SequenceIdGenerator {
|
||||
|
||||
private final String nextSql;
|
||||
/**
|
||||
* Construct with stepSize (typically 50).
|
||||
*/
|
||||
protected SequenceStepIdGenerator(BackgroundExecutor be, DataSource ds, String seqName, int stepSize) {
|
||||
protected SequenceStepIdGenerator(BackgroundExecutor be, DataSource ds, String seqName, int stepSize, String nextSql) {
|
||||
super(be, ds, seqName, stepSize);
|
||||
this.nextSql = nextSql;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSql() {
|
||||
return nextSql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the next set of Ids as the next value plus all the following numbers up to the step size.
|
||||
*/
|
||||
@Override
|
||||
protected List<Long> readIds(ResultSet resultSet, int ignoreRequestSize) throws SQLException {
|
||||
|
||||
protected List<Long> readIds(ResultSet resultSet) throws SQLException {
|
||||
List<Long> newIds = new ArrayList<>(allocationSize);
|
||||
if (resultSet.next()) {
|
||||
long start = resultSet.getLong(1);
|
||||
|
||||
@@ -3,6 +3,7 @@ package io.ebean.config.dbplatform;
|
||||
import io.ebean.AcquireLockException;
|
||||
import io.ebean.DataIntegrityException;
|
||||
import io.ebean.DuplicateKeyException;
|
||||
import io.ebean.SerializableConflictException;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
import java.sql.SQLException;
|
||||
@@ -14,12 +15,12 @@ import java.util.Map;
|
||||
*/
|
||||
public class SqlCodeTranslator implements SqlExceptionTranslator {
|
||||
|
||||
private final Map<String,DataErrorType> map;
|
||||
private final Map<String, DataErrorType> map;
|
||||
|
||||
/**
|
||||
* Create given the map of SQLState codes to error types.
|
||||
*/
|
||||
public SqlCodeTranslator(Map<String,DataErrorType> map) {
|
||||
public SqlCodeTranslator(Map<String, DataErrorType> map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
@@ -46,6 +47,8 @@ public class SqlCodeTranslator implements SqlExceptionTranslator {
|
||||
return new DuplicateKeyException(message, e);
|
||||
case DataIntegrity:
|
||||
return new DataIntegrityException(message, e);
|
||||
case SerializableConflict:
|
||||
return new SerializableConflictException(message, e);
|
||||
}
|
||||
}
|
||||
// return a generic exception
|
||||
|
||||
@@ -8,7 +8,7 @@ import java.util.Map;
|
||||
*/
|
||||
public class SqlErrorCodes {
|
||||
|
||||
private Map<String,DataErrorType> map = new HashMap<>();
|
||||
private final Map<String, DataErrorType> map = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Map the codes to AcquireLockException.
|
||||
@@ -31,6 +31,13 @@ public class SqlErrorCodes {
|
||||
return add(DataErrorType.DuplicateKey, codes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Map the codes to SerializableConflictException.
|
||||
*/
|
||||
public SqlErrorCodes addSerializableConflict(String... codes) {
|
||||
return add(DataErrorType.SerializableConflict, codes);
|
||||
}
|
||||
|
||||
private SqlErrorCodes add(DataErrorType type, String... codes) {
|
||||
for (String code : codes) {
|
||||
map.put(code, type);
|
||||
|
||||
@@ -7,14 +7,11 @@ public class SqlLimitResponse {
|
||||
|
||||
final String sql;
|
||||
|
||||
final boolean includesRowNumberColumn;
|
||||
|
||||
/**
|
||||
* Create the response.
|
||||
*/
|
||||
public SqlLimitResponse(String sql, boolean includesRowNumberColumn) {
|
||||
public SqlLimitResponse(String sql) {
|
||||
this.sql = sql;
|
||||
this.includesRowNumberColumn = includesRowNumberColumn;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -24,11 +21,4 @@ public class SqlLimitResponse {
|
||||
return sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a ROW_NUMBER column is used in the query.
|
||||
*/
|
||||
public boolean isIncludesRowNumberColumn() {
|
||||
return includesRowNumberColumn;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ public class ClickHousePlatform extends DatabasePlatform {
|
||||
|
||||
dbTypeMap.put(DbType.UUID, new DbPlatformType("UUID", false));
|
||||
dbTypeMap.put(DbType.INET, new DbPlatformType("String", false));
|
||||
dbTypeMap.put(DbType.CDIR, new DbPlatformType("String", false));
|
||||
dbTypeMap.put(DbType.CIDR, new DbPlatformType("String", false));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Clickhouse DB specific support.
|
||||
*/
|
||||
package io.ebean.config.dbplatform.clickhouse;
|
||||
@@ -21,7 +21,7 @@ public class CockroachPlatform extends PostgresPlatform {
|
||||
* Needs a commit after create index such that alter table add foreign key ... succeeds.
|
||||
*/
|
||||
@Override
|
||||
public boolean isDdlCommitOnCreateIndex() {
|
||||
public boolean isDdlAutoCommit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Cockroach DB specific support.
|
||||
*/
|
||||
package io.ebean.config.dbplatform.cockroach;
|
||||
@@ -22,6 +22,7 @@ public class DB2Platform extends DatabasePlatform {
|
||||
this.platform = Platform.DB2;
|
||||
this.maxTableNameLength = 18;
|
||||
this.maxConstraintNameLength = 18;
|
||||
this.truncateTable = "truncate table %s reuse storage ignore delete triggers immediate";
|
||||
this.sqlLimiter = new Db2SqlLimiter();
|
||||
|
||||
this.dbIdentity.setSupportsGetGeneratedKeys(true);
|
||||
@@ -51,9 +52,8 @@ public class DB2Platform extends DatabasePlatform {
|
||||
* sequence values.
|
||||
*/
|
||||
@Override
|
||||
public PlatformIdGenerator createSequenceIdGenerator(BackgroundExecutor be, DataSource ds, int stepSize, String seqName) {
|
||||
|
||||
return new DB2SequenceIdGenerator(be, ds, seqName, sequenceBatchSize);
|
||||
public PlatformIdGenerator createSequenceIdGenerator(BackgroundExecutor be, DataSource ds, int increment, String seqName) {
|
||||
return new DB2Sequence(be, ds, seqName, increment);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package io.ebean.config.dbplatform.db2;
|
||||
|
||||
import io.ebean.BackgroundExecutor;
|
||||
import io.ebean.config.dbplatform.SequenceStepIdGenerator;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
/**
|
||||
* DB2 specific sequence Id Generator.
|
||||
*/
|
||||
class DB2Sequence extends SequenceStepIdGenerator {
|
||||
|
||||
DB2Sequence(BackgroundExecutor be, DataSource ds, String seqName, int stepSize) {
|
||||
super(be, ds, seqName, stepSize, "values nextval for " + seqName);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package io.ebean.config.dbplatform.db2;
|
||||
|
||||
import io.ebean.BackgroundExecutor;
|
||||
import io.ebean.config.dbplatform.SequenceBatchIdGenerator;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
/**
|
||||
* DB2 specific sequence Id Generator.
|
||||
*/
|
||||
public class DB2SequenceIdGenerator extends SequenceBatchIdGenerator {
|
||||
|
||||
private final String baseSql;
|
||||
private final String unionBaseSql;
|
||||
|
||||
/**
|
||||
* Construct given a dataSource and sql to return the next sequence value.
|
||||
*/
|
||||
public DB2SequenceIdGenerator(BackgroundExecutor be, DataSource ds, String seqName, int batchSize) {
|
||||
super(be, ds, seqName, batchSize);
|
||||
this.baseSql = "values nextval for " + seqName;
|
||||
this.unionBaseSql = " union " + baseSql;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSql(int batchSize) {
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(baseSql);
|
||||
for (int i = 1; i < batchSize; i++) {
|
||||
sb.append(unionBaseSql);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,6 @@ public class Db2SqlLimiter implements SqlLimiter {
|
||||
}
|
||||
|
||||
String sql = request.getDbPlatform().completeSql(sb.toString(), request.getOrmQuery());
|
||||
return new SqlLimitResponse(sql, false);
|
||||
return new SqlLimitResponse(sql);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package io.ebean.config.dbplatform.h2;
|
||||
|
||||
import io.ebean.BackgroundExecutor;
|
||||
import io.ebean.config.dbplatform.SequenceStepIdGenerator;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
class H2DbSequence extends SequenceStepIdGenerator {
|
||||
|
||||
H2DbSequence(BackgroundExecutor be, DataSource ds, String seqName, int stepSize) {
|
||||
super(be, ds, seqName, stepSize, "select " + seqName + ".nextval");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,9 +24,9 @@ public class H2Platform extends DatabasePlatform {
|
||||
this.historySupport = new H2HistorySupport();
|
||||
this.nativeUuidType = true;
|
||||
this.supportsDeleteTableAlias = true;
|
||||
this.inlineSqlUpdateLimit = true;
|
||||
this.dbDefaultValue.setNow("now()");
|
||||
this.columnAliasPrefix = null;
|
||||
|
||||
this.exceptionTranslator =
|
||||
new SqlErrorCodes()
|
||||
.addAcquireLock("50200","HYT00")
|
||||
@@ -42,13 +42,9 @@ public class H2Platform extends DatabasePlatform {
|
||||
dbTypeMap.put(DbType.UUID, new DbPlatformType("uuid", false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a H2 specific sequence IdGenerator that supports batch fetching
|
||||
* sequence values.
|
||||
*/
|
||||
@Override
|
||||
public PlatformIdGenerator createSequenceIdGenerator(BackgroundExecutor be, DataSource ds, int stepSize, String seqName) {
|
||||
return new H2SequenceIdGenerator(be, ds, seqName, sequenceBatchSize);
|
||||
public PlatformIdGenerator createSequenceIdGenerator(BackgroundExecutor be, DataSource ds, int increment, String seqName) {
|
||||
return new H2DbSequence(be, ds, seqName, increment);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
package io.ebean.config.dbplatform.h2;
|
||||
|
||||
import io.ebean.BackgroundExecutor;
|
||||
import io.ebean.config.dbplatform.SequenceBatchIdGenerator;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
/**
|
||||
* H2 specific sequence Id Generator.
|
||||
*/
|
||||
public class H2SequenceIdGenerator extends SequenceBatchIdGenerator {
|
||||
|
||||
private final String baseSql;
|
||||
private final String unionBaseSql;
|
||||
|
||||
/**
|
||||
* Construct given a dataSource and sql to return the next sequence value.
|
||||
*/
|
||||
public H2SequenceIdGenerator(BackgroundExecutor be, DataSource ds, String seqName, int batchSize) {
|
||||
super(be, ds, seqName, batchSize);
|
||||
this.baseSql = "select " + seqName + ".nextval";
|
||||
this.unionBaseSql = " union " + baseSql;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSql(int batchSize) {
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(baseSql);
|
||||
for (int i = 1; i < batchSize; i++) {
|
||||
sb.append(unionBaseSql);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,6 @@ public class HanaPlatform extends DatabasePlatform {
|
||||
this.persistBatchOnCascade = PersistBatch.NONE;
|
||||
this.supportsResultSetConcurrencyModeUpdatable = false;
|
||||
this.columnAliasPrefix = null;
|
||||
|
||||
this.historySupport = new HanaHistorySupport();
|
||||
this.basicSqlLimiter = new HanaBasicSqlLimiter();
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@ public class HanaSqlLimiter implements SqlLimiter {
|
||||
}
|
||||
|
||||
String sql = request.getDbPlatform().completeSql(sb.toString(), request.getOrmQuery());
|
||||
|
||||
return new SqlLimitResponse(sql, false);
|
||||
return new SqlLimitResponse(sql);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
package io.ebean.config.dbplatform.hsqldb;
|
||||
|
||||
import io.ebean.BackgroundExecutor;
|
||||
import io.ebean.annotation.Platform;
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebean.config.dbplatform.DbPlatformType;
|
||||
import io.ebean.config.dbplatform.DbType;
|
||||
import io.ebean.config.dbplatform.IdType;
|
||||
import io.ebean.config.dbplatform.PlatformIdGenerator;
|
||||
import io.ebean.config.dbplatform.h2.H2DbEncrypt;
|
||||
import io.ebean.config.dbplatform.h2.H2SequenceIdGenerator;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
/**
|
||||
* H2 specific platform.
|
||||
*/
|
||||
public class HsqldbPlatform extends DatabasePlatform {
|
||||
|
||||
public HsqldbPlatform() {
|
||||
super();
|
||||
this.platform = Platform.HSQLDB;
|
||||
this.dbEncrypt = new H2DbEncrypt();
|
||||
|
||||
this.dbIdentity.setIdType(IdType.IDENTITY);
|
||||
this.dbIdentity.setSupportsGetGeneratedKeys(true);
|
||||
this.dbIdentity.setSupportsSequence(true);
|
||||
this.dbIdentity.setSupportsIdentity(true);
|
||||
|
||||
dbTypeMap.put(DbType.INTEGER, new DbPlatformType("integer", false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlatformIdGenerator createSequenceIdGenerator(BackgroundExecutor be, DataSource ds, int stepSize, String seqName) {
|
||||
return new H2SequenceIdGenerator(be, ds, seqName, sequenceBatchSize);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
/**
|
||||
* Hsqldb specific support.
|
||||
*/
|
||||
package io.ebean.config.dbplatform.hsqldb;
|
||||
@@ -0,0 +1,14 @@
|
||||
package io.ebean.config.dbplatform.mysql;
|
||||
|
||||
import io.ebean.annotation.Platform;
|
||||
import io.ebean.config.dbplatform.DbPlatformType;
|
||||
import io.ebean.config.dbplatform.DbType;
|
||||
|
||||
public class MySql55Platform extends MySqlPlatform {
|
||||
|
||||
public MySql55Platform() {
|
||||
super();
|
||||
this.platform = Platform.MYSQL55;
|
||||
dbTypeMap.put(DbType.TIMESTAMP, new DbPlatformType("datetime"));
|
||||
}
|
||||
}
|
||||
@@ -27,15 +27,16 @@ public class MySqlPlatform extends DatabasePlatform {
|
||||
this.platform = Platform.MYSQL;
|
||||
this.useExtraTransactionOnIterateSecondaryQueries = true;
|
||||
this.selectCountWithAlias = true;
|
||||
this.supportsSavepointId = false;
|
||||
this.inlineSqlUpdateLimit = true;
|
||||
this.dbEncrypt = new MySqlDbEncrypt();
|
||||
this.historySupport = new MySqlHistorySupport();
|
||||
this.columnAliasPrefix = null;
|
||||
|
||||
this.dbIdentity.setIdType(IdType.IDENTITY);
|
||||
this.dbIdentity.setSupportsGetGeneratedKeys(true);
|
||||
this.dbIdentity.setSupportsIdentity(true);
|
||||
this.dbIdentity.setSupportsSequence(false);
|
||||
|
||||
|
||||
this.dbDefaultValue.setNow("now(6)"); // must have same precision as TIMESTAMP
|
||||
this.dbDefaultValue.setFalse("0");
|
||||
this.dbDefaultValue.setTrue("1");
|
||||
@@ -51,8 +52,8 @@ public class MySqlPlatform extends DatabasePlatform {
|
||||
this.openQuote = "`";
|
||||
this.closeQuote = "`";
|
||||
// use pipe for escaping as it depends if mysql runs in no_backslash_escapes or not.
|
||||
this.likeClauseRaw = "like binary ? escape ''";
|
||||
this.likeClauseEscaped = "like binary ? escape '|'";
|
||||
this.likeClauseRaw = "like ? escape''";
|
||||
this.likeClauseEscaped = "like ? escape'|'";
|
||||
|
||||
this.forwardOnlyHintOnFindIterate = true;
|
||||
this.booleanDbType = Types.BIT;
|
||||
@@ -64,6 +65,8 @@ public class MySqlPlatform extends DatabasePlatform {
|
||||
dbTypeMap.put(DbType.BLOB, new MySqlBlob());
|
||||
dbTypeMap.put(DbType.BINARY, new DbPlatformType("binary", 255));
|
||||
dbTypeMap.put(DbType.VARBINARY, new DbPlatformType("varbinary", 255));
|
||||
dbTypeMap.put(DbType.JSON, new DbPlatformType("json", false));
|
||||
dbTypeMap.put(DbType.JSONB, new DbPlatformType("json", false));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package io.ebean.config.dbplatform.nuodb;
|
||||
|
||||
import io.ebean.config.dbplatform.DbViewHistorySupport;
|
||||
|
||||
/**
|
||||
* Runtime support for @History with NuoDB.
|
||||
*/
|
||||
public class NuoDbHistorySupport extends DbViewHistorySupport {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package io.ebean.config.dbplatform.nuodb;
|
||||
|
||||
import io.ebean.BackgroundExecutor;
|
||||
import io.ebean.Query;
|
||||
import io.ebean.annotation.Platform;
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebean.config.dbplatform.DbPlatformType;
|
||||
import io.ebean.config.dbplatform.DbType;
|
||||
import io.ebean.config.dbplatform.IdType;
|
||||
import io.ebean.config.dbplatform.PlatformIdGenerator;
|
||||
import io.ebean.config.dbplatform.SqlErrorCodes;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
/**
|
||||
* NuoDb specific platform.
|
||||
*/
|
||||
public class NuoDbPlatform extends DatabasePlatform {
|
||||
|
||||
public NuoDbPlatform() {
|
||||
super();
|
||||
this.platform = Platform.NUODB;
|
||||
this.idInExpandedForm = true;
|
||||
this.supportsResultSetConcurrencyModeUpdatable = false;
|
||||
this.supportsDeleteTableAlias = true;
|
||||
this.columnAliasPrefix = null;
|
||||
this.likeClauseRaw = "like ?";
|
||||
this.historySupport = new NuoDbHistorySupport();
|
||||
//this.dbEncrypt = ...
|
||||
dbIdentity.setIdType(IdType.IDENTITY);
|
||||
dbIdentity.setSupportsIdentity(true);
|
||||
dbIdentity.setSupportsSequence(true);
|
||||
dbIdentity.setSupportsGetGeneratedKeys(true);
|
||||
|
||||
// No referential integrity exception to map
|
||||
this.exceptionTranslator =
|
||||
new SqlErrorCodes()
|
||||
//.addAcquireLock("")
|
||||
.addDuplicateKey("23000")
|
||||
.addSerializableConflict("40002")
|
||||
.build();
|
||||
|
||||
dbTypeMap.put(DbType.INTEGER, new DbPlatformType("integer", false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlatformIdGenerator createSequenceIdGenerator(BackgroundExecutor be, DataSource ds, int increment, String seqName) {
|
||||
return new NuoDbSequence(be, ds, seqName, increment);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String withForUpdate(String sql, Query.ForUpdate forUpdateMode) {
|
||||
switch (forUpdateMode) {
|
||||
case NOWAIT:
|
||||
return sql + " for update nowait";
|
||||
case SKIPLOCKED:
|
||||
default:
|
||||
return sql + " for update";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package io.ebean.config.dbplatform.nuodb;
|
||||
|
||||
import io.ebean.BackgroundExecutor;
|
||||
import io.ebean.config.dbplatform.SequenceStepIdGenerator;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
class NuoDbSequence extends SequenceStepIdGenerator {
|
||||
|
||||
NuoDbSequence(BackgroundExecutor be, DataSource ds, String seqName, int stepSize) {
|
||||
super(be, ds, seqName, stepSize, "select next value for " + seqName + " from dual");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* NuoDB specific support.
|
||||
*/
|
||||
package io.ebean.config.dbplatform.nuodb;
|
||||
@@ -0,0 +1,16 @@
|
||||
package io.ebean.config.dbplatform.oracle;
|
||||
|
||||
import io.ebean.annotation.Platform;
|
||||
|
||||
/**
|
||||
* Oracle 11 platform using rownum sql limiting.
|
||||
*/
|
||||
public class Oracle11Platform extends OraclePlatform {
|
||||
|
||||
public Oracle11Platform() {
|
||||
super();
|
||||
this.platform = Platform.ORACLE11;
|
||||
this.columnAliasPrefix = "c";
|
||||
this.sqlLimiter = new OracleRownumSqlLimiter();
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user