mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-09-20 11:17:36 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
77383f4d29 | ||
|
|
29fcbbfe97 | ||
|
|
d9e0a35efb | ||
|
|
0c01ecbac7 | ||
|
|
5095583cc8 | ||
|
|
92f04a2353 | ||
|
|
acbce35182 | ||
|
|
d6165f4b17 | ||
|
|
95656360a9 | ||
|
|
65d7df5488 | ||
|
|
12648cd37d | ||
|
|
edbd13c075 | ||
|
|
0964980a69 | ||
|
|
dc7d349366 | ||
|
|
a2e66bcb89 | ||
|
|
4d79815779 | ||
|
|
cbac00a89f | ||
|
|
33b2c398f6 | ||
|
|
416f50e782 | ||
|
|
2e8a6ceb53 | ||
|
|
f0fd9003ad | ||
|
|
dfeffb7c5e | ||
|
|
4b0fcb1d29 | ||
|
|
a7fe5d2b84 | ||
|
|
30327fe33e | ||
|
|
1e013331d4 | ||
|
|
f8964707d9 | ||
|
|
86c7de2de8 | ||
|
|
53b4d94933 | ||
|
|
b0ec23e53c | ||
|
|
20caae532c | ||
|
|
4369481c1a | ||
|
|
c94426b6b4 | ||
|
|
b2ff32e88c | ||
|
|
3bd8dfa7bf | ||
|
|
0e7abdd137 | ||
|
|
9135f2cd3e | ||
|
|
6785d5703e | ||
|
|
0a95ac7fa0 | ||
|
|
bbd5636689 | ||
|
|
9f0eaef3d8 | ||
|
|
a5d2a574d3 | ||
|
|
6e7adbb8e4 | ||
|
|
8913bead89 | ||
|
|
cdf1cd8487 | ||
|
|
2582c4b653 | ||
|
|
a9e3e2ea43 | ||
|
|
834ce971b3 | ||
|
|
5c27f89677 | ||
|
|
bfbbb7e7a7 | ||
|
|
a8947c7d2f | ||
|
|
d5401efb08 | ||
|
|
925ceaf441 | ||
|
|
c5fea13ca5 | ||
|
|
6fa3759786 | ||
|
|
1c5288b6ec | ||
|
|
b485fb7440 | ||
|
|
b07f909dd3 | ||
|
|
fa92e7a4b7 | ||
|
|
1823ef288a | ||
|
|
7b2128b02f | ||
|
|
3c84a902e8 | ||
|
|
3ce95c34cb | ||
|
|
d817dcb549 | ||
|
|
5f218e1fdb | ||
|
|
59daf5689a | ||
|
|
44efed5cd9 | ||
|
|
be28314e31 | ||
|
|
053d82b54a | ||
|
|
0141e2effa | ||
|
|
a33bb4d4c8 | ||
|
|
d0348210be | ||
|
|
753cf66cf0 | ||
|
|
4a8b4dd5fb | ||
|
|
2faf7008db | ||
|
|
76c25cbe83 | ||
|
|
5c36a725f4 | ||
|
|
b99d4f5a51 | ||
|
|
7d18942357 | ||
|
|
e51d9ba2ab | ||
|
|
1b1dce90ed | ||
|
|
405834fa45 | ||
|
|
7720229af9 | ||
|
|
89a294414e | ||
|
|
7bbfc00b86 | ||
|
|
d6c76de0a2 | ||
|
|
36f3986689 | ||
|
|
f0f4f13ec6 | ||
|
|
08466d42e9 | ||
|
|
1f841982a5 | ||
|
|
b34704a1fa |
@@ -20,14 +20,14 @@ jobs:
|
||||
os: [ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v3
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: ${{ matrix.java_version }}
|
||||
distribution: 'zulu'
|
||||
- name: Maven cache
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
cache-name: maven-cache
|
||||
with:
|
||||
|
||||
@@ -20,14 +20,14 @@ jobs:
|
||||
os: [ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v3
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: ${{ matrix.java_version }}
|
||||
distribution: 'adopt'
|
||||
- name: Maven cache
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
cache-name: maven-cache
|
||||
with:
|
||||
|
||||
@@ -20,14 +20,14 @@ jobs:
|
||||
os: [ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v3
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: ${{ matrix.java_version }}
|
||||
distribution: 'zulu'
|
||||
- name: Maven cache
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
cache-name: maven-cache
|
||||
with:
|
||||
|
||||
@@ -16,18 +16,18 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
java_version: [GA,EA]
|
||||
java_version: [GA,EA,23]
|
||||
os: [ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Java
|
||||
uses: oracle-actions/setup-java@v1
|
||||
with:
|
||||
website: jdk.java.net
|
||||
release: ${{ matrix.java_version }}
|
||||
- name: Maven cache
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
cache-name: maven-cache
|
||||
with:
|
||||
|
||||
@@ -20,14 +20,14 @@ jobs:
|
||||
os: [ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v3
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: ${{ matrix.java_version }}
|
||||
distribution: 'adopt'
|
||||
- name: Maven cache
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
cache-name: maven-cache
|
||||
with:
|
||||
|
||||
@@ -17,14 +17,14 @@ jobs:
|
||||
os: [ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v3
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: ${{ matrix.java_version }}
|
||||
distribution: 'adopt'
|
||||
- name: Maven cache
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
cache-name: maven-cache
|
||||
with:
|
||||
|
||||
@@ -20,14 +20,14 @@ jobs:
|
||||
os: [ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v3
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: ${{ matrix.java_version }}
|
||||
distribution: 'zulu'
|
||||
- name: Maven cache
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
cache-name: maven-cache
|
||||
with:
|
||||
|
||||
@@ -20,14 +20,14 @@ jobs:
|
||||
os: [ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v3
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: ${{ matrix.java_version }}
|
||||
distribution: 'adopt'
|
||||
- name: Maven cache
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
cache-name: maven-cache
|
||||
with:
|
||||
|
||||
@@ -20,14 +20,14 @@ jobs:
|
||||
os: [ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v3
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: ${{ matrix.java_version }}
|
||||
distribution: 'zulu'
|
||||
- name: Maven cache
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
cache-name: maven-cache
|
||||
with:
|
||||
|
||||
@@ -20,14 +20,14 @@ jobs:
|
||||
os: [ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v3
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: ${{ matrix.java_version }}
|
||||
distribution: 'adopt'
|
||||
- name: Maven cache
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
cache-name: maven-cache
|
||||
with:
|
||||
|
||||
@@ -17,14 +17,14 @@ jobs:
|
||||
os: [ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v3
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: ${{ matrix.java_version }}
|
||||
distribution: 'adopt'
|
||||
- name: Maven cache
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
cache-name: maven-cache
|
||||
with:
|
||||
|
||||
@@ -20,14 +20,14 @@ jobs:
|
||||
os: [ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v3
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: ${{ matrix.java_version }}
|
||||
distribution: 'adopt'
|
||||
- name: Maven cache
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
cache-name: maven-cache
|
||||
with:
|
||||
|
||||
@@ -20,14 +20,14 @@ jobs:
|
||||
os: [ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v3
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: ${{ matrix.java_version }}
|
||||
distribution: 'adopt'
|
||||
- name: Maven cache
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
cache-name: maven-cache
|
||||
with:
|
||||
|
||||
@@ -56,7 +56,7 @@ Work at the highest level of abstraction and drop down levels as needed.
|
||||
<tr>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://www.foconis.de/" target="_blank">
|
||||
<img width="222px" src="https://www.foconis.de/templates/yootheme/cache/foconis_logo_322-709da1de.png">
|
||||
<img width="222px" src="https://group.foconis.com/download/ci/logo/png-72dpi/logo-quer/foconis-analytics-quer.png">
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -42,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-clickhouse</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -42,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -42,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-db2</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -42,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-h2</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -42,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-hana</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -42,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-mariadb</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -42,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-mysql</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>14.6.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
<name>ebean-net-postgis</name>
|
||||
<description>ebean-net-postgis composite</description>
|
||||
<artifactId>ebean-net-postgis</artifactId>
|
||||
|
||||
<properties>
|
||||
<postgis.jdbc.version>2023.1.0</postgis.jdbc.version>
|
||||
<postgres.jdbc.version>42.7.2</postgres.jdbc.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-datasource</artifactId>
|
||||
<version>${ebean-datasource.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-migration</artifactId>
|
||||
<version>${ebean-migration.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Technically optional but most expected to use query beans -->
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-net-postgis-types</artifactId>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>${postgres.jdbc.version}</version>
|
||||
<exclusions>
|
||||
<!-- exclude unnecessary checker framework -->
|
||||
<exclusion>
|
||||
<groupId>*</groupId>
|
||||
<artifactId>*</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>net.postgis</groupId>
|
||||
<artifactId>postgis-jdbc</artifactId>
|
||||
<version>${postgis.jdbc.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,7 @@
|
||||
package io.ebean.postgis.assembly;
|
||||
|
||||
/**
|
||||
* Nothing interesting here - required placeholder for javadoc.
|
||||
*/
|
||||
public class Assembly {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
module io.ebean.postgis {
|
||||
|
||||
requires transitive io.ebean.api;
|
||||
requires transitive io.ebean.core;
|
||||
requires transitive io.ebean.datasource;
|
||||
requires transitive io.ebean.querybean;
|
||||
requires transitive io.ebean.platform.postgres;
|
||||
// requires transitive io.ebean.postgis.types;
|
||||
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -42,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-nuodb</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -42,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-oracle</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -22,13 +22,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -47,19 +47,19 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-postgis-types</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -42,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -42,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-sqlite</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -42,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-sqlserver</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -42,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -41,7 +41,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-jackson-mapper</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -60,13 +60,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-all</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
+2
-1
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>composites</artifactId>
|
||||
@@ -24,6 +24,7 @@
|
||||
<module>ebean-oracle</module>
|
||||
<module>ebean-postgres</module>
|
||||
<module>ebean-postgis</module>
|
||||
<module>ebean-net-postgis</module>
|
||||
<!-- <module>sqlanywhere</module>-->
|
||||
<module>ebean-sqlite</module>
|
||||
<module>ebean-sqlserver</module>
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean api</name>
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package io.ebean;
|
||||
|
||||
final class DPaging implements Paging {
|
||||
|
||||
static final Paging NONE = new DPaging(0, 0, null);
|
||||
|
||||
static Paging build(int pgIndex, int pgSize, OrderBy<?> orderBy) {
|
||||
return new DPaging(pgIndex, pgSize, orderBy);
|
||||
}
|
||||
|
||||
static Paging build(int pgIndex, int pgSize) {
|
||||
return new DPaging(pgIndex, pgSize, null);
|
||||
}
|
||||
|
||||
private final int pageNumber;
|
||||
private final int pageSize;
|
||||
private final OrderBy<?> orderBy;
|
||||
|
||||
DPaging(int pageNumber, int pageSize, OrderBy<?> orderBy) {
|
||||
this.pageNumber = pageNumber;
|
||||
this.pageSize = pageSize;
|
||||
this.orderBy = orderBy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int pageIndex() {
|
||||
return pageNumber;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int pageSize() {
|
||||
return pageSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OrderBy<?> orderBy() {
|
||||
return orderBy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Paging withPage(int pageNumber) {
|
||||
return new DPaging(pageNumber, pageSize, orderBy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Paging withOrderBy(String orderByClause) {
|
||||
return new DPaging(pageNumber, pageSize, OrderBy.of(orderByClause));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,8 +5,6 @@ import io.ebean.service.SpiContainer;
|
||||
import io.ebean.service.SpiContainerFactory;
|
||||
import jakarta.persistence.PersistenceException;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
/**
|
||||
@@ -157,10 +155,10 @@ public final class DatabaseFactory {
|
||||
* Create the container instance using the configuration.
|
||||
*/
|
||||
private static SpiContainer createContainer(ContainerConfig containerConfig) {
|
||||
Iterator<SpiContainerFactory> factories = ServiceLoader.load(SpiContainerFactory.class).iterator();
|
||||
if (factories.hasNext()) {
|
||||
return factories.next().create(containerConfig);
|
||||
SpiContainerFactory factory = XBootstrapService.containerFactory();
|
||||
if (factory == null) {
|
||||
throw new IllegalStateException("Service loader didn't find a SpiContainerFactory?");
|
||||
}
|
||||
throw new IllegalStateException("Service loader didn't find a SpiContainerFactory?");
|
||||
return factory.create(containerConfig);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ import java.util.List;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
/**
|
||||
* @deprecated migrate to using {@link PagedList#emptyList()} only.
|
||||
* <p>
|
||||
* An empty PagedList.
|
||||
* <p>
|
||||
* For use in application code when we need to return a PagedList but don't want to
|
||||
@@ -17,7 +19,8 @@ import java.util.concurrent.Future;
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
public class EmptyPagedList<T> implements PagedList<T> {
|
||||
@Deprecated(forRemoval = true)
|
||||
public final class EmptyPagedList<T> implements PagedList<T> {
|
||||
|
||||
@Override
|
||||
public void loadCount() {
|
||||
|
||||
@@ -84,7 +84,7 @@ public interface FetchGroup<T> {
|
||||
* @return The FetchGroup with the given select clause
|
||||
*/
|
||||
static <T> FetchGroup<T> of(Class<T> cls, String select) {
|
||||
return XServiceProvider.fetchGroupOf(cls, select);
|
||||
return XBootstrapService.fetchGroupOf(cls, select);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -108,14 +108,14 @@ public interface FetchGroup<T> {
|
||||
* @return The FetchGroupBuilder with the given select clause which we will add fetch clauses to
|
||||
*/
|
||||
static <T> FetchGroupBuilder<T> of(Class<T> cls) {
|
||||
return XServiceProvider.fetchGroupOf(cls);
|
||||
return XBootstrapService.fetchGroupOf(cls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a query to be used by query beans for constructing FetchGroup.
|
||||
*/
|
||||
static <T> SpiFetchGroupQuery<T> queryFor(Class<T> beanType) {
|
||||
return XServiceProvider.fetchGroupQueryFor(beanType);
|
||||
return XBootstrapService.fetchGroupQueryFor(beanType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,13 +8,11 @@ import java.util.Objects;
|
||||
/**
|
||||
* Represents an Order By for a Query.
|
||||
* <p>
|
||||
* Is a ordered list of OrderBy.Property objects each specifying a property and
|
||||
* Is an ordered list of OrderBy.Property objects each specifying a property and
|
||||
* whether it is ascending or descending order.
|
||||
* </p>
|
||||
* <p>
|
||||
* Typically you will not construct an OrderBy yourself but use one that exists
|
||||
* Typically, you will not construct an OrderBy yourself but use one that exists
|
||||
* on the Query object.
|
||||
* </p>
|
||||
*/
|
||||
public class OrderBy<T> implements Serializable {
|
||||
|
||||
@@ -25,8 +23,22 @@ public class OrderBy<T> implements Serializable {
|
||||
private final List<Property> list;
|
||||
|
||||
/**
|
||||
* Create an OrderBy parsing the given order by clause.
|
||||
* <p>
|
||||
* The order by clause follows SQL order by clause with comma's between each
|
||||
* property and optionally "asc" or "desc" to represent ascending or
|
||||
* descending order respectively.
|
||||
*/
|
||||
public static <P> OrderBy<P> of(String orderByClause) {
|
||||
return new OrderBy<>(orderByClause);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated This method will be removed from public API.
|
||||
* <p>
|
||||
* Create an empty OrderBy with no associated query.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public OrderBy() {
|
||||
this.list = new ArrayList<>(3);
|
||||
}
|
||||
@@ -36,20 +48,17 @@ public class OrderBy<T> implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an orderBy parsing the order by clause.
|
||||
* <p>
|
||||
* The order by clause follows SQL order by clause with comma's between each
|
||||
* property and optionally "asc" or "desc" to represent ascending or
|
||||
* descending order respectively.
|
||||
* </p>
|
||||
* @deprecated migrate to {@link OrderBy#of(String)}.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public OrderBy(String orderByClause) {
|
||||
this(null, orderByClause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct with a given query and order by clause.
|
||||
* @deprecated This method will be removed from public API.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public OrderBy(Query<T> query, String orderByClause) {
|
||||
this.query = query;
|
||||
this.list = new ArrayList<>(3);
|
||||
@@ -110,8 +119,11 @@ public class OrderBy<T> implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated This method will become internal only API.
|
||||
* <p>
|
||||
* Return a copy of this OrderBy with the path trimmed.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public OrderBy<T> copyWithTrim(String path) {
|
||||
List<Property> newList = new ArrayList<>(list.size());
|
||||
for (Property aList : list) {
|
||||
@@ -186,15 +198,15 @@ public class OrderBy<T> implements Serializable {
|
||||
if (list.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
var append = new StringAppend();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Property property = list.get(i);
|
||||
if (i > 0) {
|
||||
sb.append(", ");
|
||||
append.append(", ");
|
||||
}
|
||||
sb.append(property.toStringFormat());
|
||||
property.toStringFormat(append);
|
||||
}
|
||||
return sb.toString();
|
||||
return append.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -231,6 +243,55 @@ public class OrderBy<T> implements Serializable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append the order by clause.
|
||||
*/
|
||||
public interface Append {
|
||||
|
||||
/**
|
||||
* Append a property expression.
|
||||
*/
|
||||
Append property(String property);
|
||||
|
||||
/**
|
||||
* Append a literal.
|
||||
*/
|
||||
Append append(String literal);
|
||||
|
||||
/**
|
||||
* Parse and append an expression.
|
||||
*/
|
||||
Append parse(String expression);
|
||||
}
|
||||
|
||||
private static final class StringAppend implements Append {
|
||||
|
||||
private final StringBuilder builder = new StringBuilder();
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Append property(String property) {
|
||||
builder.append(property);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Append append(String literal) {
|
||||
builder.append(literal);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Append parse(String raw) {
|
||||
builder.append(raw);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A property and its ascending descending order.
|
||||
*/
|
||||
@@ -309,36 +370,25 @@ public class OrderBy<T> implements Serializable {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toStringFormat();
|
||||
return property;
|
||||
}
|
||||
|
||||
public String toStringFormat() {
|
||||
if (nulls == null && collation == null) {
|
||||
if (ascending) {
|
||||
return property;
|
||||
public void toStringFormat(Append append) {
|
||||
if (collation != null) {
|
||||
if (collation.contains("${}")) {
|
||||
// this is a complex collation, e.g. DB2 - we must replace the property
|
||||
append.parse(collation.replace("${}", property));
|
||||
} else {
|
||||
return property + " desc";
|
||||
append.property(property).append(" collate ").append(collation);
|
||||
}
|
||||
} else {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (collation != null) {
|
||||
if (collation.contains("${}")) {
|
||||
// this is a complex collation, e.g. DB2 - we must replace the property
|
||||
sb.append(collation.replace("${}", property));
|
||||
} else {
|
||||
sb.append(property);
|
||||
sb.append(" collate ").append(collation);
|
||||
}
|
||||
} else {
|
||||
sb.append(property);
|
||||
}
|
||||
if (!ascending) {
|
||||
sb.append(' ').append("desc");
|
||||
}
|
||||
if (nulls != null) {
|
||||
sb.append(' ').append(nulls).append(' ').append(highLow);
|
||||
}
|
||||
return sb.toString();
|
||||
append.property(property);
|
||||
}
|
||||
if (!ascending) {
|
||||
append.append(" desc");
|
||||
}
|
||||
if (nulls != null) {
|
||||
append.append(" ").append(nulls).append(" ").append(highLow);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.avaje.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Used to specify Paging on a Query as an alternative to setting each of the
|
||||
* maxRows, firstRow and orderBy clause via:
|
||||
* {@link Query#setMaxRows(int)} + {@link Query#setFirstRow(int)} + {@link Query#setOrderBy(OrderBy)}.
|
||||
* <p>
|
||||
* Example use:
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* var orderBy = OrderBy.of("lastName desc nulls first, firstName asc");
|
||||
* var paging = Paging.of(0, 100, orderBy);
|
||||
*
|
||||
* new QCustomer()
|
||||
* .name.isNotNull()
|
||||
* .setPaging(paging)
|
||||
* .findList();
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
public interface Paging {
|
||||
|
||||
/**
|
||||
* Create a Paging with the given page index size and orderBy.
|
||||
*
|
||||
* @param pageIndex the page index starting from zero
|
||||
* @param pageSize the page size (effectively max rows)
|
||||
* @param orderBy order by for the query result
|
||||
*/
|
||||
static Paging of(int pageIndex, int pageSize, @Nullable OrderBy<?> orderBy) {
|
||||
return DPaging.build(pageIndex, pageSize, orderBy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Paging with a raw order by clause.
|
||||
*
|
||||
* @param pageIndex the page index starting from zero
|
||||
* @param pageSize the page size (effectively max rows)
|
||||
* @param orderByClause raw order by clause for ordering the query result
|
||||
*/
|
||||
static Paging of(int pageIndex, int pageSize, @Nullable String orderByClause) {
|
||||
return of(pageIndex, pageSize, OrderBy.of(orderByClause));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Paging that will use the id property for ordering.
|
||||
*
|
||||
* @param pageIndex the page index starting from zero
|
||||
* @param pageSize the page size (effectively max rows)
|
||||
*/
|
||||
static Paging of(int pageIndex, int pageSize) {
|
||||
return DPaging.build(pageIndex, pageSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a Paging that will not apply any pagination to a query.
|
||||
*/
|
||||
static Paging ofNone() {
|
||||
return DPaging.NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the page index.
|
||||
*/
|
||||
int pageIndex();
|
||||
|
||||
/**
|
||||
* Return the page size.
|
||||
*/
|
||||
int pageSize();
|
||||
|
||||
/**
|
||||
* Return the order by.
|
||||
*/
|
||||
OrderBy<?> orderBy();
|
||||
|
||||
/**
|
||||
* Return a Paging using the given page index.
|
||||
*/
|
||||
Paging withPage(int pageIndex);
|
||||
|
||||
/**
|
||||
* Return a Paging using the given order by clause.
|
||||
*/
|
||||
Paging withOrderBy(String orderByClause);
|
||||
|
||||
}
|
||||
@@ -13,21 +13,21 @@ public interface ProfileLocation {
|
||||
* Create and return a new ProfileLocation.
|
||||
*/
|
||||
static ProfileLocation create() {
|
||||
return XServiceProvider.profileLocationFactory().create();
|
||||
return XBootstrapService.profileLocationFactory().create();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return a new ProfileLocation with line number.
|
||||
*/
|
||||
static ProfileLocation createWithLine() {
|
||||
return XServiceProvider.profileLocationFactory().createWithLine();
|
||||
return XBootstrapService.profileLocationFactory().createWithLine();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return a new ProfileLocation with a given lineNumber and label.
|
||||
*/
|
||||
static ProfileLocation create(String label) {
|
||||
return XServiceProvider.profileLocationFactory().create(label);
|
||||
return XBootstrapService.profileLocationFactory().create(label);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,6 +27,13 @@ public interface QueryBuilder<SELF, T> extends QueryBuilderProjection<SELF, T> {
|
||||
*/
|
||||
SELF alias(String alias);
|
||||
|
||||
/**
|
||||
* Apply changes to the query using a function.
|
||||
*
|
||||
* @param apply Function that applies changes to the query.
|
||||
*/
|
||||
SELF also(Consumer<SELF> apply);
|
||||
|
||||
/**
|
||||
* Apply changes to the query conditional on the supplied predicate.
|
||||
* <p>
|
||||
@@ -317,6 +324,8 @@ public interface QueryBuilder<SELF, T> extends QueryBuilderProjection<SELF, T> {
|
||||
*/
|
||||
SELF setMaxRows(int maxRows);
|
||||
|
||||
SELF setPaging(Paging paging);
|
||||
|
||||
/**
|
||||
* Set RawSql to use for this query.
|
||||
*/
|
||||
|
||||
@@ -40,6 +40,13 @@ public interface QueryBuilderProjection<SELF, T> {
|
||||
*/
|
||||
SELF select(String fetchProperties);
|
||||
|
||||
/**
|
||||
* Set DISTINCT ON clause. This is a Postgres only SQL feature.
|
||||
*
|
||||
* @param distinctOn The properties to include in the DISTINCT ON clause.
|
||||
*/
|
||||
SELF distinctOn(String distinctOn);
|
||||
|
||||
/**
|
||||
* Apply the fetchGroup which defines what part of the object graph to load.
|
||||
*/
|
||||
|
||||
@@ -22,14 +22,14 @@ public interface RawSqlBuilder {
|
||||
* resultSet.
|
||||
*/
|
||||
static RawSql resultSet(ResultSet resultSet, String... propertyNames) {
|
||||
return XServiceProvider.rawSql().resultSet(resultSet, propertyNames);
|
||||
return XBootstrapService.rawSql().resultSet(resultSet, propertyNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return a SqlRow based on the resultSet with dbTrueValue and binaryOptimizedUUID options.
|
||||
*/
|
||||
static SqlRow sqlRow(ResultSet resultSet, final String dbTrueValue, boolean binaryOptimizedUUID) throws SQLException {
|
||||
return XServiceProvider.rawSql().sqlRow(resultSet, dbTrueValue, binaryOptimizedUUID);
|
||||
return XBootstrapService.rawSql().sqlRow(resultSet, dbTrueValue, binaryOptimizedUUID);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -38,7 +38,7 @@ public interface RawSqlBuilder {
|
||||
* this query.
|
||||
*/
|
||||
static RawSqlBuilder unparsed(String sql) {
|
||||
return XServiceProvider.rawSql().unparsed(sql);
|
||||
return XBootstrapService.rawSql().unparsed(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,7 +55,7 @@ public interface RawSqlBuilder {
|
||||
* </p>
|
||||
*/
|
||||
static RawSqlBuilder parse(String sql) {
|
||||
return XServiceProvider.rawSql().parsed(sql);
|
||||
return XBootstrapService.rawSql().parsed(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.ebean.metric.MetricFactory;
|
||||
import io.ebean.service.*;
|
||||
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
/**
|
||||
* Bootstrap internal services.
|
||||
*/
|
||||
public final class XBootstrapService {
|
||||
|
||||
private static final SpiContainerFactory containerFactory;
|
||||
private static final SpiRawSqlService rawSqlService;
|
||||
private static final SpiProfileLocationFactory profileLocationFactory;
|
||||
private static final SpiFetchGroupService fetchGroupService;
|
||||
private static final MetricFactory metricFactory;
|
||||
private static final SpiJsonService jsonService;
|
||||
static {
|
||||
SpiContainerFactory _factory = null;
|
||||
SpiRawSqlService _raw = null;
|
||||
SpiProfileLocationFactory _profile = null;
|
||||
SpiFetchGroupService _fetch = null;
|
||||
MetricFactory _metric = null;
|
||||
SpiJsonService _json = null;
|
||||
for (BootstrapService extension : ServiceLoader.load(BootstrapService.class)) {
|
||||
if (extension instanceof SpiContainerFactory) {
|
||||
_factory = (SpiContainerFactory)extension;
|
||||
} else if (extension instanceof SpiRawSqlService) {
|
||||
_raw = (SpiRawSqlService)extension;
|
||||
} else if (extension instanceof SpiProfileLocationFactory) {
|
||||
_profile = (SpiProfileLocationFactory)extension;
|
||||
} else if (extension instanceof SpiFetchGroupService) {
|
||||
_fetch = (SpiFetchGroupService)extension;
|
||||
} else if (extension instanceof MetricFactory) {
|
||||
_metric = (MetricFactory)extension;
|
||||
} else if (extension instanceof SpiJsonService) {
|
||||
_json = (SpiJsonService)extension;
|
||||
}
|
||||
}
|
||||
containerFactory = _factory;
|
||||
rawSqlService = _raw;
|
||||
profileLocationFactory = _profile;
|
||||
fetchGroupService = _fetch;
|
||||
metricFactory = _metric;
|
||||
jsonService = _json;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the MetricFactory found in boostrap service loading.
|
||||
*/
|
||||
public static MetricFactory metricFactory() {
|
||||
return metricFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the SpiJsonService found in boostrap service loading.
|
||||
*/
|
||||
public static SpiJsonService jsonService() {
|
||||
return jsonService;
|
||||
}
|
||||
|
||||
static SpiContainerFactory containerFactory() {
|
||||
return containerFactory;
|
||||
}
|
||||
|
||||
static SpiRawSqlService rawSql() {
|
||||
return rawSqlService;
|
||||
}
|
||||
|
||||
static SpiProfileLocationFactory profileLocationFactory() {
|
||||
return profileLocationFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the FetchGroup with the given select clause.
|
||||
*/
|
||||
static <T> FetchGroup<T> fetchGroupOf(Class<T> cls, String select) {
|
||||
return fetchGroupService.of(cls, select);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the FetchGroupBuilder with the given select clause.
|
||||
*/
|
||||
static <T> FetchGroupBuilder<T> fetchGroupOf(Class<T> cls) {
|
||||
return fetchGroupService.of(cls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the FetchGroup Query for building fetch groups via query beans.
|
||||
*/
|
||||
static <T> SpiFetchGroupQuery<T> fetchGroupQueryFor(Class<T> cls) {
|
||||
return fetchGroupService.queryFor(cls);
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.ebean.service.SpiFetchGroupQuery;
|
||||
import io.ebean.service.SpiFetchGroupService;
|
||||
import io.ebean.service.SpiProfileLocationFactory;
|
||||
import io.ebean.service.SpiRawSqlService;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
/**
|
||||
* Lookup internal services.
|
||||
*/
|
||||
final class XServiceProvider {
|
||||
|
||||
private static SpiRawSqlService rawSqlService = initRawSql();
|
||||
|
||||
private static SpiProfileLocationFactory profileLocationFactory = initProfileLocation();
|
||||
|
||||
private static SpiFetchGroupService fetchGroupService = initSpiFetchGroupService();
|
||||
|
||||
private static SpiFetchGroupService initSpiFetchGroupService() {
|
||||
return loadFirstService(SpiFetchGroupService.class);
|
||||
}
|
||||
|
||||
private static SpiRawSqlService initRawSql() {
|
||||
return loadFirstService(SpiRawSqlService.class);
|
||||
}
|
||||
|
||||
private static SpiProfileLocationFactory initProfileLocation() {
|
||||
return loadFirstService(SpiProfileLocationFactory.class);
|
||||
}
|
||||
|
||||
private static <T> T loadFirstService(Class<T> cls) {
|
||||
Iterator<T> loader = ServiceLoader.load(cls).iterator();
|
||||
if (loader.hasNext()) {
|
||||
return loader.next();
|
||||
}
|
||||
throw new IllegalStateException("No service implementation found for " + cls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the RawSqlService implementation.
|
||||
*/
|
||||
static SpiRawSqlService rawSql() {
|
||||
return rawSqlService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the RawSqlService implementation.
|
||||
*/
|
||||
static SpiProfileLocationFactory profileLocationFactory() {
|
||||
return profileLocationFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the FetchGroup with the given select clause.
|
||||
*/
|
||||
static <T> FetchGroup<T> fetchGroupOf(Class<T> cls, String select) {
|
||||
return fetchGroupService.of(cls, select);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the FetchGroupBuilder with the given select clause.
|
||||
*/
|
||||
static <T> FetchGroupBuilder<T> fetchGroupOf(Class<T> cls) {
|
||||
return fetchGroupService.of(cls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the FetchGroup Query for building fetch groups via query beans.
|
||||
*/
|
||||
static <T> SpiFetchGroupQuery<T> fetchGroupQueryFor(Class<T> cls) {
|
||||
return fetchGroupService.queryFor(cls);
|
||||
}
|
||||
}
|
||||
@@ -129,7 +129,7 @@ public class DatabaseConfig implements DatabaseBuilder.Settings {
|
||||
* When true then include a sql comment in generated SELECT queries with the query
|
||||
* label or profile location label.
|
||||
*/
|
||||
private boolean includeLabelInSql;
|
||||
private boolean includeLabelInSql = true;
|
||||
|
||||
/**
|
||||
* Interesting classes such as entities, embedded, ScalarTypes,
|
||||
|
||||
@@ -4,22 +4,8 @@ public final class AnsiSqlRowsLimiter implements SqlLimiter {
|
||||
|
||||
@Override
|
||||
public SqlLimitResponse limit(SqlLimitRequest request) {
|
||||
String dbSql = request.getDbSql();
|
||||
StringBuilder sb = new StringBuilder(50 + dbSql.length());
|
||||
sb.append("select ");
|
||||
if (request.isDistinct()) {
|
||||
sb.append("distinct ");
|
||||
}
|
||||
sb.append(dbSql);
|
||||
int firstRow = request.getFirstRow();
|
||||
if (firstRow > 0) {
|
||||
sb.append(" offset ").append(firstRow).append(" rows");
|
||||
}
|
||||
int maxRows = request.getMaxRows();
|
||||
if (maxRows > 0) {
|
||||
sb.append(" fetch next ").append(maxRows).append(" rows only");
|
||||
}
|
||||
String sql = request.getDbPlatform().completeSql(sb.toString(), request.getOrmQuery());
|
||||
final var ansiSql = request.ansiOffsetRows();
|
||||
final var sql = request.getDbPlatform().completeSql(ansiSql, request.getOrmQuery());
|
||||
return new SqlLimitResponse(sql);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,23 +7,16 @@ public final class LimitOffsetSqlLimiter implements SqlLimiter {
|
||||
|
||||
@Override
|
||||
public SqlLimitResponse limit(SqlLimitRequest request) {
|
||||
String dbSql = request.getDbSql();
|
||||
StringBuilder sb = new StringBuilder(50 + dbSql.length());
|
||||
sb.append("select ");
|
||||
if (request.isDistinct()) {
|
||||
sb.append("distinct ");
|
||||
}
|
||||
sb.append(dbSql);
|
||||
final var buffer = request.selectDistinctOnSql();
|
||||
int maxRows = request.getMaxRows();
|
||||
if (maxRows > 0) {
|
||||
sb.append(" limit ").append(maxRows);
|
||||
buffer.append(" limit ").append(maxRows);
|
||||
}
|
||||
int firstRow = request.getFirstRow();
|
||||
if (firstRow > 0) {
|
||||
sb.append(" offset ").append(firstRow);
|
||||
buffer.append(" offset ").append(firstRow);
|
||||
}
|
||||
String sql = request.getDbPlatform().completeSql(sb.toString(), request.getOrmQuery());
|
||||
return new SqlLimitResponse(sql);
|
||||
return new SqlLimitResponse(request.getDbPlatform().completeSql(buffer.toString(), request.getOrmQuery()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,6 +8,21 @@ import io.ebean.Query;
|
||||
*/
|
||||
public interface SqlLimitRequest {
|
||||
|
||||
/**
|
||||
* Return ANSI SQL Offset and next rows.
|
||||
*/
|
||||
String ansiOffsetRows();
|
||||
|
||||
/**
|
||||
* Create and return buffer including the select distinct clause.
|
||||
*/
|
||||
StringBuilder selectDistinct();
|
||||
|
||||
/**
|
||||
* Create and return buffer including the select distinct on clause.
|
||||
*/
|
||||
StringBuilder selectDistinctOnSql();
|
||||
|
||||
/**
|
||||
* Return true if the query uses distinct.
|
||||
*/
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
package io.ebean.metric;
|
||||
|
||||
import io.ebean.ProfileLocation;
|
||||
import io.ebean.XBootstrapService;
|
||||
import io.ebean.service.BootstrapService;
|
||||
|
||||
/**
|
||||
* Factory to create timed metric counters.
|
||||
*/
|
||||
public interface MetricFactory {
|
||||
public interface MetricFactory extends BootstrapService {
|
||||
|
||||
/**
|
||||
* Return the factory instance.
|
||||
*/
|
||||
static MetricFactory get() {
|
||||
return MetricServiceProvider.get();
|
||||
return XBootstrapService.metricFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
package io.ebean.metric;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
/**
|
||||
* Lookup MetricFactory service.
|
||||
*/
|
||||
final class MetricServiceProvider {
|
||||
|
||||
private static final MetricFactory metricFactory = init();
|
||||
|
||||
private static MetricFactory init() {
|
||||
Iterator<MetricFactory> loader = ServiceLoader.load(MetricFactory.class).iterator();
|
||||
if (loader.hasNext()) {
|
||||
return loader.next();
|
||||
}
|
||||
throw new IllegalStateException("MetricFactory not service loaded?");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the MetricFactory implementation.
|
||||
*/
|
||||
static MetricFactory get() {
|
||||
return metricFactory;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package io.ebean.service;
|
||||
|
||||
/**
|
||||
* Marker interface for internal services loaded at startup.
|
||||
*/
|
||||
public interface BootstrapService {
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import io.ebean.config.ContainerConfig;
|
||||
/**
|
||||
* Provides shutdown of the entire container.
|
||||
*/
|
||||
public interface SpiContainerFactory {
|
||||
public interface SpiContainerFactory extends BootstrapService {
|
||||
|
||||
/**
|
||||
* Create the Container that builds EbeanServer instances.
|
||||
|
||||
@@ -6,7 +6,7 @@ import io.ebean.FetchGroupBuilder;
|
||||
/**
|
||||
* Service that parses FetchGroup expressions.
|
||||
*/
|
||||
public interface SpiFetchGroupService {
|
||||
public interface SpiFetchGroupService extends BootstrapService {
|
||||
|
||||
/**
|
||||
* Return the FetchGroup with the given select clause.
|
||||
|
||||
@@ -17,7 +17,7 @@ import java.util.Set;
|
||||
*
|
||||
* Supports converting between JSON content and simple java Maps/Lists.
|
||||
*/
|
||||
public interface SpiJsonService {
|
||||
public interface SpiJsonService extends BootstrapService {
|
||||
|
||||
/**
|
||||
* Write the nested Map/List as json.
|
||||
|
||||
@@ -5,7 +5,7 @@ import io.ebean.ProfileLocation;
|
||||
/**
|
||||
* Factory for creating profile locations.
|
||||
*/
|
||||
public interface SpiProfileLocationFactory {
|
||||
public interface SpiProfileLocationFactory extends BootstrapService {
|
||||
|
||||
/**
|
||||
* Create a profile location.
|
||||
|
||||
@@ -10,7 +10,7 @@ import java.sql.SQLException;
|
||||
/**
|
||||
* Service provided by Ebean for parsing and column mapping raw SQL queries.
|
||||
*/
|
||||
public interface SpiRawSqlService {
|
||||
public interface SpiRawSqlService extends BootstrapService {
|
||||
|
||||
/**
|
||||
* Create based on a JDBC ResultSet.
|
||||
|
||||
@@ -3,16 +3,15 @@ package io.ebean.text.json;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
import io.ebean.XBootstrapService;
|
||||
import io.ebean.service.SpiJsonService;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -20,16 +19,7 @@ import java.util.Set;
|
||||
*/
|
||||
public class EJson {
|
||||
|
||||
private static SpiJsonService plugin = init();
|
||||
|
||||
private static SpiJsonService init() {
|
||||
|
||||
Iterator<SpiJsonService> loader = ServiceLoader.load(SpiJsonService.class).iterator();
|
||||
if (loader.hasNext()) {
|
||||
return loader.next();
|
||||
}
|
||||
throw new IllegalStateException("No service implementation found for SpiJsonService?");
|
||||
}
|
||||
private static final SpiJsonService plugin = XBootstrapService.jsonService();
|
||||
|
||||
/**
|
||||
* Write the nested Map/List as json.
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
module io.ebean.api {
|
||||
|
||||
uses io.ebean.config.AutoConfigure;
|
||||
uses io.ebean.config.dbplatform.DatabasePlatformProvider;
|
||||
uses io.ebean.datasource.DataSourceAlertFactory;
|
||||
uses io.ebean.metric.MetricFactory;
|
||||
uses io.ebean.service.SpiContainerFactory;
|
||||
uses io.ebean.service.SpiRawSqlService;
|
||||
uses io.ebean.service.SpiProfileLocationFactory;
|
||||
uses io.ebean.service.SpiFetchGroupService;
|
||||
uses io.ebean.service.BootstrapService;
|
||||
uses io.ebean.service.SpiJsonService;
|
||||
|
||||
requires transitive java.sql;
|
||||
requires transitive io.avaje.config;
|
||||
|
||||
@@ -1 +1 @@
|
||||
ebean-version: 143
|
||||
ebean-version: 145
|
||||
|
||||
@@ -76,7 +76,7 @@ class DatabaseConfigTest {
|
||||
props.setProperty("skipDataSourceCheck", "true");
|
||||
props.setProperty("readOnlyDatabase", "true");
|
||||
props.setProperty("lengthCheck", "ON");
|
||||
props.setProperty("includeLabelInSql", "true");
|
||||
props.setProperty("includeLabelInSql", "false");
|
||||
|
||||
props.setProperty("queryPlan.enable", "true");
|
||||
props.setProperty("queryPlan.thresholdMicros", "10000");
|
||||
@@ -97,7 +97,7 @@ class DatabaseConfigTest {
|
||||
assertTrue(settings.isLoadModuleInfo());
|
||||
assertTrue(settings.skipDataSourceCheck());
|
||||
assertTrue(settings.readOnlyDatabase());
|
||||
assertTrue(settings.isIncludeLabelInSql());
|
||||
assertFalse(settings.isIncludeLabelInSql());
|
||||
assertThat(settings.getLengthCheck()).isEqualTo(LengthCheck.ON);
|
||||
|
||||
assertTrue(settings.isIdGeneratorAutomatic());
|
||||
@@ -183,7 +183,7 @@ class DatabaseConfigTest {
|
||||
assertEquals(10000L, config.getQueryPlanCaptureMaxTimeMillis());
|
||||
assertEquals(10, config.getQueryPlanCaptureMaxCount());
|
||||
assertThat(config.getLengthCheck()).isEqualTo(LengthCheck.OFF);
|
||||
assertFalse(config.isIncludeLabelInSql());
|
||||
assertTrue(config.isIncludeLabelInSql());
|
||||
|
||||
config.setLoadModuleInfo(false);
|
||||
assertFalse(config.isAutoLoadModuleInfo());
|
||||
|
||||
+26
-26
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean bom</name>
|
||||
@@ -89,25 +89,25 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core-type</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -125,13 +125,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-jackson-mapper</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-ddl-generator</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -155,37 +155,37 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>querybean-generator</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>kotlin-querybean-generator</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-test</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-redis</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-spring-txn</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- platforms -->
|
||||
@@ -193,79 +193,79 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-clickhouse</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-db2</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-h2</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-hana</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-mariadb</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-mysql</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-nuodb</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-oracle</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-postgres</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-postgis</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-postgis-types</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-sqlite</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-sqlserver</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>ebean-core-type</artifactId>
|
||||
@@ -16,7 +16,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
+7
-6
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>ebean-core</artifactId>
|
||||
@@ -22,7 +22,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -46,7 +46,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core-type</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -159,21 +159,21 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-h2</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-sqlserver</artifactId>
|
||||
<version>14.1.0</version>
|
||||
<version>14.6.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -211,6 +211,7 @@
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<argLine>-Dnet.bytebuddy.experimental=true</argLine>
|
||||
<useSystemClassLoader>false</useSystemClassLoader>
|
||||
<trimStackTrace>false</trimStackTrace>
|
||||
<failIfNoTests>false</failIfNoTests>
|
||||
|
||||
@@ -84,10 +84,17 @@ public final class LoadBeanRequest extends LoadRequest {
|
||||
return idList;
|
||||
}
|
||||
|
||||
public SpiQuery<?> createQuery(SpiEbeanServer server) {
|
||||
final SpiQuery<?> query = server.createQuery(beanType());
|
||||
query.usingTransaction(transaction);
|
||||
configureQuery(query);
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the query for lazy loading execution.
|
||||
*/
|
||||
public void configureQuery(SpiQuery<?> query) {
|
||||
private void configureQuery(SpiQuery<?> query) {
|
||||
query.setMode(Mode.LAZYLOAD_BEAN);
|
||||
query.setPersistenceContext(loadBuffer.persistenceContext());
|
||||
query.setLoadDescription(mode(), description());
|
||||
|
||||
@@ -94,6 +94,7 @@ public final class LoadManyRequest extends LoadRequest {
|
||||
public SpiQuery<?> createQuery(SpiEbeanServer server) {
|
||||
BeanPropertyAssocMany<?> many = many();
|
||||
SpiQuery<?> query = many.newQuery(server);
|
||||
query.usingTransaction(transaction);
|
||||
String orderBy = many.lazyFetchOrderBy();
|
||||
if (orderBy != null) {
|
||||
query.orderBy(orderBy);
|
||||
|
||||
@@ -439,6 +439,11 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
|
||||
@Override
|
||||
SpiQuery<T> copy();
|
||||
|
||||
/**
|
||||
* Return the distinct on clause.
|
||||
*/
|
||||
String distinctOn();
|
||||
|
||||
/**
|
||||
* Return a copy of the query attaching to a different EbeanServer.
|
||||
*/
|
||||
@@ -549,7 +554,6 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
|
||||
* Return true if the query should include the Id property.
|
||||
* <p>
|
||||
* distinct and single attribute queries exclude the Id property.
|
||||
* </p>
|
||||
*/
|
||||
boolean isWithId();
|
||||
|
||||
@@ -576,7 +580,12 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
|
||||
/**
|
||||
* Convert joins as necessary to query joins etc.
|
||||
*/
|
||||
SpiQuerySecondary convertJoins();
|
||||
SpiQueryManyJoin convertJoins();
|
||||
|
||||
/**
|
||||
* Return secondary queries if required.
|
||||
*/
|
||||
SpiQuerySecondary secondaryQuery();
|
||||
|
||||
/**
|
||||
* Return the TransactionContext.
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package io.ebeaninternal.api;
|
||||
|
||||
/**
|
||||
* A SQL Join for a ToMany property included in the query.
|
||||
*/
|
||||
public interface SpiQueryManyJoin {
|
||||
|
||||
/**
|
||||
* The full path of the many property to include in the query via join.
|
||||
*/
|
||||
String path();
|
||||
|
||||
/**
|
||||
* Order by clause defined via mapping on the ToMany property.
|
||||
*/
|
||||
String fetchOrderBy();
|
||||
|
||||
/**
|
||||
* Wrap the filter many expression with a condition allowing lEFT JOIN null matching row.
|
||||
*/
|
||||
String idNullOr(String filterManyExpression);
|
||||
}
|
||||
@@ -357,4 +357,8 @@ public interface SpiTransaction extends Transaction {
|
||||
*/
|
||||
void postRollback(Throwable cause);
|
||||
|
||||
/**
|
||||
* Set the transaction to be inactive via external transaction manager.
|
||||
*/
|
||||
void deactivateExternal();
|
||||
}
|
||||
|
||||
@@ -447,4 +447,9 @@ public abstract class SpiTransactionProxy implements SpiTransaction {
|
||||
public void postRollback(Throwable cause) {
|
||||
transaction.postRollback(cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deactivateExternal() {
|
||||
transaction.deactivateExternal();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,9 +126,7 @@ final class DefaultBeanLoader {
|
||||
if (loadRequest.checkEmpty()) {
|
||||
throw new RuntimeException("Nothing in batch?");
|
||||
}
|
||||
final SpiQuery<?> query = server.createQuery(loadRequest.beanType());
|
||||
query.usingTransaction(loadRequest.transaction());
|
||||
loadRequest.configureQuery(query);
|
||||
final SpiQuery<?> query = loadRequest.createQuery(server);
|
||||
loadRequest.postLoad(executeQuery(loadRequest, query));
|
||||
}
|
||||
|
||||
|
||||
@@ -449,6 +449,9 @@ public final class InternalConfiguration {
|
||||
*/
|
||||
private DataTimeZone initDataTimeZone() {
|
||||
String tz = config.getDataTimeZone();
|
||||
if ("NoTimeZone".equals(tz)) {
|
||||
return new NoDataTimeZone();
|
||||
}
|
||||
if (tz == null) {
|
||||
if (isMySql(getPlatform())) {
|
||||
return new MySqlDataTimeZone();
|
||||
|
||||
@@ -41,9 +41,9 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
|
||||
private CQueryPlanKey queryPlanKey;
|
||||
private SpiQuerySecondary secondaryQueries;
|
||||
private List<T> cacheBeans;
|
||||
private BeanPropertyAssocMany<?> manyProperty;
|
||||
private boolean inlineCountDistinct;
|
||||
private Set<String> dependentTables;
|
||||
private SpiQueryManyJoin manyJoin;
|
||||
|
||||
public OrmQueryRequest(SpiEbeanServer server, OrmQueryEngine queryEngine, SpiQuery<T> query, SpiTransaction t) {
|
||||
super(server, t);
|
||||
@@ -168,7 +168,8 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
|
||||
*/
|
||||
@Override
|
||||
public void prepareQuery() {
|
||||
secondaryQueries = query.convertJoins();
|
||||
manyJoin = query.convertJoins();
|
||||
secondaryQueries = query.secondaryQuery();
|
||||
beanDescriptor.prepareQuery(query);
|
||||
adapterPreQuery();
|
||||
queryPlanKey = query.prepare(this);
|
||||
@@ -446,19 +447,19 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine and return the ToMany property that is included in the query.
|
||||
*/
|
||||
public BeanPropertyAssocMany<?> determineMany() {
|
||||
manyProperty = beanDescriptor.manyProperty(query);
|
||||
return manyProperty;
|
||||
public SpiQueryManyJoin manyJoin() {
|
||||
return manyJoin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the many property that is fetched in the query or null if there is not one.
|
||||
* Return true if there is a manyJoin that should be included with this query.
|
||||
*/
|
||||
public BeanPropertyAssocMany<?> manyPropertyForOrderBy() {
|
||||
return query.isSingleAttribute() ? null : manyProperty;
|
||||
public boolean includeManyJoin() {
|
||||
if (manyJoin == null || query.isSingleAttribute()) {
|
||||
return false;
|
||||
}
|
||||
final Type type = query.type();
|
||||
return type != Type.SQ_EX && type != Type.COUNT;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1601,19 +1601,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the many property included in the query or null if one is not.
|
||||
*/
|
||||
public BeanPropertyAssocMany<?> manyProperty(SpiQuery<?> query) {
|
||||
OrmQueryDetail detail = query.detail();
|
||||
for (BeanPropertyAssocMany<?> many : propertiesMany) {
|
||||
if (detail.includesPath(many.name())) {
|
||||
return many;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a raw expression for 'where parent id in ...' clause.
|
||||
*/
|
||||
|
||||
+1
-1
@@ -514,7 +514,7 @@ final class BeanDescriptorCacheHelp<T> {
|
||||
|
||||
if (natKeys != null && !natKeys.isEmpty()) {
|
||||
if (natLog.isLoggable(DEBUG)) {
|
||||
natLog.log(DEBUG, " MPUT {0}({1}, {2})", cacheName, naturalKey, natKeys.keySet());
|
||||
natLog.log(DEBUG, " MPUT {0}({1}, {2})", cacheName, Arrays.toString(naturalKey), natKeys.keySet());
|
||||
}
|
||||
naturalKeyCache.putAll(natKeys);
|
||||
}
|
||||
|
||||
@@ -36,6 +36,11 @@ public final class BeanFkeyProperty implements ElPropertyValue {
|
||||
return "prefix:" + prefix + " name:" + name + " dbColumn:" + dbColumn + " ph:" + placeHolder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String idNullOr(String filterManyExpression) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAggregation() {
|
||||
return false;
|
||||
|
||||
@@ -512,6 +512,11 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
|
||||
return owningType.isAssignableFrom(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String idNullOr(String filterManyExpression) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadIgnore(DbReadContext ctx) {
|
||||
ctx.dataReader().incrementPos(1);
|
||||
|
||||
@@ -634,6 +634,11 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
|
||||
return fetchOrderBy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String idNullOr(String filterManyExpression) {
|
||||
return targetIdBinder.idNullOr(name, filterManyExpression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the order by for use when lazy loading the associated collection.
|
||||
*/
|
||||
|
||||
@@ -27,6 +27,11 @@ public interface IdBinder {
|
||||
*/
|
||||
void initialise();
|
||||
|
||||
/**
|
||||
* Wrap the filter many expression with a condition allowing lEFT JOIN null matching row.
|
||||
*/
|
||||
String idNullOr(String name, String filterManyExpression);
|
||||
|
||||
String idSelect();
|
||||
|
||||
/**
|
||||
|
||||
@@ -46,6 +46,20 @@ public final class IdBinderEmbedded implements IdBinder {
|
||||
this.idInValueSql = idInExpandedForm ? idInExpanded() : idInCompressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String idNullOr(String prefix, String filterManyExpression) {
|
||||
StringBuilder sb = new StringBuilder(100);
|
||||
sb.append("((");
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(" and ");
|
||||
}
|
||||
sb.append("${").append(prefix).append('.').append(embIdProperty.name()).append('}').append(props[i].name()).append(" is null");
|
||||
}
|
||||
sb.append(") or (").append(filterManyExpression).append("))");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String idSelect() {
|
||||
return embIdProperty.name();
|
||||
|
||||
@@ -28,6 +28,11 @@ final class IdBinderEmpty implements IdBinder {
|
||||
public void initialise() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String idNullOr(String name, String filterManyExpression) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String idSelect() {
|
||||
return "";
|
||||
|
||||
@@ -260,4 +260,9 @@ public final class IdBinderSimple implements IdBinder {
|
||||
final Object value = idProperty.getValue(bean);
|
||||
return scalarType.format(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String idNullOr(String prefix, String filterManyExpression) {
|
||||
return "(${" + prefix + "}" + idProperty.name() + " is null or (" + filterManyExpression + "))";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,4 +286,8 @@ public final class ElPropertyChain implements ElPropertyValue {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String idNullOr(String filterManyExpression) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.ebeaninternal.server.el;
|
||||
|
||||
import io.ebeaninternal.api.SpiQueryManyJoin;
|
||||
import io.ebeaninternal.server.deploy.BeanProperty;
|
||||
|
||||
/**
|
||||
@@ -10,7 +11,7 @@ import io.ebeaninternal.server.deploy.BeanProperty;
|
||||
* joins and set place holders for table alias'.
|
||||
* </p>
|
||||
*/
|
||||
public interface ElPropertyDeploy {
|
||||
public interface ElPropertyDeploy extends SpiQueryManyJoin {
|
||||
|
||||
/**
|
||||
* This is the elPrefix for all root level properties.
|
||||
@@ -80,4 +81,14 @@ public interface ElPropertyDeploy {
|
||||
* is left as a 'join' and which get converted to query join.
|
||||
*/
|
||||
int fetchPreference();
|
||||
|
||||
@Override
|
||||
default String path() {
|
||||
return elName();
|
||||
}
|
||||
|
||||
@Override
|
||||
default String fetchOrderBy() {
|
||||
return beanProperty().fetchOrderBy();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,10 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
|
||||
*/
|
||||
private final boolean textRoot;
|
||||
|
||||
public static <P> ExpressionList<P> forFetchGroup(Query<P> q) {
|
||||
return new DefaultExpressionList<>(q, null, null, null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct for Text root expression list - this handles implicit Bool Should, Must etc.
|
||||
*/
|
||||
|
||||
@@ -75,7 +75,7 @@ final class SubQueryExpression extends AbstractExpression implements Unsupported
|
||||
|
||||
@Override
|
||||
public void addSql(SpiExpressionRequest request) {
|
||||
request.property(propName).append(op.expression).append('(').parse(sql).append(')');
|
||||
request.property(propName).append(op.expression).append('(').append(sql).append(')');
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -3,7 +3,6 @@ package io.ebeaninternal.server.query;
|
||||
import io.ebean.*;
|
||||
import io.ebean.annotation.Platform;
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebean.config.dbplatform.SqlLimitRequest;
|
||||
import io.ebean.config.dbplatform.SqlLimitResponse;
|
||||
import io.ebean.config.dbplatform.SqlLimiter;
|
||||
import io.ebean.event.readaudit.ReadAuditQueryPlan;
|
||||
@@ -533,7 +532,7 @@ final class CQueryBuilder {
|
||||
private final boolean distinct;
|
||||
private final boolean countSingleAttribute;
|
||||
private final String dbOrderBy;
|
||||
private boolean useSqlLimiter;
|
||||
private final boolean useSqlLimiter;
|
||||
private boolean hasWhere;
|
||||
|
||||
private BuildReq(String selectClause, OrmQueryRequest<?> request, CQueryPredicates predicates, SqlTree select) {
|
||||
@@ -550,13 +549,15 @@ final class CQueryBuilder {
|
||||
this.distinct = query.isDistinct() || select.isSqlDistinct();
|
||||
this.dbOrderBy = predicates.dbOrderBy();
|
||||
this.countSingleAttribute = query.isCountDistinct() && query.isSingleAttribute();
|
||||
this.useSqlLimiter = selectClause == null
|
||||
&& query.hasMaxRowsOrFirstRow()
|
||||
&& (select.distinctOn() != null || select.manyProperty() == null || query.isSingleAttribute());
|
||||
}
|
||||
|
||||
private void appendSelect() {
|
||||
if (selectClause != null) {
|
||||
sb.append(selectClause);
|
||||
} else {
|
||||
useSqlLimiter = (query.hasMaxRowsOrFirstRow() && (select.manyProperty() == null || query.isSingleAttribute()));
|
||||
if (!useSqlLimiter) {
|
||||
appendSelectDistinct();
|
||||
}
|
||||
@@ -581,7 +582,7 @@ final class CQueryBuilder {
|
||||
if (request.isInlineCountDistinct()) {
|
||||
sb.append(')');
|
||||
}
|
||||
if (distinct && dbOrderBy != null) {
|
||||
if (distinct && dbOrderBy != null && query.distinctOn() == null) {
|
||||
// add the orderBy columns to the select clause (due to distinct)
|
||||
String[] tokens = DbOrderByTrim.trim(dbOrderBy).split(",");
|
||||
for (String token : tokens) {
|
||||
@@ -733,7 +734,7 @@ final class CQueryBuilder {
|
||||
}
|
||||
if (useSqlLimiter) {
|
||||
// use LIMIT/OFFSET, ROW_NUMBER() or rownum type SQL query limitation
|
||||
SqlLimitRequest r = new OrmQueryLimitRequest(sb.toString(), dbOrderBy, query, dbPlatform, distinct);
|
||||
var r = new OrmQueryLimitRequest(sb.toString(), dbOrderBy, query, dbPlatform, distinct, select.distinctOn(), hint(), inlineSqlComment());
|
||||
return sqlLimiter.limit(r);
|
||||
} else {
|
||||
if (updateStatement) {
|
||||
|
||||
@@ -5,6 +5,7 @@ import io.ebean.OrderBy.Property;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import io.ebeaninternal.server.deploy.BeanProperty;
|
||||
import io.ebeaninternal.server.deploy.BeanPropertyAssoc;
|
||||
import io.ebeaninternal.server.deploy.DeployParser;
|
||||
import io.ebeaninternal.server.deploy.id.IdBinder;
|
||||
import io.ebeaninternal.server.el.ElPropertyValue;
|
||||
|
||||
@@ -17,50 +18,81 @@ final class CQueryOrderBy {
|
||||
|
||||
private final BeanDescriptor<?> desc;
|
||||
private final OrderBy<?> orderBy;
|
||||
private final DeployParser parser;
|
||||
|
||||
/**
|
||||
* Create the logical order by clause.
|
||||
*/
|
||||
public static String parse(BeanDescriptor<?> desc, OrderBy<?> orderBy) {
|
||||
return new CQueryOrderBy(desc, orderBy).parseInternal();
|
||||
static String parse(DeployParser parser, BeanDescriptor<?> desc, OrderBy<?> orderBy) {
|
||||
return new CQueryOrderBy(parser, desc, orderBy).parseInternal();
|
||||
}
|
||||
|
||||
private CQueryOrderBy(BeanDescriptor<?> desc, OrderBy<?> orderBy) {
|
||||
private CQueryOrderBy(DeployParser parser, BeanDescriptor<?> desc, OrderBy<?> orderBy) {
|
||||
this.desc = desc;
|
||||
this.parser = parser;
|
||||
this.orderBy = orderBy;
|
||||
}
|
||||
|
||||
private String parseInternal() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
List<Property> properties = orderBy.getProperties();
|
||||
if (properties.isEmpty()) {
|
||||
// order by clause removed by filterMany()
|
||||
return null;
|
||||
}
|
||||
var append = new StringAppend(parser);
|
||||
for (int i = 0; i < properties.size(); i++) {
|
||||
if (i > 0) {
|
||||
sb.append(", ");
|
||||
append.append(", ");
|
||||
}
|
||||
Property p = properties.get(i);
|
||||
String expression = parseProperty(p);
|
||||
sb.append(expression);
|
||||
parseProperty(properties.get(i), append);
|
||||
}
|
||||
return sb.toString();
|
||||
return append.toString();
|
||||
}
|
||||
|
||||
private String parseProperty(Property p) {
|
||||
String propName = p.getProperty();
|
||||
ElPropertyValue el = desc.elGetValue(propName);
|
||||
if (el == null) {
|
||||
return p.toStringFormat();
|
||||
private void parseProperty(Property p, StringAppend append) {
|
||||
ElPropertyValue el = desc.elGetValue(p.getProperty());
|
||||
if (el != null) {
|
||||
BeanProperty beanProperty = el.beanProperty();
|
||||
if (beanProperty instanceof BeanPropertyAssoc<?>) {
|
||||
BeanPropertyAssoc<?> ap = (BeanPropertyAssoc<?>) beanProperty;
|
||||
IdBinder idBinder = ap.targetDescriptor().idBinder();
|
||||
append.parse(idBinder.orderBy(el.elName(), p.isAscending()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
p.toStringFormat(append);
|
||||
}
|
||||
|
||||
private static class StringAppend implements OrderBy.Append {
|
||||
|
||||
private final StringBuilder builder = new StringBuilder();
|
||||
private final DeployParser parser;
|
||||
|
||||
StringAppend(DeployParser parser) {
|
||||
this.parser = parser;
|
||||
}
|
||||
|
||||
BeanProperty beanProperty = el.beanProperty();
|
||||
if (beanProperty instanceof BeanPropertyAssoc<?>) {
|
||||
BeanPropertyAssoc<?> ap = (BeanPropertyAssoc<?>) beanProperty;
|
||||
IdBinder idBinder = ap.targetDescriptor().idBinder();
|
||||
return idBinder.orderBy(el.elName(), p.isAscending());
|
||||
@Override
|
||||
public String toString() {
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public OrderBy.Append property(String property) {
|
||||
builder.append(parser.property(property));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OrderBy.Append append(String literal) {
|
||||
builder.append(literal);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OrderBy.Append parse(String raw) {
|
||||
builder.append(parser.parse(raw));
|
||||
return this;
|
||||
}
|
||||
return p.toStringFormat();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
package io.ebeaninternal.server.query;
|
||||
|
||||
import io.ebean.OrderBy;
|
||||
import io.ebeaninternal.api.BindParams;
|
||||
import io.ebeaninternal.api.CoreLog;
|
||||
import io.ebeaninternal.api.SpiExpressionList;
|
||||
import io.ebeaninternal.api.SpiQuery;
|
||||
import io.ebeaninternal.api.*;
|
||||
import io.ebeaninternal.server.bind.DataBind;
|
||||
import io.ebeaninternal.server.core.OrmQueryRequest;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import io.ebeaninternal.server.deploy.BeanPropertyAssocMany;
|
||||
import io.ebeaninternal.server.deploy.DeployParser;
|
||||
import io.ebeaninternal.server.expression.DefaultExpressionRequest;
|
||||
import io.ebeaninternal.server.persist.Binder;
|
||||
@@ -62,6 +57,7 @@ public final class CQueryPredicates {
|
||||
*/
|
||||
private String dbFilterMany;
|
||||
private String dbOrderBy;
|
||||
private String dbDistinctOn;
|
||||
private String dbUpdateClause;
|
||||
/**
|
||||
* Includes from where and order by clauses.
|
||||
@@ -175,12 +171,8 @@ public final class CQueryPredicates {
|
||||
buildUpdateClause(buildSql, deployParser);
|
||||
buildBindWhereRawSql(buildSql);
|
||||
|
||||
BeanPropertyAssocMany<?> manyProperty = request.determineMany();
|
||||
if (buildSql) {
|
||||
String logicalOrderBy = deriveOrderByWithMany(request.manyPropertyForOrderBy());
|
||||
if (logicalOrderBy != null) {
|
||||
dbOrderBy = deployParser.parse(logicalOrderBy);
|
||||
}
|
||||
dbOrderBy = deriveOrderByWithMany(deployParser);
|
||||
// create a copy of the includes required to support the orderBy
|
||||
orderByIncludes = new HashSet<>(deployParser.includes());
|
||||
}
|
||||
@@ -191,13 +183,16 @@ public final class CQueryPredicates {
|
||||
dbWhere = where.buildSql();
|
||||
}
|
||||
}
|
||||
SpiQueryManyJoin manyProperty = request.manyJoin();
|
||||
if (manyProperty != null) {
|
||||
OrmQueryProperties chunk = query.detail().getChunk(manyProperty.name(), false);
|
||||
SpiExpressionList<?> filterManyExpr = chunk.getFilterMany();
|
||||
if (filterManyExpr != null) {
|
||||
this.filterMany = new DefaultExpressionRequest(request, deployParser, binder, filterManyExpr);
|
||||
if (buildSql) {
|
||||
dbFilterMany = filterMany.buildSql();
|
||||
OrmQueryProperties chunk = query.detail().getChunk(manyProperty.path(), false);
|
||||
if (chunk != null) {
|
||||
SpiExpressionList<?> filterManyExpr = chunk.getFilterMany();
|
||||
if (filterManyExpr != null) {
|
||||
this.filterMany = new DefaultExpressionRequest(request, deployParser, binder, filterManyExpr);
|
||||
if (buildSql) {
|
||||
dbFilterMany = manyProperty.idNullOr(filterMany.buildSql());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -209,6 +204,10 @@ public final class CQueryPredicates {
|
||||
}
|
||||
}
|
||||
if (buildSql) {
|
||||
final String distinctOn = query.distinctOn();
|
||||
if (distinctOn != null) {
|
||||
dbDistinctOn = deployParser.parse(distinctOn);
|
||||
}
|
||||
predicateIncludes = deployParser.includes();
|
||||
}
|
||||
}
|
||||
@@ -231,51 +230,53 @@ public final class CQueryPredicates {
|
||||
if (dbOrderBy != null) {
|
||||
dbOrderBy = alias.parse(dbOrderBy);
|
||||
}
|
||||
if (dbDistinctOn != null) {
|
||||
dbDistinctOn = alias.parse(dbDistinctOn);
|
||||
}
|
||||
}
|
||||
|
||||
private String parseOrderBy() {
|
||||
private String parseOrderBy(DeployParser parser) {
|
||||
OrderBy<?> orderBy = query.getOrderBy();
|
||||
if (orderBy == null) {
|
||||
return null;
|
||||
}
|
||||
return CQueryOrderBy.parse(request.descriptor(), orderBy);
|
||||
return CQueryOrderBy.parse(parser, request.descriptor(), orderBy);
|
||||
}
|
||||
|
||||
/**
|
||||
* There is a many property we need to make sure the ordering is appropriate.
|
||||
*/
|
||||
private String deriveOrderByWithMany(BeanPropertyAssocMany<?> manyProp) {
|
||||
if (manyProp == null) {
|
||||
return parseOrderBy();
|
||||
private String deriveOrderByWithMany(DeployParser parser) {
|
||||
String orderBy = parseOrderBy(parser);
|
||||
if (!request.includeManyJoin()) {
|
||||
return orderBy;
|
||||
}
|
||||
String orderBy = parseOrderBy();
|
||||
BeanDescriptor<?> desc = request.descriptor();
|
||||
String orderById = desc.defaultOrderBy();
|
||||
String orderById = parser.parse(request.descriptor().defaultOrderBy());
|
||||
if (orderBy == null) {
|
||||
orderBy = orderById;
|
||||
}
|
||||
// check for default ordering on the many property...
|
||||
SpiQueryManyJoin manyProp = request.manyJoin();
|
||||
String manyOrderBy = manyProp.fetchOrderBy();
|
||||
if (manyOrderBy != null) {
|
||||
orderBy = orderBy + ", " + CQueryBuilder.prefixOrderByFields(manyProp.name(), manyOrderBy);
|
||||
orderBy = orderBy + ", " + parser.parse(CQueryBuilder.prefixOrderByFields(manyProp.path(), manyOrderBy));
|
||||
}
|
||||
if (request.isFindById()) {
|
||||
// only one master bean so should be fine...
|
||||
return orderBy;
|
||||
}
|
||||
if (orderBy.startsWith(orderById)) {
|
||||
return orderBy;
|
||||
}
|
||||
// more than one top level row may be returned so
|
||||
// we need to make sure their is an order by on the
|
||||
// top level first (to ensure master/detail construction).
|
||||
int manyPos = orderBy.indexOf(manyProp.name());
|
||||
int idPos = orderBy.indexOf(" " + orderById);
|
||||
int idPos = orderBy.indexOf(orderById);
|
||||
if (idPos == 0) {
|
||||
return orderBy;
|
||||
}
|
||||
int manyPos = orderBy.indexOf("${" + manyProp.path() + "}");
|
||||
if (manyPos == -1) {
|
||||
// no ordering of the many
|
||||
if (idPos == -1) {
|
||||
// append the orderById so that master level objects are ordered
|
||||
// even if the orderBy is not unique for the master object
|
||||
return orderBy + ", " + orderById;
|
||||
}
|
||||
// orderById is already in the order by clause
|
||||
@@ -284,10 +285,10 @@ public final class CQueryPredicates {
|
||||
if (idPos == -1 || idPos >= manyPos) {
|
||||
if (idPos > manyPos) {
|
||||
// there was an error with the order by...
|
||||
String msg = "A Query on [" + desc + "] includes a join to a 'many' association [" + manyProp.name()
|
||||
+ "] with an incorrect orderBy [" + orderBy + "]. The id property [" + orderById
|
||||
+ "] must come before the many property [" + manyProp.name() + "] in the orderBy."
|
||||
+ " Ebean has automatically modified the orderBy clause to do this.";
|
||||
String msg = "A Query on [" + request.descriptor() + "] includes a join to a 'many' association [" + manyProp.path()
|
||||
+ "] with an incorrect orderBy [" + orderBy + "]. The id property [" + orderById
|
||||
+ "] must come before the many property [" + manyProp.path() + "] in the orderBy."
|
||||
+ " Ebean has automatically modified the orderBy clause to do this.";
|
||||
CoreLog.log.log(WARNING, msg);
|
||||
}
|
||||
// the id needs to come before the manyPropName
|
||||
@@ -351,6 +352,13 @@ public final class CQueryPredicates {
|
||||
return dbOrderBy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the db distinct on clause.
|
||||
*/
|
||||
String dbDistinctOn() {
|
||||
return dbDistinctOn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the includes required for the where and order by clause.
|
||||
*/
|
||||
|
||||
+23
-26
@@ -2,32 +2,10 @@ package io.ebeaninternal.server.query;
|
||||
|
||||
import io.avaje.lang.NonNullApi;
|
||||
import io.avaje.lang.Nullable;
|
||||
import io.ebean.CacheMode;
|
||||
import io.ebean.CountDistinctOrder;
|
||||
import io.ebean.Database;
|
||||
import io.ebean.DtoQuery;
|
||||
import io.ebean.Expression;
|
||||
import io.ebean.ExpressionFactory;
|
||||
import io.ebean.ExpressionList;
|
||||
import io.ebean.FetchConfig;
|
||||
import io.ebean.FetchGroup;
|
||||
import io.ebean.FetchPath;
|
||||
import io.ebean.FutureIds;
|
||||
import io.ebean.FutureList;
|
||||
import io.ebean.FutureRowCount;
|
||||
import io.ebean.OrderBy;
|
||||
import io.ebean.PagedList;
|
||||
import io.ebean.PersistenceContextScope;
|
||||
import io.ebean.ProfileLocation;
|
||||
import io.ebean.Query;
|
||||
import io.ebean.QueryIterator;
|
||||
import io.ebean.QueryType;
|
||||
import io.ebean.RawSql;
|
||||
import io.ebean.Transaction;
|
||||
import io.ebean.UpdateQuery;
|
||||
import io.ebean.Version;
|
||||
import io.ebean.*;
|
||||
import io.ebean.service.SpiFetchGroupQuery;
|
||||
import io.ebeaninternal.api.SpiQueryFetch;
|
||||
import io.ebeaninternal.server.expression.DefaultExpressionList;
|
||||
import io.ebeaninternal.server.querydefn.OrmQueryDetail;
|
||||
import io.ebeaninternal.server.querydefn.SpiFetchGroup;
|
||||
|
||||
@@ -53,12 +31,18 @@ final class DefaultFetchGroupQuery<T> implements SpiFetchGroupQuery<T>, SpiQuery
|
||||
private static final FetchConfig FETCH_LAZY = FetchConfig.ofLazy();
|
||||
|
||||
private OrmQueryDetail detail = new OrmQueryDetail();
|
||||
private OrderBy<T> orderBy;
|
||||
|
||||
@Override
|
||||
public FetchGroup<T> buildFetchGroup() {
|
||||
return new DFetchGroup<>(detail);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query<T> distinctOn(String distinctOn) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query<T> select(String columns) {
|
||||
detail.select(columns);
|
||||
@@ -225,6 +209,11 @@ final class DefaultFetchGroupQuery<T> implements SpiFetchGroupQuery<T>, SpiQuery
|
||||
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query<T> also(Consumer<Query<T>> apply) {
|
||||
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query<T> alsoIf(BooleanSupplier predicate, Consumer<Query<T>> apply) {
|
||||
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
|
||||
@@ -428,7 +417,7 @@ final class DefaultFetchGroupQuery<T> implements SpiFetchGroupQuery<T>, SpiQuery
|
||||
|
||||
@Override
|
||||
public ExpressionList<T> where() {
|
||||
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
|
||||
return DefaultExpressionList.forFetchGroup(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -458,7 +447,10 @@ final class DefaultFetchGroupQuery<T> implements SpiFetchGroupQuery<T>, SpiQuery
|
||||
|
||||
@Override
|
||||
public OrderBy<T> orderBy() {
|
||||
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
|
||||
if (orderBy == null) {
|
||||
orderBy = new OrderBy<>();
|
||||
}
|
||||
return orderBy;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -496,6 +488,11 @@ final class DefaultFetchGroupQuery<T> implements SpiFetchGroupQuery<T>, SpiQuery
|
||||
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query<T> setPaging(Paging paging) {
|
||||
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query<T> setMapKey(String mapKey) {
|
||||
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
|
||||
|
||||
@@ -156,6 +156,10 @@ public final class SqlTreeBuilder {
|
||||
}
|
||||
|
||||
private String buildDistinctOn() {
|
||||
String distinctOn = predicates.dbDistinctOn();
|
||||
if (distinctOn != null) {
|
||||
return distinctOn;
|
||||
}
|
||||
if (rawSql || !distinctOnPlatform || !sqlDistinct || Type.COUNT == query.type()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -72,6 +72,7 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
|
||||
* Lazy loading batch size (can override server wide default).
|
||||
*/
|
||||
private int lazyLoadBatchSize;
|
||||
private String distinctOn;
|
||||
private OrderBy<T> orderBy;
|
||||
private String loadMode;
|
||||
private String loadDescription;
|
||||
@@ -292,6 +293,12 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query<T> also(Consumer<Query<T>> apply) {
|
||||
apply.accept(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query<T> alsoIf(BooleanSupplier predicate, Consumer<Query<T>> consumer) {
|
||||
if (predicate.getAsBoolean()) {
|
||||
@@ -503,19 +510,26 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final SpiQuerySecondary convertJoins() {
|
||||
public final SpiQueryManyJoin convertJoins() {
|
||||
if (!useDocStore) {
|
||||
createExtraJoinsToSupportManyWhereClause();
|
||||
}
|
||||
markQueryJoins();
|
||||
return markQueryJoins();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpiQuerySecondary secondaryQuery() {
|
||||
return new OrmQuerySecondary(removeQueryJoins(), removeLazyJoins());
|
||||
}
|
||||
|
||||
/**
|
||||
* Limit the number of fetch joins to Many properties, mark as query joins as needed.
|
||||
*
|
||||
* @return The query join many property or null.
|
||||
*/
|
||||
private void markQueryJoins() {
|
||||
detail.markQueryJoins(beanDescriptor, lazyLoadManyPath, isAllowOneManyFetch(), type.defaultSelect());
|
||||
private SpiQueryManyJoin markQueryJoins() {
|
||||
// no automatic join to query join conversion when distinctOn is used
|
||||
return distinctOn != null ? null : detail.markQueryJoins(beanDescriptor, lazyLoadManyPath, isAllowOneManyFetch(), type.defaultSelect());
|
||||
}
|
||||
|
||||
private boolean isAllowOneManyFetch() {
|
||||
@@ -639,12 +653,11 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
|
||||
return countDistinctOrder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the Id should be included in the query.
|
||||
*/
|
||||
@Override
|
||||
public final boolean isWithId() {
|
||||
return !manualId && !distinct && !singleAttribute;
|
||||
// distinctOn orm query will auto include the id property
|
||||
// distinctOn dto query does NOT (via setting manualId to true)
|
||||
return !manualId && !singleAttribute && (!distinct || distinctOn != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -740,6 +753,7 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
|
||||
copy.baseTable = baseTable;
|
||||
copy.rootTableAlias = rootTableAlias;
|
||||
copy.distinct = distinct;
|
||||
copy.distinctOn = distinctOn;
|
||||
copy.allowLoadErrors = allowLoadErrors;
|
||||
copy.timeout = timeout;
|
||||
copy.mapKey = mapKey;
|
||||
@@ -799,6 +813,11 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String distinctOn() {
|
||||
return distinctOn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String loadDescription() {
|
||||
return loadDescription;
|
||||
@@ -1087,6 +1106,9 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
|
||||
}
|
||||
if (distinct) {
|
||||
sb.append("/dt");
|
||||
if (distinctOn != null) {
|
||||
sb.append("/o:").append(distinctOn);
|
||||
}
|
||||
}
|
||||
if (allowLoadErrors) {
|
||||
sb.append("/ae");
|
||||
@@ -1340,6 +1362,13 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
|
||||
detail.addNested(name, nestedDetail, config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Query<T> distinctOn(String distinctOn) {
|
||||
this.distinctOn = distinctOn;
|
||||
this.distinct = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Query<T> select(String columns) {
|
||||
detail.select(columns);
|
||||
@@ -1348,7 +1377,9 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
|
||||
|
||||
@Override
|
||||
public final Query<T> select(FetchGroup<T> fetchGroup) {
|
||||
this.detail = ((SpiFetchGroup<T>) fetchGroup).detail();
|
||||
if (fetchGroup != null) {
|
||||
this.detail = ((SpiFetchGroup<T>) fetchGroup).detail();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -1796,6 +1827,22 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Query<T> setPaging(@Nullable Paging paging) {
|
||||
if (paging != null && paging.pageSize() > 0) {
|
||||
firstRow = paging.pageIndex() * paging.pageSize();
|
||||
maxRows = paging.pageSize();
|
||||
orderBy = (OrderBy<T>) paging.orderBy();
|
||||
if (orderBy == null || orderBy.isEmpty()) {
|
||||
// should not be paging without any order by clause so set
|
||||
// orderById such that the Id property is used
|
||||
orderById = true;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String mapKey() {
|
||||
return mapKey;
|
||||
|
||||
@@ -3,6 +3,7 @@ package io.ebeaninternal.server.querydefn;
|
||||
import io.ebean.FetchConfig;
|
||||
import io.ebean.event.BeanQueryRequest;
|
||||
import io.ebean.util.SplitName;
|
||||
import io.ebeaninternal.api.SpiQueryManyJoin;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import io.ebeaninternal.server.deploy.BeanPropertyAssoc;
|
||||
import io.ebeaninternal.server.el.ElPropertyDeploy;
|
||||
@@ -327,12 +328,15 @@ public final class OrmQueryDetail implements Serializable {
|
||||
|
||||
/**
|
||||
* Mark 'fetch joins' to 'many' properties over to 'query joins' where needed.
|
||||
*
|
||||
* @return The fetch join many property or null
|
||||
*/
|
||||
void markQueryJoins(BeanDescriptor<?> beanDescriptor, String lazyLoadManyPath, boolean allowOne, boolean addIds) {
|
||||
SpiQueryManyJoin markQueryJoins(BeanDescriptor<?> beanDescriptor, String lazyLoadManyPath, boolean allowOne, boolean addIds) {
|
||||
if (fetchPaths.isEmpty()) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
ElPropertyDeploy many = null;
|
||||
// the name of the many fetch property if there is one
|
||||
String manyFetchProperty = null;
|
||||
// flag that is set once the many fetch property is chosen
|
||||
@@ -353,6 +357,7 @@ public final class OrmQueryDetail implements Serializable {
|
||||
fetchJoinFirstMany = false;
|
||||
manyFetchProperty = pair.getPath();
|
||||
chunk.filterManyInline();
|
||||
many = elProp;
|
||||
} else {
|
||||
// convert this one over to a 'query join'
|
||||
chunk.markForQueryJoin();
|
||||
@@ -360,6 +365,7 @@ public final class OrmQueryDetail implements Serializable {
|
||||
}
|
||||
}
|
||||
}
|
||||
return many;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,13 +11,67 @@ public final class OrmQueryLimitRequest implements SqlLimitRequest {
|
||||
private final String sql;
|
||||
private final String sqlOrderBy;
|
||||
private final boolean distinct;
|
||||
private final String distinctOn;
|
||||
private final String hint;
|
||||
private final String label;
|
||||
|
||||
public OrmQueryLimitRequest(String sql, String sqlOrderBy, SpiQuery<?> ormQuery, DatabasePlatform dbPlatform, boolean distinct) {
|
||||
this(sql, sqlOrderBy, ormQuery, dbPlatform, distinct, null, "", "");
|
||||
}
|
||||
|
||||
public OrmQueryLimitRequest(String sql, String sqlOrderBy, SpiQuery<?> ormQuery, DatabasePlatform dbPlatform,
|
||||
boolean distinct, String distinctOn, String hint, String label) {
|
||||
this.sql = sql;
|
||||
this.sqlOrderBy = sqlOrderBy;
|
||||
this.ormQuery = ormQuery;
|
||||
this.dbPlatform = dbPlatform;
|
||||
this.distinct = distinct;
|
||||
this.distinctOn = distinctOn;
|
||||
this.hint = hint;
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
private StringBuilder newBuffer() {
|
||||
return new StringBuilder(50 + sql.length());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String ansiOffsetRows() {
|
||||
final var buffer = selectDistinct();
|
||||
buffer.append(sql);
|
||||
int firstRow = getFirstRow();
|
||||
if (firstRow > 0) {
|
||||
buffer.append(" offset ").append(firstRow).append(" rows");
|
||||
}
|
||||
int maxRows = getMaxRows();
|
||||
if (maxRows > 0) {
|
||||
buffer.append(" fetch next ").append(maxRows).append(" rows only");
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringBuilder selectDistinct() {
|
||||
final var buffer = newBuffer();
|
||||
buffer.append("select ").append(hint).append(label);
|
||||
if (distinct) {
|
||||
buffer.append("distinct ");
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringBuilder selectDistinctOnSql() {
|
||||
var buffer = newBuffer();
|
||||
buffer.append("select ").append(hint).append(label);
|
||||
if (distinct) {
|
||||
buffer.append("distinct ");
|
||||
if (distinctOn != null) {
|
||||
buffer.append("on (").append(distinctOn).append(") ");
|
||||
}
|
||||
}
|
||||
buffer.append(sql);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+5
@@ -609,6 +609,11 @@ final class ImplicitReadOnlyTransaction implements SpiTransaction, TxnProfileEve
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deactivateExternal() {
|
||||
this.active = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the transaction is active.
|
||||
*/
|
||||
|
||||
@@ -1082,6 +1082,11 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes {
|
||||
return active;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deactivateExternal() {
|
||||
this.active = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isPersistCascade() {
|
||||
return persistCascade;
|
||||
|
||||
+26
-21
@@ -94,9 +94,14 @@ public final class JtaTransactionManager implements ExternalTransactionManager {
|
||||
// check current Ebean transaction
|
||||
SpiTransaction currentEbeanTransaction = scope.inScope();
|
||||
if (currentEbeanTransaction != null) {
|
||||
// NOT expecting this so log WARNING
|
||||
log.log(WARNING, "JTA Transaction - no current txn BUT using current Ebean one {0}", currentEbeanTransaction.id());
|
||||
return currentEbeanTransaction;
|
||||
if (currentEbeanTransaction.isActive()) {
|
||||
// NOT expecting this so log WARNING
|
||||
log.log(WARNING, "JTA Transaction - no current txn BUT using current Ebean one {0}", currentEbeanTransaction.id());
|
||||
return currentEbeanTransaction;
|
||||
} else {
|
||||
log.log(DEBUG, "JTA Transaction - clearing inActive Ebean transaction {0}", currentEbeanTransaction.id());
|
||||
scope.clearExternal();
|
||||
}
|
||||
}
|
||||
|
||||
UserTransaction ut = userTransaction();
|
||||
@@ -186,27 +191,27 @@ public final class JtaTransactionManager implements ExternalTransactionManager {
|
||||
|
||||
@Override
|
||||
public void afterCompletion(int status) {
|
||||
switch (status) {
|
||||
case Status.STATUS_COMMITTED:
|
||||
log.log(DEBUG, "Jta Txn [{0}] committed", transaction.id());
|
||||
transaction.postCommit();
|
||||
// Remove this transaction object as it is completed
|
||||
transactionManager.scope().clearExternal();
|
||||
break;
|
||||
try {
|
||||
switch (status) {
|
||||
case Status.STATUS_COMMITTED:
|
||||
log.log(DEBUG, "Jta Txn [{0}] committed", transaction.id());
|
||||
transaction.postCommit();
|
||||
break;
|
||||
|
||||
case Status.STATUS_ROLLEDBACK:
|
||||
log.log(DEBUG, "Jta Txn [{0}] rollback", transaction.id());
|
||||
transaction.postRollback(null);
|
||||
// Remove this transaction object as it is completed
|
||||
transactionManager.scope().clearExternal();
|
||||
break;
|
||||
case Status.STATUS_ROLLEDBACK:
|
||||
log.log(DEBUG, "Jta Txn [{0}] rollback", transaction.id());
|
||||
transaction.postRollback(null);
|
||||
break;
|
||||
|
||||
default:
|
||||
log.log(DEBUG, "Jta Txn [{0}] status:{1}", transaction.id(), status);
|
||||
default:
|
||||
log.log(DEBUG, "Jta Txn [{0}] status:{1}", transaction.id(), status);
|
||||
}
|
||||
} finally {
|
||||
transaction.deactivateExternal();
|
||||
transactionManager.scope().clearExternal();
|
||||
// No matter the completion status of the transaction, we release the connection we got from the pool.
|
||||
JdbcClose.close(transaction.internalConnection());
|
||||
}
|
||||
|
||||
// No matter the completion status of the transaction, we release the connection we got from the pool.
|
||||
JdbcClose.close(transaction.internalConnection());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -117,6 +117,10 @@ final class NoTransaction implements SpiTransaction {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deactivateExternal() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLogSql() {
|
||||
|
||||
@@ -47,7 +47,7 @@ module io.ebean.core {
|
||||
exports io.ebeanservice.docstore.api.support to io.ebean.elastic, io.ebean.test;
|
||||
exports io.ebeanservice.docstore.api.mapping to io.ebean.elastic;
|
||||
|
||||
exports io.ebeaninternal.api to io.ebean.ddl.generator, io.ebean.querybean, io.ebean.autotune, io.ebean.postgis, io.ebean.test, io.ebean.elastic, io.ebean.spring.txn;
|
||||
exports io.ebeaninternal.api to io.ebean.ddl.generator, io.ebean.querybean, io.ebean.autotune, io.ebean.postgis, io.ebean.test, io.ebean.elastic, io.ebean.spring.txn, io.ebean.postgis.types;
|
||||
exports io.ebeaninternal.api.json to io.ebean.test;
|
||||
exports io.ebeaninternal.json to io.ebean.test;
|
||||
exports io.ebeaninternal.server.autotune to io.ebean.autotune;
|
||||
@@ -69,15 +69,16 @@ module io.ebean.core {
|
||||
exports io.ebeaninternal.server.querydefn to io.ebean.autotune, io.ebean.querybean, io.ebean.test, io.ebean.elastic;
|
||||
exports io.ebeaninternal.server.rawsql to io.ebean.test;
|
||||
exports io.ebeaninternal.server.json to io.ebean.test, io.ebean.elastic;
|
||||
exports io.ebeaninternal.server.type to io.ebean.postgis, io.ebean.test;
|
||||
exports io.ebeaninternal.server.type to io.ebean.postgis, io.ebean.test, io.ebean.postgis.types;
|
||||
exports io.ebeaninternal.server.transaction to io.ebean.test, io.ebean.elastic, io.ebean.spring.txn, io.ebean.k8scache;
|
||||
exports io.ebeaninternal.server.util to io.ebean.querybean;
|
||||
|
||||
provides io.ebean.metric.MetricFactory with io.ebeaninternal.server.profile.DMetricFactory;
|
||||
provides io.ebean.service.SpiContainerFactory with io.ebeaninternal.server.DContainerFactory;
|
||||
provides io.ebean.service.SpiFetchGroupService with io.ebeaninternal.server.query.DFetchGroupService;
|
||||
provides io.ebean.service.SpiJsonService with io.ebeaninternal.json.DJsonService;
|
||||
provides io.ebean.service.SpiProfileLocationFactory with io.ebeaninternal.server.profile.DProfileLocationFactory;
|
||||
provides io.ebean.service.SpiRawSqlService with io.ebeaninternal.server.rawsql.DRawSqlService;
|
||||
provides io.ebean.service.BootstrapService with
|
||||
io.ebeaninternal.server.DContainerFactory,
|
||||
io.ebeaninternal.server.query.DFetchGroupService,
|
||||
io.ebeaninternal.server.profile.DProfileLocationFactory,
|
||||
io.ebeaninternal.server.rawsql.DRawSqlService,
|
||||
io.ebeaninternal.server.profile.DMetricFactory,
|
||||
io.ebeaninternal.json.DJsonService;
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user