Compare commits

..
Author SHA1 Message Date
rob bygrave 08d241d946 #1966 Remove sequence batching - postgres opps 2020-03-05 00:34:05 +13:00
rob bygrave 1c24ebf6dc Remove Sequence batching in favour of JPA increment 50
Also remove h2sqldb in favour of always using H2
2020-03-05 00:22:20 +13:00
5395 changed files with 132529 additions and 211773 deletions
+6
View File
@@ -1,3 +1,9 @@
GITHUB ISSUES ARE STRICTLY CONTROLLED FOR THIS PROJECT.
Refer to http://ebean-orm.github.io/support for the policies controlling the use of github issues.
Please post issues to the Ebean group https://groups.google.com/forum/#!forum/ebean first.
## Expected behavior
## Actual behavior
-40
View File
@@ -1,40 +0,0 @@
name: Build
on: [push, pull_request]
jobs:
build:
runs-on: ${{ matrix.os }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
java_version: [11]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v3
- name: Set up Java
uses: actions/setup-java@v3
with:
java-version: ${{ matrix.java_version }}
distribution: 'zulu'
- name: Maven cache
uses: actions/cache@v3
env:
cache-name: maven-cache
with:
path:
~/.m2
key: build-${{ env.cache-name }}
- name: Maven version
run: mvn --version
# - name: Maven single test
# run: mvn --batch-mode clean verify -Dtest="io.ebeaninternal.server.core.DefaultServer_getReferenceTest" -DfailIfNoTests=false
- name: Build with Maven
run: mvn -T 8 clean test
-38
View File
@@ -1,38 +0,0 @@
name: DB2 LUW
on:
workflow_dispatch:
schedule:
- cron: '10 8 * * 2,5'
jobs:
build:
runs-on: ${{ matrix.os }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
java_version: [11]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v3
- name: Set up Java
uses: actions/setup-java@v3
with:
java-version: ${{ matrix.java_version }}
distribution: 'adopt'
- name: Maven cache
uses: actions/cache@v3
env:
cache-name: maven-cache
with:
path:
~/.m2
key: build-${{ env.cache-name }}
- name: db2
run: mvn -T 8 clean test -Dprops.file=testconfig/ebean-db2.properties
-41
View File
@@ -1,41 +0,0 @@
name: H2Database
on:
workflow_dispatch:
schedule:
- cron: '10 1 * * *'
jobs:
build:
runs-on: ${{ matrix.os }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
java_version: [11]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v3
- name: Set up Java
uses: actions/setup-java@v3
with:
java-version: ${{ matrix.java_version }}
distribution: 'zulu'
- name: Maven cache
uses: actions/cache@v3
env:
cache-name: maven-cache
with:
path:
~/.m2
key: build-${{ env.cache-name }}
- name: Maven version
run: mvn --version
- name: H2Database
run: mvn -T 8 clean package
-41
View File
@@ -1,41 +0,0 @@
name: ebean EA
on:
workflow_dispatch:
schedule:
- cron: '39 6 * * 1,3,5'
jobs:
build:
runs-on: ${{ matrix.os }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
java_version: [GA,EA]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v3
- 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
env:
cache-name: maven-cache
with:
path:
~/.m2
key: build-${{ env.cache-name }}
- name: Maven version
run: mvn --version
- name: Build with Maven
run: mvn -T 8 test
-38
View File
@@ -1,38 +0,0 @@
name: MariaDB
on:
workflow_dispatch:
schedule:
- cron: '10 7 * * 1,4'
jobs:
build:
runs-on: ${{ matrix.os }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
java_version: [11]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v3
- name: Set up Java
uses: actions/setup-java@v3
with:
java-version: ${{ matrix.java_version }}
distribution: 'adopt'
- name: Maven cache
uses: actions/cache@v3
env:
cache-name: maven-cache
with:
path:
~/.m2
key: build-${{ env.cache-name }}
- name: mariadb 10.6
run: mvn -T 8 clean test -Dprops.file=testconfig/ebean-mariadb.properties
-51
View File
@@ -1,51 +0,0 @@
name: Multi-database platform
on: [workflow_dispatch]
jobs:
build:
runs-on: ${{ matrix.os }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
java_version: [11]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v3
- name: Set up Java
uses: actions/setup-java@v3
with:
java-version: ${{ matrix.java_version }}
distribution: 'adopt'
- name: Maven cache
uses: actions/cache@v3
env:
cache-name: maven-cache
with:
path:
~/.m2
key: build-${{ env.cache-name }}
- name: h2database
run: mvn clean test
- name: postgres
run: mvn clean test -Dprops.file=testconfig/ebean-postgres.properties
- name: mysql
run: mvn clean test -Dprops.file=testconfig/ebean-mysql.properties
- name: mariadb
run: mvn clean test -Dprops.file=testconfig/ebean-mariadb.properties
- name: yugabyte
run: mvn clean test -Dprops.file=testconfig/ebean-yugabyte.properties
- name: sqlserver
run: mvn clean test -Dprops.file=testconfig/ebean-sqlserver17.properties
# - name: sqlserver19
# run: mvn clean test -Dprops.file=testconfig/ebean-sqlserver19.properties
# - name: db2
# run: mvn clean test -Dprops.file=testconfig/ebean-db2.properties
# - name: oracle
# run: mvn clean test -Dprops.file=testconfig/ebean-oracle.properties
-39
View File
@@ -1,39 +0,0 @@
name: Multi-JDK Build
on:
workflow_dispatch:
schedule:
- cron: '30 6 * * *'
jobs:
build:
runs-on: ${{ matrix.os }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
java_version: [11, 17]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v3
- name: Set up Java
uses: actions/setup-java@v3
with:
java-version: ${{ matrix.java_version }}
distribution: 'zulu'
- name: Maven cache
uses: actions/cache@v3
env:
cache-name: maven-cache
with:
path:
~/.m2
key: build-${{ env.cache-name }}
- name: Build with Maven
run: mvn package
-38
View File
@@ -1,38 +0,0 @@
name: MySql
on:
workflow_dispatch:
schedule:
- cron: '20 6 * * *'
jobs:
build:
runs-on: ${{ matrix.os }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
java_version: [11]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v3
- name: Set up Java
uses: actions/setup-java@v3
with:
java-version: ${{ matrix.java_version }}
distribution: 'adopt'
- name: Maven cache
uses: actions/cache@v3
env:
cache-name: maven-cache
with:
path:
~/.m2
key: build-${{ env.cache-name }}
- name: mysql
run: mvn -T 8 clean test -Dprops.file=testconfig/ebean-mysql.properties
-38
View File
@@ -1,38 +0,0 @@
name: Oracle
on:
workflow_dispatch:
schedule:
- cron: '10 6 * * 1,4'
jobs:
build:
runs-on: ${{ matrix.os }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
java_version: [11]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v3
- name: Set up Java
uses: actions/setup-java@v3
with:
java-version: ${{ matrix.java_version }}
distribution: 'zulu'
- name: Maven cache
uses: actions/cache@v3
env:
cache-name: maven-cache
with:
path:
~/.m2
key: build-${{ env.cache-name }}
- name: oracle
run: mvn -T 8 clean test -Dprops.file=testconfig/ebean-oracle.properties
-38
View File
@@ -1,38 +0,0 @@
name: Postgres
on:
workflow_dispatch:
schedule:
- cron: '10 6 * * *'
jobs:
build:
runs-on: ${{ matrix.os }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
java_version: [11]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v3
- name: Set up Java
uses: actions/setup-java@v3
with:
java-version: ${{ matrix.java_version }}
distribution: 'adopt'
- name: Maven cache
uses: actions/cache@v3
env:
cache-name: maven-cache
with:
path:
~/.m2
key: build-${{ env.cache-name }}
- name: postgres
run: mvn -T 8 clean test -Dprops.file=testconfig/ebean-postgres.properties
-35
View File
@@ -1,35 +0,0 @@
name: SqlServer 2019
on: [workflow_dispatch]
jobs:
build:
runs-on: ${{ matrix.os }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
java_version: [11]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v3
- name: Set up Java
uses: actions/setup-java@v3
with:
java-version: ${{ matrix.java_version }}
distribution: 'adopt'
- name: Maven cache
uses: actions/cache@v3
env:
cache-name: maven-cache
with:
path:
~/.m2
key: build-${{ env.cache-name }}
- name: sqlserver 2019 latest
run: mvn clean test -Dprops.file=testconfig/ebean-sqlserver19.properties
-38
View File
@@ -1,38 +0,0 @@
name: SqlServer
on:
workflow_dispatch:
schedule:
- cron: '10 7 * * 2,5'
jobs:
build:
runs-on: ${{ matrix.os }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
java_version: [11]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v3
- name: Set up Java
uses: actions/setup-java@v3
with:
java-version: ${{ matrix.java_version }}
distribution: 'adopt'
- name: Maven cache
uses: actions/cache@v3
env:
cache-name: maven-cache
with:
path:
~/.m2
key: build-${{ env.cache-name }}
- name: sqlserver 2017
run: mvn -T 8 clean test -Dprops.file=testconfig/ebean-sqlserver17.properties
-38
View File
@@ -1,38 +0,0 @@
name: Yugabyte
on:
workflow_dispatch:
schedule:
- cron: '10 3 * * *'
jobs:
build:
runs-on: ${{ matrix.os }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
java_version: [11]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v3
- name: Set up Java
uses: actions/setup-java@v3
with:
java-version: ${{ matrix.java_version }}
distribution: 'adopt'
- name: Maven cache
uses: actions/cache@v3
env:
cache-name: maven-cache
with:
path:
~/.m2
key: build-${{ env.cache-name }}
- name: yugabyte
run: mvn clean test -Dprops.file=testconfig/ebean-yugabyte.properties
+4 -1
View File
@@ -1,4 +1,6 @@
*.autofetch
*create-all.sql
*drop-all.sql
*.orig
.classpath
.project
@@ -10,6 +12,7 @@ ebean-autotune.xml
ebean-profiling*.xml
/db
/mydb.db
!src/test/ddl-review/*.sql
profiling/
# Intellij project files
@@ -17,4 +20,4 @@ profiling/
*.ipr
*.iws
.idea/
*uuid.state
*uuid.state
+1 -1
View File
@@ -34,7 +34,7 @@ env:
install: true
script:
- mvn -T 1C clean test
- mvn clean test
after_failure:
- ./.travis/print_surefire_reports
+1 -8
View File
@@ -7,11 +7,4 @@ do
echo ${file}
cat ${file}
echo
done
for file in ebean-autotune/target/surefire-reports/*.txt
do
echo ${file}
cat ${file}
echo
done
done
+1 -1
View File
@@ -293,6 +293,6 @@ ebean.tenant.schemaProvider
ebean.updateAllPropertiesInBatch
ebean.updateChangesOnly
ebean.updatesDeleteMissingChildren
ebean.useValidationNotNull
ebean.useJavaxValidationNotNull
ebean.useJtaTransactionManager
-201
View File
@@ -1,201 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2012 Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+15
View File
@@ -0,0 +1,15 @@
EbeanORM
Copyright 2012 Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+10 -86
View File
@@ -1,55 +1,6 @@
[![Build](https://github.com/ebean-orm/ebean/actions/workflows/build.yml/badge.svg)](https://github.com/ebean-orm/ebean/actions/workflows/build.yml)
[![Build Status](https://travis-ci.org/ebean-orm/ebean.svg?branch=master)](https://travis-ci.org/ebean-orm/ebean)
[![Maven Central : ebean](https://maven-badges.herokuapp.com/maven-central/io.ebean/ebean/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.ebean/ebean)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/ebean-orm/ebean/blob/master/LICENSE)
[![Multi-JDK Build](https://github.com/ebean-orm/ebean/actions/workflows/multi-jdk-build.yml/badge.svg)](https://github.com/ebean-orm/ebean/actions/workflows/multi-jdk-build.yml)
##### Build with database platforms
[![H2Database](https://github.com/ebean-orm/ebean/actions/workflows/h2database.yml/badge.svg)](https://github.com/ebean-orm/ebean/actions/workflows/h2database.yml)
[![Postgres](https://github.com/ebean-orm/ebean/actions/workflows/postgres.yml/badge.svg)](https://github.com/ebean-orm/ebean/actions/workflows/postgres.yml)
[![MySql](https://github.com/ebean-orm/ebean/actions/workflows/mysql.yml/badge.svg)](https://github.com/ebean-orm/ebean/actions/workflows/mysql.yml)
[![MariaDB](https://github.com/ebean-orm/ebean/actions/workflows/mariadb.yml/badge.svg)](https://github.com/ebean-orm/ebean/actions/workflows/mariadb.yml)
[![Oracle](https://github.com/ebean-orm/ebean/actions/workflows/oracle.yml/badge.svg)](https://github.com/ebean-orm/ebean/actions/workflows/oracle.yml)
[![SqlServer](https://github.com/ebean-orm/ebean/actions/workflows/sqlserver.yml/badge.svg)](https://github.com/ebean-orm/ebean/actions/workflows/sqlserver.yml)
[![DB2 LUW](https://github.com/ebean-orm/ebean/actions/workflows/db2luw.yml/badge.svg)](https://github.com/ebean-orm/ebean/actions/workflows/db2luw.yml)
[![Yugabyte](https://github.com/ebean-orm/ebean/actions/workflows/yugabyte.yml/badge.svg)](https://github.com/ebean-orm/ebean/actions/workflows/yugabyte.yml)
##### Build with Java Early Access versions
[![ebean EA](https://github.com/ebean-orm/ebean/actions/workflows/jdk-ea.yml/badge.svg)](https://github.com/ebean-orm/ebean/actions/workflows/jdk-ea.yml)
[![datasource EA](https://github.com/ebean-orm/ebean-datasource/actions/workflows/jdk-ea.yml/badge.svg)](https://github.com/ebean-orm/ebean-datasource/actions/workflows/jdk-ea.yml)
[![migration EA](https://github.com/ebean-orm/ebean-migration/actions/workflows/jdk-ea.yml/badge.svg)](https://github.com/ebean-orm/ebean-migration/actions/workflows/jdk-ea.yml)
[![test-docker EA](https://github.com/ebean-orm/ebean-test-docker/actions/workflows/jdk-ea.yml/badge.svg)](https://github.com/ebean-orm/ebean-test-docker/actions/workflows/jdk-ea.yml)
[![ebean-agent EA](https://github.com/ebean-orm/ebean-agent/actions/workflows/jdk-ea.yml/badge.svg)](https://github.com/ebean-orm/ebean-agent/actions/workflows/jdk-ea.yml)
----------------------
# Ebean ORM for Java & Kotlin
**Multiple abstraction levels**: Ebean provides multiple levels of query abstraction [ORM Queries, mixed with SQL](https://ebean.io/docs/intro/queries/orm-query), [DTO Queries](https://ebean.io/docs/intro/queries/dto-query), [SqlQuery and JDBC](https://ebean.io/docs/intro/queries/sql-query).
Work at the highest level of abstraction and drop down levels as needed.
**Database migrations**: Built in [DB migration](https://ebean.io/docs/db-migrations/) generation and running. Support for "rebase" migrations as well as repeatable, init and 'normal' migrations.
**Awesome SQL**: Ebean produces SQL that you would hand craft yourself. Use great SQL, never generate SQL cartesian product, always honor relational limit/offset.
**Automated query tuning**: For ORM queries Ebean can profile the object graph being used and either [automatically tune the query](https://ebean.io/docs/query/background/autotune).
**Docker test containers**: [Docker test containers](https://ebean.io/docs/testing/) for all the supported databases. Get 100% test coverage on all the features of the database we use.
**Type safe queries**: We can build queries using type safe [query beans](https://ebean.io/docs/query/query-beans). IDE auto-complete when writing queries, compile time checking and it's FUN.
**Performance isn't optional**: Optimise queries to only fetch what we need (partial objects). Automatically avoid N+1 via a smart load context.
#### Benefits of ORM
* Automatically avoid N+1
* L2 caching to reduce database load
* Queries mixing database and L2 cache
* Automatically tune ORM queries
* Elasticsearch for search or L3 cache
----------------------
# Sponsors
<table>
<tbody>
@@ -78,45 +29,18 @@ Work at the highest level of abstraction and drop down levels as needed.
</tbody>
</table>
## Need help?
Post questions or issues to the [Ebean google group](https://groups.google.com/forum/#!forum/ebean)
or [github discussions](https://github.com/ebean-orm/ebean/discussions)
# Need help?
Post questions or issues to the Ebean google group - https://groups.google.com/forum/#!forum/ebean
## Documentation
# Documentation
Goto [https://ebean.io/docs/](https://ebean.io/docs/)
## Maven central
[Maven central - g:io.ebean](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22io.ebean%22%20)
## Building Ebean from source
- JDK 11 or higher installed
- Maven installed
- `git clone git@github.com:ebean-orm/ebean.git`
- `mvn clean install`
Ebean 13 uses Java modules with module-info. This means that there are stricter compilation
rules in place now than when building with classpath pre version 13.
For Maven Surefire testing we use `<surefire.useModulePath>false</surefire.useModulePath>` such
that tests run using classpath and not module-path. We are doing this until all the tooling
(Maven, IDE) improves in the area of testing with module-info.
#### Eclipse IDE
Right now we can't use Eclipse IDE to build Ebean and run its tests due to its poor support
for java modules. See [ebean/issues/2653](https://github.com/ebean-orm/ebean/issues/2653)
The current recommendation is to use IntelliJ IDEA as the IDE to build and hack Ebean.
#### IntelliJ IDEA
We want to get IntelliJ to run tests using classpath similar to Maven Surefire. To do this set:
`JUnit -> modify options -> Do not use module-path option`
To set this option as the global default for IntelliJ use:
`Run - Edit Configurations -> Edit configuration templates -> JUnit -> modify options - Do not use module-path option`
## Maven cental links:
[Maven central - ebean](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22io.ebean%22%20AND%20a%3A%22ebean%22 "maven central ebean")
[Maven central - all related projects](http://search.maven.org/#search%7Cga%7C1%7Cebean "maven central all related projects")
## Other versions
* [![Maven Central : ebean-agent](https://maven-badges.herokuapp.com/maven-central/io.ebean/ebean-agent/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.ebean/ebean-agent) - ebean-agent
* [![Maven Central : ebean-maven-plugin](https://maven-badges.herokuapp.com/maven-central/io.ebean/ebean-maven-plugin/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.ebean/ebean-maven-plugin) - ebean-maven-plugin
-48
View File
@@ -1,48 +0,0 @@
<?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>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
</parent>
<name>ebean-clickhouse</name>
<description>ebean-clickhouse composite</description>
<artifactId>ebean-clickhouse</artifactId>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-clickhouse</artifactId>
<version>13.17.0</version>
</dependency>
</dependencies>
</project>
@@ -1,7 +0,0 @@
package io.ebean.clickhouse.assembly;
/**
* Nothing interesting here - required placeholder for javadoc.
*/
public class Assembly {
}
@@ -1,9 +0,0 @@
module io.ebean.clickhouse {
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.clickhouse;
}
-48
View File
@@ -1,48 +0,0 @@
<?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>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
</parent>
<name>ebean-cockroach</name>
<description>ebean-cockroach composite</description>
<artifactId>ebean-cockroach</artifactId>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.17.0</version>
</dependency>
</dependencies>
</project>
@@ -1,7 +0,0 @@
package io.ebean.cockroach.assembly;
/**
* Nothing interesting here - required placeholder for javadoc.
*/
public class Assembly {
}
@@ -1,9 +0,0 @@
module io.ebean.cockroach {
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;
}
-48
View File
@@ -1,48 +0,0 @@
<?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>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
</parent>
<name>ebean-db2</name>
<description>ebean-db2 composite</description>
<artifactId>ebean-db2</artifactId>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-db2</artifactId>
<version>13.17.0</version>
</dependency>
</dependencies>
</project>
@@ -1,7 +0,0 @@
package io.ebean.db2.assembly;
/**
* Nothing interesting here - required placeholder for javadoc.
*/
public class Assembly {
}
@@ -1,9 +0,0 @@
module io.ebean.db2 {
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.db2;
}
-48
View File
@@ -1,48 +0,0 @@
<?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>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
</parent>
<name>ebean-h2</name>
<description>ebean-h2 composite</description>
<artifactId>ebean-h2</artifactId>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>13.17.0</version>
</dependency>
</dependencies>
</project>
@@ -1,7 +0,0 @@
package io.ebean.h2.assembly;
/**
* Nothing interesting here - required placeholder for javadoc.
*/
public class Assembly {
}
@@ -1,9 +0,0 @@
module io.ebean.h2 {
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.h2;
}
-48
View File
@@ -1,48 +0,0 @@
<?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>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
</parent>
<name>ebean-hana</name>
<description>ebean-hana composite</description>
<artifactId>ebean-hana</artifactId>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-hana</artifactId>
<version>13.17.0</version>
</dependency>
</dependencies>
</project>
@@ -1,7 +0,0 @@
package io.ebean.hana.assembly;
/**
* Nothing interesting here - required placeholder for javadoc.
*/
public class Assembly {
}
@@ -1,9 +0,0 @@
module io.ebean.hana {
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.hana;
}
-48
View File
@@ -1,48 +0,0 @@
<?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>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
</parent>
<name>ebean-mariadb</name>
<description>ebean-mariadb composite</description>
<artifactId>ebean-mariadb</artifactId>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-mariadb</artifactId>
<version>13.17.0</version>
</dependency>
</dependencies>
</project>
@@ -1,7 +0,0 @@
package io.ebean.mariadb.assembly;
/**
* Nothing interesting here - required placeholder for javadoc.
*/
public class Assembly {
}
@@ -1,9 +0,0 @@
module io.ebean.mariadb {
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.mariadb;
}
-48
View File
@@ -1,48 +0,0 @@
<?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>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
</parent>
<name>ebean-mysql</name>
<description>ebean-mysql composite</description>
<artifactId>ebean-mysql</artifactId>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-mysql</artifactId>
<version>13.17.0</version>
</dependency>
</dependencies>
</project>
@@ -1,7 +0,0 @@
package io.ebean.mysql.assembly;
/**
* Nothing interesting here - required placeholder for javadoc.
*/
public class Assembly {
}
@@ -1,9 +0,0 @@
module io.ebean.mysql {
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.mysql;
}
-48
View File
@@ -1,48 +0,0 @@
<?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>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
</parent>
<name>ebean-nuodb</name>
<description>ebean-nuodb composite</description>
<artifactId>ebean-nuodb</artifactId>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-nuodb</artifactId>
<version>13.17.0</version>
</dependency>
</dependencies>
</project>
@@ -1,7 +0,0 @@
package io.ebean.nuodb.assembly;
/**
* Nothing interesting here - required placeholder for javadoc.
*/
public class Assembly {
}
@@ -1,9 +0,0 @@
module io.ebean.nuodb {
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.nuodb;
}
-48
View File
@@ -1,48 +0,0 @@
<?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>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
</parent>
<name>ebean-oracle</name>
<description>ebean-oracle composite</description>
<artifactId>ebean-oracle</artifactId>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-oracle</artifactId>
<version>13.17.0</version>
</dependency>
</dependencies>
</project>
@@ -1,7 +0,0 @@
package io.ebean.oracle.assembly;
/**
* Nothing interesting here - required placeholder for javadoc.
*/
public class Assembly {
}
@@ -1,9 +0,0 @@
module io.ebean.oracle {
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.oracle;
}
-48
View File
@@ -1,48 +0,0 @@
<?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>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
</parent>
<name>ebean-postgres</name>
<description>ebean-postgres composite</description>
<artifactId>ebean-postgres</artifactId>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.17.0</version>
</dependency>
</dependencies>
</project>
@@ -1,7 +0,0 @@
package io.ebean.postgres.assembly;
/**
* Nothing interesting here - required placeholder for javadoc.
*/
public class Assembly {
}
@@ -1,9 +0,0 @@
module io.ebean.postgres {
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;
}
-48
View File
@@ -1,48 +0,0 @@
<?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>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
</parent>
<name>ebean-sqlite</name>
<description>ebean-sqlite composite</description>
<artifactId>ebean-sqlite</artifactId>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlite</artifactId>
<version>13.17.0</version>
</dependency>
</dependencies>
</project>
@@ -1,7 +0,0 @@
package io.ebean.sqlite.assembly;
/**
* Nothing interesting here - required placeholder for javadoc.
*/
public class Assembly {
}
@@ -1,9 +0,0 @@
module io.ebean.sqlite {
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.sqlite;
}
-48
View File
@@ -1,48 +0,0 @@
<?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>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
</parent>
<name>ebean-sqlserver</name>
<description>ebean-sqlserver composite</description>
<artifactId>ebean-sqlserver</artifactId>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlserver</artifactId>
<version>13.17.0</version>
</dependency>
</dependencies>
</project>
@@ -1,7 +0,0 @@
package io.ebean.sqlserver.assembly;
/**
* Nothing interesting here - required placeholder for javadoc.
*/
public class Assembly {
}
@@ -1,9 +0,0 @@
module io.ebean.sqlserver {
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.sqlserver;
}
-48
View File
@@ -1,48 +0,0 @@
<?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>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
</parent>
<name>ebean-yugabyte</name>
<description>ebean-yugabyte composite</description>
<artifactId>ebean-yugabyte</artifactId>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.17.0</version>
</dependency>
</dependencies>
</project>
@@ -1,7 +0,0 @@
package io.ebean.yugabyte.assembly;
/**
* Nothing interesting here - required placeholder for javadoc.
*/
public class Assembly {
}
@@ -1,9 +0,0 @@
module io.ebean.yugabyte {
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;
}
-66
View File
@@ -1,66 +0,0 @@
<?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>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
</parent>
<name>ebean (all platforms)</name>
<description>composite of common runtime dependencies for all platforms</description>
<artifactId>ebean</artifactId>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-joda-time</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-jsonnode</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-mapper</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.17.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-all</artifactId>
<version>13.17.0</version>
</dependency>
</dependencies>
</project>
@@ -1,7 +0,0 @@
package io.ebean.assembly;
/**
* Nothing interesting here - look at ebean-api.
*/
public class Assembly {
}
@@ -1,8 +0,0 @@
module io.ebean {
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.all;
}
-32
View File
@@ -1,32 +0,0 @@
<?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>13.17.0</version>
</parent>
<artifactId>composites</artifactId>
<packaging>pom</packaging>
<modules>
<module>ebean</module>
<module>ebean-clickhouse</module>
<module>ebean-cockroach</module>
<module>ebean-db2</module>
<module>ebean-h2</module>
<module>ebean-hana</module>
<!-- <module>hsqldb</module>-->
<module>ebean-mariadb</module>
<module>ebean-mysql</module>
<module>ebean-nuodb</module>
<module>ebean-oracle</module>
<module>ebean-postgres</module>
<!-- <module>sqlanywhere</module>-->
<module>ebean-sqlite</module>
<module>ebean-sqlserver</module>
<module>ebean-yugabyte</module>
</modules>
</project>
-138
View File
@@ -1,138 +0,0 @@
<?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>13.17.0</version>
</parent>
<name>ebean api</name>
<description>ebean api</description>
<artifactId>ebean-api</artifactId>
<dependencies>
<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-applog</artifactId>
<version>1.0</version>
</dependency>
<!-- exclude avaje-applog-slf4j to direct logging to something else -->
<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-applog-slf4j</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-config</artifactId>
<version>2.4</version>
</dependency>
<!--
Class retention Nonnull and Nullable annotations
to assist with IDE auto-completion with Ebean API
-->
<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-lang</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>persistence-api</artifactId>
<version>${ebean-persistence-api.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-annotation</artifactId>
<version>${ebean-annotation.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-types</artifactId>
<version>${ebean-types.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource-api</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<!-- Support MdcBackgroundExecutorWrapper -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.36</version>
<optional>true</optional>
</dependency>
<!-- Jackson core used internally by Ebean -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
<optional>true</optional>
</dependency>
<!-- provided scope for JsonNode support -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
<optional>true</optional>
</dependency>
<!-- JAVAX-DEPENDENCY-START -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<optional>true</optional>
</dependency>
<!-- JAVAX-DEPENDENCY-END -->
<!-- JAKARTA-DEPENDENCY-START ___
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.0.0</version>
<optional>true</optional>
</dependency>
____ JAKARTA-DEPENDENCY-END -->
<dependency>
<groupId>io.avaje</groupId>
<artifactId>junit</artifactId>
<version>1.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/ebean-maven-version.txt</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<excludes>
<exclude>**/ebean-maven-version.txt</exclude>
</excludes>
</resource>
</resources>
</build>
</project>
@@ -1,92 +0,0 @@
package io.ebean;
import io.avaje.lang.NonNullApi;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
/**
* Background executor service for executing of tasks asynchronously.
* <p>
* This service can be used to execute tasks in the background.
* <p>
* This service is managed by Ebean and will perform a clean shutdown
* waiting for background tasks to complete with a default 30 second
* timeout. Shutdown occurs prior to DataSource shutdown.
* <p>
* This also propagates MDC context from the current thread to the
* background task if defined.
*/
@NonNullApi
public interface BackgroundExecutor {
/**
* Execute a callable task in the background returning the Future.
*/
<T> Future<T> submit(Callable<T> task);
/**
* Execute a runnable task in the background returning the Future.
*/
Future<?> submit(Runnable task);
/**
* Execute a task in the background. Effectively the same as
* {@link BackgroundExecutor#submit(Runnable)} but returns void.
*/
void execute(Runnable task);
/**
* Execute a task periodically with a given delay.
*
* @param task the task to execute
* @param initialDelay the time to delay first execution
* @param delay the delay between the termination of one
* execution and the commencement of the next
* @param unit the time unit of the initialDelay and delay parameters
* @return a ScheduledFuture representing pending completion of
* the series of repeated tasks. The future's {@link
* Future#get() get()} method will never return normally,
* and will throw an exception upon task cancellation or
* abnormal termination of a task execution.
*/
ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, long initialDelay, long delay, TimeUnit unit);
/**
* Execute a task periodically with a given period.
*
* <p>If any execution of this task takes longer than its period, then
* subsequent executions may start late, but will not concurrently
* execute.
*
* @param task the task to execute
* @param initialDelay the time to delay first execution
* @param period the period between successive executions
* @param unit the time unit of the initialDelay and period parameters
* @return a ScheduledFuture representing pending completion of
* the series of repeated tasks. The future's {@link
* Future#get() get()} method will never return normally,
* and will throw an exception upon task cancellation or
* abnormal termination of a task execution.
*/
ScheduledFuture<?> scheduleAtFixedRate(Runnable task, long initialDelay, long period, TimeUnit unit);
/**
* Schedules a Runnable for one-shot action that becomes enabled after the given delay.
*
* @return a ScheduledFuture representing pending completion of the task and
* whose get() method will return null upon completion
*/
ScheduledFuture<?> schedule(Runnable task, long delay, TimeUnit unit);
/**
* Schedules a Callable for one-shot action that becomes enabled after the given delay.
*
* @return a ScheduledFuture that can be used to extract result or cancel
*/
<V> ScheduledFuture<V> schedule(Callable<V> task, long delay, TimeUnit unit);
}
@@ -1,19 +0,0 @@
package io.ebean;
/**
* Defines a cancelable query.
* <p>
* Typically holds a representation of the PreparedStatement to perform the
* actual cancel.
* </p>
*/
public interface CancelableQuery {
/**
* Cancel the query.
* <p>
* For JDBC this translates to calling cancel on the PreparedStatement.
* </p>
*/
void cancel();
}
@@ -1,170 +0,0 @@
package io.ebean;
import io.ebean.config.ContainerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebean.service.SpiContainer;
import io.ebean.service.SpiContainerFactory;
import javax.persistence.PersistenceException;
import java.util.Iterator;
import java.util.Properties;
import java.util.ServiceLoader;
import java.util.concurrent.locks.ReentrantLock;
/**
* Creates Database instances.
* <p>
* This uses either DatabaseConfig or properties in the application.properties file to
* configure and create a Database instance.
* <p>
* The Database instance can either be registered with the DB singleton or
* not. The DB singleton effectively holds a map of Database by a name.
* If the Database is registered with the DB singleton you can retrieve it
* later via {@link DB#byName(String)}.
* <p>
* One Database can be nominated as the 'default/primary' Database. Many
* methods on the DB singleton such as {@link DB#find(Class)} are just a
* convenient way of using the 'default/primary' Database.
*/
public final class DatabaseFactory {
private static final ReentrantLock lock = new ReentrantLock();
private static SpiContainer container;
private static String defaultServerName;
static {
EbeanVersion.getVersion();
}
/**
* Initialise the container with clustering configuration.
* <p>
* Call this prior to creating any Database instances or alternatively set the
* ContainerConfig on the DatabaseConfig when creating the first Database instance.
*/
public static void initialiseContainer(ContainerConfig containerConfig) {
lock.lock();
try {
container(containerConfig);
} finally {
lock.unlock();
}
}
/**
* Create using properties to configure the database.
*/
public static Database create(String name) {
lock.lock();
try {
return container(null).createServer(name);
} finally {
lock.unlock();
}
}
/**
* Create using the DatabaseConfig object to configure the database.
*
* <pre>{@code
*
* DatabaseConfig config = new DatabaseConfig();
* config.setName("db");
* config.loadProperties();
*
* Database database = DatabaseFactory.create(config);
*
* }</pre>
*/
public static Database create(DatabaseConfig config) {
lock.lock();
try {
if (config.getName() == null) {
throw new PersistenceException("The name is null (it is required)");
}
Database server = createInternal(config);
if (config.isRegister()) {
if (config.isDefaultServer()) {
if (defaultServerName != null && !defaultServerName.equals(config.getName())) {
throw new IllegalStateException("Registering [" + config.getName() + "] as the default server but [" + defaultServerName + "] is already registered as the default");
}
defaultServerName = config.getName();
}
DbPrimary.setSkip(true);
DbContext.getInstance().register(server, config.isDefaultServer());
}
return server;
} finally {
lock.unlock();
}
}
/**
* Create using the DatabaseConfig additionally specifying a classLoader to use as the context class loader.
*/
public static Database createWithContextClassLoader(DatabaseConfig config, ClassLoader classLoader) {
lock.lock();
try {
ClassLoader currentContextLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(classLoader);
try {
return DatabaseFactory.create(config);
} finally {
// set the currentContextLoader back
Thread.currentThread().setContextClassLoader(currentContextLoader);
}
} finally {
lock.unlock();
}
}
/**
* Shutdown gracefully all Database instances cleaning up any resources as required.
* <p>
* This is typically invoked via JVM shutdown hook and not explicitly called.
*/
public static void shutdown() {
lock.lock();
try {
container.shutdown();
} finally {
lock.unlock();
}
}
private static Database createInternal(DatabaseConfig config) {
return container(config.getContainerConfig()).createServer(config);
}
/**
* Return the SpiContainer initialising it if necessary.
*
* @param containerConfig the configuration controlling clustering communication
*/
private static SpiContainer container(ContainerConfig containerConfig) {
// thread safe in that all calling methods hold lock
if (container != null) {
return container;
}
if (containerConfig == null) {
// effectively load configuration from ebean.properties
Properties properties = DbPrimary.getProperties();
containerConfig = new ContainerConfig();
containerConfig.loadFromProperties(properties);
}
container = createContainer(containerConfig);
return container;
}
/**
* Create the container instance using the configuration.
*/
protected static SpiContainer createContainer(ContainerConfig containerConfig) {
Iterator<SpiContainerFactory> factories = ServiceLoader.load(SpiContainerFactory.class).iterator();
if (factories.hasNext()) {
return factories.next().create(containerConfig);
}
throw new IllegalStateException("Service loader didn't find a SpiContainerFactory?");
}
}
@@ -1,132 +0,0 @@
package io.ebean;
import io.ebean.config.BeanNotEnhancedException;
import io.ebean.datasource.DataSourceConfigurationException;
import javax.persistence.PersistenceException;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;
import static java.lang.System.Logger.Level.ERROR;
/**
* Holds Database instances.
*/
final class DbContext {
private static final System.Logger log = EbeanVersion.log;
static {
EbeanVersion.getVersion();
}
private static final DbContext INSTANCE = new DbContext();
private final ConcurrentHashMap<String, Database> concMap = new ConcurrentHashMap<>();
private final HashMap<String, Database> syncMap = new HashMap<>();
private final ReentrantLock lock = new ReentrantLock();
private Database defaultDatabase;
private DbContext() {
try {
if (!DbPrimary.isSkip()) {
// look to see if there is a default server defined
String defaultName = DbPrimary.getDefaultServerName();
if (defaultName != null && !defaultName.trim().isEmpty()) {
defaultDatabase = getWithCreate(defaultName.trim());
}
}
} catch (BeanNotEnhancedException e) {
throw e;
} catch (DataSourceConfigurationException e) {
String msg = "Configuration error creating DataSource for the default Database." +
" This typically means a missing application-test.yaml or missing ebean-test dependency." +
" See https://ebean.io/docs/trouble-shooting#datasource";
throw new DataSourceConfigurationException(msg, e);
} catch (Throwable e) {
log.log(ERROR, "Error trying to create the default Database", e);
throw new RuntimeException(e);
}
}
/**
* Return the shared singleton instance.
*/
static DbContext getInstance() {
return INSTANCE;
}
/**
* Return the default database.
*/
Database getDefault() {
if (defaultDatabase == null) {
String msg = "The default Database has not been defined?"
+ " This is normally set via the ebean.datasource.default property."
+ " Otherwise it should be registered programmatically via registerServer()";
throw new PersistenceException(msg);
}
return defaultDatabase;
}
/**
* Return the database by name.
*/
Database get(String name) {
if (name == null || name.isEmpty()) {
return defaultDatabase;
}
Database server = concMap.get(name);
if (server != null) {
return server;
}
return getWithCreate(name);
}
/**
* Read, create and put of Databases.
*/
private Database getWithCreate(String name) {
lock.lock();
try {
Database server = syncMap.get(name);
if (server == null) {
// register when creating server this way
server = DatabaseFactory.create(name);
register(server, false);
}
return server;
} finally {
lock.unlock();
}
}
/**
* Register a server so we can get it by its name.
*/
void register(Database server, boolean isDefault) {
registerWithName(server.name(), server, isDefault);
}
private void registerWithName(String name, Database server, boolean isDefault) {
lock.lock();
try {
concMap.put(name, server);
syncMap.put(name, server);
if (isDefault) {
defaultDatabase = server;
}
} finally {
lock.unlock();
}
}
Database mock(String name, Database server, boolean defaultServer) {
Database originalPrimaryServer = this.defaultDatabase;
registerWithName(name, server, defaultServer);
return originalPrimaryServer;
}
}
@@ -1,96 +0,0 @@
package io.ebean;
import io.avaje.config.Config;
import java.util.Properties;
import java.util.concurrent.locks.ReentrantLock;
/**
* Provides singleton state for the default database.
* <p/>
* Intended for internal use as part of bootup, construction, registration of the default database.
*/
final class DbPrimary {
private static final ReentrantLock lock = new ReentrantLock();
private static String defaultServerName;
private static boolean skip;
/**
* Set whether to skip automatically creating the primary database.
*/
static void setSkip(boolean skip) {
lock.lock();
try {
DbPrimary.skip = skip;
} finally {
lock.unlock();
}
}
/**
* Return true to skip automatically creating the primary database.
*/
static boolean isSkip() {
lock.lock();
try {
return skip;
} finally {
lock.unlock();
}
}
/**
* Return the default database name.
*/
static String getDefaultServerName() {
lock.lock();
try {
getProperties();
return defaultServerName;
} finally {
lock.unlock();
}
}
/**
* Return the default configuration Properties.
*/
static Properties getProperties() {
lock.lock();
try {
if (defaultServerName == null) {
defaultServerName = determineDefaultServerName();
}
return Config.asProperties();
} finally {
lock.unlock();
}
}
/**
* Determine and return the default server name checking system environment variables and then global properties.
*/
private static String determineDefaultServerName() {
String defaultServerName = System.getenv("EBEAN_DB");
defaultServerName = System.getProperty("db", defaultServerName);
defaultServerName = System.getProperty("ebean_db", defaultServerName);
if (isEmpty(defaultServerName)) {
defaultServerName = Config.getOptional("datasource.default").orElse(null);
if (isEmpty(defaultServerName)) {
defaultServerName = Config.getOptional("ebean.default.datasource").orElse(null);
}
}
if (defaultServerName == null) {
defaultServerName = "db";
}
return defaultServerName;
}
/**
* Return true if the string is null or empty.
*/
private static boolean isEmpty(String value) {
return value == null || value.trim().isEmpty();
}
}
@@ -1,208 +0,0 @@
package io.ebean;
import io.avaje.lang.NonNullApi;
import io.avaje.lang.Nullable;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Stream;
/**
* Query for performing native SQL queries that return DTO Bean's.
* <p>
* These beans are just normal classes. They must have public constructors
* and setters.
* <p>
* Constructors with arguments are used if the number of constructor arguments
* matches the number of columns in the resultSet.
* </p>
* <p>
* If the number of columns in the resultSet is greater than the largest constructor
* then the largest constructor is used for the first columns and remaining columns
* are mapped by setter methods.
* </p>
*
* <pre>{@code
*
* // CustomerDto is just a 'bean like' class
* // with public constructor(s) and public setter methods
*
* String sql = "select id, name from customer where name like :name and status_code = :status";
*
* List<CustomerDto> beans =
* DB.findDto(CustomerDto.class, sql)
* .setParameter("name", "Acme%")
* .setParameter("status", "ACTIVE")
* .findList();
*
* }</pre>
*/
@NonNullApi
public interface DtoQuery<T> extends CancelableQuery {
/**
* Execute the query returning a list.
*/
List<T> findList();
/**
* Execute the query iterating a row at a time.
* <p>
* Note that the QueryIterator holds resources related to the underlying
* resultSet and potentially connection and MUST be closed. We should use
* QueryIterator in a <em>try with resource block</em>.
*/
QueryIterator<T> findIterate();
/**
* Execute the query returning a Stream.
* <p>
* Note that the Stream holds resources related to the underlying
* resultSet and potentially connection and MUST be closed. We should use
* the Stream in a <em>try with resource block</em>.
*/
Stream<T> findStream();
/**
* Execute the query iterating a row at a time.
* <p>
* This streaming type query is useful for large query execution as only 1 row needs to be held in memory.
* </p>
*/
void findEach(Consumer<T> consumer);
/**
* Execute the query iterating the results and batching them for the consumer.
* <p>
* This runs like findEach streaming results from the database but just collects the results
* into batches to pass to the consumer.
*
* @param batch The number of dto beans to collect before given them to the consumer
* @param consumer The consumer to process the batch of DTO beans
*/
void findEach(int batch, Consumer<List<T>> consumer);
/**
* Execute the query iterating a row at a time with the ability to stop consuming part way through.
* <p>
* Returning false after processing a row stops the iteration through the query results.
* </p>
* <p>
* This streaming type query is useful for large query execution as only 1 row needs to be held in memory.
* </p>
*/
void findEachWhile(Predicate<T> consumer);
/**
* Execute the query returning a single bean.
*/
@Nullable
T findOne();
/**
* Execute the query returning an optional bean.
*/
Optional<T> findOneOrEmpty();
/**
* Bind all the parameters using index positions.
* <p>
* Binds each parameter moving the index position each time.
* <p>
* A convenience for multiple calls to {@link #setParameter(Object)}
*/
DtoQuery<T> setParameters(Object... value);
/**
* Bind the next parameter using index position.
* <p>
* Bind the parameter using index position starting at 1 and incrementing.
* <p>
*/
DtoQuery<T> setParameter(Object value);
/**
* Bind the named parameter.
*/
DtoQuery<T> setParameter(String name, Object value);
/**
* Bind the named parameter to SQL NULL.
*/
DtoQuery<T> setNullParameter(String name, int jdbcType);
/**
* Bind the named multi-value array parameter which we would use with Postgres ANY.
* <p>
* For Postgres this binds an ARRAY rather than expands into multiple bind values.
*/
DtoQuery<T> setArrayParameter(String name, Collection<?> values);
/**
* Bind the parameter by its index position (1 based like JDBC).
*/
DtoQuery<T> setParameter(int position, Object value);
/**
* Set a positioned parameter to SQL NULL.
*/
DtoQuery<T> setNullParameter(int position, int jdbcType);
/**
* Set the index of the first row of the results to return.
*/
DtoQuery<T> setFirstRow(int firstRow);
/**
* Set the maximum number of query results to return.
*/
DtoQuery<T> setMaxRows(int maxRows);
/**
* When resultSet columns are not able to be mapped to a bean property then instead of
* throwing effectively skip reading that column.
*/
DtoQuery<T> setRelaxedMode();
/**
* Set a label on the query to make it easier to identify queries related to query execution statistics.
*
* @param label A label that is unique to the DTO bean type.
*/
DtoQuery<T> setLabel(String label);
/**
* Set the profile location of this query. This is used to relate query execution metrics
* back to a location like a specific line of code.
*/
DtoQuery<T> setProfileLocation(ProfileLocation profileLocation);
/**
* Set a timeout on this query.
* <p>
* This will typically result in a call to setQueryTimeout() on a
* preparedStatement. If the timeout occurs an exception will be thrown - this
* will be a SQLException wrapped up in a PersistenceException.
* </p>
*
* @param secs the query timeout limit in seconds. Zero means there is no limit.
*/
DtoQuery<T> setTimeout(int secs);
/**
* A hint which for JDBC translates to the Statement.fetchSize().
* <p>
* Gives the JDBC driver a hint as to the number of rows that should be
* fetched from the database when more rows are needed for ResultSet.
* </p>
*/
DtoQuery<T> setBufferFetchSizeHint(int bufferFetchSizeHint);
/**
* Use the explicit transaction to execute the query.
*/
DtoQuery<T> usingTransaction(Transaction transaction);
}
@@ -1,37 +0,0 @@
package io.ebean;
/**
* Thrown when a duplicate is attempted on a unique constraint.
* <p>
* In terms of catching this exception with the view of continuing processing
* using the same transaction look to use {@link Transaction#rollbackAndContinue()}.
*
* <pre>{@code
*
* try (Transaction txn = database.beginTransaction()) {
*
* try {
* ...
* database.save(bean);
* database.flush();
* } catch (DuplicateKeyException e) {
* // carry on processing using the transaction
* txn.rollbackAndContinue();
* ...
* }
*
* txn.commit();
* }
*
* }</pre>
*/
public class DuplicateKeyException extends DataIntegrityException {
private static final long serialVersionUID = -4771932723285724817L;
/**
* Create with a message and cause.
*/
public DuplicateKeyException(String message, Throwable cause) {
super(message, cause);
}
}
@@ -1,103 +0,0 @@
package io.ebean;
import io.avaje.applog.AppLog;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.Properties;
import static java.lang.System.Logger.Level.*;
/**
* Class to determine the ebean version.
*
* @author Roland Praml, FOCONIS AG
*/
public final class EbeanVersion {
public static final System.Logger log = AppLog.getLogger("io.ebean");
/**
* Maintain the minimum ebean-agent version manually based on required ebean-agent bug fixes.
*/
private static final int MIN_AGENT_MAJOR_VERSION = 12;
private static final int MIN_AGENT_MINOR_VERSION = 12;
private static String version = "unknown";
static {
readVersion();
checkAgentVersion();
}
private static void readVersion() {
try {
try (InputStream in = ClassLoader.getSystemResourceAsStream("META-INF/ebean-maven-version.txt")) {
if (in != null) {
try (LineNumberReader reader = new LineNumberReader(new InputStreamReader(in))) {
version = reader.readLine();
log.log(INFO, "ebean version: {0}", version);
}
}
}
} catch (IOException e) {
log.log(WARNING, "Could not determine ebean version: {0}", e.getMessage());
}
}
private static void checkAgentVersion() {
try {
try (InputStream in = ClassLoader.getSystemResourceAsStream("META-INF/maven/io.ebean/ebean-agent/pom.properties")) {
// often we only have ebean-agent during development (with build time enhancement), null is expected
if (in != null) {
String agentVersion = readVersion(in);
if (agentVersion != null) {
if (checkMinAgentVersion(agentVersion)) {
log.log(ERROR, "Expected minimum ebean-agent version {0}.{1}.0 but we have {2}, please update the ebean-agent", MIN_AGENT_MAJOR_VERSION, MIN_AGENT_MINOR_VERSION, agentVersion);
}
}
}
}
} catch (IOException e) {
log.log(WARNING, "Could not check minimum ebean-agent version {0}.{1}.0 required due to - {2}", MIN_AGENT_MAJOR_VERSION, MIN_AGENT_MINOR_VERSION, e.getMessage());
}
}
/**
* Return true if ebean-agent is NOT at our minimum version.
*/
static boolean checkMinAgentVersion(String agentVersion) {
String[] versionSegments = agentVersion.split("\\.");
if (versionSegments.length != 3) {
return true;
} else {
int major = Integer.parseInt(versionSegments[0]);
int minor = Integer.parseInt(versionSegments[1]);
if (major < MIN_AGENT_MAJOR_VERSION) {
return true;
} else {
return major == MIN_AGENT_MAJOR_VERSION && minor < MIN_AGENT_MINOR_VERSION;
}
}
}
private static String readVersion(InputStream in) throws IOException {
Properties prop = new Properties();
prop.load(in);
in.close();
return prop.getProperty("version");
}
private EbeanVersion() {
// hide
}
/**
* Returns the ebean version (read from META-INF/ebean-maven-version.txt)
*/
public static String getVersion() {
return version;
}
}
@@ -1,196 +0,0 @@
package io.ebean;
import io.avaje.lang.Nullable;
import java.time.Clock;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Stream;
/**
* The extended API for Database.
* <p>
* Deprecated in favour of using {@link Query#usingTransaction(Transaction)} instead.
* <p>
* This provides the finder methods that take an explicit transaction rather than obtaining
* the transaction from the usual mechanism (which is ThreadLocal based).
* <p>
* Note that in all cases the transaction supplied can be null and in this case the Database
* will use the normal mechanism to obtain the transaction to use.
*/
public interface ExtendedServer {
/**
* Deprecated but no yet determined suitable replacement (to support testing only change of clock).
* <p>
* Set the Clock to use for <code>@WhenCreated</code> and <code>@WhenModified</code>.
* <p>
* Note that we only expect to change the Clock for testing purposes.
* </p>
*/
@Deprecated
void setClock(Clock clock);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
@Deprecated
<T> boolean exists(Query<T> ormQuery, Transaction transaction);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
@Deprecated
<T> int findCount(Query<T> query, Transaction transaction);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
@Deprecated
<A, T> List<A> findIds(Query<T> query, Transaction transaction);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
@Deprecated
<T> QueryIterator<T> findIterate(Query<T> query, Transaction transaction);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
@Deprecated
<T> Stream<T> findStream(Query<T> query, Transaction transaction);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
@Deprecated
<T> void findEach(Query<T> query, Consumer<T> consumer, Transaction transaction);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
@Deprecated
<T> void findEach(Query<T> query, int batch, Consumer<List<T>> consumer, Transaction t);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
@Deprecated
<T> void findEachWhile(Query<T> query, Predicate<T> consumer, Transaction transaction);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
@Deprecated
<T> List<Version<T>> findVersions(Query<T> query, Transaction transaction);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
@Deprecated
<T> List<T> findList(Query<T> query, Transaction transaction);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
@Deprecated
<T> FutureRowCount<T> findFutureCount(Query<T> query, Transaction transaction);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
@Deprecated
<T> FutureIds<T> findFutureIds(Query<T> query, Transaction transaction);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
@Deprecated
<T> FutureList<T> findFutureList(Query<T> query, Transaction transaction);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
@Deprecated
<T> PagedList<T> findPagedList(Query<T> query, Transaction transaction);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
@Deprecated
<T> Set<T> findSet(Query<T> query, Transaction transaction);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
@Deprecated
<K, T> Map<K, T> findMap(Query<T> query, Transaction transaction);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
@Deprecated
<A, T> List<A> findSingleAttributeList(Query<T> query, Transaction transaction);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
@Deprecated
<A, T> Set<A> findSingleAttributeSet(Query<T> query, Transaction transaction);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
@Deprecated
@Nullable
<T> T findOne(Query<T> query, Transaction transaction);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
@Deprecated
<T> Optional<T> findOneOrEmpty(Query<T> query, Transaction transaction);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
@Deprecated
<T> int delete(Query<T> query, Transaction transaction);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
@Deprecated
<T> int update(Query<T> query, Transaction transaction);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
@Deprecated
List<SqlRow> findList(SqlQuery query, Transaction transaction);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
@Deprecated
void findEach(SqlQuery query, Consumer<SqlRow> consumer, Transaction transaction);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
@Deprecated
void findEachWhile(SqlQuery query, Predicate<SqlRow> consumer, Transaction transaction);
/**
* Deprecated migrate to using {@link SqlQuery#usingTransaction(Transaction)}.
*/
@Deprecated
@Nullable
SqlRow findOne(SqlQuery query, Transaction transaction);
}
@@ -1,139 +0,0 @@
package io.ebean;
import java.io.Serializable;
/**
* Defines how a relationship is fetched via either normal SQL join,
* a eager secondary query, via lazy loading or via eagerly hitting L2 cache.
* <p>
* <pre>{@code
* // Normal fetch join results in a single SQL query
* List<Order> list = DB.find(Order.class).fetch("details").findList();
*
* }</pre>
* <p>
* Example: Using a "query join" instead of a "fetch join" we instead use 2 SQL queries
*
* <pre>{@code
*
* // This will use 2 SQL queries to build this object graph
* List<Order> list =
* DB.find(Order.class)
* .fetch("details", FetchConfig.ofQuery())
* .findList();
*
* // query 1) find order
* // query 2) find orderDetails where order.id in (?,?...) // first 100 order id's
*
* }</pre>
*/
public final class FetchConfig implements Serializable {
private static final long serialVersionUID = 1L;
private static final int JOIN_MODE = 0;
private static final int QUERY_MODE = 1;
private static final int LAZY_MODE = 2;
private static final int CACHE_MODE = 3;
private final int mode;
private final int batchSize;
private final int hashCode;
private FetchConfig(int mode, int batchSize) {
this.mode = mode;
this.batchSize = batchSize;
this.hashCode = mode + 10 * batchSize;
}
/**
* Return FetchConfig to eagerly fetch the relationship using L2 cache.
* <p>
* Any cache misses will be loaded by secondary query to the database.
*/
public static FetchConfig ofCache() {
return new FetchConfig(CACHE_MODE, 100);
}
/**
* Return FetchConfig to eagerly fetch the relationship using a secondary query.
*/
public static FetchConfig ofQuery() {
return new FetchConfig(QUERY_MODE, 100);
}
/**
* Return FetchConfig to eagerly fetch the relationship using a secondary with a given batch size.
*/
public static FetchConfig ofQuery(int batchSize) {
return new FetchConfig(QUERY_MODE, batchSize);
}
/**
* Return FetchConfig to lazily load the relationship.
*/
public static FetchConfig ofLazy() {
return new FetchConfig(LAZY_MODE, 0);
}
/**
* Return FetchConfig to lazily load the relationship specifying the batch size.
*/
public static FetchConfig ofLazy(int batchSize) {
return new FetchConfig(LAZY_MODE, batchSize);
}
/**
* Return FetchConfig to fetch the relationship using SQL join.
*/
public static FetchConfig ofDefault() {
return new FetchConfig(JOIN_MODE, 100);
}
/**
* Return the batch size for fetching.
*/
public int getBatchSize() {
return batchSize;
}
/**
* Return true if the fetch should use the L2 cache.
*/
public boolean isCache() {
return mode == CACHE_MODE;
}
/**
* Return true if the fetch should be a eager secondary query.
*/
public boolean isQuery() {
return mode == QUERY_MODE;
}
/**
* Return true if the fetch should be a lazy query.
*/
public boolean isLazy() {
return mode == LAZY_MODE;
}
/**
* Return true if the fetch should try to use SQL join.
*/
public boolean isJoin() {
return mode == JOIN_MODE;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
return (hashCode == ((FetchConfig) o).hashCode);
}
@Override
public int hashCode() {
return hashCode;
}
}
@@ -1,19 +0,0 @@
package io.ebean;
/**
* Owner object notified when a modification is detected.
*/
public interface ModifyAwareType {
/**
* Return true if the value is considered dirty.
* Note that this resets the dirty status back to clean.
*/
boolean isMarkedDirty();
/**
* Marks the object as modified.
*/
void setMarkedDirty(boolean markedDirty);
}
@@ -1,84 +0,0 @@
package io.ebean;
/**
* A location for profiling transactions and queries.
* <p>
* Typically represents a class method in the form of class file and line of code that started
* the transaction or invoked the query.
* </p>
*/
public interface ProfileLocation {
/**
* Create and return a new ProfileLocation.
*/
static ProfileLocation create() {
return XServiceProvider.profileLocationFactory().create();
}
/**
* Create and return a new ProfileLocation with line number.
*/
static ProfileLocation createWithLine() {
return XServiceProvider.profileLocationFactory().createWithLine();
}
/**
* Create and return a new ProfileLocation with a given lineNumber and label.
*/
static ProfileLocation create(String label) {
return XServiceProvider.profileLocationFactory().create(label);
}
/**
* Deprecated in favor of {@link #create(String)}.
*/
@Deprecated
static ProfileLocation create(int lineNumber, String label) {
return create(label);
}
/**
* Deprecated for removal - not used.
* Create and return a new ProfileLocation with a given location.
*/
@Deprecated
static ProfileLocation createAt(String location) {
return XServiceProvider.profileLocationFactory().createAt(location);
}
/**
* Obtain the description returning true if this is the initial call.
*/
boolean obtain();
/**
* Return a short version of the location description.
*/
String location();
/**
* Return the short label.
*/
String label();
/**
* Return the full location.
*/
String fullLocation();
/**
* Add execution time.
*/
void add(long executionTime);
/**
* Return true if this request should be traced.
*/
boolean trace();
/**
* Set the number of times to trace the transactions for this profile location.
*/
void setTraceCount(int traceCount);
}
@@ -1,15 +0,0 @@
package io.ebean;
final class SimpleProperty<T> implements Query.Property<T> {
private final String expression;
SimpleProperty(String expression) {
this.expression = expression;
}
@Override
public String toString() {
return expression;
}
}
@@ -1,332 +0,0 @@
package io.ebean;
import io.ebean.Query.Property;
import java.util.Collection;
/**
* Standard Operators for use with strongly typed query construction.
* <p>
* This is currently deemed to be experimental and subject to change.
*/
@Deprecated(since = "experimental")
public final class StdOperators {
// ---- Functions ---- //
/**
* Sum of the given property.
*/
public static Property<Number> sum(Property<? extends Number> property) {
return Property.of("sum(" + property + ")");
}
/**
* Count of the given property.
*/
public static Property<Number> count(Property<?> property) {
return Property.of("count(" + property + ")");
}
/**
* Average of the given property.
*/
public static <T> Property<T> avg(Property<T> property) {
return Property.of("avg(" + property + ")");
}
/**
* Max of the given property.
*/
public static <T> Property<T> max(Property<T> property) {
return Property.of("max(" + property + ")");
}
/**
* Min of the given property.
*/
public static <T> Property<T> min(Property<T> property) {
return Property.of("min(" + property + ")");
}
/**
* Coalesce of the property and value.
*/
public static <T> Property<T> coalesce(Property<T> property, Object value) {
return Property.of("coalesce(" + property.toString() + "," + sqlValue(value) + ")");
}
/**
* Lower of the given property.
*/
public static Property<String> lower(Property<String> property) {
return Property.of("lower(" + property + ")");
}
/**
* Upper of the given property.
*/
public static Property<String> upper(Property<String> property) {
return Property.of("upper(" + property + ")");
}
/**
* Concat of the given property and values or other properties.
*/
public static Property<String> concat(Property<?> property, Object... values) {
StringBuilder expression = new StringBuilder(50);
expression.append("concat(").append(property.toString());
for (Object value : values) {
expression.append(",").append(sqlConcatString(value));
}
expression.append(")");
return Property.of(expression.toString());
}
private static String sqlConcatString(Object value) {
if (value instanceof Property) {
return value.toString();
} else {
return sqlQuote(value);
}
}
/**
* Allows numbers to be unquoted.
*/
private static String sqlValue(Object value) {
if (value instanceof Property || value instanceof Number) {
return value.toString();
} else {
return sqlQuote(value);
}
}
/**
* SQL quoted escaping single quotes.
*/
private static String sqlQuote(Object value) {
return "'" + String.valueOf(value).replace("'", "''") + "'";
}
// ---- Operators ---- //
/**
* Equal to - for a property and value.
*/
public static <T> Expression eq(Property<T> property, T value) {
return Expr.eq(property.toString(), value);
}
/**
* Equal to - for a property and sub-query.
*/
public static <T> Expression eq(Property<T> property, Query<?> subQuery) {
return Expr.in(property.toString(), subQuery);
}
/**
* Equal to or null - for a property and value.
*/
public static <T> Expression eqOrNull(Property<T> property, T value) {
return Expr.factory().eqOrNull(property.toString(), value);
}
/**
* Not equal to - for a property and value.
*/
public static <T> Expression ne(Property<T> property, T value) {
return Expr.ne(property.toString(), value);
}
/**
* Not equal to - for a property and sub-query.
*/
public static <T> Expression ne(Property<T> property, Query<?> subQuery) {
return Expr.ne(property.toString(), subQuery);
}
/**
* Greater than - for a property and value.
*/
public static <T> Expression gt(Property<T> property, T value) {
return Expr.gt(property.toString(), value);
}
/**
* Greater than - for a property and sub-query.
*/
public static <T> Expression gt(Property<T> property, Query<?> subQuery) {
return Expr.gt(property.toString(), subQuery);
}
/**
* Greater than or null - for a property and value.
*/
public static <T> Expression gtOrNull(Property<T> property, T value) {
return Expr.factory().gtOrNull(property.toString(), value);
}
/**
* Greater than or equal to - for a property and value.
*/
public static <T> Expression ge(Property<T> property, T value) {
return Expr.ge(property.toString(), value);
}
/**
* Greater than or equal to - for a property and sub-query.
*/
public static <T> Expression ge(Property<T> property, Query<?> subQuery) {
return Expr.ge(property.toString(), subQuery);
}
/**
* Greater than or null - for a property and value.
*/
public static <T> Expression geOrNull(Property<T> property, T value) {
return Expr.factory().geOrNull(property.toString(), value);
}
/**
* Less than - for a property and value.
*/
public static <T> Expression lt(Property<T> property, T value) {
return Expr.lt(property.toString(), value);
}
/**
* Less than - for a property and sub-query.
*/
public static <T> Expression lt(Property<T> property, Query<?> subQuery) {
return Expr.lt(property.toString(), subQuery);
}
/**
* Less than or null - for a property and value.
*/
public static <T> Expression ltOrNull(Property<T> property, T value) {
return Expr.factory().ltOrNull(property.toString(), value);
}
/**
* Greater than or equal to - for a property and value.
*/
public static <T> Expression le(Property<T> property, T value) {
return Expr.le(property.toString(), value);
}
/**
* Greater than or equal to - for a property and sub-query.
*/
public static <T> Expression le(Property<T> property, Query<?> subQuery) {
return Expr.le(property.toString(), subQuery);
}
/**
* Greater than or equal to or null - for a property and value.
*/
public static <T> Expression leOrNull(Property<T> property, T value) {
return Expr.factory().leOrNull(property.toString(), value);
}
/**
* In range - for a property and values.
*/
public static <T> Expression inRange(Property<T> property, T lowValue, T highValue) {
return Expr.factory().inRange(property.toString(), lowValue, highValue);
}
/**
* In range - for properties and a value.
*/
public static <T> Expression inRange(Property<T> lowProperty, Property<T> highProperty, T value) {
return Expr.factory().inRangeWith(lowProperty.toString(), highProperty.toString(), value);
}
/**
* In range - for properties.
*/
public static <T> Expression inRange(Property<T> lowProperty, Property<T> property, Property<T> highProperty) {
return Expr.factory().inRangeWithProperties(lowProperty.toString(), property.toString(), highProperty.toString());
}
/**
* In - for a given property and collection of values.
*/
public static <T> Expression in(Property<T> property, Collection<T> value) {
return Expr.in(property.toString(), value);
}
/**
* In - for a given property and sub-query.
*/
public static <T> Expression in(Property<T> property, Query<?> subQuery) {
return Expr.in(property.toString(), subQuery);
}
/**
* In or empty - for a given property and collection of values.
*/
public static <T> Expression inOrEmpty(Property<T> property, Collection<T> value) {
return Expr.inOrEmpty(property.toString(), value);
}
/**
* Not In - for a given property and collection of values.
*/
public static <T> Expression notIn(Property<T> property, Collection<T> value) {
return Expr.factory().notIn(property.toString(), value);
}
/**
* Not In - for a given property and sub-query.
*/
public static <T> Expression notIn(Property<T> property, Query<?> subQuery) {
return Expr.factory().notIn(property.toString(), subQuery);
}
// ---- String operators ---- //
/**
* Like - for a given property and value.
*/
public static Expression like(Property<String> property, String value) {
return Expr.like(property.toString(), value);
}
/**
* Case-insensitive Like - for a given property and value.
*/
public static Expression ilike(Property<String> property, String value) {
return Expr.ilike(property.toString(), value);
}
/**
* Starts with - for a given property and value.
*/
public static Expression startsWith(Property<String> property, String value) {
return Expr.startsWith(property.toString(), value);
}
/**
* Case-insensitive starts with - for a given property and value.
*/
public static Expression istartsWith(Property<String> property, String value) {
return Expr.istartsWith(property.toString(), value);
}
/**
* Contains - for a given property and value.
*/
public static Expression contains(Property<String> property, String value) {
return Expr.contains(property.toString(), value);
}
/**
* Case-insensitive contains - for a given property and value.
*/
public static Expression icontains(Property<String> property, String value) {
return Expr.icontains(property.toString(), value);
}
}
@@ -1,28 +0,0 @@
package io.ebean.bean;
import java.util.concurrent.locks.Lock;
/**
* Loads a entity bean.
* <p>
* Typically invokes lazy loading for a single or batch of entity beans.
* </p>
*/
public interface BeanLoader {
/**
* Return the name of the associated Database.
*/
String name();
/**
* Invoke the lazy loading for this bean.
*/
void loadBean(EntityBeanIntercept ebi);
/**
* Obtain a lock on the loader.
*/
Lock lock();
}
@@ -1,555 +0,0 @@
package io.ebean.bean;
import io.ebean.ValuePair;
import java.io.Serializable;
import java.util.Map;
import java.util.Set;
/**
* This is the object associated to every entity bean using byte code enhancement.
* <p>
* This provides per property state such as loaded state, changed state, original values
* as well as bean level dirty state etc.
*/
public interface EntityBeanIntercept extends Serializable {
/**
* Return the 'owning' entity bean.
*/
EntityBean owner();
/**
* Return the persistenceContext.
*/
PersistenceContext persistenceContext();
/**
* Set the persistenceContext.
*/
void setPersistenceContext(PersistenceContext persistenceContext);
/**
* Turn on profile collection.
*/
void setNodeUsageCollector(NodeUsageCollector usageCollector);
/**
* Return the ownerId (IdClass).
*/
Object ownerId();
/**
* Set the ownerId (IdClass).
*/
void setOwnerId(Object ownerId);
/**
* Return the owning bean for an embedded bean.
*/
Object embeddedOwner();
/**
* Return the property index (for the parent) of this embedded bean.
*/
int embeddedOwnerIndex();
/**
* Clear the getter callback.
*/
void clearGetterCallback();
/**
* Register the callback to be triggered when getter is called.
* This is used primarily to automatically flush the JDBC batch.
*/
void registerGetterCallback(PreGetterCallback getterCallback);
/**
* Set the embedded beans owning bean.
*/
void setEmbeddedOwner(EntityBean parentBean, int embeddedOwnerIndex);
/**
* Set the BeanLoader with PersistenceContext.
*/
void setBeanLoader(BeanLoader beanLoader, PersistenceContext ctx);
/**
* Set the BeanLoader.
*/
void setBeanLoader(BeanLoader beanLoader);
/**
* Return true if the bean is fully loaded (not a partial).
*/
boolean isFullyLoadedBean();
/**
* Set true when the bean is fully loaded (not a partial).
*/
void setFullyLoadedBean(boolean fullyLoadedBean);
/**
* Return true if the bean is partially loaded.
*/
boolean isPartial();
/**
* Return true if this bean has been directly modified (it has oldValues) or
* if any embedded beans are either new or dirty (and hence need saving).
*/
boolean isDirty();
/**
* Called by an embedded bean onto its owner.
*/
void setEmbeddedDirty(int embeddedProperty);
/**
* Marks the bean as dirty.
*/
void setDirty(boolean dirty);
/**
* Return true if this entity bean is new and not yet saved.
*/
boolean isNew();
/**
* Return true if the entity bean is new or dirty (and should be saved).
*/
boolean isNewOrDirty();
/**
* Return true if only the Id property has been loaded.
*/
boolean hasIdOnly(int idIndex);
/**
* Return true if the entity is a reference.
*/
boolean isReference();
/**
* Set this as a reference object.
*/
void setReference(int idPos);
/**
* Set true when the bean has been loaded from L2 bean cache.
* The effect of this is that we should skip the cache if there
* is subsequent lazy loading (bean cache partially populated).
*/
void setLoadedFromCache(boolean loadedFromCache);
/**
* Return true if this bean was loaded from L2 bean cache.
*/
boolean isLoadedFromCache();
/**
* Return true if the bean should be treated as readOnly. If a setter method
* is called when it is readOnly an Exception is thrown.
*/
boolean isReadOnly();
/**
* Set the readOnly status. If readOnly then calls to setter methods through
* an exception.
*/
void setReadOnly(boolean readOnly);
/**
* Set the bean to be updated when persisted (for merge).
*/
void setForceUpdate(boolean forceUpdate);
/**
* Return true if the entity should be updated.
*/
boolean isUpdate();
/**
* Return true if the entity has been loaded.
*/
boolean isLoaded();
/**
* Set the bean into NEW state.
*/
void setNew();
/**
* Set the loaded state to true.
* <p>
* Calls to setter methods after the bean is loaded can result in
* 'Old Values' being created.
* <p>
* Worth noting that this is also set after a insert/update. By doing so it
* 'resets' the bean for making further changes and saving again.
*/
void setLoaded();
/**
* When finished loading for lazy or refresh on an already partially populated bean.
*/
void setLoadedLazy();
/**
* Set lazy load failure flag.
*/
void setLazyLoadFailure(Object ownerId);
/**
* Return true if the bean is marked as having failed lazy loading.
*/
boolean isLazyLoadFailure();
/**
* Return true if lazy loading is disabled.
*/
boolean isDisableLazyLoad();
/**
* Set true to turn off lazy loading.
*/
void setDisableLazyLoad(boolean disableLazyLoad);
/**
* Set the loaded status for the embedded bean.
*/
void setEmbeddedLoaded(Object embeddedBean);
/**
* Return true if the embedded bean is new or dirty and hence needs saving.
*/
boolean isEmbeddedNewOrDirty(Object embeddedBean);
/**
* Return the original value that was changed via an update.
*/
Object origValue(int propertyIndex);
/**
* Finds the index position of a given property. Returns -1 if the
* property can not be found.
*/
int findProperty(String propertyName);
/**
* Return the property name for the given property.
*/
String property(int propertyIndex);
/**
* Return the number of properties.
*/
int propertyLength();
/**
* Set the loaded state of the property given it's name.
*/
void setPropertyLoaded(String propertyName, boolean loaded);
/**
* Set the property to be treated as unloaded. Used for properties initialised in default constructor.
*/
void setPropertyUnloaded(int propertyIndex);
/**
* Set the property to be loaded.
*/
void setLoadedProperty(int propertyIndex);
/**
* Set all properties to be loaded (post insert).
*/
void setLoadedPropertyAll();
/**
* Return true if the property is loaded.
*/
boolean isLoadedProperty(int propertyIndex);
/**
* Return true if the property is considered changed.
*/
boolean isChangedProperty(int propertyIndex);
/**
* Return true if the property was changed or if it is embedded and one of its
* embedded properties is dirty.
*/
boolean isDirtyProperty(int propertyIndex);
/**
* Explicitly mark a property as having been changed.
*/
void markPropertyAsChanged(int propertyIndex);
/**
* Set the changed state for the given property.
*/
void setChangedProperty(int propertyIndex);
/**
* Set the changed and loaded state for the given property.
*/
void setChangeLoaded(int propertyIndex);
/**
* Set that an embedded bean has had one of its properties changed.
*/
void setEmbeddedPropertyDirty(int propertyIndex);
/**
* Set the original value for the property.
*/
void setOriginalValue(int propertyIndex, Object value);
/**
* Set old value but force it to be set regardless if it already has a value.
*/
void setOriginalValueForce(int propertyIndex, Object value);
/**
* For forced update on a 'New' bean set all the loaded properties to changed.
*/
void setNewBeanForUpdate();
/**
* Return the set of property names for a partially loaded bean.
*/
Set<String> loadedPropertyNames();
/**
* Return the array of flags indicating the dirty properties.
*/
boolean[] dirtyProperties();
/**
* Return the set of dirty properties.
*/
Set<String> dirtyPropertyNames();
/**
* Recursively add dirty properties.
*/
void addDirtyPropertyNames(Set<String> props, String prefix);
/**
* Return true if any of the given property names are dirty.
*/
boolean hasDirtyProperty(Set<String> propertyNames);
/**
* Return a map of dirty properties with their new and old values.
*/
Map<String, ValuePair> dirtyValues();
/**
* Recursively add dirty properties.
*/
void addDirtyPropertyValues(Map<String, ValuePair> dirtyValues, String prefix);
/**
* Recursively add dirty properties.
*/
void addDirtyPropertyValues(BeanDiffVisitor visitor);
/**
* Return a dirty property hash taking into account embedded beans.
*/
StringBuilder dirtyPropertyKey();
/**
* Add and return a dirty property hash.
*/
void addDirtyPropertyKey(StringBuilder sb);
/**
* Return a loaded property hash.
*/
StringBuilder loadedPropertyKey();
/**
* Return the loaded state for all the properties.
*/
boolean[] loaded();
/**
* Return the index of the property that triggered the lazy load.
*/
int lazyLoadPropertyIndex();
/**
* Return the property that triggered the lazy load.
*/
String lazyLoadProperty();
/**
* Load the bean when it is a reference.
*/
void loadBean(int loadProperty);
/**
* Invoke the lazy loading. This method is synchronised externally.
*/
void loadBeanInternal(int loadProperty, BeanLoader loader);
/**
* Called when a BeanCollection is initialised automatically.
*/
void initialisedMany(int propertyIndex);
/**
* Invoke the PreGetterCallback if it has been set due to getter for the given property.
*/
void preGetterCallback(int propertyIndex);
/**
* Called prior to Id property getter.
*/
void preGetId();
/**
* Method that is called prior to a getter method on the actual entity.
*/
void preGetter(int propertyIndex);
/**
* OneToMany and ManyToMany only set loaded state.
*/
void preSetterMany(boolean interceptField, int propertyIndex, Object oldValue, Object newValue);
/**
* Set the property changed state, bean dirtyState and property original value.
*/
void setChangedPropertyValue(int propertyIndex, boolean setDirtyState, Object origValue);
/**
* Set the dirty state on the bean.
*/
void setDirtyStatus();
/**
* Check to see if the values are not equal. If they are not equal then create
* the old values for use with ConcurrencyMode.ALL.
*/
void preSetter(boolean intercept, int propertyIndex, Object oldValue, Object newValue);
/**
* Check for primitive boolean.
*/
void preSetter(boolean intercept, int propertyIndex, boolean oldValue, boolean newValue);
/**
* Check for primitive int.
*/
void preSetter(boolean intercept, int propertyIndex, int oldValue, int newValue);
/**
* Check for primitive long.
*/
void preSetter(boolean intercept, int propertyIndex, long oldValue, long newValue);
/**
* Check for primitive double.
*/
void preSetter(boolean intercept, int propertyIndex, double oldValue, double newValue);
/**
* Check for primitive float.
*/
void preSetter(boolean intercept, int propertyIndex, float oldValue, float newValue);
/**
* Check for primitive short.
*/
void preSetter(boolean intercept, int propertyIndex, short oldValue, short newValue);
/**
* Check for primitive char.
*/
void preSetter(boolean intercept, int propertyIndex, char oldValue, char newValue);
/**
* Check for primitive byte.
*/
void preSetter(boolean intercept, int propertyIndex, byte oldValue, byte newValue);
/**
* Check for primitive char array.
*/
void preSetter(boolean intercept, int propertyIndex, char[] oldValue, char[] newValue);
/**
* Check for primitive byte array.
*/
void preSetter(boolean intercept, int propertyIndex, byte[] oldValue, byte[] newValue);
/**
* Explicitly set an old value with force (the old value is forced even it is already set).
*/
void setOldValue(int propertyIndex, Object oldValue);
/**
* Return the sort order value for an order column.
*/
int sortOrder();
/**
* Set the sort order value for an order column.
*/
void setSortOrder(int sortOrder);
/**
* Set if the entity was deleted from a BeanCollection.
*/
void setDeletedFromCollection(boolean deletedFromCollection);
/**
* Return true if the bean was orphan deleted from a collection.
*/
boolean isOrphanDelete();
/**
* Set the load error that happened on this property.
*/
void setLoadError(int propertyIndex, Exception t);
/**
* Returns the loadErrors.
*/
Map<String, Exception> loadErrors();
/**
* Return true if the property has its changed state set.
*/
boolean isChangedProp(int propertyIndex);
/**
* Return the MutableValueInfo for the given property or null.
*/
MutableValueInfo mutableInfo(int propertyIndex);
/**
* Set the MutableValueInfo for the given property.
*/
void mutableInfo(int propertyIndex, MutableValueInfo info);
/**
* Dirty detection set the next mutable property content and info .
* <p>
* Set here as the mutable property dirty detection is based on json content comparison.
* We only want to perform the json serialisation once so storing it here as part of
* dirty detection so that we can get it back to bind in insert or update etc.
*/
void mutableNext(int propertyIndex, MutableValueNext next);
/**
* Update the 'next' mutable info returning the content that was obtained via dirty detection.
*/
String mutableNext(int propertyIndex);
}
@@ -1,551 +0,0 @@
package io.ebean.bean;
import io.ebean.ValuePair;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
/**
* EntityBeanIntercept optimised for read only use.
* <p>
* For the read only use this intercept doesn't need to hold any state that is normally
* required for updates such as per property changed, loaded, dirty state, original values
* bean state etc.
*/
public class InterceptReadOnly implements EntityBeanIntercept {
private final EntityBean owner;
/**
* Create with a given entity.
*/
public InterceptReadOnly(Object ownerBean) {
this.owner = (EntityBean) ownerBean;
}
@Override
public String toString() {
return "InterceptReadOnly{" + owner + '}';
}
@Override
public EntityBean owner() {
return owner;
}
@Override
public PersistenceContext persistenceContext() {
return null;
}
@Override
public void setPersistenceContext(PersistenceContext persistenceContext) {
}
@Override
public void setNodeUsageCollector(NodeUsageCollector usageCollector) {
}
@Override
public Object ownerId() {
return null;
}
@Override
public void setOwnerId(Object ownerId) {
}
@Override
public Object embeddedOwner() {
return null;
}
@Override
public int embeddedOwnerIndex() {
return 0;
}
@Override
public void clearGetterCallback() {
}
@Override
public void registerGetterCallback(PreGetterCallback getterCallback) {
}
@Override
public void setEmbeddedOwner(EntityBean parentBean, int embeddedOwnerIndex) {
}
@Override
public void setBeanLoader(BeanLoader beanLoader, PersistenceContext ctx) {
}
@Override
public void setBeanLoader(BeanLoader beanLoader) {
}
@Override
public boolean isFullyLoadedBean() {
return false;
}
@Override
public void setFullyLoadedBean(boolean fullyLoadedBean) {
}
@Override
public boolean isPartial() {
return false;
}
@Override
public boolean isDirty() {
return false;
}
@Override
public void setEmbeddedDirty(int embeddedProperty) {
}
@Override
public void setDirty(boolean dirty) {
}
@Override
public boolean isNew() {
return false;
}
@Override
public boolean isNewOrDirty() {
return false;
}
@Override
public boolean hasIdOnly(int idIndex) {
return false;
}
@Override
public boolean isReference() {
return false;
}
@Override
public void setReference(int idPos) {
}
@Override
public void setLoadedFromCache(boolean loadedFromCache) {
}
@Override
public boolean isLoadedFromCache() {
return false;
}
@Override
public boolean isReadOnly() {
return true;
}
@Override
public void setReadOnly(boolean readOnly) {
}
@Override
public void setForceUpdate(boolean forceUpdate) {
}
@Override
public boolean isUpdate() {
return false;
}
@Override
public boolean isLoaded() {
return true;
}
@Override
public void setNew() {
}
@Override
public void setLoaded() {
}
@Override
public void setLoadedLazy() {
}
@Override
public void setLazyLoadFailure(Object ownerId) {
}
@Override
public boolean isLazyLoadFailure() {
return false;
}
@Override
public boolean isDisableLazyLoad() {
return false;
}
@Override
public void setDisableLazyLoad(boolean disableLazyLoad) {
}
@Override
public void setEmbeddedLoaded(Object embeddedBean) {
}
@Override
public boolean isEmbeddedNewOrDirty(Object embeddedBean) {
return false;
}
@Override
public Object origValue(int propertyIndex) {
return null;
}
@Override
public int findProperty(String propertyName) {
return 0;
}
@Override
public String property(int propertyIndex) {
return null;
}
@Override
public int propertyLength() {
return 0;
}
@Override
public void setPropertyLoaded(String propertyName, boolean loaded) {
}
@Override
public void setPropertyUnloaded(int propertyIndex) {
}
@Override
public void setLoadedProperty(int propertyIndex) {
}
@Override
public void setLoadedPropertyAll() {
}
@Override
public boolean isLoadedProperty(int propertyIndex) {
return false;
}
@Override
public boolean isChangedProperty(int propertyIndex) {
return false;
}
@Override
public boolean isDirtyProperty(int propertyIndex) {
return false;
}
@Override
public void markPropertyAsChanged(int propertyIndex) {
}
@Override
public void setChangedProperty(int propertyIndex) {
}
@Override
public void setChangeLoaded(int propertyIndex) {
}
@Override
public void setEmbeddedPropertyDirty(int propertyIndex) {
}
@Override
public void setOriginalValue(int propertyIndex, Object value) {
}
@Override
public void setOriginalValueForce(int propertyIndex, Object value) {
}
@Override
public void setNewBeanForUpdate() {
}
@Override
public Set<String> loadedPropertyNames() {
return Collections.emptySet();
}
@Override
public boolean[] dirtyProperties() {
return new boolean[0];
}
@Override
public Set<String> dirtyPropertyNames() {
return Collections.emptySet();
}
@Override
public void addDirtyPropertyNames(Set<String> props, String prefix) {
}
@Override
public boolean hasDirtyProperty(Set<String> propertyNames) {
return false;
}
@Override
public Map<String, ValuePair> dirtyValues() {
return Collections.emptyMap();
}
@Override
public void addDirtyPropertyValues(Map<String, ValuePair> dirtyValues, String prefix) {
}
@Override
public void addDirtyPropertyValues(BeanDiffVisitor visitor) {
}
@Override
public StringBuilder dirtyPropertyKey() {
return null;
}
@Override
public void addDirtyPropertyKey(StringBuilder sb) {
}
@Override
public StringBuilder loadedPropertyKey() {
return null;
}
@Override
public boolean[] loaded() {
return new boolean[0];
}
@Override
public int lazyLoadPropertyIndex() {
return 0;
}
@Override
public String lazyLoadProperty() {
return null;
}
@Override
public void loadBean(int loadProperty) {
}
@Override
public void loadBeanInternal(int loadProperty, BeanLoader loader) {
}
@Override
public void initialisedMany(int propertyIndex) {
}
@Override
public void preGetterCallback(int propertyIndex) {
}
@Override
public void preGetId() {
}
@Override
public void preGetter(int propertyIndex) {
}
@Override
public void preSetterMany(boolean interceptField, int propertyIndex, Object oldValue, Object newValue) {
}
@Override
public void setChangedPropertyValue(int propertyIndex, boolean setDirtyState, Object origValue) {
}
@Override
public void setDirtyStatus() {
}
@Override
public void preSetter(boolean intercept, int propertyIndex, Object oldValue, Object newValue) {
}
@Override
public void preSetter(boolean intercept, int propertyIndex, boolean oldValue, boolean newValue) {
}
@Override
public void preSetter(boolean intercept, int propertyIndex, int oldValue, int newValue) {
}
@Override
public void preSetter(boolean intercept, int propertyIndex, long oldValue, long newValue) {
}
@Override
public void preSetter(boolean intercept, int propertyIndex, double oldValue, double newValue) {
}
@Override
public void preSetter(boolean intercept, int propertyIndex, float oldValue, float newValue) {
}
@Override
public void preSetter(boolean intercept, int propertyIndex, short oldValue, short newValue) {
}
@Override
public void preSetter(boolean intercept, int propertyIndex, char oldValue, char newValue) {
}
@Override
public void preSetter(boolean intercept, int propertyIndex, byte oldValue, byte newValue) {
}
@Override
public void preSetter(boolean intercept, int propertyIndex, char[] oldValue, char[] newValue) {
}
@Override
public void preSetter(boolean intercept, int propertyIndex, byte[] oldValue, byte[] newValue) {
}
@Override
public void setOldValue(int propertyIndex, Object oldValue) {
}
@Override
public int sortOrder() {
return 0;
}
@Override
public void setSortOrder(int sortOrder) {
}
@Override
public void setDeletedFromCollection(boolean deletedFromCollection) {
}
@Override
public boolean isOrphanDelete() {
return false;
}
@Override
public void setLoadError(int propertyIndex, Exception t) {
}
@Override
public Map<String, Exception> loadErrors() {
return null;
}
@Override
public boolean isChangedProp(int i) {
return false;
}
@Override
public MutableValueInfo mutableInfo(int propertyIndex) {
return null;
}
@Override
public void mutableInfo(int propertyIndex, MutableValueInfo info) {
}
@Override
public void mutableNext(int propertyIndex, MutableValueNext next) {
}
@Override
public String mutableNext(int propertyIndex) {
return null;
}
}
File diff suppressed because it is too large Load Diff
@@ -1,42 +0,0 @@
package io.ebean.bean;
/**
* Holds information on mutable values (like plain beans stored as json).
* <p>
* Used internally in EntityBeanIntercept for dirty detection on mutable values.
* Typically, mutation detection is based on a hash/checksum of json content or the
* original json content itself.
* <p>
* Refer to the mapping options {@code @DbJson(mutationDetection)}.
*/
public interface MutableValueInfo {
/**
* Compares the given json returning null if deemed unchanged or returning
* the MutableValueNext to use if deemed dirty/changed.
* <p>
* Returning MutableValueNext allows an implementation based on hash/checksum
* to only perform that computation once.
*
* @return Null if deemed unchanged or the MutableValueNext if deemed changed.
*/
MutableValueNext nextDirty(String json);
/**
* Compares the given object to an internal value.
* <p>
* This is used to support changelog/beanState. The implementation can serialize the
* object into json form and compare it against the original json.
*/
boolean isEqualToObject(Object obj);
/**
* Creates a new instance from the internal json string.
* <p>
* This is used to provide an original/old value for change logging / persist listeners.
* This is only available for properties that have {@code @DbJson(keepSource=true)}.
*/
default Object get() {
return null;
}
}
@@ -1,17 +0,0 @@
package io.ebean.bean;
/**
* Represents a next value to use for mutable content properties (DbJson with jackson beans).
*/
public interface MutableValueNext {
/**
* Return the next content to use. Provided such that we serialise to json once.
*/
String content();
/**
* Return the next MutableValueInfo to use after an update.
*/
MutableValueInfo info();
}
@@ -1,109 +0,0 @@
package io.ebean.bean;
import java.lang.ref.Cleaner;
import java.util.LinkedHashSet;
import java.util.Set;
/**
* Collects profile information for a bean (or reference/proxy bean) at a given node.
* <p>
* The node identifies the location of the bean in the object graph.
*/
public final class NodeUsageCollector {
private final static Cleaner cleaner = Cleaner.create();
public static final class State implements Runnable {
private final NodeUsageListener listener;
/**
* The properties used at this profile point.
*/
private final Set<String> used = new LinkedHashSet<>();
/**
* The point in the object graph for a specific query and call stack point.
*/
private final ObjectGraphNode node;
/**
* set to true if the bean is modified (setter called)
*/
private boolean modified;
private State(ObjectGraphNode node, NodeUsageListener listener) {
this.node = node;
this.listener = listener;
}
@Override
public String toString() {
return node + " read:" + used + " modified:" + modified;
}
@Override
public void run() {
listener.collectNodeUsage(this);
}
/**
* Return true if no properties where used.
*/
public boolean isEmpty() {
return used.isEmpty();
}
/**
* Return the associated node which identifies the location in the object
* graph of the bean/reference.
*/
public ObjectGraphNode node() {
return node;
}
/**
* Return the set of used properties.
*/
public Set<String> used() {
return used;
}
/**
* Return true if the bean was modified by a setter.
*/
public boolean isModified() {
return modified;
}
}
private final State state;
public NodeUsageCollector(ObjectGraphNode node, NodeUsageListener listener) {
this.state = new State(node, listener);
cleaner.register(this, state);
}
/**
* Return the underlying state.
*/
public State state() {
return state;
}
/**
* The bean has been modified by a setter method.
*/
public void setModified() {
state.modified = true;
}
/**
* Add the name of a property that has been used.
*/
public void addUsed(String property) {
state.used.add(property);
}
@Override
public String toString() {
return state.toString();
}
}
@@ -1,91 +0,0 @@
package io.ebean.bean;
import java.io.Serializable;
import java.util.Objects;
/**
* Identifies a unique node of an object graph.
* <p>
* It represents a location relative to the root of an object graph and specific
* to a query and call stack hash.
*/
public final class ObjectGraphNode implements Serializable {
private static final long serialVersionUID = 2087081778650228996L;
/**
* Identifies the origin.
*/
private final ObjectGraphOrigin origin;
/**
* The path relative to the root.
*/
private final String path;
/**
* Create at a sub level.
*/
public ObjectGraphNode(ObjectGraphNode parent, String path) {
this.origin = parent.origin();
this.path = parent.childPath(path);
}
/**
* Create an the root level.
*/
public ObjectGraphNode(ObjectGraphOrigin origin, String path) {
this.origin = origin;
this.path = path;
}
/**
* Return the origin query point.
*/
public ObjectGraphOrigin origin() {
return origin;
}
private String childPath(String childPath) {
if (path == null) {
return childPath;
} else if (childPath == null) {
return path;
} else {
return path + "." + childPath;
}
}
/**
* Return the path relative to the root.
*/
public String path() {
return path;
}
@Override
public String toString() {
return "origin:" + origin + " path[" + path + "]";
}
@Override
public int hashCode() {
int hc = 92821 * origin.hashCode();
hc = 92821 * hc + (path == null ? 0 : path.hashCode());
return hc;
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof ObjectGraphNode)) {
return false;
}
ObjectGraphNode e = (ObjectGraphNode) obj;
return (Objects.equals(e.path, path))
&& e.origin.equals(origin);
}
}
@@ -1,73 +0,0 @@
package io.ebean.bean;
import io.ebean.Database;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* BeanLoader used when single beans are loaded (which is usually not ideal / N+1).
*/
public abstract class SingleBeanLoader implements BeanLoader {
private final ReentrantLock lock = new ReentrantLock();
protected final Database database;
SingleBeanLoader(Database database) {
this.database = database;
}
@Override
public String name() {
return database.name();
}
@Override
public Lock lock() {
lock.lock();
return lock;
}
/**
* Single bean lazy loaded when bean from L2 cache.
*/
public static class L2 extends SingleBeanLoader {
public L2(Database database) {
super(database);
}
@Override
public void loadBean(EntityBeanIntercept ebi) {
database.pluginApi().loadBeanL2(ebi);
}
}
/**
* Single bean lazy loaded when a reference bean.
*/
public static class Ref extends SingleBeanLoader {
public Ref(Database database) {
super(database);
}
@Override
public void loadBean(EntityBeanIntercept ebi) {
database.pluginApi().loadBeanRef(ebi);
}
}
/**
* Single bean lazy loaded when a reference bean.
*/
public static class Dflt extends SingleBeanLoader {
public Dflt(Database database) {
super(database);
}
@Override
public void loadBean(EntityBeanIntercept ebi) {
database.pluginApi().loadBean(ebi);
}
}
}
@@ -1,12 +0,0 @@
package io.ebean.bean;
/**
* A type that can participate in building toString content with ToStringBuilder.
*/
public interface ToStringAware {
/**
* Append to the ToStringBuilder.
*/
void toString(ToStringBuilder builder);
}
@@ -1,188 +0,0 @@
package io.ebean.bean;
import java.util.Collection;
import java.util.IdentityHashMap;
import java.util.Map;
/**
* Helps build toString content taking into account recursion.
* <p>
* That is, it detects and handles the case where there are relationships that recurse
* and would otherwise become an infinite loop (e.g. bidirectional parent child).
*/
public final class ToStringBuilder {
/**
* The max number of objects that we allow before stopping content being appended.
*/
private static final int MAX = 100;
/**
* Max length of content in string form added for any given value.
*/
private static final int TRIM_LENGTH = 500;
/**
* The max total content after which we stop content being appended.
*/
private static final int MAX_TOTAL_CONTENT = 2000;
private final IdentityHashMap<Object, Integer> id = new IdentityHashMap<>();
private final StringBuilder sb = new StringBuilder(50);
private boolean first = true;
private int counter;
@Override
public String toString() {
return sb.toString();
}
/**
* Set of an object being added.
*/
public void start(Object bean) {
if (counter == 0) {
id.putIfAbsent(bean, 0);
}
if (counter <= MAX) {
sb.append(bean.getClass().getSimpleName()).append("@").append(counter).append("(");
}
}
/**
* Add a property as name value pair.
*/
public void add(String name, Object value) {
if (value != null && counter <= MAX) {
if (value instanceof BeanCollection) {
if (((BeanCollection<?>)value).isReference()) {
// suppress unloaded bean collections
return;
}
}
key(name);
value(value);
}
}
/**
* Add raw content.
*/
public void addRaw(String content) {
sb.append(content);
}
/**
* End of an object.
*/
public void end() {
if (counter <= MAX) {
sb.append(")");
}
}
private void key(String name) {
if (counter > MAX) {
return;
}
if (first) {
first = false;
} else {
sb.append(", ");
}
sb.append(name).append(":");
}
private void value(Object value) {
if (counter > MAX) {
return;
}
if (value instanceof ToStringAware) {
if (value instanceof BeanCollection) {
((ToStringAware) value).toString(this);
} else if (push(value)) {
((ToStringAware) value).toString(this);
}
} else if (value instanceof Collection) {
addCollection((Collection<?>) value);
} else if (value instanceof Map) {
addMap(((Map<?, ?>) value));
} else {
String content = String.valueOf(value);
if (content.length() > TRIM_LENGTH) {
content = content.substring(0, TRIM_LENGTH) + " <trimmed>";
}
sb.append(content);
if (sb.length() >= MAX_TOTAL_CONTENT) {
sb.append(" ...");
counter += MAX;
}
}
}
public void addMap(Map<?,?> map) {
if (map == null || map.isEmpty()) {
sb.append("{}");
} else {
boolean firstElement = true;
sb.append("{");
for (Map.Entry<?, ?> entry : map.entrySet()) {
if (firstElement) {
firstElement = false;
} else {
sb.append(", ");
}
sb.append(entry.getKey()).append(":");
value(entry.getValue());
if (counter > MAX) {
return;
}
}
sb.append("}");
}
}
/**
* Add a collection of values.
*/
public void addCollection(Collection<?> c) {
if (c == null || c.isEmpty()) {
sb.append("[]");
return;
}
boolean firstElement = true;
sb.append("[");
for (Object o : c) {
if (firstElement) {
firstElement = false;
} else {
sb.append(", ");
}
value(o);
if (counter > MAX) {
return;
}
}
sb.append("]");
}
private boolean push(Object bean) {
if (counter > MAX) {
return false;
}
if (counter == MAX) {
sb.append(" ...");
counter++;
return false;
}
Integer idx = id.putIfAbsent(bean, counter++);
if (idx != null) {
--counter;
sb.append(bean.getClass().getSimpleName()).append("@").append(idx);
return false;
}
first = true;
return true;
}
}
@@ -1,15 +0,0 @@
package io.ebean.cache;
import io.ebean.BackgroundExecutor;
import io.ebean.config.DatabaseConfig;
/**
* The plugin interface that creates a ServerCacheFactory.
*/
public interface ServerCachePlugin {
/**
* Create the ServerCacheFactory given the server config and background executor service.
*/
ServerCacheFactory create(DatabaseConfig config, BackgroundExecutor executor);
}
@@ -1,105 +0,0 @@
package io.ebean.cache;
import io.ebean.meta.MetricVisitor;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
* A ServerCache proxy that is tenant aware.
*/
public final class TenantAwareCache implements ServerCache {
private final ServerCache delegate;
private final TenantAwareKey tenantAwareKey;
/**
* Create given the TenantAwareKey and delegate cache to proxy to.
*
* @param delegate The cache to proxy to
* @param tenantAwareKey Provides tenant aware keys to use in the cache
*/
public TenantAwareCache(ServerCache delegate, TenantAwareKey tenantAwareKey) {
this.delegate = delegate;
this.tenantAwareKey = tenantAwareKey;
}
/**
* Return the underlying ServerCache that is being delegated to.
*/
@SuppressWarnings("unchecked")
@Override
public <T> T unwrap(Class<T> cls) {
return (T) delegate;
}
@Override
public void visit(MetricVisitor visitor) {
delegate.visit(visitor);
}
private Object key(Object key) {
return tenantAwareKey.key(key);
}
@Override
public Object get(Object id) {
return delegate.get(key(id));
}
@Override
public void put(Object id, Object value) {
delegate.put(key(id), value);
}
@Override
public void remove(Object id) {
delegate.remove(key(id));
}
@Override
public void clear() {
delegate.clear();
}
@Override
public int size() {
return delegate.size();
}
@Override
public int hitRatio() {
return delegate.hitRatio();
}
@Override
public ServerCacheStatistics statistics(boolean reset) {
return delegate.statistics(reset);
}
@Override
public Map<Object, Object> getAll(Set<Object> keys) {
Map<Object, Object> keyMapping = new HashMap<>(keys.size());
keys.forEach(k -> keyMapping.put(key(k), k));
Map<Object, Object> tmp = delegate.getAll(keyMapping.keySet());
Map<Object, Object> ret = new HashMap<>(keys.size());
// unwrap tenant info here
tmp.forEach((k,v)-> ret.put(((TenantAwareKey.CacheKey) k).key, v));
return ret;
}
@Override
public void putAll(Map<Object, Object> keyValues) {
Map<Object, Object> tmp = new HashMap<>();
keyValues.forEach((k, v) -> tmp.put(key(k), v));
delegate.putAll(tmp);
}
@Override
public void removeAll(Set<Object> keys) {
delegate.removeAll(keys.stream().map(this::key).collect(Collectors.toSet()));
}
}
@@ -1,131 +0,0 @@
package io.ebean.common;
import java.util.*;
/**
* Handles the Entry Set for BeanMap.
*/
class ModifyEntrySet<K, E> implements Set<Map.Entry<K, E>> {
private final BeanMap<K, E> owner;
private final Set<Map.Entry<K, E>> entrySet;
ModifyEntrySet(BeanMap<K, E> owner, Set<Map.Entry<K, E>> entrySet) {
this.owner = owner;
this.entrySet = entrySet;
}
@Override
public int size() {
return entrySet.size();
}
@Override
public boolean isEmpty() {
return entrySet.isEmpty();
}
@Override
public boolean contains(Object o) {
return entrySet.contains(o);
}
@Override
public Object[] toArray() {
return entrySet.toArray();
}
@Override
public <T> T[] toArray(T[] a) {
return entrySet.toArray(a);
}
@Override
public boolean containsAll(Collection<?> entries) {
return entrySet.containsAll(entries);
}
@Override
public void clear() {
owner.clear();
}
@Override
public boolean add(Map.Entry<K, E> entry) {
throw new UnsupportedOperationException();
}
@Override
public boolean addAll(Collection<? extends Map.Entry<K, E>> c) {
throw new UnsupportedOperationException();
}
@SuppressWarnings("rawtypes")
@Override
public boolean remove(Object o) {
if (o instanceof Map.Entry) {
Map.Entry entry = (Map.Entry) o;
final E val = owner.get(entry.getKey());
if (Objects.equals(val, entry.getValue())) {
owner.remove(entry.getKey());
return true;
}
}
return false;
}
@Override
public boolean retainAll(Collection<?> entries) {
boolean modified = false;
final Iterator<Map.Entry<K, E>> it = iterator();
while (it.hasNext()) {
if (!entries.contains(it.next())) {
it.remove();
modified = true;
}
}
return modified;
}
@Override
public boolean removeAll(Collection<?> entries) {
boolean modified = false;
for (Object entry : entries) {
modified |= remove(entry);
}
return modified;
}
@Override
public Iterator<Map.Entry<K, E>> iterator() {
return new EntrySetIterator(new ArrayList<>(entrySet).iterator());
}
class EntrySetIterator implements Iterator<Map.Entry<K, E>> {
private final Iterator<Map.Entry<K, E>> iterator;
private Map.Entry<K, E> entry;
EntrySetIterator(Iterator<Map.Entry<K, E>> iterator) {
this.iterator = iterator;
}
@Override
public boolean hasNext() {
return iterator.hasNext();
}
@Override
public Map.Entry<K, E> next() {
entry = iterator.next();
return entry;
}
@Override
public void remove() {
owner.remove(entry.getKey());
iterator.remove();
}
}
}
@@ -1,107 +0,0 @@
package io.ebean.common;
import io.ebean.bean.EntityBean;
import java.io.Serializable;
import java.util.*;
/**
* Holds sets of additions and deletions from a 'owner' List Set or Map.
* <p>
* These sets of additions and deletions are used to support persisting
* ManyToMany relationships. The additions becoming inserts into the
* intersection table and the removals becoming deletes from the intersection
* table.
* </p>
*/
class ModifyHolder<E> implements Serializable {
private static final long serialVersionUID = 2572572897923801083L;
/**
* Deletions list for manyToMany persistence.
*/
private Map<E,Object> modifyDeletions = new IdentityHashMap<>();
/**
* Additions list for manyToMany persistence.
*/
private Map<E,Object> modifyAdditions = new IdentityHashMap<>();
private boolean touched;
void reset() {
touched = false;
modifyDeletions = new IdentityHashMap<>();
modifyAdditions = new IdentityHashMap<>();
}
/**
* Used by BeanList.addAll() methods.
*/
void modifyAdditionAll(Collection<? extends E> c) {
if (c != null) {
for (E e : c) {
modifyAddition(e);
}
}
}
private boolean undoDeletion(E bean) {
return (bean != null) && modifyDeletions.remove(bean) != null;
}
void modifyAddition(E bean) {
if (bean != null) {
touched = true;
if (bean instanceof EntityBean) {
((EntityBean) bean)._ebean_getIntercept().setDeletedFromCollection(false);
}
// If it is to delete then just remove the deletion
if (!undoDeletion(bean)) {
modifyAdditions.put(bean, bean);
}
}
}
private boolean undoAddition(Object bean) {
return (bean != null) && modifyAdditions.remove(bean) != null;
}
@SuppressWarnings("unchecked")
void modifyRemoval(Object bean) {
if (bean != null) {
touched = true;
if (bean instanceof EntityBean) {
((EntityBean) bean)._ebean_getIntercept().setDeletedFromCollection(true);
}
// If it is to be added then just remove the addition
if (!undoAddition(bean)) {
modifyDeletions.put((E) bean, bean);
}
}
}
Set<E> getModifyAdditions() {
return modifyAdditions.keySet();
}
Set<E> getModifyRemovals() {
return modifyDeletions.keySet();
}
/**
* Return true if the collection was touched in some way. This is still true even if
* a bean was removed and then added (which is not held as a modification).
*/
boolean wasTouched() {
return touched;
}
/**
* Return true if there additions or removals.
*/
boolean hasModifications() {
return !modifyDeletions.isEmpty() || !modifyAdditions.isEmpty();
}
}
@@ -1,126 +0,0 @@
package io.ebean.common;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
/**
* Handle the Key Set for BeanMap.
*/
class ModifyKeySet<E> implements Set<E> {
private final Set<E> keySet;
private final BeanMap<E, ?> owner;
ModifyKeySet(BeanMap<E, ?> owner, Set<E> keySet) {
this.owner = owner;
this.keySet = keySet;
}
@Override
public int size() {
return keySet.size();
}
@Override
public boolean isEmpty() {
return keySet.isEmpty();
}
@Override
public boolean contains(Object o) {
return keySet.contains(o);
}
@Override
public Object[] toArray() {
return keySet.toArray();
}
@Override
public <T> T[] toArray(T[] a) {
return keySet.toArray(a);
}
@Override
public boolean add(E key) {
throw new UnsupportedOperationException();
}
@Override
public boolean addAll(Collection<? extends E> keys) {
throw new UnsupportedOperationException();
}
@Override
public boolean remove(Object o) {
return owner.remove(o) != null;
}
@Override
public boolean containsAll(Collection<?> keys) {
return keySet.containsAll(keys);
}
@Override
public void clear() {
owner.clear();
}
@Override
public Iterator<E> iterator() {
return new KeySetIterator<>(new ArrayList<>(keySet).iterator());
}
@Override
public boolean retainAll(Collection<?> keys) {
return keysMatch(keys, false);
}
@Override
public boolean removeAll(Collection<?> keys) {
return keysMatch(keys, true);
}
private boolean keysMatch(Collection<?> keys, boolean containsMatch) {
boolean changed = false;
final Iterator<E> iterator = iterator();
while (iterator.hasNext()) {
final E key = iterator.next();
if (keys.contains(key) == containsMatch) {
iterator.remove();
changed = true;
}
}
return changed;
}
class KeySetIterator<K> implements Iterator<K> {
private final Iterator<K> iterator;
private K key;
KeySetIterator(Iterator<K> iterator) {
this.iterator = iterator;
}
@Override
public boolean hasNext() {
return iterator.hasNext();
}
@Override
public K next() {
key = iterator.next();
return key;
}
@Override
public void remove() {
owner.remove(key);
iterator.remove();
}
}
}
@@ -1,18 +0,0 @@
package io.ebean.config;
/**
* Used to provide some automatic configuration early in the creation of a Database.
*/
public interface AutoConfigure {
/**
* Perform configuration for the DatabaseConfig prior to properties load.
*/
void preConfigure(DatabaseConfig config);
/**
* Provide some configuration the DatabaseConfig prior to server creation but after properties have been applied.
*/
void postConfigure(DatabaseConfig config);
}
@@ -1,46 +0,0 @@
package io.ebean.config;
import java.util.concurrent.Callable;
/**
* BackgroundExecutorWrapper that can be used to wrap tasks that are sent to background (i.e. another thread).
* It should copy all necessary thread-local variables. See {@link MdcBackgroundExecutorWrapper} for implementation details.
*
* Note: only tasks that are executed immediately (submit, execute) are wrapped. Periodic or scheduled tasks are not wrapped,
* as these may keep copied variables in memory either forever or until the scheduled task is finished.
* The caller is responsible to handle these cases.
*
* @author Roland Praml, FOCONIS AG
*/
public interface BackgroundExecutorWrapper {
/**
* Wrap the task with MDC context if defined.
*/
<T> Callable<T> wrap(Callable<T> task);
/**
* Wrap the task with MDC context if defined.
*/
Runnable wrap(Runnable task);
/**
* Combines two wrappers by nesting them.
*/
default BackgroundExecutorWrapper with(BackgroundExecutorWrapper inner) {
return new BackgroundExecutorWrapper() {
@Override
public Runnable wrap(Runnable task) {
return BackgroundExecutorWrapper.this.wrap(inner.wrap(task));
}
@Override
public <T> Callable<T> wrap(Callable<T> task) {
return BackgroundExecutorWrapper.this.wrap(inner.wrap(task));
}
};
}
}
File diff suppressed because it is too large Load Diff
@@ -1,39 +0,0 @@
package io.ebean.config;
/**
* Provides a ServiceLoader based mechanism to configure a DatabaseConfig.
* <p>
* Provide an implementation and register it via the standard Java ServiceLoader mechanism
* via a file at <code>META-INF/services/io.ebean.config.DatabaseConfigProvider</code>.
* </p>
* <p>
* If you are using a DI container like Spring or Guice you are unlikely to use this but instead use a
* spring specific configuration. When we are not using a DI container we may use this mechanism to
* explicitly register the entity beans and avoid classpath scanning.
* </p>
* <pre>{@code
*
* public class EbeanConfigProvider implements DatabaseConfigProvider {
*
* @Override
* public void apply(DatabaseConfig config) {
*
* // register the entity bean classes explicitly
* config.addClass(Customer.class);
* config.addClass(User.class);
* ...
* }
* }
*
* }</pre>
*/
public interface DatabaseConfigProvider {
/**
* Apply the configuration to the DatabaseConfig.
* <p>
* Typically we explicitly register entity bean classes and thus avoid classpath scanning.
* </p>
*/
void apply(DatabaseConfig config);
}
@@ -1,74 +0,0 @@
package io.ebean.config;
/**
* Used to normalise table and column names which means stripping out
* quoted identifier characters and any catalog or schema prefix.
*/
public class DbConstraintNormalise {
protected final String[] quotedIdentifiers;
protected final boolean lowerCaseTables;
protected final boolean lowerCaseColumns;
public DbConstraintNormalise() {
this(true, true);
}
public DbConstraintNormalise(boolean lowerCaseTables, boolean lowerCaseColumns) {
this.lowerCaseTables = lowerCaseTables;
this.lowerCaseColumns = lowerCaseColumns;
this.quotedIdentifiers = new String[]{"\"", "'", "[", "]", "`"};
}
/**
* Normalise the table name by trimming catalog and schema and removing any
* quoted identifier characters (",',[,] etc).
*/
public String normaliseTable(String tableName) {
tableName = trimQuotes(tableName);
int lastPeriod = tableName.lastIndexOf('.');
if (lastPeriod > -1) {
// trim off catalog and schema prefix
tableName = tableName.substring(lastPeriod + 1);
}
if (lowerCaseTables) {
tableName = tableName.toLowerCase();
}
return tableName;
}
/**
* Normalise the column name by removing any quoted identifier characters and formula brackets.
*/
public String normaliseColumn(String columnName) {
columnName = trimBrackets(trimQuotes(columnName));
if (lowerCaseColumns) {
columnName = columnName.toLowerCase();
}
return columnName;
}
private String trimBrackets(String value) {
return value.replace("(","").replace(")","");
}
/**
* Trim off the platform quoted identifier quotes like [ ' and ".
*/
public String trimQuotes(String identifier) {
if (identifier == null) {
return "";
}
// remove quoted identifier characters
for (String quotedIdentifier : quotedIdentifiers) {
identifier = identifier.replace(quotedIdentifier, "");
}
return identifier;
}
}

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