mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Compare commits
390
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6f694eb6ca | ||
|
|
539633c963 | ||
|
|
8e05956f6b | ||
|
|
94951a5476 | ||
|
|
2cd769d00f | ||
|
|
389f2bcd2f | ||
|
|
1ba259d15d | ||
|
|
4899f23773 | ||
|
|
771e9ff069 | ||
|
|
7d27c06483 | ||
|
|
d6a8643fe4 | ||
|
|
97c714d945 | ||
|
|
57f6668b37 | ||
|
|
9d506b4397 | ||
|
|
5a12cc58d1 | ||
|
|
f7c83411c2 | ||
|
|
a02fee7de0 | ||
|
|
170e323ee9 | ||
|
|
4555f3da51 | ||
|
|
376b3a9f13 | ||
|
|
43af5343a4 | ||
|
|
886f539fc4 | ||
|
|
1035d74113 | ||
|
|
26a4feb5ba | ||
|
|
a1c0e21234 | ||
|
|
cbe133dd68 | ||
|
|
4b1fe063b0 | ||
|
|
15f1bd310b | ||
|
|
6e3e9bd4f7 | ||
|
|
fddcc64741 | ||
|
|
ed917c55f1 | ||
|
|
17fed0ebd8 | ||
|
|
2dcd17830a | ||
|
|
a412873da6 | ||
|
|
7f5370c709 | ||
|
|
9470a1376c | ||
|
|
7f5b65cf45 | ||
|
|
6d0f5aea82 | ||
|
|
530a75b591 | ||
|
|
13cfaba0c8 | ||
|
|
1fa92efb63 | ||
|
|
bc477c64cb | ||
|
|
804098149e | ||
|
|
567ad92050 | ||
|
|
3a84cb8623 | ||
|
|
b4ddbe38ee | ||
|
|
01722b334b | ||
|
|
0a780523cf | ||
|
|
f2e04d9fbf | ||
|
|
4b8565e7c7 | ||
|
|
1359d534d5 | ||
|
|
94ae513d85 | ||
|
|
d58c56484e | ||
|
|
75a27fa2d6 | ||
|
|
cc1c08cd34 | ||
|
|
029cde12db | ||
|
|
b33914ab2f | ||
|
|
d571a6c354 | ||
|
|
95b19569e4 | ||
|
|
a9560c6664 | ||
|
|
235822bcb2 | ||
|
|
5a024ea19f | ||
|
|
399f8b92fa | ||
|
|
be93263015 | ||
|
|
b4fe4ec8b9 | ||
|
|
8c9f5f4a22 | ||
|
|
953f8054e6 | ||
|
|
aadb791980 | ||
|
|
7430f97c9c | ||
|
|
ba21eeaadb | ||
|
|
c0e827ffda | ||
|
|
3b30708dfc | ||
|
|
9f9184ac6a | ||
|
|
5845f94303 | ||
|
|
dd824ffe52 | ||
|
|
e5d29afa4c | ||
|
|
5ae5e408e3 | ||
|
|
90f6d0707f | ||
|
|
0310601e31 | ||
|
|
015dd00b8e | ||
|
|
6d978add29 | ||
|
|
e529232f76 | ||
|
|
d982ac73b7 | ||
|
|
ddaff81b9c | ||
|
|
1d11666945 | ||
|
|
223e5160dc | ||
|
|
64605b5090 | ||
|
|
425124d8f7 | ||
|
|
6af8968280 | ||
|
|
a9bee03ba7 | ||
|
|
302cc426bd | ||
|
|
44462e3513 | ||
|
|
b748c598a1 | ||
|
|
dbac184b4c | ||
|
|
29c5916203 | ||
|
|
827315a11d | ||
|
|
14ef8f6e0d | ||
|
|
5b63434f13 | ||
|
|
3e8cc87f01 | ||
|
|
190b4ef588 | ||
|
|
4a20c9eb99 | ||
|
|
d8c2b3d583 | ||
|
|
48c8f5e2ca | ||
|
|
69a753fc4f | ||
|
|
b9ba6b2db5 | ||
|
|
7a6071ac9a | ||
|
|
404b167bcc | ||
|
|
7278db56ea | ||
|
|
1dc5ecc81f | ||
|
|
c39661e2c2 | ||
|
|
a702bbb5ee | ||
|
|
1982027300 | ||
|
|
2e1a6eec04 | ||
|
|
e5f37e638c | ||
|
|
7ffea8e922 | ||
|
|
315640df6b | ||
|
|
78a647a72e | ||
|
|
7ffd2f1886 | ||
|
|
0087eabb4e | ||
|
|
5f0731f975 | ||
|
|
85e31899b9 | ||
|
|
3337541ac4 | ||
|
|
b123b06f4d | ||
|
|
17df5a2c16 | ||
|
|
e13aaefee1 | ||
|
|
09ce693da2 | ||
|
|
17f7be72f4 | ||
|
|
23061473c7 | ||
|
|
0944b87283 | ||
|
|
86768dfe4d | ||
|
|
ffdafc796b | ||
|
|
5466c6a350 | ||
|
|
7e0ac5a73a | ||
|
|
008e1849a2 | ||
|
|
dcf60a3d1c | ||
|
|
774cab327d | ||
|
|
2f824c99ea | ||
|
|
1a54fc12ad | ||
|
|
a1d6b280bc | ||
|
|
fa561e5197 | ||
|
|
4a8231a6cc | ||
|
|
5cb486c745 | ||
|
|
dd26dc342d | ||
|
|
7733e9382c | ||
|
|
bc6d2fb3be | ||
|
|
a9dbc036e9 | ||
|
|
8d29a3a575 | ||
|
|
4158ac4665 | ||
|
|
ddab6e65b7 | ||
|
|
bbede04a56 | ||
|
|
9df96b0294 | ||
|
|
6a6b6b8200 | ||
|
|
e26e093680 | ||
|
|
fc107115c6 | ||
|
|
0139ad891e | ||
|
|
4f70c09690 | ||
|
|
df8ae18bf6 | ||
|
|
8edaabf755 | ||
|
|
25eea42211 | ||
|
|
263f6cdeba | ||
|
|
38f1967e60 | ||
|
|
6eb8eb0dd2 | ||
|
|
1165d857d8 | ||
|
|
874c2f5231 | ||
|
|
88ab852855 | ||
|
|
b577331524 | ||
|
|
ec45fc1c86 | ||
|
|
e65876e8ed | ||
|
|
5453037172 | ||
|
|
9b116c9bf6 | ||
|
|
82862deccc | ||
|
|
1c83bbe0b0 | ||
|
|
f16f34f35f | ||
|
|
38bc5b2fea | ||
|
|
356dc5eb19 | ||
|
|
c5779133bc | ||
|
|
b8b6311348 | ||
|
|
8eed983fbb | ||
|
|
7cfecb83a9 | ||
|
|
e92939a34d | ||
|
|
408b982eb3 | ||
|
|
dd7e7711a8 | ||
|
|
5a3f7853a6 | ||
|
|
01847e44de | ||
|
|
0cf9f0bf58 | ||
|
|
b01b44af10 | ||
|
|
8d85000970 | ||
|
|
e7f9c63502 | ||
|
|
eb21b41fba | ||
|
|
3dc6c567a0 | ||
|
|
18eed47306 | ||
|
|
9ddf1333ed | ||
|
|
73896d375f | ||
|
|
3f645211a6 | ||
|
|
451e2fa93c | ||
|
|
2ff3b0acb7 | ||
|
|
42594533da | ||
|
|
678494f331 | ||
|
|
361df6732a | ||
|
|
c3320f4a0b | ||
|
|
c411d9a665 | ||
|
|
8ea2c31076 | ||
|
|
254b0df16b | ||
|
|
c0f4451d20 | ||
|
|
6c544a2835 | ||
|
|
227d18bbf0 | ||
|
|
18cdd2ed7a | ||
|
|
91d1fb8cea | ||
|
|
058021f8d0 | ||
|
|
f4d270e8b5 | ||
|
|
7b8052c097 | ||
|
|
68b7deba9d | ||
|
|
860aad11ce | ||
|
|
65e924feaa | ||
|
|
6cc5e83b01 | ||
|
|
752d5d4782 | ||
|
|
20fdbfc972 | ||
|
|
bd01dfd29a | ||
|
|
6a9b5944a3 | ||
|
|
6e31de6f2e | ||
|
|
5fddc37037 | ||
|
|
ca6e3963db | ||
|
|
a966557b68 | ||
|
|
1a6a426683 | ||
|
|
dd43fe4db3 | ||
|
|
b4ebeb0070 | ||
|
|
0dbf982293 | ||
|
|
12d7184f02 | ||
|
|
c3295f1145 | ||
|
|
9bdcd6c55e | ||
|
|
b627794f8f | ||
|
|
b9f3ff24e9 | ||
|
|
9752eced1f | ||
|
|
e7aa1fdac5 | ||
|
|
9d26ab2103 | ||
|
|
103f965182 | ||
|
|
d28d9a6176 | ||
|
|
173b81a64b | ||
|
|
135b1e3b57 | ||
|
|
888109d706 | ||
|
|
8cd6d50def | ||
|
|
272b316ecc | ||
|
|
e95edad04b | ||
|
|
f830662cce | ||
|
|
84ac737ceb | ||
|
|
483f0398b2 | ||
|
|
d934d44164 | ||
|
|
a2ad1aaf6e | ||
|
|
a0b6a13e6c | ||
|
|
a65340b939 | ||
|
|
0279f8b1ad | ||
|
|
bd2faed6a0 | ||
|
|
a0e2155ec2 | ||
|
|
5ff9171aaf | ||
|
|
4d7936c1a6 | ||
|
|
552145db37 | ||
|
|
0504cdc2d8 | ||
|
|
a380b609cd | ||
|
|
65ac083872 | ||
|
|
a82dca24da | ||
|
|
466a616f3e | ||
|
|
a0552387f8 | ||
|
|
25bc0e947d | ||
|
|
c67e66c0ca | ||
|
|
b60f9201a9 | ||
|
|
f8253a1252 | ||
|
|
2581d82cff | ||
|
|
331ea90e14 | ||
|
|
dfb1d6ab54 | ||
|
|
067f4bfdea | ||
|
|
0a71ad624e | ||
|
|
09115a824d | ||
|
|
28d4d07966 | ||
|
|
c3e91fed65 | ||
|
|
2cad98ad26 | ||
|
|
8a25a7b6ec | ||
|
|
83fbfd1b2a | ||
|
|
a9c6cd15a1 | ||
|
|
63b9b42dc8 | ||
|
|
268146df85 | ||
|
|
d05a77e755 | ||
|
|
69c768b3be | ||
|
|
07f9bf98c3 | ||
|
|
9af64f61f7 | ||
|
|
c1a78d3c8b | ||
|
|
08fc7399ec | ||
|
|
86d805c9fa | ||
|
|
34135360ed | ||
|
|
53b4d6fd73 | ||
|
|
1114ccfb3a | ||
|
|
b4403c58d1 | ||
|
|
951903db76 | ||
|
|
093d111524 | ||
|
|
08e166a9b7 | ||
|
|
d5fe7a9ebe | ||
|
|
9f52856343 | ||
|
|
0b529603c4 | ||
|
|
60d0a3da39 | ||
|
|
1c224444c0 | ||
|
|
d3e07defa0 | ||
|
|
1b5d379ed3 | ||
|
|
b90393a691 | ||
|
|
2d26740286 | ||
|
|
5807874c9e | ||
|
|
ea7b4e8162 | ||
|
|
43742fdc0b | ||
|
|
8ef71bd451 | ||
|
|
0f60e2240c | ||
|
|
2cbb161ed5 | ||
|
|
a47caec85b | ||
|
|
fd1b5f58bc | ||
|
|
39a4035f3b | ||
|
|
0bb7d79015 | ||
|
|
9907cffe6e | ||
|
|
704a138ff0 | ||
|
|
f3cab4ee10 | ||
|
|
d507452d63 | ||
|
|
893aa6cb1a | ||
|
|
e92fd2ef06 | ||
|
|
bdad8b258a | ||
|
|
a6cdf8d6dc | ||
|
|
e232c724c0 | ||
|
|
d55023dbc7 | ||
|
|
fa4e013692 | ||
|
|
08502d7315 | ||
|
|
6f4bc0ac2c | ||
|
|
5585866e82 | ||
|
|
f21f6d9592 | ||
|
|
03e0519951 | ||
|
|
bc23d5829c | ||
|
|
64108aac40 | ||
|
|
fcda419abb | ||
|
|
4d34c9e868 | ||
|
|
5178b76431 | ||
|
|
8fb02662e6 | ||
|
|
1aac63771d | ||
|
|
3a138c3462 | ||
|
|
30088f4de7 | ||
|
|
cc272bb950 | ||
|
|
b3ee982b64 | ||
|
|
92a13ad265 | ||
|
|
a445557ec3 | ||
|
|
c7bb027c7d | ||
|
|
709eb369c9 | ||
|
|
5a4924b6cb | ||
|
|
a61c73c62a | ||
|
|
7862648b83 | ||
|
|
fa252a1fe4 | ||
|
|
add7a8c4ba | ||
|
|
834c04bd33 | ||
|
|
9bda4ab5c7 | ||
|
|
d1ca7a30dc | ||
|
|
cb67dd0f29 | ||
|
|
e173f6e9a9 | ||
|
|
349cd01921 | ||
|
|
8fa7fa6af3 | ||
|
|
caf18565a0 | ||
|
|
c89d39ec2d | ||
|
|
556557276c | ||
|
|
2f277938e5 | ||
|
|
5322ab3e7e | ||
|
|
100832ddd9 | ||
|
|
3f5009aa91 | ||
|
|
8dbd290119 | ||
|
|
ea3fb833a4 | ||
|
|
0273e1c2c8 | ||
|
|
8440a13b0f | ||
|
|
c5e940733c | ||
|
|
ac73031bec | ||
|
|
a65ff8a650 | ||
|
|
f904fea104 | ||
|
|
2549eace09 | ||
|
|
a592717c77 | ||
|
|
db6f93e383 | ||
|
|
0a0d67585c | ||
|
|
db2f8cd811 | ||
|
|
b6e524f879 | ||
|
|
40492f487c | ||
|
|
2cee03bc4b | ||
|
|
e2c6125501 | ||
|
|
3fe521c53a | ||
|
|
b53221fc0e | ||
|
|
b23551ce43 | ||
|
|
3971ccea1a | ||
|
|
35b1f835c5 | ||
|
|
ef5e3a796d | ||
|
|
091b5fbf26 | ||
|
|
d3dbde4e79 | ||
|
|
033c579984 | ||
|
|
1a34a56351 |
@@ -0,0 +1,40 @@
|
||||
|
||||
name: Build
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
java_version: [8]
|
||||
os: [ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: ${{ matrix.java_version }}
|
||||
distribution: 'zulu'
|
||||
- name: Maven cache
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: maven-cache
|
||||
with:
|
||||
path:
|
||||
~/.m2
|
||||
key: build-${{ env.cache-name }}
|
||||
- name: Maven version
|
||||
run: mvn --version
|
||||
# - name: Maven single test
|
||||
# run: mvn --batch-mode clean verify -Dtest="io.ebeaninternal.server.core.DefaultServer_getReferenceTest" -DfailIfNoTests=false
|
||||
- name: Build with Maven
|
||||
run: mvn clean package
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
|
||||
name: DB2 LUW
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '10 8 * * 2,5'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
java_version: [11]
|
||||
os: [ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: ${{ matrix.java_version }}
|
||||
distribution: 'adopt'
|
||||
- name: Maven cache
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: maven-cache
|
||||
with:
|
||||
path:
|
||||
~/.m2
|
||||
key: build-${{ env.cache-name }}
|
||||
- name: db2
|
||||
run: mvn clean test -Dprops.file=testconfig/ebean-db2.properties
|
||||
@@ -0,0 +1,39 @@
|
||||
|
||||
name: JDK 18-ea
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '30 6 * * 1,3,5'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
java_version: [18-ea]
|
||||
os: [ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: ${{ matrix.java_version }}
|
||||
distribution: 'zulu'
|
||||
- name: Maven cache
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: maven-cache
|
||||
with:
|
||||
path:
|
||||
~/.m2
|
||||
key: build-${{ env.cache-name }}
|
||||
- name: Build with Maven
|
||||
run: mvn package
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
|
||||
name: MariaDB
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '10 7 * * 1,4'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
java_version: [11]
|
||||
os: [ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: ${{ matrix.java_version }}
|
||||
distribution: 'adopt'
|
||||
- name: Maven cache
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: maven-cache
|
||||
with:
|
||||
path:
|
||||
~/.m2
|
||||
key: build-${{ env.cache-name }}
|
||||
- name: mariadb 10.6
|
||||
run: mvn clean test -Dprops.file=testconfig/ebean-mariadb.properties
|
||||
@@ -0,0 +1,53 @@
|
||||
|
||||
name: Multi-database platform
|
||||
|
||||
on: [workflow_dispatch]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
java_version: [11]
|
||||
os: [ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: ${{ matrix.java_version }}
|
||||
distribution: 'adopt'
|
||||
- name: Maven cache
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: maven-cache
|
||||
with:
|
||||
path:
|
||||
~/.m2
|
||||
key: build-${{ env.cache-name }}
|
||||
- name: h2
|
||||
run: mvn clean test
|
||||
- name: postgres
|
||||
run: mvn clean test -Dprops.file=testconfig/ebean-postgres.properties
|
||||
- name: mysql
|
||||
run: mvn clean test -Dprops.file=testconfig/ebean-mysql.properties
|
||||
- name: mariadb
|
||||
run: mvn clean test -Dprops.file=testconfig/ebean-mariadb.properties
|
||||
- name: mariadb
|
||||
run: mvn clean test -Dprops.file=testconfig/ebean-mariadb.properties
|
||||
- name: sqlserver
|
||||
run: mvn clean test -Dprops.file=testconfig/ebean-sqlserver17.properties
|
||||
- name: yugabyte
|
||||
run: mvn clean test -Dprops.file=testconfig/ebean-yugabyte.properties
|
||||
# - name: sqlserver 2019
|
||||
# run: mvn clean test -Dprops.file=testconfig/ebean-sqlserver19.properties
|
||||
# - name: db2
|
||||
# run: mvn clean test -Dprops.file=testconfig/ebean-db2.properties
|
||||
# - name: oracle
|
||||
# run: mvn clean test -Dprops.file=testconfig/ebean-oracle.properties
|
||||
@@ -0,0 +1,39 @@
|
||||
|
||||
name: Multi-JDK Build
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '30 6 * * *'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
java_version: [8.0.192, 8, 11.0.3, 11, 17]
|
||||
os: [ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: ${{ matrix.java_version }}
|
||||
distribution: 'zulu'
|
||||
- name: Maven cache
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: maven-cache
|
||||
with:
|
||||
path:
|
||||
~/.m2
|
||||
key: build-${{ env.cache-name }}
|
||||
- name: Build with Maven
|
||||
run: mvn package
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
|
||||
name: MySql
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '20 6 * * *'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
java_version: [11]
|
||||
os: [ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: ${{ matrix.java_version }}
|
||||
distribution: 'adopt'
|
||||
- name: Maven cache
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: maven-cache
|
||||
with:
|
||||
path:
|
||||
~/.m2
|
||||
key: build-${{ env.cache-name }}
|
||||
- name: mysql
|
||||
run: mvn clean test -Dprops.file=testconfig/ebean-mysql.properties
|
||||
@@ -0,0 +1,38 @@
|
||||
|
||||
name: Oracle18
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '10 6 * * 1,4'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
java_version: [11]
|
||||
os: [ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: ${{ matrix.java_version }}
|
||||
distribution: 'zulu'
|
||||
- name: Maven cache
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: maven-cache
|
||||
with:
|
||||
path:
|
||||
~/.m2
|
||||
key: build-${{ env.cache-name }}
|
||||
- name: oracle
|
||||
run: mvn clean test -Dprops.file=testconfig/ebean-oracle.properties
|
||||
@@ -0,0 +1,38 @@
|
||||
|
||||
name: Postgres
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '10 6 * * *'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
java_version: [11]
|
||||
os: [ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: ${{ matrix.java_version }}
|
||||
distribution: 'adopt'
|
||||
- name: Maven cache
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: maven-cache
|
||||
with:
|
||||
path:
|
||||
~/.m2
|
||||
key: build-${{ env.cache-name }}
|
||||
- name: postgres
|
||||
run: mvn clean test -Dprops.file=testconfig/ebean-postgres.properties
|
||||
@@ -0,0 +1,35 @@
|
||||
|
||||
name: SqlServer 2019
|
||||
|
||||
on: [workflow_dispatch]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
java_version: [11]
|
||||
os: [ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: ${{ matrix.java_version }}
|
||||
distribution: 'adopt'
|
||||
- name: Maven cache
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: maven-cache
|
||||
with:
|
||||
path:
|
||||
~/.m2
|
||||
key: build-${{ env.cache-name }}
|
||||
- name: sqlserver 2019 latest
|
||||
run: mvn clean test -Dprops.file=testconfig/ebean-sqlserver19.properties
|
||||
@@ -0,0 +1,40 @@
|
||||
|
||||
name: SqlServer
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '10 7 * * 2,5'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
java_version: [11]
|
||||
os: [ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: ${{ matrix.java_version }}
|
||||
distribution: 'adopt'
|
||||
- name: Maven cache
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: maven-cache
|
||||
with:
|
||||
path:
|
||||
~/.m2
|
||||
key: build-${{ env.cache-name }}
|
||||
# - name: sqlserver 2019 latest
|
||||
# run: mvn clean test -Dprops.file=testconfig/ebean-sqlserver.properties
|
||||
- name: sqlserver 2017 latest
|
||||
run: mvn clean test -Dprops.file=testconfig/ebean-sqlserver17.properties
|
||||
@@ -0,0 +1,38 @@
|
||||
|
||||
name: Yugabyte
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '10 3 * * *'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
java_version: [11]
|
||||
os: [ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: ${{ matrix.java_version }}
|
||||
distribution: 'adopt'
|
||||
- name: Maven cache
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: maven-cache
|
||||
with:
|
||||
path:
|
||||
~/.m2
|
||||
key: build-${{ env.cache-name }}
|
||||
- name: yugabyte
|
||||
run: mvn clean test -Dprops.file=testconfig/ebean-yugabyte.properties
|
||||
@@ -1,5 +1,13 @@
|
||||
[](https://travis-ci.org/ebean-orm/ebean)
|
||||
[](https://github.com/ebean-orm/ebean/actions/workflows/build.yml)
|
||||
[](https://maven-badges.herokuapp.com/maven-central/io.ebean/ebean)
|
||||
[](https://github.com/ebean-orm/ebean/blob/master/LICENSE)
|
||||
[](https://github.com/ebean-orm/ebean/actions/workflows/multi-jdk-build.yml)
|
||||
[](https://github.com/ebean-orm/ebean/actions/workflows/jdk-18-ea.yml)
|
||||
|
||||
[](https://github.com/ebean-orm/ebean/actions/workflows/postgres.yml)
|
||||
[](https://github.com/ebean-orm/ebean/actions/workflows/mysql.yml)
|
||||
[](https://github.com/ebean-orm/ebean/actions/workflows/mariadb.yml)
|
||||
[](https://github.com/ebean-orm/ebean/actions/workflows/sqlserver.yml)
|
||||
|
||||
# Sponsors
|
||||
<table>
|
||||
@@ -36,11 +44,8 @@ Post questions or issues to the Ebean google group - https://groups.google.com/f
|
||||
Goto [https://ebean.io/docs/](https://ebean.io/docs/)
|
||||
|
||||
|
||||
## Maven cental links:
|
||||
## Maven central links:
|
||||
[Maven central - ebean](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22io.ebean%22%20AND%20a%3A%22ebean%22 "maven central ebean")
|
||||
|
||||
[Maven central - all related projects](http://search.maven.org/#search%7Cga%7C1%7Cebean "maven central all related projects")
|
||||
|
||||
## 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
|
||||
|
||||
+6
-7
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>12.12.0</version>
|
||||
<version>12.15.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean api</name>
|
||||
@@ -27,7 +27,7 @@
|
||||
<dependency>
|
||||
<groupId>io.avaje</groupId>
|
||||
<artifactId>avaje-config</artifactId>
|
||||
<version>1.5</version>
|
||||
<version>1.7</version>
|
||||
</dependency>
|
||||
|
||||
<!--
|
||||
@@ -36,9 +36,8 @@
|
||||
-->
|
||||
<dependency>
|
||||
<groupId>io.avaje</groupId>
|
||||
<artifactId>avaje-jsr305</artifactId>
|
||||
<version>1.1</version>
|
||||
<scope>provided</scope>
|
||||
<artifactId>avaje-lang</artifactId>
|
||||
<version>1.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -50,7 +49,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-annotation</artifactId>
|
||||
<version>7.3</version>
|
||||
<version>7.6</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -86,7 +85,7 @@
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>1.4.199</version>
|
||||
<version>${h2database.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.avaje.lang.NonNullApi;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
@@ -18,6 +20,7 @@ import java.util.concurrent.TimeUnit;
|
||||
* This also propagates MDC context from the current thread to the
|
||||
* background task if defined.
|
||||
*/
|
||||
@NonNullApi
|
||||
public interface BackgroundExecutor {
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.ebean;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import io.avaje.lang.NonNullApi;
|
||||
import io.avaje.lang.Nullable;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -27,10 +27,10 @@ import java.util.Optional;
|
||||
* @param <I> The ID type
|
||||
* @param <T> The Bean type
|
||||
*/
|
||||
@NonNullApi
|
||||
public abstract class BeanFinder<I,T> {
|
||||
|
||||
protected final Database server;
|
||||
|
||||
protected final Class<T> type;
|
||||
|
||||
/**
|
||||
@@ -81,7 +81,6 @@ public abstract class BeanFinder<I,T> {
|
||||
* <p>
|
||||
* Equivalent to {@link Database#reference(Class, Object)}
|
||||
*/
|
||||
@Nonnull
|
||||
public T ref(I id) {
|
||||
return db().reference(type, id);
|
||||
}
|
||||
@@ -97,7 +96,6 @@ public abstract class BeanFinder<I,T> {
|
||||
/**
|
||||
* Find an entity by ID returning an Optional.
|
||||
*/
|
||||
@Nullable
|
||||
public Optional<T> findByIdOrEmpty(I id) {
|
||||
return db().find(type).setId(id).findOneOrEmpty();
|
||||
}
|
||||
@@ -112,7 +110,6 @@ public abstract class BeanFinder<I,T> {
|
||||
/**
|
||||
* Retrieves all entities of the given type.
|
||||
*/
|
||||
@Nonnull
|
||||
public List<T> findAll() {
|
||||
return query().findList();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.avaje.lang.NonNullApi;
|
||||
import io.ebean.bean.EntityBean;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -31,6 +32,7 @@ import java.util.Collection;
|
||||
* @param <I> The ID type
|
||||
* @param <T> The Bean type
|
||||
*/
|
||||
@NonNullApi
|
||||
public abstract class BeanRepository<I, T> extends BeanFinder<I, T> {
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.ebean;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -138,7 +137,6 @@ public interface BeanState {
|
||||
/**
|
||||
* Returns a map with load errors.
|
||||
*/
|
||||
@Nullable
|
||||
Map<String, Exception> loadErrors();
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.avaje.lang.NonNullApi;
|
||||
import io.avaje.lang.Nullable;
|
||||
import io.ebean.annotation.TxIsolation;
|
||||
import io.ebean.cache.ServerCacheManager;
|
||||
import io.ebean.plugin.Property;
|
||||
import io.ebean.text.csv.CsvReader;
|
||||
import io.ebean.text.json.JsonContext;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.OptimisticLockException;
|
||||
import javax.persistence.PersistenceException;
|
||||
import java.util.Collection;
|
||||
@@ -60,6 +60,7 @@ import java.util.concurrent.Callable;
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
@NonNullApi
|
||||
public final class DB {
|
||||
|
||||
private static final DbContext context = DbContext.getInstance();
|
||||
@@ -523,15 +524,13 @@ public final class DB {
|
||||
* @param bean The entity bean to check uniqueness on
|
||||
* @return a set of Properties if constraint validation was detected or empty list.
|
||||
*/
|
||||
@Nonnull
|
||||
public static Set<Property> checkUniqueness(Object bean) {
|
||||
return getDefault().checkUniqueness(bean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@link #checkUniqueness(Object)}. but with given transaction.
|
||||
* Same as {@link #checkUniqueness(Object)} but with given transaction.
|
||||
*/
|
||||
@Nonnull
|
||||
public static Set<Property> checkUniqueness(Object bean, Transaction transaction) {
|
||||
return getDefault().checkUniqueness(bean, transaction);
|
||||
}
|
||||
@@ -851,7 +850,6 @@ public final class DB {
|
||||
* }</pre>
|
||||
*/
|
||||
public static <T> Update<T> createUpdate(Class<T> beanType, String ormUpdate) {
|
||||
|
||||
return getDefault().createUpdate(beanType, ormUpdate);
|
||||
}
|
||||
|
||||
@@ -859,7 +857,6 @@ public final class DB {
|
||||
* Create a CsvReader for a given beanType.
|
||||
*/
|
||||
public static <T> CsvReader<T> createCsvReader(Class<T> beanType) {
|
||||
|
||||
return getDefault().createCsvReader(beanType);
|
||||
}
|
||||
|
||||
@@ -897,7 +894,6 @@ public final class DB {
|
||||
* @return A ORM Query for this beanType
|
||||
*/
|
||||
public static <T> Query<T> createQuery(Class<T> beanType) {
|
||||
|
||||
return getDefault().createQuery(beanType);
|
||||
}
|
||||
|
||||
@@ -935,7 +931,6 @@ public final class DB {
|
||||
* @return The query with expressions defined as per the parsed query statement
|
||||
*/
|
||||
public static <T> Query<T> createQuery(Class<T> beanType, String eql) {
|
||||
|
||||
return getDefault().createQuery(beanType, eql);
|
||||
}
|
||||
|
||||
@@ -951,7 +946,6 @@ public final class DB {
|
||||
* @return A ORM Query object for this beanType
|
||||
*/
|
||||
public static <T> Query<T> find(Class<T> beanType) {
|
||||
|
||||
return getDefault().find(beanType);
|
||||
}
|
||||
|
||||
@@ -1030,77 +1024,6 @@ public final class DB {
|
||||
return getDefault().filter(beanType);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Execute a Sql Update Delete or Insert statement. This returns the number of
|
||||
// * rows that where updated, deleted or inserted. If is executed in batch then
|
||||
// * this returns -1. You can get the actual rowCount after commit() from
|
||||
// * updateSql.getRowCount().
|
||||
// * <p>
|
||||
// * If you wish to execute a Sql Select natively then you should use the
|
||||
// * FindByNativeSql object.
|
||||
// * </p>
|
||||
// * <p>
|
||||
// * Note that the table modification information is automatically deduced and
|
||||
// * you do not need to call the DB.externalModification() method when you
|
||||
// * use this method.
|
||||
// * </p>
|
||||
// * <p>
|
||||
// * Example:
|
||||
// * </p>
|
||||
// * <pre>{@code
|
||||
// *
|
||||
// * // example that uses 'named' parameters
|
||||
// * String s = "UPDATE f_topic set post_count = :count where id = :id"
|
||||
// *
|
||||
// * SqlUpdate update = DB.createSqlUpdate(s);
|
||||
// *
|
||||
// * update.setParameter("id", 1);
|
||||
// * update.setParameter("count", 50);
|
||||
// *
|
||||
// * int modifiedCount = DB.execute(update);
|
||||
// *
|
||||
// * String msg = "There where " + modifiedCount + "rows updated";
|
||||
// *
|
||||
// * }</pre>
|
||||
// *
|
||||
// * @param sqlUpdate the update sql potentially with bind values
|
||||
// * @return the number of rows updated or deleted. -1 if executed in batch.
|
||||
// * @see SqlUpdate
|
||||
// * @see CallableSql
|
||||
// * @see DB#execute(CallableSql)
|
||||
// */
|
||||
// public static int execute(SqlUpdate sqlUpdate) {
|
||||
// return defaultDatabase().execute(sqlUpdate);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * For making calls to stored procedures.
|
||||
// * <p>
|
||||
// * Example:
|
||||
// * </p>
|
||||
// * <pre>{@code
|
||||
// *
|
||||
// * String sql = "{call sp_order_modify(?,?,?)}";
|
||||
// *
|
||||
// * CallableSql cs = DB.createCallableSql(sql);
|
||||
// * cs.setParameter(1, 27);
|
||||
// * cs.setParameter(2, "SHIPPED");
|
||||
// * cs.registerOut(3, Types.INTEGER);
|
||||
// *
|
||||
// * DB.execute(cs);
|
||||
// *
|
||||
// * // read the out parameter
|
||||
// * Integer returnValue = (Integer) cs.getObject(3);
|
||||
// *
|
||||
// * }</pre>
|
||||
// *
|
||||
// * @see CallableSql
|
||||
// * @see Ebean#execute(SqlUpdate)
|
||||
// */
|
||||
// public static int execute(CallableSql callableSql) {
|
||||
// return defaultDatabase().execute(callableSql);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Execute a TxRunnable in a Transaction with an explicit scope.
|
||||
* <p>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.avaje.lang.NonNullApi;
|
||||
import io.avaje.lang.Nullable;
|
||||
import io.ebean.annotation.Platform;
|
||||
import io.ebean.annotation.TxIsolation;
|
||||
import io.ebean.cache.ServerCacheManager;
|
||||
@@ -10,8 +12,6 @@ import io.ebean.plugin.SpiServer;
|
||||
import io.ebean.text.csv.CsvReader;
|
||||
import io.ebean.text.json.JsonContext;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.OptimisticLockException;
|
||||
import javax.persistence.PersistenceException;
|
||||
import javax.sql.DataSource;
|
||||
@@ -92,6 +92,7 @@ import java.util.concurrent.Callable;
|
||||
* @see DatabaseFactory
|
||||
* @see DatabaseConfig
|
||||
*/
|
||||
@NonNullApi
|
||||
public interface Database {
|
||||
|
||||
/**
|
||||
@@ -575,8 +576,8 @@ public interface Database {
|
||||
<T> DtoQuery<T> createNamedDtoQuery(Class<T> dtoType, String namedQuery);
|
||||
|
||||
/**
|
||||
* Look to execute a native sql query that does not returns beans but instead
|
||||
* returns SqlRow or direct access to ResultSet (see {@link SqlQuery#findList(RowMapper)}.
|
||||
* Look to execute a native sql query that does not return beans but instead
|
||||
* returns SqlRow or direct access to ResultSet.
|
||||
*
|
||||
* <p>
|
||||
* Refer to {@link DtoQuery} for native sql queries returning DTO beans.
|
||||
@@ -949,7 +950,6 @@ public interface Database {
|
||||
* @param beanType the type of entity bean
|
||||
* @param id the id value
|
||||
*/
|
||||
@Nonnull
|
||||
<T> T reference(Class<T> beanType, Object id);
|
||||
|
||||
/**
|
||||
@@ -1236,6 +1236,7 @@ public interface Database {
|
||||
* @param id the bean id value
|
||||
* @param transaction the transaction to use (can be null)
|
||||
*/
|
||||
@Nullable
|
||||
<T> T find(Class<T> beanType, Object id, Transaction transaction);
|
||||
|
||||
/**
|
||||
@@ -1294,13 +1295,11 @@ public interface Database {
|
||||
* @param bean The entity bean to check uniqueness on
|
||||
* @return a set of Properties if constraint validation was detected or empty list.
|
||||
*/
|
||||
@Nonnull
|
||||
Set<Property> checkUniqueness(Object bean);
|
||||
|
||||
/**
|
||||
* Same as {@link #checkUniqueness(Object)}. but with given transaction.
|
||||
*/
|
||||
@Nonnull
|
||||
Set<Property> checkUniqueness(Object bean, Transaction transaction);
|
||||
|
||||
/**
|
||||
@@ -1614,6 +1613,7 @@ public interface Database {
|
||||
* @param id the id of the entity bean
|
||||
* @param transaction the transaction the publish process should use (can be null)
|
||||
*/
|
||||
@Nullable
|
||||
<T> T publish(Class<T> beanType, Object id, Transaction transaction);
|
||||
|
||||
/**
|
||||
@@ -1627,6 +1627,7 @@ public interface Database {
|
||||
* @param beanType the type of the entity bean
|
||||
* @param id the id of the entity bean
|
||||
*/
|
||||
@Nullable
|
||||
<T> T publish(Class<T> beanType, Object id);
|
||||
|
||||
/**
|
||||
@@ -1665,6 +1666,7 @@ public interface Database {
|
||||
* @param id the id of the entity bean to restore
|
||||
* @param transaction the transaction the restore process should use (can be null)
|
||||
*/
|
||||
@Nullable
|
||||
<T> T draftRestore(Class<T> beanType, Object id, Transaction transaction);
|
||||
|
||||
/**
|
||||
@@ -1678,6 +1680,7 @@ public interface Database {
|
||||
* @param beanType the type of the entity bean
|
||||
* @param id the id of the entity bean to restore
|
||||
*/
|
||||
@Nullable
|
||||
<T> T draftRestore(Class<T> beanType, Object id);
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.avaje.lang.NonNullApi;
|
||||
import io.avaje.lang.Nullable;
|
||||
import io.ebean.docstore.DocQueryContext;
|
||||
import io.ebean.docstore.RawDoc;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -13,6 +14,7 @@ import java.util.function.Predicate;
|
||||
/**
|
||||
* Document storage operations.
|
||||
*/
|
||||
@NonNullApi
|
||||
public interface DocumentStore {
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package io.ebean;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import io.avaje.lang.NonNullApi;
|
||||
import io.avaje.lang.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
@@ -38,12 +40,12 @@ import java.util.stream.Stream;
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
@NonNullApi
|
||||
public interface DtoQuery<T> extends CancelableQuery {
|
||||
|
||||
/**
|
||||
* Execute the query returning a list.
|
||||
*/
|
||||
@Nonnull
|
||||
List<T> findList();
|
||||
|
||||
/**
|
||||
@@ -53,7 +55,6 @@ public interface DtoQuery<T> extends CancelableQuery {
|
||||
* resultSet and potentially connection and MUST be closed. We should use
|
||||
* QueryIterator in a <em>try with resource block</em>.
|
||||
*/
|
||||
@Nonnull
|
||||
QueryIterator<T> findIterate();
|
||||
|
||||
/**
|
||||
@@ -63,7 +64,6 @@ public interface DtoQuery<T> extends CancelableQuery {
|
||||
* resultSet and potentially connection and MUST be closed. We should use
|
||||
* the Stream in a <em>try with resource block</em>.
|
||||
*/
|
||||
@Nonnull
|
||||
Stream<T> findStream();
|
||||
|
||||
/**
|
||||
@@ -105,7 +105,6 @@ public interface DtoQuery<T> extends CancelableQuery {
|
||||
/**
|
||||
* Execute the query returning an optional bean.
|
||||
*/
|
||||
@Nonnull
|
||||
Optional<T> findOneOrEmpty();
|
||||
|
||||
/**
|
||||
@@ -130,6 +129,13 @@ public interface DtoQuery<T> extends CancelableQuery {
|
||||
*/
|
||||
DtoQuery<T> setParameter(String name, Object value);
|
||||
|
||||
/**
|
||||
* Bind the named multi-value array parameter which we would use with Postgres ANY.
|
||||
* <p>
|
||||
* For Postgres this binds an ARRAY rather than expands into multiple bind values.
|
||||
*/
|
||||
DtoQuery<T> setArrayParameter(String name, Collection<?> values);
|
||||
|
||||
/**
|
||||
* Bind the parameter by its index position (1 based like JDBC).
|
||||
*/
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.avaje.lang.Nullable;
|
||||
import io.ebean.annotation.TxIsolation;
|
||||
import io.ebean.cache.ServerCacheManager;
|
||||
import io.ebean.plugin.Property;
|
||||
import io.ebean.text.csv.CsvReader;
|
||||
import io.ebean.text.json.JsonContext;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.OptimisticLockException;
|
||||
import javax.persistence.PersistenceException;
|
||||
import java.util.Collection;
|
||||
@@ -506,7 +505,6 @@ public final class Ebean {
|
||||
* @param bean The entity bean to check uniqueness on
|
||||
* @return a set of Properties if constraint validation was detected or empty list.
|
||||
*/
|
||||
@Nonnull
|
||||
public static Set<Property> checkUniqueness(Object bean) {
|
||||
return getDefault().checkUniqueness(bean);
|
||||
}
|
||||
@@ -514,7 +512,6 @@ public final class Ebean {
|
||||
/**
|
||||
* Same as {@link #checkUniqueness(Object)}. but with given transaction.
|
||||
*/
|
||||
@Nonnull
|
||||
public static Set<Property> checkUniqueness(Object bean, Transaction transaction) {
|
||||
return getDefault().checkUniqueness(bean, transaction);
|
||||
}
|
||||
|
||||
@@ -16,15 +16,22 @@ public class EbeanVersion {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger("io.ebean");
|
||||
|
||||
/**
|
||||
* Maintain the minimum ebean-agent version manually based on required ebean-agent bug fixes.
|
||||
*/
|
||||
private static final int MIN_AGENT_MAJOR_VERSION = 12;
|
||||
private static final int MIN_AGENT_MINOR_VERSION = 12;
|
||||
private static String version = "unknown";
|
||||
static {
|
||||
readVersion();
|
||||
checkAgentVersion();
|
||||
}
|
||||
|
||||
private static void readVersion() {
|
||||
try {
|
||||
Properties prop = new Properties();
|
||||
try (InputStream in = DB.class.getResourceAsStream("/META-INF/maven/io.ebean/ebean/pom.properties")) {
|
||||
try (InputStream in = ClassLoader.getSystemResourceAsStream("META-INF/maven/io.ebean/ebean-api/pom.properties")) {
|
||||
if (in != null) {
|
||||
prop.load(in);
|
||||
in.close();
|
||||
version = prop.getProperty("version");
|
||||
version = readVersion(in);
|
||||
}
|
||||
}
|
||||
log.info("ebean version: {}", version);
|
||||
@@ -33,6 +40,49 @@ public class EbeanVersion {
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkAgentVersion() {
|
||||
try {
|
||||
try (InputStream in = ClassLoader.getSystemResourceAsStream("META-INF/maven/io.ebean/ebean-agent/pom.properties")) {
|
||||
// often we only have ebean-agent during development (with build time enhancement), null is expected
|
||||
if (in != null) {
|
||||
String agentVersion = readVersion(in);
|
||||
if (agentVersion != null) {
|
||||
if (checkMinAgentVersion(agentVersion)) {
|
||||
log.error("Expected minimum ebean-agent version {}.{}.0 but we have {}, please update the ebean-agent", MIN_AGENT_MAJOR_VERSION, MIN_AGENT_MINOR_VERSION, agentVersion);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.warn("Could not check minimum ebean-agent version {}.{}.0 required due to - {}", MIN_AGENT_MAJOR_VERSION, MIN_AGENT_MINOR_VERSION, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if ebean-agent is NOT at our minimum version.
|
||||
*/
|
||||
static boolean checkMinAgentVersion(String agentVersion) {
|
||||
String[] versionSegments = agentVersion.split("\\.");
|
||||
if (versionSegments.length != 3) {
|
||||
return true;
|
||||
} else {
|
||||
int major = Integer.parseInt(versionSegments[0]);
|
||||
int minor = Integer.parseInt(versionSegments[1]);
|
||||
if (major < MIN_AGENT_MAJOR_VERSION) {
|
||||
return true;
|
||||
} else {
|
||||
return major == MIN_AGENT_MAJOR_VERSION && minor < MIN_AGENT_MINOR_VERSION;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String readVersion(InputStream in) throws IOException {
|
||||
Properties prop = new Properties();
|
||||
prop.load(in);
|
||||
in.close();
|
||||
return prop.getProperty("version");
|
||||
}
|
||||
|
||||
private EbeanVersion() {
|
||||
// hide
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.ebean;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Future;
|
||||
@@ -25,13 +24,11 @@ public class EmptyPagedList<T> implements PagedList<T> {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Future<Integer> getFutureCount() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public List<T> getList() {
|
||||
return Collections.emptyList();
|
||||
|
||||
@@ -1,21 +1,13 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.ebean.search.Match;
|
||||
import io.ebean.search.MultiMatch;
|
||||
import io.ebean.search.TextCommonTerms;
|
||||
import io.ebean.search.TextQueryString;
|
||||
import io.ebean.search.TextSimple;
|
||||
import io.avaje.lang.NonNullApi;
|
||||
import io.avaje.lang.Nullable;
|
||||
import io.ebean.search.*;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.NonUniqueResultException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@@ -39,6 +31,7 @@ import java.util.function.Predicate;
|
||||
*
|
||||
* @see Query#where()
|
||||
*/
|
||||
@NonNullApi
|
||||
public interface ExpressionList<T> {
|
||||
|
||||
/**
|
||||
@@ -327,7 +320,6 @@ public interface ExpressionList<T> {
|
||||
*
|
||||
* @see Query#findList()
|
||||
*/
|
||||
@Nonnull
|
||||
List<T> findList();
|
||||
|
||||
/**
|
||||
@@ -335,7 +327,6 @@ public interface ExpressionList<T> {
|
||||
*
|
||||
* @see Query#findIds()
|
||||
*/
|
||||
@Nonnull
|
||||
<A> List<A> findIds();
|
||||
|
||||
/**
|
||||
@@ -351,7 +342,6 @@ public interface ExpressionList<T> {
|
||||
*
|
||||
* @see Query#findSet()
|
||||
*/
|
||||
@Nonnull
|
||||
Set<T> findSet();
|
||||
|
||||
/**
|
||||
@@ -359,7 +349,6 @@ public interface ExpressionList<T> {
|
||||
*
|
||||
* @see Query#findMap()
|
||||
*/
|
||||
@Nonnull
|
||||
<K> Map<K, T> findMap();
|
||||
|
||||
/**
|
||||
@@ -392,7 +381,6 @@ public interface ExpressionList<T> {
|
||||
*
|
||||
* @return the list of values for the selected property
|
||||
*/
|
||||
@Nonnull
|
||||
<A> List<A> findSingleAttributeList();
|
||||
|
||||
/**
|
||||
@@ -429,7 +417,6 @@ public interface ExpressionList<T> {
|
||||
/**
|
||||
* Execute the query returning an optional bean.
|
||||
*/
|
||||
@Nonnull
|
||||
Optional<T> findOneOrEmpty();
|
||||
|
||||
/**
|
||||
@@ -442,7 +429,6 @@ public interface ExpressionList<T> {
|
||||
*
|
||||
* @return a Future object for the row count query
|
||||
*/
|
||||
@Nonnull
|
||||
FutureRowCount<T> findFutureCount();
|
||||
|
||||
/**
|
||||
@@ -455,7 +441,6 @@ public interface ExpressionList<T> {
|
||||
*
|
||||
* @return a Future object for the list of Id's
|
||||
*/
|
||||
@Nonnull
|
||||
FutureIds<T> findFutureIds();
|
||||
|
||||
/**
|
||||
@@ -468,7 +453,6 @@ public interface ExpressionList<T> {
|
||||
*
|
||||
* @return a Future object for the list result of the query
|
||||
*/
|
||||
@Nonnull
|
||||
FutureList<T> findFutureList();
|
||||
|
||||
/**
|
||||
@@ -499,7 +483,6 @@ public interface ExpressionList<T> {
|
||||
* @return The PagedList
|
||||
* @see Query#findPagedList()
|
||||
*/
|
||||
@Nonnull
|
||||
PagedList<T> findPagedList();
|
||||
|
||||
/**
|
||||
@@ -509,7 +492,6 @@ public interface ExpressionList<T> {
|
||||
* It will execute the query against the history returning the versions of the bean.
|
||||
* </p>
|
||||
*/
|
||||
@Nonnull
|
||||
List<Version<T>> findVersions();
|
||||
|
||||
/**
|
||||
@@ -519,13 +501,11 @@ public interface ExpressionList<T> {
|
||||
* It will execute the query against the history returning the versions of the bean.
|
||||
* </p>
|
||||
*/
|
||||
@Nonnull
|
||||
List<Version<T>> findVersionsBetween(Timestamp start, Timestamp end);
|
||||
|
||||
/**
|
||||
* Add some filter predicate expressions to the many property.
|
||||
*/
|
||||
@Nonnull
|
||||
ExpressionList<T> filterMany(String manyProperty);
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.ebean;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import io.avaje.lang.Nullable;
|
||||
|
||||
import javax.persistence.NonUniqueResultException;
|
||||
import java.time.Clock;
|
||||
import java.util.List;
|
||||
@@ -82,7 +82,6 @@ public interface ExtendedServer {
|
||||
*
|
||||
* @see Query#findIds()
|
||||
*/
|
||||
@Nonnull
|
||||
<A, T> List<A> findIds(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
@@ -100,7 +99,6 @@ public interface ExtendedServer {
|
||||
* @see Query#findEach(Consumer)
|
||||
* @see Query#findEachWhile(Predicate)
|
||||
*/
|
||||
@Nonnull
|
||||
<T> QueryIterator<T> findIterate(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
@@ -112,7 +110,6 @@ public interface ExtendedServer {
|
||||
* 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);
|
||||
|
||||
/**
|
||||
@@ -125,7 +122,6 @@ public interface ExtendedServer {
|
||||
* <p>
|
||||
* Note that the stream needs to be closed so use with try with resources.
|
||||
*/
|
||||
@Nonnull
|
||||
@Deprecated
|
||||
<T> Stream<T> findLargeStream(Query<T> query, Transaction transaction);
|
||||
|
||||
@@ -210,7 +206,6 @@ public interface ExtendedServer {
|
||||
* It will execute the query against the history returning the versions of the bean.
|
||||
* </p>
|
||||
*/
|
||||
@Nonnull
|
||||
<T> List<Version<T>> findVersions(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
@@ -235,7 +230,6 @@ public interface ExtendedServer {
|
||||
* @return the list of fetched beans.
|
||||
* @see Query#findList()
|
||||
*/
|
||||
@Nonnull
|
||||
<T> List<T> findList(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
@@ -251,7 +245,6 @@ public interface ExtendedServer {
|
||||
* @return a Future object for the row count query
|
||||
* @see Query#findFutureCount()
|
||||
*/
|
||||
@Nonnull
|
||||
<T> FutureRowCount<T> findFutureCount(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
@@ -267,7 +260,6 @@ public interface ExtendedServer {
|
||||
* @return a Future object for the list of Id's
|
||||
* @see Query#findFutureIds()
|
||||
*/
|
||||
@Nonnull
|
||||
<T> FutureIds<T> findFutureIds(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
@@ -284,7 +276,6 @@ public interface ExtendedServer {
|
||||
* @return a Future object for the list result of the query
|
||||
* @see Query#findFutureList()
|
||||
*/
|
||||
@Nonnull
|
||||
<T> FutureList<T> findFutureList(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
@@ -316,7 +307,6 @@ public interface ExtendedServer {
|
||||
* @return The PagedList
|
||||
* @see Query#findPagedList()
|
||||
*/
|
||||
@Nonnull
|
||||
<T> PagedList<T> findPagedList(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
@@ -341,7 +331,6 @@ public interface ExtendedServer {
|
||||
* @return the set of fetched beans.
|
||||
* @see Query#findSet()
|
||||
*/
|
||||
@Nonnull
|
||||
<T> Set<T> findSet(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
@@ -358,7 +347,6 @@ public interface ExtendedServer {
|
||||
* @return the map of fetched beans.
|
||||
* @see Query#findMap()
|
||||
*/
|
||||
@Nonnull
|
||||
<K, T> Map<K, T> findMap(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
@@ -391,7 +379,6 @@ public interface ExtendedServer {
|
||||
* @return the list of values for the selected property
|
||||
* @see Query#findSingleAttributeList()
|
||||
*/
|
||||
@Nonnull
|
||||
<A, T> List<A> findSingleAttributeList(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
@@ -419,7 +406,6 @@ public interface ExtendedServer {
|
||||
/**
|
||||
* Similar to findOne() but returns an Optional (rather than nullable).
|
||||
*/
|
||||
@Nonnull
|
||||
<T> Optional<T> findOneOrEmpty(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
@@ -463,7 +449,6 @@ public interface ExtendedServer {
|
||||
* @return the list of fetched MapBean.
|
||||
* @see SqlQuery#findList()
|
||||
*/
|
||||
@Nonnull
|
||||
List<SqlRow> findList(SqlQuery query, Transaction transaction);
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.avaje.lang.NonNullApi;
|
||||
import io.ebean.service.SpiFetchGroupQuery;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* Defines what part of the object graph to load (select and fetch clauses).
|
||||
* <p>
|
||||
@@ -62,6 +61,7 @@ import javax.annotation.Nonnull;
|
||||
*
|
||||
* @param <T> The bean type the Fetch group can be applied to
|
||||
*/
|
||||
@NonNullApi
|
||||
public interface FetchGroup<T> {
|
||||
|
||||
/**
|
||||
@@ -83,7 +83,6 @@ public interface FetchGroup<T> {
|
||||
*
|
||||
* @return The FetchGroup with the given select clause
|
||||
*/
|
||||
@Nonnull
|
||||
static <T> FetchGroup<T> of(Class<T> cls, String select) {
|
||||
return XServiceProvider.fetchGroupOf(cls, select);
|
||||
}
|
||||
@@ -108,7 +107,6 @@ public interface FetchGroup<T> {
|
||||
*
|
||||
* @return The FetchGroupBuilder with the given select clause which we will add fetch clauses to
|
||||
*/
|
||||
@Nonnull
|
||||
static <T> FetchGroupBuilder<T> of(Class<T> cls) {
|
||||
return XServiceProvider.fetchGroupOf(cls);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package io.ebean;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import io.avaje.lang.NonNullApi;
|
||||
|
||||
/**
|
||||
* Builds a FetchGroup by adding fetch clauses.
|
||||
@@ -23,85 +23,73 @@ import javax.annotation.Nonnull;
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
@NonNullApi
|
||||
public interface FetchGroupBuilder<T> {
|
||||
|
||||
/**
|
||||
* Specify specific properties to select (top level properties).
|
||||
*/
|
||||
@Nonnull
|
||||
FetchGroupBuilder<T> select(String select);
|
||||
|
||||
/**
|
||||
* Fetch all the properties at the given path.
|
||||
*/
|
||||
@Nonnull
|
||||
FetchGroupBuilder<T> fetch(String path);
|
||||
|
||||
/**
|
||||
* Fetch the path with the nested fetch group.
|
||||
*/
|
||||
@Nonnull
|
||||
FetchGroupBuilder<T> fetch(String path, FetchGroup<?> nestedGroup);
|
||||
|
||||
/**
|
||||
* Fetch the path using a query join with the nested fetch group.
|
||||
*/
|
||||
@Nonnull
|
||||
FetchGroupBuilder<T> fetchQuery(String path, FetchGroup<?> nestedGroup);
|
||||
|
||||
/**
|
||||
* Fetch the path lazily with the nested fetch group.
|
||||
*/
|
||||
@Nonnull
|
||||
FetchGroupBuilder<T> fetchLazy(String path, FetchGroup<?> nestedGroup);
|
||||
|
||||
/**
|
||||
* Fetch the path including specified properties.
|
||||
*/
|
||||
@Nonnull
|
||||
FetchGroupBuilder<T> fetch(String path, String properties);
|
||||
|
||||
/**
|
||||
* Fetch the path including all its properties using a query join.
|
||||
*/
|
||||
@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.
|
||||
*/
|
||||
@Nonnull
|
||||
FetchGroupBuilder<T> fetchLazy(String path);
|
||||
|
||||
/**
|
||||
* Fetch the path including specified properties lazily.
|
||||
*/
|
||||
@Nonnull
|
||||
FetchGroupBuilder<T> fetchLazy(String path, String properties);
|
||||
|
||||
/**
|
||||
* Build and return the FetchGroup.
|
||||
*/
|
||||
@Nonnull
|
||||
FetchGroup<T> build();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.avaje.lang.NonNullApi;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -77,6 +79,7 @@ import java.util.Set;
|
||||
*
|
||||
* @param <T> the entity bean type
|
||||
*/
|
||||
@NonNullApi
|
||||
public interface Filter<T> {
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.ebean;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import io.avaje.lang.NonNullApi;
|
||||
import io.avaje.lang.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -55,6 +55,7 @@ import java.util.List;
|
||||
* }</pre>
|
||||
*
|
||||
*/
|
||||
@NonNullApi
|
||||
public class Finder<I, T> {
|
||||
|
||||
/**
|
||||
@@ -139,7 +140,6 @@ public class Finder<I, T> {
|
||||
* <p>
|
||||
* Equivalent to {@link Database#reference(Class, Object)}
|
||||
*/
|
||||
@Nonnull
|
||||
public T ref(I id) {
|
||||
return db().reference(type, id);
|
||||
}
|
||||
@@ -166,7 +166,6 @@ public class Finder<I, T> {
|
||||
/**
|
||||
* Retrieves all entities of the given type.
|
||||
*/
|
||||
@Nonnull
|
||||
public List<T> all() {
|
||||
return query().findList();
|
||||
}
|
||||
|
||||
@@ -113,9 +113,9 @@ public interface Junction<T> extends Expression, ExpressionList<T> {
|
||||
*/
|
||||
SHOULD("should", "", true);
|
||||
|
||||
private String prefix;
|
||||
private String literal;
|
||||
private boolean text;
|
||||
private final String prefix;
|
||||
private final String literal;
|
||||
private final boolean text;
|
||||
|
||||
Type(String literal, String prefix, boolean text) {
|
||||
this.literal = literal;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.ebean;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
@@ -116,13 +115,11 @@ public interface PagedList<T> {
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
@Nonnull
|
||||
Future<Integer> getFutureCount();
|
||||
|
||||
/**
|
||||
* Return the list of entities for this page.
|
||||
*/
|
||||
@Nonnull
|
||||
List<T> getList();
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.ebean;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import io.avaje.lang.NonNullApi;
|
||||
import io.avaje.lang.Nullable;
|
||||
import javax.persistence.NonUniqueResultException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.Timestamp;
|
||||
@@ -177,6 +177,7 @@ import java.util.stream.Stream;
|
||||
*
|
||||
* @param <T> the type of Entity bean this query will fetch.
|
||||
*/
|
||||
@NonNullApi
|
||||
public interface Query<T> extends CancelableQuery {
|
||||
|
||||
/**
|
||||
@@ -689,7 +690,6 @@ public interface Query<T> extends CancelableQuery {
|
||||
* This query will execute against the Database that was used to create it.
|
||||
* </p>
|
||||
*/
|
||||
@Nonnull
|
||||
<A> List<A> findIds();
|
||||
|
||||
/**
|
||||
@@ -727,7 +727,6 @@ public interface Query<T> extends CancelableQuery {
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
@Nonnull
|
||||
QueryIterator<T> findIterate();
|
||||
|
||||
/**
|
||||
@@ -749,7 +748,6 @@ public interface Query<T> extends CancelableQuery {
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
@Nonnull
|
||||
Stream<T> findStream();
|
||||
|
||||
/**
|
||||
@@ -772,7 +770,6 @@ public interface Query<T> extends CancelableQuery {
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
@Nonnull
|
||||
@Deprecated
|
||||
Stream<T> findLargeStream();
|
||||
|
||||
@@ -882,7 +879,6 @@ public interface Query<T> extends CancelableQuery {
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
@Nonnull
|
||||
List<T> findList();
|
||||
|
||||
/**
|
||||
@@ -898,7 +894,6 @@ public interface Query<T> extends CancelableQuery {
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
@Nonnull
|
||||
Set<T> findSet();
|
||||
|
||||
/**
|
||||
@@ -918,7 +913,6 @@ public interface Query<T> extends CancelableQuery {
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
@Nonnull
|
||||
<K> Map<K, T> findMap();
|
||||
|
||||
/**
|
||||
@@ -951,7 +945,6 @@ public interface Query<T> extends CancelableQuery {
|
||||
*
|
||||
* @return the list of values for the selected property
|
||||
*/
|
||||
@Nonnull
|
||||
<A> List<A> findSingleAttributeList();
|
||||
|
||||
/**
|
||||
@@ -1049,7 +1042,6 @@ public interface Query<T> extends CancelableQuery {
|
||||
/**
|
||||
* Execute the query returning an optional bean.
|
||||
*/
|
||||
@Nonnull
|
||||
Optional<T> findOneOrEmpty();
|
||||
|
||||
/**
|
||||
@@ -1064,7 +1056,6 @@ public interface Query<T> extends CancelableQuery {
|
||||
* It will execute the query against the history returning the versions of the bean.
|
||||
* </p>
|
||||
*/
|
||||
@Nonnull
|
||||
List<Version<T>> findVersions();
|
||||
|
||||
/**
|
||||
@@ -1074,7 +1065,6 @@ public interface Query<T> extends CancelableQuery {
|
||||
* It will execute the query against the history returning the versions of the bean.
|
||||
* </p>
|
||||
*/
|
||||
@Nonnull
|
||||
List<Version<T>> findVersionsBetween(Timestamp start, Timestamp end);
|
||||
|
||||
/**
|
||||
@@ -1132,7 +1122,6 @@ public interface Query<T> extends CancelableQuery {
|
||||
*
|
||||
* @return a Future object for the row count query
|
||||
*/
|
||||
@Nonnull
|
||||
FutureRowCount<T> findFutureCount();
|
||||
|
||||
/**
|
||||
@@ -1145,7 +1134,6 @@ public interface Query<T> extends CancelableQuery {
|
||||
*
|
||||
* @return a Future object for the list of Id's
|
||||
*/
|
||||
@Nonnull
|
||||
FutureIds<T> findFutureIds();
|
||||
|
||||
/**
|
||||
@@ -1157,7 +1145,6 @@ public interface Query<T> extends CancelableQuery {
|
||||
*
|
||||
* @return a Future object for the list result of the query
|
||||
*/
|
||||
@Nonnull
|
||||
FutureList<T> findFutureList();
|
||||
|
||||
/**
|
||||
@@ -1187,7 +1174,6 @@ public interface Query<T> extends CancelableQuery {
|
||||
*
|
||||
* @return The PagedList
|
||||
*/
|
||||
@Nonnull
|
||||
PagedList<T> findPagedList();
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.ebean;
|
||||
|
||||
import java.net.URL;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -23,10 +24,10 @@ public interface ScriptRunner {
|
||||
/**
|
||||
* Run a script given the resource path (that should start with "/").
|
||||
*/
|
||||
void run(String path);
|
||||
void run(String resourcePath);
|
||||
|
||||
/**
|
||||
* Run a script given the resource path (that should start with "/") and place holders.
|
||||
* Run a script given the resource path (that should start with "/") and place-holders.
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
@@ -38,7 +39,7 @@ public interface ScriptRunner {
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
void run(String path, Map<String, String> placeholderMap);
|
||||
void run(String resourcePath, Map<String, String> placeholderMap);
|
||||
|
||||
/**
|
||||
* Run a DDL or SQL script given the resource.
|
||||
@@ -46,10 +47,20 @@ public interface ScriptRunner {
|
||||
void run(URL resource);
|
||||
|
||||
/**
|
||||
* Run a DDL or SQL script given the resource and place holders.
|
||||
* Run a DDL or SQL script given the resource and place-holders.
|
||||
*/
|
||||
void run(URL resource, Map<String, String> placeholderMap);
|
||||
|
||||
/**
|
||||
* Run a DDL or SQL script given the file.
|
||||
*/
|
||||
void run(Path file);
|
||||
|
||||
/**
|
||||
* Run a DDL or SQL script given the file and place-holders.
|
||||
*/
|
||||
void run(Path file, Map<String, String> placeholderMap);
|
||||
|
||||
/**
|
||||
* Run the raw provided DDL or SQL script.
|
||||
*
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.ebean;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import io.avaje.lang.NonNullApi;
|
||||
import io.avaje.lang.Nullable;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
@@ -37,12 +37,12 @@ import java.util.function.Predicate;
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
@NonNullApi
|
||||
public interface SqlQuery extends Serializable, CancelableQuery {
|
||||
|
||||
/**
|
||||
* Execute the query returning a list.
|
||||
*/
|
||||
@Nonnull
|
||||
List<SqlRow> findList();
|
||||
|
||||
/**
|
||||
@@ -119,7 +119,6 @@ public interface SqlQuery extends Serializable, CancelableQuery {
|
||||
/**
|
||||
* Execute the query returning an optional row.
|
||||
*/
|
||||
@Nonnull
|
||||
Optional<SqlRow> findOneOrEmpty();
|
||||
|
||||
/**
|
||||
@@ -354,6 +353,7 @@ public interface SqlQuery extends Serializable, CancelableQuery {
|
||||
/**
|
||||
* Return the single value.
|
||||
*/
|
||||
@Nullable
|
||||
T findOne();
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package io.ebean;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* A SqlUpdate for executing insert update or delete statements.
|
||||
* <p>
|
||||
@@ -324,6 +326,13 @@ public interface SqlUpdate {
|
||||
*/
|
||||
SqlUpdate setParameter(String name, Object param);
|
||||
|
||||
/**
|
||||
* Bind the named multi-value array parameter which we would use with Postgres ANY.
|
||||
* <p>
|
||||
* For Postgres this binds an ARRAY rather than expands into multiple bind values.
|
||||
*/
|
||||
SqlUpdate setArrayParameter(String name, Collection<?> values);
|
||||
|
||||
/**
|
||||
* Set a named parameter that has a null value. Exactly the same as
|
||||
* {@link #setNullParameter(String, int)}.
|
||||
|
||||
@@ -9,11 +9,7 @@ import javax.persistence.PersistenceException;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
@@ -1164,7 +1160,7 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
*/
|
||||
public Map<String, Exception> getLoadErrors() {
|
||||
if (loadErrors == null) {
|
||||
return null;
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
Map<String, Exception> ret = null;
|
||||
int len = getPropertyLength();
|
||||
|
||||
@@ -60,21 +60,15 @@ public interface PersistenceContext {
|
||||
int size(Class<?> rootType);
|
||||
|
||||
/**
|
||||
* Return a copy of the Persistence context to use for large query iteration.
|
||||
* Signalizes the PersistenceContext, the begin for large query iteration.
|
||||
*/
|
||||
PersistenceContext forIterate();
|
||||
void beginIterate();
|
||||
|
||||
/**
|
||||
* Return a new Persistence context during iteration of large query result.
|
||||
* Signalizes the PersistenceContext, the end for large query iteration.
|
||||
*/
|
||||
PersistenceContext forIterateReset();
|
||||
|
||||
/**
|
||||
* Return true if the persistence context has grown and hit the 'reset limit'
|
||||
* during large query iteration.
|
||||
*/
|
||||
boolean resetLimit();
|
||||
|
||||
void endIterate();
|
||||
|
||||
/**
|
||||
* Wrapper on a bean to also indicate if a bean has been deleted.
|
||||
* <p>
|
||||
|
||||
@@ -371,6 +371,33 @@ public class DatabaseConfig {
|
||||
*/
|
||||
private String uuidStateFile;
|
||||
|
||||
/**
|
||||
* The node id (=mac address) for Version 1 UUIDs. There are several options:
|
||||
* <ul>
|
||||
* <li><code>null</code> (default) The generator tries to get the hardwarwe MAC
|
||||
* address. If this fails, it will fall back to 'generate' mode.</li>
|
||||
* <li><code>"generate"</code> Hardware detection is skipped. It generates a
|
||||
* random identifier and tries to persist this to the state file. This nodeId
|
||||
* will be reused on next start. If persisting to the state file will fail also,
|
||||
* it will fall back to 'random' mode.<br>
|
||||
* This mode is good, if the MAC address is not reliable, e.g. if you run
|
||||
* multiple ebean instances on the same machine.</li>
|
||||
* <li><code>"random"</code> In this mode, a random node id is generated on each
|
||||
* start. No stateFile is used. it will generate a new nodeId on each
|
||||
* application start.<br>
|
||||
* This mode is good, if you have no write access to save the state file.</li>
|
||||
* <li><code>"xx-xx-xx-xx-xx-xx"</code> When an explicit nodeId is specified,
|
||||
* this one is used.</li>
|
||||
* </ul>
|
||||
* Note: It is possible that multiple servers are sharing the same state file as
|
||||
* long as they are in the <b>same</b> JVM/ClassLoader scope. In this case it is
|
||||
* recommended to use the same uuidNodeId configuration.
|
||||
*
|
||||
* If you have multiple servers in different JVMs, do <b>not</b> share the state
|
||||
* files!
|
||||
*/
|
||||
private String uuidNodeId;
|
||||
|
||||
/**
|
||||
* The clock used for setting the timestamps (e.g. @UpdatedTimestamp) on objects.
|
||||
*/
|
||||
@@ -1547,6 +1574,9 @@ public class DatabaseConfig {
|
||||
|
||||
/**
|
||||
* Set to true if all DB column and table names should use quoted identifiers.
|
||||
* <p>
|
||||
* For Postgres pgjdbc version 42.3.0 should be used with datasource property
|
||||
* <em>quoteReturningIdentifiers</em> set to <em>false</em> (refer #2303).
|
||||
*/
|
||||
public void setAllQuotedIdentifiers(boolean allQuotedIdentifiers) {
|
||||
platformConfig.setAllQuotedIdentifiers(allQuotedIdentifiers);
|
||||
@@ -2016,6 +2046,20 @@ public class DatabaseConfig {
|
||||
public void setUuidStateFile(String uuidStateFile) {
|
||||
this.uuidStateFile = uuidStateFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the V1-UUID-NodeId
|
||||
*/
|
||||
public String getUuidNodeId() {
|
||||
return uuidNodeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the V1-UUID-NodeId.
|
||||
*/
|
||||
public void setUuidNodeId(String uuidNodeId) {
|
||||
this.uuidNodeId = uuidNodeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if LocalTime should be persisted with nanos precision.
|
||||
@@ -2885,6 +2929,7 @@ public class DatabaseConfig {
|
||||
|
||||
uuidVersion = p.getEnum(UuidVersion.class, "uuidVersion", uuidVersion);
|
||||
uuidStateFile = p.get("uuidStateFile", uuidStateFile);
|
||||
uuidNodeId = p.get("uuidNodeId", uuidNodeId);
|
||||
|
||||
localTimeWithNanos = p.getBoolean("localTimeWithNanos", localTimeWithNanos);
|
||||
jodaLocalTimeMode = p.get("jodaLocalTimeMode", jodaLocalTimeMode);
|
||||
|
||||
@@ -66,6 +66,8 @@ public class PlatformConfig {
|
||||
|
||||
private boolean caseSensitiveCollation = true;
|
||||
|
||||
private boolean useMigrationStoredProcedures = false;
|
||||
|
||||
/**
|
||||
* Modify the default mapping of standard types such as default precision for DECIMAL etc.
|
||||
*/
|
||||
@@ -90,6 +92,7 @@ public class PlatformConfig {
|
||||
this.geometrySRID = platformConfig.geometrySRID;
|
||||
this.dbUuid = platformConfig.dbUuid;
|
||||
this.caseSensitiveCollation = platformConfig.caseSensitiveCollation;
|
||||
this.useMigrationStoredProcedures = platformConfig.useMigrationStoredProcedures;
|
||||
this.allQuotedIdentifiers = platformConfig.allQuotedIdentifiers;
|
||||
this.databaseInetAddressVarchar = platformConfig.databaseInetAddressVarchar;
|
||||
this.customDbTypeMappings = platformConfig.customDbTypeMappings;
|
||||
@@ -117,6 +120,9 @@ public class PlatformConfig {
|
||||
|
||||
/**
|
||||
* Set to true if all DB column and table names should use quoted identifiers.
|
||||
* <p>
|
||||
* For Postgres pgjdbc version 42.3.0 should be used with datasource property
|
||||
* <em>quoteReturningIdentifiers</em> set to <em>false</em> (refer #2303).
|
||||
*/
|
||||
public void setAllQuotedIdentifiers(boolean allQuotedIdentifiers) {
|
||||
this.allQuotedIdentifiers = allQuotedIdentifiers;
|
||||
@@ -139,6 +145,20 @@ public class PlatformConfig {
|
||||
this.caseSensitiveCollation = caseSensitiveCollation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if force use of helper stored procedures for migrations.
|
||||
*/
|
||||
public boolean isUseMigrationStoredProcedures() {
|
||||
return useMigrationStoredProcedures;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set true to force use of helper stored procedures for migrations.
|
||||
*/
|
||||
public void setUseMigrationStoredProcedures(boolean useMigrationStoredProcedures) {
|
||||
this.useMigrationStoredProcedures = useMigrationStoredProcedures;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if Postgres FOR UPDATE should use the NO KEY option.
|
||||
*/
|
||||
@@ -314,6 +334,7 @@ public class PlatformConfig {
|
||||
databaseBooleanFalse = p.get("databaseBooleanFalse", databaseBooleanFalse);
|
||||
databaseInetAddressVarchar = p.getBoolean("databaseInetAddressVarchar", databaseInetAddressVarchar);
|
||||
caseSensitiveCollation = p.getBoolean("caseSensitiveCollation", caseSensitiveCollation);
|
||||
useMigrationStoredProcedures = p.getBoolean("useMigrationStoredProcedures", useMigrationStoredProcedures);
|
||||
|
||||
DbUuid dbUuid = p.getEnum(DbUuid.class, "dbuuid", null);
|
||||
if (dbUuid != null) {
|
||||
@@ -375,7 +396,7 @@ public class PlatformConfig {
|
||||
BINARY(false, true, false),
|
||||
|
||||
/**
|
||||
* Store using DB BINARY(16).
|
||||
* Store using DB BINARY(16) with optimized packing.
|
||||
*/
|
||||
BINARY_OPTIMIZED(false, true, true);
|
||||
|
||||
|
||||
@@ -7,13 +7,10 @@ public class BasicSqlAnsiLimiter implements BasicSqlLimiter {
|
||||
|
||||
@Override
|
||||
public String limit(String dbSql, int firstRow, int maxRows) {
|
||||
|
||||
StringBuilder sb = new StringBuilder(50 + dbSql.length());
|
||||
|
||||
sb.append(dbSql);
|
||||
if (firstRow > 0) {
|
||||
sb.append(" ").append("offset");
|
||||
sb.append(" ").append(firstRow).append(" rows");
|
||||
sb.append(" offset ").append(firstRow).append(" rows");
|
||||
}
|
||||
if (maxRows > 0) {
|
||||
sb.append(" fetch next ").append(maxRows).append(" rows only");
|
||||
|
||||
@@ -15,6 +15,7 @@ import javax.persistence.PersistenceException;
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
@@ -53,6 +54,17 @@ public class DatabasePlatform {
|
||||
|
||||
protected boolean supportsSavepointId = true;
|
||||
|
||||
protected boolean useMigrationStoredProcedures = false;
|
||||
|
||||
/**
|
||||
* Can we use native java time API objects in
|
||||
* {@link ResultSet#getObject(int, Class)} and
|
||||
* {@link PreparedStatement#setObject(int, Object)}.
|
||||
*
|
||||
* Not all drivers (DB2 e.g.) will support this.
|
||||
*/
|
||||
protected boolean supportsNativeJavaTime = true;
|
||||
|
||||
/**
|
||||
* The behaviour used when ending a read only transaction at read committed isolation level.
|
||||
*/
|
||||
@@ -202,6 +214,8 @@ public class DatabasePlatform {
|
||||
*/
|
||||
protected PersistBatch persistBatchOnCascade = PersistBatch.ALL;
|
||||
|
||||
protected int maxInBinding;
|
||||
|
||||
/**
|
||||
* The maximum length of table names - used specifically when derived
|
||||
* default table names for intersection tables.
|
||||
@@ -237,6 +251,7 @@ public class DatabasePlatform {
|
||||
public void configure(PlatformConfig config) {
|
||||
this.sequenceBatchSize = config.getDatabaseSequenceBatchSize();
|
||||
this.caseSensitiveCollation = config.isCaseSensitiveCollation();
|
||||
this.useMigrationStoredProcedures = config.isUseMigrationStoredProcedures();
|
||||
configureIdType(config.getIdType());
|
||||
configure(config, config.isAllQuotedIdentifiers());
|
||||
}
|
||||
@@ -343,6 +358,13 @@ public class DatabasePlatform {
|
||||
return supportsSavepointId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if migrations should use stored procedures.
|
||||
*/
|
||||
public boolean isUseMigrationStoredProcedures() {
|
||||
return useMigrationStoredProcedures;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the platform supports LIMIT with sql update.
|
||||
*/
|
||||
@@ -350,6 +372,13 @@ public class DatabasePlatform {
|
||||
return inlineSqlUpdateLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the maximum number of bind values this database platform allows or zero for no limit.
|
||||
*/
|
||||
public int getMaxInBinding() {
|
||||
return maxInBinding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the maximum table name length.
|
||||
* <p>
|
||||
@@ -573,6 +602,10 @@ public class DatabasePlatform {
|
||||
this.supportsResultSetConcurrencyModeUpdatable = supportsResultSetConcurrencyModeUpdatable;
|
||||
}
|
||||
|
||||
public void setUseMigrationStoredProcedures(final boolean useMigrationStoredProcedures) {
|
||||
this.useMigrationStoredProcedures = useMigrationStoredProcedures;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normally not needed - overridden in CockroachPlatform.
|
||||
*/
|
||||
@@ -813,4 +846,8 @@ public class DatabasePlatform {
|
||||
protected void escapeLikeCharacter(char ch, StringBuilder sb) {
|
||||
sb.append(likeEscapeChar).append(ch);
|
||||
}
|
||||
|
||||
public boolean supportsNativeJavaTime() {
|
||||
return supportsNativeJavaTime;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,14 +31,39 @@ public class SqlCodeTranslator implements SqlExceptionTranslator {
|
||||
this.map = Collections.emptyMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PersistenceException translate(String message, SQLException e) {
|
||||
|
||||
private DataErrorType getErrorType(SQLException e) {
|
||||
DataErrorType errorType = map.get(e.getSQLState());
|
||||
if (errorType == null) {
|
||||
// fall back to error code
|
||||
errorType = map.get(String.valueOf(e.getErrorCode()));
|
||||
}
|
||||
return errorType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PersistenceException translate(String message, SQLException e) {
|
||||
|
||||
DataErrorType errorType = getErrorType(e);
|
||||
// for DB2 we must inspect the sql exception chain to determine which
|
||||
// persistence error occurred in a batch execution. We also concatenate
|
||||
// the error messages to improve error analysis.
|
||||
SQLException chain = e.getNextException();
|
||||
if (chain != null) {
|
||||
StringBuilder sb = new StringBuilder(message);
|
||||
int i = 1;
|
||||
while (chain != null && i < 100000) { // prevents from endless loop
|
||||
sb.append("\n\t#").append(i++).append(": ").append(chain.getMessage());
|
||||
if (errorType == null) {
|
||||
errorType = getErrorType(chain);
|
||||
if (errorType != null) {
|
||||
sb.append(" (causing error)"); // mark the line, where we found a matching error code
|
||||
}
|
||||
}
|
||||
chain = chain.getNextException();
|
||||
}
|
||||
message = sb.toString();
|
||||
}
|
||||
|
||||
if (errorType != null) {
|
||||
switch (errorType) {
|
||||
case AcquireLock:
|
||||
|
||||
+5
-6
@@ -15,19 +15,19 @@ import java.sql.Types;
|
||||
/**
|
||||
* DB2 specific platform.
|
||||
*/
|
||||
public class DB2Platform extends DatabasePlatform {
|
||||
public abstract class BaseDB2Platform extends DatabasePlatform {
|
||||
|
||||
public DB2Platform() {
|
||||
public BaseDB2Platform() {
|
||||
super();
|
||||
this.platform = Platform.DB2;
|
||||
this.maxTableNameLength = 18;
|
||||
this.maxConstraintNameLength = 18;
|
||||
this.supportsNativeJavaTime = false;
|
||||
this.truncateTable = "truncate table %s reuse storage ignore delete triggers immediate";
|
||||
this.likeClauseRaw = "like ?";
|
||||
this.sqlLimiter = new Db2SqlLimiter();
|
||||
|
||||
this.dbIdentity.setSupportsGetGeneratedKeys(true);
|
||||
this.dbIdentity.setSupportsSequence(true);
|
||||
|
||||
this.idInExpandedForm = true; // Db2 does not support (a,b) in ((?,?),(?,?))
|
||||
this.exceptionTranslator =
|
||||
new SqlErrorCodes()
|
||||
.addAcquireLock("40001","57033") // key -911/-913
|
||||
@@ -43,7 +43,6 @@ public class DB2Platform extends DatabasePlatform {
|
||||
dbTypeMap.put(DbType.BIGINT, new DbPlatformType("bigint", false));
|
||||
dbTypeMap.put(DbType.REAL, new DbPlatformType("real"));
|
||||
dbTypeMap.put(DbType.DECIMAL, new DbPlatformType("decimal", 16, 3));
|
||||
persistBatchOnCascade = PersistBatch.NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -0,0 +1,39 @@
|
||||
package io.ebean.config.dbplatform.db2;
|
||||
|
||||
import io.ebean.annotation.Platform;
|
||||
import io.ebean.config.dbplatform.DbPlatformType;
|
||||
import io.ebean.config.dbplatform.DbType;
|
||||
import io.ebean.config.dbplatform.SqlErrorCodes;
|
||||
|
||||
import java.sql.Types;
|
||||
|
||||
/**
|
||||
* DB2 specific platform for i Series.
|
||||
*
|
||||
* @author Cédric Sougné
|
||||
*/
|
||||
public class DB2ForIPlatform extends BaseDB2Platform {
|
||||
|
||||
public DB2ForIPlatform() {
|
||||
super();
|
||||
this.platform = Platform.DB2FORI;
|
||||
// Note: IBM i from 7.1 allow up to to 128
|
||||
// TODO: Check if we need to introduce older platform (DB2ForI_6 ? but older
|
||||
// documentation is not anymore published on ibm.com),
|
||||
this.maxTableNameLength = 128;
|
||||
this.maxConstraintNameLength = 128;
|
||||
|
||||
this.dbIdentity.setSupportsIdentity(true);
|
||||
|
||||
this.exceptionTranslator = new SqlErrorCodes().addAcquireLock("57033") // key -913
|
||||
.addDuplicateKey("23505") // -803
|
||||
// .addDataIntegrity("-407","-530","-531","-532","-543","-544","-545","-603","-667")
|
||||
// we need SQLState, not code:
|
||||
// https://www.ibm.com/support/knowledgecenter/en/SSEPEK_10.0.0/codes/src/tpc/db2z_n.html
|
||||
.addDataIntegrity("23502", "23503", "23504", "23507", "23511", "23512", "23513", "42917", "23515")
|
||||
.build();
|
||||
|
||||
booleanDbType = Types.SMALLINT;
|
||||
dbTypeMap.put(DbType.BOOLEAN, new DbPlatformType("smallint default 0"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package io.ebean.config.dbplatform.db2;
|
||||
|
||||
import io.ebean.annotation.PersistBatch;
|
||||
import io.ebean.annotation.Platform;
|
||||
|
||||
/**
|
||||
* DB2 specific platform for older DB2 versions. This platform is here for
|
||||
* compatibility reasons. It uses a length limit of 18 chars for table and
|
||||
* constraint names. Newer DB2 versions will support up to 128. It is strongly
|
||||
* recommended to migrate to db2luw/DB2ForI or db2zos platform.
|
||||
*/
|
||||
public class DB2LegacyPlatform extends BaseDB2Platform {
|
||||
public DB2LegacyPlatform() {
|
||||
super();
|
||||
this.platform = Platform.DB2;
|
||||
// Note: DB2 (at least LUW supports length up to 128)
|
||||
// TOOD: Check if we need to introduce a new platform (DB2_LUW_11 ?)
|
||||
this.maxTableNameLength = 18;
|
||||
this.maxConstraintNameLength = 18;
|
||||
this.persistBatchOnCascade = PersistBatch.NONE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package io.ebean.config.dbplatform.db2;
|
||||
|
||||
import io.ebean.annotation.Platform;
|
||||
|
||||
/**
|
||||
* DB2 platform for Linux/Unix/Windows.
|
||||
* @author Roland Praml, FOCONIS AG
|
||||
*
|
||||
*/
|
||||
public class DB2LuwPlatform extends BaseDB2Platform {
|
||||
public DB2LuwPlatform() {
|
||||
super();
|
||||
this.platform = Platform.DB2LUW;
|
||||
this.maxTableNameLength = 128;
|
||||
this.maxConstraintNameLength = 128;
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@ public class DB2SequenceIdGenerator extends SequenceBatchIdGenerator {
|
||||
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;
|
||||
this.unionBaseSql = ", nextval for " + seqName;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package io.ebean.config.dbplatform.db2;
|
||||
|
||||
import io.ebean.annotation.Platform;
|
||||
|
||||
/**
|
||||
* DB2 platform for z/OS.
|
||||
* Note: This platform is currently not tested!
|
||||
* @author Roland Praml, FOCONIS AG
|
||||
*
|
||||
*/
|
||||
public class DB2ZosPlatform extends BaseDB2Platform {
|
||||
public DB2ZosPlatform() {
|
||||
super();
|
||||
this.platform = Platform.DB2ZOS;
|
||||
this.maxTableNameLength = 128;
|
||||
this.maxConstraintNameLength = 128;
|
||||
}
|
||||
}
|
||||
@@ -15,10 +15,13 @@ public class Db2SqlLimiter implements SqlLimiter {
|
||||
sb.append("distinct ");
|
||||
}
|
||||
sb.append(request.getDbSql());
|
||||
|
||||
int firstRow = request.getFirstRow();
|
||||
if (firstRow > 0) {
|
||||
sb.append(" offset ").append(firstRow).append(" rows");
|
||||
}
|
||||
int maxRows = request.getMaxRows();
|
||||
if (maxRows > 0) {
|
||||
sb.append(" ").append(NEW_LINE).append("FETCH FIRST ").append(maxRows).append(" ROWS ONLY");
|
||||
sb.append(" fetch next ").append(maxRows).append(" rows only");
|
||||
}
|
||||
|
||||
String sql = request.getDbPlatform().completeSql(sb.toString(), request.getOrmQuery());
|
||||
|
||||
@@ -39,6 +39,7 @@ public class H2Platform extends DatabasePlatform {
|
||||
this.dbIdentity.setSupportsIdentity(true);
|
||||
|
||||
dbTypeMap.put(DbType.UUID, new DbPlatformType("uuid", false));
|
||||
dbTypeMap.put(DbType.INTEGER, new DbPlatformType("integer", false));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,13 +18,12 @@ public class H2SequenceIdGenerator extends SequenceBatchIdGenerator {
|
||||
*/
|
||||
public H2SequenceIdGenerator(BackgroundExecutor be, DataSource ds, String seqName, int batchSize) {
|
||||
super(be, ds, seqName, batchSize);
|
||||
this.baseSql = "select " + seqName + ".nextval";
|
||||
this.baseSql = "select nextval('" + 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++) {
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
package io.ebean.config.dbplatform.mariadb;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import io.ebean.BackgroundExecutor;
|
||||
import io.ebean.annotation.Platform;
|
||||
import io.ebean.config.dbplatform.PlatformIdGenerator;
|
||||
import io.ebean.config.dbplatform.mysql.BaseMySqlPlatform;
|
||||
|
||||
/**
|
||||
@@ -11,6 +15,14 @@ public class MariaDbPlatform extends BaseMySqlPlatform {
|
||||
public MariaDbPlatform() {
|
||||
super();
|
||||
this.platform = Platform.MARIADB;
|
||||
this.sequenceBatchMode = false;
|
||||
this.historySupport = new MariaDbHistorySupport();
|
||||
this.dbIdentity.setSupportsSequence(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlatformIdGenerator createSequenceIdGenerator(BackgroundExecutor be, DataSource ds, int stepSize, String seqName) {
|
||||
return new MariaDbSequence(be, ds, seqName, stepSize);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package io.ebean.config.dbplatform.mariadb;
|
||||
|
||||
import io.ebean.BackgroundExecutor;
|
||||
import io.ebean.config.dbplatform.SequenceStepIdGenerator;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
public class MariaDbSequence extends SequenceStepIdGenerator {
|
||||
|
||||
private final String nextSql;
|
||||
|
||||
/**
|
||||
* Construct where batchSize is the sequence step size.
|
||||
*/
|
||||
public MariaDbSequence(BackgroundExecutor be, DataSource ds, String seqName, int stepSize) {
|
||||
super(be, ds, seqName, stepSize);
|
||||
this.nextSql = "select next value for " + seqName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSql(int batchSize) {
|
||||
return nextSql;
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ public class Oracle11Platform extends OraclePlatform {
|
||||
public Oracle11Platform() {
|
||||
super();
|
||||
this.platform = Platform.ORACLE11;
|
||||
this.columnAliasPrefix = "c";
|
||||
this.sqlLimiter = new OracleRownumSqlLimiter();
|
||||
this.basicSqlLimiter = new OracleRownumBasicLimiter();
|
||||
dbIdentity.setIdType(IdType.SEQUENCE);
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package io.ebean.config.dbplatform.oracle;
|
||||
|
||||
/**
|
||||
* Oracle 12 platform using column alias.
|
||||
*/
|
||||
public class Oracle12Platform extends OraclePlatform {
|
||||
|
||||
public Oracle12Platform() {
|
||||
super();
|
||||
//this.platform = Platform.ORACLE12;
|
||||
this.columnAliasPrefix = "c";
|
||||
}
|
||||
}
|
||||
@@ -22,8 +22,8 @@ public class OraclePlatform extends DatabasePlatform {
|
||||
public OraclePlatform() {
|
||||
super();
|
||||
this.platform = Platform.ORACLE;
|
||||
this.columnAliasPrefix = "c";
|
||||
this.supportsDeleteTableAlias = true;
|
||||
this.maxInBinding = 1000;
|
||||
this.maxTableNameLength = 30;
|
||||
this.maxConstraintNameLength = 30;
|
||||
this.dbEncrypt = new OracleDbEncrypt();
|
||||
@@ -35,11 +35,9 @@ public class OraclePlatform extends DatabasePlatform {
|
||||
dbIdentity.setSupportsSequence(true);
|
||||
dbIdentity.setSupportsIdentity(true);
|
||||
dbIdentity.setSupportsGetGeneratedKeys(true);
|
||||
|
||||
this.dbDefaultValue.setFalse("0");
|
||||
this.dbDefaultValue.setTrue("1");
|
||||
this.dbDefaultValue.setNow("current_timestamp");
|
||||
|
||||
this.treatEmptyStringsAsNull = true;
|
||||
this.likeClauseRaw = "like ?";
|
||||
|
||||
@@ -56,7 +54,6 @@ public class OraclePlatform extends DatabasePlatform {
|
||||
|
||||
booleanDbType = Types.INTEGER;
|
||||
dbTypeMap.put(DbType.BOOLEAN, new DbPlatformType("number(1)"));
|
||||
|
||||
dbTypeMap.put(DbType.INTEGER, new DbPlatformType("number", 10));
|
||||
dbTypeMap.put(DbType.BIGINT, new DbPlatformType("number", 19));
|
||||
dbTypeMap.put(DbType.REAL, new DbPlatformType("number", 19, 4));
|
||||
@@ -65,12 +62,10 @@ public class OraclePlatform extends DatabasePlatform {
|
||||
dbTypeMap.put(DbType.TINYINT, new DbPlatformType("number", 3));
|
||||
dbTypeMap.put(DbType.DECIMAL, new DbPlatformType("number", 16, 3));
|
||||
dbTypeMap.put(DbType.VARCHAR, new DbPlatformType("varchar2", 255));
|
||||
|
||||
dbTypeMap.put(DbType.LONGVARBINARY, new DbPlatformType("blob"));
|
||||
dbTypeMap.put(DbType.LONGVARCHAR, new DbPlatformType("clob"));
|
||||
dbTypeMap.put(DbType.VARBINARY, new DbPlatformType("raw", 255));
|
||||
dbTypeMap.put(DbType.BINARY, new DbPlatformType("raw", 255));
|
||||
|
||||
dbTypeMap.put(DbType.TIME, new DbPlatformType("timestamp"));
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ public class SQLitePlatform extends DatabasePlatform {
|
||||
this.dbDefaultValue.setFalse("0");
|
||||
this.dbDefaultValue.setTrue("1");
|
||||
this.dbDefaultValue.setNow("CURRENT_TIMESTAMP");
|
||||
this.supportsResultSetConcurrencyModeUpdatable = false;
|
||||
|
||||
dbTypeMap.put(DbType.BIT, new DbPlatformType("int"));
|
||||
dbTypeMap.put(DbType.BOOLEAN, new DbPlatformType("int"));
|
||||
|
||||
+6
@@ -27,6 +27,7 @@ abstract class SqlServerBasePlatform extends DatabasePlatform {
|
||||
// SQL Server unless we are using sequences
|
||||
this.dbEncrypt = new SqlServerDbEncrypt();
|
||||
this.persistBatchOnCascade = PersistBatch.NONE;
|
||||
this.maxInBinding = 2000;
|
||||
this.idInExpandedForm = true;
|
||||
this.selectCountWithAlias = true;
|
||||
this.selectCountWithColumnAlias = true;
|
||||
@@ -119,4 +120,9 @@ abstract class SqlServerBasePlatform extends DatabasePlatform {
|
||||
// for update are hints on from clause of base table
|
||||
return sql;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUseMigrationStoredProcedures() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package io.ebean.config.dbplatform.yugabyte;
|
||||
|
||||
import io.ebean.annotation.Platform;
|
||||
import io.ebean.config.dbplatform.postgres.PostgresPlatform;
|
||||
|
||||
public class YugabytePlaform extends PostgresPlatform {
|
||||
|
||||
public YugabytePlaform() {
|
||||
super();
|
||||
this.platform = Platform.YUGABYTE;
|
||||
}
|
||||
}
|
||||
@@ -43,6 +43,12 @@ public interface BeanPersistRequest<T> {
|
||||
return transaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this request is due to cascading persist.
|
||||
* False implies this is a "top level" request.
|
||||
*/
|
||||
boolean isCascade();
|
||||
|
||||
/**
|
||||
* For an update or delete of a partially populated bean this is the set of
|
||||
* loaded properties and otherwise returns null.
|
||||
|
||||
@@ -8,7 +8,6 @@ import io.ebean.event.BeanPersistController;
|
||||
import io.ebean.event.BeanPersistListener;
|
||||
import io.ebean.event.BeanQueryAdapter;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
@@ -21,7 +20,6 @@ public interface BeanType<T> {
|
||||
/**
|
||||
* Return the short name of the bean type.
|
||||
*/
|
||||
@Nonnull
|
||||
String name();
|
||||
|
||||
/**
|
||||
@@ -35,7 +33,6 @@ public interface BeanType<T> {
|
||||
/**
|
||||
* Return the full name of the bean type.
|
||||
*/
|
||||
@Nonnull
|
||||
String fullName();
|
||||
|
||||
/**
|
||||
@@ -49,7 +46,6 @@ public interface BeanType<T> {
|
||||
/**
|
||||
* Return the class type this BeanDescriptor describes.
|
||||
*/
|
||||
@Nonnull
|
||||
Class<T> type();
|
||||
|
||||
/**
|
||||
@@ -76,7 +72,6 @@ public interface BeanType<T> {
|
||||
/**
|
||||
* Return all the properties for this bean type.
|
||||
*/
|
||||
@Nonnull
|
||||
Collection<? extends Property> allProperties();
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
package io.ebean.plugin;
|
||||
|
||||
import io.ebean.bean.EntityBean;
|
||||
|
||||
/**
|
||||
* Errorhandler to handle load errors and may be recover correct value.
|
||||
*
|
||||
* @author Roland Praml, FOCONIS AG
|
||||
*
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface LoadErrorHandler {
|
||||
void handleLoadError(EntityBean bean, Property prop, String fullName, Exception e);
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
package io.ebean.plugin;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* Property of a entity bean that can be read.
|
||||
*/
|
||||
@@ -10,7 +8,6 @@ public interface Property {
|
||||
/**
|
||||
* Return the name of the property.
|
||||
*/
|
||||
@Nonnull
|
||||
String name();
|
||||
|
||||
/**
|
||||
@@ -24,7 +21,6 @@ public interface Property {
|
||||
/**
|
||||
* Return the type of the property.
|
||||
*/
|
||||
@Nonnull
|
||||
Class<?> type();
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,7 +18,7 @@ import java.util.Locale;
|
||||
* try {
|
||||
* File f = new File("src/test/resources/test1.csv");
|
||||
*
|
||||
* FileReader reader = new FileReader(f);
|
||||
* FileReader reader = new FileReader(f, encoding);
|
||||
*
|
||||
* CsvReader<Customer> csvReader = DB.createCsvReader(Customer.class);
|
||||
*
|
||||
|
||||
@@ -20,7 +20,7 @@ public interface JsonBeanReader<T> {
|
||||
/**
|
||||
* Create a new reader taking the context from the existing one but using a new JsonParser.
|
||||
*/
|
||||
JsonBeanReader<T> forJson(JsonParser moreJson, boolean resetContext);
|
||||
JsonBeanReader<T> forJson(JsonParser moreJson);
|
||||
|
||||
/**
|
||||
* Add a bean explicitly to the persistence context.
|
||||
|
||||
@@ -2,6 +2,7 @@ package io.ebean.util;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
@@ -57,10 +58,8 @@ public class AnnotationUtil {
|
||||
|
||||
private static <A extends Annotation> void typeGetAllCollect(Class<?> clazz, Class<A> annotationType, Set<A> result) {
|
||||
while (clazz != null && clazz != Object.class) {
|
||||
final A val = clazz.getAnnotation(annotationType);
|
||||
if (val != null) {
|
||||
result.add(val);
|
||||
}
|
||||
final A[] annotations = clazz.getAnnotationsByType(annotationType);
|
||||
Collections.addAll(result, annotations);
|
||||
clazz = clazz.getSuperclass();
|
||||
}
|
||||
}
|
||||
@@ -72,6 +71,20 @@ public class AnnotationUtil {
|
||||
return typeGet(clazz, annotation) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an element is annotated with an annotation of given type searching meta-annotations.
|
||||
*/
|
||||
public static boolean metaHas(AnnotatedElement element, Class<?> annotationType) {
|
||||
return !metaFindAll(element, annotationType).isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all the annotations of a given type searching meta-annotations.
|
||||
*/
|
||||
public static Set<Annotation> metaFindAll(AnnotatedElement element, Class<?> annotationType) {
|
||||
return metaFindAllFor(element, Collections.singleton(annotationType));
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all the annotations for the filter searching meta-annotations.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package io.ebean.util;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* Utilities for IO. It uses UTF-8 as encoding when reading/writing and uses
|
||||
* buffered IO for better performance.
|
||||
*/
|
||||
public class IOUtils {
|
||||
|
||||
/**
|
||||
* Read from stream as UTF-8.
|
||||
*/
|
||||
public static BufferedReader newReader(InputStream is) {
|
||||
return new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
/**
|
||||
* Read from file as UTF-8.
|
||||
*/
|
||||
public static BufferedReader newReader(File file) throws FileNotFoundException {
|
||||
return newReader(new FileInputStream(file));
|
||||
}
|
||||
|
||||
/**
|
||||
* Write to stream as UTF-8
|
||||
*/
|
||||
public static BufferedWriter newWriter(OutputStream os) {
|
||||
return new BufferedWriter(new OutputStreamWriter(os, StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
/**
|
||||
* Write to file as UTF-8
|
||||
*/
|
||||
public static BufferedWriter newWriter(File file) throws FileNotFoundException {
|
||||
return newWriter(new FileOutputStream(file));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package io.ebean;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class EbeanVersionTest {
|
||||
|
||||
@Test
|
||||
void checkMinAgentVersion_ok() {
|
||||
assertFalse(EbeanVersion.checkMinAgentVersion("12.12.0"));
|
||||
assertFalse(EbeanVersion.checkMinAgentVersion("12.12.99"));
|
||||
assertFalse(EbeanVersion.checkMinAgentVersion("13.1.0"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void checkMinAgentVersion_agentTooOld() {
|
||||
assertTrue(EbeanVersion.checkMinAgentVersion("11.13.0"));
|
||||
assertTrue(EbeanVersion.checkMinAgentVersion("12.11.0"));
|
||||
assertTrue(EbeanVersion.checkMinAgentVersion("12.11.99"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void checkMinAgentVersion_unexpectedAgentVersion() {
|
||||
assertTrue(EbeanVersion.checkMinAgentVersion("13.13"));
|
||||
assertTrue(EbeanVersion.checkMinAgentVersion("13"));
|
||||
assertTrue(EbeanVersion.checkMinAgentVersion(""));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package io.ebean.util;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import io.ebean.annotation.Formula;
|
||||
|
||||
public class TestAnnotationUtil {
|
||||
|
||||
@Formula(select = "x")
|
||||
@Formula(select = "y")
|
||||
private static class TestObject {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRepeatableAnnotation() {
|
||||
|
||||
Set<Formula> list = AnnotationUtil.typeGetAll(TestObject.class, Formula.class);
|
||||
assertThat(list).hasSize(2);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>12.12.0</version>
|
||||
<version>12.15.0</version>
|
||||
</parent>
|
||||
<!-- <parent>-->
|
||||
<!-- <groupId>org.avaje</groupId>-->
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
<scm>
|
||||
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
|
||||
<tag>ebean-parent-12.12.0</tag>
|
||||
<tag>ebean-parent-12.15.0</tag>
|
||||
</scm>
|
||||
|
||||
<name>ebean autotune</name>
|
||||
@@ -26,7 +26,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>12.12.0</version>
|
||||
<version>12.15.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jaxb</groupId>
|
||||
<artifactId>jaxb-runtime</artifactId>
|
||||
<version>2.3.2</version>
|
||||
<version>2.3.6</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<tiles>
|
||||
<tile>io.ebean.tile:enhancement:12.11.3</tile>
|
||||
<tile>io.ebean.tile:enhancement:12.15.0</tile>
|
||||
<tile>io.avaje.tile:moditech-module:1.0</tile>
|
||||
</tiles>
|
||||
</configuration>
|
||||
|
||||
+15
-15
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>12.12.0</version>
|
||||
<version>12.15.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean bom</name>
|
||||
@@ -71,88 +71,88 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean</artifactId>
|
||||
<version>12.12.0</version>
|
||||
<version>12.15.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>12.12.0</version>
|
||||
<version>12.15.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>12.12.0</version>
|
||||
<version>12.15.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core-type</artifactId>
|
||||
<version>12.12.0</version>
|
||||
<version>12.15.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-ddl-generator</artifactId>
|
||||
<version>12.12.0</version>
|
||||
<version>12.15.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-externalmapping-api</artifactId>
|
||||
<version>12.12.0</version>
|
||||
<version>12.15.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-externalmapping-xml</artifactId>
|
||||
<version>12.12.0</version>
|
||||
<version>12.15.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-autotune</artifactId>
|
||||
<version>12.12.0</version>
|
||||
<version>12.15.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>12.12.0</version>
|
||||
<version>12.15.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>querybean-generator</artifactId>
|
||||
<version>12.12.0</version>
|
||||
<version>12.15.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>kotlin-querybean-generator</artifactId>
|
||||
<version>12.12.0</version>
|
||||
<version>12.15.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-test</artifactId>
|
||||
<version>12.12.0</version>
|
||||
<version>12.15.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-postgis</artifactId>
|
||||
<version>12.12.0</version>
|
||||
<version>12.15.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-redis</artifactId>
|
||||
<version>12.12.0</version>
|
||||
<version>12.15.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>12.12.0</version>
|
||||
<version>12.15.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>ebean-core-type</artifactId>
|
||||
@@ -16,7 +16,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>12.12.0</version>
|
||||
<version>12.15.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@@ -47,6 +47,8 @@ public interface DataReader {
|
||||
|
||||
Object getObject() throws SQLException;
|
||||
|
||||
<T> T getObject(Class<T> cls) throws SQLException;
|
||||
|
||||
InputStream getBinaryStream() throws SQLException;
|
||||
|
||||
/**
|
||||
|
||||
+7
-7
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>12.12.0</version>
|
||||
<version>12.15.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>ebean-core</artifactId>
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
<scm>
|
||||
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
|
||||
<tag>ebean-parent-12.12.0</tag>
|
||||
<tag>ebean-parent-12.15.0</tag>
|
||||
</scm>
|
||||
|
||||
<dependencies>
|
||||
@@ -41,19 +41,19 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>12.12.0</version>
|
||||
<version>12.15.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core-type</artifactId>
|
||||
<version>12.12.0</version>
|
||||
<version>12.15.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-externalmapping-api</artifactId>
|
||||
<version>12.12.0</version>
|
||||
<version>12.15.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -78,7 +78,7 @@
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>1.4.199</version>
|
||||
<version>${h2database.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -136,7 +136,7 @@
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>42.2.20</version>
|
||||
<version>42.3.2</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -167,6 +167,7 @@ public final class BindParams implements Serializable {
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public void setParameter(int position, Object value) {
|
||||
assert value != null : "use setNullParameter";
|
||||
Param p = getParam(position);
|
||||
if (value instanceof Collection) {
|
||||
// use of postgres ANY with positioned parameter
|
||||
@@ -218,11 +219,21 @@ public final class BindParams implements Serializable {
|
||||
* Set a named In parameter that is not null.
|
||||
*/
|
||||
public Param setParameter(String name, Object value) {
|
||||
assert value != null : "use setNullParameter";
|
||||
Param p = getParam(name);
|
||||
p.setInValue(value);
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a named In parameter that is multi-valued.
|
||||
*/
|
||||
public Param setArrayParameter(String name, Collection<?> value) {
|
||||
Param p = getParam(name);
|
||||
p.setInValue(new MultiValueWrapper(value));
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an encryption key as a bind value.
|
||||
* <p>
|
||||
@@ -285,12 +296,17 @@ public final class BindParams implements Serializable {
|
||||
*/
|
||||
public boolean isSameBindHash() {
|
||||
if (bindHash == null) {
|
||||
bindHash = calcQueryPlanHash();
|
||||
return false;
|
||||
}
|
||||
String oldPlan = bindHash;
|
||||
String newHash = calcQueryPlanHash();
|
||||
return bindHash.equals(newHash);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the hash.
|
||||
*/
|
||||
public void updateHash() {
|
||||
bindHash = calcQueryPlanHash();
|
||||
return bindHash.equals(oldPlan);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -36,14 +36,6 @@ public interface LoadContext {
|
||||
*/
|
||||
PersistenceContext getPersistenceContext();
|
||||
|
||||
/**
|
||||
* Set the persistence context used by this query and future lazy loading.
|
||||
* <p>
|
||||
* Used by query iterator when processing large result sets.
|
||||
* </p>
|
||||
*/
|
||||
void resetPersistenceContext(PersistenceContext persistenceContext);
|
||||
|
||||
/**
|
||||
* Register a Bean for lazy loading.
|
||||
*/
|
||||
|
||||
@@ -16,6 +16,7 @@ import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import io.ebeaninternal.server.query.CQuery;
|
||||
import io.ebeaninternal.server.transaction.RemoteTransactionEvent;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
@@ -141,7 +142,7 @@ public interface SpiEbeanServer extends SpiServer, ExtendedServer, EbeanServer,
|
||||
/**
|
||||
* Compile a query.
|
||||
*/
|
||||
<T> CQuery<T> compileQuery(Type type, Query<T> query, Transaction t);
|
||||
<T> CQuery<T> compileQuery(Type type, Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Execute the findId's query but without copying the query.
|
||||
@@ -150,12 +151,12 @@ public interface SpiEbeanServer extends SpiServer, ExtendedServer, EbeanServer,
|
||||
* the query has finished (if executing in a background thread).
|
||||
* </p>
|
||||
*/
|
||||
<A, T> List<A> findIdsWithCopy(Query<T> query, Transaction t);
|
||||
<A, T> List<A> findIdsWithCopy(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Execute the findCount query but without copying the query.
|
||||
*/
|
||||
<T> int findCountWithCopy(Query<T> query, Transaction t);
|
||||
<T> int findCountWithCopy(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Load a batch of Associated One Beans.
|
||||
@@ -257,6 +258,7 @@ public interface SpiEbeanServer extends SpiServer, ExtendedServer, EbeanServer,
|
||||
/**
|
||||
* DTO findOne query.
|
||||
*/
|
||||
@Nullable
|
||||
<T> T findDtoOne(SpiDtoQuery<T> query);
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,6 +24,7 @@ import io.ebeaninternal.server.querydefn.OrmUpdateProperties;
|
||||
import io.ebeaninternal.server.rawsql.SpiRawSql;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -399,6 +400,11 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
|
||||
|
||||
List<String> getSoftDeletePredicates();
|
||||
|
||||
/**
|
||||
* Bind the named multi-value array parameter which we would use with Postgres ANY.
|
||||
*/
|
||||
void setArrayParameter(String name, Collection<?> values);
|
||||
|
||||
/**
|
||||
* Return a copy of the query.
|
||||
*/
|
||||
|
||||
@@ -14,7 +14,7 @@ public interface SpiJsonReader {
|
||||
|
||||
PersistenceContext getPersistenceContext();
|
||||
|
||||
SpiJsonReader forJson(JsonParser moreJson, boolean resetContext);
|
||||
SpiJsonReader forJson(JsonParser moreJson);
|
||||
|
||||
<T> void persistenceContextPut(Object beanId, T currentBean);
|
||||
|
||||
|
||||
@@ -3,20 +3,20 @@ package io.ebeaninternal.server.core;
|
||||
import io.ebean.ScriptRunner;
|
||||
import io.ebean.ddlrunner.DdlRunner;
|
||||
import io.ebean.ddlrunner.ScriptTransform;
|
||||
import io.ebean.util.IOUtils;
|
||||
import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.util.UrlHelper;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.LineNumberReader;
|
||||
import java.io.Reader;
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Path;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
final class DScriptRunner implements ScriptRunner {
|
||||
|
||||
private static final String NEWLINE = "\n";
|
||||
@@ -30,8 +30,8 @@ final class DScriptRunner implements ScriptRunner {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(String path) {
|
||||
run(path, null);
|
||||
public void run(String resourcePath) {
|
||||
run(resourcePath, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -49,26 +49,42 @@ final class DScriptRunner implements ScriptRunner {
|
||||
run(resource, null, placeholderMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(Path file) {
|
||||
run(file, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(Path file, Map<String, String> placeholderMap) {
|
||||
requireNonNull(file);
|
||||
String scriptName = file.toFile().getName();
|
||||
String content = fileContent(file);
|
||||
runScript(content, scriptName, placeholderMap, false);
|
||||
}
|
||||
|
||||
private void run(URL resource, String scriptName, Map<String, String> placeholderMap) {
|
||||
if (resource == null) {
|
||||
throw new IllegalArgumentException("resource is null?");
|
||||
}
|
||||
requireNonNull(resource);
|
||||
if (scriptName == null) {
|
||||
scriptName = resource.getFile();
|
||||
}
|
||||
|
||||
String content = content(resource);
|
||||
runScript(content, scriptName, placeholderMap, false);
|
||||
}
|
||||
|
||||
private String content(URL resource) {
|
||||
if (resource == null) {
|
||||
throw new IllegalArgumentException("resource is null?");
|
||||
private String fileContent(Path file) {
|
||||
try (InputStream inputStream = new FileInputStream(file.toFile());
|
||||
Reader reader = IOUtils.newReader(inputStream)) {
|
||||
return readContent(reader);
|
||||
} catch (IOException e) {
|
||||
throw new PersistenceException("Failed to read script content", e);
|
||||
}
|
||||
}
|
||||
|
||||
try (InputStream inputStream = UrlHelper.openNoCache(resource)) {
|
||||
return readContent(new InputStreamReader(inputStream));
|
||||
|
||||
private String content(URL resource) {
|
||||
requireNonNull(resource);
|
||||
try (InputStream inputStream = UrlHelper.openNoCache(resource);
|
||||
Reader reader = IOUtils.newReader(inputStream)) {
|
||||
return readContent(reader);
|
||||
} catch (IOException e) {
|
||||
throw new PersistenceException("Failed to read script content", e);
|
||||
}
|
||||
@@ -84,10 +100,9 @@ final class DScriptRunner implements ScriptRunner {
|
||||
*/
|
||||
private void runScript(String content, String scriptName, Map<String, String> placeholderMap, boolean useAutoCommit) {
|
||||
try {
|
||||
if (placeholderMap != null) {
|
||||
if (placeholderMap != null && !placeholderMap.isEmpty()) {
|
||||
content = ScriptTransform.build(null, placeholderMap).transform(content);
|
||||
}
|
||||
|
||||
try (Connection connection = obtainConnection()) {
|
||||
DdlRunner runner = new DdlRunner(useAutoCommit, scriptName, platformName);
|
||||
runner.runAll(content, connection);
|
||||
@@ -109,7 +124,6 @@ final class DScriptRunner implements ScriptRunner {
|
||||
}
|
||||
|
||||
private String readContent(Reader reader) throws IOException {
|
||||
|
||||
StringBuilder buf = new StringBuilder();
|
||||
try (LineNumberReader lineReader = new LineNumberReader(reader)) {
|
||||
String line;
|
||||
|
||||
+39
-12
@@ -4,7 +4,10 @@ import io.ebean.config.DatabaseConfig;
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebean.config.dbplatform.clickhouse.ClickHousePlatform;
|
||||
import io.ebean.config.dbplatform.cockroach.CockroachPlatform;
|
||||
import io.ebean.config.dbplatform.db2.DB2Platform;
|
||||
import io.ebean.config.dbplatform.db2.DB2ForIPlatform;
|
||||
import io.ebean.config.dbplatform.db2.DB2LegacyPlatform;
|
||||
import io.ebean.config.dbplatform.db2.DB2LuwPlatform;
|
||||
import io.ebean.config.dbplatform.db2.DB2ZosPlatform;
|
||||
import io.ebean.config.dbplatform.h2.H2Platform;
|
||||
import io.ebean.config.dbplatform.hana.HanaPlatform;
|
||||
import io.ebean.config.dbplatform.hsqldb.HsqldbPlatform;
|
||||
@@ -13,6 +16,7 @@ import io.ebean.config.dbplatform.mysql.MySql55Platform;
|
||||
import io.ebean.config.dbplatform.mysql.MySqlPlatform;
|
||||
import io.ebean.config.dbplatform.nuodb.NuoDbPlatform;
|
||||
import io.ebean.config.dbplatform.oracle.Oracle11Platform;
|
||||
import io.ebean.config.dbplatform.oracle.Oracle12Platform;
|
||||
import io.ebean.config.dbplatform.oracle.OraclePlatform;
|
||||
import io.ebean.config.dbplatform.postgres.Postgres9Platform;
|
||||
import io.ebean.config.dbplatform.postgres.PostgresPlatform;
|
||||
@@ -20,16 +24,14 @@ import io.ebean.config.dbplatform.sqlanywhere.SqlAnywherePlatform;
|
||||
import io.ebean.config.dbplatform.sqlite.SQLitePlatform;
|
||||
import io.ebean.config.dbplatform.sqlserver.SqlServer16Platform;
|
||||
import io.ebean.config.dbplatform.sqlserver.SqlServer17Platform;
|
||||
import io.ebean.config.dbplatform.yugabyte.YugabytePlaform;
|
||||
import io.ebeaninternal.api.CoreLog;
|
||||
import io.ebeaninternal.api.DbOffline;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.*;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Create a DatabasePlatform from the configuration.
|
||||
@@ -87,6 +89,9 @@ public class DatabasePlatformFactory {
|
||||
if (dbName.equals("oracle11") || dbName.equals("oracle10") || dbName.equals("oracle9")) {
|
||||
return new Oracle11Platform();
|
||||
}
|
||||
if (dbName.equals("oracle12")) {
|
||||
return new Oracle12Platform();
|
||||
}
|
||||
if (dbName.equals("oracle")) {
|
||||
return new OraclePlatform();
|
||||
}
|
||||
@@ -103,7 +108,19 @@ public class DatabasePlatformFactory {
|
||||
return new SqlAnywherePlatform();
|
||||
}
|
||||
if (dbName.equals("db2")) {
|
||||
return new DB2Platform();
|
||||
throw new IllegalArgumentException("Please choose the more specific db2luw/db2zos/db2fori platform. Refer to issue #2514 for details");
|
||||
}
|
||||
if (dbName.equals("db2legacy")) {
|
||||
return new DB2LegacyPlatform();
|
||||
}
|
||||
if (dbName.equals("db2zos")) {
|
||||
return new DB2ZosPlatform();
|
||||
}
|
||||
if (dbName.equals("db2fori")) {
|
||||
return new DB2ForIPlatform();
|
||||
}
|
||||
if (dbName.equals("db2luw")) {
|
||||
return new DB2LuwPlatform();
|
||||
}
|
||||
if (dbName.equals("clickhouse")) {
|
||||
return new ClickHousePlatform();
|
||||
@@ -149,7 +166,8 @@ public class DatabasePlatformFactory {
|
||||
} else if (dbProductName.contains("hsql database engine")) {
|
||||
return new HsqldbPlatform();
|
||||
} else if (dbProductName.contains("postgres")) {
|
||||
return readPostgres(connection, majorVersion);
|
||||
String productVersion = metaData.getDatabaseProductVersion().toLowerCase(Locale.ENGLISH);
|
||||
return readPostgres(connection, majorVersion, productVersion);
|
||||
} else if (dbProductName.contains("mariadb")) {
|
||||
return new MariaDbPlatform();
|
||||
} else if (dbProductName.contains("mysql")) {
|
||||
@@ -159,7 +177,7 @@ public class DatabasePlatformFactory {
|
||||
} else if (dbProductName.contains("sqlite")) {
|
||||
return new SQLitePlatform();
|
||||
} else if (dbProductName.contains("db2")) {
|
||||
return new DB2Platform();
|
||||
throw new IllegalArgumentException("For DB2 please explicitly choose either db2legacy/db2luw/db2zos/db2fori platform. Refer to issue #2514 for details");
|
||||
} else if (dbProductName.contains("sql anywhere")) {
|
||||
return new SqlAnywherePlatform();
|
||||
} else if (dbProductName.contains("hdb")) {
|
||||
@@ -173,7 +191,13 @@ public class DatabasePlatformFactory {
|
||||
}
|
||||
|
||||
private DatabasePlatform oracleVersion(int majorVersion) {
|
||||
return majorVersion < 12 ? new Oracle11Platform() : new OraclePlatform();
|
||||
if (majorVersion < 12) {
|
||||
return new Oracle11Platform();
|
||||
}
|
||||
if (majorVersion < 13) {
|
||||
return new Oracle12Platform();
|
||||
}
|
||||
return new OraclePlatform();
|
||||
}
|
||||
|
||||
private DatabasePlatform mysqlVersion(int majorVersion, int minorVersion) {
|
||||
@@ -186,11 +210,14 @@ public class DatabasePlatformFactory {
|
||||
/**
|
||||
* Use a select version() query as it could be Postgres or CockroachDB.
|
||||
*/
|
||||
private static DatabasePlatform readPostgres(Connection connection, int majorVersion) {
|
||||
private static DatabasePlatform readPostgres(Connection connection, int majorVersion, String productVersion) {
|
||||
if (productVersion.contains("-yb-")) {
|
||||
return new YugabytePlaform();
|
||||
}
|
||||
try (PreparedStatement statement = connection.prepareStatement("select version() as \"version\"")) {
|
||||
try (ResultSet resultSet = statement.executeQuery()) {
|
||||
if (resultSet.next()) {
|
||||
String productVersion = resultSet.getString("version").toLowerCase();
|
||||
productVersion = resultSet.getString("version").toLowerCase();
|
||||
if (productVersion.contains("cockroach")) {
|
||||
return new CockroachPlatform();
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -331,6 +331,12 @@ public final class DefaultSqlUpdate implements Serializable, SpiSqlUpdate {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqlUpdate setArrayParameter(String name, Collection<?> values) {
|
||||
bindParams.setArrayParameter(name, values);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqlUpdate setNull(String name, int jdbcType) {
|
||||
bindParams.setNullParameter(name, jdbcType);
|
||||
|
||||
@@ -99,7 +99,6 @@ final class InitDataSource {
|
||||
if (config.getDatabasePlatformName() == null) {
|
||||
throw new PersistenceException("You MUST specify a DatabasePlatformName on DatabaseConfig when offline");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
attachAlert(dsConfig);
|
||||
|
||||
@@ -280,7 +280,7 @@ public final class InternalConfiguration {
|
||||
|
||||
private MultiValueBind createMultiValueBind(Platform platform) {
|
||||
// only Postgres at this stage
|
||||
if (platform.base() == Platform.POSTGRES) {
|
||||
if (platform.base() == Platform.POSTGRES || platform.base() == Platform.YUGABYTE) {
|
||||
return new PostgresMultiValueBind();
|
||||
}
|
||||
return new MultiValueBind();
|
||||
|
||||
@@ -2,7 +2,6 @@ package io.ebeaninternal.server.core;
|
||||
|
||||
import io.ebean.*;
|
||||
import io.ebean.bean.BeanCollection;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebean.bean.PersistenceContext;
|
||||
import io.ebean.cache.QueryCacheEntry;
|
||||
import io.ebean.common.BeanList;
|
||||
@@ -37,7 +36,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
|
||||
private final Boolean readOnly;
|
||||
private LoadContext loadContext;
|
||||
private PersistenceContext persistenceContext;
|
||||
private JsonReadOptions jsonRead;
|
||||
private HashQuery cacheKey;
|
||||
private CQueryPlanKey queryPlanKey;
|
||||
private SpiQuerySecondary secondaryQueries;
|
||||
@@ -201,14 +199,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
|
||||
return persistenceContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the bean to the persistence context.
|
||||
*/
|
||||
public void persistenceContextAdd(EntityBean bean) {
|
||||
Object id = beanDescriptor.getId(bean);
|
||||
beanDescriptor.contextPut(persistenceContext, id, bean);
|
||||
}
|
||||
|
||||
/**
|
||||
* This will create a local (readOnly) transaction if no current transaction
|
||||
* exists.
|
||||
@@ -233,6 +223,9 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
|
||||
createdTransaction = true;
|
||||
}
|
||||
persistenceContext = persistenceContext(query, transaction);
|
||||
if (Type.ITERATE == query.getType()) {
|
||||
persistenceContext.beginIterate();
|
||||
}
|
||||
loadContext = new DLoadContext(this, secondaryQueries);
|
||||
}
|
||||
|
||||
@@ -241,6 +234,9 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
|
||||
*/
|
||||
@Override
|
||||
public void rollbackTransIfRequired() {
|
||||
if (Type.ITERATE == query.getType()) {
|
||||
persistenceContext.endIterate();
|
||||
}
|
||||
if (createdTransaction) {
|
||||
try {
|
||||
transaction.end();
|
||||
@@ -262,7 +258,7 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
|
||||
if (query.getPersistenceContext() == null) {
|
||||
query.setPersistenceContext(persistenceContext);
|
||||
}
|
||||
jsonRead = new JsonReadOptions();
|
||||
JsonReadOptions jsonRead = new JsonReadOptions();
|
||||
jsonRead.setPersistenceContext(persistenceContext);
|
||||
if (!query.isDisableLazyLoading()) {
|
||||
loadContext = new DLoadContext(this, secondaryQueries);
|
||||
@@ -271,20 +267,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
|
||||
return jsonRead;
|
||||
}
|
||||
|
||||
/**
|
||||
* For iterate queries reset the persistenceContext and loadContext.
|
||||
*/
|
||||
public void flushPersistenceContextOnIterate() {
|
||||
if (persistenceContext.resetLimit()) {
|
||||
persistenceContext = persistenceContext.forIterateReset();
|
||||
loadContext.resetPersistenceContext(persistenceContext);
|
||||
if (jsonRead != null) {
|
||||
jsonRead.setPersistenceContext(persistenceContext);
|
||||
jsonRead.setLoadContext(loadContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the TransactionContext either explicitly set on the query or
|
||||
* transaction scoped.
|
||||
@@ -300,11 +282,7 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
|
||||
if (scope == PersistenceContextScope.QUERY || t == null) {
|
||||
return new DefaultPersistenceContext();
|
||||
}
|
||||
if (Type.ITERATE == query.getType()) {
|
||||
return t.getPersistenceContext().forIterate();
|
||||
} else {
|
||||
return t.getPersistenceContext();
|
||||
}
|
||||
return t.getPersistenceContext();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -314,6 +292,9 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
|
||||
*/
|
||||
@Override
|
||||
public void endTransIfRequired() {
|
||||
if (Type.ITERATE == query.getType()) {
|
||||
persistenceContext.endIterate();
|
||||
}
|
||||
if (createdTransaction && transaction.isActive()) {
|
||||
transaction.commit();
|
||||
if (query.getType().isUpdate()) {
|
||||
@@ -552,7 +533,7 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
|
||||
|
||||
@SuppressWarnings({"rawtypes"})
|
||||
private void mergeCacheHitsToMap(BeanCollection<T> result) {
|
||||
BeanMap map = (BeanMap)result;
|
||||
BeanMap map = (BeanMap) result;
|
||||
ElPropertyValue property = mapProperty();
|
||||
for (T bean : cacheBeans) {
|
||||
map.internalPut(property.pathGet(bean), bean);
|
||||
@@ -580,17 +561,18 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
|
||||
@SuppressWarnings("unchecked")
|
||||
private <K> Map<K, T> cacheBeansToMap() {
|
||||
ElPropertyValue property = mapProperty();
|
||||
Map<K,T> map = new LinkedHashMap<>();
|
||||
Map<K, T> map = new LinkedHashMap<>();
|
||||
for (T bean : cacheBeans) {
|
||||
map.put((K)property.pathGet(bean), bean);
|
||||
map.put((K) property.pathGet(bean), bean);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private ElPropertyValue mapProperty() {
|
||||
ElPropertyValue property = beanDescriptor.elGetValue(query.getMapKey());
|
||||
final String key = query.getMapKey();
|
||||
final ElPropertyValue property = key == null ? beanDescriptor.idProperty() : beanDescriptor.elGetValue(key);
|
||||
if (property == null) {
|
||||
throw new IllegalStateException("Unknown map key property "+query.getMapKey());
|
||||
throw new IllegalStateException("Unknown map key property " + key);
|
||||
}
|
||||
return property;
|
||||
}
|
||||
@@ -652,7 +634,7 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
|
||||
if (cached != null && isAuditReads() && readAuditQueryType()) {
|
||||
if (cached instanceof BeanCollection) {
|
||||
// raw sql can't use L2 cache so normal queries only in here
|
||||
Collection<T> actualDetails = ((BeanCollection<T>)cached).getActualDetails();
|
||||
Collection<T> actualDetails = ((BeanCollection<T>) cached).getActualDetails();
|
||||
List<Object> ids = new ArrayList<>(actualDetails.size());
|
||||
for (T bean : actualDetails) {
|
||||
ids.add(beanDescriptor.idForJson(bean));
|
||||
@@ -663,13 +645,13 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
|
||||
if (Boolean.FALSE.equals(query.isReadOnly())) {
|
||||
// return shallow copies if readonly is explicitly set to false
|
||||
if (cached instanceof BeanCollection) {
|
||||
cached = ((BeanCollection<?>)cached).getShallowCopy();
|
||||
cached = ((BeanCollection<?>) cached).getShallowCopy();
|
||||
} else if (cached instanceof List) {
|
||||
cached = new CopyOnFirstWriteList<>((List<?>)cached);
|
||||
cached = new CopyOnFirstWriteList<>((List<?>) cached);
|
||||
} else if (cached instanceof Set) {
|
||||
cached = new LinkedHashSet<>((Set<?>)cached);
|
||||
cached = new LinkedHashSet<>((Set<?>) cached);
|
||||
} else if (cached instanceof Map) {
|
||||
cached = new LinkedHashMap<>((Map<?,?>)cached);
|
||||
cached = new LinkedHashMap<>((Map<?, ?>) cached);
|
||||
}
|
||||
}
|
||||
return cached;
|
||||
|
||||
@@ -40,6 +40,9 @@ public final class PersistDeferredRelationship {
|
||||
|
||||
// bind the set clause for the importedId
|
||||
int pos = importedId.bind(1, sqlUpdate, assocBean);
|
||||
if (pos == -1) {
|
||||
return; // could not bind: TODO: should we log/throw an error?
|
||||
}
|
||||
// bind the where clause for the bean
|
||||
Object[] idValues = beanDescriptor.idBinder().getIdValues(bean);
|
||||
for (int j = 0; j < idValues.length; j++) {
|
||||
|
||||
@@ -213,6 +213,11 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
||||
return beanDescriptor.docStoreMode(type, txnMode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCascade() {
|
||||
return Flags.isRecurse(flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the draftDirty property should be set to true for this request.
|
||||
*/
|
||||
|
||||
@@ -31,7 +31,12 @@ final class AssocOneHelpRefInherit extends AssocOneHelp {
|
||||
Object read(DbReadContext ctx) throws SQLException {
|
||||
// read discriminator to determine the type
|
||||
InheritInfo rowInheritInfo = inherit.readType(ctx);
|
||||
if (rowInheritInfo == null) {
|
||||
BeanDescriptor<?> desc;
|
||||
if (rowInheritInfo != null) {
|
||||
desc = rowInheritInfo.desc();
|
||||
} else if (!inherit.hasChildren()) {
|
||||
desc = inherit.desc();
|
||||
} else {
|
||||
// ignore the id property
|
||||
property.targetIdBinder.loadIgnore(ctx);
|
||||
return null;
|
||||
@@ -42,7 +47,6 @@ final class AssocOneHelpRefInherit extends AssocOneHelp {
|
||||
}
|
||||
// check transaction context to see if it already exists
|
||||
PersistenceContext pc = ctx.getPersistenceContext();
|
||||
BeanDescriptor<?> desc = rowInheritInfo.desc();
|
||||
Object existing = desc.contextGet(pc, id);
|
||||
if (existing != null) {
|
||||
return existing;
|
||||
|
||||
@@ -56,7 +56,6 @@ import io.ebeanservice.docstore.api.mapping.DocPropertyMapping;
|
||||
import io.ebeanservice.docstore.api.mapping.DocumentMapping;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.persistence.PersistenceException;
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
@@ -87,6 +86,8 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
private final ConcurrentHashMap<String, ElPropertyDeploy> elDeployCache = new ConcurrentHashMap<>();
|
||||
private final ConcurrentHashMap<String, ElComparator<T>> comparatorCache = new ConcurrentHashMap<>();
|
||||
private final ConcurrentHashMap<String, STreeProperty> dynamicProperty = new ConcurrentHashMap<>();
|
||||
private final ConcurrentHashMap<String, Map<String,String>> pathMaps = new ConcurrentHashMap<>();
|
||||
|
||||
private final Map<String, SpiRawSql> namedRawSql;
|
||||
private final Map<String, String> namedQuery;
|
||||
private final boolean multiValueSupported;
|
||||
@@ -209,6 +210,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
private final EntityBean prototypeEntityBean;
|
||||
|
||||
private final IdBinder idBinder;
|
||||
private final String idSelect;
|
||||
private String idBinderInLHSSql;
|
||||
private String idBinderIdSql;
|
||||
private String deleteByIdSql;
|
||||
@@ -350,6 +352,23 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
propertiesIndex[i] = propMap.get(ebi.getProperty(i));
|
||||
}
|
||||
}
|
||||
idSelect = initIdSelect();
|
||||
}
|
||||
|
||||
String initIdSelect() {
|
||||
if (idProperty != null && !idProperty.name().equals("_idClass")) {
|
||||
return idProperty.name();
|
||||
} else if (entityType == EntityType.EMBEDDED) {
|
||||
return null;
|
||||
} else {
|
||||
StringJoiner sj = new StringJoiner(",");
|
||||
for (BeanProperty prop : propertiesNonMany) {
|
||||
if (prop.isImportedPrimaryKey()) {
|
||||
sj.add(prop.name());
|
||||
}
|
||||
}
|
||||
return sj.toString().intern();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isJacksonCorePresent() {
|
||||
@@ -1961,7 +1980,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
* Return the class type this BeanDescriptor describes.
|
||||
*/
|
||||
@Override
|
||||
@Nonnull
|
||||
public Class<T> type() {
|
||||
return beanType;
|
||||
}
|
||||
@@ -1973,7 +1991,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
* instead.
|
||||
*/
|
||||
@Override
|
||||
@Nonnull
|
||||
public String fullName() {
|
||||
return fullName;
|
||||
}
|
||||
@@ -1982,7 +1999,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
* Return the short name of the entity bean.
|
||||
*/
|
||||
@Override
|
||||
@Nonnull
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
@@ -2761,6 +2777,22 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
return draftableElement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> pathMap(String prefix) {
|
||||
return pathMaps.computeIfAbsent(prefix, s -> {
|
||||
HashMap<String, String> m = new HashMap<>();
|
||||
for (STreePropertyAssocMany many : propsMany()) {
|
||||
String name = many.name();
|
||||
m.put(name, prefix + "." + name);
|
||||
}
|
||||
for (STreePropertyAssocOne one : propsOne()) {
|
||||
String name = one.name();
|
||||
m.put(name, prefix + "." + name);
|
||||
}
|
||||
return m.isEmpty() ? Collections.emptyMap() : m;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmbeddedPath(String propertyPath) {
|
||||
ElPropertyDeploy elProp = elPropertyDeploy(propertyPath);
|
||||
@@ -2936,7 +2968,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public Collection<? extends Property> allProperties() {
|
||||
return propertiesAll();
|
||||
}
|
||||
@@ -3016,6 +3047,10 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
return idProperty;
|
||||
}
|
||||
|
||||
public String idSelect() {
|
||||
return idSelect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this bean should be inserted rather than updated.
|
||||
*
|
||||
@@ -3060,6 +3095,12 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
return versionPropertyIndex > -1 && ebi.isLoadedProperty(versionPropertyIndex);
|
||||
}
|
||||
|
||||
void setReferenceIfIdOnly(EntityBeanIntercept ebi) {
|
||||
if (referenceIdPropertyOnly(ebi)) {
|
||||
ebi.setReference(idPropertyIndex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the version value returning it in primitive long form.
|
||||
*/
|
||||
|
||||
@@ -23,6 +23,11 @@ abstract class BeanDescriptorElement<T> extends BeanDescriptor<T> {
|
||||
this.elementHelp = elementHelp;
|
||||
}
|
||||
|
||||
@Override
|
||||
String initIdSelect() {
|
||||
return null;
|
||||
}
|
||||
|
||||
private String shortName(String name) {
|
||||
int pos = name.lastIndexOf('.');
|
||||
if (pos > 1) {
|
||||
|
||||
@@ -90,7 +90,7 @@ final class BeanDescriptorJsonHelp<T> {
|
||||
return null;
|
||||
}
|
||||
JsonParser newParser = node.traverse();
|
||||
SpiJsonReader newReader = jsonRead.forJson(newParser, false);
|
||||
SpiJsonReader newReader = jsonRead.forJson(newParser);
|
||||
|
||||
// check for the discriminator value to determine the correct sub type
|
||||
String discColumn = inheritInfo.getRoot().getDiscriminatorColumn();
|
||||
@@ -152,6 +152,9 @@ final class BeanDescriptorJsonHelp<T> {
|
||||
}
|
||||
if (contextBean == null) {
|
||||
readJson.beanVisitor(bean, unmappedProperties);
|
||||
if (!isNullOrZero(id)) {
|
||||
desc.setReferenceIfIdOnly(bean._ebean_getIntercept());
|
||||
}
|
||||
}
|
||||
if (path != null) {
|
||||
readJson.popPath();
|
||||
|
||||
+50
-73
@@ -349,10 +349,10 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
builder = RawSqlBuilder.unparsed(sql.getQuery());
|
||||
}
|
||||
|
||||
for (Map.Entry<String,String> columnMapping : sql.getColumnMapping().entrySet()) {
|
||||
for (Map.Entry<String, String> columnMapping : sql.getColumnMapping().entrySet()) {
|
||||
builder.columnMapping(columnMapping.getKey(), columnMapping.getValue());
|
||||
}
|
||||
for (Map.Entry<String,String> aliasMapping : sql.getAliasMapping().entrySet()) {
|
||||
for (Map.Entry<String, String> aliasMapping : sql.getAliasMapping().entrySet()) {
|
||||
builder.tableAliasMapping(aliasMapping.getKey(), aliasMapping.getValue());
|
||||
}
|
||||
info.addRawSql(sql.getName(), builder.create());
|
||||
@@ -410,7 +410,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
@Override
|
||||
public boolean isTableManaged(String tableName) {
|
||||
return tableToDescMap.get(tableName.toLowerCase()) != null
|
||||
|| tableToViewDescMap.get(tableName.toLowerCase()) != null;
|
||||
|| tableToViewDescMap.get(tableName.toLowerCase()) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -618,7 +618,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
DeployBeanInfo<?> info = createDeployBeanInfo(entityClass);
|
||||
deployInfoMap.put(entityClass, info);
|
||||
Class<?> embeddedIdType = info.getEmbeddedIdType();
|
||||
if (embeddedIdType != null){
|
||||
if (embeddedIdType != null) {
|
||||
embeddedIdTypes.add(embeddedIdType);
|
||||
}
|
||||
}
|
||||
@@ -788,8 +788,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
Class<?> targetType = prop.getTargetType();
|
||||
DeployBeanInfo<?> info = deployInfoMap.get(targetType);
|
||||
if (info == null) {
|
||||
String msg = "Can not find descriptor [" + targetType + "] for " + prop.getFullBeanName();
|
||||
throw new PersistenceException(msg);
|
||||
throw new PersistenceException("Can not find descriptor [" + targetType + "] for " + prop.getFullBeanName());
|
||||
}
|
||||
return info.getDescriptor();
|
||||
}
|
||||
@@ -901,21 +900,17 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
Class<?> owningType = oneToMany.getOwningType();
|
||||
if (!oneToMany.getCascadeInfo().isSave()) {
|
||||
// The property MUST have persist cascading so that inserts work.
|
||||
|
||||
Class<?> targetType = oneToMany.getTargetType();
|
||||
String msg = "Error on " + oneToMany.getFullBeanName() + ". @OneToMany MUST have ";
|
||||
msg += "Cascade.PERSIST or Cascade.ALL because this is a unidirectional ";
|
||||
msg += "relationship. That is, there is no property of type " + owningType + " on " + targetType;
|
||||
|
||||
throw new PersistenceException(msg);
|
||||
}
|
||||
|
||||
// mark this property as unidirectional
|
||||
oneToMany.setUnidirectional();
|
||||
|
||||
// specify table and table alias...
|
||||
BeanTable beanTable = beanTable(owningType);
|
||||
|
||||
// define the TableJoin
|
||||
DeployTableJoin oneToManyJoin = oneToMany.getTableJoin();
|
||||
if (!oneToManyJoin.hasJoinColumns()) {
|
||||
@@ -951,27 +946,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
String mappedBy = prop.getMappedBy();
|
||||
// get the mappedBy property
|
||||
DeployBeanDescriptor<?> targetDesc = targetDescriptor(prop);
|
||||
DeployBeanProperty mappedProp = targetDesc.getBeanProperty(mappedBy);
|
||||
if (mappedProp == null) {
|
||||
String m = "Error on " + prop.getFullBeanName();
|
||||
m += " Can not find mappedBy property [" + targetDesc + "." + mappedBy + "] ";
|
||||
throw new PersistenceException(m);
|
||||
}
|
||||
|
||||
if (!(mappedProp instanceof DeployBeanPropertyAssocOne<?>)) {
|
||||
String m = "Error on " + prop.getFullBeanName();
|
||||
m += ". mappedBy property [" + targetDesc + "." + mappedBy + "]is not a OneToOne?";
|
||||
throw new PersistenceException(m);
|
||||
}
|
||||
|
||||
DeployBeanPropertyAssocOne<?> mappedAssocOne = (DeployBeanPropertyAssocOne<?>) mappedProp;
|
||||
|
||||
if (!mappedAssocOne.isOneToOne()) {
|
||||
String m = "Error on " + prop.getFullBeanName();
|
||||
m += ". mappedBy property [" + targetDesc + "." + mappedBy + "]is not a OneToOne?";
|
||||
throw new PersistenceException(m);
|
||||
}
|
||||
|
||||
DeployBeanPropertyAssocOne<?> mappedAssocOne = mappedOneToOne(prop, mappedBy, targetDesc);
|
||||
DeployTableJoin tableJoin = prop.getTableJoin();
|
||||
if (!tableJoin.hasJoinColumns()) {
|
||||
// define Join as the inverse of the mappedBy property
|
||||
@@ -987,6 +962,21 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
}
|
||||
}
|
||||
|
||||
private DeployBeanPropertyAssocOne<?> mappedOneToOne(DeployBeanPropertyAssocOne<?> prop, String mappedBy, DeployBeanDescriptor<?> targetDesc) {
|
||||
DeployBeanProperty mappedProp = targetDesc.getBeanProperty(mappedBy);
|
||||
if (mappedProp == null) {
|
||||
throw new PersistenceException("Error on " + prop.getFullBeanName() + " Can not find mappedBy property [" + targetDesc + "." + mappedBy + "]");
|
||||
}
|
||||
if (!(mappedProp instanceof DeployBeanPropertyAssocOne<?>)) {
|
||||
throw new PersistenceException("Error on " + prop.getFullBeanName() + ". mappedBy property [" + targetDesc + "." + mappedBy + "]is not a OneToOne?");
|
||||
}
|
||||
DeployBeanPropertyAssocOne<?> mappedAssocOne = (DeployBeanPropertyAssocOne<?>) mappedProp;
|
||||
if (!mappedAssocOne.isOneToOne()) {
|
||||
throw new PersistenceException("Error on " + prop.getFullBeanName() + ". mappedBy property [" + targetDesc + "." + mappedBy + "]is not a OneToOne?");
|
||||
}
|
||||
return mappedAssocOne;
|
||||
}
|
||||
|
||||
private void checkUniDirectionalPrimaryKeyJoin(DeployBeanPropertyAssocOne<?> prop) {
|
||||
if (prop.isPrimaryKeyJoin()) {
|
||||
// uni-directional PrimaryKeyJoin ...
|
||||
@@ -1008,7 +998,6 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
return;
|
||||
}
|
||||
DeployBeanDescriptor<?> targetDesc = targetDescriptor(prop);
|
||||
|
||||
if (targetDesc.isDraftableElement()) {
|
||||
// automatically turning on orphan removal and CascadeType.ALL
|
||||
prop.setModifyListenMode(BeanCollection.ModifyListenMode.REMOVALS);
|
||||
@@ -1040,23 +1029,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
String mappedBy = prop.getMappedBy();
|
||||
|
||||
// get the mappedBy property
|
||||
DeployBeanProperty mappedProp = targetDesc.getBeanProperty(mappedBy);
|
||||
if (mappedProp == null) {
|
||||
String m = "Error on " + prop.getFullBeanName();
|
||||
m += " Can not find mappedBy property [" + mappedBy + "] ";
|
||||
m += "in [" + targetDesc + "]";
|
||||
throw new PersistenceException(m);
|
||||
}
|
||||
|
||||
if (!(mappedProp instanceof DeployBeanPropertyAssocOne<?>)) {
|
||||
String m = "Error on " + prop.getFullBeanName();
|
||||
m += ". mappedBy property [" + mappedBy + "]is not a ManyToOne?";
|
||||
m += "in [" + targetDesc + "]";
|
||||
throw new PersistenceException(m);
|
||||
}
|
||||
|
||||
DeployBeanPropertyAssocOne<?> mappedAssocOne = (DeployBeanPropertyAssocOne<?>) mappedProp;
|
||||
|
||||
DeployBeanPropertyAssocOne<?> mappedAssocOne = mappedManyToOne(prop, targetDesc, mappedBy);
|
||||
DeployTableJoin tableJoin = prop.getTableJoin();
|
||||
if (!tableJoin.hasJoinColumns()) {
|
||||
// define Join as the inverse of the mappedBy property
|
||||
@@ -1079,6 +1052,17 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
}
|
||||
}
|
||||
|
||||
private DeployBeanPropertyAssocOne<?> mappedManyToOne(DeployBeanPropertyAssocMany<?> prop, DeployBeanDescriptor<?> targetDesc, String mappedBy) {
|
||||
DeployBeanProperty mappedProp = targetDesc.getBeanProperty(mappedBy);
|
||||
if (mappedProp == null) {
|
||||
throw new PersistenceException("Error on " + prop.getFullBeanName() + " Can not find mappedBy property [" + mappedBy + "] " + "in [" + targetDesc + "]");
|
||||
}
|
||||
if (!(mappedProp instanceof DeployBeanPropertyAssocOne<?>)) {
|
||||
throw new PersistenceException("Error on " + prop.getFullBeanName() + ". mappedBy property [" + mappedBy + "]is not a ManyToOne?" + "in [" + targetDesc + "]");
|
||||
}
|
||||
return (DeployBeanPropertyAssocOne<?>) mappedProp;
|
||||
}
|
||||
|
||||
/**
|
||||
* For mappedBy copy the joins from the other side.
|
||||
*/
|
||||
@@ -1094,33 +1078,10 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
|
||||
// get the mappedBy property
|
||||
DeployBeanDescriptor<?> targetDesc = targetDescriptor(prop);
|
||||
DeployBeanProperty mappedProp = targetDesc.getBeanProperty(mappedBy);
|
||||
|
||||
if (mappedProp == null) {
|
||||
String m = "Error on " + prop.getFullBeanName();
|
||||
m += " Can not find mappedBy property [" + mappedBy + "] ";
|
||||
m += "in [" + targetDesc + "]";
|
||||
throw new PersistenceException(m);
|
||||
}
|
||||
|
||||
if (!(mappedProp instanceof DeployBeanPropertyAssocMany<?>)) {
|
||||
String m = "Error on " + prop.getFullBeanName();
|
||||
m += ". mappedBy property [" + targetDesc + "." + mappedBy + "] is not a ManyToMany?";
|
||||
throw new PersistenceException(m);
|
||||
}
|
||||
|
||||
DeployBeanPropertyAssocMany<?> mappedAssocMany = (DeployBeanPropertyAssocMany<?>) mappedProp;
|
||||
|
||||
if (!mappedAssocMany.isManyToMany()) {
|
||||
String m = "Error on " + prop.getFullBeanName();
|
||||
m += ". mappedBy property [" + targetDesc + "." + mappedBy + "] is not a ManyToMany?";
|
||||
throw new PersistenceException(m);
|
||||
}
|
||||
DeployBeanPropertyAssocMany<?> mappedAssocMany = mappedManyToMany(prop, mappedBy, targetDesc);
|
||||
|
||||
// define the relationships/joins on this side as the
|
||||
// reverse of the other mappedBy side ...
|
||||
|
||||
// DeployTableJoin mappedJoin = mappedAssocMany.getTableJoin();
|
||||
DeployTableJoin mappedIntJoin = mappedAssocMany.getIntersectionJoin();
|
||||
DeployTableJoin mappendInverseJoin = mappedAssocMany.getInverseJoin();
|
||||
|
||||
@@ -1142,6 +1103,22 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
}
|
||||
}
|
||||
|
||||
private DeployBeanPropertyAssocMany<?> mappedManyToMany(DeployBeanPropertyAssocMany<?> prop, String mappedBy, DeployBeanDescriptor<?> targetDesc) {
|
||||
DeployBeanProperty mappedProp = targetDesc.getBeanProperty(mappedBy);
|
||||
if (mappedProp == null) {
|
||||
throw new PersistenceException("Error on " + prop.getFullBeanName() + " Can not find mappedBy property [" + mappedBy + "] " + "in [" + targetDesc + "]");
|
||||
}
|
||||
if (!(mappedProp instanceof DeployBeanPropertyAssocMany<?>)) {
|
||||
throw new PersistenceException("Error on " + prop.getFullBeanName() + ". mappedBy property [" + targetDesc + "." + mappedBy + "] is not a ManyToMany?");
|
||||
}
|
||||
|
||||
DeployBeanPropertyAssocMany<?> mappedAssocMany = (DeployBeanPropertyAssocMany<?>) mappedProp;
|
||||
if (!mappedAssocMany.isManyToMany()) {
|
||||
throw new PersistenceException("Error on " + prop.getFullBeanName() + ". mappedBy property [" + targetDesc + "." + mappedBy + "] is not a ManyToMany?");
|
||||
}
|
||||
return mappedAssocMany;
|
||||
}
|
||||
|
||||
private <T> void setBeanControllerFinderListener(DeployBeanDescriptor<T> descriptor) {
|
||||
persistControllerManager.addPersistControllers(descriptor);
|
||||
postLoadManager.addPostLoad(descriptor);
|
||||
|
||||
@@ -40,7 +40,6 @@ import io.ebeanservice.docstore.api.mapping.DocPropertyMapping;
|
||||
import io.ebeanservice.docstore.api.mapping.DocPropertyOptions;
|
||||
import io.ebeanservice.docstore.api.support.DocStructure;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.persistence.PersistenceException;
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
@@ -813,7 +812,6 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
|
||||
* Return the name of the property.
|
||||
*/
|
||||
@Override
|
||||
@Nonnull
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
@@ -1162,7 +1160,26 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
|
||||
public boolean isLob() {
|
||||
return lob;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if this <code>isLob()</code> or the type will effectively map to a lob.
|
||||
*/
|
||||
public boolean isDbLob() {
|
||||
if (lob) {
|
||||
return true;
|
||||
}
|
||||
switch (dbType) {
|
||||
case DbPlatformType.JSON:
|
||||
case DbPlatformType.JSONB:
|
||||
return dbLength == 0; // must be analog to DbPlatformTypeMapping.lookup
|
||||
case DbPlatformType.JSONBlob:
|
||||
case DbPlatformType.JSONClob:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isLobType(int type) {
|
||||
switch (type) {
|
||||
case Types.CLOB:
|
||||
@@ -1299,7 +1316,6 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
|
||||
* Return the property type.
|
||||
*/
|
||||
@Override
|
||||
@Nonnull
|
||||
public Class<?> type() {
|
||||
return propertyType;
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
|
||||
*/
|
||||
@Override
|
||||
public void addBeanToCollectionWithCreate(EntityBean parentBean, EntityBean detailBean, boolean withCheck) {
|
||||
BeanCollection<?> bc = (BeanCollection<?>) super.getValue(parentBean);
|
||||
BeanCollection<?> bc = beanCollection(parentBean);
|
||||
if (bc == null) {
|
||||
bc = help.createEmpty(parentBean);
|
||||
setValue(parentBean, bc);
|
||||
@@ -234,6 +234,15 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
|
||||
help.add(bc, detailBean, withCheck);
|
||||
}
|
||||
|
||||
private BeanCollection<?> beanCollection(EntityBean parentBean) {
|
||||
try {
|
||||
return (BeanCollection<?>) super.getValue(parentBean);
|
||||
} catch (ClassCastException e) {
|
||||
// fetching element collection, ok for now
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this is considered 'empty' from a save perspective.
|
||||
*/
|
||||
|
||||
+5
@@ -62,4 +62,9 @@ class DynamicPropertyAggregationFormula extends DynamicPropertyBase {
|
||||
ctx.appendParseSelect(parsedFormula, alias);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDbLob() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -35,8 +35,7 @@ public final class ImportedIdEmbedded implements ImportedId {
|
||||
BeanProperty[] embeddedProps = foreignAssocOne.properties();
|
||||
for (int i = 0; i < imported.length; i++) {
|
||||
String n = name + "." + foreignAssocOne.name() + "." + embeddedProps[i].name();
|
||||
BeanFkeyProperty fkey = new BeanFkeyProperty(n, imported[i].localDbColumn, foreignAssocOne.deployOrder());
|
||||
owner.descriptor().add(fkey);
|
||||
owner.descriptor().add(new BeanFkeyProperty(n, imported[i].localDbColumn, foreignAssocOne.deployOrder()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,6 +85,9 @@ public final class ImportedIdEmbedded implements ImportedId {
|
||||
for (ImportedIdSimple anImported : imported) {
|
||||
if (anImported.owner.isUpdateable()) {
|
||||
Object scalarValue = anImported.foreignProperty.getValue(embedded);
|
||||
if (scalarValue == null) {
|
||||
return -1; // could not bind
|
||||
}
|
||||
update.setParameter(pos++, scalarValue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,8 +88,7 @@ public final class ImportedIdSimple implements ImportedId, Comparable<ImportedId
|
||||
|
||||
@Override
|
||||
public void addFkeys(String name) {
|
||||
BeanFkeyProperty fkey = new BeanFkeyProperty(name + "." + foreignProperty.name(), localDbColumn, owner.deployOrder());
|
||||
owner.descriptor().add(fkey);
|
||||
owner.descriptor().add(new BeanFkeyProperty(name + "." + foreignProperty.name(), localDbColumn, owner.deployOrder()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -152,6 +151,9 @@ public final class ImportedIdSimple implements ImportedId, Comparable<ImportedId
|
||||
@Override
|
||||
public int bind(int position, SqlUpdate update, EntityBean bean) {
|
||||
Object value = getIdValue(bean);
|
||||
if (value == null) {
|
||||
return -1; // could not bind
|
||||
}
|
||||
update.setParameter(position, value);
|
||||
return ++position;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user